avfiltergraph.c 3.53 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Filter graphs
 * copyright (c) 2007 Bobby Bingham
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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.1 of the License, or (at your option) any later version.
 *
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

22 23 24
#include <string.h>
#include <stddef.h>

25
#include "avstring.h"
26 27 28 29 30 31 32 33 34 35 36 37 38
#include "avfilter.h"
#include "avfiltergraph.h"

struct AVFilterGraph {
    unsigned filter_count;
    AVFilterContext **filters;
};

AVFilterGraph *avfilter_create_graph(void)
{
    return av_mallocz(sizeof(AVFilterGraph));
}

39
static void destroy_graph_filters(AVFilterGraph *graph)
40
{
41 42
    for(; graph->filter_count > 0; graph->filter_count --)
        avfilter_destroy(graph->filters[graph->filter_count - 1]);
43 44 45 46 47 48
    av_freep(&graph->filters);
}

void avfilter_destroy_graph(AVFilterGraph *graph)
{
    destroy_graph_filters(graph);
49 50 51 52 53 54 55 56 57 58
    av_free(graph);
}

void avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
{
    graph->filters = av_realloc(graph->filters,
                                sizeof(AVFilterContext*) * ++graph->filter_count);
    graph->filters[graph->filter_count - 1] = filter;
}

59
static AVFilterContext *create_filter_with_args(const char *filt, void *opaque)
60 61
{
    AVFilterContext *ret;
62
    char *filter = av_strdup(filt); /* copy - don't mangle the input string */
63 64 65 66 67 68
    char *name, *args;

    name = filter;
    if((args = strchr(filter, '='))) {
        /* ensure we at least have a name */
        if(args == filter)
69
            goto fail;
70 71 72 73 74 75 76 77

        *args ++ = 0;
    }

    av_log(NULL, AV_LOG_INFO, "creating filter \"%s\" with args \"%s\"\n",
           name, args ? args : "(none)");

    if((ret = avfilter_create_by_name(name, NULL))) {
78
        if(avfilter_init_filter(ret, args, opaque)) {
79 80
            av_log(NULL, AV_LOG_ERROR, "error initializing filter!\n");
            avfilter_destroy(ret);
81
            goto fail;
82 83 84 85
        }
    } else av_log(NULL, AV_LOG_ERROR, "error creating filter!\n");

    return ret;
86 87 88 89

fail:
    av_free(filter);
    return NULL;
90 91 92
}

int avfilter_graph_load_chain(AVFilterGraph *graph,
93
                              unsigned count, char **filter_list, void **opaque,
94 95 96 97 98 99
                              AVFilterContext **first, AVFilterContext **last)
{
    unsigned i;
    AVFilterContext *filters[2] = {NULL,NULL};

    for(i = 0; i < count; i ++) {
100 101 102 103 104 105
        void *op;

        if(opaque) op = opaque[i];
        else       op = NULL;

        if(!(filters[1] = create_filter_with_args(filter_list[i], op)))
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
            goto fail;
        if(i == 0) {
            if(first) *first = filters[1];
        } else {
            if(avfilter_link(filters[0], 0, filters[1], 0)) {
                av_log(NULL, AV_LOG_ERROR, "error linking filters!\n");
                goto fail;
            }
        }
        avfilter_graph_add_filter(graph, filters[1]);
        filters[0] = filters[1];
    }

    if(last) *last = filters[1];
    return 0;

fail:
    destroy_graph_filters(graph);
Vitor Sessak's avatar
Vitor Sessak committed
124 125
    if(first) *first = NULL;
    if(last)  *last  = NULL;
126 127 128
    return -1;
}