[vorbis] Ogg in MP4 file, Unexpected result from _vorbis_unpack_books

Peter Maersk-Moller Peter.Maersk-Moller at ebone.net
Thu Mar 14 03:46:12 PST 2002



Hi.

I'm trying to implement Ogg/Vorbis support for the MPEG4IP project.
The goal is to support Ogg/Vorbis audio for MPEG-4 streaming.

So far I have managed to make the encoder save Ogg packets as an Audio
object in an .mp4 file. As a side effect, it can also save Ogg pages in
an .ogg file playable by xmms, but that's no big deal.

So what I'm doing is this. First the init part.

  a) vorbis_info_init
  b) vorbis_encode_init
  c) vorbis_comment_init
  d) vorbis_comment_add_tag
  e) ogg_stream_init
  f) vorbis_analysis_headerout
  g) ogg_stream_packetin for the header, the header_comment and the header_code

Then the encode part

  a) sample pcm and hand it to encode code
  b) get buffer space  with vorbis_analysis_buffer
  c) convert 16 bit signed pcm to float and place in buffer
  d) tell data size submitted with vorbis_analysis_wrote
  then go back to a)

In another thread I do

  a) submit ogg packet header(header and data) to MP4 save routine
  b) submit ogg packet header_comment (header and data) to MP4 save routine
  c) submit ogg packet header_code (header and data) to MP4 save routine
  d) Get Ogg page(s) containing the header, comment and code using ogg_stream_flush
     and save it into an .ogg file

Note that the ogg_packets and not the ogg page is submitted to the MP4 save routine.

Then I do

  a) If we have a block ready, then get next ogg_packet with
     vorbis_bitrate_flushpacket
  b) If we didn't get an ogg packet or if we don't have a block then
     b1) get a block with vorbis_analysis_blockout
     b2) run vorbis_analysis on block.
     b3) run vorbis_bitrate_addblock
     b4) get an ogg packet with vorbis_bitrate_flushpacket. If none are
         available, then return to a)
  c) submit ogg packet to MP4 save routine
  d) add ogg packet to stream using ogg_stream_packetin
  e) If an Ogg page is ready, then get it using ogg_stream_pageout and then
  append it to .ogg file.
  f) return to a)

Now on the playing side playing the generated MP4 file, the encoder gets
handed chunks of data as they were handed over to the MP save routine.

  a) get the first ogg packet (the header), adjust the packet pointer
     a1) run vorbis_info_init
     a2) run vorbis_comment_init
     a3) call vorbis_synthesis_headerin using the first packet
  b) get the second packet (the header_comment), adjust the packet pointer
     b1) call vorbis_synthesis_headerin using the second packet
  c) get the third packet (the code book), adjust the packet pointer
     b1) call vorbis_synthesis_headerin using the third packet

Here the vorbis_synthesis_headerin returns -133 (Bad header).

Can anybody tell me if I'm using the libs in a way they are not suppose to ?
Is it invalid to hand over the raw ogg_packets the way I do it ?

Looking into vorbis_synthesis_headerin I find the return (-133) is
caused by the _vorbis_unpack_books code in the lib/info.c in the
libvorbis library. In this code in the last poart of the function
_vorbis_unpack_books it says

----------------------------------------------------------------
  for(i=0;i<ci->modes;i++){
    ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
    ci->mode_param[i]->blockflag=oggpack_read(opb,1);
    ci->mode_param[i]->windowtype=oggpack_read(opb,16);
    ci->mode_param[i]->transformtype=oggpack_read(opb,16);
    ci->mode_param[i]->mapping=oggpack_read(opb,8);

    if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
    if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
fprintf(stderr,"i = %d mapping =%d maps=%d\n",i, ci->mode_param[i]->mapping,ci->maps);
    if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
  }

  if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */

  return(0);
 err_out:
  vorbis_info_clear(vi);
  return(ci->maps);
  return(OV_EBADHEADER);
----------------------------------------------------------------

The fprintf line is mine and the output for packet no 3 is

        i = 0 mapping =0 maps=2
        i = 1 mapping =96 maps=2

which makes the code return OV_EBADHEADER

Is this to be expected ?

Later when I have this working, the goal is to use pure Vorbis data
rather than Ogg packets as described here - but that's for later.

Kind regards

--PMM

PS, using libvorbis-1.0rc3 on Linux i386 2.4.13pre5 SMP and GCC 2.95.3

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the Vorbis mailing list