mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-15 11:17:49 +00:00
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>
This commit is contained in:
parent
3ef5a8ba2b
commit
b24488e727
@ -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,
|
static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf,
|
||||||
ASSStyle style)
|
ASSScriptInfo script_info, ASSStyle style)
|
||||||
{
|
{
|
||||||
const char *display_alignment = NULL;
|
const char *display_alignment = NULL;
|
||||||
const char *text_alignment = NULL;
|
const char *text_alignment = NULL;
|
||||||
|
int origin_left = 0;
|
||||||
|
int origin_top = 0;
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
if (!style.name) {
|
if (!style.name) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Subtitle style name not set!\n");
|
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;
|
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);
|
display_alignment = ttml_get_display_alignment(style.alignment);
|
||||||
text_alignment = ttml_get_text_alignment(style.alignment);
|
text_alignment = ttml_get_text_alignment(style.alignment);
|
||||||
if (!display_alignment || !text_alignment) {
|
if (!display_alignment || !text_alignment) {
|
||||||
@ -265,11 +297,19 @@ static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf,
|
|||||||
return AVERROR_INVALIDDATA;
|
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_bprintf(buf, " <region xml:id=\"");
|
||||||
av_bprint_escape(buf, style.name, NULL, AV_ESCAPE_MODE_XML,
|
av_bprint_escape(buf, style.name, NULL, AV_ESCAPE_MODE_XML,
|
||||||
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
|
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
|
||||||
av_bprintf(buf, "\"\n");
|
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_bprintf(buf, " tts:displayAlign=\"");
|
||||||
av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML,
|
av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML,
|
||||||
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
|
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
|
||||||
@ -331,7 +371,8 @@ static int ttml_write_header_content(AVCodecContext *avctx)
|
|||||||
av_bprintf(&s->buffer, " <layout>\n");
|
av_bprintf(&s->buffer, " <layout>\n");
|
||||||
|
|
||||||
for (int i = 0; i < ass->styles_count; i++) {
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<layout>
|
<layout>
|
||||||
<region xml:id="Default"
|
<region xml:id="Default"
|
||||||
|
tts:origin="3% 0%"
|
||||||
|
tts:extent="97% 97%"
|
||||||
tts:displayAlign="after"
|
tts:displayAlign="after"
|
||||||
tts:textAlign="center"
|
tts:textAlign="center"
|
||||||
tts:fontSize="16c"
|
tts:fontSize="16c"
|
||||||
|
Loading…
Reference in New Issue
Block a user