[FFmpeg-devel] [PATCH 8/9] lavf/oggdec: make stream replacement less convoluted.
Clément Bœsch
ubitux at gmail.com
Sat Sep 15 01:20:47 CEST 2012
Also re-use the allocated buffer instead of re-allocating a new one.
---
libavformat/oggdec.c | 58 ++++++++++++++++++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 18 deletions(-)
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index aed49a5..5b3b789 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -161,9 +161,44 @@ static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
return NULL;
}
-static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
+/**
+ * Reset the current stream with a new one. This is a typical webradio
+ * situation where a new audio stream spawn (identified with a new serial) and
+ * must replace the previous one (track switch).
+ */
+static int ogg_replace_stream(AVFormatContext *s, uint32_t serial)
{
+ struct ogg *ogg = s->priv_data;
+ struct ogg_stream *os;
+ unsigned bufsize;
+ uint8_t *buf;
+
+ if (ogg->nstreams != 1) {
+ av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
+ return AVERROR_PATCHWELCOME;
+ }
+ os = &ogg->streams[0];
+
+ buf = os->buf;
+ bufsize = os->bufsize;
+
+ if (!ogg->state || ogg->state->streams[0].private != os->private)
+ av_freep(&ogg->streams[0].private);
+
+ /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We
+ * also re-use the ogg_stream allocated buffer */
+ memset(os, 0, sizeof(*os));
+ os->serial = serial;
+ os->bufsize = bufsize;
+ os->buf = buf;
+ os->header = -1;
+
+ return 0;
+}
+
+static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
+{
struct ogg *ogg = s->priv_data;
int idx = ogg->nstreams++;
AVStream *st;
@@ -182,14 +217,12 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
if (!os->buf)
return AVERROR(ENOMEM);
- if (new_avstream) {
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->id = idx;
avpriv_set_pts_info(st, 64, 1, 1000000);
- }
return idx;
}
@@ -259,22 +292,11 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
idx = ogg_find_stream (ogg, serial);
if (idx < 0){
- if (ogg->headers) {
+ if (ogg->headers)
+ idx = ogg_replace_stream(s, serial);
+ else
+ idx = ogg_new_stream(s, serial);
- if (ogg->nstreams != 1) {
- av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
- return idx;
- }
-
- av_freep(&ogg->streams[0].buf);
- if (!ogg->state || ogg->state->streams[0].private != ogg->streams[0].private)
- av_freep(&ogg->streams[0].private);
- ogg->curidx = -1;
- ogg->nstreams = 0;
- idx = ogg_new_stream(s, serial, 0);
- } else {
- idx = ogg_new_stream(s, serial, 1);
- }
if (idx < 0)
return idx;
}
--
1.7.12
More information about the ffmpeg-devel
mailing list