00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00029 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
00030 {
00031 av_free(ptr->data[0]);
00032 av_free(ptr);
00033 }
00034
00035
00036
00037
00038 AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
00039 {
00040 int linesize[4];
00041 uint8_t *data[4];
00042 AVFilterBufferRef *picref = NULL;
00043
00044
00045 if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
00046 return NULL;
00047
00048 picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
00049 perms, w, h, link->format);
00050 if (!picref) {
00051 av_free(data[0]);
00052 return NULL;
00053 }
00054
00055 return picref;
00056 }
00057
00058 AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
00059 enum AVSampleFormat sample_fmt, int size,
00060 uint64_t channel_layout, int planar)
00061 {
00062 AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
00063 AVFilterBufferRef *ref = NULL;
00064 int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0;
00065 char *buf;
00066
00067 if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef))))
00068 goto fail;
00069
00070 ref->buf = samples;
00071 ref->format = sample_fmt;
00072
00073 ref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps));
00074 if (!ref->audio)
00075 goto fail;
00076
00077 ref->audio->channel_layout = channel_layout;
00078 ref->audio->size = size;
00079 ref->audio->planar = planar;
00080
00081
00082 ref->perms = perms | AV_PERM_READ;
00083
00084 samples->refcount = 1;
00085 samples->free = ff_avfilter_default_free_buffer;
00086
00087 sample_size = av_get_bytes_per_sample(sample_fmt);
00088 chans_nb = av_get_channel_layout_nb_channels(channel_layout);
00089
00090 per_channel_size = size/chans_nb;
00091 ref->audio->nb_samples = per_channel_size/sample_size;
00092
00093
00094
00095
00096
00097 for (i = 0; i < chans_nb; i++)
00098 samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;
00099 memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));
00100
00101
00102 bufsize = (size + 15)&~15;
00103 buf = av_malloc(bufsize);
00104 if (!buf)
00105 goto fail;
00106
00107
00108
00109
00110 samples->data[0] = buf;
00111 if (buf && planar) {
00112 for (i = 1; i < chans_nb; i++) {
00113 step_size += per_channel_size;
00114 samples->data[i] = buf + step_size;
00115 }
00116 } else {
00117 for (i = 1; i < chans_nb; i++)
00118 samples->data[i] = buf;
00119 }
00120
00121 memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0]));
00122
00123 memcpy(ref->data, samples->data, sizeof(ref->data));
00124 memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));
00125
00126 return ref;
00127
00128 fail:
00129 if (ref)
00130 av_free(ref->audio);
00131 av_free(ref);
00132 av_free(samples);
00133 return NULL;
00134 }
00135
00136 void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
00137 {
00138 AVFilterLink *outlink = NULL;
00139
00140 if (inlink->dst->output_count)
00141 outlink = inlink->dst->outputs[0];
00142
00143 if (outlink) {
00144 outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
00145 avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
00146 avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
00147 }
00148 }
00149
00150 void avfilter_default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
00151 {
00152 AVFilterLink *outlink = NULL;
00153
00154 if (inlink->dst->output_count)
00155 outlink = inlink->dst->outputs[0];
00156
00157 if (outlink)
00158 avfilter_draw_slice(outlink, y, h, slice_dir);
00159 }
00160
00161 void avfilter_default_end_frame(AVFilterLink *inlink)
00162 {
00163 AVFilterLink *outlink = NULL;
00164
00165 if (inlink->dst->output_count)
00166 outlink = inlink->dst->outputs[0];
00167
00168 avfilter_unref_buffer(inlink->cur_buf);
00169 inlink->cur_buf = NULL;
00170
00171 if (outlink) {
00172 if (outlink->out_buf) {
00173 avfilter_unref_buffer(outlink->out_buf);
00174 outlink->out_buf = NULL;
00175 }
00176 avfilter_end_frame(outlink);
00177 }
00178 }
00179
00180
00181 void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
00182 {
00183 AVFilterLink *outlink = NULL;
00184
00185 if (inlink->dst->output_count)
00186 outlink = inlink->dst->outputs[0];
00187
00188 if (outlink) {
00189 outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format,
00190 samplesref->audio->size,
00191 samplesref->audio->channel_layout,
00192 samplesref->audio->planar);
00193 outlink->out_buf->pts = samplesref->pts;
00194 outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate;
00195 avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
00196 avfilter_unref_buffer(outlink->out_buf);
00197 outlink->out_buf = NULL;
00198 }
00199 avfilter_unref_buffer(samplesref);
00200 inlink->cur_buf = NULL;
00201 }
00202
00206 int avfilter_default_config_output_link(AVFilterLink *link)
00207 {
00208 if (link->src->input_count && link->src->inputs[0]) {
00209 if (link->type == AVMEDIA_TYPE_VIDEO) {
00210 link->w = link->src->inputs[0]->w;
00211 link->h = link->src->inputs[0]->h;
00212 link->time_base = link->src->inputs[0]->time_base;
00213 } else if (link->type == AVMEDIA_TYPE_AUDIO) {
00214 link->channel_layout = link->src->inputs[0]->channel_layout;
00215 link->sample_rate = link->src->inputs[0]->sample_rate;
00216 }
00217 } else {
00218
00219
00220 return -1;
00221 }
00222
00223 return 0;
00224 }
00225
00234 void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
00235 {
00236 int count = 0, i;
00237
00238 for (i = 0; i < ctx->input_count; i++) {
00239 if (ctx->inputs[i]) {
00240 avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats);
00241 count++;
00242 }
00243 }
00244 for (i = 0; i < ctx->output_count; i++) {
00245 if (ctx->outputs[i]) {
00246 avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats);
00247 count++;
00248 }
00249 }
00250
00251 if (!count) {
00252 av_free(formats->formats);
00253 av_free(formats->refs);
00254 av_free(formats);
00255 }
00256 }
00257
00258 int avfilter_default_query_formats(AVFilterContext *ctx)
00259 {
00260 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
00261 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
00262 AVMEDIA_TYPE_VIDEO;
00263
00264 avfilter_set_common_formats(ctx, avfilter_all_formats(type));
00265 return 0;
00266 }
00267
00268 void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
00269 {
00270 avfilter_start_frame(link->dst->outputs[0], picref);
00271 }
00272
00273 void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
00274 {
00275 avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
00276 }
00277
00278 void avfilter_null_end_frame(AVFilterLink *link)
00279 {
00280 avfilter_end_frame(link->dst->outputs[0]);
00281 }
00282
00283 void avfilter_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
00284 {
00285 avfilter_filter_samples(link->dst->outputs[0], samplesref);
00286 }
00287
00288 AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
00289 {
00290 return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h);
00291 }
00292
00293 AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
00294 enum AVSampleFormat sample_fmt, int size,
00295 uint64_t channel_layout, int packed)
00296 {
00297 return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt,
00298 size, channel_layout, packed);
00299 }
00300