1 /*
2 * TED Talks captions format decoder
3 * Copyright (c) 2012 Nicolas George
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
28
34
36 { "start_time", "set the start time (offset) of the subtitles, in ms",
38 { .i64 = 15000 }, INT64_MIN, INT64_MAX,
41 };
42
48 };
49
50 #define BETWEEN(a, amin, amax) ((unsigned)((a) - (amin)) <= (amax) - (amin))
51
52 #define HEX_DIGIT_TEST(c) (BETWEEN(c, '0', '9') || BETWEEN((c) | 32, 'a', 'z'))
53 #define HEX_DIGIT_VAL(c) ((c) <= '9' ? (c) - '0' : ((c) | 32) - 'a' + 10)
54 #define ERR_CODE(c) ((c) < 0 ? (c) : AVERROR_INVALIDDATA)
55
57 {
58 int bytes, i;
59
60 if (c <= 0x7F) {
62 return;
63 }
65 av_bprint_chars(bp, (c >> (bytes * 6)) | ((0xFF80 >> bytes) & 0xFF), 1);
66 for (i = bytes - 1; i >= 0; i--)
68 }
69
71 {
75 }
76
78 {
79 while (*cur_byte == ' ' || *cur_byte == '\t' ||
80 *cur_byte == '\n' || *cur_byte == '\r')
82 }
83
85 {
87 if (*cur_byte != c)
90 return 0;
91 }
92
94 {
96
99 if (ret < 0)
100 goto fail;
101 while (*cur_byte > 0 && *cur_byte != '"') {
102 if (*cur_byte == '\\') {
104 if (*cur_byte < 0) {
106 goto fail;
107 }
108 if ((*cur_byte | 32) == 'u') {
109 unsigned chr = 0, i;
110 for (i = 0; i < 4; i++) {
114 goto fail;
115 }
117 }
119 } else {
121 }
122 } else {
124 }
126 }
128 if (ret < 0)
129 goto fail;
132 goto fail;
133 }
134 return 0;
135
136 fail:
139 }
140
142 {
144
146 if (ret < 0)
149 if (ret < 0)
151 return 0;
152 }
153
155 {
156 static const char * const text[] = { "false", "true" };
157 const char *p;
158 int i;
159
161 for (i = 0; i < 2; i++) {
162 p = text[i];
163 if (*cur_byte != *p)
164 continue;
166 if (*cur_byte != *p)
168 if (
BETWEEN(*cur_byte | 32,
'a',
'z'))
170 *result = i;
171 return 0;
172 }
174 }
175
177 {
179
181 if ((unsigned)*cur_byte - '0' > 9)
183 while (
BETWEEN(*cur_byte,
'0',
'9')) {
184 val = val * 10 + (*cur_byte - '0');
186 }
188 return 0;
189 }
190
192 {
193 int ret, cur_byte, start_of_par;
194 AVBPrint label, content;
197
200 if (ret < 0)
203 if (ret < 0 || strcmp(label.str, "captions"))
206 if (ret < 0)
208 while (1) {
209 content.size = 0;
212 if (ret < 0)
215 while (1) {
217 if (ret < 0)
219 if (!strcmp(label.str, "startOfParagraph")) {
221 if (ret < 0)
223 } else if (!strcmp(label.str, "content")) {
225 if (ret < 0)
227 } else if (!strcmp(label.str, "startTime")) {
229 if (ret < 0)
231 } else if (!strcmp(label.str, "duration")) {
232 ret =
parse_int(pb, &cur_byte, &duration);
233 if (ret < 0)
235 } else {
237 }
239 if (cur_byte != ',')
240 break;
242 }
244 if (ret < 0)
246
251 if (!pkt)
257
259 if (cur_byte != ',')
260 break;
262 }
264 if (ret < 0)
267 if (ret < 0)
272 return 0;
273 }
274
276 {
281
283 if (ret < 0) {
289 }
293
296 if (!st)
305
306 return 0;
307 }
308
310 {
312
314 }
315
317 {
319
321 return 0;
322 }
323
325 {
326 static const char *const tags[] = {
327 "\"captions\"", "\"duration\"", "\"content\"",
328 "\"startOfParagraph\"", "\"startTime\"",
329 };
330 unsigned i,
count = 0;
331 const char *t;
332
333 if (p->
buf[strspn(p->
buf,
" \t\r\n")] !=
'{')
334 return 0;
336 if (!(t = strstr(p->
buf, tags[i])))
337 continue;
338 t += strlen(tags[i]);
339 t += strspn(t, " \t\r\n");
340 if (*t == ':')
341 count++;
342 }
345 }
346
348 int64_t min_ts, int64_t ts, int64_t max_ts,
350 {
353 min_ts, ts, max_ts, flags);
354 }
355
357 .
name =
"tedcaptions",
360 .priv_class = &tedcaptions_demuxer_class,
366 };