/
filters.h
4949 lines (4199 loc) · 224 KB
/
filters.h
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
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* GPAC - Multimedia Framework C SDK
*
* Authors: Jean Le Feuvre
* Copyright (c) Telecom ParisTech 2017-2024
* All rights reserved
*
* This file is part of GPAC / filters sub-project
*
* GPAC is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GPAC 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _GF_FILTERS_H_
#define _GF_FILTERS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <gpac/tools.h>
#include <gpac/list.h>
#include <gpac/events.h>
#include <gpac/constants.h>
#include <gpac/download.h>
#include <gpac/main.h>
//for offsetof()
#include <stddef.h>
/*!
\file "gpac/filters.h"
\brief Filter management of GPAC.
This file contains all exported functions for filter management of the GPAC framework.
*/
/*!
\addtogroup filters_grp Filter Management
\brief Filter Management of GPAC.
API Documentation of the filter managment system of GPAC.
The filter management in GPAC is built using the following core objects:
- \ref GF_FilterSession in charge of:
- loading filters from register, managing argument parsing and co
- resolving filter graphs to handle PID connection(s)
- tracking data packets and properties exchanged on PIDs
- scheduling tasks between filters
- ensuring thread-safe filter state: a filter may be called from any thread in the session (unless explicitly asked not to), but only by a single thread at any time.
- \ref __gf_filter_register static structure describing possible entry points of the filter, possible arguments and input output PID capabilities.
Each filter share the same API (register definition) regardless of its type: source/sink, mux/demux, encode/decode, raw media processing, encoded media processing, ...
- \ref GF_Filter is an instance of the filter register. A filter implementation typical tasks are:
- accepting new input PIDs (for non source filters)
- defining new output PIDs (for non sink filters), applying any property change due to filter processing
- consuming packets on the input PIDs
- dispatching packets on the output PIDs
- \ref GF_FilterPid handling the connections between two filters.
- PID natively supports fan-out (one filter PID connecting to multiple destinations).
- A PID is in charge of dispatching packets to possible destinations and storing PID properties in sync with dispatched packets.
- Whenever PID properties change, the next packet sent on that PID is associated with the new state, and the destination filter(s) will be called
upon fetching the new packet. This is the one of the two reentrant code of a filter, the other one being the \ref GF_FEVT_INFO_UPDATE event.
- When blocking mode is not disabled at the session filter, a PID is also in charge of managing its occupancy through either a number of packets or the
cumulated duration of the packets it is holding.
- Whenever a PID holds too much data, it enters a blocking state. A filter with ALL its output PIDs in a blocked state won't be scheduled
for processing. This is a semi-blocking design, which imply that if a filter has one of its PIDs in a non blocking state, it will be scheduled for processing. If a PID has multiple destinations and one of the destination consumes faster than the other one, the filter is currently not blocking (this might change in the near future).
- A PID is in charge of managing the packet references across filters, by performing memory management of allocated data packets
(avoid alloc/free at each packet but rather recycle the memory) and tracking shared packets references.
- \ref GF_FilterPacket holding data to dispatch from a filter on a given PID.
- Packets are always associated to a single output PID, ie it is not possible for a filter to send one packet to multiple PIDs, the data has to be cloned.
- Packets have default attributes such as timestamps, size, random access status, start/end frame, etc, as well as optional properties.
- All packets are reference counted.
- A packet can hold allocated block on the output PID, a pointer to some filter internal data, a data reference to a single input packet, or a frame interface object used for accessing data or OpenGL textures of the emitting filter.
Packets holding data references rather than copy are notified back to their creators upon destruction.
- \ref __gf_prop_val holding various properties for a PID or a packet
- Properties can be copied/merged between input and output PIDs, or input and output packets. These properties are reference counted.
- Two kinds of properties are defined, built-in ones which use a 32 bit identifier (usually a four character code), and user properties identified by a string.
- PID properties are defined by the filter creating the PID. They can be overridden/added after being set by the filter by specifying fragment properties
in the filter arguments. For example \code fin=src=myfile.foo:#FEXT=bar \endcode will override the file extension property (FEXT) foo to bar AFTER the PID is being defined.
- \ref __gf_filter_event used to pass various events (play/stop/buffer requirements/...) up and down the filter chain.
This part of the API will likely change in the future, being merged with the global GF_Event of GPAC.
GPAC comes with a set of built-in filters in libgpac. It is also possible to define external filters in dynamic libraries. GPAC will look for such libraries
in default module folder and folders listed in GPAC config file section core, key mod-dirs. The files SHALL be named gf_* and export a function called RegisterFilter
with the following prototype:
\param fsess is set to NULL unless meta filters are listed, in which case the filter register should list all possible meta filters it supports
\return a GF_FilterRegister structure used for instantiating the filter.
\code const GF_FilterRegister *RegisterFilter(GF_FilterSession *fsess);\endcode
*/
/*! \hideinitializer
A packet byte offset is set to this value when not valid
*/
#define GF_FILTER_NO_BO 0xFFFFFFFFFFFFFFFFUL
/*! \hideinitializer
A packet timestamp (Decoding or Composition) is set to this value when not valid
*/
#define GF_FILTER_NO_TS 0xFFFFFFFFFFFFFFFFUL
/*! \hideinitializer
Filter Session object
*/
typedef struct __gf_filter_session GF_FilterSession;
/*! \hideinitializer
Filter object
*/
typedef struct __gf_filter GF_Filter;
/*! \hideinitializer
Filter PID object
*/
typedef struct __gf_filter_pid GF_FilterPid;
/*! \hideinitializer
Filter Packet object
*/
typedef struct __gf_filter_pck GF_FilterPacket;
/*!
Filter Packet destructor function prototype
*/
typedef void (*gf_fsess_packet_destructor)(GF_Filter *filter, GF_FilterPid *PID, GF_FilterPacket *pck);
/*!
Filter Event object
*/
typedef union __gf_filter_event GF_FilterEvent;
/*!
Filter Session Task object
*/
typedef struct __gf_fs_task GF_FSTask;
/*!
Filter Register object
*/
typedef struct __gf_filter_register GF_FilterRegister;
/*!
Filter Property object
*/
typedef struct __gf_prop_val GF_PropertyValue;
/*!
Filter Property Reference object, used for info query only
*/
typedef struct __gf_prop_entry GF_PropertyEntry;
/*!
\addtogroup fs_grp Filter Session
\ingroup filters_grp
\brief Filter Session
The GPAC filter session object allows building media pipelines using multiple sources and destinations and arbitrary filter chains.
Filters are described through a \ref __gf_filter_register structure. A set of built-in filters are available, and user-defined filters can be added or removed at runtime.
The filter session keeps an internal graph representation of all available filters and their possible input connections, which is used when resolving connections between filters.
The number of \ref GF_FilterCapability matched between registries defines the weight of the connection.
Paths from an instantiated filter are enabled/disabled based on the source PID capabilities.
Paths to destination are recomputed for each destination, based on the instantiated destination filter capabilities.
The graph edges are then enabled in the possible subgraphs allowed by the destination capabilities, and unused filter registries (without enabled input connections) are removed from the graph.
The resulting weighted graph is then solved using Dijkstra's algorithm, using filter priority in case of weight equality.
The filter session works by default in a semi-blocking state. Whenever output PID buffers on a filter are all full, the filter is marked as blocked and not scheduled for processing. Whenever one output PID buffer is not full, the filter unblocks.
This implies that PID buffers may grow quite large if a filter is consuming data from a PID at a much faster rate than another filter consuming from that same PID.
* @{
*/
/*! Filter session scheduler type */
typedef enum
{
/*! In this mode, the scheduler does not use locks for packet and property queues. Main task list is mutex-protected */
GF_FS_SCHEDULER_LOCK_FREE=0,
/*! In this mode, the scheduler uses locks for packet and property queues. Defaults to lock-free if no threads are used. Main task list is mutex-protected */
GF_FS_SCHEDULER_LOCK,
/*! In this mode, the scheduler does not use locks for packet and property queues, nor for the main task list */
GF_FS_SCHEDULER_LOCK_FREE_X,
/*! In this mode, the scheduler uses locks for packet and property queues even if single-threaded (test mode) */
GF_FS_SCHEDULER_LOCK_FORCE,
/*! In this mode, the scheduler uses direct dispatch and no threads, trying to nest task calls within task calls */
GF_FS_SCHEDULER_DIRECT
} GF_FilterSchedulerType;
/*! Filter session flags */
typedef enum
{
/*! Flag set to indicate meta filters should be loaded. A meta filter is a filter providing various sub-filters.
The sub-filters are usually not exposed as filters, only the parent one is.
When set, all sub-filters are exposed. This should only be set when inspecting filters help*/
GF_FS_FLAG_LOAD_META = 1<<1,
/*! Flag set to run session in non-blocking mode. Each call to \ref gf_fs_run will return as soon as there are no more pending tasks on the main thread */
GF_FS_FLAG_NON_BLOCKING = 1<<2,
/*! Flag set to disable internal caching of filter graph connections. If disabled, the graph will be recomputed at each link resolution (less memory occupancy but slower)*/
GF_FS_FLAG_NO_GRAPH_CACHE = 1<<3,
/*! Flag set to disable session regulation (no sleep)*/
GF_FS_FLAG_NO_REGULATION = 1<<4,
/*! Flag set to disable data probe*/
GF_FS_FLAG_NO_PROBE = 1<<5,
/*! Flag set to disable source reassignment (e.g. switching from fin to ffdmx) in PID resolution*/
GF_FS_FLAG_NO_REASSIGN = 1<<6,
/*! Flag set to print enabled/disabled edges for debug of PID resolution*/
GF_FS_FLAG_PRINT_CONNECTIONS = 1<<7,
/*! Flag set to disable argument checking*/
GF_FS_FLAG_NO_ARG_CHECK = 1<<8,
/*! Disables reservoir for packets and properties, uses much less memory but much more alloc/free*/
GF_FS_FLAG_NO_RESERVOIR = 1<<9,
/*! Throws an error if any PID in the filter graph cannot be linked. The default behavior is to run the session even when some PIDs are not connected*/
GF_FS_FLAG_FULL_LINK = 1<<10,
/*! Flag set to disable implicit linking
By default the session runs in implicit linking when no link directives are set on any filter: linking aborts after the first successful pid if destination is not a sink, or links only to sinks otherwise.
\note This implies that the order in which filters are added to the session matters
*/
GF_FS_FLAG_NO_IMPLICIT = 1<<11,
/*! Flag set to force all filters to require a source ID (same as setting RSID option on all filters). This is typically used when the app sets links on all used filters while declaring more, unused filters.
*/
GF_FS_FLAG_REQUIRE_SOURCE_ID = 1<<12,
/*! Flag set to force all explicitly added filters to be loaded in deferred link state - linking will only happen once \ref gf_filter_reconnect_output is called on the filter.
*/
GF_FS_FLAG_FORCE_DEFER_LINK = 1<<13,
/*! Flag set to ignore all PLAY events from sinks - use \ref gf_fs_send_deferred_play to start playback
*/
GF_FS_FLAG_PREVENT_PLAY = 1<<14
} GF_FilterSessionFlags;
/*! Creates a new filter session. This will also load all available filter registers not blacklisted.
\param nb_threads number of extra threads to allocate. A negative value means all core used by session (eg nb_cores-1 extra threads)
\param type scheduler type
\param flags set of above flags for the session. Modes set by flags cannot be changed at runtime
\param blacklist string containing comma-separated names of filters to disable. If first character is '-', this describes a whitelist, i.e. only filters listed in this string will be allowed
\return the created filter session
*/
GF_FilterSession *gf_fs_new(s32 nb_threads, GF_FilterSchedulerType type, GF_FilterSessionFlags flags, const char *blacklist);
/*! Creates a new filter session, loading parameters from gpac config. This will also load all available filter registers not blacklisted.
\param flags set of flags for the session. Only \ref GF_FS_FLAG_LOAD_META, \ref GF_FS_FLAG_NON_BLOCKING , \ref GF_FS_FLAG_NO_GRAPH_CACHE and \ref GF_FS_FLAG_PRINT_CONNECTIONS are used, other flags are set from config file or command line
\return the created filter session
*/
GF_FilterSession *gf_fs_new_defaults(GF_FilterSessionFlags flags);
/*! Destructs the filter session
\param session the filter session to destruct
*/
void gf_fs_del(GF_FilterSession *session);
/*! Loads a given filter by its register name. Filter are created using their register name, with options appended as a list of colon-separated Name=Value pairs.
Value can be omitted for boolean, defaulting to true (eg :allt). Using '!' before the name negates the result (eg :!moof_first).
Name can be omitted for enumerations (eg :disp=pbo is equivalent to :pbo), provided that filter developers pay attention to not reuse enum names in one filter.
Options are either options for the target filter class, options to be inherited between the new filter and its implicit source(s) or implici destination(s), or generic filter options.
Generic filter options are:
- FID: filter identifier (string value)
- SID: filter source(s) (string value)
- N=NAME: filter name (string value)
- FS: sub-session identifier (unsigned int value)
- RSID: require sourceID to be present on target filters (no value)
- TAG: filter tag (string value)
- ITAG: filter inherited tag (string value)
- FBT: buffer time in microseconds (unsigned int value)
- FBU: buffer units (unsigned int value)
- FBD: decode buffer time in microseconds (unsigned int value)
- clone: explicitly enable/disable filter cloning flag (no value)
- nomux: enable/disable direct file copy (no value)
- gfreg: preferred filter registry names for link solving (string value)
- gfloc: following options are local to filter declaration, not inherited (no value)
- gfopt: following options are not tracked (no value)
- gpac: argument separator for URLs (no value)
- ccp: filter replacement control (string list value)
- NCID: ID of netcap configuration to use (string)
- DBG: debug missing input PID property (`=pid`), missing input packet property (`=pck`) or both (`=all`)
- DL: enable defer linking of filter (no value) - the filter output pids will not be connected until a call to \ref gf_filter_reconnect_output
\param session filter session
\param name name and arguments of the filter register to instantiate.
\param err_code set to error code if any - may be NULL. If initially set to GF_EOS, disables log messages.
\return created filter or NULL if filter register cannot be found
*/
GF_Filter *gf_fs_load_filter(GF_FilterSession *session, const char *name, GF_Err *err_code);
/*! Checks if a filter register exists by name.
\param session filter session
\param name name of the filter register to check.
\return GF_TRUE if a filter register exists with the given name, GF_FALSE otherwise
*/
Bool gf_fs_filter_exists(GF_FilterSession *session, const char *name);
/*! Runs the session
If the session is non-blocking (created with \ref GF_FS_FLAG_NON_BLOCKING), process all tasks of oldest scheduled filter, process any pending PID connections and returns.
Otherwise (session is blocking), runs until session is over or aborted.
\param session filter session
\return error if any, or GF_EOS. The last errors can be retrieved using \ref gf_fs_get_last_connect_error and \ref gf_fs_get_last_process_error
*/
GF_Err gf_fs_run(GF_FilterSession *session);
/*! The default separator set used*/
#define GF_FS_DEFAULT_SEPS ":=#,!@"
/*! Sets the set of separators to use when parsing args
\param session filter session
\param separator_set filter session.
The first char is used to separate argument names - default is ':'
The second char, if present, is used to separate names and values - default is '='
The third char, if present, is used to separate fragments for PID sources - default is '#'
The fourth char, if present, is used for list separators (sourceIDs, gfreg, ...) - default is ','
The fifth char, if present, is used for boolean negation - default is '!'
The sixth char, if present, is used for LINK directives - default is '@'
\return error if any
*/
GF_Err gf_fs_set_separators(GF_FilterSession *session, const char *separator_set);
/*! Sets the maximum length of a filter chain dynamically loaded to solve connection between two filters
\param session filter session
\param max_chain_length sets maximum chain length when resolving filter links.
Default value is 6 ([ in -> ] demux -> reframe -> decode -> encode -> reframe -> mux [ -> out ])
(filter chains loaded for adaptation (eg pixel format change, audio resample) are loaded after the link resolution)
Setting the value to 0 disables dynamic link resolution. You will have to specify the entire chain manually
\return error if any
*/
GF_Err gf_fs_set_max_resolution_chain_length(GF_FilterSession *session, u32 max_chain_length);
/*! Sets the maximum sleep time when postponing tasks.
\param session filter session
\param max_sleep maximum sleep time in milliseconds. 0 means yield only.
\return error if any
*/
GF_Err gf_fs_set_max_sleep_time(GF_FilterSession *session, u32 max_sleep);
/*! gets the maximum filter chain lengtG
\param session filter session
\return maximum chain length when resolving filter links.
*/
u32 gf_fs_get_max_resolution_chain_length(GF_FilterSession *session);
/*! Stops the session, waiting for all additional threads to complete
\param session filter session
\return error if any
*/
GF_Err gf_fs_stop(GF_FilterSession *session);
/*! Gets the number of available filter registries (not blacklisted)
\param session filter session
\return number of filter registries
*/
u32 gf_fs_filters_registers_count(GF_FilterSession *session);
/*! Returns the register at the given index
\param session filter session
\param idx index of register, from 0 to \ref gf_fs_filters_registers_count
\return the register object, or NULL if index is out of bounds
*/
const GF_FilterRegister *gf_fs_get_filter_register(GF_FilterSession *session, u32 idx);
/*! Registers the test filters used for unit tests
\param session filter session
*/
void gf_fs_register_test_filters(GF_FilterSession *session);
/*! Loads a source filter from a URL and arguments
\param session filter session
\param url URL of the source to load. Can be a local file name, a full path (/.., \\...) or a full URL with scheme (eg http://, tcp://)
\param args arguments for the filter, see \ref gf_fs_load_filter - the arguments can also be set in the url, typycally using `:gpac:` option delimiter
\param parent_url parent URL of the source, or NULL if none
\param err if not NULL, is set to error code if any
\return the filter loaded or NULL if error
*/
GF_Filter *gf_fs_load_source(GF_FilterSession *session, const char *url, const char *args, const char *parent_url, GF_Err *err);
/*! Loads a destination filter from a URL and arguments
\param session filter session
\param url URL of the source to load. Can be a local file name, a full path (/.., \\...) or a full URL with scheme (eg http://, tcp://)
\param args arguments for the filter, see \ref gf_fs_load_filter - the arguments can also be set in the url, typycally using `:gpac:` option delimiter
\param parent_url parent URL of the source, or NULL if none
\param err if not NULL, is set to error code if any
\return the filter loaded or NULL if error
*/
GF_Filter *gf_fs_load_destination(GF_FilterSession *session, const char *url, const char *args, const char *parent_url, GF_Err *err);
/*! Returns the last error which happened during a PID connection
\param session filter session
\return the error code if any
*/
GF_Err gf_fs_get_last_connect_error(GF_FilterSession *session);
/*! Returns the last error which happened during a filter process
\param session filter session
\return the error code if any
*/
GF_Err gf_fs_get_last_process_error(GF_FilterSession *session);
/*! Adds a user-defined register to the session - the register is added regardless of the session blacklist
\param session filter session
\param freg filter register to add
*/
void gf_fs_add_filter_register(GF_FilterSession *session, const GF_FilterRegister *freg);
/*! Removes a user-defined register from the session
\param session filter session
\param freg filter register to remove
*/
void gf_fs_remove_filter_register(GF_FilterSession *session, GF_FilterRegister *freg);
/*! Sends PLAY event on all sinks, ignored if GF_FS_FLAG_PREVENT_PLAY flag is not set
\param session filter session
*/
void gf_fs_send_deferred_play(GF_FilterSession *session);
/*! Posts a user task to the session
\param session filter session
\param task_execute the callback function for the task. The callback can return:
- GF_FALSE to cancel the task
- GF_TRUE to reschedule the task, in which case the task will be rescheduled immediately or after reschedule_ms.
\param udta_callback callback user data passed back to the task_execute function
\param log_name log name of the task. If NULL, default is "user_task"
\return the error code if any
*/
GF_Err gf_fs_post_user_task(GF_FilterSession *session, Bool (*task_execute) (GF_FilterSession *fsess, void *callback, u32 *reschedule_ms), void *udta_callback, const char *log_name);
/*! Posts a user task to the session main thread only
\param session filter session
\param task_execute the callback function for the task. The callback can return:
- GF_FALSE to cancel the task
- GF_TRUE to reschedule the task, in which case the task will be rescheduled immediately or after reschedule_ms.
\param udta_callback callback user data passed back to the task_execute function
\param log_name log name of the task. If NULL, default is "user_task"
\return the error code if any
*/
GF_Err gf_fs_post_user_task_main(GF_FilterSession *session, Bool (*task_execute) (GF_FilterSession *fsess, void *callback, u32 *reschedule_ms), void *udta_callback, const char *log_name);
/*! Session flush types*/
typedef enum
{
/*! Do not flush session: everything is discarded, potentially breaking output files*/
GF_FS_FLUSH_NONE=0,
/*! Flush all pending data before closing sessions: sources will be forced into end of stream and all emitted packets will be processed*/
GF_FS_FLUSH_ALL,
/*! Stop session (resetting buffers) and flush pipeline*/
GF_FS_FLUSH_FAST
} GF_FSFlushType;
/*! Aborts the session. This can be called within a callback task to stop the session. Do NOT use \ref gf_fs_stop from within a user task callback, this will deadlock the session
\param session filter session
\param flush_type flush method to use
\return the error code if any
*/
GF_Err gf_fs_abort(GF_FilterSession *session, GF_FSFlushType flush_type);
/*! Checks if the session is processing its last task. This can be called within a callback task to check if this is the last task, in order to avoid rescheduling the task
\param session filter session
\return GF_TRUE if no more task, GF_FALSE otherwise
*/
Bool gf_fs_is_last_task(GF_FilterSession *session);
/*! Checks if the session is in its final flush state (shutdown)
\param session filter session
\return GF_TRUE if no session is aborting, GF_FALSE otherwise
*/
Bool gf_fs_in_final_flush(GF_FilterSession *session);
/*! Checks if a given MIME type is supported as input
\param session filter session
\param mime MIME type to query
\return GF_TRUE if MIME is supported
*/
Bool gf_fs_is_supported_mime(GF_FilterSession *session, const char *mime);
/*! Sets UI callback event
\param session filter session
\param ui_event_proc the event proc callback function. Its return value depends on the event type, usually 0
\param cbk_udta pointer passed back to callback
*/
void gf_fs_set_ui_callback(GF_FilterSession *session, Bool (*ui_event_proc)(void *opaque, GF_Event *event), void *cbk_udta);
/*! Prints stats to logs using \code LOG_APP@LOG_INFO \endcode
\param session filter session
*/
void gf_fs_print_stats(GF_FilterSession *session);
/*! Prints connections between loaded filters in the session to logs using \code LOG_APP@LOG_INFO \endcode
\param session filter session
*/
void gf_fs_print_connections(GF_FilterSession *session);
/*! Prints the list of filters not connected using \code LOG_APP@LOG_WARNING \endcode
\param session filter session
*/
void gf_fs_print_non_connected(GF_FilterSession *session);
/*! Prints the list of filters not connected using \code LOG_APP@LOG_WARNING \endcode
\param session filter session
\param ignore_sinks if set, do not warn if some sinks are not connected (mostly used for playback cases)
*/
void gf_fs_print_non_connected_ex(GF_FilterSession *session, Bool ignore_sinks);
/*! Prints the list of arguments specified but not used by the filter session using \code LOG_APP@LOG_WARNING \endcode
\note This is simply a wrapper to \ref gf_fs_enum_unmapped_options
\param session filter session
\param ignore_args ignore unused arguments if present in this comma-separated list - may be NULL
*/
void gf_fs_print_unused_args(GF_FilterSession *session, const char *ignore_args);
/*! Prints all possible connections between filter registries to logs using \code LOG_APP@LOG_INFO \endcode
\param session filter session
\param filter_name if not null, only prints input connection for this filter register
\param print_fn optional callback function for print, otherwise print to stderr
*/
void gf_fs_print_all_connections(GF_FilterSession *session, char *filter_name, void (*print_fn)(FILE *output, GF_SysPrintArgFlags flags, const char *fmt, ...) );
/*! Checks the presence of an input capability and an output capability in a target register. The caps are matched only if they belong to the same bundle.
\param filter_reg filter register to check
\param in_cap_code capability code (property type) of input capability to check
\param in_cap capabiility value of input capability to check
\param out_cap_code capability code (property type) of output capability to check
\param out_cap capability value of output capability to check
\param exact_match_only if true returns TRUE only if exact match (code and value), otherwise return TRUE if caps code are matched
\return GF_TRUE if filter register has such a match, GF_FALSE otherwise
*/
Bool gf_fs_check_filter_register_cap(const GF_FilterRegister *filter_reg, u32 in_cap_code, GF_PropertyValue *in_cap, u32 out_cap_code, GF_PropertyValue *out_cap, Bool exact_match_only);
/*! Enables or disables filter reporting
\param session filter session
\param reporting_on if GF_TRUE, reporting will be enabled
*/
void gf_fs_enable_reporting(GF_FilterSession *session, Bool reporting_on);
/*! Locks global session mutex - mostly used to query filter reports and avoids concurrent destruction of a filter.
When adding a filter in an already running session, the session must be locked if set_source is to be used.
\param session filter session
\param do_lock if GF_TRUE, session is locked, otherwise session is unlocked
*/
void gf_fs_lock_filters(GF_FilterSession *session, Bool do_lock);
/*! Gets number of active filters in the session
\param session filter session
\return number of active filters
*/
u32 gf_fs_get_filters_count(GF_FilterSession *session);
/*! Gets a filter by its current index in the session
\param session filter session
\param idx index in the filter session
\return filter, or NULL if none found
*/
GF_Filter *gf_fs_get_filter(GF_FilterSession *session, u32 idx);
/*! Type of filter*/
typedef enum
{
/*! Generic filter type accepting input(s) and producing output(s)*/
GF_FS_STATS_FILTER_GENERIC,
/*! raw input (file, socket, pipe) filter type*/
GF_FS_STATS_FILTER_RAWIN,
/*! demultiplexer filter type*/
GF_FS_STATS_FILTER_DEMUX,
/*! decoder filter type*/
GF_FS_STATS_FILTER_DECODE,
/*! encoder filter type*/
GF_FS_STATS_FILTER_ENCODE,
/*! multiplexer filter type*/
GF_FS_STATS_FILTER_MUX,
/*! raw output (file, socket, pipe) filter type*/
GF_FS_STATS_FILTER_RAWOUT,
/*! media sink (video out, audio out, ...) filter type*/
GF_FS_STATS_FILTER_MEDIA_SINK,
/*! media source (capture audio or video ...) filter type*/
GF_FS_STATS_FILTER_MEDIA_SOURCE,
} GF_FSFilterType;
/*! Filter statistics object*/
typedef struct
{
/*!filter object*/
const GF_Filter *filter;
/*!set if filter is only an alias, in which case all remaining fields of the structure are not set*/
const GF_Filter *filter_alias;
/*!number of tasks executed by this filter*/
u64 nb_tasks_done;
/*!number of packets processed by this filter*/
u64 nb_pck_processed;
/*!number of bytes processed by this filter*/
u64 nb_bytes_processed;
/*!number of packets sent by this filter*/
u64 nb_pck_sent;
/*!number of hardware frames packets sent by this filter*/
u64 nb_hw_pck_sent;
/*!number of processing errors in the lifetime of the filter*/
u32 nb_errors;
/*!number of bytes sent by this filter*/
u64 nb_bytes_sent;
/*!number of microseconds this filter was active*/
u64 time_process;
/*!percentage of data processed (between 0 and 100), otherwise unknown (-1)*/
s32 percent;
/*!last status report from filter, null if session reporting is not enabled*/
const char *status;
/*!set to GF_TRUE of status or percent changed since last query for this filter, GF_FALSE otherwise*/
Bool report_updated;
/*!filter name*/
const char *name;
/*!filter register name*/
const char *reg_name;
/*!filter register ID*/
const char *filter_id;
/*!set to GF_TRUE if filter is done processing*/
Bool done;
/*!number of input PIDs*/
u32 nb_pid_in;
/*!number of input packets processed*/
u64 nb_in_pck;
/*!number of output PIDs*/
u32 nb_pid_out;
/*!number of output packets sent*/
u64 nb_out_pck;
/*!set to GF_TRUE if filter has seen end of stream*/
Bool in_eos;
/*!set to the filter class type*/
GF_FSFilterType type;
/*!set to streamtype of output PID if single output, GF_STREAM_UNKNOWN otherwise*/
u32 stream_type;
/*!set to codecid of output PID if single output, GF_CODECID_NONE otherwise*/
u32 codecid;
/*! timestamp and timescale of last packet emitted on output pids*/
GF_Fraction64 last_ts_sent;
/*! timestamp and timescale of last packet dropped on input pids*/
GF_Fraction64 last_ts_drop;
} GF_FilterStats;
/*! Gets statistics for a given filter index in the session
\param session filter session
\param idx index of filter to query
\param stats statistics for filter
\return error code if any
*/
GF_Err gf_fs_get_filter_stats(GF_FilterSession *session, u32 idx, GF_FilterStats *stats);
/*! Enumerates filter and meta-filter arguments not matched in the session. All output parameters may be NULL.
\param session filter session
\param idx index of argument to query, 0 being first argument; this value is automatically incremented
\param argname set to argument name
\param argtype set to argument type: 0 was a filter param (eg :arg=val), 1 was a global arg (eg --arg=val) and 2 was a global meta arg (eg -+arg=val)
\param meta_name set to meta filter name if any (for local filter args only)
\param meta_opt set to meta filter suboption name if any (for local filter args only)
\return GF_TRUE if success, GF_FALSE if nothing more to enumerate
*/
Bool gf_fs_enum_unmapped_options(GF_FilterSession *session, u32 *idx, const char **argname, u32 *argtype, const char **meta_name, const char **meta_opt);
/*! Flags for argument update event*/
typedef enum
{
/*! the update event can be sent down the source chain*/
GF_FILTER_UPDATE_DOWNSTREAM = 1,
/*! the update event can be sent up the filter chain*/
GF_FILTER_UPDATE_UPSTREAM = 1<<1,
} GF_EventPropagateType;
/*! Enumerates filter and meta-filter arguments not matched in the session
\param session filter session
\param fid ID of filter on which to send the update, NULL if filter is set
\param filter filter on which to send the update, NULL if fid is set
\param name name of filter option to update
\param val value of filter option to update
\param propagate_mask propagation flags - 0 means no propagation
*/
void gf_fs_send_update(GF_FilterSession *session, const char *fid, GF_Filter *filter, const char *name, const char *val, GF_EventPropagateType propagate_mask);
/*! Loads JS script for filter session
\param session filter session
\param jsfile path to local JS script file to use
\return error if any
*/
GF_Err gf_fs_load_script(GF_FilterSession *session, const char *jsfile);
/*! get max download rate allowed by download manager
\param session filter session
\return max rate in bps
*/
u32 gf_fs_get_http_max_rate(GF_FilterSession *session);
/*! set max download rate allowed by download manager
\param session filter session
\param rate max rate in bps
\return error if any
*/
GF_Err gf_fs_set_http_max_rate(GF_FilterSession *session, u32 rate);
/*! get current download rate of download manager, all active resources together
\param session filter session
\return current rate in bps
*/
u32 gf_fs_get_http_rate(GF_FilterSession *session);
/*! check if a URL is likely to be supported
\param session filter session
\param url the URL to test
\param parent_url the parent URL
\return GF_TRUE if a filter for such a source could be loaded
*/
Bool gf_fs_is_supported_source(GF_FilterSession *session, const char *url, const char *parent_url);
/*! callback functions for external monitoring of filter creation or destruction
\param udta user data passed back to callback
\param filter created or destroyed filter
\param is_destroy if GF_TRUE, the filter is being destroyed, otherwise it is being created
*/
typedef void (*gf_fs_on_filter_creation)(void *udta, GF_Filter *filter, Bool is_destroy);
/*! assign callbacks for filter creation and destruction monitoring
\param session filter session
\param on_create_destroy filter creation/destruction callback, may be NULL
\param udta user data for callbacks, may be NULL
\param force_sync execute tasks involving filter creation/setup and user tasks on main thread
\return error if any
*/
GF_Err gf_fs_set_filter_creation_callback(GF_FilterSession *session, gf_fs_on_filter_creation on_create_destroy, void *udta, Bool force_sync);
/*! returns RT user data passed in \ref gf_fs_set_filter_creation_callback
\param session filter session
\return udta user data, NULL if error or none
*/
void *gf_fs_get_rt_udta(GF_FilterSession *session);
/*! Checks if a filter is still valid - typically used when not monitoring filter destruction at session level using \ref gf_fs_set_filter_creation_callback
\param session filter session
\param filter filter to check
\return GF_TRUE if filter is still valid until the next call to \ref gf_fs_run, GF_FALSE otherwise
*/
Bool gf_fs_check_filter(GF_FilterSession *session, GF_Filter *filter);
/*! Fires an event on filter
\param session filter session
\param filter target filter - if NULL, event will be executed on all filters. Otherwise, the event will be executed directly if its type is \ref GF_FEVT_USER, and fired otherwise
\param evt event to fire
\param upstream if true, send event toward sinks, otherwise towards sources
\return GF_TRUE if event was sent, GF_FALSE otherwise
*/
Bool gf_fs_fire_event(GF_FilterSession *session, GF_Filter *filter, GF_FilterEvent *evt, Bool upstream);
/*! callback functions for external monitoring of filter creation or destruction
\param udta user data passed back to callback
\param do_activate if true context must be activated for calling thread, otherwise context is no longer used
\return error if any
*/
typedef GF_Err (*gf_fs_gl_activate)(void *udta, Bool do_activate);
/*! assign callbacks for filter creation and destruction monitoring
\param session filter session
\param on_gl_activate openGL context activation callback, must not be NULL
\param udta user data for callbacks, may be NULL
\return error if any
*/
GF_Err gf_fs_set_external_gl_provider(GF_FilterSession *session, gf_fs_gl_activate on_gl_activate, void *udta);
/*! Flags for debug info*/
typedef enum
{
/*! print filter graph*/
GF_FS_DEBUG_GRAPH = 1,
/*! print filter stats*/
GF_FS_DEBUG_STATS = 1<<1,
/*! print tasks present in scheduler*/
GF_FS_DEBUG_TASKS = 1<<2,
/*! print filter status and task scheduled on filter*/
GF_FS_DEBUG_FILTERS = 1<<3,
/*! print all info*/
GF_FS_DEBUG_ALL = 0x00FFFFFF,
/*! enable continuous reporting*/
GF_FS_DEBUG_CONTINUOUS = 0x80000000,
} GF_SessionDebugFlag;
/*! prints session debug info on stderr
To turn on (resp.off) continous reporting, set (resp. unset) the flag GF_FS_DEBUG_CONTINUOUS. Continuous reporting is done in the main thread using the last flags provided
\param session filter session
\param dbg_flags set of flags indicating what to print
*/
void gf_fs_print_debug_info(GF_FilterSession *session, GF_SessionDebugFlag dbg_flags);
/*! @} */
/*!
\addtogroup fs_props Filter Properties
\ingroup filters_grp
\brief PID and filter properties
Documents the property object used for PID and packets.
@{
*/
/*! Property types*/
//DO NOT MODIFY WITHOUT APPLYNG SIMILAR CHANGE TO share/python/libgpac.py
//DO NOT CHANGE A VALUE ASSIGNMENT WITHOUT CHANGING GF_GSF_VERSION
typedef enum
{
/*! not allowed*/
GF_PROP_FORBIDDEN = 0,
/*! signed 32 bit integer*/
GF_PROP_SINT = 1,
/*! unsigned 32 bit integer*/
GF_PROP_UINT = 2,
/*! signed 64 bit integer*/
GF_PROP_LSINT = 3,
/*! unsigned 64 bit integer*/
GF_PROP_LUINT = 4,
/*! boolean*/
GF_PROP_BOOL = 5,
/*! 32 bit / 32 bit fraction*/
GF_PROP_FRACTION = 6,
/*! 64 bit / 64 bit fraction*/
GF_PROP_FRACTION64 = 7,
/*! float (Fixed) number*/
GF_PROP_FLOAT = 8,
/*! double number*/
GF_PROP_DOUBLE = 9,
/*! 2D signed integer vector*/
GF_PROP_VEC2I = 10,
/*! 2D double number vector*/
GF_PROP_VEC2 = 11,
/*! 3D signed integer vector*/
GF_PROP_VEC3I = 12,
/*! 4D signed integer vector*/
GF_PROP_VEC4I = 13,
/*! string property, memory is duplicated when setting the property and managed internally*/
GF_PROP_STRING = 14,
/*! string property, memory is NOT duplicated when setting the property but is then managed (and free) internally.
Only used when setting a property, the type then defaults to GF_PROP_STRING
DO NOT USE the associate string field upon return from setting the property, it might have been destroyed*/
GF_PROP_STRING_NO_COPY= 15,
/*! data property, memory is duplicated when setting the property and managed internally*/
GF_PROP_DATA = 16,
/*! const string property, memory is NOT duplicated when setting the property, stays user-managed*/
GF_PROP_NAME = 17,
/*! data property, memory is NOT duplicated when setting the property but is then managed (and free) internally.
Only used when setting a property, the type then defaults to GF_PROP_DATA
DO NOT USE the associate data field upon return from setting the property, it might have been destroyed*/
GF_PROP_DATA_NO_COPY= 18,
/*! const data property, memory is NOT duplicated when setting the property, stays user-managed*/
GF_PROP_CONST_DATA = 19,
/*! user-managed pointer*/
GF_PROP_POINTER = 20,
/*! string list, memory is NOT duplicated when setting the property, the passed array is directly assigned to the new property and will be and managed internally (freed by the filter session)
DO NOT USE the associate string array field upon return from setting the property, it might have been destroyed*/
GF_PROP_STRING_LIST = 21,
/*! unsigned 32 bit integer list, memory is ALWAYS duplicated when setting the property*/
GF_PROP_UINT_LIST = 22,
/*! signed 32 bit integer list, memory is ALWAYS duplicated when setting the property*/
GF_PROP_SINT_LIST = 23,
/*! 2D signed integer vector list, memory is ALWAYS duplicated when setting the property*/
GF_PROP_VEC2I_LIST = 24,
/*! 4CC on unsigned 32 bit integer*/
GF_PROP_4CC = 25,
/*! 4CC list on unsigned 32 bit integer, memory is ALWAYS duplicated when setting the property*/
GF_PROP_4CC_LIST = 26,
/*! string list, memory is duplicated when setting the property - to use only with property assignment functions*/
GF_PROP_STRING_LIST_COPY = 27,
/*! last non-enum property*/
GF_PROP_LAST_NON_ENUM,
/*! All constants are defined after this - constants are stored as u32*/
GF_PROP_FIRST_ENUM = 40, //GSF will code prop type using vlen, try to keep all values between 1 and 127 to only use 1 byte
/*! Video Pixel format*/
GF_PROP_PIXFMT = GF_PROP_FIRST_ENUM,
/*! Audio PCM format*/
GF_PROP_PCMFMT = GF_PROP_FIRST_ENUM+1,
/*! CICP Color Primaries*/
GF_PROP_CICP_COL_PRIM = GF_PROP_FIRST_ENUM+2,
/*! CICP Color Transfer Characteristics*/
GF_PROP_CICP_COL_TFC = GF_PROP_FIRST_ENUM+3,
/*! CICP Color Matrix*/
GF_PROP_CICP_COL_MX = GF_PROP_FIRST_ENUM+4,
/*! CICP Layout*/
GF_PROP_CICP_LAYOUT = GF_PROP_FIRST_ENUM+5,
/*! not allowed*/
GF_PROP_LAST_DEFINED
} GF_PropType;
/*! GSF version (coded on 8 bits in gsf format) */
#define GF_GSF_VERSION 2
/*! Data property*/
typedef struct
{
/*! data pointer */
u8 *ptr;
/*! data size */
u32 size;
} GF_PropData;
/*! 2D signed integer vector property*/
typedef struct
{
/*! x coord */
s32 x;
/*! y coord */
s32 y;
} GF_PropVec2i;
/*! 2D double number vector property*/
typedef struct
{
/*! x coord */
Double x;
/*! y coord */
Double y;
} GF_PropVec2;
/*! 3D signed integer vector property*/
typedef struct
{
/*! x coord */
s32 x;
/*! y coord */
s32 y;
/*! z coord */
s32 z;
} GF_PropVec3i;
/*! 4D signed integer vector property*/
typedef struct
{
/*! x coord */
s32 x;
/*! y coord */
s32 y;
/*! z coord */
s32 z;
/*! w coord */
s32 w;
} GF_PropVec4i;
/*! List of strings property - do not change field order !*/
typedef struct
{
/*! array of unsigned integers */
char **vals;
/*! number of items in array */
u32 nb_items;
} GF_PropStringList;
/*! List of unsigned int property - do not change field order !*/
typedef struct
{
/*! array of unsigned integers */
u32 *vals;
/*! number of items in array */
u32 nb_items;
} GF_PropUIntList;
/*! List of signed int property - do not change field order !*/
typedef struct
{
/*! array of signed integers */
s32 *vals;
/*! number of items in array */
u32 nb_items;
} GF_PropIntList;
/*! List of unsigned int property*/