X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Foggparsevorbis.c;h=519a0a7371e662569cc01d9abc9b541d49b5860d;hb=e55376a1fd5abebbb0a082aa20739d58c2260a37;hp=3eac0ba083433264a5da13c574a45ca6bb74088c;hpb=0048deb84cb6d22ba7f4fd7c8b4ecc054fcc22d4;p=ffmpeg diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index 3eac0ba0834..519a0a7371e 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -71,11 +71,25 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val) return 1; } +int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, + const uint8_t *buf, int size) +{ + int updates = ff_vorbis_comment(as, &st->metadata, buf, size, 1); + + if (updates > 0) { + st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED; + } + + return updates; +} + int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, - const uint8_t *buf, int size) + const uint8_t *buf, int size, + int parse_picture) { const uint8_t *p = buf; const uint8_t *end = buf + size; + int updates = 0; unsigned n, j; int s; @@ -137,7 +151,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, * 'METADATA_BLOCK_PICTURE'. This is the preferred and * recommended way of embedding cover art within VorbisComments." */ - if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) { + if (!strcmp(tt, "METADATA_BLOCK_PICTURE") && parse_picture) { int ret; char *pict = av_malloc(vl); @@ -155,10 +169,12 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n"); continue; } - } else if (!ogm_chapter(as, tt, ct)) + } else if (!ogm_chapter(as, tt, ct)) { + updates++; av_dict_set(m, tt, ct, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + } } } @@ -171,7 +187,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv); - return 0; + return updates; } /* @@ -192,7 +208,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, struct oggvorbis_private { unsigned int len[3]; unsigned char *packet[3]; - VorbisParseContext vp; + AVVorbisParseContext *vp; int64_t final_pts; int final_duration; }; @@ -218,7 +234,7 @@ static int fixup_vorbis_headers(AVFormatContext *as, offset += priv->len[i]; av_freep(&priv->packet[i]); } - if ((err = av_reallocp(buf, offset + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) + if ((err = av_reallocp(buf, offset + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) return err; return offset; } @@ -229,9 +245,11 @@ static void vorbis_cleanup(AVFormatContext *s, int idx) struct ogg_stream *os = ogg->streams + idx; struct oggvorbis_private *priv = os->private; int i; - if (os->private) + if (os->private) { + av_vorbis_parse_free(&priv->vp); for (i = 0; i < 3; i++) av_freep(&priv->packet[i]); + } } static int vorbis_header(AVFormatContext *s, int idx) @@ -304,8 +322,8 @@ static int vorbis_header(AVFormatContext *s, int idx) } } else if (os->buf[os->pstart] == 3) { if (os->psize > 8 && - ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, - os->psize - 8) >= 0) { + ff_vorbis_stream_comment(s, st, os->buf + os->pstart + 7, + os->psize - 8) >= 0) { unsigned new_len; int ret = ff_replaygain_export(st, st->metadata); @@ -327,7 +345,9 @@ static int vorbis_header(AVFormatContext *s, int idx) return ret; } st->codec->extradata_size = ret; - if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) { + + priv->vp = av_vorbis_parse_init(st->codec->extradata, st->codec->extradata_size); + if (!priv->vp) { av_freep(&st->codec->extradata); st->codec->extradata_size = 0; return ret; @@ -344,6 +364,9 @@ static int vorbis_packet(AVFormatContext *s, int idx) struct oggvorbis_private *priv = os->private; int duration; + if (!priv->vp) + return AVERROR_INVALIDDATA; + /* first packet handling * here we parse the duration of each packet in the first page and compare * the total duration to the page granule to find the encoder delay and @@ -354,11 +377,11 @@ static int vorbis_packet(AVFormatContext *s, int idx) uint8_t *next_pkt = last_pkt; int first_duration = 0; - avpriv_vorbis_parse_reset(&priv->vp); + av_vorbis_parse_reset(priv->vp); duration = 0; for (seg = 0; seg < os->nsegs; seg++) { if (os->segments[seg] < 255) { - int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1); + int d = av_vorbis_parse_frame(priv->vp, last_pkt, 1); if (d < 0) { duration = os->granule; break; @@ -377,12 +400,12 @@ static int vorbis_packet(AVFormatContext *s, int idx) s->streams[idx]->duration -= s->streams[idx]->start_time; s->streams[idx]->cur_dts = AV_NOPTS_VALUE; priv->final_pts = AV_NOPTS_VALUE; - avpriv_vorbis_parse_reset(&priv->vp); + av_vorbis_parse_reset(priv->vp); } /* parse packet duration */ if (os->psize > 0) { - duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1); + duration = av_vorbis_parse_frame(priv->vp, os->buf + os->pstart, 1); if (duration <= 0) { os->pflags |= AV_PKT_FLAG_CORRUPT; return 0;