diff mbox series

[FFmpeg-devel,1/4] avfilter/vf_drawtext: add option to draw timecode in S12M side data

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

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Lance Wang June 19, 2020, 2:35 p.m. UTC
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(+)

Comments

Nicolas George June 19, 2020, 2:45 p.m. UTC | #1
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,
Nicolas George June 19, 2020, 2:46 p.m. UTC | #2
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,
Lance Wang June 19, 2020, 3:04 p.m. UTC | #3
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
Lance Wang June 19, 2020, 3:10 p.m. UTC | #4
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
Lance Wang June 20, 2020, 12:34 p.m. UTC | #5
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
Nicolas George June 20, 2020, 12:36 p.m. UTC | #6
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 mbox series

Patch

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);