Peter Maersk-Moller
2002-Mar-14 03:46 UTC
[vorbis] Ogg in MP4 file, Unexpected result from _vorbis_unpack_books
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@xiph.org' containing only the word 'unsubscribe' in the body. No subject is needed. Unsubscribe messages sent to the list will be ignored/filtered.
Michael Smith
2002-Mar-14 04:19 UTC
[vorbis] Ogg in MP4 file, Unexpected result from _vorbis_unpack_books
>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 ?You may certainly hand over ogg_packets as they are as long as they remain valid. There are various things you can do to make an existing packet become invalid, though (because the libraries are managing their memory internally rather than forcing the application to do it). You probably need to make a copy of the packet (i.e. create a new ogg_packet structure, and make a copy of the data in it). You're most likely hitting this: calling vorbis_analysis_buffer (which is called from vorbis_analysis_wrote()) will invalidate the header packets (it frees the memory associated with the headers). Similarly, a non-header packet will become invalidated on a call to one of the analysis functions (not sure which offhand, but as a general rule: finish with one packet before you ask libvorbis to produce the next - then you'll be safe). Making copies of the packets isn't terribly efficient, but it's the easy way to get this stuff working, if this is your problem (it probably is). Feel free to ask again if this doesn't explain the problems you're having. <p>Michael <p><p><p>--- >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@xiph.org' containing only the word 'unsubscribe' in the body. No subject is needed. Unsubscribe messages sent to the list will be ignored/filtered.
Peter Maersk-Moller
2002-Mar-14 04:56 UTC
[vorbis] Ogg in MP4 file, Unexpected result from _vorbis_unpack_books
Hi Michael <p>Thanks for the fast response.> >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 ? > > You may certainly hand over ogg_packets as they are as long as they remain > valid. There are various things you can do to make an existing packet > become invalid, though (because the libraries are managing their memory > internally rather than forcing the application to do it). You probably > need to make a copy of the packet (i.e. create a new ogg_packet structure, > and make a copy of the data in it). > > You're most likely hitting this: calling vorbis_analysis_buffer (which is > called from vorbis_analysis_wrote()) will invalidate the header packets > (it frees the memory associated with the headers).Not sure i completely understand. Are you saying, that my 3 ogg packets (header, header_comment and header_code) becomes invalid (or the data that the pointer packet within the ogg_packet points to) when I submit sampled audio using vorbis_analysis_wrote ?> Similarly, a non-header packet will become invalidated on a call to one > of the analysis functions (not sure which offhand, but as a general rule: > finish with one packet before you ask libvorbis to produce the next - then > you'll be safe).In my case I continously adds data in thread one by calling a) vorbis_analysis_buffer b) vorbis_analysis_wrote In thread two I do this a) ogg packet header (previously submitted to ogg_stream_packet in) is saved in a MP4 file. b) ogg packet header_comment (previously submitted to ogg_stream_packet in) is added to the MP4 file. c) ogg packet header_code (previously submitted to ogg_stream_packet in) is added to the MP4 file. d) as long as ogg_stream_flush produces a page, then save header and body of the produced page in an .ogg file In principle, the rest of the code in thread two (which extract blocks, extracts packets from blocks and submit packets to the MP4 file and then submits packets to stream and then extracts pages to save in .ogg file) ought not matter, because while trying to decode the saved data in MP4 file I get an error trying to install the code book Question #1) Adding data in thread one ought not invalidate the ogg packets header, header_comment and header_code. True or false ? Remark: Since writing the ogg packets (header, header_comment and header_code) to MP4 file before submitting them to the stream (packetin), then they ought to be valid. Assumed the described procedure above is correct, then am I doing the right thing in the player if I do this a) get the first ogg packet (the header) from the MP4 file, adjust the packet pointer a1) call vorbis_info_init a2) call 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 Can't really see why vorbis_synthesis_headerin using the third packet fails as described in my first mail. Suggestions are welcome> Making copies of the packets isn't terribly efficient, but it's the easy > way to get this stuff working, if this is your problem (it probably is).I will try this, but as described above, I can't really see why it should fail.> Feel free to ask again if this doesn't explain the problems you're having.Thanks. See questions above. Kind regards --PMM --- >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@xiph.org' containing only the word 'unsubscribe' in the body. No subject is needed. Unsubscribe messages sent to the list will be ignored/filtered.