• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavfilter/formats.c

Go to the documentation of this file.
00001 /*
00002  * Filter layer - format negotiation
00003  * copyright (c) 2007 Bobby Bingham
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "libavutil/pixdesc.h"
00023 #include "avfilter.h"
00024 
00028 static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
00029 {
00030     int i;
00031 
00032     for(i = 0; i < a->refcount; i ++) {
00033         ret->refs[ret->refcount] = a->refs[i];
00034         *ret->refs[ret->refcount++] = ret;
00035     }
00036 
00037     av_free(a->refs);
00038     av_free(a->formats);
00039     av_free(a);
00040 }
00041 
00042 AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
00043 {
00044     AVFilterFormats *ret;
00045     unsigned i, j, k = 0;
00046 
00047     ret = av_mallocz(sizeof(AVFilterFormats));
00048 
00049     /* merge list of formats */
00050     ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
00051                                                            b->format_count));
00052     for(i = 0; i < a->format_count; i ++)
00053         for(j = 0; j < b->format_count; j ++)
00054             if(a->formats[i] == b->formats[j])
00055                 ret->formats[k++] = a->formats[i];
00056 
00057     ret->format_count = k;
00058     /* check that there was at least one common format */
00059     if(!ret->format_count) {
00060         av_free(ret->formats);
00061         av_free(ret);
00062         return NULL;
00063     }
00064 
00065     ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
00066 
00067     merge_ref(ret, a);
00068     merge_ref(ret, b);
00069 
00070     return ret;
00071 }
00072 
00073 AVFilterFormats *avfilter_make_format_list(const enum PixelFormat *pix_fmts)
00074 {
00075     AVFilterFormats *formats;
00076     int count;
00077 
00078     for (count = 0; pix_fmts[count] != PIX_FMT_NONE; count++)
00079         ;
00080 
00081     formats               = av_mallocz(sizeof(AVFilterFormats));
00082     formats->formats      = av_malloc(sizeof(*formats->formats) * count);
00083     formats->format_count = count;
00084     memcpy(formats->formats, pix_fmts, sizeof(*formats->formats) * count);
00085 
00086     return formats;
00087 }
00088 
00089 int avfilter_add_colorspace(AVFilterFormats **avff, enum PixelFormat pix_fmt)
00090 {
00091     enum PixelFormat *pix_fmts;
00092 
00093     if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats))))
00094         return AVERROR(ENOMEM);
00095 
00096     pix_fmts = av_realloc((*avff)->formats,
00097                           sizeof((*avff)->formats) * ((*avff)->format_count+1));
00098     if (!pix_fmts)
00099         return AVERROR(ENOMEM);
00100 
00101     (*avff)->formats = pix_fmts;
00102     (*avff)->formats[(*avff)->format_count++] = pix_fmt;
00103     return 0;
00104 }
00105 
00106 AVFilterFormats *avfilter_all_colorspaces(void)
00107 {
00108     AVFilterFormats *ret = NULL;
00109     enum PixelFormat pix_fmt;
00110 
00111     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++)
00112         if (!(av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL))
00113             avfilter_add_colorspace(&ret, pix_fmt);
00114 
00115     return ret;
00116 }
00117 
00118 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
00119 {
00120     *ref = f;
00121     f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
00122     f->refs[f->refcount-1] = ref;
00123 }
00124 
00125 static int find_ref_index(AVFilterFormats **ref)
00126 {
00127     int i;
00128     for(i = 0; i < (*ref)->refcount; i ++)
00129         if((*ref)->refs[i] == ref)
00130             return i;
00131     return -1;
00132 }
00133 
00134 void avfilter_formats_unref(AVFilterFormats **ref)
00135 {
00136     int idx;
00137 
00138     if (!*ref)
00139         return;
00140 
00141     idx = find_ref_index(ref);
00142 
00143     if(idx >= 0)
00144         memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
00145             sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
00146 
00147     if(!--(*ref)->refcount) {
00148         av_free((*ref)->formats);
00149         av_free((*ref)->refs);
00150         av_free(*ref);
00151     }
00152     *ref = NULL;
00153 }
00154 
00155 void avfilter_formats_changeref(AVFilterFormats **oldref,
00156                                 AVFilterFormats **newref)
00157 {
00158     int idx = find_ref_index(oldref);
00159 
00160     if(idx >= 0) {
00161         (*oldref)->refs[idx] = newref;
00162         *newref = *oldref;
00163         *oldref = NULL;
00164     }
00165 }
00166 

Generated on Fri Sep 16 2011 17:17:47 for FFmpeg by  doxygen 1.7.1