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

libavfilter/defaults.c

Go to the documentation of this file.
00001 /*
00002  * Filter layer - default implementations
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/audioconvert.h"
00023 #include "libavutil/imgutils.h"
00024 #include "libavutil/samplefmt.h"
00025 #include "avfilter.h"
00026 #include "internal.h"
00027 
00028 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
00029 {
00030     av_free(ptr->data[0]);
00031     av_free(ptr);
00032 }
00033 
00034 /* TODO: set the buffer's priv member to a context structure for the whole
00035  * filter chain.  This will allow for a buffer pool instead of the constant
00036  * alloc & free cycle currently implemented. */
00037 AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
00038 {
00039     int linesize[4];
00040     uint8_t *data[4];
00041     int i;
00042     AVFilterBufferRef *picref = NULL;
00043     AVFilterPool *pool = link->pool;
00044 
00045     if (pool) {
00046         for (i = 0; i < POOL_SIZE; i++) {
00047             picref = pool->pic[i];
00048             if (picref && picref->buf->format == link->format && picref->buf->w == w && picref->buf->h == h) {
00049                 AVFilterBuffer *pic = picref->buf;
00050                 pool->pic[i] = NULL;
00051                 pool->count--;
00052                 picref->video->w = w;
00053                 picref->video->h = h;
00054                 picref->perms = perms | AV_PERM_READ;
00055                 picref->format = link->format;
00056                 pic->refcount = 1;
00057                 memcpy(picref->data,     pic->data,     sizeof(picref->data));
00058                 memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
00059                 return picref;
00060             }
00061         }
00062     } else
00063         pool = link->pool = av_mallocz(sizeof(AVFilterPool));
00064 
00065     // align: +2 is needed for swscaler, +16 to be SIMD-friendly
00066     if ((i = av_image_alloc(data, linesize, w, h, link->format, 16)) < 0)
00067         return NULL;
00068 
00069     picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
00070                                                        perms, w, h, link->format);
00071     if (!picref) {
00072         av_free(data[0]);
00073         return NULL;
00074     }
00075     memset(data[0], 128, i);
00076 
00077     picref->buf->priv = pool;
00078     picref->buf->free = NULL;
00079 
00080     return picref;
00081 }
00082 
00083 AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
00084                                                      enum AVSampleFormat sample_fmt, int nb_samples,
00085                                                      int64_t channel_layout, int planar)
00086 {
00087     AVFilterBufferRef *samplesref = NULL;
00088     int linesize[8];
00089     uint8_t *data[8];
00090     int nb_channels = av_get_channel_layout_nb_channels(channel_layout);
00091 
00092     /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */
00093     if (av_samples_alloc(data, linesize,
00094                          nb_channels, nb_samples, sample_fmt,
00095                          planar, 16) < 0)
00096         return NULL;
00097 
00098     samplesref =
00099         avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,
00100                                                   nb_samples, sample_fmt,
00101                                                   channel_layout, planar);
00102     if (!samplesref) {
00103         av_free(data[0]);
00104         return NULL;
00105     }
00106 
00107     return samplesref;
00108 }
00109 
00110 void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
00111 {
00112     AVFilterLink *outlink = NULL;
00113 
00114     if (inlink->dst->output_count)
00115         outlink = inlink->dst->outputs[0];
00116 
00117     if (outlink) {
00118         outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
00119         avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
00120         avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
00121     }
00122 }
00123 
00124 void avfilter_default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
00125 {
00126     AVFilterLink *outlink = NULL;
00127 
00128     if (inlink->dst->output_count)
00129         outlink = inlink->dst->outputs[0];
00130 
00131     if (outlink)
00132         avfilter_draw_slice(outlink, y, h, slice_dir);
00133 }
00134 
00135 void avfilter_default_end_frame(AVFilterLink *inlink)
00136 {
00137     AVFilterLink *outlink = NULL;
00138 
00139     if (inlink->dst->output_count)
00140         outlink = inlink->dst->outputs[0];
00141 
00142     avfilter_unref_buffer(inlink->cur_buf);
00143     inlink->cur_buf = NULL;
00144 
00145     if (outlink) {
00146         if (outlink->out_buf) {
00147             avfilter_unref_buffer(outlink->out_buf);
00148             outlink->out_buf = NULL;
00149         }
00150         avfilter_end_frame(outlink);
00151     }
00152 }
00153 
00154 /* FIXME: samplesref is same as link->cur_buf. Need to consider removing the redundant parameter. */
00155 void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
00156 {
00157     AVFilterLink *outlink = NULL;
00158 
00159     if (inlink->dst->output_count)
00160         outlink = inlink->dst->outputs[0];
00161 
00162     if (outlink) {
00163         outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format,
00164                                                              samplesref->audio->nb_samples,
00165                                                              samplesref->audio->channel_layout,
00166                                                              samplesref->audio->planar);
00167         outlink->out_buf->pts                = samplesref->pts;
00168         outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate;
00169         avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
00170         avfilter_unref_buffer(outlink->out_buf);
00171         outlink->out_buf = NULL;
00172     }
00173     avfilter_unref_buffer(samplesref);
00174     inlink->cur_buf = NULL;
00175 }
00176 
00180 int avfilter_default_config_output_link(AVFilterLink *link)
00181 {
00182     if (link->src->input_count && link->src->inputs[0]) {
00183         if (link->type == AVMEDIA_TYPE_VIDEO) {
00184             link->w = link->src->inputs[0]->w;
00185             link->h = link->src->inputs[0]->h;
00186             link->time_base = link->src->inputs[0]->time_base;
00187         } else if (link->type == AVMEDIA_TYPE_AUDIO) {
00188             link->channel_layout = link->src->inputs[0]->channel_layout;
00189             link->sample_rate    = link->src->inputs[0]->sample_rate;
00190         }
00191     } else {
00192         /* XXX: any non-simple filter which would cause this branch to be taken
00193          * really should implement its own config_props() for this link. */
00194         return -1;
00195     }
00196 
00197     return 0;
00198 }
00199 
00200 static void set_common_formats(AVFilterContext *ctx, AVFilterFormats *fmts,
00201                                enum AVMediaType type, int offin, int offout)
00202 {
00203     int i;
00204     for (i = 0; i < ctx->input_count; i++)
00205         if (ctx->inputs[i] && ctx->inputs[i]->type == type)
00206             avfilter_formats_ref(fmts,
00207                                  (AVFilterFormats**)((void*)ctx->inputs[i]+offout));
00208 
00209     for (i = 0; i < ctx->output_count; i++)
00210         if (ctx->outputs[i] && ctx->outputs[i]->type == type)
00211             avfilter_formats_ref(fmts,
00212                                  (AVFilterFormats**)((void*)ctx->outputs[i]+offin));
00213 
00214     if (!fmts->refcount) {
00215         av_free(fmts->formats);
00216         av_free(fmts->refs);
00217         av_free(fmts);
00218     }
00219 }
00220 
00221 void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats)
00222 {
00223     set_common_formats(ctx, formats, AVMEDIA_TYPE_VIDEO,
00224                        offsetof(AVFilterLink, in_formats),
00225                        offsetof(AVFilterLink, out_formats));
00226 }
00227 
00228 void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats)
00229 {
00230     set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO,
00231                        offsetof(AVFilterLink, in_formats),
00232                        offsetof(AVFilterLink, out_formats));
00233 }
00234 
00235 void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats)
00236 {
00237     set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO,
00238                        offsetof(AVFilterLink, in_chlayouts),
00239                        offsetof(AVFilterLink, out_chlayouts));
00240 }
00241 
00242 int avfilter_default_query_formats(AVFilterContext *ctx)
00243 {
00244     avfilter_set_common_pixel_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_VIDEO));
00245     avfilter_set_common_sample_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_AUDIO));
00246     avfilter_set_common_channel_layouts(ctx, avfilter_all_channel_layouts());
00247 
00248     return 0;
00249 }
00250 
00251 void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
00252 {
00253     avfilter_start_frame(link->dst->outputs[0], picref);
00254 }
00255 
00256 void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
00257 {
00258     avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
00259 }
00260 
00261 void avfilter_null_end_frame(AVFilterLink *link)
00262 {
00263     avfilter_end_frame(link->dst->outputs[0]);
00264 }
00265 
00266 void avfilter_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
00267 {
00268     avfilter_filter_samples(link->dst->outputs[0], samplesref);
00269 }
00270 
00271 AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
00272 {
00273     return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
00274 }
00275 
00276 AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
00277                                                   enum AVSampleFormat sample_fmt, int size,
00278                                                   int64_t channel_layout, int packed)
00279 {
00280     return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt,
00281                                      size, channel_layout, packed);
00282 }
00283 

Generated on Fri Feb 22 2013 07:24:30 for FFmpeg by  doxygen 1.7.1