diff mbox series

[FFmpeg-devel,10/23] lavc/movtextdec: allow setting subtitle frame dimensions

Message ID 20200406175218.1299994-11-jstebbins@jetheaddev.com
State Accepted
Headers show
Series [FFmpeg-devel,01/23] lavc/movtextdec: fix ass header colors | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork warning Failed to apply patch

Commit Message

John Stebbins April 6, 2020, 5:52 p.m. UTC
Font sizes are relative to the subtitle frame dimensions. If the
expected frame dimensions are not known, the font sizes will most
likely be incorrect.
---
 libavcodec/ass.c        | 30 +++++++++++++++++++++++-------
 libavcodec/ass.h        | 28 ++++++++++++++++++++++++++++
 libavcodec/movtextdec.c | 30 +++++++++++++++++++++++++++++-
 3 files changed, 80 insertions(+), 8 deletions(-)

Comments

Philip Langdale April 8, 2020, 5:31 p.m. UTC | #1
On Mon, 6 Apr 2020 11:52:05 -0600
John Stebbins <jstebbins@jetheaddev.com> wrote:

> Font sizes are relative to the subtitle frame dimensions. If the
> expected frame dimensions are not known, the font sizes will most
> likely be incorrect.
> ---
>  libavcodec/ass.c        | 30 +++++++++++++++++++++++-------
>  libavcodec/ass.h        | 28 ++++++++++++++++++++++++++++
>  libavcodec/movtextdec.c | 30 +++++++++++++++++++++++++++++-
>  3 files changed, 80 insertions(+), 8 deletions(-)
> 
> diff --git a/libavcodec/ass.c b/libavcodec/ass.c
> index a51673fb4e..7c26e3fd6d 100644
> --- a/libavcodec/ass.c
> +++ b/libavcodec/ass.c
> @@ -26,11 +26,13 @@
>  #include "libavutil/bprint.h"
>  #include "libavutil/common.h"
>  
> -int ff_ass_subtitle_header(AVCodecContext *avctx,
> -                           const char *font, int font_size,
> -                           int color, int back_color,
> -                           int bold, int italic, int underline,
> -                           int border_style, int alignment)
> +int ff_ass_subtitle_header_full(AVCodecContext *avctx,
> +                                int play_res_x, int play_res_y,
> +                                const char *font, int font_size,
> +                                int primary_color, int
> secondary_color,
> +                                int outline_color, int back_color,
> +                                int bold, int italic, int underline,
> +                                int border_style, int alignment)
>  {
>      avctx->subtitle_header = av_asprintf(
>               "[Script Info]\r\n"
> @@ -67,8 +69,8 @@ int ff_ass_subtitle_header(AVCodecContext *avctx,
>               "[Events]\r\n"
>               "Format: Layer, Start, End, Style, Name, MarginL,
> MarginR, MarginV, Effect, Text\r\n", !(avctx->flags &
> AV_CODEC_FLAG_BITEXACT) ? AV_STRINGIFY(LIBAVCODEC_VERSION) : "",
> -             ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY,
> -             font, font_size, color, color, back_color, back_color,
> +             play_res_x, play_res_y, font, font_size,
> +             primary_color, secondary_color, outline_color,
> back_color, -bold, -italic, -underline, border_style, alignment);
>  
>      if (!avctx->subtitle_header)
> @@ -77,6 +79,20 @@ int ff_ass_subtitle_header(AVCodecContext *avctx,
>      return 0;
>  }
>  
> +int ff_ass_subtitle_header(AVCodecContext *avctx,
> +                           const char *font, int font_size,
> +                           int color, int back_color,
> +                           int bold, int italic, int underline,
> +                           int border_style, int alignment)
> +{
> +    return ff_ass_subtitle_header_full(avctx,
> +                               ASS_DEFAULT_PLAYRESX,
> ASS_DEFAULT_PLAYRESY,
> +                               font, font_size, color, color,
> +                               back_color, back_color,
> +                               bold, italic, underline,
> +                               border_style, alignment);
> +}
> +
>  int ff_ass_subtitle_header_default(AVCodecContext *avctx)
>  {
>      return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT,
> diff --git a/libavcodec/ass.h b/libavcodec/ass.h
> index 314b43b686..2c260e4e78 100644
> --- a/libavcodec/ass.h
> +++ b/libavcodec/ass.h
> @@ -47,6 +47,34 @@ typedef struct FFASSDecoderContext {
>      int readorder;
>  } FFASSDecoderContext;
>  
> +/**
> + * Generate a suitable AVCodecContext.subtitle_header for
> SUBTITLE_ASS.
> + * Can specify all fields explicitly
> + *
> + * @param avctx pointer to the AVCodecContext
> + * @param play_res_x subtitle frame width
> + * @param play_res_y subtitle frame height
> + * @param font name of the default font face to use
> + * @param font_size default font size to use
> + * @param primary_color default text color to use (ABGR)
> + * @param secondary_color default secondary text color to use (ABGR)
> + * @param outline_color default outline color to use (ABGR)
> + * @param back_color default background color to use (ABGR)
> + * @param bold 1 for bold text, 0 for normal text
> + * @param italic 1 for italic text, 0 for normal text
> + * @param underline 1 for underline text, 0 for normal text
> + * @param border_style 1 for outline, 3 for opaque box
> + * @param alignment position of the text (left, center, top...),
> defined after
> + *                  the layout of the numpad (1-3 sub, 4-6 mid, 7-9
> top)
> + * @return >= 0 on success otherwise an error code <0
> + */
> +int ff_ass_subtitle_header_full(AVCodecContext *avctx,
> +                                int play_res_x, int play_res_y,
> +                                const char *font, int font_size,
> +                                int primary_color, int
> secondary_color,
> +                                int outline_color, int back_color,
> +                                int bold, int italic, int underline,
> +                                int border_style, int alignment);
>  /**
>   * Generate a suitable AVCodecContext.subtitle_header for
> SUBTITLE_ASS. *
> diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
> index f3a504b47b..4b4da5e0d9 100644
> --- a/libavcodec/movtextdec.c
> +++ b/libavcodec/movtextdec.c
> @@ -21,6 +21,7 @@
>  
>  #include "avcodec.h"
>  #include "ass.h"
> +#include "libavutil/opt.h"
>  #include "libavutil/avstring.h"
>  #include "libavutil/common.h"
>  #include "libavutil/bprint.h"
> @@ -96,6 +97,7 @@ typedef struct {
>  } TextWrapBox;
>  
>  typedef struct {
> +    AVClass *class;
>      StyleBox **s;
>      StyleBox *s_temp;
>      HighlightBox h;
> @@ -110,6 +112,8 @@ typedef struct {
>      int size_var;
>      int count_s, count_f;
>      int readorder;
> +    int frame_width;
> +    int frame_height;
>  } MovTextContext;
>  
>  typedef struct {
> @@ -481,9 +485,17 @@ static int mov_text_init(AVCodecContext *avctx) {
>      MovTextContext *m = avctx->priv_data;
>      ret = mov_text_tx3g(avctx, m);
>      if (ret == 0) {
> -        return ff_ass_subtitle_header(avctx, m->d.font,
> m->d.fontsize,
> +        if (!m->frame_width || !m->frame_height) {
> +            m->frame_width = ASS_DEFAULT_PLAYRESX;
> +            m->frame_height = ASS_DEFAULT_PLAYRESY;
> +        }
> +        return ff_ass_subtitle_header_full(avctx,
> +                    m->frame_width, m->frame_height,
> +                    m->d.font, m->d.fontsize,
> +                    (255 - m->d.alpha) << 24 |
> RGB_TO_BGR(m->d.color), (255 - m->d.alpha) << 24 |
> RGB_TO_BGR(m->d.color), (255 - m->d.back_alpha) << 24 |
> RGB_TO_BGR(m->d.back_color),
> +                    (255 - m->d.back_alpha) << 24 |
> RGB_TO_BGR(m->d.back_color), m->d.bold, m->d.italic, m->d.underline,
>                      ASS_DEFAULT_BORDERSTYLE, m->d.alignment);
>      } else
> @@ -601,12 +613,28 @@ static void mov_text_flush(AVCodecContext
> *avctx) m->readorder = 0;
>  }
>  
> +#define OFFSET(x) offsetof(MovTextContext, x)
> +#define FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
> +static const AVOption options[] = {
> +    { "width", "Frame width, usually video width",
> OFFSET(frame_width), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
> +    { "height", "Frame height, usually video height",
> OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
> +    { NULL },
> +};
> +
> +static const AVClass mov_text_decoder_class = {
> +    .class_name = "MOV text decoder",
> +    .item_name  = av_default_item_name,
> +    .option     = options,
> +    .version    = LIBAVUTIL_VERSION_INT,
> +};
> +
>  AVCodec ff_movtext_decoder = {
>      .name         = "mov_text",
>      .long_name    = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
>      .type         = AVMEDIA_TYPE_SUBTITLE,
>      .id           = AV_CODEC_ID_MOV_TEXT,
>      .priv_data_size = sizeof(MovTextContext),
> +    .priv_class   = &mov_text_decoder_class,
>      .init         = mov_text_init,
>      .decode       = mov_text_decode_frame,
>      .close        = mov_text_decode_close,


LGTM. When I last looked at frame dimensions, I could never
find a sane way to set these values to the actual video frame
dimensions. I'm guess you couldn't either? :-)

--phil
John Stebbins April 8, 2020, 11:05 p.m. UTC | #2
On Wed, 2020-04-08 at 10:31 -0700, Philip Langdale wrote:
> On Mon, 6 Apr 2020 11:52:05 -0600
> John Stebbins <jstebbins@jetheaddev.com> wrote:
> 
> > Font sizes are relative to the subtitle frame dimensions. If the
> > expected frame dimensions are not known, the font sizes will most
> > likely be incorrect.
> > ---
> >  libavcodec/ass.c        | 30 +++++++++++++++++++++++-------
> >  libavcodec/ass.h        | 28 ++++++++++++++++++++++++++++
> >  libavcodec/movtextdec.c | 30 +++++++++++++++++++++++++++++-
> >  3 files changed, 80 insertions(+), 8 deletions(-)
> > 
> > diff --git a/libavcodec/ass.c b/libavcodec/ass.c
> > index a51673fb4e..7c26e3fd6d 100644
> > --- a/libavcodec/ass.c
> > +++ b/libavcodec/ass.c
> > @@ -26,11 +26,13 @@
> >  #include "libavutil/bprint.h"
> >  #include "libavutil/common.h"
> >  
> > -int ff_ass_subtitle_header(AVCodecContext *avctx,
> > -                           const char *font, int font_size,
> > -                           int color, int back_color,
> > -                           int bold, int italic, int underline,
> > -                           int border_style, int alignment)
> > +int ff_ass_subtitle_header_full(AVCodecContext *avctx,
> > +                                int play_res_x, int play_res_y,
> > +                                const char *font, int font_size,
> > +                                int primary_color, int
> > secondary_color,
> > +                                int outline_color, int back_color,
> > +                                int bold, int italic, int
> > underline,
> > +                                int border_style, int alignment)
> >  {
> >      avctx->subtitle_header = av_asprintf(
> >               "[Script Info]\r\n"
> > @@ -67,8 +69,8 @@ int ff_ass_subtitle_header(AVCodecContext *avctx,
> >               "[Events]\r\n"
> >               "Format: Layer, Start, End, Style, Name, MarginL,
> > MarginR, MarginV, Effect, Text\r\n", !(avctx->flags &
> > AV_CODEC_FLAG_BITEXACT) ? AV_STRINGIFY(LIBAVCODEC_VERSION) : "",
> > -             ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY,
> > -             font, font_size, color, color, back_color,
> > back_color,
> > +             play_res_x, play_res_y, font, font_size,
> > +             primary_color, secondary_color, outline_color,
> > back_color, -bold, -italic, -underline, border_style, alignment);
> >  
> >      if (!avctx->subtitle_header)
> > @@ -77,6 +79,20 @@ int ff_ass_subtitle_header(AVCodecContext
> > *avctx,
> >      return 0;
> >  }
> >  
> > +int ff_ass_subtitle_header(AVCodecContext *avctx,
> > +                           const char *font, int font_size,
> > +                           int color, int back_color,
> > +                           int bold, int italic, int underline,
> > +                           int border_style, int alignment)
> > +{
> > +    return ff_ass_subtitle_header_full(avctx,
> > +                               ASS_DEFAULT_PLAYRESX,
> > ASS_DEFAULT_PLAYRESY,
> > +                               font, font_size, color, color,
> > +                               back_color, back_color,
> > +                               bold, italic, underline,
> > +                               border_style, alignment);
> > +}
> > +
> >  int ff_ass_subtitle_header_default(AVCodecContext *avctx)
> >  {
> >      return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT,
> > diff --git a/libavcodec/ass.h b/libavcodec/ass.h
> > index 314b43b686..2c260e4e78 100644
> > --- a/libavcodec/ass.h
> > +++ b/libavcodec/ass.h
> > @@ -47,6 +47,34 @@ typedef struct FFASSDecoderContext {
> >      int readorder;
> >  } FFASSDecoderContext;
> >  
> > +/**
> > + * Generate a suitable AVCodecContext.subtitle_header for
> > SUBTITLE_ASS.
> > + * Can specify all fields explicitly
> > + *
> > + * @param avctx pointer to the AVCodecContext
> > + * @param play_res_x subtitle frame width
> > + * @param play_res_y subtitle frame height
> > + * @param font name of the default font face to use
> > + * @param font_size default font size to use
> > + * @param primary_color default text color to use (ABGR)
> > + * @param secondary_color default secondary text color to use
> > (ABGR)
> > + * @param outline_color default outline color to use (ABGR)
> > + * @param back_color default background color to use (ABGR)
> > + * @param bold 1 for bold text, 0 for normal text
> > + * @param italic 1 for italic text, 0 for normal text
> > + * @param underline 1 for underline text, 0 for normal text
> > + * @param border_style 1 for outline, 3 for opaque box
> > + * @param alignment position of the text (left, center, top...),
> > defined after
> > + *                  the layout of the numpad (1-3 sub, 4-6 mid, 7-
> > 9
> > top)
> > + * @return >= 0 on success otherwise an error code <0
> > + */
> > +int ff_ass_subtitle_header_full(AVCodecContext *avctx,
> > +                                int play_res_x, int play_res_y,
> > +                                const char *font, int font_size,
> > +                                int primary_color, int
> > secondary_color,
> > +                                int outline_color, int back_color,
> > +                                int bold, int italic, int
> > underline,
> > +                                int border_style, int alignment);
> >  /**
> >   * Generate a suitable AVCodecContext.subtitle_header for
> > SUBTITLE_ASS. *
> > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
> > index f3a504b47b..4b4da5e0d9 100644
> > --- a/libavcodec/movtextdec.c
> > +++ b/libavcodec/movtextdec.c
> > @@ -21,6 +21,7 @@
> >  
> >  #include "avcodec.h"
> >  #include "ass.h"
> > +#include "libavutil/opt.h"
> >  #include "libavutil/avstring.h"
> >  #include "libavutil/common.h"
> >  #include "libavutil/bprint.h"
> > @@ -96,6 +97,7 @@ typedef struct {
> >  } TextWrapBox;
> >  
> >  typedef struct {
> > +    AVClass *class;
> >      StyleBox **s;
> >      StyleBox *s_temp;
> >      HighlightBox h;
> > @@ -110,6 +112,8 @@ typedef struct {
> >      int size_var;
> >      int count_s, count_f;
> >      int readorder;
> > +    int frame_width;
> > +    int frame_height;
> >  } MovTextContext;
> >  
> >  typedef struct {
> > @@ -481,9 +485,17 @@ static int mov_text_init(AVCodecContext
> > *avctx) {
> >      MovTextContext *m = avctx->priv_data;
> >      ret = mov_text_tx3g(avctx, m);
> >      if (ret == 0) {
> > -        return ff_ass_subtitle_header(avctx, m->d.font,
> > m->d.fontsize,
> > +        if (!m->frame_width || !m->frame_height) {
> > +            m->frame_width = ASS_DEFAULT_PLAYRESX;
> > +            m->frame_height = ASS_DEFAULT_PLAYRESY;
> > +        }
> > +        return ff_ass_subtitle_header_full(avctx,
> > +                    m->frame_width, m->frame_height,
> > +                    m->d.font, m->d.fontsize,
> > +                    (255 - m->d.alpha) << 24 |
> > RGB_TO_BGR(m->d.color), (255 - m->d.alpha) << 24 |
> > RGB_TO_BGR(m->d.color), (255 - m->d.back_alpha) << 24 |
> > RGB_TO_BGR(m->d.back_color),
> > +                    (255 - m->d.back_alpha) << 24 |
> > RGB_TO_BGR(m->d.back_color), m->d.bold, m->d.italic, m-
> > >d.underline,
> >                      ASS_DEFAULT_BORDERSTYLE, m->d.alignment);
> >      } else
> > @@ -601,12 +613,28 @@ static void mov_text_flush(AVCodecContext
> > *avctx) m->readorder = 0;
> >  }
> >  
> > +#define OFFSET(x) offsetof(MovTextContext, x)
> > +#define FLAGS AV_OPT_FLAG_DECODING_PARAM |
> > AV_OPT_FLAG_SUBTITLE_PARAM
> > +static const AVOption options[] = {
> > +    { "width", "Frame width, usually video width",
> > OFFSET(frame_width), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS
> > },
> > +    { "height", "Frame height, usually video height",
> > OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS
> > },
> > +    { NULL },
> > +};
> > +
> > +static const AVClass mov_text_decoder_class = {
> > +    .class_name = "MOV text decoder",
> > +    .item_name  = av_default_item_name,
> > +    .option     = options,
> > +    .version    = LIBAVUTIL_VERSION_INT,
> > +};
> > +
> >  AVCodec ff_movtext_decoder = {
> >      .name         = "mov_text",
> >      .long_name    = NULL_IF_CONFIG_SMALL("3GPP Timed Text
> > subtitle"),
> >      .type         = AVMEDIA_TYPE_SUBTITLE,
> >      .id           = AV_CODEC_ID_MOV_TEXT,
> >      .priv_data_size = sizeof(MovTextContext),
> > +    .priv_class   = &mov_text_decoder_class,
> >      .init         = mov_text_init,
> >      .decode       = mov_text_decode_frame,
> >      .close        = mov_text_decode_close,
> 
> LGTM. When I last looked at frame dimensions, I could never
> find a sane way to set these values to the actual video frame
> dimensions. I'm guess you couldn't either? :-)
> 
> 

They could also be provided through AVCodecContext.with/height.  But I
thought this made the API more clear and provides a way to give some
help text.

But yeah, since this is information that relates to a completely
different stream, there's no automatic way to get this information. It
must be supplied by higher level code.
diff mbox series

Patch

diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index a51673fb4e..7c26e3fd6d 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -26,11 +26,13 @@ 
 #include "libavutil/bprint.h"
 #include "libavutil/common.h"
 
-int ff_ass_subtitle_header(AVCodecContext *avctx,
-                           const char *font, int font_size,
-                           int color, int back_color,
-                           int bold, int italic, int underline,
-                           int border_style, int alignment)
+int ff_ass_subtitle_header_full(AVCodecContext *avctx,
+                                int play_res_x, int play_res_y,
+                                const char *font, int font_size,
+                                int primary_color, int secondary_color,
+                                int outline_color, int back_color,
+                                int bold, int italic, int underline,
+                                int border_style, int alignment)
 {
     avctx->subtitle_header = av_asprintf(
              "[Script Info]\r\n"
@@ -67,8 +69,8 @@  int ff_ass_subtitle_header(AVCodecContext *avctx,
              "[Events]\r\n"
              "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n",
              !(avctx->flags & AV_CODEC_FLAG_BITEXACT) ? AV_STRINGIFY(LIBAVCODEC_VERSION) : "",
-             ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY,
-             font, font_size, color, color, back_color, back_color,
+             play_res_x, play_res_y, font, font_size,
+             primary_color, secondary_color, outline_color, back_color,
              -bold, -italic, -underline, border_style, alignment);
 
     if (!avctx->subtitle_header)
@@ -77,6 +79,20 @@  int ff_ass_subtitle_header(AVCodecContext *avctx,
     return 0;
 }
 
+int ff_ass_subtitle_header(AVCodecContext *avctx,
+                           const char *font, int font_size,
+                           int color, int back_color,
+                           int bold, int italic, int underline,
+                           int border_style, int alignment)
+{
+    return ff_ass_subtitle_header_full(avctx,
+                               ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY,
+                               font, font_size, color, color,
+                               back_color, back_color,
+                               bold, italic, underline,
+                               border_style, alignment);
+}
+
 int ff_ass_subtitle_header_default(AVCodecContext *avctx)
 {
     return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT,
diff --git a/libavcodec/ass.h b/libavcodec/ass.h
index 314b43b686..2c260e4e78 100644
--- a/libavcodec/ass.h
+++ b/libavcodec/ass.h
@@ -47,6 +47,34 @@  typedef struct FFASSDecoderContext {
     int readorder;
 } FFASSDecoderContext;
 
+/**
+ * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
+ * Can specify all fields explicitly
+ *
+ * @param avctx pointer to the AVCodecContext
+ * @param play_res_x subtitle frame width
+ * @param play_res_y subtitle frame height
+ * @param font name of the default font face to use
+ * @param font_size default font size to use
+ * @param primary_color default text color to use (ABGR)
+ * @param secondary_color default secondary text color to use (ABGR)
+ * @param outline_color default outline color to use (ABGR)
+ * @param back_color default background color to use (ABGR)
+ * @param bold 1 for bold text, 0 for normal text
+ * @param italic 1 for italic text, 0 for normal text
+ * @param underline 1 for underline text, 0 for normal text
+ * @param border_style 1 for outline, 3 for opaque box
+ * @param alignment position of the text (left, center, top...), defined after
+ *                  the layout of the numpad (1-3 sub, 4-6 mid, 7-9 top)
+ * @return >= 0 on success otherwise an error code <0
+ */
+int ff_ass_subtitle_header_full(AVCodecContext *avctx,
+                                int play_res_x, int play_res_y,
+                                const char *font, int font_size,
+                                int primary_color, int secondary_color,
+                                int outline_color, int back_color,
+                                int bold, int italic, int underline,
+                                int border_style, int alignment);
 /**
  * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
  *
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
index f3a504b47b..4b4da5e0d9 100644
--- a/libavcodec/movtextdec.c
+++ b/libavcodec/movtextdec.c
@@ -21,6 +21,7 @@ 
 
 #include "avcodec.h"
 #include "ass.h"
+#include "libavutil/opt.h"
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
 #include "libavutil/bprint.h"
@@ -96,6 +97,7 @@  typedef struct {
 } TextWrapBox;
 
 typedef struct {
+    AVClass *class;
     StyleBox **s;
     StyleBox *s_temp;
     HighlightBox h;
@@ -110,6 +112,8 @@  typedef struct {
     int size_var;
     int count_s, count_f;
     int readorder;
+    int frame_width;
+    int frame_height;
 } MovTextContext;
 
 typedef struct {
@@ -481,9 +485,17 @@  static int mov_text_init(AVCodecContext *avctx) {
     MovTextContext *m = avctx->priv_data;
     ret = mov_text_tx3g(avctx, m);
     if (ret == 0) {
-        return ff_ass_subtitle_header(avctx, m->d.font, m->d.fontsize,
+        if (!m->frame_width || !m->frame_height) {
+            m->frame_width = ASS_DEFAULT_PLAYRESX;
+            m->frame_height = ASS_DEFAULT_PLAYRESY;
+        }
+        return ff_ass_subtitle_header_full(avctx,
+                    m->frame_width, m->frame_height,
+                    m->d.font, m->d.fontsize,
+                    (255 - m->d.alpha) << 24 | RGB_TO_BGR(m->d.color),
                     (255 - m->d.alpha) << 24 | RGB_TO_BGR(m->d.color),
                     (255 - m->d.back_alpha) << 24 | RGB_TO_BGR(m->d.back_color),
+                    (255 - m->d.back_alpha) << 24 | RGB_TO_BGR(m->d.back_color),
                     m->d.bold, m->d.italic, m->d.underline,
                     ASS_DEFAULT_BORDERSTYLE, m->d.alignment);
     } else
@@ -601,12 +613,28 @@  static void mov_text_flush(AVCodecContext *avctx)
         m->readorder = 0;
 }
 
+#define OFFSET(x) offsetof(MovTextContext, x)
+#define FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
+static const AVOption options[] = {
+    { "width", "Frame width, usually video width", OFFSET(frame_width), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
+    { "height", "Frame height, usually video height", OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass mov_text_decoder_class = {
+    .class_name = "MOV text decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_movtext_decoder = {
     .name         = "mov_text",
     .long_name    = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
     .type         = AVMEDIA_TYPE_SUBTITLE,
     .id           = AV_CODEC_ID_MOV_TEXT,
     .priv_data_size = sizeof(MovTextContext),
+    .priv_class   = &mov_text_decoder_class,
     .init         = mov_text_init,
     .decode       = mov_text_decode_frame,
     .close        = mov_text_decode_close,