&ff_theora_codec,
&ff_flac_codec,
&ff_celt_codec,
+ &ff_opus_codec,
+ &ff_vp8_codec,
&ff_old_dirac_codec,
&ff_old_flac_codec,
&ff_ogm_video_codec,
struct ogg *ogg = s->priv_data;
AVIOContext *bc = s->pb;
struct ogg_state *ost = ogg->state;
- int i;
+ int i, err;
if (!ost)
return 0;
ogg->state = ost->next;
if (!discard) {
- struct ogg_stream *old_streams = ogg->streams;
for (i = 0; i < ogg->nstreams; i++)
av_free(ogg->streams[i].buf);
avio_seek(bc, ost->pos, SEEK_SET);
ogg->curidx = ost->curidx;
ogg->nstreams = ost->nstreams;
- ogg->streams = av_realloc(ogg->streams,
- ogg->nstreams * sizeof(*ogg->streams));
-
- if (ogg->streams) {
+ if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
+ sizeof(*ogg->streams))) < 0) {
+ ogg->nstreams = 0;
+ return err;
+ } else
memcpy(ogg->streams, ost->streams,
ost->nstreams * sizeof(*ogg->streams));
- } else {
- av_free(old_streams);
- ogg->nstreams = 0;
- }
}
av_free(ost);
if (!complete && os->segp == os->nsegs) {
ogg->curidx = -1;
- os->incomplete = 1;
+ // Do not set incomplete for empty packets.
+ // Together with the code in ogg_read_page
+ // that discards all continuation of empty packets
+ // we would get an infinite loop.
+ os->incomplete = !!os->psize;
}
} while (!complete);
// Update the header state for all streams and
// compute the data_offset.
- if (!s->data_offset)
- s->data_offset = os->sync_pos;
+ if (!s->internal->data_offset)
+ s->internal->data_offset = os->sync_pos;
for (i = 0; i < ogg->nstreams; i++) {
struct ogg_stream *cur_os = ogg->streams + i;
// if we have a partial non-header packet, its start is
// obviously at or after the data start
if (cur_os->incomplete)
- s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
+ s->internal->data_offset = FFMIN(s->internal->data_offset, cur_os->sync_pos);
}
} else {
os->nb_header++;
if (os->codec && os->codec->nb_header &&
os->nb_header < os->codec->nb_header) {
av_log(s, AV_LOG_ERROR,
- "Headers mismatch for stream %d\n", i);
- return AVERROR_INVALIDDATA;
+ "Headers mismatch for stream %d: "
+ "expected %d received %d.\n",
+ i, os->codec->nb_header, os->nb_header);
+ if (s->error_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
if (os->start_granule != OGG_NOGRANULE_VALUE)
os->lastpts = s->streams[i]->start_time =
for (i = 0; i < ogg->nstreams; i++) {
av_free(ogg->streams[i].buf);
+ if (ogg->streams[i].codec &&
+ ogg->streams[i].codec->cleanup) {
+ ogg->streams[i].codec->cleanup(s, i);
+ }
av_free(ogg->streams[i].private);
}
av_free(ogg->streams);
.read_seek = ogg_read_seek,
.read_timestamp = ogg_read_timestamp,
.extensions = "ogg",
- .flags = AVFMT_GENERIC_INDEX,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_NOBINSEARCH,
};