diff options
author | Clément Bœsch <ubitux@gmail.com> | 2013-01-03 07:25:45 +0100 |
---|---|---|
committer | Clément Bœsch <ubitux@gmail.com> | 2013-01-03 07:25:47 +0100 |
commit | 3fa642d60f428a36413498a191eb2ee319fe4445 (patch) | |
tree | bb52e50a620674614da7f43ff3c33e15134c4dca /libavformat/subviewerdec.c | |
parent | 52334f5be2ef31a5c836f689f3ab95b25bad026a (diff) | |
download | ffmpeg-3fa642d60f428a36413498a191eb2ee319fe4445.tar.gz |
subviewer: sanitize packets.
The data does not contain timing or trailing line breaks anymore. In
addition to being less idiotic, it is consistent with other codecs and
thus allows more switches between formats and codecs. It also fixes the
issue of the trailing line returns being simple \n instead of CRLF in
the ASS rectangle dialogue (this is the reason of the FATE update).
Diffstat (limited to 'libavformat/subviewerdec.c')
-rw-r--r-- | libavformat/subviewerdec.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c index 439f5e76dc..7cacd973db 100644 --- a/libavformat/subviewerdec.c +++ b/libavformat/subviewerdec.c @@ -71,7 +71,10 @@ static int subviewer_read_header(AVFormatContext *s) SubViewerContext *subviewer = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); AVBPrint header; - int res = 0; + int res = 0, new_event = 1; + int64_t pts_start = AV_NOPTS_VALUE; + int duration = -1; + AVPacket *sub = NULL; if (!st) return AVERROR(ENOMEM); @@ -83,12 +86,14 @@ static int subviewer_read_header(AVFormatContext *s) while (!url_feof(s->pb)) { char line[2048]; - const int64_t pos = avio_tell(s->pb); + int64_t pos = 0; int len = ff_get_line(s->pb, line, sizeof(line)); if (!len) break; + line[strcspn(line, "\r\n")] = 0; + if (line[0] == '[' && strncmp(line, "[br]", 4)) { /* ignore event style, XXX: add to side_data? */ @@ -97,7 +102,7 @@ static int subviewer_read_header(AVFormatContext *s) continue; if (!st->codec->extradata) { // header not finalized yet - av_bprintf(&header, "%s", line); + av_bprintf(&header, "%s\n", line); if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) { /* end of header */ res = avpriv_bprint_to_extradata(st->codec, &header); @@ -116,29 +121,35 @@ static int subviewer_read_header(AVFormatContext *s) i++; while (line[i] == ' ') i++; - while (j < sizeof(value) - 1 && line[i] && !strchr("]\r\n", line[i])) + while (j < sizeof(value) - 1 && line[i] && line[i] != ']') value[j++] = line[i++]; value[j] = 0; av_dict_set(&s->metadata, key, value, 0); } } - } else { - int64_t pts_start = AV_NOPTS_VALUE; - int duration = -1; - int timed_line = !read_ts(line, &pts_start, &duration); - AVPacket *sub; - - sub = ff_subtitles_queue_insert(&subviewer->q, line, len, !timed_line); + } else if (read_ts(line, &pts_start, &duration) >= 0) { + new_event = 1; + pos = avio_tell(s->pb); + } else if (*line) { + if (!new_event) { + sub = ff_subtitles_queue_insert(&subviewer->q, "\n", 1, 1); + if (!sub) { + res = AVERROR(ENOMEM); + goto end; + } + } + sub = ff_subtitles_queue_insert(&subviewer->q, line, strlen(line), !new_event); if (!sub) { res = AVERROR(ENOMEM); goto end; } - if (timed_line) { + if (new_event) { sub->pos = pos; sub->pts = pts_start; sub->duration = duration; } + new_event = 0; } } |