[FFmpeg-cvslog] lavf/oggdec: make stream replacement less convoluted.
Clément Bœsch
git at videolan.org
Sun Sep 16 18:34:20 CEST 2012
ffmpeg | branch: master | Clément Bœsch <ubitux at gmail.com> | Sat Sep 15 00:41:08 2012 +0200| [a218c5ebd277451cf177877739d806bc70e8e262] | committer: Clément Bœsch
lavf/oggdec: make stream replacement less convoluted.
Also re-use the allocated buffer instead of re-allocating a new one.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a218c5ebd277451cf177877739d806bc70e8e262
---
libavformat/oggdec.c | 58 ++++++++++++++++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 18 deletions(-)
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 682a942..45fba7e 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)
+/**
+ * Replace 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;
@@ -183,7 +218,6 @@ 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) {
av_freep(&os->buf);
@@ -192,7 +226,6 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
st->id = idx;
avpriv_set_pts_info(st, 64, 1, 1000000);
- }
ogg->nstreams++;
return idx;
@@ -263,22 +296,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) {
av_log (s, AV_LOG_ERROR, "failed to create stream (OOM?)\n");
return idx;
More information about the ffmpeg-cvslog
mailing list