History

Remove AVFilterGraphDesc struct. Now the parser link the filters from the graph directly with avfilter_link().

Commited in SoC by Vitor Sessak on 2008-03-29 15:12:47 Originally committed as revision 12743 to svn://svn.ffmpeg.org/ffmpeg/trunk

Vitor Sessak committed 18 years ago

Commit 398f1291 parent c4913b81 file · +70 −214Browse files

Showing the changes to libavfilter/avfiltergraph.c (1 of 1 file). Show all

Unified · Split

libavfilter/avfiltergraph.c+70−214
@@ -26,49 +26,6 @@ · 25 unmodified lines
26#include "avfilter.h"26#include "avfilter.h"
27#include "avfiltergraph.h"27#include "avfiltergraph.h"
28 28
29
30/** Linked-list of filters to create for an AVFilterGraphDesc */
31typedef struct AVFilterGraphDescFilter
32{
33 int index; ///< filter instance index
34 char *filter; ///< name of filter type
35 char *args; ///< filter parameters
36 struct AVFilterGraphDescFilter *next;
37} AVFilterGraphDescFilter;
38
39/** Linked-list of links between filters */
40typedef struct AVFilterGraphDescLink
41{
42 /* TODO: allow referencing pads by name, not just by index */
43 int src; ///< index of the source filter
44 unsigned srcpad; ///< index of the output pad on the source filter
45
46 int dst; ///< index of the dest filter
47 unsigned dstpad; ///< index of the input pad on the dest filter
48
49 struct AVFilterGraphDescLink *next;
50} AVFilterGraphDescLink;
51
52/** Linked-list of filter pads to be exported from the graph */
53typedef struct AVFilterGraphDescExport
54{
55 /* TODO: allow referencing pads by name, not just by index */
56 char *name; ///< name of the exported pad
57 int filter; ///< index of the filter
58 unsigned pad; ///< index of the pad to be exported
59
60 struct AVFilterGraphDescExport *next;
61} AVFilterGraphDescExport;
62
63/** Description of a graph to be loaded from a file, etc */
64typedef struct
65{
66 AVFilterGraphDescFilter *filters; ///< filters in the graph
67 AVFilterGraphDescLink *links; ///< links between the filters
68 AVFilterGraphDescExport *inputs; ///< inputs to export
69 AVFilterGraphDescExport *outputs; ///< outputs to export
70} AVFilterGraphDesc;
71
72/**29/**
73 * For use in av_log30 * For use in av_log
74 */31 */
@@ -253,64 +210,6 @@ static int link_filter(AVFilterGraph *ctx, int src, int srcpad, · 178 unmodified lines
253 return 0;210 return 0;
254}211}
255 212
256static int load_from_desc(AVFilterGraph *graph, AVFilterGraphDesc *desc, AVFilterContext *in, int inpad, AVFilterContext *out, int outpad)
257{
258 AVFilterGraphDescExport *curpad;
259 char tmp[20];
260 AVFilterContext *filt;
261 AVFilterGraphDescFilter *curfilt;
262 AVFilterGraphDescLink *curlink;
263
264
265 /* create all filters */
266 for(curfilt = desc->filters; curfilt; curfilt = curfilt->next) {
267 if (create_filter(graph, curfilt->index, curfilt->filter,
268 curfilt->args) < 0)
269 goto fail;
270 }
271
272 /* create all links */
273 for(curlink = desc->links; curlink; curlink = curlink->next) {
274 if (link_filter(graph, curlink->src, curlink->srcpad,
275 curlink->dst, curlink->dstpad) < 0)
276 goto fail;
277 }
278
279 /* export all input pads */
280 for(curpad = desc->inputs; curpad; curpad = curpad->next) {
281 snprintf(tmp, 20, "%d", curpad->filter);
282 if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
283 av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
284 goto fail;
285 }
286 if(avfilter_link(in, inpad, filt, curpad->pad)) {
287 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
288 goto fail;
289 }
290 }
291
292 /* export all output pads */
293 for(curpad = desc->outputs; curpad; curpad = curpad->next) {
294 snprintf(tmp, 20, "%d", curpad->filter);
295 if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
296 av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
297 goto fail;
298 }
299
300 if(avfilter_link(filt, curpad->pad, out, outpad)) {
301 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
302 goto fail;
303 }
304 }
305
306 return 0;
307
308fail:
309 avfilter_destroy_graph(graph);
310 return -1;
311}
312
313
314static void consume_whitespace(const char **buf)213static void consume_whitespace(const char **buf)
315{214{
316 *buf += strspn(*buf, " \n\t");215 *buf += strspn(*buf, " \n\t");
@@ -415,17 +314,19 @@ static void parse_link_name(const char **buf, char **name) · 98 unmodified lines
415 * @arg ars a pointer (that need to be free'd after use) to the args of the314 * @arg ars a pointer (that need to be free'd after use) to the args of the
416 * filter315 * filter
417 */316 */
418static void parse_filter(const char **buf, char **name, char **opts)317static int parse_filter(const char **buf, AVFilterGraph *graph, int index)
419{318{
420 *name = consume_string(buf);319 char *name, *opts;
320 name = consume_string(buf);
421 321
422 if (**buf == '=') {322 if (**buf == '=') {
423 consume_char(buf);323 consume_char(buf);
424 *opts = consume_string(buf);324 opts = consume_string(buf);
425 } else {325 } else {
426 *opts = NULL;326 opts = NULL;
427 }327 }
428 328
329 return create_filter(graph, index, name, opts);
429}330}
430 331
431enum LinkType {332enum LinkType {
@@ -475,82 +376,51 @@ static int parse_inouts(const char **buf, AVFilterInOut **inout, int firstpad, · 43 unmodified lines
475}376}
476 377
477/**378/**
478 * Free a graph description.379 * Parse a string describing a filter graph.
479 */380 */
480static void free_desc(AVFilterGraphDesc *desc)381int avfilter_graph_parse_chain(AVFilterGraph *graph, const char *filters, AVFilterContext *in, int inpad, AVFilterContext *out, int outpad)
481{
482 void *next;
483
484 while(desc->filters) {
485 next = desc->filters->next;
486 av_free(desc->filters->filter);
487 av_free(desc->filters->args);
488 av_free(desc->filters);
489 desc->filters = next;
490 }
491
492 while(desc->links) {
493 next = desc->links->next;
494 av_free(desc->links);
495 desc->links = next;
496 }
497
498 while(desc->inputs) {
499 next = desc->inputs->next;
500 av_free(desc->inputs);
501 desc->inputs = next;
502 }
503
504 while(desc->outputs) {
505 next = desc->outputs->next;
506 av_free(desc->outputs);
507 desc->outputs = next;
508 }
509}
510
511static AVFilterGraphDesc *parse_chain(const char *filters, int has_in)
512{382{
513 AVFilterGraphDesc *ret;
514 AVFilterGraphDescFilter **filterp, *filtern;
515 AVFilterGraphDescLink **linkp, *linkn;
516 AVFilterInOut *inout=NULL;383 AVFilterInOut *inout=NULL;
517 AVFilterInOut *head;384 AVFilterInOut *head=NULL;
518 385
519 int index = 0;386 int index = 0;
520 char chr = 0;387 char chr = 0;
521 int pad = 0;388 int pad = 0;
522 int has_out = 0;389 int has_out = 0;
523 390
391 char tmp[20];
392 AVFilterContext *filt;
393
524 consume_whitespace(&filters);394 consume_whitespace(&filters);
525 395
526 if(!(ret = av_mallocz(sizeof(AVFilterGraphDesc))))396 do {
527 return NULL;397 int oldpad = pad;
528 398
529 filterp = &ret->filters;399 pad = parse_inouts(&filters, &inout, chr == ',', LinkTypeIn, index);
530 linkp = &ret->links;
531 400
532 do {401 if (parse_filter(&filters, graph, index) < 0)
533 if(chr == ',') {402 goto fail;
534 linkn = av_mallocz(sizeof(AVFilterGraphDescLink));403
535 linkn->src = index-1;404 // If the first filter has an input and none was given, it is
536 linkn->srcpad = pad;405 // implicitly the input of the whole graph.
537 linkn->dst = index;406 if (pad == 0 && graph->filters[graph->filter_count-1]->input_count == 1) {
538 linkn->dstpad = 0;407 snprintf(tmp, 20, "%d", index);
539 408 if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
540 *linkp = linkn;409 av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
541 linkp = &linkn->next;410 goto fail;
411 }
412 if(avfilter_link(in, inpad, filt, 0)) {
413 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
414 goto fail;
415 }
542 }416 }
543 pad = parse_inouts(&filters, &inout, chr == ',' || (!has_in),
544 LinkTypeIn, index);
545 417
546 filtern = av_mallocz(sizeof(AVFilterGraphDescFilter));418 if(chr == ',') {
547 filtern->index = index;419 if (link_filter(graph, index-1, oldpad, index, 0) < 0)
548 parse_filter(&filters, &filtern->filter, &filtern->args);420 goto fail;
549 *filterp = filtern;
550 filterp = &filtern->next;
551 421
552 pad = parse_inouts(&filters, &inout, 0,422 }
553 LinkTypeOut, index);423 pad = parse_inouts(&filters, &inout, 0, LinkTypeOut, index);
554 chr = consume_char(&filters);424 chr = consume_char(&filters);
555 index++;425 index++;
556 } while (chr == ',' || chr == ';');426 } while (chr == ',' || chr == ';');
@@ -561,16 +431,28 @@ static AVFilterGraphDesc *parse_chain(const char *filters, int has_in) · 4 unmodified lines
561 continue; // Already processed431 continue; // Already processed
562 432
563 if (!strcmp(inout->name, "in")) {433 if (!strcmp(inout->name, "in")) {
564 if (!has_in)434 snprintf(tmp, 20, "%d", inout->instance);
435 if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
436 av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
437 goto fail;
438 }
439 if(avfilter_link(in, inpad, filt, inout->pad_idx)) {
440 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
565 goto fail;441 goto fail;
566 ret->inputs = av_mallocz(sizeof(AVFilterGraphDescExport));442 }
567 ret->inputs->filter = inout->instance;
568 ret->inputs->pad = inout->pad_idx;
569 } else if (!strcmp(inout->name, "out")) {443 } else if (!strcmp(inout->name, "out")) {
570 has_out = 1;444 has_out = 1;
571 ret->outputs = av_mallocz(sizeof(AVFilterGraphDescExport));445 snprintf(tmp, 20, "%d", inout->instance);
572 ret->outputs->filter = inout->instance;446 if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
573 ret->outputs->pad = inout->pad_idx;447 av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
448 goto fail;
449 }
450
451 if(avfilter_link(filt, inout->pad_idx, out, outpad)) {
452 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
453 goto fail;
454 }
455
574 } else {456 } else {
575 AVFilterInOut *p, *src, *dst;457 AVFilterInOut *p, *src, *dst;
576 for (p = inout->next;458 for (p = inout->next;
@@ -593,15 +475,9 @@ static AVFilterGraphDesc *parse_chain(const char *filters, int has_in) · 16 unmodified lines
593 inout->name);475 inout->name);
594 goto fail;476 goto fail;
595 }477 }
596 linkn = av_mallocz(sizeof(AVFilterGraphDescLink));
597
598 linkn->src = src->instance;
599 linkn->srcpad = src->pad_idx;
600 linkn->dst = dst->instance;
601 linkn->dstpad = dst->pad_idx;
602 478
603 *linkp = linkn;479 if (link_filter(graph, src->instance, src->pad_idx, dst->instance, dst->pad_idx) < 0)
604 linkp = &linkn->next;480 goto fail;
605 481
606 src->instance = -1;482 src->instance = -1;
607 dst->instance = -1;483 dst->instance = -1;
@@ -610,44 +486,24 @@ static AVFilterGraphDesc *parse_chain(const char *filters, int has_in) · 2 unmodified lines
610 486
611 free_inout(head);487 free_inout(head);
612 488
613 if (!has_in) {
614 ret->inputs = av_mallocz(sizeof(AVFilterGraphDescExport));
615 ret->inputs->filter = 0;
616 }
617 if (!has_out) {489 if (!has_out) {
618 ret->outputs = av_mallocz(sizeof(AVFilterGraphDescExport));490 snprintf(tmp, 20, "%d", index-1);
619 ret->outputs->filter = index-1;491 if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
620 }492 av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
621 493 goto fail;
622 return ret;494 }
623
624 fail:
625 free_inout(head);
626
627 free_desc(ret);
628 return NULL;
629}
630
631/**
632 * Parse a string describing a filter graph.
633 */
634int avfilter_graph_parse_chain(AVFilterGraph *graph, const char *filters, AVFilterContext *in, int inpad, AVFilterContext *out, int outpad)
635{
636 AVFilterGraphDesc *desc;
637 495
638 /* Try first to parse supposing there is no (in) element */496 if(avfilter_link(filt, pad, out, outpad)) {
639 if (!(desc = parse_chain(filters, 0))) {497 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
640 /* If it didn't work, parse supposing there is an (in) element */498 goto fail;
641 desc = parse_chain(filters, 1);499 }
642 }
643 if (!desc)
644 return -1;
645 500
646 if (load_from_desc(graph, desc, in, inpad, out, outpad) < 0) {
647 free_desc(desc);
648 return -1;
649 }501 }
650 502
651 free_desc(desc);
652 return 0;503 return 0;
504
505 fail:
506 free_inout(head);
507 avfilter_destroy_graph(graph);
508 return -1;
653}509}

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