FFmpeg: libavcodec/ttmlenc.c Source File
Go to the documentation of this file. 1 /*
2 * TTML subtitle encoder
3 * Copyright (c) 2020 24i
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * TTML subtitle encoder
25 * @see https://www.w3.org/TR/ttml1/
26 * @see https://www.w3.org/TR/ttml2/
27 * @see https://www.w3.org/TR/ttml-imsc/rec
28 */
29
37
43
45 {
47 AVBPrint cur_line;
49
51
55 "Failed to move the current subtitle dialog to AVBPrint!\n");
57 return;
58 }
59
60
62 0);
63
65 }
66
68 {
70
72 }
73
77 };
78
81 {
85
87
91
95 }
96
98 if (!dialog)
100
107 }
108
115 "Splitting received ASS dialog text %s failed: %s\n",
118
122 }
123 }
124
127
129 }
130
132 return 0;
136 }
137
138 return s->buffer.len;
139 }
140
142 {
144
146
147 return 0;
148 }
149
151 {
152 switch (alignment) {
153 case 1:
154 case 2:
155 case 3:
156 return "after";
157 case 4:
158 case 5:
159 case 6:
160 return "center";
161 case 7:
162 case 8:
163 case 9:
164 return "before";
165 default:
167 }
168 }
169
171 {
172 switch (alignment) {
173 case 1:
174 case 4:
175 case 7:
176 return "left";
177 case 2:
178 case 5:
179 case 8:
180 return "center";
181 case 3:
182 case 6:
183 case 9:
184 return "right";
185 default:
187 }
188 }
189
191 int *origin_left, int *origin_top)
192 {
194 *origin_top =
197 }
198
201 {
208 }
209
212 {
213 const char *display_alignment =
NULL;
215 int origin_left = 0;
216 int origin_top = 0;
219
223 }
224
229 }
230
233 "One or more negative margin values in subtitle style: "
234 "left: %d, right: %d, vertical: %d!\n",
237 }
238
243 "Failed to convert ASS style alignment %d of style %s to "
244 "TTML display and text alignment!\n",
248 }
249
252
257
258 av_bprintf(buf,
" tts:origin=\"%d%% %d%%\"\n",
259 origin_left, origin_top);
260 av_bprintf(buf,
" tts:extent=\"%d%% %d%%\"\n",
262
267
272
273 // if we set cell resolution to our script reference resolution,
274 // then a single line is a single "point" on our canvas. Thus, by setting
275 // our font size to font size in cells, we should gain a similar enough
276 // scale without resorting to explicit pixel based font sizing, which is
277 // frowned upon in the TTML community.
280
286 }
287
288 av_bprintf(buf,
" tts:overflow=\"visible\" />\n");
289
290 return 0;
291 }
292
294 {
300 size_t additional_extradata_size = 0;
302
303 if (script_info.play_res_x <= 0 || script_info.play_res_y <= 0) {
305 "Invalid subtitle reference resolution %dx%d!\n",
306 script_info.play_res_x, script_info.play_res_y);
308 }
309
311
312 // write the first string in extradata, attributes in the base "tt" element.
314 // the cell resolution is in character cells, so not exactly 1:1 against
315 // a pixel based resolution, but as the tts:extent in the root
316 // "tt" element is frowned upon (and disallowed in the EBU-TT profile),
317 // we mimic the reference resolution by setting it as the cell resolution.
318 av_bprintf(&
s->buffer,
" ttp:cellResolution=\"%d %d\"\n",
319 script_info.play_res_x, script_info.play_res_y);
321
322 // write the second string in extradata, head element containing the styles
325
331 }
332
336
340 }
341
342 additional_extradata_size =
s->buffer.len;
343
345 av_mallocz(base_extradata_size + additional_extradata_size))) {
348 }
349
354
356 s->buffer.str, additional_extradata_size);
357
361
363 }
364
366 {
370
373 }
374
377 }
378
379 return 0;
380 }
381
392 };
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_BPRINT_SIZE_UNLIMITED
#define AV_EF_EXPLODE
abort decoding on minor error detection
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Set of callback functions corresponding to each override codes that can be encountered in a "Dialogue...
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Filter the word "frame" indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
int alignment
position of the text (left, center, top...), defined after the layout of the numpad (1-3 sub,...
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
ASSDialog * ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf)
Split one ASS Dialogue line from a string buffer.
const FFCodec ff_ttml_encoder
ASSStyle * styles
array of split out styles
uint8_t * subtitle_header
static void ttml_get_extent(ASSScriptInfo script_info, ASSStyle style, int *width, int *height)
char * style
name of the ASSStyle to use with this dialog
@ SUBTITLE_ASS
Formatted text, the ass field must be set by the decoder and is authoritative.
#define TTMLENC_EXTRADATA_SIGNATURE_SIZE
char * font_name
font face (case sensitive)
static void ttml_text_cb(void *priv, const char *text, int len)
AVCodec p
The public AVCodec.
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
Init a print buffer using a pre-existing buffer.
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
static int ttml_write_header_content(AVCodecContext *avctx)
char * ass
0 terminated ASS/SSA compatible event line.
#define TTMLENC_EXTRADATA_SIGNATURE
void ff_ass_free_dialog(ASSDialog **dialogp)
Free a dialogue obtained from ff_ass_split_dialog().
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void ttml_get_origin(ASSScriptInfo script_info, ASSStyle style, int *origin_left, int *origin_top)
#define AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES
Within AV_ESCAPE_MODE_XML, additionally escape double quotes for double quoted attributes.
#define CODEC_LONG_NAME(str)
int play_res_y
video height that ASS coords are referring to
structure containing the whole split ASS data
static const ASSCodesCallbacks ttml_callbacks
int play_res_x
video width that ASS coords are referring to
void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, enum AVEscapeMode mode, int flags)
Escape the content in src and append it to dstbuf.
static void ttml_new_line_cb(void *priv, int forced)
static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, int bufsize, const AVSubtitle *sub)
fields extracted from the [Script Info] section
ASSSplitContext * ass_ctx
#define FF_CODEC_ENCODE_SUB_CB(func)
This struct can be casted to ASS to access to the split data.
ASSSplitContext * ff_ass_split(const char *buf)
Split a full ASS file or a ASS header from a string buffer and store the split structure in a newly a...
fields extracted from the [V4(+) Styles] section
int(* init)(AVBSFContext *ctx)
void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
char * text
actual text which will be displayed as a subtitle, can include style override control codes (see ff_a...
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
char * name
name of the tyle (case sensitive)
@ AV_ESCAPE_MODE_XML
Use XML non-markup character data escaping.
static av_cold int ttml_encode_init(AVCodecContext *avctx)
static const char * ttml_get_text_alignment(int alignment)
#define i(width, name, range_min, range_max)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const char * name
Name of the codec implementation.
int styles_count
number of ASSStyle in the styles array
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
#define AV_INPUT_BUFFER_PADDING_SIZE
main external API structure.
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
fields extracted from the [Events] section
static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, ASSScriptInfo script_info, ASSStyle style)
#define TTML_DEFAULT_NAMESPACING
static const char * ttml_get_display_alignment(int alignment)
static av_cold int ttml_encode_close(AVCodecContext *avctx)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, const char *buf)
Split override codes out of a ASS "Dialogue" Text field.
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
void(* text)(void *priv, const char *text, int len)
ASSScriptInfo script_info
general information about the SSA script
Generated on Fri Aug 22 2025 13:58:53 for FFmpeg by
doxygen
1.8.17