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
189{189{
190 AVFilterInOut *ret;190 AVFilterInOut *ret;
191 191
192 while (*links && strcmp((*links)->name, label))192 while (*links && (!(*links)->name || strcmp((*links)->name, label)))
193 links = &((*links)->next);193 links = &((*links)->next);
194 194
195 ret = *links;195 ret = *links;
196 196
197 if (ret)197 if (ret) {
198 *links = ret->next;198 *links = ret->next;
199 ret->next = NULL;
200 }
199 201
200 return ret;202 return ret;
201}203}
@@ -206,22 +208,31 @@ static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element) · 4 unmodified lines
206 *inouts = element;208 *inouts = element;
207}209}
208 210
211static 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
209static int link_filter_inouts(AVFilterContext *filt_ctx,223static int link_filter_inouts(AVFilterContext *filt_ctx,
210 AVFilterInOut **curr_inputs,224 AVFilterInOut **curr_inputs,
211 AVFilterInOut **open_inputs, void *log_ctx)225 AVFilterInOut **open_inputs, void *log_ctx)
212{226{
213 int pad = filt_ctx->input_count, ret;227 int pad, ret;
214 228
215 while (pad--) {229 for (pad = 0; pad < filt_ctx->input_count; pad++) {
216 AVFilterInOut *p = *curr_inputs;230 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 }
223 231
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);
225 236
226 if (p->filter_ctx) {237 if (p->filter_ctx) {
227 if ((ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx)) < 0)238 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
258static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,269static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
259 AVFilterInOut **open_outputs, void *log_ctx)270 AVFilterInOut **open_outputs, void *log_ctx)
260{271{
272 AVFilterInOut *parsed_inputs = NULL;
261 int pad = 0;273 int pad = 0;
262 274
263 while (**buf == '[') {275 while (**buf == '[') {
@@ -280,12 +292,15 @@ static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, · 16 unmodified lines
280 match->pad_idx = pad;292 match->pad_idx = pad;
281 }293 }
282 294
283 insert_inout(curr_inputs, match);295 append_inout(&parsed_inputs, &match);
284 296
285 *buf += strspn(*buf, WHITESPACES);297 *buf += strspn(*buf, WHITESPACES);
286 pad++;298 pad++;
287 }299 }
288 300
301 append_inout(&parsed_inputs, curr_inputs);
302 *curr_inputs = parsed_inputs;
303
289 return pad;304 return pad;
290}305}
291 306
@@ -334,10 +349,173 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, · 42 unmodified lines
334 return pad;349 return pad;
335}350}
336 351
352#if FF_API_GRAPH_AVCLASS
353#define log_ctx graph
354#else
355#define log_ctx NULL
356#endif
357
358static 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
381int 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
337int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,450int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
338 AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,451 AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
339 void *log_ctx)452 void *log_ctx)
340{453{
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
341 int index = 0, ret = 0;519 int index = 0, ret = 0;
342 char chr = 0;520 char chr = 0;
343 521
@@ -414,3 +592,5 @@ end: · 70 unmodified lines
414 }592 }
415 return ret;593 return ret;
416}594}
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