[FFmpeg-devel] [PATCH] Add "split" mode to tinterlace filter.
Paul B Mahol
onemda at gmail.com
Sun Mar 29 04:48:59 CEST 2015
Dana 28. 3. 2015. 23:35 osoba "Brian Matherly" <code at brianmatherly.com>
napisala je:
>
> From: Brian Matherly <pez4brian at yahoo.com>
>
> This mode is the opposite of the "merge" mode.
> ---
> This patch adds a new mode to tinterlace which performs the opposite
operation
> as the "merge" mode.
>
> My primary motivation is that I have been working with Derek Buitenhuis
to see
> about adding interlace support to the libx265 encoder. It turns out that
this is
> a complex situation since libx265 requires each field to be encoded
separately
> but ffmpeg stores fields together as an interlaced frame. tinterlace can
be used
> with this new mode to provide each field as a separate frame to libx265 -
and
> therefore perform valid interlaced h.265 encoding.
>
> At first I considered this patch a hack and planned on keeping it to
myself. But
> now I think that it must be generally useful since it can produce the
exact
> format of data that would be the input to the tinterlace "merge" mode.
> As a test, I have checked:
> ffmpeg -i input.file -vf "tinterlace=split,tinterlace=merge"
output.file
> And the image makes a successful round trip.
What about separatefields filter?
> doc/filters.texi | 24 ++++++++++++++++++++++++
> libavfilter/tinterlace.h | 1 +
> libavfilter/vf_tinterlace.c | 43
+++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 66 insertions(+), 2 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 15f8ed5..9b3fd02 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -9197,6 +9197,30 @@ Output:
> 11111 11111 22222 22222 33333 33333 44444
> @end example
>
> + at item split, 7
> +Perform the inverse operation as merge. Move upper field to odd frames,
lower
> +field to even frames, generating a half height frame at double frame
rate.
> + at example
> + ------> time
> +Input:
> +Frame 1 Frame 2
> +11111 33333
> +22222 44444
> +11111 33333
> +22222 44444
> +11111 33333
> +22222 44444
> +11111 33333
> +22222 44444
> +
> +Output:
> +Frame 1 Frame 2 Frame 3 Frame 4
> +11111 22222 33333 44444
> +11111 22222 33333 44444
> +11111 22222 33333 44444
> +11111 22222 33333 44444
> + at end example
> +
>
> @end table
>
> diff --git a/libavfilter/tinterlace.h b/libavfilter/tinterlace.h
> index fa0a83a..ece8ce4 100644
> --- a/libavfilter/tinterlace.h
> +++ b/libavfilter/tinterlace.h
> @@ -38,6 +38,7 @@ enum TInterlaceMode {
> MODE_INTERLEAVE_TOP,
> MODE_INTERLEAVE_BOTTOM,
> MODE_INTERLACEX2,
> + MODE_SPLIT,
> MODE_NB,
> };
>
> diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
> index f3411f9..2c9047b 100644
> --- a/libavfilter/vf_tinterlace.c
> +++ b/libavfilter/vf_tinterlace.c
> @@ -46,6 +46,7 @@ static const AVOption tinterlace_options[] = {
> {"interleave_top", "interleave top and bottom fields",
0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_TOP}, INT_MIN, INT_MAX,
FLAGS, "mode"},
> {"interleave_bottom", "interleave bottom and top fields",
0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_BOTTOM}, INT_MIN, INT_MAX,
FLAGS, "mode"},
> {"interlacex2", "interlace fields from two consecutive
frames", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLACEX2}, INT_MIN,
INT_MAX, FLAGS, "mode"},
> + {"split", "split fields",
0, AV_OPT_TYPE_CONST, {.i64=MODE_SPLIT}, INT_MIN, INT_MAX,
FLAGS, "mode"},
>
> {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = 0}, 0, INT_MAX, 0, "flags" },
> {"low_pass_filter", "enable vertical low-pass filter",
0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX,
FLAGS, "flags" },
> @@ -118,7 +119,8 @@ static int config_out_props(AVFilterLink *outlink)
> outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
> outlink->w = inlink->w;
> outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode ==
MODE_PAD ?
> - inlink->h*2 : inlink->h;
> + inlink->h*2 : tinterlace->mode == MODE_SPLIT ?
> + inlink->h/2 : inlink->h;
>
> if (tinterlace->mode == MODE_PAD) {
> uint8_t black[4] = { 16, 128, 128, 16 };
> @@ -145,7 +147,7 @@ static int config_out_props(AVFilterLink *outlink)
> tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
> }
> tinterlace->preout_time_base = inlink->time_base;
> - if (tinterlace->mode == MODE_INTERLACEX2) {
> + if (tinterlace->mode == MODE_INTERLACEX2 || tinterlace->mode ==
MODE_SPLIT) {
> tinterlace->preout_time_base.den *= 2;
> outlink->frame_rate = av_mul_q(inlink->frame_rate,
(AVRational){2,1});
> outlink->time_base = av_mul_q(inlink->time_base ,
(AVRational){1,2});
> @@ -372,6 +374,43 @@ static int filter_frame(AVFilterLink *inlink,
AVFrame *picref)
> tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ?
FIELD_UPPER : FIELD_LOWER,
> tinterlace->flags);
> break;
> + case MODE_SPLIT: /* move the upper field into the new odd frame,
lower into the new
> + * even frame, generating a half-height video at
double framerate */
> + /* output upper field first */
> + out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> + if (!out)
> + return AVERROR(ENOMEM);
> + av_frame_copy_props(out, cur);
> + out->height = outlink->h;
> + out->interlaced_frame = 0;
> + if (cur->pts != AV_NOPTS_VALUE)
> + out->pts = cur->pts*2;
> + out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base,
outlink->time_base);
> + /* write upper field lines into the new odd frame */
> + copy_picture_field(tinterlace, out->data, out->linesize,
> + (const uint8_t **)cur->data, cur->linesize,
> + inlink->format, inlink->w, inlink->h,
> + FIELD_UPPER, 0, FIELD_UPPER_AND_LOWER,
tinterlace->flags);
> + if ((ret = ff_filter_frame(outlink, out)) < 0)
> + return ret;
> +
> + /* output lower field */
> + out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> + if (!out)
> + return AVERROR(ENOMEM);
> + av_frame_copy_props(out, cur);
> + out->height = outlink->h;
> + out->interlaced_frame = 0;
> + if (next->pts != AV_NOPTS_VALUE && cur->pts != AV_NOPTS_VALUE)
> + out->pts = cur->pts + next->pts;
> + else
> + out->pts = AV_NOPTS_VALUE;
> + /* write lower field lines into the new even frame */
> + copy_picture_field(tinterlace, out->data, out->linesize,
> + (const uint8_t **)cur->data, cur->linesize,
> + inlink->format, inlink->w, inlink->h,
> + FIELD_LOWER, 0, FIELD_UPPER_AND_LOWER,
tinterlace->flags);
> + break;
> default:
> av_assert0(0);
> }
> --
> 1.9.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
More information about the ffmpeg-devel
mailing list