From 255302da7019753bae84d809c6d603c4cd0a41ca Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 27 Oct 2013 22:47:31 -0400 Subject: [PATCH] vorbis: handle special packets in the middle of a stream This allows for updating metadata from new metadata packets in the middle of a stream (e.g., MPD streams). There still needs to be a signal that there *is* new metadata, but this is at least gets the data into a data structure. Signed-off-by: Ben Boeckel Reviewed-by: wm4 Signed-off-by: Michael Niedermayer --- libavcodec/vorbis_parser.c | 26 ++++++++++++++++++++++++-- libavcodec/vorbis_parser.h | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c index fcbecc89e9..1e2cab3927 100644 --- a/libavcodec/vorbis_parser.c +++ b/libavcodec/vorbis_parser.c @@ -201,8 +201,8 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s) return 0; } -int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, - int buf_size) +int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags) { int duration = 0; @@ -211,6 +211,22 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, int previous_blocksize = s->previous_blocksize; if (buf[0] & 1) { + /* If the user doesn't care about special packets, it's a bad one. */ + if (!flags) + goto bad_packet; + + /* Set the flag for which kind of special packet it is. */ + if (buf[0] == 1) + *flags |= VORBIS_FLAG_HEADER; + else if (buf[0] == 3) + *flags |= VORBIS_FLAG_COMMENT; + else + goto bad_packet; + + /* Special packets have no duration. */ + return 0; + +bad_packet: av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n"); return AVERROR_INVALIDDATA; } @@ -234,6 +250,12 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, return duration; } +int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, + int buf_size) +{ + return avpriv_vorbis_parse_frame_flags(s, buf, buf_size, NULL); +} + void avpriv_vorbis_parse_reset(VorbisParseContext *s) { if (s->valid_extradata) diff --git a/libavcodec/vorbis_parser.h b/libavcodec/vorbis_parser.h index 101df5d765..590101bbad 100644 --- a/libavcodec/vorbis_parser.h +++ b/libavcodec/vorbis_parser.h @@ -50,6 +50,24 @@ typedef struct VorbisParseContext { */ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s); +#define VORBIS_FLAG_HEADER 0x00000001 +#define VORBIS_FLAG_COMMENT 0x00000002 + +/** + * Get the duration for a Vorbis packet. + * + * avpriv_vorbis_parse_extradata() must have been successfully called prior to + * this in order for a correct duration to be returned. If @p flags is @c NULL, + * special frames are considered invalid. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + * @param flags flags for special frames + */ +int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags); + /** * Get the duration for a Vorbis packet. *