annotate ffmpeg/libavfilter/buffersrc.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2008 Vitor Sessak
yading@10 3 *
yading@10 4 * This file is part of FFmpeg.
yading@10 5 *
yading@10 6 * FFmpeg is free software; you can redistribute it and/or
yading@10 7 * modify it under the terms of the GNU Lesser General Public
yading@10 8 * License as published by the Free Software Foundation; either
yading@10 9 * version 2.1 of the License, or (at your option) any later version.
yading@10 10 *
yading@10 11 * FFmpeg is distributed in the hope that it will be useful,
yading@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 14 * Lesser General Public License for more details.
yading@10 15 *
yading@10 16 * You should have received a copy of the GNU Lesser General Public
yading@10 17 * License along with FFmpeg; if not, write to the Free Software
yading@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 19 */
yading@10 20
yading@10 21 /**
yading@10 22 * @file
yading@10 23 * memory buffer source filter
yading@10 24 */
yading@10 25
yading@10 26 #include <float.h>
yading@10 27
yading@10 28 #include "libavutil/channel_layout.h"
yading@10 29 #include "libavutil/common.h"
yading@10 30 #include "libavutil/fifo.h"
yading@10 31 #include "libavutil/frame.h"
yading@10 32 #include "libavutil/imgutils.h"
yading@10 33 #include "libavutil/opt.h"
yading@10 34 #include "libavutil/samplefmt.h"
yading@10 35 #include "audio.h"
yading@10 36 #include "avfilter.h"
yading@10 37 #include "buffersrc.h"
yading@10 38 #include "formats.h"
yading@10 39 #include "internal.h"
yading@10 40 #include "video.h"
yading@10 41 #include "avcodec.h"
yading@10 42
yading@10 43 typedef struct {
yading@10 44 const AVClass *class;
yading@10 45 AVFifoBuffer *fifo;
yading@10 46 AVRational time_base; ///< time_base to set in the output link
yading@10 47 AVRational frame_rate; ///< frame_rate to set in the output link
yading@10 48 unsigned nb_failed_requests;
yading@10 49 unsigned warning_limit;
yading@10 50
yading@10 51 /* video only */
yading@10 52 int w, h;
yading@10 53 enum AVPixelFormat pix_fmt;
yading@10 54 char *pix_fmt_str;
yading@10 55 AVRational pixel_aspect;
yading@10 56 char *sws_param;
yading@10 57
yading@10 58 /* audio only */
yading@10 59 int sample_rate;
yading@10 60 enum AVSampleFormat sample_fmt;
yading@10 61 char *sample_fmt_str;
yading@10 62 int channels;
yading@10 63 uint64_t channel_layout;
yading@10 64 char *channel_layout_str;
yading@10 65
yading@10 66 int eof;
yading@10 67 } BufferSourceContext;
yading@10 68
yading@10 69 #define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\
yading@10 70 if (c->w != width || c->h != height || c->pix_fmt != format) {\
yading@10 71 av_log(s, AV_LOG_INFO, "Changing frame properties on the fly is not supported by all filters.\n");\
yading@10 72 }
yading@10 73
yading@10 74 #define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, ch_count, format)\
yading@10 75 if (c->sample_fmt != format || c->sample_rate != srate ||\
yading@10 76 c->channel_layout != ch_layout || c->channels != ch_count) {\
yading@10 77 av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
yading@10 78 return AVERROR(EINVAL);\
yading@10 79 }
yading@10 80
yading@10 81 int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
yading@10 82 {
yading@10 83 return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame,
yading@10 84 AV_BUFFERSRC_FLAG_KEEP_REF);
yading@10 85 }
yading@10 86
yading@10 87 int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
yading@10 88 {
yading@10 89 return av_buffersrc_add_frame_flags(ctx, frame, 0);
yading@10 90 }
yading@10 91
yading@10 92 static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
yading@10 93 AVFrame *frame, int flags);
yading@10 94
yading@10 95 int av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
yading@10 96 {
yading@10 97 AVFrame *copy = NULL;
yading@10 98 int ret = 0;
yading@10 99
yading@10 100 if (frame && frame->channel_layout &&
yading@10 101 av_get_channel_layout_nb_channels(frame->channel_layout) != av_frame_get_channels(frame)) {
yading@10 102 av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
yading@10 103 return AVERROR(EINVAL);
yading@10 104 }
yading@10 105
yading@10 106 if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame)
yading@10 107 return av_buffersrc_add_frame_internal(ctx, frame, flags);
yading@10 108
yading@10 109 if (!(copy = av_frame_alloc()))
yading@10 110 return AVERROR(ENOMEM);
yading@10 111 ret = av_frame_ref(copy, frame);
yading@10 112 if (ret >= 0)
yading@10 113 ret = av_buffersrc_add_frame_internal(ctx, copy, flags);
yading@10 114
yading@10 115 av_frame_free(&copy);
yading@10 116 return ret;
yading@10 117 }
yading@10 118
yading@10 119 static int attribute_align_arg av_buffersrc_add_frame_internal(AVFilterContext *ctx,
yading@10 120 AVFrame *frame, int flags)
yading@10 121 {
yading@10 122 BufferSourceContext *s = ctx->priv;
yading@10 123 AVFrame *copy;
yading@10 124 int ret;
yading@10 125
yading@10 126 s->nb_failed_requests = 0;
yading@10 127
yading@10 128 if (!frame) {
yading@10 129 s->eof = 1;
yading@10 130 return 0;
yading@10 131 } else if (s->eof)
yading@10 132 return AVERROR(EINVAL);
yading@10 133
yading@10 134 if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) {
yading@10 135
yading@10 136 switch (ctx->outputs[0]->type) {
yading@10 137 case AVMEDIA_TYPE_VIDEO:
yading@10 138 CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
yading@10 139 frame->format);
yading@10 140 break;
yading@10 141 case AVMEDIA_TYPE_AUDIO:
yading@10 142 /* For layouts unknown on input but known on link after negotiation. */
yading@10 143 if (!frame->channel_layout)
yading@10 144 frame->channel_layout = s->channel_layout;
yading@10 145 CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
yading@10 146 av_frame_get_channels(frame), frame->format);
yading@10 147 break;
yading@10 148 default:
yading@10 149 return AVERROR(EINVAL);
yading@10 150 }
yading@10 151
yading@10 152 }
yading@10 153
yading@10 154 if (!av_fifo_space(s->fifo) &&
yading@10 155 (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
yading@10 156 sizeof(copy))) < 0)
yading@10 157 return ret;
yading@10 158
yading@10 159 if (!(copy = av_frame_alloc()))
yading@10 160 return AVERROR(ENOMEM);
yading@10 161 av_frame_move_ref(copy, frame);
yading@10 162
yading@10 163 if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
yading@10 164 av_frame_move_ref(frame, copy);
yading@10 165 av_frame_free(&copy);
yading@10 166 return ret;
yading@10 167 }
yading@10 168
yading@10 169 if ((flags & AV_BUFFERSRC_FLAG_PUSH))
yading@10 170 if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0)
yading@10 171 return ret;
yading@10 172
yading@10 173 return 0;
yading@10 174 }
yading@10 175
yading@10 176 #if FF_API_AVFILTERBUFFER
yading@10 177 static void compat_free_buffer(void *opaque, uint8_t *data)
yading@10 178 {
yading@10 179 AVFilterBufferRef *buf = opaque;
yading@10 180 AV_NOWARN_DEPRECATED(
yading@10 181 avfilter_unref_buffer(buf);
yading@10 182 )
yading@10 183 }
yading@10 184
yading@10 185 static void compat_unref_buffer(void *opaque, uint8_t *data)
yading@10 186 {
yading@10 187 AVBufferRef *buf = opaque;
yading@10 188 AV_NOWARN_DEPRECATED(
yading@10 189 av_buffer_unref(&buf);
yading@10 190 )
yading@10 191 }
yading@10 192
yading@10 193 int av_buffersrc_add_ref(AVFilterContext *ctx, AVFilterBufferRef *buf,
yading@10 194 int flags)
yading@10 195 {
yading@10 196 BufferSourceContext *s = ctx->priv;
yading@10 197 AVFrame *frame = NULL;
yading@10 198 AVBufferRef *dummy_buf = NULL;
yading@10 199 int ret = 0, planes, i;
yading@10 200
yading@10 201 if (!buf) {
yading@10 202 s->eof = 1;
yading@10 203 return 0;
yading@10 204 } else if (s->eof)
yading@10 205 return AVERROR(EINVAL);
yading@10 206
yading@10 207 frame = av_frame_alloc();
yading@10 208 if (!frame)
yading@10 209 return AVERROR(ENOMEM);
yading@10 210
yading@10 211 dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, buf,
yading@10 212 (buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY);
yading@10 213 if (!dummy_buf) {
yading@10 214 ret = AVERROR(ENOMEM);
yading@10 215 goto fail;
yading@10 216 }
yading@10 217
yading@10 218 AV_NOWARN_DEPRECATED(
yading@10 219 if ((ret = avfilter_copy_buf_props(frame, buf)) < 0)
yading@10 220 goto fail;
yading@10 221 )
yading@10 222
yading@10 223 #define WRAP_PLANE(ref_out, data, data_size) \
yading@10 224 do { \
yading@10 225 AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf); \
yading@10 226 if (!dummy_ref) { \
yading@10 227 ret = AVERROR(ENOMEM); \
yading@10 228 goto fail; \
yading@10 229 } \
yading@10 230 ref_out = av_buffer_create(data, data_size, compat_unref_buffer, \
yading@10 231 dummy_ref, (buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY); \
yading@10 232 if (!ref_out) { \
yading@10 233 av_frame_unref(frame); \
yading@10 234 ret = AVERROR(ENOMEM); \
yading@10 235 goto fail; \
yading@10 236 } \
yading@10 237 } while (0)
yading@10 238
yading@10 239 if (ctx->outputs[0]->type == AVMEDIA_TYPE_VIDEO) {
yading@10 240 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
yading@10 241
yading@10 242 planes = av_pix_fmt_count_planes(frame->format);
yading@10 243 if (!desc || planes <= 0) {
yading@10 244 ret = AVERROR(EINVAL);
yading@10 245 goto fail;
yading@10 246 }
yading@10 247
yading@10 248 for (i = 0; i < planes; i++) {
yading@10 249 int v_shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
yading@10 250 int plane_size = (frame->height >> v_shift) * frame->linesize[i];
yading@10 251
yading@10 252 WRAP_PLANE(frame->buf[i], frame->data[i], plane_size);
yading@10 253 }
yading@10 254 } else {
yading@10 255 int planar = av_sample_fmt_is_planar(frame->format);
yading@10 256 int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
yading@10 257
yading@10 258 planes = planar ? channels : 1;
yading@10 259
yading@10 260 if (planes > FF_ARRAY_ELEMS(frame->buf)) {
yading@10 261 frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf);
yading@10 262 frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) *
yading@10 263 frame->nb_extended_buf);
yading@10 264 if (!frame->extended_buf) {
yading@10 265 ret = AVERROR(ENOMEM);
yading@10 266 goto fail;
yading@10 267 }
yading@10 268 }
yading@10 269
yading@10 270 for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
yading@10 271 WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
yading@10 272
yading@10 273 for (i = 0; i < planes - FF_ARRAY_ELEMS(frame->buf); i++)
yading@10 274 WRAP_PLANE(frame->extended_buf[i],
yading@10 275 frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)],
yading@10 276 frame->linesize[0]);
yading@10 277 }
yading@10 278
yading@10 279 ret = av_buffersrc_add_frame_flags(ctx, frame, flags);
yading@10 280
yading@10 281 fail:
yading@10 282 av_buffer_unref(&dummy_buf);
yading@10 283 av_frame_free(&frame);
yading@10 284
yading@10 285 return ret;
yading@10 286 }
yading@10 287
yading@10 288 int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf)
yading@10 289 {
yading@10 290 return av_buffersrc_add_ref(ctx, buf, 0);
yading@10 291 }
yading@10 292 #endif
yading@10 293
yading@10 294 static av_cold int init_video(AVFilterContext *ctx)
yading@10 295 {
yading@10 296 BufferSourceContext *c = ctx->priv;
yading@10 297
yading@10 298 if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h || av_q2d(c->time_base) <= 0) {
yading@10 299 av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n");
yading@10 300 return AVERROR(EINVAL);
yading@10 301 }
yading@10 302
yading@10 303 if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*))))
yading@10 304 return AVERROR(ENOMEM);
yading@10 305
yading@10 306 av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n",
yading@10 307 c->w, c->h, av_get_pix_fmt_name(c->pix_fmt),
yading@10 308 c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den,
yading@10 309 c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, ""));
yading@10 310 c->warning_limit = 100;
yading@10 311 return 0;
yading@10 312 }
yading@10 313
yading@10 314 unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
yading@10 315 {
yading@10 316 return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
yading@10 317 }
yading@10 318
yading@10 319 #define OFFSET(x) offsetof(BufferSourceContext, x)
yading@10 320 #define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
yading@10 321 #define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
yading@10 322
yading@10 323 static const AVOption buffer_options[] = {
yading@10 324 { "width", NULL, OFFSET(w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V },
yading@10 325 { "video_size", NULL, OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, .flags = V },
yading@10 326 { "height", NULL, OFFSET(h), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V },
yading@10 327 { "pix_fmt", NULL, OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, .flags = V },
yading@10 328 #if FF_API_OLD_FILTER_OPTS
yading@10 329 /* those 4 are for compatibility with the old option passing system where each filter
yading@10 330 * did its own parsing */
yading@10 331 { "time_base_num", "deprecated, do not use", OFFSET(time_base.num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V },
yading@10 332 { "time_base_den", "deprecated, do not use", OFFSET(time_base.den), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V },
yading@10 333 { "sar_num", "deprecated, do not use", OFFSET(pixel_aspect.num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V },
yading@10 334 { "sar_den", "deprecated, do not use", OFFSET(pixel_aspect.den), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V },
yading@10 335 #endif
yading@10 336 { "sar", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V },
yading@10 337 { "pixel_aspect", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V },
yading@10 338 { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
yading@10 339 { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
yading@10 340 { "sws_param", NULL, OFFSET(sws_param), AV_OPT_TYPE_STRING, .flags = V },
yading@10 341 { NULL },
yading@10 342 };
yading@10 343
yading@10 344 AVFILTER_DEFINE_CLASS(buffer);
yading@10 345
yading@10 346 static const AVOption abuffer_options[] = {
yading@10 347 { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A },
yading@10 348 { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A },
yading@10 349 { "sample_fmt", NULL, OFFSET(sample_fmt_str), AV_OPT_TYPE_STRING, .flags = A },
yading@10 350 { "channel_layout", NULL, OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A },
yading@10 351 { "channels", NULL, OFFSET(channels), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A },
yading@10 352 { NULL },
yading@10 353 };
yading@10 354
yading@10 355 AVFILTER_DEFINE_CLASS(abuffer);
yading@10 356
yading@10 357 static av_cold int init_audio(AVFilterContext *ctx)
yading@10 358 {
yading@10 359 BufferSourceContext *s = ctx->priv;
yading@10 360 int ret = 0;
yading@10 361
yading@10 362 s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str);
yading@10 363 if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
yading@10 364 av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s\n",
yading@10 365 s->sample_fmt_str);
yading@10 366 return AVERROR(EINVAL);
yading@10 367 }
yading@10 368
yading@10 369 if (s->channel_layout_str) {
yading@10 370 int n;
yading@10 371 /* TODO reindent */
yading@10 372 s->channel_layout = av_get_channel_layout(s->channel_layout_str);
yading@10 373 if (!s->channel_layout) {
yading@10 374 av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
yading@10 375 s->channel_layout_str);
yading@10 376 return AVERROR(EINVAL);
yading@10 377 }
yading@10 378 n = av_get_channel_layout_nb_channels(s->channel_layout);
yading@10 379 if (s->channels) {
yading@10 380 if (n != s->channels) {
yading@10 381 av_log(ctx, AV_LOG_ERROR,
yading@10 382 "Mismatching channel count %d and layout '%s' "
yading@10 383 "(%d channels)\n",
yading@10 384 s->channels, s->channel_layout_str, n);
yading@10 385 return AVERROR(EINVAL);
yading@10 386 }
yading@10 387 }
yading@10 388 s->channels = n;
yading@10 389 } else if (!s->channels) {
yading@10 390 av_log(ctx, AV_LOG_ERROR, "Neither number of channels nor "
yading@10 391 "channel layout specified\n");
yading@10 392 return AVERROR(EINVAL);
yading@10 393 }
yading@10 394
yading@10 395 if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*))))
yading@10 396 return AVERROR(ENOMEM);
yading@10 397
yading@10 398 if (!s->time_base.num)
yading@10 399 s->time_base = (AVRational){1, s->sample_rate};
yading@10 400
yading@10 401 av_log(ctx, AV_LOG_VERBOSE,
yading@10 402 "tb:%d/%d samplefmt:%s samplerate:%d chlayout:%s\n",
yading@10 403 s->time_base.num, s->time_base.den, s->sample_fmt_str,
yading@10 404 s->sample_rate, s->channel_layout_str);
yading@10 405 s->warning_limit = 100;
yading@10 406
yading@10 407 return ret;
yading@10 408 }
yading@10 409
yading@10 410 static av_cold void uninit(AVFilterContext *ctx)
yading@10 411 {
yading@10 412 BufferSourceContext *s = ctx->priv;
yading@10 413 while (s->fifo && av_fifo_size(s->fifo)) {
yading@10 414 AVFrame *frame;
yading@10 415 av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL);
yading@10 416 av_frame_free(&frame);
yading@10 417 }
yading@10 418 av_fifo_free(s->fifo);
yading@10 419 s->fifo = NULL;
yading@10 420 }
yading@10 421
yading@10 422 static int query_formats(AVFilterContext *ctx)
yading@10 423 {
yading@10 424 BufferSourceContext *c = ctx->priv;
yading@10 425 AVFilterChannelLayouts *channel_layouts = NULL;
yading@10 426 AVFilterFormats *formats = NULL;
yading@10 427 AVFilterFormats *samplerates = NULL;
yading@10 428
yading@10 429 switch (ctx->outputs[0]->type) {
yading@10 430 case AVMEDIA_TYPE_VIDEO:
yading@10 431 ff_add_format(&formats, c->pix_fmt);
yading@10 432 ff_set_common_formats(ctx, formats);
yading@10 433 break;
yading@10 434 case AVMEDIA_TYPE_AUDIO:
yading@10 435 ff_add_format(&formats, c->sample_fmt);
yading@10 436 ff_set_common_formats(ctx, formats);
yading@10 437
yading@10 438 ff_add_format(&samplerates, c->sample_rate);
yading@10 439 ff_set_common_samplerates(ctx, samplerates);
yading@10 440
yading@10 441 ff_add_channel_layout(&channel_layouts,
yading@10 442 c->channel_layout ? c->channel_layout :
yading@10 443 FF_COUNT2LAYOUT(c->channels));
yading@10 444 ff_set_common_channel_layouts(ctx, channel_layouts);
yading@10 445 break;
yading@10 446 default:
yading@10 447 return AVERROR(EINVAL);
yading@10 448 }
yading@10 449
yading@10 450 return 0;
yading@10 451 }
yading@10 452
yading@10 453 static int config_props(AVFilterLink *link)
yading@10 454 {
yading@10 455 BufferSourceContext *c = link->src->priv;
yading@10 456
yading@10 457 switch (link->type) {
yading@10 458 case AVMEDIA_TYPE_VIDEO:
yading@10 459 link->w = c->w;
yading@10 460 link->h = c->h;
yading@10 461 link->sample_aspect_ratio = c->pixel_aspect;
yading@10 462 break;
yading@10 463 case AVMEDIA_TYPE_AUDIO:
yading@10 464 if (!c->channel_layout)
yading@10 465 c->channel_layout = link->channel_layout;
yading@10 466 break;
yading@10 467 default:
yading@10 468 return AVERROR(EINVAL);
yading@10 469 }
yading@10 470
yading@10 471 link->time_base = c->time_base;
yading@10 472 link->frame_rate = c->frame_rate;
yading@10 473 return 0;
yading@10 474 }
yading@10 475
yading@10 476 static int request_frame(AVFilterLink *link)
yading@10 477 {
yading@10 478 BufferSourceContext *c = link->src->priv;
yading@10 479 AVFrame *frame;
yading@10 480
yading@10 481 if (!av_fifo_size(c->fifo)) {
yading@10 482 if (c->eof)
yading@10 483 return AVERROR_EOF;
yading@10 484 c->nb_failed_requests++;
yading@10 485 return AVERROR(EAGAIN);
yading@10 486 }
yading@10 487 av_fifo_generic_read(c->fifo, &frame, sizeof(frame), NULL);
yading@10 488
yading@10 489 return ff_filter_frame(link, frame);
yading@10 490 }
yading@10 491
yading@10 492 static int poll_frame(AVFilterLink *link)
yading@10 493 {
yading@10 494 BufferSourceContext *c = link->src->priv;
yading@10 495 int size = av_fifo_size(c->fifo);
yading@10 496 if (!size && c->eof)
yading@10 497 return AVERROR_EOF;
yading@10 498 return size/sizeof(AVFrame*);
yading@10 499 }
yading@10 500
yading@10 501 static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {
yading@10 502 {
yading@10 503 .name = "default",
yading@10 504 .type = AVMEDIA_TYPE_VIDEO,
yading@10 505 .request_frame = request_frame,
yading@10 506 .poll_frame = poll_frame,
yading@10 507 .config_props = config_props,
yading@10 508 },
yading@10 509 { NULL }
yading@10 510 };
yading@10 511
yading@10 512 AVFilter avfilter_vsrc_buffer = {
yading@10 513 .name = "buffer",
yading@10 514 .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
yading@10 515 .priv_size = sizeof(BufferSourceContext),
yading@10 516 .query_formats = query_formats,
yading@10 517
yading@10 518 .init = init_video,
yading@10 519 .uninit = uninit,
yading@10 520
yading@10 521 .inputs = NULL,
yading@10 522 .outputs = avfilter_vsrc_buffer_outputs,
yading@10 523 .priv_class = &buffer_class,
yading@10 524 };
yading@10 525
yading@10 526 static const AVFilterPad avfilter_asrc_abuffer_outputs[] = {
yading@10 527 {
yading@10 528 .name = "default",
yading@10 529 .type = AVMEDIA_TYPE_AUDIO,
yading@10 530 .request_frame = request_frame,
yading@10 531 .poll_frame = poll_frame,
yading@10 532 .config_props = config_props,
yading@10 533 },
yading@10 534 { NULL }
yading@10 535 };
yading@10 536
yading@10 537 AVFilter avfilter_asrc_abuffer = {
yading@10 538 .name = "abuffer",
yading@10 539 .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
yading@10 540 .priv_size = sizeof(BufferSourceContext),
yading@10 541 .query_formats = query_formats,
yading@10 542
yading@10 543 .init = init_audio,
yading@10 544 .uninit = uninit,
yading@10 545
yading@10 546 .inputs = NULL,
yading@10 547 .outputs = avfilter_asrc_abuffer_outputs,
yading@10 548 .priv_class = &abuffer_class,
yading@10 549 };