summaryrefslogtreecommitdiff
path: root/ffmpeg/libavformat/webvttdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/libavformat/webvttdec.c')
-rw-r--r--ffmpeg/libavformat/webvttdec.c69
1 files changed, 58 insertions, 11 deletions
diff --git a/ffmpeg/libavformat/webvttdec.c b/ffmpeg/libavformat/webvttdec.c
index 694a020..0654485 100644
--- a/ffmpeg/libavformat/webvttdec.c
+++ b/ffmpeg/libavformat/webvttdec.c
@@ -29,9 +29,12 @@
#include "subtitles.h"
#include "libavutil/bprint.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
typedef struct {
+ const AVClass *class;
FFDemuxSubtitlesQueue q;
+ int kind;
} WebVTTContext;
static int webvtt_probe(AVProbeData *p)
@@ -66,6 +69,7 @@ static int webvtt_read_header(AVFormatContext *s)
avpriv_set_pts_info(st, 64, 1, 1000);
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id = AV_CODEC_ID_WEBVTT;
+ st->disposition |= webvtt->kind;
av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_init(&cue, 0, AV_BPRINT_SIZE_UNLIMITED);
@@ -74,8 +78,8 @@ static int webvtt_read_header(AVFormatContext *s)
int i;
int64_t pos;
AVPacket *sub;
- const char *p, *identifier;
- //const char *settings = NULL;
+ const char *p, *identifier, *settings;
+ int identifier_len, settings_len;
int64_t ts_start, ts_end;
ff_subtitles_read_chunk(s->pb, &cue);
@@ -92,15 +96,23 @@ static int webvtt_read_header(AVFormatContext *s)
continue;
/* optional cue identifier (can be a number like in SRT or some kind of
- * chaptering id), silently skip it */
- for (i = 0; p[i] && p[i] != '\n'; i++) {
+ * chaptering id) */
+ for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) {
if (!strncmp(p + i, "-->", 3)) {
identifier = NULL;
break;
}
}
- if (identifier)
- p += strcspn(p, "\n");
+ if (!identifier)
+ identifier_len = 0;
+ else {
+ identifier_len = strcspn(p, "\r\n");
+ p += identifier_len;
+ if (*p == '\r')
+ p++;
+ if (*p == '\n')
+ p++;
+ }
/* cue timestamps */
if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE)
@@ -112,14 +124,15 @@ static int webvtt_read_header(AVFormatContext *s)
if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE)
break;
- /* optional cue settings, TODO: store in side_data */
+ /* optional cue settings */
p += strcspn(p, "\n\t ");
while (*p == '\t' || *p == ' ')
p++;
- if (*p != '\n') {
- //settings = p;
- p += strcspn(p, "\n");
- }
+ settings = p;
+ settings_len = strcspn(p, "\r\n");
+ p += settings_len;
+ if (*p == '\r')
+ p++;
if (*p == '\n')
p++;
@@ -132,6 +145,20 @@ static int webvtt_read_header(AVFormatContext *s)
sub->pos = pos;
sub->pts = ts_start;
sub->duration = ts_end - ts_start;
+
+#define SET_SIDE_DATA(name, type) do { \
+ if (name##_len) { \
+ uint8_t *buf = av_packet_new_side_data(sub, type, name##_len); \
+ if (!buf) { \
+ res = AVERROR(ENOMEM); \
+ goto end; \
+ } \
+ memcpy(buf, name, name##_len); \
+ } \
+} while (0)
+
+ SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER);
+ SET_SIDE_DATA(settings, AV_PKT_DATA_WEBVTT_SETTINGS);
}
ff_subtitles_queue_finalize(&webvtt->q);
@@ -163,6 +190,25 @@ static int webvtt_read_close(AVFormatContext *s)
return 0;
}
+#define OFFSET(x) offsetof(WebVTTContext, x)
+#define KIND_FLAGS AV_OPT_FLAG_SUBTITLE_PARAM
+
+static const AVOption options[] = {
+ { "kind", "Set kind of WebVTT track", OFFSET(kind), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, KIND_FLAGS, "webvtt_kind" },
+ { "subtitles", "WebVTT subtitles kind", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { "captions", "WebVTT captions kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { "descriptions", "WebVTT descriptions kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { "metadata", "WebVTT metadata kind", 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, INT_MIN, INT_MAX, 0, "webvtt_kind" },
+ { NULL }
+};
+
+static const AVClass webvtt_demuxer_class = {
+ .class_name = "WebVTT demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_webvtt_demuxer = {
.name = "webvtt",
.long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
@@ -173,4 +219,5 @@ AVInputFormat ff_webvtt_demuxer = {
.read_seek2 = webvtt_read_seek,
.read_close = webvtt_read_close,
.extensions = "vtt",
+ .priv_class = &webvtt_demuxer_class,
};