mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lavf/oggdec: check for begin-of-stream flag in case of chained streams.
Fix Ticket #1617, revealing a regression I introduced in 8f3eebd
.
We need to make sure no stream is added in between Ogg context save and
restore operations (because it would likely lead to a mismatch between
ogg->nstreams and AVFormatContext->nb_streams after the restore op).
This is the reason the ogg->state check is added in ogg_new_stream().
Before this patch, checking for ogg->headers was preventing this:
ogg->headers is always set before any ogg save/restore (though, it was
also preventing from creating the stream when necessary).
This commit is contained in:
parent
405ee405c9
commit
ea5bd7ea6f
@ -139,6 +139,7 @@ static int ogg_reset(AVFormatContext *s)
|
|||||||
os->nsegs = 0;
|
os->nsegs = 0;
|
||||||
os->segp = 0;
|
os->segp = 0;
|
||||||
os->incomplete = 0;
|
os->incomplete = 0;
|
||||||
|
os->got_data = 0;
|
||||||
if (start_pos <= s->data_offset) {
|
if (start_pos <= s->data_offset) {
|
||||||
os->lastpts = 0;
|
os->lastpts = 0;
|
||||||
}
|
}
|
||||||
@ -205,6 +206,12 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
|
|||||||
struct ogg_stream *os;
|
struct ogg_stream *os;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
if (ogg->state) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
|
||||||
|
"in between Ogg context save/restore operations.\n");
|
||||||
|
return AVERROR_BUG;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate and init a new Ogg Stream */
|
/* Allocate and init a new Ogg Stream */
|
||||||
if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
|
if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
|
||||||
!(os = av_realloc(ogg->streams, size)))
|
!(os = av_realloc(ogg->streams, size)))
|
||||||
@ -248,6 +255,16 @@ static int ogg_new_buf(struct ogg *ogg, int idx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int data_packets_seen(const struct ogg *ogg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ogg->nstreams; i++)
|
||||||
|
if (ogg->streams[i].got_data)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ogg_read_page(AVFormatContext *s, int *sid)
|
static int ogg_read_page(AVFormatContext *s, int *sid)
|
||||||
{
|
{
|
||||||
AVIOContext *bc = s->pb;
|
AVIOContext *bc = s->pb;
|
||||||
@ -297,7 +314,7 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
|
|||||||
|
|
||||||
idx = ogg_find_stream (ogg, serial);
|
idx = ogg_find_stream (ogg, serial);
|
||||||
if (idx < 0){
|
if (idx < 0){
|
||||||
if (ogg->headers)
|
if (data_packets_seen(ogg))
|
||||||
idx = ogg_replace_stream(s, serial);
|
idx = ogg_replace_stream(s, serial);
|
||||||
else
|
else
|
||||||
idx = ogg_new_stream(s, serial);
|
idx = ogg_new_stream(s, serial);
|
||||||
@ -325,6 +342,9 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
|
|||||||
for (i = 0; i < nsegs; i++)
|
for (i = 0; i < nsegs; i++)
|
||||||
size += os->segments[i];
|
size += os->segments[i];
|
||||||
|
|
||||||
|
if (!(flags & OGG_FLAG_BOS))
|
||||||
|
os->got_data = 1;
|
||||||
|
|
||||||
if (flags & OGG_FLAG_CONT || os->incomplete){
|
if (flags & OGG_FLAG_CONT || os->incomplete){
|
||||||
if (!os->psize){
|
if (!os->psize){
|
||||||
// If this is the very first segment we started
|
// If this is the very first segment we started
|
||||||
|
@ -76,6 +76,7 @@ struct ogg_stream {
|
|||||||
int page_end; ///< current packet is the last one completed in the page
|
int page_end; ///< current packet is the last one completed in the page
|
||||||
int keyframe_seek;
|
int keyframe_seek;
|
||||||
int got_start;
|
int got_start;
|
||||||
|
int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise
|
||||||
void *private;
|
void *private;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user