Merge and adapt commit d28cb84 by Anton Khirnov.
Nicolas George authored on 2013/04/10 22:58:52... | ... |
@@ -1400,11 +1400,14 @@ Buffer audio frames, and make them available to the filter chain. |
1400 | 1400 |
This source is mainly intended for a programmatic use, in particular |
1401 | 1401 |
through the interface defined in @file{libavfilter/asrc_abuffer.h}. |
1402 | 1402 |
|
1403 |
-It accepts the following mandatory parameters: |
|
1404 |
-@var{sample_rate}:@var{sample_fmt}:@var{channel_layout} |
|
1403 |
+It accepts the following named parameters: |
|
1405 | 1404 |
|
1406 | 1405 |
@table @option |
1407 | 1406 |
|
1407 |
+@item time_base |
|
1408 |
+Timebase which will be used for timestamps of submitted frames. It must be |
|
1409 |
+either a floating-point number or in @var{numerator}/@var{denominator} form. |
|
1410 |
+ |
|
1408 | 1411 |
@item sample_rate |
1409 | 1412 |
The sample rate of the incoming audio buffers. |
1410 | 1413 |
|
... | ... |
@@ -1429,7 +1432,7 @@ must be consistent. |
1429 | 1429 |
@subsection Examples |
1430 | 1430 |
|
1431 | 1431 |
@example |
1432 |
-abuffer=44100:s16p:stereo |
|
1432 |
+abuffer=sample_rate=44100:sample_fmt=s16p:channel_layout=stereo |
|
1433 | 1433 |
@end example |
1434 | 1434 |
|
1435 | 1435 |
will instruct the source to accept planar 16bit signed stereo at 44100Hz. |
... | ... |
@@ -1437,7 +1440,7 @@ Since the sample format with name "s16p" corresponds to the number |
1437 | 1437 |
6 and the "stereo" channel layout corresponds to the value 0x3, this is |
1438 | 1438 |
equivalent to: |
1439 | 1439 |
@example |
1440 |
-abuffer=44100:6:0x3 |
|
1440 |
+abuffer=sample_rate=44100:sample_fmt=6:channel_layout=0x3 |
|
1441 | 1441 |
@end example |
1442 | 1442 |
|
1443 | 1443 |
@section aevalsrc |
... | ... |
@@ -5743,6 +5746,12 @@ separated by ":". A description of the accepted options follows. |
5743 | 5743 |
@item video_size |
5744 | 5744 |
Specify the size (width and height) of the buffered video frames. |
5745 | 5745 |
|
5746 |
+@item width |
|
5747 |
+Input video width. |
|
5748 |
+ |
|
5749 |
+@item height |
|
5750 |
+Input video height. |
|
5751 |
+ |
|
5746 | 5752 |
@item pix_fmt |
5747 | 5753 |
A string representing the pixel format of the buffered video frames. |
5748 | 5754 |
It may be a number corresponding to a pixel format, or a pixel format |
... | ... |
@@ -5751,10 +5760,10 @@ name. |
5751 | 5751 |
@item time_base |
5752 | 5752 |
Specify the timebase assumed by the timestamps of the buffered frames. |
5753 | 5753 |
|
5754 |
-@item time_base |
|
5754 |
+@item frame_rate |
|
5755 | 5755 |
Specify the frame rate expected for the video stream. |
5756 | 5756 |
|
5757 |
-@item pixel_aspect |
|
5757 |
+@item pixel_aspect, sar |
|
5758 | 5758 |
Specify the sample aspect ratio assumed by the video frames. |
5759 | 5759 |
|
5760 | 5760 |
@item sws_param |
... | ... |
@@ -5765,7 +5774,7 @@ input size or format. |
5765 | 5765 |
|
5766 | 5766 |
For example: |
5767 | 5767 |
@example |
5768 |
-buffer=size=320x240:pix_fmt=yuv410p:time_base=1/24:pixel_aspect=1/1 |
|
5768 |
+buffer=width=320:height=240:pix_fmt=yuv410p:time_base=1/24:sar=1 |
|
5769 | 5769 |
@end example |
5770 | 5770 |
|
5771 | 5771 |
will instruct the source to accept video frames with size 320x240 and |
... | ... |
@@ -23,6 +23,8 @@ |
23 | 23 |
* memory buffer source filter |
24 | 24 |
*/ |
25 | 25 |
|
26 |
+#include <float.h> |
|
27 |
+ |
|
26 | 28 |
#include "libavutil/channel_layout.h" |
27 | 29 |
#include "libavutil/common.h" |
28 | 30 |
#include "libavutil/fifo.h" |
... | ... |
@@ -49,6 +51,7 @@ typedef struct { |
49 | 49 |
/* video only */ |
50 | 50 |
int w, h; |
51 | 51 |
enum AVPixelFormat pix_fmt; |
52 |
+ char *pix_fmt_str; |
|
52 | 53 |
AVRational pixel_aspect; |
53 | 54 |
char *sws_param; |
54 | 55 |
|
... | ... |
@@ -286,59 +289,15 @@ int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf) |
286 | 286 |
} |
287 | 287 |
#endif |
288 | 288 |
|
289 |
-#define OFFSET(x) offsetof(BufferSourceContext, x) |
|
290 |
-#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
|
291 |
-static const AVOption buffer_options[] = { |
|
292 |
- { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS }, |
|
293 |
- { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS }, |
|
294 |
- { "video_size", NULL, OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, .flags = FLAGS }, |
|
295 |
- { "pix_fmt", NULL, OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, .flags = FLAGS }, |
|
296 |
- { "pixel_aspect", NULL, OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS }, |
|
297 |
- { "sws_param", NULL, OFFSET(sws_param), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
|
298 |
- { NULL }, |
|
299 |
-}; |
|
300 |
-#undef FLAGS |
|
301 |
- |
|
302 |
-AVFILTER_DEFINE_CLASS(buffer); |
|
303 |
- |
|
304 | 289 |
static av_cold int init_video(AVFilterContext *ctx, const char *args) |
305 | 290 |
{ |
306 | 291 |
BufferSourceContext *c = ctx->priv; |
307 |
- char pix_fmt_str[128], *colon, *equal; |
|
308 |
- int ret, n = 0; |
|
309 |
- |
|
310 |
- c->class = &buffer_class; |
|
311 | 292 |
|
312 |
- if (!args) { |
|
313 |
- av_log(ctx, AV_LOG_ERROR, "Arguments required\n"); |
|
293 |
+ if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h || av_q2d(c->time_base) <= 0) { |
|
294 |
+ av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n"); |
|
314 | 295 |
return AVERROR(EINVAL); |
315 | 296 |
} |
316 | 297 |
|
317 |
- colon = strchr(args, ':'); |
|
318 |
- equal = strchr(args, '='); |
|
319 |
- if (equal && (!colon || equal < colon)) { |
|
320 |
- av_opt_set_defaults(c); |
|
321 |
- ret = av_set_options_string(c, args, "=", ":"); |
|
322 |
- if (ret < 0) |
|
323 |
- goto fail; |
|
324 |
- } else { |
|
325 |
- if (!args || |
|
326 |
- (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str, |
|
327 |
- &c->time_base.num, &c->time_base.den, |
|
328 |
- &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) { |
|
329 |
- av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args); |
|
330 |
- return AVERROR(EINVAL); |
|
331 |
- } |
|
332 |
- if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == AV_PIX_FMT_NONE) { |
|
333 |
- char *tail; |
|
334 |
- c->pix_fmt = strtol(pix_fmt_str, &tail, 10); |
|
335 |
- if (*tail || c->pix_fmt < 0 || c->pix_fmt >= AV_PIX_FMT_NB) { |
|
336 |
- av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str); |
|
337 |
- return AVERROR(EINVAL); |
|
338 |
- } |
|
339 |
- } |
|
340 |
- } |
|
341 |
- |
|
342 | 298 |
if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*)))) |
343 | 299 |
return AVERROR(ENOMEM); |
344 | 300 |
|
... | ... |
@@ -348,10 +307,6 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args) |
348 | 348 |
c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, "")); |
349 | 349 |
c->warning_limit = 100; |
350 | 350 |
return 0; |
351 |
- |
|
352 |
-fail: |
|
353 |
- av_opt_free(c); |
|
354 |
- return ret; |
|
355 | 351 |
} |
356 | 352 |
|
357 | 353 |
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) |
... | ... |
@@ -359,13 +314,39 @@ unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) |
359 | 359 |
return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests; |
360 | 360 |
} |
361 | 361 |
|
362 |
-#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM |
|
362 |
+#define OFFSET(x) offsetof(BufferSourceContext, x) |
|
363 |
+#define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM |
|
364 |
+#define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
|
365 |
+ |
|
366 |
+static const AVOption buffer_options[] = { |
|
367 |
+ { "width", NULL, OFFSET(w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, |
|
368 |
+ { "height", NULL, OFFSET(h), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, |
|
369 |
+ { "video_size", NULL, OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, .flags = V }, |
|
370 |
+ { "pix_fmt", NULL, OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, .flags = V }, |
|
371 |
+#if FF_API_OLD_FILTER_OPTS |
|
372 |
+ /* those 4 are for compatibility with the old option passing system where each filter |
|
373 |
+ * did its own parsing */ |
|
374 |
+ { "time_base_num", "deprecated, do not use", OFFSET(time_base.num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, |
|
375 |
+ { "time_base_den", "deprecated, do not use", OFFSET(time_base.den), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, |
|
376 |
+ { "sar_num", "deprecated, do not use", OFFSET(pixel_aspect.num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, |
|
377 |
+ { "sar_den", "deprecated, do not use", OFFSET(pixel_aspect.den), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, |
|
378 |
+#endif |
|
379 |
+ { "sar", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V }, |
|
380 |
+ { "pixel_aspect", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V }, |
|
381 |
+ { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, |
|
382 |
+ { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, |
|
383 |
+ { "sws_param", NULL, OFFSET(sws_param), AV_OPT_TYPE_STRING, .flags = V }, |
|
384 |
+ { NULL }, |
|
385 |
+}; |
|
386 |
+ |
|
387 |
+AVFILTER_DEFINE_CLASS(buffer); |
|
388 |
+ |
|
363 | 389 |
static const AVOption abuffer_options[] = { |
364 |
- { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS }, |
|
365 |
- { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, |
|
366 |
- { "sample_fmt", NULL, OFFSET(sample_fmt_str), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
|
367 |
- { "channels", NULL, OFFSET(channels), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, |
|
368 |
- { "channel_layout", NULL, OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
|
390 |
+ { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A }, |
|
391 |
+ { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A }, |
|
392 |
+ { "sample_fmt", NULL, OFFSET(sample_fmt_str), AV_OPT_TYPE_STRING, .flags = A }, |
|
393 |
+ { "channels", NULL, OFFSET(channels), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A }, |
|
394 |
+ { "channel_layout", NULL, OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A }, |
|
369 | 395 |
{ NULL }, |
370 | 396 |
}; |
371 | 397 |
|
... | ... |
@@ -376,18 +357,11 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args) |
376 | 376 |
BufferSourceContext *s = ctx->priv; |
377 | 377 |
int ret = 0; |
378 | 378 |
|
379 |
- s->class = &abuffer_class; |
|
380 |
- av_opt_set_defaults(s); |
|
381 |
- |
|
382 |
- if ((ret = av_set_options_string(s, args, "=", ":")) < 0) |
|
383 |
- goto fail; |
|
384 |
- |
|
385 | 379 |
s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str); |
386 | 380 |
if (s->sample_fmt == AV_SAMPLE_FMT_NONE) { |
387 |
- av_log(ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", |
|
381 |
+ av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s\n", |
|
388 | 382 |
s->sample_fmt_str); |
389 |
- ret = AVERROR(EINVAL); |
|
390 |
- goto fail; |
|
383 |
+ return AVERROR(EINVAL); |
|
391 | 384 |
} |
392 | 385 |
|
393 | 386 |
if (s->channel_layout_str) { |
... | ... |
@@ -395,10 +369,9 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args) |
395 | 395 |
/* TODO reindent */ |
396 | 396 |
s->channel_layout = av_get_channel_layout(s->channel_layout_str); |
397 | 397 |
if (!s->channel_layout) { |
398 |
- av_log(ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", |
|
398 |
+ av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n", |
|
399 | 399 |
s->channel_layout_str); |
400 |
- ret = AVERROR(EINVAL); |
|
401 |
- goto fail; |
|
400 |
+ return AVERROR(EINVAL); |
|
402 | 401 |
} |
403 | 402 |
n = av_get_channel_layout_nb_channels(s->channel_layout); |
404 | 403 |
if (s->channels) { |
... | ... |
@@ -407,22 +380,18 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args) |
407 | 407 |
"Mismatching channel count %d and layout '%s' " |
408 | 408 |
"(%d channels)\n", |
409 | 409 |
s->channels, s->channel_layout_str, n); |
410 |
- ret = AVERROR(EINVAL); |
|
411 |
- goto fail; |
|
410 |
+ return AVERROR(EINVAL); |
|
412 | 411 |
} |
413 | 412 |
} |
414 | 413 |
s->channels = n; |
415 | 414 |
} else if (!s->channels) { |
416 | 415 |
av_log(ctx, AV_LOG_ERROR, "Neither number of channels nor " |
417 | 416 |
"channel layout specified\n"); |
418 |
- ret = AVERROR(EINVAL); |
|
419 |
- goto fail; |
|
417 |
+ return AVERROR(EINVAL); |
|
420 | 418 |
} |
421 | 419 |
|
422 |
- if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*)))) { |
|
423 |
- ret = AVERROR(ENOMEM); |
|
424 |
- goto fail; |
|
425 |
- } |
|
420 |
+ if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*)))) |
|
421 |
+ return AVERROR(ENOMEM); |
|
426 | 422 |
|
427 | 423 |
if (!s->time_base.num) |
428 | 424 |
s->time_base = (AVRational){1, s->sample_rate}; |
... | ... |
@@ -433,8 +402,6 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args) |
433 | 433 |
s->sample_rate, s->channel_layout_str); |
434 | 434 |
s->warning_limit = 100; |
435 | 435 |
|
436 |
-fail: |
|
437 |
- av_opt_free(s); |
|
438 | 436 |
return ret; |
439 | 437 |
} |
440 | 438 |
|
... | ... |
@@ -448,7 +415,6 @@ static av_cold void uninit(AVFilterContext *ctx) |
448 | 448 |
} |
449 | 449 |
av_fifo_free(s->fifo); |
450 | 450 |
s->fifo = NULL; |
451 |
- av_freep(&s->sws_param); |
|
452 | 451 |
} |
453 | 452 |
|
454 | 453 |
static int query_formats(AVFilterContext *ctx) |
... | ... |
@@ -541,6 +507,9 @@ static const AVFilterPad avfilter_vsrc_buffer_outputs[] = { |
541 | 541 |
{ NULL } |
542 | 542 |
}; |
543 | 543 |
|
544 |
+static const char *const buffer_shorthand[] = { "width", "height", "pix_fmt", |
|
545 |
+ "time_base_num", "time_base_den", "sar_num", "sar_den", NULL }; |
|
546 |
+ |
|
544 | 547 |
AVFilter avfilter_vsrc_buffer = { |
545 | 548 |
.name = "buffer", |
546 | 549 |
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."), |
... | ... |
@@ -553,6 +522,7 @@ AVFilter avfilter_vsrc_buffer = { |
553 | 553 |
.inputs = NULL, |
554 | 554 |
.outputs = avfilter_vsrc_buffer_outputs, |
555 | 555 |
.priv_class = &buffer_class, |
556 |
+ .shorthand = buffer_shorthand, |
|
556 | 557 |
}; |
557 | 558 |
|
558 | 559 |
static const AVFilterPad avfilter_asrc_abuffer_outputs[] = { |
... | ... |
@@ -566,6 +536,9 @@ static const AVFilterPad avfilter_asrc_abuffer_outputs[] = { |
566 | 566 |
{ NULL } |
567 | 567 |
}; |
568 | 568 |
|
569 |
+static const char *const abuffer_shorthand[] = { "time_base", "sample_rate", |
|
570 |
+ "sample_fmt", "channel_layout", NULL }; |
|
571 |
+ |
|
569 | 572 |
AVFilter avfilter_asrc_abuffer = { |
570 | 573 |
.name = "abuffer", |
571 | 574 |
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."), |
... | ... |
@@ -578,4 +551,5 @@ AVFilter avfilter_asrc_abuffer = { |
578 | 578 |
.inputs = NULL, |
579 | 579 |
.outputs = avfilter_asrc_abuffer_outputs, |
580 | 580 |
.priv_class = &abuffer_class, |
581 |
+ .shorthand = abuffer_shorthand, |
|
581 | 582 |
}; |