FFmpeg
bsfgraph.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "config.h"
20 
21 #include <stddef.h>
22 #include <string.h>
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/error.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/opt.h"
28 
29 #include "bsf.h"
30 #include "bsf_internal.h"
31 
32 #define OFFSET(x) offsetof(AVBitStreamFilterGraph, x)
33 #define FLAGS (AV_OPT_FLAG_BSF_PARAM|AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
34 static const AVOption filtergraph_options[] = {
35  {"max_buffered_packets" , "maximum number of buffered packets allowed", OFFSET(max_buffered_packets),
36  AV_OPT_TYPE_UINT, {.i64 = 0}, 0, UINT_MAX, FLAGS },
37  { NULL },
38 };
39 
40 static const AVClass filtergraph_class = {
41  .class_name = "AVBitStreamFilterGraph",
42  .item_name = av_default_item_name,
43  .version = LIBAVUTIL_VERSION_INT,
44  .option = filtergraph_options,
46 };
47 
49 {
50  FFBitStreamFilterGraph *graph = av_mallocz(sizeof(*graph));
52 
53  if (!graph)
54  return NULL;
55 
56  ret = &graph->p;
57  ret->av_class = &filtergraph_class;
59  graph->max_packet_queue = SIZE_MAX;
60 
61  return ret;
62 }
63 
65 {
66  int i, j;
67  for (i = 0; i < graph->nb_filters; i++) {
68  if (graph->filters[i] == filter) {
70  graph->filters[graph->nb_filters - 1]);
71  graph->nb_filters--;
72  filter->graph = NULL;
73  for (j = 0; j<filter->nb_outputs; j++)
74  if (filter->outputs[j])
75  filter->outputs[j]->graph = NULL;
76 
77  return;
78  }
79  }
80 }
81 
83 {
84  int i;
85 
86  for (i = 0; i < graph->nb_filters; i++)
87  if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
88  return graph->filters[i];
89 
90  return NULL;
91 }
92 
94 {
95  AVBitStreamFilterGraph *graph = *graphp;
97 
98  if (!graph)
99  return;
100 
101  while (graph->nb_filters)
102  ff_bsf_free(graph->filters[0]);
103 
104  av_freep(&graphi->sink_links);
105  av_freep(&graphi->source_links);
106 
107  av_opt_free(graph);
108 
109  av_freep(&graph->filters);
110  av_freep(graphp);
111 }
112 
114  const char *name, AVDictionary **options, AVBitStreamFilterGraph *graph_ctx)
115 {
117  int ret;
118 
119  ret = av_bsf_graph_alloc_filter(&s, filt, name, graph_ctx);
120  if (ret < 0)
121  return ret;
122 
124  if (ret < 0)
125  goto fail;
126 
127  if (filt_ctx)
128  *filt_ctx = s;
129 
130  return 0;
131 
132 fail:
133  ff_bsf_free(s);
134  if (filt_ctx)
135  *filt_ctx = NULL;
136  return ret;
137 }
138 
140  const AVBitStreamFilter *filter,
141  const char *name,
142  AVBitStreamFilterGraph *graph)
143 {
145  int ret;
146 
147  if (!ff_bsf(filter)->activate && !ff_bsf(filter)->nb_inputs && !ff_bsf(filter)->nb_outputs)
148  return AVERROR(ENOTSUP);
149 
150  filters = av_realloc_array(graph->filters, graph->nb_filters + 1, sizeof(*filters));
151  if (!filters)
152  return AVERROR(ENOMEM);
153  graph->filters = filters;
154 
155  ret = ff_bsf_alloc(filter, name, &s);
156  if (ret < 0)
157  return ret;
158 
159  graph->filters[graph->nb_filters++] = s;
160 
161  s->graph = graph;
162 
163  if (filt_ctx)
164  *filt_ctx = s;
165 
166  return ret;
167 }
168 
169 /**
170  * Check for the validity of graph.
171  *
172  * A graph is considered valid if all its input and output pads are
173  * connected.
174  *
175  * @return >= 0 in case of success, a negative value otherwise
176  */
177 static int graph_check_validity(AVBitStreamFilterGraph *graph, void *log_ctx)
178 {
180  int i, j;
181 
182  for (i = 0; i < graph->nb_filters; i++) {
183  const AVBitStreamFilterPad *pad;
184  filt = graph->filters[i];
185 
186  for (j = 0; j < filt->nb_inputs; j++) {
187  if (!filt->inputs[j] || !filt->inputs[j]->src) {
188  pad = &filt->input_pads[j];
189  av_log(log_ctx, AV_LOG_ERROR,
190  "Input pad \"%s\" of the filter instance \"%s\" of %s not connected to any source\n",
191  pad->name, filt->name, filt->filter->name);
192  return AVERROR(EINVAL);
193  }
194  }
195 
196  for (j = 0; j < filt->nb_outputs; j++) {
197  if (!filt->outputs[j] || !filt->outputs[j]->dst) {
198  pad = &filt->output_pads[j];
199  av_log(log_ctx, AV_LOG_ERROR,
200  "Output pad \"%s\" of the filter instance \"%s\" of %s not connected to any destination\n",
201  pad->name, filt->name, filt->filter->name);
202  return AVERROR(EINVAL);
203  }
204  }
205  }
206 
207  return 0;
208 }
209 
210 /**
211  * Configure all the links of graphctx.
212  *
213  * @return >= 0 in case of success, a negative value otherwise
214  */
215 static int graph_config_links(AVBitStreamFilterGraph *graph, void *log_ctx)
216 {
218  int i, ret;
219 
220  for (i = 0; i < graph->nb_filters; i++) {
221  filt = graph->filters[i];
222 
223  if (!filt->nb_outputs) {
224  if ((ret = ff_bsf_config_links(filt)))
225  return ret;
226  }
227  }
228 
229  return 0;
230 }
231 
232 static int graph_config_pointers(AVBitStreamFilterGraph *graph, void *log_ctx)
233 {
234  unsigned i, j;
235  int sink_links_count = 0, source_links_count = 0, n = 0;
238 
239  for (i = 0; i < graph->nb_filters; i++) {
240  f = graph->filters[i];
241  for (j = 0; j < f->nb_inputs; j++) {
242  ff_link_internal(f->inputs[j])->age_index = -1;
243  }
244  for (j = 0; j < f->nb_outputs; j++) {
245  ff_link_internal(f->outputs[j])->age_index = -1;
246  }
247  if (!f->nb_outputs) {
248  if (f->nb_inputs > INT_MAX - sink_links_count)
249  return AVERROR(EINVAL);
250  sink_links_count += f->nb_inputs;
251  }
252  if (!f->nb_inputs && !strcmp(f->filter->name, "source")) {
253  if (f->nb_outputs > INT_MAX - source_links_count)
254  return AVERROR(EINVAL);
255  source_links_count += f->nb_outputs;
256  }
257  }
258  sinks = av_calloc(sink_links_count, sizeof(*sinks));
259  if (!sinks)
260  return AVERROR(ENOMEM);
261  for (i = 0; i < graph->nb_filters; i++) {
262  f = graph->filters[i];
263  if (!f->nb_outputs) {
264  for (j = 0; j < f->nb_inputs; j++) {
265  sinks[n] = ff_link_internal(f->inputs[j]);
266  sinks[n]->age_index = n;
267  n++;
268  }
269  }
270  }
271  av_assert0(n == sink_links_count);
272  ffbsffiltergraph(graph)->sink_links = sinks;
273  ffbsffiltergraph(graph)->sink_links_count = sink_links_count;
274 
275  sources = av_calloc(source_links_count, sizeof(*sources));
276  if (!sources)
277  return AVERROR(ENOMEM);
278  for (i = 0, n = 0; i < graph->nb_filters; i++) {
279  f = graph->filters[i];
280  if (!f->nb_inputs && !strcmp(f->filter->name, "source")) {
281  for (j = 0; j < f->nb_outputs; j++) {
282  sources[n] = ff_link_internal(f->outputs[j]);
283  n++;
284  }
285  }
286  }
287  av_assert0(n == source_links_count);
289  ffbsffiltergraph(graph)->source_links_count = source_links_count;
290 
291  return 0;
292 }
293 
294 int av_bsf_graph_config(AVBitStreamFilterGraph *graphctx, void *log_ctx)
295 {
296  int ret;
297 
298  if (graphctx->max_buffered_packets)
300  if ((ret = graph_check_validity(graphctx, log_ctx)))
301  return ret;
302  if ((ret = graph_config_links(graphctx, log_ctx)))
303  return ret;
304  if ((ret = graph_config_pointers(graphctx, log_ctx)))
305  return ret;
306 
307  return 0;
308 }
309 
312 {
314 
315  av_assert0(index >= 0);
316 
317  while (index) {
318  int parent = (index - 1) >> 1;
319  if (links[parent]->l.current_pts_us >= li->l.current_pts_us)
320  break;
321  links[index] = links[parent];
322  links[index]->age_index = index;
323  index = parent;
324  }
325  links[index] = li;
326  li->age_index = index;
327 }
328 
331 {
333 
334  av_assert0(index >= 0);
335 
336  while (1) {
337  int child = 2 * index + 1;
338  if (child >= graph->sink_links_count)
339  break;
340  if (child + 1 < graph->sink_links_count &&
341  links[child + 1]->l.current_pts_us < links[child]->l.current_pts_us)
342  child++;
343  if (li->l.current_pts_us < links[child]->l.current_pts_us)
344  break;
345  links[index] = links[child];
346  links[index]->age_index = index;
347  index = child;
348  }
349  links[index] = li;
350  li->age_index = index;
351 }
352 
354 {
355  FFBitStreamFilterGraph *graphi = ffbsffiltergraph(graph);
356 
357  heap_bubble_up (graphi, li, li->age_index);
358  heap_bubble_down(graphi, li, li->age_index);
359 }
360 
362 {
364  unsigned i;
365 
366  av_assert0(graph->nb_filters);
367  ctxi = ffbsfctx(graph->filters[0]);
368  for (i = 1; i < graph->nb_filters; i++) {
369  FFBitStreamFilterContext *ctxi_other = ffbsfctx(graph->filters[i]);
370 
371  if (ctxi_other->ready > ctxi->ready)
372  ctxi = ctxi_other;
373  }
374 
375  if (!ctxi->ready)
376  return AVERROR(EAGAIN);
377 
378  ctxi->ready = 0;
379 
380  return ff_bsf_activate(&ctxi->p);
381 }
382 
384 {
385  const FFBitStreamFilterGraph *graphi = cffbsffiltergraph(graph);
386  int nb_requests, nb_requests_max = -1;
387  int best_input = AVERROR(EOF);
388 
389  for (int i = 0; i < graphi->source_links_count; i++) {
390  const BitStreamFilterLinkInternal *sourcei = graphi->source_links[i];
391  const AVBitStreamFilterLink *source = &sourcei->l;
392 
393  if (av_bsf_source_get_status(source->src) == AVERROR(EOF))
394  continue;
395 
396  nb_requests = ff_bsf_source_get_nb_failed_requests(source->src);
397  if (nb_requests > nb_requests_max) {
398  nb_requests_max = nb_requests;
399  best_input = i;
400  }
401  }
402 
403  return best_input;
404 }
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
av_opt_set_defaults
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1671
ff_bsf
static const av_always_inline FFBitStreamFilter * ff_bsf(const AVBitStreamFilter *bsf)
Definition: bsf_internal.h:82
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
bsf_internal.h
opt.h
cffbsffiltergraph
static const FFBitStreamFilterGraph * cffbsffiltergraph(const AVBitStreamFilterGraph *graph)
Definition: bsf_internal.h:230
graph_config_links
static int graph_config_links(AVBitStreamFilterGraph *graph, void *log_ctx)
Configure all the links of graphctx.
Definition: bsfgraph.c:215
AVBitStreamFilterPad
A filter pad used for either input or output.
Definition: filters.h:35
FFBitStreamFilterContext::ready
unsigned ready
Ready status of the filter.
Definition: bsf_internal.h:194
FFBitStreamFilterGraph::source_links
struct BitStreamFilterLinkInternal ** source_links
Definition: bsf_internal.h:217
FFBitStreamFilterGraph::sink_links
struct BitStreamFilterLinkInternal ** sink_links
Definition: bsf_internal.h:216
sources
Note except for filters that can have queued frames and sources
Definition: filter_design.txt:286
AVOption
AVOption.
Definition: opt.h:428
heap_bubble_up
static void heap_bubble_up(FFBitStreamFilterGraph *graph, BitStreamFilterLinkInternal *li, int index)
Definition: bsfgraph.c:310
AVBitStreamFilterGraph::nb_filters
unsigned nb_filters
Definition: bsf.h:482
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
AVDictionary
Definition: dict.c:32
bsf.h
heap_bubble_down
static void heap_bubble_down(FFBitStreamFilterGraph *graph, BitStreamFilterLinkInternal *li, int index)
Definition: bsfgraph.c:329
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1942
ff_bsf_free
void ff_bsf_free(AVBitStreamFilterContext *ctx)
Free a filter context.
Definition: bitstreamfilter.c:226
OFFSET
#define OFFSET(x)
Definition: bsfgraph.c:32
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_bsf_graph_create_filter
int av_bsf_graph_create_filter(AVBitStreamFilterContext **filt_ctx, const AVBitStreamFilter *filt, const char *name, AVDictionary **options, AVBitStreamFilterGraph *graph_ctx)
A convenience wrapper that allocates and initializes a filter in a single step.
Definition: bsfgraph.c:113
ff_bsf_config_links
int ff_bsf_config_links(AVBitStreamFilterContext *filter)
Definition: bitstreamfilter.c:452
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
filters
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
Definition: af_crystalizer.c:55
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
AVBitStreamFilterGraph::max_buffered_packets
unsigned max_buffered_packets
Sets the maximum number of buffered packets in the filtergraph combined.
Definition: bsf.h:490
FFBitStreamFilterContext::p
AVBitStreamFilterContext p
The public AVBitStreamFilterContext.
Definition: bsf_internal.h:184
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
fail
#define fail
Definition: test.h:478
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_bsf_graph_source_needs_input
int av_bsf_graph_source_needs_input(const AVBitStreamFilterGraph *graph)
Get the index of the source filter in the filtergraph that reported needing input more urgently.
Definition: bsfgraph.c:383
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
FLAGS
#define FLAGS
Definition: bsfgraph.c:33
ff_bsf_alloc
int ff_bsf_alloc(const AVBitStreamFilter *filter, const char *inst_name, AVBitStreamFilterContext **pctx)
Allocate a new filter context and return it.
Definition: bitstreamfilter.c:54
AVBitStreamFilterGraph::filters
AVBitStreamFilterContext ** filters
Definition: bsf.h:480
activate
filter_frame For filters that do not use the activate() callback
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
options
Definition: swscale.c:50
FFBitStreamFilterGraph::source_links_count
int source_links_count
Definition: bsf_internal.h:219
AV_OPT_TYPE_UINT
@ AV_OPT_TYPE_UINT
Underlying C type is unsigned int.
Definition: opt.h:334
BitStreamFilterLinkInternal::age_index
int age_index
Index in the age array.
Definition: bsf_internal.h:154
av_bsf_graph_alloc
AVBitStreamFilterGraph * av_bsf_graph_alloc(void)
Allocate a filter graph.
Definition: bsfgraph.c:48
index
int index
Definition: gxfenc.c:90
graph_config_pointers
static int graph_config_pointers(AVBitStreamFilterGraph *graph, void *log_ctx)
Definition: bsfgraph.c:232
error.h
AVBitStreamFilterContext::name
char * name
name of this filter instance
Definition: bsf.h:361
source
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a source
Definition: filter_design.txt:256
f
f
Definition: af_crystalizer.c:122
ff_bsf_activate
int ff_bsf_activate(AVBitStreamFilterContext *ctx)
Definition: bitstreamfilter.c:797
ff_link_internal
static BitStreamFilterLinkInternal * ff_link_internal(AVBitStreamFilterLink *link)
Definition: bsf_internal.h:164
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_bsf_graph_alloc_filter
int av_bsf_graph_alloc_filter(AVBitStreamFilterContext **filt_ctx, const AVBitStreamFilter *filter, const char *name, AVBitStreamFilterGraph *graph)
Create a new filter instance in a filter graph.
Definition: bsfgraph.c:139
av_bsf_source_get_status
int av_bsf_source_get_status(AVBitStreamFilterContext *ctx)
Returns 0 or a negative AVERROR code.
Definition: source.c:127
ff_bsf_source_get_nb_failed_requests
unsigned ff_bsf_source_get_nb_failed_requests(const AVBitStreamFilterContext *src)
Get the number of failed requests.
Definition: source.c:161
ff_bsf_graph_update_heap
void ff_bsf_graph_update_heap(AVBitStreamFilterGraph *graph, BitStreamFilterLinkInternal *li)
Definition: bsfgraph.c:353
graph_check_validity
static int graph_check_validity(AVBitStreamFilterGraph *graph, void *log_ctx)
Check for the validity of graph.
Definition: bsfgraph.c:177
FFBitStreamFilterGraph::p
AVBitStreamFilterGraph p
The public AVBitStreamFilterGraph.
Definition: bsf_internal.h:214
av_bsf_graph_config
int av_bsf_graph_config(AVBitStreamFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
Definition: bsfgraph.c:294
filtergraph_options
static const AVOption filtergraph_options[]
Definition: bsfgraph.c:34
s
uint8_t s
Definition: llvidencdsp.c:39
av_bsf_graph_free
void av_bsf_graph_free(AVBitStreamFilterGraph **graphp)
Free a graph, destroy its links, and set *graph to NULL.
Definition: bsfgraph.c:93
filt
static const int8_t filt[NUMTAPS *2]
Definition: af_earwax.c:40
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
FFBitStreamFilterContext
Definition: bsf_internal.h:180
FFBitStreamFilterGraph::max_packet_queue
size_t max_packet_queue
Definition: bsf_internal.h:221
ret
ret
Definition: filter_design.txt:187
links
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output links
Definition: filter_design.txt:14
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
ff_bsf_graph_run_once
int ff_bsf_graph_run_once(AVBitStreamFilterGraph *graph)
Run one round of processing on a filter graph.
Definition: bsfgraph.c:361
AVBitStreamFilter
Definition: bsf.h:111
AVBitStreamFilterPad::name
const char * name
Pad name.
Definition: filters.h:41
FFBitStreamFilterGraph
Definition: bsf_internal.h:210
FFBitStreamFilterGraph::sink_links_count
int sink_links_count
Definition: bsf_internal.h:218
BitStreamFilterLinkInternal
Definition: bsf_internal.h:110
mem.h
av_bsf_init_dict
int av_bsf_init_dict(AVBitStreamFilterContext *ctx, AVDictionary **options)
Initialize a filter with the supplied dictionary of options.
Definition: bitstreamfilter.c:326
AV_CLASS_CATEGORY_BITSTREAM_FILTER
@ AV_CLASS_CATEGORY_BITSTREAM_FILTER
Definition: log.h:37
ff_bsf_graph_remove_filter
void ff_bsf_graph_remove_filter(AVBitStreamFilterGraph *graph, AVBitStreamFilterContext *filter)
Remove a filter from a graph;.
Definition: bsfgraph.c:64
ffbsffiltergraph
static FFBitStreamFilterGraph * ffbsffiltergraph(AVBitStreamFilterGraph *graph)
Definition: bsf_internal.h:225
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
BitStreamFilterLinkInternal::l
AVBitStreamFilterLink l
Definition: bsf_internal.h:111
filtergraph_class
static const AVClass filtergraph_class
Definition: bsfgraph.c:40
AVBitStreamFilterContext
An instance of a filter.
Definition: bsf.h:347
av_bsf_graph_get_filter
AVBitStreamFilterContext * av_bsf_graph_get_filter(AVBitStreamFilterGraph *graph, const char *name)
Get a filter instance identified by instance name from graph.
Definition: bsfgraph.c:82
AVBitStreamFilterGraph
Definition: bsf.h:477
ffbsfctx
static FFBitStreamFilterContext * ffbsfctx(AVBitStreamFilterContext *ctx)
Definition: bsf_internal.h:197