static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
static int ogg_new_stream(AVFormatContext *s, uint32_t serial);
-static int ogg_restore(AVFormatContext *s, int discard);
+static int ogg_restore(AVFormatContext *s);
+
+static void free_stream(AVFormatContext *s, int i)
+{
+ struct ogg *ogg = s->priv_data;
+ struct ogg_stream *stream = &ogg->streams[i];
+
+ av_freep(&stream->buf);
+ if (stream->codec &&
+ stream->codec->cleanup) {
+ stream->codec->cleanup(s, i);
+ }
+
+ av_freep(&stream->private);
+ av_freep(&stream->new_metadata);
+}
//FIXME We could avoid some structure duplication
static int ogg_save(AVFormatContext *s)
ogg->state = ost;
if (ret < 0)
- ogg_restore(s, 0);
+ ogg_restore(s);
return ret;
}
-static int ogg_restore(AVFormatContext *s, int discard)
+static int ogg_restore(AVFormatContext *s)
{
struct ogg *ogg = s->priv_data;
AVIOContext *bc = s->pb;
ogg->state = ost->next;
- if (!discard) {
-
- for (i = 0; i < ogg->nstreams; i++)
+ for (i = 0; i < ogg->nstreams; i++) {
av_freep(&ogg->streams[i].buf);
+ if (i >= ost->nstreams || !ost->streams[i].private) {
+ free_stream(s, i);
+ }
+ }
avio_seek(bc, ost->pos, SEEK_SET);
ogg->page_pos = -1;
} else
memcpy(ogg->streams, ost->streams,
ost->nstreams * sizeof(*ogg->streams));
- }
av_free(ost);
}
}
- ogg_restore(s, 0);
+ ogg_restore(s);
ret = ogg_save(s);
if (ret < 0)
int64_t pts;
if (i < 0) continue;
pts = ogg_calc_pts(s, i, NULL);
+ if (s->streams[i]->duration == AV_NOPTS_VALUE)
+ continue;
if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) {
s->streams[i]->duration -= pts;
ogg->streams[i].got_start= 1;
streams_left--;
}
}
- ogg_restore (s, 0);
+ ogg_restore (s);
return 0;
}
int i;
for (i = 0; i < ogg->nstreams; i++) {
- av_freep(&ogg->streams[i].buf);
- if (ogg->streams[i].codec &&
- ogg->streams[i].codec->cleanup) {
- ogg->streams[i].codec->cleanup(s, i);
- }
- av_freep(&ogg->streams[i].private);
- av_freep(&ogg->streams[i].new_metadata);
+ free_stream(s, i);
}
ogg->nstreams = 0;