[FFmpeg-devel] [PATCH] WebVTT demuxer - save cue id and settings as side data
Clément Bœsch
ubitux at gmail.com
Fri May 31 15:32:39 CEST 2013
On Thu, May 30, 2013 at 04:37:56PM -0700, Matthew Heaney wrote:
> Currently the WebVTT demuxer parses the cues but throws away
> the cue id (the optional first line of the cue) and cue
> settings (the optional rendering instructions that follow
> the timestamp).
>
> However, in order to write inband text tracks (to WebM
> files), the entire cue payload from the WebVTT source must
> be preserved.
>
> This commit makes no change to the data part of the output
> buffer packet (where the actual cue text is stored), but
> does add the cue id and settings as a side data items, if
> they're present in the cue. Existing code that cares only
> about the data part of the packet can continue to ignore the
> side data.
>
> There are two new packet data type flags,
> AV_PKT_DATA_WEBVTT_IDENTIFIER and
> AV_PKT_DATA_WEBVTT_SETTINGS.
> ---
> libavcodec/avcodec.h | 11 ++++++++++
> libavcodec/version.h | 2 +-
> libavformat/webvttdec.c | 53 +++++++++++++++++++++++++++++++++++++++----------
> 3 files changed, 54 insertions(+), 12 deletions(-)
>
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 93d63e8..5ece48c 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -1008,6 +1008,17 @@ enum AVPacketSideDataType {
> * by data.
> */
> AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
> +
> + /**
> + * The optional first identifier line of a WebVTT cue.
> + */
> + AV_PKT_DATA_WEBVTT_IDENTIFIER,
> +
> + /**
> + * The optional settings (rendering instructions) that immediately
> + * follow the timestamp specifier of a WebVTT cue.
> + */
> + AV_PKT_DATA_WEBVTT_SETTINGS,
> };
>
> /**
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index b904048..4eab7a8 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -29,7 +29,7 @@
> #include "libavutil/avutil.h"
>
> #define LIBAVCODEC_VERSION_MAJOR 55
> -#define LIBAVCODEC_VERSION_MINOR 12
> +#define LIBAVCODEC_VERSION_MINOR 13
> #define LIBAVCODEC_VERSION_MICRO 102
>
> #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c
> index 694a020..894a762 100644
> --- a/libavformat/webvttdec.c
> +++ b/libavformat/webvttdec.c
> @@ -74,8 +74,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 +92,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 +120,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 +141,28 @@ static int webvtt_read_header(AVFormatContext *s)
> sub->pos = pos;
> sub->pts = ts_start;
> sub->duration = ts_end - ts_start;
> +
> + if (identifier_len) {
> + uint8_t *buf = av_packet_new_side_data(sub,
> + AV_PKT_DATA_WEBVTT_IDENTIFIER,
> + identifier_len);
> + if (!buf) {
> + res = AVERROR(ENOMEM);
> + goto end;
> + }
> + memcpy(buf, identifier, identifier_len);
> + }
> +
> + if (settings_len) {
> + uint8_t *buf = av_packet_new_side_data(sub,
> + AV_PKT_DATA_WEBVTT_SETTINGS,
> + settings_len);
> + if (!buf) {
> + res = AVERROR(ENOMEM);
> + goto end;
> + }
> + memcpy(buf, settings, settings_len);
> + }
> }
>
> ff_subtitles_queue_finalize(&webvtt->q);
LGTM.
I'll test and apply in the next 24 hours unless someone object.
Note: I'm assuming you at least tested fate-sub-webvtt
--
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130531/a825062b/attachment.asc>
More information about the ffmpeg-devel
mailing list