Hi,

Here is the patch for the issue discussed here:
http://lists.libav.org/pipermail/libav-devel/2011-April/001220.html.

I had to change the ogg_stream struct to add a field; I thought about
using another unset field to check if a packet is an initial one or not,
but I wasn't able to find one.

After the patch, with a recent MPD httpd streamer and the always_on option
(send silence when song is paused), I'm able to pause a song, continue it,
switch song and even pause the song and then start a new one. This last
one was not obvious to deal with since MPD strangely send packet with BOS
flags set when a song is paused… This means the state stays in "waiting
for new streams" (the only stream available is on initial mode) while in
fact the stream for the new song have to replace the old one.

I hope this is the correct way to fix it.

Regards,

-- 
Clément B.
From d6a5f219ab10092fa34df8e63d3ebdac50cdcf37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <[email protected]>
Date: Tue, 5 Apr 2011 00:29:01 +0200
Subject: [PATCH] oggdec: fix streaming with continuous audio streams (issue2337)

---
 libavformat/oggdec.c |   20 +++++++++++++++-----
 libavformat/oggdec.h |    1 +
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index cd866d4..ae638c2 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -164,6 +164,7 @@ ogg_new_stream (AVFormatContext * s, uint32_t serial)
     os->bufsize = DECODER_BUFFER_SIZE;
     os->buf = av_malloc(os->bufsize);
     os->header = -1;
+    os->initial = 1;
 
     st = av_new_stream (s, idx);
     if (!st)
@@ -239,14 +240,23 @@ ogg_read_page (AVFormatContext * s, int *str)
     crc = avio_rl32 (bc);
     nsegs = avio_r8(bc);
 
-    idx = ogg_find_stream (ogg, serial);
-    if (idx < 0){
-        idx = ogg_new_stream (s, serial);
-        if (idx < 0)
-            return -1;
+    idx = ogg_find_stream(ogg, serial);
+    if (idx < 0) {
+        for (i = 0; i < ogg->nstreams; i++) {
+            if (!ogg->streams[i].initial) {
+                ogg_reset(ogg);
+                ogg->nstreams = 0;
+                break;
+            }
+        }
+        idx = ogg_new_stream(s, serial);
     }
+    if (idx < 0)
+        return -1;
 
     os = ogg->streams + idx;
+    if (!(flags & OGG_FLAG_BOS))
+        os->initial = 0;
     os->page_pos = avio_tell(bc) - 27;
 
     if(os->psize > 0)
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index 7d66cd5..2cac20d 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -75,6 +75,7 @@ struct ogg_stream {
     int incomplete; ///< whether we're expecting a continuation in the next 
page
     int page_end;   ///< current packet is the last one completed in the page
     int keyframe_seek;
+    int initial;
     void *private;
 };
 
-- 
1.7.4.2

Attachment: pgpjvJi1VNtMk.pgp
Description: PGP signature

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to