diff options
author | Jan Ekström <jan.ekstrom@24i.com> | 2021-03-29 17:19:58 +0300 |
---|---|---|
committer | Jan Ekström <jeebjp@gmail.com> | 2021-04-26 16:40:31 +0300 |
commit | b24488e7277af2a4b77a33fa795b4df5979b0fcd (patch) | |
tree | 0cb1790093939507f5e1a713907f5a3ef5fd2ac2 | |
parent | 3ef5a8ba2b7798ea4e5708c5644fa60dd00bde06 (diff) | |
download | ffmpeg-b24488e7277af2a4b77a33fa795b4df5979b0fcd.tar.gz |
avcodec/ttmlenc: add support for region positioning and sizing
The ASS margins are utilized to generate percentual values, as
the usage of cell-based sizing and offsetting seems to be not too
well supported by renderers.
Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
-rw-r--r-- | libavcodec/ttmlenc.c | 45 | ||||
-rw-r--r-- | tests/ref/fate/sub-ttmlenc | 2 |
2 files changed, 45 insertions, 2 deletions
diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index 37372b29cd..6dfcc0a216 100644 --- a/libavcodec/ttmlenc.c +++ b/libavcodec/ttmlenc.c @@ -237,11 +237,35 @@ static const char *ttml_get_text_alignment(int alignment) } } +static void ttml_get_origin(ASSScriptInfo script_info, ASSStyle style, + int *origin_left, int *origin_top) +{ + *origin_left = av_rescale(style.margin_l, 100, script_info.play_res_x); + *origin_top = + av_rescale((style.alignment >= 7) ? style.margin_v : 0, + 100, script_info.play_res_y); +} + +static void ttml_get_extent(ASSScriptInfo script_info, ASSStyle style, + int *width, int *height) +{ + *width = av_rescale(script_info.play_res_x - style.margin_r, + 100, script_info.play_res_x); + *height = av_rescale((style.alignment <= 3) ? + script_info.play_res_y - style.margin_v : + script_info.play_res_y, + 100, script_info.play_res_y); +} + static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, - ASSStyle style) + ASSScriptInfo script_info, ASSStyle style) { const char *display_alignment = NULL; const char *text_alignment = NULL; + int origin_left = 0; + int origin_top = 0; + int width = 0; + int height = 0; if (!style.name) { av_log(avctx, AV_LOG_ERROR, "Subtitle style name not set!\n"); @@ -254,6 +278,14 @@ static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, return AVERROR_INVALIDDATA; } + if (style.margin_l < 0 || style.margin_r < 0 || style.margin_v < 0) { + av_log(avctx, AV_LOG_ERROR, + "One or more negative margin values in subtitle style: " + "left: %d, right: %d, vertical: %d!\n", + style.margin_l, style.margin_r, style.margin_v); + return AVERROR_INVALIDDATA; + } + display_alignment = ttml_get_display_alignment(style.alignment); text_alignment = ttml_get_text_alignment(style.alignment); if (!display_alignment || !text_alignment) { @@ -265,11 +297,19 @@ static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, return AVERROR_INVALIDDATA; } + ttml_get_origin(script_info, style, &origin_left, &origin_top); + ttml_get_extent(script_info, style, &width, &height); + av_bprintf(buf, " <region xml:id=\""); av_bprint_escape(buf, style.name, NULL, AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); av_bprintf(buf, "\"\n"); + av_bprintf(buf, " tts:origin=\"%d%% %d%%\"\n", + origin_left, origin_top); + av_bprintf(buf, " tts:extent=\"%d%% %d%%\"\n", + width, height); + av_bprintf(buf, " tts:displayAlign=\""); av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); @@ -331,7 +371,8 @@ static int ttml_write_header_content(AVCodecContext *avctx) av_bprintf(&s->buffer, " <layout>\n"); for (int i = 0; i < ass->styles_count; i++) { - int ret = ttml_write_region(avctx, &s->buffer, ass->styles[i]); + int ret = ttml_write_region(avctx, &s->buffer, script_info, + ass->styles[i]); if (ret < 0) return ret; } diff --git a/tests/ref/fate/sub-ttmlenc b/tests/ref/fate/sub-ttmlenc index 6d0a8067fc..4df8f8796f 100644 --- a/tests/ref/fate/sub-ttmlenc +++ b/tests/ref/fate/sub-ttmlenc @@ -9,6 +9,8 @@ <head> <layout> <region xml:id="Default" + tts:origin="3% 0%" + tts:extent="97% 97%" tts:displayAlign="after" tts:textAlign="center" tts:fontSize="16c" |