lavfi/tinterlace: support symbolic names for the parameter

Also deprecate the use of numerical values.
This commit is contained in:
Stefano Sabatini 2012-04-29 16:45:35 +02:00
parent 837d034787
commit 5f161c2357
3 changed files with 71 additions and 31 deletions

View File

@ -2778,31 +2778,31 @@ This filter accepts a single parameter specifying the mode. Available
modes are: modes are:
@table @samp @table @samp
@item 0 @item merge, 0
Move odd frames into the upper field, even into the lower field, Move odd frames into the upper field, even into the lower field,
generating a double height frame at half framerate. generating a double height frame at half framerate.
@item 1 @item drop_odd, 1
Only output even frames, odd frames are dropped, generating a frame with Only output even frames, odd frames are dropped, generating a frame with
unchanged height at half framerate. unchanged height at half framerate.
@item 2 @item drop_even, 2
Only output odd frames, even frames are dropped, generating a frame with Only output odd frames, even frames are dropped, generating a frame with
unchanged height at half framerate. unchanged height at half framerate.
@item 3 @item pad, 3
Expand each frame to full height, but pad alternate lines with black, Expand each frame to full height, but pad alternate lines with black,
generating a frame with double height at the same input framerate. generating a frame with double height at the same input framerate.
@item 4 @item interleave_top, 4
Interleave the upper field from odd frames with the lower field from Interleave the upper field from odd frames with the lower field from
even frames, generating a frame with unchanged height at half framerate. even frames, generating a frame with unchanged height at half framerate.
@item 5 @item interleave_bottom, 5
Interleave the lower field from odd frames with the upper field from Interleave the lower field from odd frames with the upper field from
even frames, generating a frame with unchanged height at half framerate. even frames, generating a frame with unchanged height at half framerate.
@item 6 @item interlacex2, 6
Double frame rate with unchanged height. Frames are inserted each Double frame rate with unchanged height. Frames are inserted each
containing the second temporal field from the previous input frame and containing the second temporal field from the previous input frame and
the first temporal field from the next input frame. This mode relies on the first temporal field from the next input frame. This mode relies on
@ -2810,7 +2810,10 @@ the top_field_first flag. Useful for interlaced video displays with no
field synchronisation. field synchronisation.
@end table @end table
Default mode is 0. Numeric values are deprecated but are accepted for backward
compatibility reasons.
Default mode is @code{merge}.
@section transpose @section transpose

View File

@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 2 #define LIBAVFILTER_VERSION_MAJOR 2
#define LIBAVFILTER_VERSION_MINOR 72 #define LIBAVFILTER_VERSION_MINOR 72
#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_MICRO 102
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \ LIBAVFILTER_VERSION_MINOR, \

View File

@ -29,8 +29,29 @@
#include "avfilter.h" #include "avfilter.h"
#include "internal.h" #include "internal.h"
enum TInterlaceMode {
MODE_MERGE = 0,
MODE_DROP_EVEN,
MODE_DROP_ODD,
MODE_PAD,
MODE_INTERLEAVE_TOP,
MODE_INTERLEAVE_BOTTOM,
MODE_INTERLACEX2,
};
static const char *tinterlace_mode_str[] = {
"merge",
"drop_even",
"drop_odd",
"pad",
"interleave_top",
"interleave_bottom",
"interlacex2",
NULL
};
typedef struct { typedef struct {
int mode; ///< interlace mode selected enum TInterlaceMode mode; ///< interlace mode selected
int frame; ///< number of the output frame int frame; ///< number of the output frame
int vsub; ///< chroma vertical subsampling int vsub; ///< chroma vertical subsampling
AVFilterBufferRef *cur; AVFilterBufferRef *cur;
@ -62,16 +83,32 @@ static int query_formats(AVFilterContext *ctx)
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{ {
TInterlaceContext *tinterlace = ctx->priv; TInterlaceContext *tinterlace = ctx->priv;
int n; int i;
tinterlace->mode = 0; char c;
tinterlace->mode = MODE_MERGE;
if (args) { if (args) {
n = sscanf(args, "%d", &tinterlace->mode); if (sscanf(args, "%d%c", (int *)&tinterlace->mode, &c) == 1) {
if (tinterlace->mode > 6) {
av_log(ctx, AV_LOG_ERROR,
"Invalid mode '%s', use an integer between 0 and 6\n", args);
return AVERROR(EINVAL);
}
if (n != 1 || tinterlace->mode < 0 || tinterlace->mode > 6) { av_log(ctx, AV_LOG_WARNING,
av_log(ctx, AV_LOG_ERROR, "Using numeric constant is deprecated, use symbolic values\n");
"Invalid mode '%s', use an integer between 0 and 6\n", args); } else {
return AVERROR(EINVAL); for (i = 0; tinterlace_mode_str[i]; i++) {
if (!strcmp(tinterlace_mode_str[i], args)) {
tinterlace->mode = i;
break;
}
}
if (!tinterlace_mode_str[i]) {
av_log(ctx, AV_LOG_ERROR, "Invalid argument '%s'\n", args);
return AVERROR(EINVAL);
}
} }
} }
@ -97,10 +134,10 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace->vsub = desc->log2_chroma_h; tinterlace->vsub = desc->log2_chroma_h;
outlink->w = inlink->w; outlink->w = inlink->w;
outlink->h = tinterlace->mode == 0 || tinterlace->mode == 3 ? outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD ?
inlink->h*2 : inlink->h; inlink->h*2 : inlink->h;
if (tinterlace->mode == 3) { if (tinterlace->mode == MODE_PAD) {
uint8_t black[4] = { 16, 128, 128, 16 }; uint8_t black[4] = { 16, 128, 128, 16 };
int i, ret; int i, ret;
if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts))
@ -117,8 +154,8 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace->black_linesize[i] * h); tinterlace->black_linesize[i] * h);
} }
} }
av_log(ctx, AV_LOG_INFO, "mode:%d h:%d -> h:%d\n", av_log(ctx, AV_LOG_INFO, "mode:%s h:%d -> h:%d\n",
tinterlace->mode, inlink->h, outlink->h); tinterlace_mode_str[tinterlace->mode], inlink->h, outlink->h);
return 0; return 0;
} }
@ -185,7 +222,7 @@ static void end_frame(AVFilterLink *inlink)
return; return;
switch (tinterlace->mode) { switch (tinterlace->mode) {
case 0: /* move the odd frame into the upper field of the new image, even into case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into
* the lower field, generating a double-height video at half framerate */ * the lower field, generating a double-height video at half framerate */
out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(out, cur); avfilter_copy_buffer_ref_props(out, cur);
@ -206,14 +243,14 @@ static void end_frame(AVFilterLink *inlink)
avfilter_unref_bufferp(&tinterlace->next); avfilter_unref_bufferp(&tinterlace->next);
break; break;
case 1: /* only output even frames, odd frames are dropped; height unchanged, half framerate */ case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */
case 2: /* only output odd frames, even frames are dropped; height unchanged, half framerate */ case MODE_DROP_EVEN: /* only output odd frames, even frames are dropped; height unchanged, half framerate */
out = avfilter_ref_buffer(tinterlace->mode == 2 ? cur : next, AV_PERM_READ); out = avfilter_ref_buffer(tinterlace->mode == MODE_DROP_EVEN ? cur : next, AV_PERM_READ);
avfilter_unref_bufferp(&tinterlace->next); avfilter_unref_bufferp(&tinterlace->next);
break; break;
case 3: /* expand each frame to double height, but pad alternate case MODE_PAD: /* expand each frame to double height, but pad alternate
* lines with black; framerate unchanged */ * lines with black; framerate unchanged */
out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(out, cur); avfilter_copy_buffer_ref_props(out, cur);
out->video->h = outlink->h; out->video->h = outlink->h;
@ -233,9 +270,9 @@ static void end_frame(AVFilterLink *inlink)
/* interleave upper/lower lines from odd frames with lower/upper lines from even frames, /* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
* halving the frame rate and preserving image height */ * halving the frame rate and preserving image height */
case 4: /* top field first */ case MODE_INTERLEAVE_TOP: /* top field first */
case 5: /* bottom field first */ case MODE_INTERLEAVE_BOTTOM: /* bottom field first */
tff = tinterlace->mode == 4; tff = tinterlace->mode == MODE_INTERLEAVE_TOP;
out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); out = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
avfilter_copy_buffer_ref_props(out, cur); avfilter_copy_buffer_ref_props(out, cur);
out->video->interlaced = 1; out->video->interlaced = 1;
@ -253,7 +290,7 @@ static void end_frame(AVFilterLink *inlink)
tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER); tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER);
avfilter_unref_bufferp(&tinterlace->next); avfilter_unref_bufferp(&tinterlace->next);
break; break;
case 6: /* re-interlace preserving image height, double frame rate */ case MODE_INTERLACEX2: /* re-interlace preserving image height, double frame rate */
/* output current frame first */ /* output current frame first */
out = avfilter_ref_buffer(cur, AV_PERM_READ); out = avfilter_ref_buffer(cur, AV_PERM_READ);
out->video->interlaced = 1; out->video->interlaced = 1;