1 /*
2 * TTML subtitle muxer
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 muxer
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
41 };
42
46 };
47
52
54 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
55 "<tt\n"
56 "%s"
57 " xml:lang=\"%s\">\n"
58 "%s"
59 " <body>\n"
60 " <div>\n";
61
63 " </div>\n"
64 " </body>\n"
65 "</tt>\n";
66
69 {
71 sec = millisec / 1000;
72 millisec -= 1000 * sec;
77
78 avio_printf(pb,
"%s=\"%02"PRId64
":%02"PRId64
":%02"PRId64
".%03"PRId64
"\"",
79 tag, hour,
min, sec, millisec);
80 }
81
84 {
85 size_t additional_data_size =
91
92 if (!additional_data_size) {
93 // simple case, we don't have to go through local_params and just
94 // set default fall-back values (for old extradata format).
97
98 return 0;
99 }
100
101 if (value_size == additional_data_size ||
102 value[value_size] !=
'0円')
104
106
107 additional_data_size -= value_size + 1;
108 value += value_size + 1;
109 if (!additional_data_size)
111
113 if (value_size == additional_data_size ||
114 value[value_size] !=
'0円')
116
118
119 *header_params = local_params;
120
121 return 0;
122 }
123
125 {
129
131 0);
132 const char *printed_lang = (lang && lang->
value) ? lang->
value :
"";
133
138
140
147 "Failed to parse TTML header values from extradata: "
150 }
151
154 printed_lang,
156 }
157
158 return 0;
159 }
160
162 {
165
168 // write out a paragraph element with the given contents.
176 break;
178 // dump the given document out as-is.
181 "Attempting to write multiple TTML documents into a "
182 "single document! The XML specification forbids this "
183 "as there has to be a single root tag.\n");
185 }
188 break;
189 default:
191 "Internal error: invalid TTML input packet type: %d!\n",
194 }
195
196 return 0;
197 }
198
200 {
203
206
207 return 0;
208 }
209
213 .p.extensions = "ttml",
214 .p.mime_type = "text/ttml",
226 };