History

Merge remote-tracking branch 'qatar/master'

* qatar/master: vsrc_buffer: fix check from 7ae7c41. libxvid: Reorder functions to avoid forward declarations; make functions static. libxvid: drop some pointless dead code wmal: vertical alignment cosmetics wmal: Warn about missing bitstream splicing feature and ask for sample. wmal: Skip seekable_frame_in_packet. wmal: Drop unused variable num_possible_block_size. avfiltergraph: make the AVFilterInOut alloc/free API public graphparser: allow specifying sws flags in the graph description. graphparser: fix the order of connecting unlabeled links. graphparser: add avfilter_graph_parse2(). vsrc_buffer: allow using a NULL buffer to signal EOF. swscale: handle last pixel if lines have an odd width. qdm2: fix a dubious pointer cast WMAL: Do not try to read rawpcm coefficients if bits is invalid mov: Fix detecting there is no sync sample. tiffdec: K&R cosmetics avf: has_duration does not check the global one dsputil: fix optimized emu_edge function on Win64. Conflicts: doc/APIchanges libavcodec/libxvid_rc.c libavcodec/libxvidff.c libavcodec/tiff.c libavcodec/wmalosslessdec.c libavfilter/avfiltergraph.h libavfilter/graphparser.c libavfilter/version.h libavfilter/vsrc_buffer.c libswscale/output.c

Michael Niedermayer committed 14 years ago

Commit 7432bcf2 parents 01bf2ad 7bf9e3318 files · +993 −702Browse files

Showing the changes to libavfilter/graphparser.c (1 of 18 files). Show all

Unified · Split

libavfilter/graphparser.c+192−12
@@ -189,13 +189,15 @@ static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links) · 188 unmodified lines
189189 {
190190 AVFilterInOut *ret;
191191
192− while (*links && strcmp((*links)->name, label))
192+ while (*links && (!(*links)->name || strcmp((*links)->name, label)))
193193 links = &((*links)->next);
194194
195195 ret = *links;
196196
197− if (ret)
197+ if (ret) {
198198 *links = ret->next;
199+ ret->next = NULL;
200+ }
199201
200202 return ret;
201203 }
@@ -206,22 +208,31 @@ static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element) · 4 unmodified lines
206208 *inouts = element;
207209 }
208210
211+static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element)
212+{
213+ while (*inouts && (*inouts)->next)
214+ inouts = &((*inouts)->next);
215+
216+ if (!*inouts)
217+ *inouts = *element;
218+ else
219+ (*inouts)->next = *element;
220+ *element = NULL;
221+}
222+
209223 static int link_filter_inouts(AVFilterContext *filt_ctx,
210224 AVFilterInOut **curr_inputs,
211225 AVFilterInOut **open_inputs, void *log_ctx)
212226 {
213− int pad = filt_ctx->input_count, ret;
227+ int pad, ret;
214228
215− while (pad--) {
229+ for (pad = 0; pad < filt_ctx->input_count; pad++) {
216230 AVFilterInOut *p = *curr_inputs;
217− if (!p) {
218− av_log(log_ctx, AV_LOG_ERROR,
219− "Not enough inputs specified for the \"%s\" filter.\n",
220− filt_ctx->filter->name);
221− return AVERROR(EINVAL);
222− }
223231
224− *curr_inputs = (*curr_inputs)->next;
232+ if (p)
233+ *curr_inputs = (*curr_inputs)->next;
234+ else if (!(p = av_mallocz(sizeof(*p))))
235+ return AVERROR(ENOMEM);
225236
226237 if (p->filter_ctx) {
227238 if ((ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx)) < 0)
@@ -258,6 +269,7 @@ static int link_filter_inouts(AVFilterContext *filt_ctx, · 30 unmodified lines
258269 static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
259270 AVFilterInOut **open_outputs, void *log_ctx)
260271 {
272+ AVFilterInOut *parsed_inputs = NULL;
261273 int pad = 0;
262274
263275 while (**buf == '[') {
@@ -280,12 +292,15 @@ static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, · 16 unmodified lines
280292 match->pad_idx = pad;
281293 }
282294
283− insert_inout(curr_inputs, match);
295+ append_inout(&parsed_inputs, &match);
284296
285297 *buf += strspn(*buf, WHITESPACES);
286298 pad++;
287299 }
288300
301+ append_inout(&parsed_inputs, curr_inputs);
302+ *curr_inputs = parsed_inputs;
303+
289304 return pad;
290305 }
291306
@@ -334,10 +349,173 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, · 42 unmodified lines
334349 return pad;
335350 }
336351
352+#if FF_API_GRAPH_AVCLASS
353+#define log_ctx graph
354+#else
355+#define log_ctx NULL
356+#endif
357+
358+static int parse_sws_flags(const char **buf, AVFilterGraph *graph)
359+{
360+ char *p = strchr(*buf, ';');
361+
362+ if (strncmp(*buf, "sws_flags=", 10))
363+ return 0;
364+
365+ if (!p) {
366+ av_log(log_ctx, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n");
367+ return AVERROR(EINVAL);
368+ }
369+
370+ *buf += 4; // keep the 'flags=' part
371+
372+ av_freep(&graph->scale_sws_opts);
373+ if (!(graph->scale_sws_opts = av_mallocz(p - *buf + 1)))
374+ return AVERROR(ENOMEM);
375+ av_strlcpy(graph->scale_sws_opts, *buf, p - *buf + 1);
376+
377+ *buf = p + 1;
378+ return 0;
379+}
380+
381+int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
382+ AVFilterInOut **inputs,
383+ AVFilterInOut **outputs)
384+{
385+ int index = 0, ret = 0;
386+ char chr = 0;
387+
388+ AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL;
389+
390+ filters += strspn(filters, WHITESPACES);
391+
392+ if ((ret = parse_sws_flags(&filters, graph)) < 0)
393+ goto fail;
394+
395+ do {
396+ AVFilterContext *filter;
397+ filters += strspn(filters, WHITESPACES);
398+
399+ if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0)
400+ goto end;
401+
402+ if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0)
403+ goto end;
404+
405+ if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0)
406+ goto end;
407+
408+ if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
409+ log_ctx)) < 0)
410+ goto end;
411+
412+ filters += strspn(filters, WHITESPACES);
413+ chr = *filters++;
414+
415+ if (chr == ';' && curr_inputs)
416+ append_inout(&open_outputs, &curr_inputs);
417+ index++;
418+ } while (chr == ',' || chr == ';');
419+
420+ if (chr) {
421+ av_log(log_ctx, AV_LOG_ERROR,
422+ "Unable to parse graph description substring: \"%s\"\n",
423+ filters - 1);
424+ ret = AVERROR(EINVAL);
425+ goto end;
426+ }
427+
428+ append_inout(&open_outputs, &curr_inputs);
429+
430+
431+ *inputs = open_inputs;
432+ *outputs = open_outputs;
433+ return 0;
434+
435+ fail:end:
436+ for (; graph->filter_count > 0; graph->filter_count--)
437+ avfilter_free(graph->filters[graph->filter_count - 1]);
438+ av_freep(&graph->filters);
439+ avfilter_inout_free(&open_inputs);
440+ avfilter_inout_free(&open_outputs);
441+ avfilter_inout_free(&curr_inputs);
442+
443+ *inputs = NULL;
444+ *outputs = NULL;
445+
446+ return ret;
447+}
448+#undef log_ctx
449+
337450 int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
338451 AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
339452 void *log_ctx)
340453 {
454+#if 0
455+ int ret;
456+ AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL;
457+ AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
458+ AVFilterInOut *cur, *match, *inputs = NULL, *outputs = NULL;
459+
460+ if ((ret = avfilter_graph_parse2(graph, filters, &inputs, &outputs)) < 0)
461+ goto fail;
462+
463+ /* First input can be omitted if it is "[in]" */
464+ if (inputs && !inputs->name)
465+ inputs->name = av_strdup("in");
466+ for (cur = inputs; cur; cur = cur->next) {
467+ if (!cur->name) {
468+ av_log(log_ctx, AV_LOG_ERROR,
469+ "Not enough inputs specified for the \"%s\" filter.\n",
470+ cur->filter_ctx->filter->name);
471+ ret = AVERROR(EINVAL);
472+ goto fail;
473+ }
474+ if (!(match = extract_inout(cur->name, &open_outputs)))
475+ continue;
476+ ret = avfilter_link(match->filter_ctx, match->pad_idx,
477+ cur->filter_ctx, cur->pad_idx);
478+ avfilter_inout_free(&match);
479+ if (ret < 0)
480+ goto fail;
481+ }
482+
483+ /* Last output can be omitted if it is "[out]" */
484+ if (outputs && !outputs->name)
485+ outputs->name = av_strdup("out");
486+ for (cur = outputs; cur; cur = cur->next) {
487+ if (!cur->name) {
488+ av_log(log_ctx, AV_LOG_ERROR,
489+ "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
490+ filters);
491+ ret = AVERROR(EINVAL);
492+ goto fail;
493+ }
494+ if (!(match = extract_inout(cur->name, &open_inputs)))
495+ continue;
496+ ret = avfilter_link(cur->filter_ctx, cur->pad_idx,
497+ match->filter_ctx, match->pad_idx);
498+ avfilter_inout_free(&match);
499+ if (ret < 0)
500+ goto fail;
501+ }
502+
503+ fail:
504+ if (ret < 0) {
505+ for (; graph->filter_count > 0; graph->filter_count--)
506+ avfilter_free(graph->filters[graph->filter_count - 1]);
507+ av_freep(&graph->filters);
508+ }
509+ avfilter_inout_free(&inputs);
510+ avfilter_inout_free(&outputs);
511+ /* clear open_in/outputs only if not passed as parameters */
512+ if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
513+ else avfilter_inout_free(&open_inputs);
514+ if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
515+ else avfilter_inout_free(&open_outputs);
516+ return ret;
517+}
518+#else
341519 int index = 0, ret = 0;
342520 char chr = 0;
343521
@@ -414,3 +592,5 @@ end: · 70 unmodified lines
414592 }
415593 return ret;
416594 }
595+
596+#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t