chenqiyang
2021-08-27 6a63c4281fbe7e17103115320cd276397d733081
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
/*
 * Copyright (c) 2010-2019 Belledonne Communications SARL.
 *
 * This file is part of mediastreamer2.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
 
#ifndef msfilter_h
#define msfilter_h
 
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/msqueue.h"
#include "mediastreamer2/allfilters.h"
#include "mediastreamer2/formats.h"
#include "mediastreamer2/box-plot.h"
 
/**
 * @file msfilter.h
 * @brief mediastreamer2 msfilter.h include file
 *
 * This file provide the API needed to create, link,
 * unlink, find and destroy filter.
 *
 * It also provides definitions if you wish to implement
 * your own filters.
 *
 */
 
/**
 * @addtogroup mediastreamer2_filter
 * @{
 */
 
/**
 * Structure for filter's methods (init, preprocess, process, postprocess, uninit).
 * @var MSFilterFunc
 */
typedef void (*MSFilterFunc)(struct _MSFilter *f);
 
/**
 * Structure for filter's methods used to set filter's options.
 * @var MSFilterMethodFunc
 */
typedef int (*MSFilterMethodFunc)(struct _MSFilter *f, void *arg);
 
/**
 * Structure for filter's methods used as a callback to notify events.
 * @var MSFilterNotifyFunc
 */
typedef void (*MSFilterNotifyFunc)(void *userdata, struct _MSFilter *f, unsigned int id, void *arg);
 
struct _MSFilterMethod{
    unsigned int id;
    MSFilterMethodFunc method;
};
 
 
/**
 * Interface IDs, used to generate method names (see MS_FILTER_METHOD macro).
 * The purpose of these interfaces is to allow different filter implementations to share the same methods, by implementing the method definitions for these interfaces.
 * For example every video encoder implementation would need a method to request the generation of a key frame. Instead of having each implementation defining its own method to do this,
 * each implementation can just implement the MS_VIDEO_ENCODER_REQ_VFU method of the MSFilterVideoEncoderInterface.
**/
enum _MSFilterInterfaceId{
    MSFilterInterfaceBegin=16384,
    MSFilterPlayerInterface, /**<Player interface, used to control playing of files.*/
    MSFilterRecorderInterface,/**<Recorder interface, used to control recording of stream into files.*/
    MSFilterVideoDisplayInterface,/**<Video display interface, used to control the rendering of raw pictures onscreen.*/
    MSFilterEchoCancellerInterface,/**Echo canceller interface, used to control echo canceller implementations.*/
    MSFilterVideoDecoderInterface,/**<Video decoder interface*/
    MSFilterVideoCaptureInterface,/**<Video capture interface*/
    MSFilterAudioDecoderInterface,/**<Audio Decoder interface*/
    MSFilterVideoEncoderInterface,/**<Video encoder interface*/
    MSFilterAudioCaptureInterface,/**<Interface for audio capture filters*/
    MSFilterAudioPlaybackInterface,/**Interface for audio playback filters.*/
    MSFilterAudioEncoderInterface,/**<Video encoder interface*/
    MSFilterVADInterface,/**<Voice activity detection interface*/
    MSFilterVoidInterface,/**<Void source/sink interface*/
};
 
/**
 * Interface IDs, used to generate method names (see MS_FILTER_METHOD macro).
 *
**/
typedef enum _MSFilterInterfaceId MSFilterInterfaceId;
 
/**
 * Structure for holding filter's methods to set filter's options.
 * @var MSFilterMethod
 */
typedef struct _MSFilterMethod MSFilterMethod;
/**
 * Filter's category
 *
 */
enum _MSFilterCategory{
    /**others*/
    MS_FILTER_OTHER,
    /**used by encoders*/
    MS_FILTER_ENCODER,
    /**used by decoders*/
    MS_FILTER_DECODER,
    /**used by capture filters that perform encoding*/
    MS_FILTER_ENCODING_CAPTURER,
    /**used by filters that perform decoding and rendering */
    MS_FILTER_DECODER_RENDERER
};
 
/**
 * Structure to describe filter's category.
 * <PRE>
 *     MS_FILTER_OTHER
 *     MS_FILTER_ENCODER
 *     MS_FILTER_DECODER
 *     MS_FILTER_ENCODING_CAPTURER
 *     MS_FILTER_DECODING_RENDERER
 * </PRE>
 * @var MSFilterCategory
 */
typedef enum _MSFilterCategory MSFilterCategory;
 
/**
 * Filter's flags controlling special behaviours.
**/
enum _MSFilterFlags{
    MS_FILTER_IS_PUMP = 1, /**< The filter must be called in process function every tick.*/
    /*...*/
    /*private flags: don't use it in filters.*/
    MS_FILTER_IS_ENABLED = 1<<31 /*<Flag to specify if a filter is enabled or not. Only enabled filters are returned by function ms_filter_get_encoder */
};
 
/**
 * Filter's flags controlling special behaviours.
**/
typedef enum _MSFilterFlags MSFilterFlags;
 
 
struct _MSFilterStats{
    const char *name; /*<filter name*/
    MSUBoxPlot bp_elapsed; /* box plot for elapsed time in filter process in nanoseconds */
};
 
typedef struct _MSFilterStats MSFilterStats;
 
struct _MSFilterDesc{
    MSFilterId id;    /**< the id declared in allfilters.h */
    const char *name; /**< the filter name*/
    const char *text; /**< short text describing the filter's function*/
    MSFilterCategory category; /**< filter's category*/
    const char *enc_fmt; /**< sub-mime of the format, must be set if category is MS_FILTER_ENCODER or MS_FILTER_DECODER */
    int ninputs; /**< number of inputs */
    int noutputs; /**< number of outputs */
    MSFilterFunc init; /**< Filter's init function*/
    MSFilterFunc preprocess; /**< Filter's preprocess function, called one time before starting to process*/
    MSFilterFunc process; /**< Filter's process function, called every tick by the MSTicker to do the filter's job*/
    MSFilterFunc postprocess; /**< Filter's postprocess function, called once after processing (the filter is no longer called in process() after)*/
    MSFilterFunc uninit; /**< Filter's uninit function, used to deallocate internal structures*/
    MSFilterMethod *methods; /**<Filter's method table*/
    unsigned int flags; /**<Filter's special flags, from the MSFilterFlags enum.*/
};
 
/**
 * Structure for filter's description.
 * @var MSFilterDesc
 */
typedef struct _MSFilterDesc MSFilterDesc;
 
struct _MSFilter{
    MSFilterDesc *desc; /**<Back pointer to filter's descriptor.*/
    /*protected attributes, do not move or suppress any of them otherwise plugins will be broken */
    ms_mutex_t lock;
    MSQueue **inputs; /**<Table of input queues.*/
    MSQueue **outputs;/**<Table of output queues */
    struct _MSFactory *factory;/**<the factory that created this filter*/
    void *padding; /**Unused - to be reused later when new protected fields have to added*/
    void *data; /**< Pointer used by the filter for internal state and computations.*/
    struct _MSTicker *ticker; /**<Pointer to the ticker object. It is not NULL when being called process()*/
    /*private attributes, they can be moved and changed at any time*/
    MSList *notify_callbacks;
    uint32_t last_tick;
    MSFilterStats *stats;
    int postponed_task; /*number of postponed tasks*/
    bool_t seen;
};
 
 
/**
 * Structure of filter's object.
 * @var MSFilter
 */
typedef struct _MSFilter MSFilter;
 
struct _MSConnectionPoint{
    MSFilter *filter; /**<Pointer to filter*/
    int pin; /**<Pin index on the filter*/
};
 
/**
 * Structure that represents a connection point of a MSFilter
 * @var MSConnectionPoint
 */
typedef struct _MSConnectionPoint MSConnectionPoint;
 
struct _MSConnectionHelper{
    MSConnectionPoint last;
};
 
/**
 * Structure that holds data when using the ms_connection_helper_* functions.
 * @var MSConnectionHelper
**/
typedef struct _MSConnectionHelper MSConnectionHelper;
 
 
#ifdef __cplusplus
extern "C"{
#endif
 
/**
 * Register a filter description. (plugins use only!)
 *
 * When you build your own plugin, this method will
 * add the encoder or decoder to the internal list
 * of supported codec. Then, this plugin can be used
 * transparently from the application.
 *
 * ms_filter_get_encoder, ms_filter_get_decoder,
 * ms_filter_create_encoder, ms_filter_create_decoder
 * and ms_filter_codec_supported
 * can then be used as if the codec was internally.
 * supported.
 *
 * @param desc    a filter description.
 * @deprecated use ms_factory_register_filter().
 */
MS2_PUBLIC MS2_DEPRECATED void ms_filter_register(MSFilterDesc *desc);
 
 
 
/**
 * Retrieve capture filter that supports encoding to codec name.
 *
 * @param mime    A string indicating the codec.
 *
 * @return a MSFilterDesc if successfull, NULL otherwise.
 * @deprecated use ms_factory_get_encoding_capturer().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilterDesc * ms_filter_get_encoding_capturer(const char *mime);
 
/**
 * Retrieve render filter that supports decoding to codec name.
 *
 * @param mime    A string indicating the codec.
 *
 * @returns a MSFilterDesc if successfull, NULL otherwise.
 * @deprecated use ms_factory_get_decoding_renderer()
 */
MS2_PUBLIC MS2_DEPRECATED MSFilterDesc * ms_filter_get_decoding_renderer(const char *mime);
 
/**
 * Retrieve encoders according to codec name.
 *
 *
 * @param mime    A string indicating the codec.
 *
 * @return a MSFilterDesc if successfull, NULL otherwise.
 * @deprecated use ms_factory_get_encoder().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilterDesc * ms_filter_get_encoder(const char *mime);
 
/**
 * Retrieve decoders according to codec name.
 *
 *
 * @param mime    A string indicating the codec.
 *
 * @return a MSFilterDesc if successfull, NULL otherwise.
 * @deprecated use ms_factory_get_decoder().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilterDesc * ms_filter_get_decoder(const char *mime);
 
/**
 * Lookup a mediastreamer2 filter using its name.
 * If found, the descriptor (MSFilterDesc) is returned.
 * This descriptor can be used to instanciate the filter using ms_filter_new_from_desc()
 * This function can be useful to query the presence of a filter loaded as a plugin, for example.
 *
 * @param filter_name The filter name.
 * @return a MSFilterDesc or NULL if no match.
 * @deprecated use ms_factory_lookup_filter_by_name().
**/
MS2_PUBLIC MS2_DEPRECATED MSFilterDesc *ms_filter_lookup_by_name(const char *filter_name);
 
/**
 * Returns a list of filter descriptions implementing a given interface.
 * The list itself must be freed by the caller of this function, but not the MSFilterDesc pointed by the list elements.
 * @param id a filter interface id
 * @return a newly allocated MSList of #MSFilterDesc.
 * @deprecated use ms_factory_lookup_filter_by_interface().
**/
MS2_PUBLIC MS2_DEPRECATED MSList *ms_filter_lookup_by_interface(MSFilterInterfaceId id);
 
/**
 * Create encoder filter according to codec name.
 
 * @param mime    A string indicating the codec.
 *
 * @return a MSFilter if successfull, NULL otherwise.
 * @deprecated use ms_factory_create_encoder().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilter * ms_filter_create_encoder(const char *mime);
 
/**
 * Create decoder filter according to codec name.
 *
 *
 * @param mime    A string indicating the codec.
 *
 * @return a MSFilter if successfull, NULL otherwise.
 * @deprecated use ms_factory_create_decoder().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilter * ms_filter_create_decoder(const char *mime);
 
/**
 * Check if both an encoder and a decoder filter exists for a codec name.
 *
 * @param mime    A string indicating the codec.
 *
 * @return TRUE if successfull, FALSE otherwise.
 * @deprecated use ms_factory_codec_supported().
 */
MS2_PUBLIC MS2_DEPRECATED bool_t ms_filter_codec_supported(const char *mime);
 
/**
 * Create decoder filter according to a filter's MSFilterId.
 *
 * @param id     A MSFilterId identifier for the filter.
 *
 * @returns a MSFilter if successfull, NULL otherwise.
 * @deprecated use ms_factory_create_filter().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilter *ms_filter_new(MSFilterId id);
 
/**
 * Create decoder filter according to a filter's name.
 *
 * @param name   A name for the filter.
 *
 * @return a MSFilter if successfull, NULL otherwise.
 * @deprecated use ms_factory_create_filter_from_name().
 */
MS2_PUBLIC MS2_DEPRECATED MSFilter *ms_filter_new_from_name(const char *name);
 
/**
 * Create decoder filter according to a filter's description.
 *
 * The primary use is to create your own filter's in your
 * application and avoid registration inside mediastreamer2.
 *
 * @param desc   A MSFilterDesc for the filter.
 *
 * @return a MSFilter if successfull, NULL otherwise.
 * @deprecated use ms_factory_create_filter_from_desc()
 */
MS2_PUBLIC MS2_DEPRECATED MSFilter *ms_filter_new_from_desc(MSFilterDesc *desc);
 
/**
 * Link one OUTPUT pin from a filter to an INPUT pin of another filter.
 *
 * All data coming from the OUTPUT pin of one filter will be distributed
 * to the INPUT pin of the second filter.
 *
 * @param f1   A MSFilter object containing the OUTPUT pin
 * @param pin1 An index of an OUTPUT pin.
 * @param f2   A MSFilter object containing the INPUT pin
 * @param pin2 An index of an INPUT pin.
 *
 * Returns: 0 if sucessful, -1 otherwise.
 */
MS2_PUBLIC int ms_filter_link(MSFilter *f1, int pin1, MSFilter *f2, int pin2);
 
/**
 * Unlink one OUTPUT pin from a filter to an INPUT pin of another filter.
 *
 * @param f1   A MSFilter object containing the OUTPUT pin
 * @param pin1 An index of an OUTPUT pin.
 * @param f2   A MSFilter object containing the INPUT pin
 * @param pin2 An index of an INPUT pin.
 *
 * Returns: 0 if sucessful, -1 otherwise.
 */
MS2_PUBLIC int ms_filter_unlink(MSFilter *f1, int pin1, MSFilter *f2, int pin2);
 
/**
 * Call a filter's method to set or get options.
 *
 * @param f    A MSFilter object.
 * @param id   A private filter ID for the option.
 * @param arg  A private user data for the filter.
 *
 * Returns: 0 if successfull, -1 otherwise.
 */
MS2_PUBLIC int ms_filter_call_method(MSFilter *f, unsigned int id, void *arg);
 
/**
 * Call a filter's method to set options.
 *
 * @param f    A MSFilter object.
 * @param id   A method ID.
 *
 * Returns: 0 if successfull, -1 otherwise.
 */
MS2_PUBLIC int ms_filter_call_method_noarg(MSFilter *f, unsigned int id);
 
 
/**
 * Returns whether the filter implements a given method
 *
 * @param f    A MSFilter object.
 * @param id   A method ID.
 *
 * Returns: TRUE if method is implemented, FALSE otherwise.
 */
MS2_PUBLIC bool_t ms_filter_has_method(MSFilter *f, unsigned int id);
 
/**
 * Returns whether a filter implements a given interface.
 * @param f a MSFilter object
 * @param id an interface id.
 *
 * Returns TRUE if interface is implemented, FALSE, otherwise.
**/
MS2_PUBLIC bool_t ms_filter_implements_interface(MSFilter *f, MSFilterInterfaceId id);
 
/**
 * Returns whether a filter implements a given interface, based on the filter's descriptor.
 * @param f a MSFilter object
 * @param id an interface id.
 *
 * Returns TRUE if interface is implemented, FALSE, otherwise.
**/
MS2_PUBLIC bool_t ms_filter_desc_implements_interface(MSFilterDesc *desc, MSFilterInterfaceId id);
 
 
/**
 * Set a callback on filter's to be informed of private filter's event.
 * This callback is called from the filter's MSTicker, unless a global event queue
 * is created to receive all filter's notification or synchronous flag is TRUE.
 * See ms_event_queue_new() for details.
 *
 * @param f        A MSFilter object.
 * @param fn       A MSFilterNotifyFunc that will be called.
 * @param userdata A pointer to private data.
 * @param synchronous boolean that indicates whether this callback must be called synchronously.
 *
 */
MS2_PUBLIC void ms_filter_add_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata, bool_t synchronous);
 
/**
 * Remove a notify callback previously entered with ms_filter_add_notify_callback()
 *
 * @param f        A MSFilter object.
 * @param fn       A MSFilterNotifyFunc that will be called.
 * @param userdata A pointer to private data.
 *
 */
MS2_PUBLIC void ms_filter_remove_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata);
 
/**
 * Get MSFilterId's filter.
 *
 * @param f        A MSFilter object.
 *
 * Returns: MSFilterId if successfull, -1 otherwise.
 */
MS2_PUBLIC MSFilterId ms_filter_get_id(MSFilter *f);
 
/**
 * Get filter's name.
 * @param[in] f #MSFilter object
 * @return The name of the filter.
 */
MS2_PUBLIC const char * ms_filter_get_name(MSFilter *f);
 
 
/**
 * Obtain the list of current filter's neighbours, ie filters that are part of same graph.
 *
 * Returns: a MSList of MSFilter, that needs to be freed by the caller when no more needed.
**/
MS2_PUBLIC MSList * ms_filter_find_neighbours(MSFilter *me);
 
/**
 * Destroy a filter object.
 *
 * @param f        A MSFilter object.
 *
 */
MS2_PUBLIC void ms_filter_destroy(MSFilter *f);
 
/**
 * Initialize a MSConnectionHelper.
 *
 * @param h A MSConnectionHelper, usually (but not necessarily) on stack
 *
**/
MS2_PUBLIC void ms_connection_helper_start(MSConnectionHelper *h);
 
/**
 * \brief Enter a MSFilter to be connected into the MSConnectionHelper object.
 *
 * This functions enters a MSFilter to be connected into the MSConnectionHelper
 * object and connects it to the last entered if not the first one.
 * The MSConnectionHelper is useful to reduce the amount of code necessary to create graphs in case
 * the connections are made in an ordered manner and some filters are present conditionally in graphs.
 * For example, instead of writing
 * \code
 * ms_filter_link(f1,0,f2,1);
 * ms_filter_link(f2,0,f3,0);
 * ms_filter_link(f3,1,f4,0);
 * \endcode
 * You can write:
 * \code
 * MSConnectionHelper h;
 * ms_connection_helper_start(&h);
 * ms_connection_helper_link(&h,f1,-1,0);
 * ms_connection_helper_link(&h,f2,1,0);
 * ms_connection_helper_link(&h,f3,0,1);
 * ms_connection_helper_link(&h,f4,0,-1);
 * \endcode
 * Which is a bit longer to write here, but now imagine f2 needs to be present in the graph only
 * in certain conditions: in the first case you have rewrite the two first lines, in the second case
 * you just need to replace the fourth line by:
 * \code
 * if (my_condition) ms_connection_helper_link(&h,f2,1,0);
 * \endcode
 *
 * @param h a connection helper
 * @param f a MSFilter
 * @param inpin an input pin number with which the MSFilter needs to connect to previously entered MSFilter
 * @param outpin an output pin number with which the MSFilter needs to be connected to the next entered MSFilter
 *
 * Returns: the return value of ms_filter_link() that is called internally to this function.
**/
MS2_PUBLIC int ms_connection_helper_link(MSConnectionHelper *h, MSFilter *f, int inpin, int outpin);
 
 
/**
 * \brief Enter a MSFilter to be disconnected into the MSConnectionHelper object.
 * Process exactly the same way as ms_connection_helper_link() but calls ms_filter_unlink() on the
 * entered filters.
**/
MS2_PUBLIC int ms_connection_helper_unlink(MSConnectionHelper *h, MSFilter *f, int inpin, int outpin);
 
 
/**
 * \brief Enable processing time measurements statistics for filters.
 *
**/
MS2_PUBLIC MS2_DEPRECATED void ms_filter_enable_statistics(bool_t enabled);
 
 
/**
 * \brief Reset processing time statistics for filters.
 *
**/
MS2_PUBLIC MS2_DEPRECATED void ms_filter_reset_statistics(void);
 
/**
 * \brief Retrieves statistics for running filters.
 * Returns a list of MSFilterStats
**/
MS2_PUBLIC MS2_DEPRECATED const MSList * ms_filter_get_statistics(void);
 
/**
 * \brief Logs runtime statistics for running filters.
 *
**/
MS2_PUBLIC MS2_DEPRECATED void ms_filter_log_statistics(void);
 
 
 
 
/* I define the id taking the lower bits of the address of the MSFilterDesc object,
the method index (_cnt_) and the argument size */
/* I hope using this to avoid type mismatch (calling a method on the wrong filter)*/
#define MS_FILTER_METHOD_ID(_id_,_cnt_,_argsize_) \
    (unsigned int)(((((unsigned int)(_id_)) & 0xFFFF)<<16) | (((unsigned int)(_cnt_))<<8) | (((unsigned int)_argsize_) & 0xFF))
 
/**
 * Macro to create a method id, unique per filter.
 * First argument shall be the filter's ID (MSFilterId) or interface ID (MSFilterInterfaceId).
 * Second argument is the method index within the context of the filter. It should start from 0 and increment for each new method.
 * Third argument is the argument type of the method, for example "int", "float" or any structure.
**/
#define MS_FILTER_METHOD(_id_,_count_,_argtype_) \
    MS_FILTER_METHOD_ID(_id_,_count_,sizeof(_argtype_))
 
/**
 * Same as MS_FILTER_METHOD, but for method that do not take any argument.
**/
#define MS_FILTER_METHOD_NO_ARG(_id_,_count_) \
    MS_FILTER_METHOD_ID(_id_,_count_,0)
 
 
#define MS_FILTER_BASE_METHOD(_count_,_argtype_) \
    MS_FILTER_METHOD_ID(MS_FILTER_BASE_ID,_count_,sizeof(_argtype_))
 
#define MS_FILTER_BASE_METHOD_NO_ARG(_count_) \
    MS_FILTER_METHOD_ID(MS_FILTER_BASE_ID,_count_,0)
 
#define MS_FILTER_EVENT(_id_,_count_,_argtype_) \
    MS_FILTER_METHOD_ID(_id_,_count_,sizeof(_argtype_))
 
#define MS_FILTER_EVENT_NO_ARG(_id_,_count_)\
    MS_FILTER_METHOD_ID(_id_,_count_,0)
 
 
#define MS_FILTER_BASE_EVENT(_count_,_argtype_) \
    MS_FILTER_EVENT(MS_FILTER_BASE_ID,_count_,_argtype_)
 
#define MS_FILTER_BASE_EVENT_NO_ARG(_count_) \
    MS_FILTER_EVENT_NO_ARG(MS_FILTER_BASE_ID,_count_)
 
/**
 *  some MSFilter base generic methods:
 **/
/**
 * Set filter output/input sampling frequency in hertz
 */
#define MS_FILTER_SET_SAMPLE_RATE    MS_FILTER_BASE_METHOD(0,int)
/**
 * Get filter output/input sampling frequency in hertz
 */
 
#define MS_FILTER_GET_SAMPLE_RATE    MS_FILTER_BASE_METHOD(1,int)
/**
 * Set filter output network bitrate in bit per seconds, this value include IP+UDP+RTP overhead
 */
#define MS_FILTER_SET_BITRATE        MS_FILTER_BASE_METHOD(2,int)
/**
 * Get filter output network bitrate in bit per seconds, this value include IP+UDP+RTP overhead
 */
#define MS_FILTER_GET_BITRATE        MS_FILTER_BASE_METHOD(3,int)
#define MS_FILTER_GET_NCHANNELS        MS_FILTER_BASE_METHOD(5,int)
#define MS_FILTER_SET_NCHANNELS        MS_FILTER_BASE_METHOD(6,int)
/**
 * Set codec dependent attributes as taken from the SDP
 */
#define MS_FILTER_ADD_FMTP        MS_FILTER_BASE_METHOD(7,const char)
 
#define MS_FILTER_ADD_ATTR        MS_FILTER_BASE_METHOD(8,const char)
#define MS_FILTER_SET_MTU        MS_FILTER_BASE_METHOD(9,int)
#define MS_FILTER_GET_MTU        MS_FILTER_BASE_METHOD(10,int)
/**Filters can return their latency in milliseconds (if known) using this method:*/
#define MS_FILTER_GET_LATENCY        MS_FILTER_BASE_METHOD(11,int)
 
/**
 * Set device ID
 */
#define MS_FILTER_SET_DEVICE_ID        MS_FILTER_BASE_METHOD(12,int)
/**
 * Get device ID
 */
#define MS_FILTER_GET_DEVICE_ID        MS_FILTER_BASE_METHOD(13,int)
 
 
typedef struct _MSPinFormat{
    uint16_t pin;
    const MSFmtDescriptor *fmt;
}MSPinFormat;
 
/**
 * Obtain the format of a filter on a given input
 */
#define MS_FILTER_GET_INPUT_FMT MS_FILTER_BASE_METHOD(30,MSPinFormat)
/**
 * Set the format of a filter on a given input
 */
#define MS_FILTER_SET_INPUT_FMT MS_FILTER_BASE_METHOD(31,MSPinFormat)
/**
 * Obtain the format of a filter on a given output
 */
#define MS_FILTER_GET_OUTPUT_FMT MS_FILTER_BASE_METHOD(32,MSPinFormat)
/**
 * Set the format of a filter on a given output
 */
#define MS_FILTER_SET_OUTPUT_FMT MS_FILTER_BASE_METHOD(33,MSPinFormat)
 
 
/**
 * MSFilter generic events
**/
#define MS_FILTER_OUTPUT_FMT_CHANGED MS_FILTER_BASE_EVENT_NO_ARG(0) /**<triggered whenever a filter decides to change its output format for one or more more output pins*/
 
/* DEPRECATED  specific methods: to be moved into implementation specific header files - DO NOT USE IN NEW CODE*/
#define MS_FILTER_SET_FILTERLENGTH     MS_FILTER_BASE_METHOD(12,int)
#define MS_FILTER_SET_OUTPUT_SAMPLE_RATE MS_FILTER_BASE_METHOD(13,int)
#define MS_FILTER_ENABLE_DIRECTMODE    MS_FILTER_BASE_METHOD(14,int)
#define MS_FILTER_ENABLE_VAD        MS_FILTER_BASE_METHOD(15,int)
#define MS_FILTER_GET_STAT_DISCARDED    MS_FILTER_BASE_METHOD(16,int)
#define MS_FILTER_GET_STAT_MISSED    MS_FILTER_BASE_METHOD(17,int)
#define MS_FILTER_GET_STAT_INPUT    MS_FILTER_BASE_METHOD(18,int)
#define MS_FILTER_GET_STAT_OUTPUT    MS_FILTER_BASE_METHOD(19,int)
#define MS_FILTER_ENABLE_AGC         MS_FILTER_BASE_METHOD(20,int)
#define MS_FILTER_SET_PLAYBACKDELAY MS_FILTER_BASE_METHOD(21,int)
#define MS_FILTER_ENABLE_HALFDUPLEX MS_FILTER_BASE_METHOD(22,int)
#define MS_FILTER_SET_VAD_PROB_START MS_FILTER_BASE_METHOD(23,int)
#define MS_FILTER_SET_VAD_PROB_CONTINUE MS_FILTER_BASE_METHOD(24,int)
#define MS_FILTER_SET_MAX_GAIN  MS_FILTER_BASE_METHOD(25,int)
#define MS_VIDEO_CAPTURE_SET_AUTOFOCUS MS_FILTER_BASE_METHOD(26,int)
/* pass value of type MSRtpPayloadPickerContext copied by the filter*/
#define MS_FILTER_SET_RTP_PAYLOAD_PICKER MS_FILTER_BASE_METHOD(27,void*)
#define MS_FILTER_SET_OUTPUT_NCHANNELS    MS_FILTER_BASE_METHOD(28,int)
 
 
/** @} */
 
/*protected/ private methods*/
MS2_PUBLIC void ms_filter_process(MSFilter *f);
MS2_PUBLIC void ms_filter_preprocess(MSFilter *f, struct _MSTicker *t);
MS2_PUBLIC void ms_filter_postprocess(MSFilter *f);
MS2_PUBLIC bool_t ms_filter_inputs_have_data(MSFilter *f);
MS2_PUBLIC void ms_filter_notify(MSFilter *f, unsigned int id, void *arg);
MS2_PUBLIC void ms_filter_notify_no_arg(MSFilter *f, unsigned int id);
MS2_PUBLIC void ms_filter_clear_notify_callback(MSFilter *f);
void ms_filter_clean_pending_events(MSFilter *f);
#define ms_filter_lock(f)    ms_mutex_lock(&(f)->lock)
#define ms_filter_unlock(f)    ms_mutex_unlock(&(f)->lock)
MS2_PUBLIC void ms_filter_unregister_all(void);
 
struct _MSFilterTask{
    MSFilter *f;
    MSFilterFunc taskfunc;
};
typedef struct _MSFilterTask MSFilterTask;
MS2_PUBLIC void ms_filter_task_process(MSFilterTask *task);
 
/**
 * Allow a filter to request the ticker to call him the tick after.
 * The ticker will call the taskfunc prior to all filter's process func.
**/
MS2_PUBLIC void ms_filter_postpone_task(MSFilter *f, MSFilterFunc taskfunc);
 
#ifdef __cplusplus
}
#endif
 
#include "mediastreamer2/msinterfaces.h"
#include "mediastreamer2/msfactory.h"
/* used by awk script in Makefile.am to generate alldescs.c */
#define MS_FILTER_DESC_EXPORT(desc)
 
#endif