Statistics
| Branch: | Revision:

ffmpeg / libavfilter / formats.c @ a1e3e4ba

History | View | Annotate | Download (3.73 KB)

1
/*
2
 * Filter layer - format negotiation
3
 * copyright (c) 2007 Bobby Bingham
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
#include "avfilter.h"
23

    
24
/** merge and update all the references */
25
static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
26
{
27
    int i;
28

    
29
    for(i = 0; i < a->refcount; i ++) {
30
        ret->refs[ret->refcount] = a->refs[i];
31
        *ret->refs[ret->refcount++] = ret;
32
    }
33

    
34
    av_free(a->refs);
35
    av_free(a->formats);
36
    av_free(a);
37
}
38

    
39
AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
40
{
41
    AVFilterFormats *ret;
42
    unsigned i, j, k = 0;
43

    
44
    ret = av_mallocz(sizeof(AVFilterFormats));
45

    
46
    /* merge list of formats */
47
    ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
48
                                                           b->format_count));
49
    for(i = 0; i < a->format_count; i ++)
50
        for(j = 0; j < b->format_count; j ++)
51
            if(a->formats[i] == b->formats[j])
52
                ret->formats[k++] = a->formats[i];
53

    
54
    ret->format_count = k;
55
    /* check that there was at least one common format */
56
    if(!ret->format_count) {
57
        av_free(ret->formats);
58
        av_free(ret);
59
        return NULL;
60
    }
61

    
62
    ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
63

    
64
    merge_ref(ret, a);
65
    merge_ref(ret, b);
66

    
67
    return ret;
68
}
69

    
70
AVFilterFormats *avfilter_make_format_list(int len, ...)
71
{
72
    AVFilterFormats *ret;
73
    int i;
74
    va_list vl;
75

    
76
    ret = av_mallocz(sizeof(AVFilterFormats));
77
    ret->formats = av_malloc(sizeof(*ret->formats) * len);
78
    ret->format_count = len;
79

    
80
    va_start(vl, len);
81
    for(i = 0; i < len; i ++)
82
        ret->formats[i] = va_arg(vl, int);
83
    va_end(vl);
84

    
85
    return ret;
86
}
87

    
88
AVFilterFormats *avfilter_all_colorspaces(void)
89
{
90
    AVFilterFormats *ret;
91
    int i;
92

    
93
    ret = av_mallocz(sizeof(AVFilterFormats));
94
    ret->formats = av_malloc(sizeof(*ret->formats) * PIX_FMT_NB);
95
    ret->format_count = PIX_FMT_NB;
96

    
97
    for(i = 0; i < PIX_FMT_NB; i ++)
98
        ret->formats[i] = i;
99

    
100
    return ret;
101
}
102

    
103
void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
104
{
105
    *ref = f;
106
    f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
107
    f->refs[f->refcount-1] = ref;
108
}
109

    
110
static int find_ref_index(AVFilterFormats **ref)
111
{
112
    int i;
113
    for(i = 0; i < (*ref)->refcount; i ++)
114
        if((*ref)->refs[i] == ref)
115
            return i;
116
    return -1;
117
}
118

    
119
void avfilter_formats_unref(AVFilterFormats **ref)
120
{
121
    int idx = find_ref_index(ref);
122

    
123
    if(idx >= 0)
124
        memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
125
            sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
126

    
127
    if(!--(*ref)->refcount) {
128
        av_free((*ref)->formats);
129
        av_free((*ref)->refs);
130
        av_free(*ref);
131
    }
132
    *ref = NULL;
133
}
134

    
135
void avfilter_formats_changeref(AVFilterFormats **oldref,
136
                                AVFilterFormats **newref)
137
{
138
    int idx = find_ref_index(oldref);
139

    
140
    if(idx >= 0) {
141
        (*oldref)->refs[idx] = newref;
142
        *newref = *oldref;
143
        *oldref = NULL;
144
    }
145
}
146