[Ffmpeg-devel] ogg vorbis encode?

Alexander Strasser eclipse7
Sun Aug 14 14:28:08 CEST 2005


Hi,

Rich Felker wrote:
> On Sat, Aug 13, 2005 at 05:53:58PM +0200, Michael Niedermayer wrote:
> > On Sat, Aug 13, 2005 at 10:03:00AM -0400, Rich Felker wrote:
> > > On Sat, Aug 13, 2005 at 09:23:00AM -0400, Justin Ruggles wrote:
> > [...]
> > > > I guess that means the problem might be
> > > > in the ogg muxer?  Even doing '-acodec copy' on a valid ogg results in
> > > > an invalid ogg.
> > > 
> > > Probably so. Ogg has very stupid codec header storage, and the muxer
> > > probably doesn't store the headers.. :(
> > 
> > vorbis in ogg encoding did work fine in the past, but indeed it seems broken
> > currently, i dont know why
> 
> It's because the encoder was fixed to output its headers as extradata
> rather than (incorrectly) as audio frames, but the ogg muxer has not
> been fixed to convert them back to packets for the broken ogg header
> format.. At least that's my guess.

  I looked into this last night and it seems Rich is right.
The encoding of vorbis extra data was changed recently. But
the ogg writer wasn't updated and expects the old extradata.
  When i extract the vorbis headers from extradata like in
vorbis.c (in case of the new extradata encoding) then it seems
to work correctly.

  Patch attached, tho i am sure it may not be the best solution.

  Alex (beastd)
-------------- next part --------------
Index: libavformat/ogg.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavformat/ogg.c,v
retrieving revision 1.23
diff -u -r1.23 ogg.c
--- libavformat/ogg.c	17 Jul 2005 22:24:36 -0000	1.23
+++ libavformat/ogg.c	14 Aug 2005 12:19:35 -0000
@@ -40,15 +40,37 @@
     
     for(n = 0 ; n < avfcontext->nb_streams ; n++) {
         AVCodecContext *codec = avfcontext->streams[n]->codec;
-        uint8_t *p= codec->extradata;
+        uint8_t *headers = codec->extradata;
+        int headers_len = codec->extradata_size;
+        uint8_t *header_start[3];
+        int header_len[3];
+        int i, j, hdr_type;
         
         av_set_pts_info(avfcontext->streams[n], 60, 1, AV_TIME_BASE);
 
-        for(i=0; i < codec->extradata_size; i+= op->bytes){
-            op->bytes = p[i++]<<8;
-            op->bytes+= p[i++];
+        if (!headers_len) {
+            av_log(codec, AV_LOG_ERROR, "Extradata corrupt.\n");
+            return -1;
+        }
+
+        for(j=1,i=0;i<2;++i, ++j) {
+            header_len[i]=0;
+            while(j<headers_len && headers[j]==0xff) {
+                header_len[i]+=0xff;
+                ++j;
+            }
+            header_len[i]+=headers[j];
+        }
+        header_len[2]=headers_len-header_len[0]-header_len[1]-j;
+        headers+=j;
+        header_start[0] = headers;
+        header_start[1] = header_start[0] + header_len[0];
+        header_start[2] = header_start[1] + header_len[1];
+
+        for(i=0; i < 3; ++i){
+            op->bytes = header_len[i];
 
-            op->packet= &p[i];
+            op->packet= header_start[i];
             op->b_o_s= op->packetno==0;
 
             ogg_stream_packetin(&context->os, op);



More information about the ffmpeg-devel mailing list