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;
* '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);
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);
+ }
}
}
ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
- return 0;
+ return updates;
}
/*
struct oggvorbis_private {
unsigned int len[3];
unsigned char *packet[3];
- VorbisParseContext vp;
+ AVVorbisParseContext *vp;
int64_t final_pts;
int final_duration;
};
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;
}
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)
}
} 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);
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;
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
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;
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;