Message ID | 20200406175218.1299994-11-jstebbins@jetheaddev.com |
---|---|
State | Accepted |
Headers | show |
Series | [FFmpeg-devel,01/23] lavc/movtextdec: fix ass header colors | expand |
Context | Check | Description |
---|---|---|
andriy/ffmpeg-patchwork | warning | Failed to apply patch |
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
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 --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,