Dana 28. 3. 2015. 23:35 osoba "Brian Matherly" <c...@brianmatherly.com> napisala je: > > From: Brian Matherly <pez4br...@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 > > +@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. > +@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 > +@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@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel