tedcaptionsdec.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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. #include "libavutil/bprint.h"
  22. #include "libavutil/log.h"
  23. #include "libavutil/opt.h"
  24. #include "avformat.h"
  25. #include "internal.h"
  26. #include "subtitles.h"
  27. typedef struct {
  28. AVClass *class;
  29. int64_t start_time;
  30. FFDemuxSubtitlesQueue subs;
  31. } TEDCaptionsDemuxer;
  32. static const AVOption tedcaptions_options[] = {
  33. { "start_time", "set the start time (offset) of the subtitles, in ms",
  34. offsetof(TEDCaptionsDemuxer, start_time), FF_OPT_TYPE_INT64,
  35. { .i64 = 15000 }, INT64_MIN, INT64_MAX,
  36. AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM },
  37. { NULL },
  38. };
  39. static const AVClass tedcaptions_demuxer_class = {
  40. .class_name = "tedcaptions_demuxer",
  41. .item_name = av_default_item_name,
  42. .option = tedcaptions_options,
  43. .version = LIBAVUTIL_VERSION_INT,
  44. };
  45. #define BETWEEN(a, amin, amax) ((unsigned)((a) - (amin)) <= (amax) - (amin))
  46. #define HEX_DIGIT_TEST(c) (BETWEEN(c, '0', '9') || BETWEEN((c) | 32, 'a', 'z'))
  47. #define HEX_DIGIT_VAL(c) ((c) <= '9' ? (c) - '0' : ((c) | 32) - 'a' + 10)
  48. #define ERR_CODE(c) (c < 0 ? c : AVERROR_INVALIDDATA)
  49. static void av_bprint_utf8(AVBPrint *bp, unsigned c)
  50. {
  51. int bytes, i;
  52. if (c <= 0x7F) {
  53. av_bprint_chars(bp, c, 1);
  54. return;
  55. }
  56. bytes = (av_log2(c) - 2) / 5;
  57. av_bprint_chars(bp, (c >> (bytes * 6)) | ((0xFF80 >> bytes) & 0xFF), 1);
  58. for (i = bytes - 1; i >= 0; i--)
  59. av_bprint_chars(bp, ((c >> (i * 6)) & 0x3F) | 0x80, 1);
  60. }
  61. static void next_byte(AVIOContext *pb, int *cur_byte)
  62. {
  63. uint8_t b;
  64. int ret = avio_read(pb, &b, 1);
  65. *cur_byte = ret > 0 ? b : ret == 0 ? AVERROR_EOF : ret;
  66. }
  67. static void skip_spaces(AVIOContext *pb, int *cur_byte)
  68. {
  69. while (*cur_byte == ' ' || *cur_byte == '\t' ||
  70. *cur_byte == '\n' || *cur_byte == '\r')
  71. next_byte(pb, cur_byte);
  72. }
  73. static int expect_byte(AVIOContext *pb, int *cur_byte, uint8_t c)
  74. {
  75. skip_spaces(pb, cur_byte);
  76. if (*cur_byte != c)
  77. return ERR_CODE(*cur_byte);
  78. next_byte(pb, cur_byte);
  79. return 0;
  80. }
  81. static int parse_string(AVIOContext *pb, int *cur_byte, AVBPrint *bp, int full)
  82. {
  83. int ret;
  84. av_bprint_init(bp, 0, full ? -1 : 1);
  85. ret = expect_byte(pb, cur_byte, '"');
  86. if (ret < 0)
  87. goto fail;
  88. while (*cur_byte > 0 && *cur_byte != '"') {
  89. if (*cur_byte == '\\') {
  90. next_byte(pb, cur_byte);
  91. if (*cur_byte < 0) {
  92. ret = AVERROR_INVALIDDATA;
  93. goto fail;
  94. }
  95. if ((*cur_byte | 32) == 'u') {
  96. unsigned chr = 0, i;
  97. for (i = 0; i < 4; i++) {
  98. next_byte(pb, cur_byte);
  99. if (!HEX_DIGIT_TEST(*cur_byte)) {
  100. ret = ERR_CODE(*cur_byte);
  101. goto fail;
  102. }
  103. chr = chr * 16 + HEX_DIGIT_VAL(*cur_byte);
  104. }
  105. av_bprint_utf8(bp, chr);
  106. } else {
  107. av_bprint_chars(bp, *cur_byte, 1);
  108. }
  109. } else {
  110. av_bprint_chars(bp, *cur_byte, 1);
  111. }
  112. next_byte(pb, cur_byte);
  113. }
  114. ret = expect_byte(pb, cur_byte, '"');
  115. if (ret < 0)
  116. goto fail;
  117. if (full && !av_bprint_is_complete(bp)) {
  118. ret = AVERROR(ENOMEM);
  119. goto fail;
  120. }
  121. return 0;
  122. fail:
  123. av_bprint_finalize(bp, NULL);
  124. return ret;
  125. }
  126. static int parse_label(AVIOContext *pb, int *cur_byte, AVBPrint *bp)
  127. {
  128. int ret;
  129. ret = parse_string(pb, cur_byte, bp, 0);
  130. if (ret < 0)
  131. return ret;
  132. ret = expect_byte(pb, cur_byte, ':');
  133. if (ret < 0)
  134. return ret;
  135. return 0;
  136. }
  137. static int parse_boolean(AVIOContext *pb, int *cur_byte, int *result)
  138. {
  139. const char *text[] = { "false", "true" }, *p;
  140. int i;
  141. skip_spaces(pb, cur_byte);
  142. for (i = 0; i < 2; i++) {
  143. p = text[i];
  144. if (*cur_byte != *p)
  145. continue;
  146. for (; *p; p++, next_byte(pb, cur_byte))
  147. if (*cur_byte != *p)
  148. return AVERROR_INVALIDDATA;
  149. if (BETWEEN(*cur_byte | 32, 'a', 'z'))
  150. return AVERROR_INVALIDDATA;
  151. *result = i;
  152. return 0;
  153. }
  154. return AVERROR_INVALIDDATA;
  155. }
  156. static int parse_int(AVIOContext *pb, int *cur_byte, int64_t *result)
  157. {
  158. int64_t val = 0;
  159. skip_spaces(pb, cur_byte);
  160. if ((unsigned)*cur_byte - '0' > 9)
  161. return AVERROR_INVALIDDATA;
  162. while (BETWEEN(*cur_byte, '0', '9')) {
  163. val = val * 10 + (*cur_byte - '0');
  164. next_byte(pb, cur_byte);
  165. }
  166. *result = val;
  167. return 0;
  168. }
  169. static int parse_file(AVIOContext *pb, FFDemuxSubtitlesQueue *subs)
  170. {
  171. int ret, cur_byte, start_of_par;
  172. AVBPrint label, content;
  173. int64_t pos, start, duration;
  174. AVPacket *pkt;
  175. next_byte(pb, &cur_byte);
  176. ret = expect_byte(pb, &cur_byte, '{');
  177. if (ret < 0)
  178. return AVERROR_INVALIDDATA;
  179. ret = parse_label(pb, &cur_byte, &label);
  180. if (ret < 0 || strcmp(label.str, "captions"))
  181. return AVERROR_INVALIDDATA;
  182. ret = expect_byte(pb, &cur_byte, '[');
  183. if (ret < 0)
  184. return AVERROR_INVALIDDATA;
  185. while (1) {
  186. content.size = 0;
  187. start = duration = AV_NOPTS_VALUE;
  188. ret = expect_byte(pb, &cur_byte, '{');
  189. if (ret < 0)
  190. return ret;
  191. pos = avio_tell(pb) - 1;
  192. while (1) {
  193. ret = parse_label(pb, &cur_byte, &label);
  194. if (ret < 0)
  195. return ret;
  196. if (!strcmp(label.str, "startOfParagraph")) {
  197. ret = parse_boolean(pb, &cur_byte, &start_of_par);
  198. if (ret < 0)
  199. return ret;
  200. } else if (!strcmp(label.str, "content")) {
  201. ret = parse_string(pb, &cur_byte, &content, 1);
  202. if (ret < 0)
  203. return ret;
  204. } else if (!strcmp(label.str, "startTime")) {
  205. ret = parse_int(pb, &cur_byte, &start);
  206. if (ret < 0)
  207. return ret;
  208. } else if (!strcmp(label.str, "duration")) {
  209. ret = parse_int(pb, &cur_byte, &duration);
  210. if (ret < 0)
  211. return ret;
  212. } else {
  213. return AVERROR_INVALIDDATA;
  214. }
  215. skip_spaces(pb, &cur_byte);
  216. if (cur_byte != ',')
  217. break;
  218. next_byte(pb, &cur_byte);
  219. }
  220. ret = expect_byte(pb, &cur_byte, '}');
  221. if (ret < 0)
  222. return ret;
  223. if (!content.size || start == AV_NOPTS_VALUE ||
  224. duration == AV_NOPTS_VALUE)
  225. return AVERROR_INVALIDDATA;
  226. pkt = ff_subtitles_queue_insert(subs, content.str, content.len, 0);
  227. if (!pkt)
  228. return AVERROR(ENOMEM);
  229. pkt->pos = pos;
  230. pkt->pts = start;
  231. pkt->duration = duration;
  232. av_bprint_finalize(&content, NULL);
  233. skip_spaces(pb, &cur_byte);
  234. if (cur_byte != ',')
  235. break;
  236. next_byte(pb, &cur_byte);
  237. }
  238. ret = expect_byte(pb, &cur_byte, ']');
  239. if (ret < 0)
  240. return ret;
  241. ret = expect_byte(pb, &cur_byte, '}');
  242. if (ret < 0)
  243. return ret;
  244. skip_spaces(pb, &cur_byte);
  245. if (cur_byte != AVERROR_EOF)
  246. return ERR_CODE(cur_byte);
  247. return 0;
  248. }
  249. static av_cold int tedcaptions_read_header(AVFormatContext *avf)
  250. {
  251. TEDCaptionsDemuxer *tc = avf->priv_data;
  252. AVStream *st;
  253. int ret, i;
  254. AVPacket *last;
  255. ret = parse_file(avf->pb, &tc->subs);
  256. if (ret < 0) {
  257. if (ret == AVERROR_INVALIDDATA)
  258. av_log(avf, AV_LOG_ERROR, "Syntax error near offset %"PRId64".\n",
  259. avio_tell(avf->pb));
  260. ff_subtitles_queue_clean(&tc->subs);
  261. return ret;
  262. }
  263. ff_subtitles_queue_finalize(&tc->subs);
  264. for (i = 0; i < tc->subs.nb_subs; i++)
  265. tc->subs.subs[i].pts += tc->start_time;
  266. last = &tc->subs.subs[tc->subs.nb_subs - 1];
  267. st = avformat_new_stream(avf, NULL);
  268. if (!st)
  269. return AVERROR(ENOMEM);
  270. st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
  271. st->codec->codec_id = CODEC_ID_TEXT;
  272. avpriv_set_pts_info(st, 64, 1, 1000);
  273. st->probe_packets = 0;
  274. st->start_time = 0;
  275. st->duration = last->pts + last->duration;
  276. st->cur_dts = 0;
  277. return 0;
  278. }
  279. static int tedcaptions_read_packet(AVFormatContext *avf, AVPacket *packet)
  280. {
  281. TEDCaptionsDemuxer *tc = avf->priv_data;
  282. return ff_subtitles_queue_read_packet(&tc->subs, packet);
  283. }
  284. static int tedcaptions_read_close(AVFormatContext *avf)
  285. {
  286. TEDCaptionsDemuxer *tc = avf->priv_data;
  287. ff_subtitles_queue_clean(&tc->subs);
  288. return 0;
  289. }
  290. static av_cold int tedcaptions_read_probe(AVProbeData *p)
  291. {
  292. static const char *const tags[] = {
  293. "\"captions\"", "\"duration\"", "\"content\"",
  294. "\"startOfParagraph\"", "\"startTime\"",
  295. };
  296. unsigned i, count = 0;
  297. const char *t;
  298. if (p->buf[strspn(p->buf, " \t\r\n")] != '{')
  299. return 0;
  300. for (i = 0; i < FF_ARRAY_ELEMS(tags); i++) {
  301. if (!(t = strstr(p->buf, tags[i])))
  302. continue;
  303. t += strlen(tags[i]);
  304. t += strspn(t, " \t\r\n");
  305. if (*t == ':')
  306. count++;
  307. }
  308. return count == FF_ARRAY_ELEMS(tags) ? AVPROBE_SCORE_MAX :
  309. count ? AVPROBE_SCORE_MAX / 2 : 0;
  310. }
  311. static int tedcaptions_read_seek(AVFormatContext *avf, int stream_index,
  312. int64_t min_ts, int64_t ts, int64_t max_ts,
  313. int flags)
  314. {
  315. TEDCaptionsDemuxer *tc = avf->priv_data;
  316. return ff_subtitles_queue_seek(&tc->subs, avf, stream_index,
  317. min_ts, ts, max_ts, flags);
  318. }
  319. AVInputFormat ff_tedcaptions_demuxer = {
  320. .name = "tedcaptions",
  321. .long_name = NULL_IF_CONFIG_SMALL("TED Talks captions"),
  322. .priv_data_size = sizeof(TEDCaptionsDemuxer),
  323. .priv_class = &tedcaptions_demuxer_class,
  324. .read_header = tedcaptions_read_header,
  325. .read_packet = tedcaptions_read_packet,
  326. .read_close = tedcaptions_read_close,
  327. .read_probe = tedcaptions_read_probe,
  328. .read_seek2 = tedcaptions_read_seek,
  329. };