Message ID | 1592577334-19049-1-git-send-email-lance.lmwang@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/4] avfilter/vf_drawtext: add option to draw timecode in S12M side data | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
lance.lmwang@gmail.com (12020-06-19): > From: Limin Wang <lance.lmwang@gmail.com> > > Signed-off-by: Limin Wang <lance.lmwang@gmail.com> > --- > doc/filters.texi | 4 ++++ > libavfilter/vf_drawtext.c | 19 +++++++++++++++++++ > 2 files changed, 23 insertions(+) > > diff --git a/doc/filters.texi b/doc/filters.texi > index 5f0eb28..8334f46 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -9825,6 +9825,10 @@ If both @var{text} and @var{textfile} are specified, an error is thrown. > If set to 1, the @var{textfile} will be reloaded before each frame. > Be sure to update it atomically, or it may be read partially, or even fail. > > +@item frame_tc > +If set to 1, the timecode in S12M side data will be used for each frame > +if have, 0 otherwise I think it should be part of the text expansion mechanism, not a separate option. > + > @item x > @item y > The expressions which specify the offsets where text will be drawn > diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c > index abe1ca6..018997a 100644 > --- a/libavfilter/vf_drawtext.c > +++ b/libavfilter/vf_drawtext.c > @@ -197,6 +197,7 @@ typedef struct DrawTextContext { > AVRational tc_rate; ///< frame rate for timecode > AVTimecode tc; ///< timecode context > int tc24hmax; ///< 1 if timecode is wrapped to 24 hours, 0 otherwise > + int frame_tc; ///< 1 use timecode in S12M side data for each frame, 0 otherwise > int reload; ///< reload text file for each frame > int start_number; ///< starting frame number for n/frame_num var > #if CONFIG_LIBFRIBIDI > @@ -268,6 +269,7 @@ static const AVOption drawtext_options[]= { > { "monochrome", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME }, .flags = FLAGS, .unit = "ft_load_flags" }, > { "linear_design", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN }, .flags = FLAGS, .unit = "ft_load_flags" }, > { "no_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" }, > + {"frame_tc", "use timecode in S21M side data for each frame if have", OFFSET(frame_tc), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, > { NULL } > }; > > @@ -1327,6 +1329,23 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame, > break; > } > > + if (s->frame_tc) { > + AVFrameSideData *sd; > + > + if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { > + uint32_t *tc = (uint32_t*)sd->data; > + int m = tc[0] & 3; > + > + av_bprint_clear(bp); > + av_bprintf(bp, "%s", s->text); > + for (int j = 1; j <= m; j++) { > + char tcbuf[AV_TIMECODE_STR_SIZE]; > + av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); > + av_bprintf(bp, "%s%s", tcbuf, j != m ? ", " : ""); > + } > + } > + } > + > if (s->tc_opt_string) { > char tcbuf[AV_TIMECODE_STR_SIZE]; > av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count_out); Regards,
lance.lmwang@gmail.com (12020-06-19): > From: Limin Wang <lance.lmwang@gmail.com> > > Signed-off-by: Limin Wang <lance.lmwang@gmail.com> > --- > doc/APIchanges | 3 +++ > libavcodec/avpacket.c | 1 + > libavcodec/decode.c | 1 + > libavcodec/packet.h | 8 ++++++++ > libavcodec/version.h | 2 +- > libavformat/dump.c | 22 ++++++++++++++++++++++ > 6 files changed, 36 insertions(+), 1 deletion(-) Should come before the patches that use it. Regards,
On Fri, Jun 19, 2020 at 04:46:56PM +0200, Nicolas George wrote: > lance.lmwang@gmail.com (12020-06-19): > > From: Limin Wang <lance.lmwang@gmail.com> > > > > Signed-off-by: Limin Wang <lance.lmwang@gmail.com> > > --- > > doc/APIchanges | 3 +++ > > libavcodec/avpacket.c | 1 + > > libavcodec/decode.c | 1 + > > libavcodec/packet.h | 8 ++++++++ > > libavcodec/version.h | 2 +- > > libavformat/dump.c | 22 ++++++++++++++++++++++ > > 6 files changed, 36 insertions(+), 1 deletion(-) > > Should come before the patches that use it. Sorry, I'm not very clear of your question for the #4 of patchset will use it? > > Regards, > > -- > Nicolas George
On Fri, Jun 19, 2020 at 04:45:34PM +0200, Nicolas George wrote: > lance.lmwang@gmail.com (12020-06-19): > > From: Limin Wang <lance.lmwang@gmail.com> > > > > Signed-off-by: Limin Wang <lance.lmwang@gmail.com> > > --- > > doc/filters.texi | 4 ++++ > > libavfilter/vf_drawtext.c | 19 +++++++++++++++++++ > > 2 files changed, 23 insertions(+) > > > > diff --git a/doc/filters.texi b/doc/filters.texi > > index 5f0eb28..8334f46 100644 > > --- a/doc/filters.texi > > +++ b/doc/filters.texi > > @@ -9825,6 +9825,10 @@ If both @var{text} and @var{textfile} are specified, an error is thrown. > > If set to 1, the @var{textfile} will be reloaded before each frame. > > Be sure to update it atomically, or it may be read partially, or even fail. > > > > > +@item frame_tc > > +If set to 1, the timecode in S12M side data will be used for each frame > > +if have, 0 otherwise > > I think it should be part of the text expansion mechanism, not a > separate option. I'm not clear how to do yet, I'll study for the text expansion mechanism. > > > + > > @item x > > @item y > > The expressions which specify the offsets where text will be drawn > > diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c > > index abe1ca6..018997a 100644 > > --- a/libavfilter/vf_drawtext.c > > +++ b/libavfilter/vf_drawtext.c > > @@ -197,6 +197,7 @@ typedef struct DrawTextContext { > > AVRational tc_rate; ///< frame rate for timecode > > AVTimecode tc; ///< timecode context > > int tc24hmax; ///< 1 if timecode is wrapped to 24 hours, 0 otherwise > > + int frame_tc; ///< 1 use timecode in S12M side data for each frame, 0 otherwise > > int reload; ///< reload text file for each frame > > int start_number; ///< starting frame number for n/frame_num var > > #if CONFIG_LIBFRIBIDI > > @@ -268,6 +269,7 @@ static const AVOption drawtext_options[]= { > > { "monochrome", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME }, .flags = FLAGS, .unit = "ft_load_flags" }, > > { "linear_design", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN }, .flags = FLAGS, .unit = "ft_load_flags" }, > > { "no_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" }, > > + {"frame_tc", "use timecode in S21M side data for each frame if have", OFFSET(frame_tc), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, > > { NULL } > > }; > > > > @@ -1327,6 +1329,23 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame, > > break; > > } > > > > + if (s->frame_tc) { > > + AVFrameSideData *sd; > > + > > + if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { > > + uint32_t *tc = (uint32_t*)sd->data; > > + int m = tc[0] & 3; > > + > > + av_bprint_clear(bp); > > + av_bprintf(bp, "%s", s->text); > > + for (int j = 1; j <= m; j++) { > > + char tcbuf[AV_TIMECODE_STR_SIZE]; > > + av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); > > + av_bprintf(bp, "%s%s", tcbuf, j != m ? ", " : ""); > > + } > > + } > > + } > > + > > if (s->tc_opt_string) { > > char tcbuf[AV_TIMECODE_STR_SIZE]; > > av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count_out); > > Regards, > > -- > Nicolas George
On Fri, Jun 19, 2020 at 04:45:34PM +0200, Nicolas George wrote: > lance.lmwang@gmail.com (12020-06-19): > > From: Limin Wang <lance.lmwang@gmail.com> > > > > Signed-off-by: Limin Wang <lance.lmwang@gmail.com> > > --- > > doc/filters.texi | 4 ++++ > > libavfilter/vf_drawtext.c | 19 +++++++++++++++++++ > > 2 files changed, 23 insertions(+) > > > > diff --git a/doc/filters.texi b/doc/filters.texi > > index 5f0eb28..8334f46 100644 > > --- a/doc/filters.texi > > +++ b/doc/filters.texi > > @@ -9825,6 +9825,10 @@ If both @var{text} and @var{textfile} are specified, an error is thrown. > > If set to 1, the @var{textfile} will be reloaded before each frame. > > Be sure to update it atomically, or it may be read partially, or even fail. > > > > > +@item frame_tc > > +If set to 1, the timecode in S12M side data will be used for each frame > > +if have, 0 otherwise > > I think it should be part of the text expansion mechanism, not a > separate option. Thanks for the suggestion, I have changed to use metadata to display the timecode without any change to vf_drawtext.c. So please ignore the patch, I'll submit timecode metadata patchset for h264/hevc later. > > > + > > @item x > > @item y > > The expressions which specify the offsets where text will be drawn > > diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c > > index abe1ca6..018997a 100644 > > --- a/libavfilter/vf_drawtext.c > > +++ b/libavfilter/vf_drawtext.c > > @@ -197,6 +197,7 @@ typedef struct DrawTextContext { > > AVRational tc_rate; ///< frame rate for timecode > > AVTimecode tc; ///< timecode context > > int tc24hmax; ///< 1 if timecode is wrapped to 24 hours, 0 otherwise > > + int frame_tc; ///< 1 use timecode in S12M side data for each frame, 0 otherwise > > int reload; ///< reload text file for each frame > > int start_number; ///< starting frame number for n/frame_num var > > #if CONFIG_LIBFRIBIDI > > @@ -268,6 +269,7 @@ static const AVOption drawtext_options[]= { > > { "monochrome", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME }, .flags = FLAGS, .unit = "ft_load_flags" }, > > { "linear_design", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN }, .flags = FLAGS, .unit = "ft_load_flags" }, > > { "no_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" }, > > + {"frame_tc", "use timecode in S21M side data for each frame if have", OFFSET(frame_tc), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, > > { NULL } > > }; > > > > @@ -1327,6 +1329,23 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame, > > break; > > } > > > > + if (s->frame_tc) { > > + AVFrameSideData *sd; > > + > > + if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { > > + uint32_t *tc = (uint32_t*)sd->data; > > + int m = tc[0] & 3; > > + > > + av_bprint_clear(bp); > > + av_bprintf(bp, "%s", s->text); > > + for (int j = 1; j <= m; j++) { > > + char tcbuf[AV_TIMECODE_STR_SIZE]; > > + av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); > > + av_bprintf(bp, "%s%s", tcbuf, j != m ? ", " : ""); > > + } > > + } > > + } > > + > > if (s->tc_opt_string) { > > char tcbuf[AV_TIMECODE_STR_SIZE]; > > av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count_out); > > Regards, > > -- > Nicolas George
lance.lmwang@gmail.com (12020-06-20): > Thanks for the suggestion, I have changed to use metadata to display the timecode without > any change to vf_drawtext.c. So please ignore the patch, I'll submit timecode metadata > patchset for h264/hevc later. If you are sure it is a good idea to do it like that, ok. Regards,
diff --git a/doc/filters.texi b/doc/filters.texi index 5f0eb28..8334f46 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -9825,6 +9825,10 @@ If both @var{text} and @var{textfile} are specified, an error is thrown. If set to 1, the @var{textfile} will be reloaded before each frame. Be sure to update it atomically, or it may be read partially, or even fail. +@item frame_tc +If set to 1, the timecode in S12M side data will be used for each frame +if have, 0 otherwise + @item x @item y The expressions which specify the offsets where text will be drawn diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index abe1ca6..018997a 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -197,6 +197,7 @@ typedef struct DrawTextContext { AVRational tc_rate; ///< frame rate for timecode AVTimecode tc; ///< timecode context int tc24hmax; ///< 1 if timecode is wrapped to 24 hours, 0 otherwise + int frame_tc; ///< 1 use timecode in S12M side data for each frame, 0 otherwise int reload; ///< reload text file for each frame int start_number; ///< starting frame number for n/frame_num var #if CONFIG_LIBFRIBIDI @@ -268,6 +269,7 @@ static const AVOption drawtext_options[]= { { "monochrome", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME }, .flags = FLAGS, .unit = "ft_load_flags" }, { "linear_design", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN }, .flags = FLAGS, .unit = "ft_load_flags" }, { "no_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" }, + {"frame_tc", "use timecode in S21M side data for each frame if have", OFFSET(frame_tc), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, { NULL } }; @@ -1327,6 +1329,23 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame, break; } + if (s->frame_tc) { + AVFrameSideData *sd; + + if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { + uint32_t *tc = (uint32_t*)sd->data; + int m = tc[0] & 3; + + av_bprint_clear(bp); + av_bprintf(bp, "%s", s->text); + for (int j = 1; j <= m; j++) { + char tcbuf[AV_TIMECODE_STR_SIZE]; + av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); + av_bprintf(bp, "%s%s", tcbuf, j != m ? ", " : ""); + } + } + } + if (s->tc_opt_string) { char tcbuf[AV_TIMECODE_STR_SIZE]; av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count_out);