diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c index a109483a6a..58a916ae0e 100644 --- a/libavcodec/movtextenc.c +++ b/libavcodec/movtextenc.c @@ -21,6 +21,7 @@ #include #include "avcodec.h" +#include "libavutil/opt.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" @@ -45,6 +46,7 @@ #define DEFAULT_STYLE_FLAG 0x00 #define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) >> 16) & 0xff)) +#define FONTSIZE_SCALE(s,fs) ((fs) * (s)->font_scale_factor + 0.5) #define av_bprint_append_any(buf, data, size) av_bprint_append_data(buf, ((const char*)data), size) typedef struct { @@ -66,6 +68,7 @@ typedef struct { } HilightcolorBox; typedef struct { + AVClass *class; AVCodecContext *avctx; ASSSplitContext *ass_ctx; @@ -82,6 +85,8 @@ typedef struct { uint16_t byte_count; char ** fonts; int font_count; + double font_scale_factor; + int frame_height; } MovTextContext; typedef struct { @@ -237,6 +242,13 @@ static int encode_sample_description(AVCodecContext *avctx) // Populate sample description from ASS header ass = (ASS*)s->ass_ctx; + // Compute font scaling factor based on (optionally) provided + // output video height and ASS script play_res_y + if (s->frame_height && ass->script_info.play_res_y) + s->font_scale_factor = (double)s->frame_height / ass->script_info.play_res_y; + else + s->font_scale_factor = 1; + style = ff_ass_style_get(s->ass_ctx, "Default"); if (!style && ass->styles_count) { style = &ass->styles[0]; @@ -246,7 +258,7 @@ static int encode_sample_description(AVCodecContext *avctx) s->d.style_color = DEFAULT_STYLE_COLOR; s->d.style_flag = DEFAULT_STYLE_FLAG; if (style) { - s->d.style_fontsize = style->font_size; + s->d.style_fontsize = FONTSIZE_SCALE(s, style->font_size); s->d.style_color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8 | 255 - ((uint32_t)style->primary_color >> 24); s->d.style_flag = (!!style->bold * STYLE_FLAG_BOLD) | @@ -531,6 +543,7 @@ static void mov_text_font_name_cb(void *priv, const char *name) static void mov_text_font_size_set(MovTextContext *s, int size) { + size = FONTSIZE_SCALE(s, size); if (!s->style_attributes_temp || s->style_attributes_temp->style_fontsize == size) { // color hasn't changed @@ -716,12 +729,27 @@ exit: return length; } +#define OFFSET(x) offsetof(MovTextContext, x) +#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM +static const AVOption options[] = { + { "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_encoder_class = { + .class_name = "MOV text enoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_movtext_encoder = { .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_encoder_class, .init = mov_text_encode_init, .encode_sub = mov_text_encode_frame, .close = mov_text_encode_close,