allocate ogg_stream_states dynamically, hold pointers to them in the map, check sync return result during GetPage, add myriad of vorbisDecoder debug calls, introduce temporary variables to ease debugging

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5764 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty
2003-12-26 17:39:43 +00:00
parent 0b18a76480
commit 77ae533d3c
3 changed files with 41 additions and 23 deletions
@@ -24,6 +24,12 @@ oggReader::oggReader()
oggReader::~oggReader() oggReader::~oggReader()
{ {
TRACE("oggReader::~oggReader\n"); TRACE("oggReader::~oggReader\n");
ogg_stream_map::iterator i = fStreams.begin();
while (i != fStreams.end()) {
ogg_stream_map::iterator j = i;
i++;
delete j->second;
}
ogg_sync_clear(&fSync); ogg_sync_clear(&fSync);
} }
@@ -38,8 +44,7 @@ status_t
oggReader::GetPage(ogg_page * page, int read_size, bool short_page) oggReader::GetPage(ogg_page * page, int read_size, bool short_page)
{ {
TRACE("oggReader::GetPage\n"); TRACE("oggReader::GetPage\n");
ogg_sync_pageout(&fSync,page); // clear the buffer int result = ogg_sync_pageout(&fSync,page); // first read leftovers
int result = 0;
while (result == 0) { while (result == 0) {
char * buffer = ogg_sync_buffer(&fSync,read_size); char * buffer = ogg_sync_buffer(&fSync,read_size);
ssize_t bytes = Source()->Read(buffer,read_size); ssize_t bytes = Source()->Read(buffer,read_size);
@@ -76,28 +81,28 @@ oggReader::GetPage(ogg_page * page, int read_size, bool short_page)
return B_ERROR; return B_ERROR;
#endif #endif
} }
ogg_stream_state stream; ogg_stream_state * stream = new ogg_stream_state;
fStreams[serialno] = stream; if (ogg_stream_init(stream,serialno) != 0) {
if (ogg_stream_init(&fStreams[serialno],serialno) != 0) {
TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n"); TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n");
return B_ERROR; return B_ERROR;
} }
fStreams[serialno] = stream;
} else if (ogg_page_bos(page) > 0) { } else if (ogg_page_bos(page) > 0) {
TRACE("oggReader::GetPage: bos packet with duplicate serialno\n"); TRACE("oggReader::GetPage: bos packet with duplicate serialno\n");
#ifdef STRICT_OGG #ifdef STRICT_OGG
return B_ERROR; return B_ERROR;
#else #else
if (ogg_stream_destroy(&fStreams[serialno]) != 0) { if (ogg_stream_clear(fStreams[serialno]) != 0) {
TRACE("oggReader::GetPage: ogg_stream_destroy failed?: error\n"); TRACE("oggReader::GetPage: ogg_stream_destroy failed?: error\n");
return B_ERROR; return B_ERROR;
} }
if (ogg_stream_init(&fStreams[serialno],serialno) != 0) { if (ogg_stream_init(fStreams[serialno],serialno) != 0) {
TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n"); TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n");
return B_ERROR; return B_ERROR;
} }
#endif #endif
} }
if (ogg_stream_pagein(&fStreams[serialno],page) != 0) { if (ogg_stream_pagein(fStreams[serialno],page) != 0) {
TRACE("oggReader::Sniff: ogg_stream_pagein: failed: error\n"); TRACE("oggReader::Sniff: ogg_stream_pagein: failed: error\n");
return B_ERROR; return B_ERROR;
} }
@@ -137,14 +142,17 @@ oggReader::Sniff(int32 *streamCount)
while (ogg_page_bos(&page) > 0) { while (ogg_page_bos(&page) > 0) {
int serialno = ogg_page_serialno(&page); int serialno = ogg_page_serialno(&page);
ogg_stream_state * stream = &fStreams[serialno]; ogg_stream_state * stream = fStreams[serialno];
ogg_packet packet; ogg_packet packet;
fInitialHeaderPackets[serialno] = packet; if (ogg_stream_packetout(stream,&packet) != 1) {
if (ogg_stream_packetout(stream,&fInitialHeaderPackets[serialno]) != 1) {
#ifdef STRICT_OGG #ifdef STRICT_OGG
return B_ERROR; return B_ERROR;
#endif STRICT_OGG #endif STRICT_OGG
} }
unsigned char * buffer = new unsigned char[packet.bytes];
fInitialHeaderPackets[serialno] = packet;
memcpy(buffer,packet.packet,packet.bytes);
fInitialHeaderPackets[serialno].packet = buffer;
if (GetPage(&page,4096,short_page) != B_OK) { if (GetPage(&page,4096,short_page) != B_OK) {
return B_ERROR; return B_ERROR;
} }
@@ -185,7 +193,7 @@ oggReader::AllocateCookie(int32 streamNumber, void **cookie)
streamNumber--; streamNumber--;
} }
// store the cookie // store the cookie
*cookie = (void*)(&i->second); *cookie = (void*)(i->second);
return B_OK; return B_OK;
} }
@@ -203,13 +211,13 @@ oggReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
media_format *format, void **infoBuffer, int32 *infoSize) media_format *format, void **infoBuffer, int32 *infoSize)
{ {
TRACE("oggReader::GetStreamInfo\n"); TRACE("oggReader::GetStreamInfo\n");
debugger("oggReader::GetStreamInfo");
ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie); ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie);
memset(format, 0, sizeof(*format)); memset(format, 0, sizeof(*format));
*frameCount = -1; // don't know *frameCount = -1; // don't know
*duration = -1; // don't know *duration = -1; // don't know
*infoBuffer = (void*)fInitialHeaderPackets[stream->serialno].packet; ogg_packet * packet = &fInitialHeaderPackets[stream->serialno];
*infoSize = (int32)fInitialHeaderPackets[stream->serialno].bytes; *infoBuffer = (void*)packet;
*infoSize = sizeof(ogg_packet);
return B_OK; return B_OK;
} }
@@ -249,13 +257,11 @@ oggReader::GetNextChunk(void *cookie,
} }
} while (ogg_page_serialno(&page) != stream->serialno); } while (ogg_page_serialno(&page) != stream->serialno);
} }
if (fPackets.find(stream->serialno) == fPackets.end()) {
ogg_packet packet; ogg_packet packet;
fPackets[stream->serialno] = packet; if (ogg_stream_packetout(stream,&packet) != 1) {
}
if (ogg_stream_packetout(stream,&fPackets[stream->serialno]) != 1) {
return B_ERROR; return B_ERROR;
} }
fPackets[stream->serialno] = packet;
*chunkBuffer = (void*)&fPackets[stream->serialno]; *chunkBuffer = (void*)&fPackets[stream->serialno];
*chunkSize = sizeof(ogg_packet); *chunkSize = sizeof(ogg_packet);
@@ -7,7 +7,7 @@
namespace BPrivate { namespace media { namespace BPrivate { namespace media {
typedef std::map<int,ogg_stream_state> ogg_stream_map; typedef std::map<int,ogg_stream_state*> ogg_stream_map;
typedef std::map<int,ogg_packet> ogg_packet_map; typedef std::map<int,ogg_packet> ogg_packet_map;
class oggReader : public Reader class oggReader : public Reader
@@ -17,6 +17,7 @@
vorbisDecoder::vorbisDecoder() vorbisDecoder::vorbisDecoder()
{ {
TRACE("vorbisDecoder::vorbisDecoder\n");
vorbis_info_init(&fInfo); vorbis_info_init(&fInfo);
vorbis_comment_init(&fComment); vorbis_comment_init(&fComment);
@@ -32,6 +33,8 @@ vorbisDecoder::vorbisDecoder()
vorbisDecoder::~vorbisDecoder() vorbisDecoder::~vorbisDecoder()
{ {
debugger("vorbisDecoder::~vorbisDecoder");
TRACE("vorbisDecoder::~vorbisDecoder\n");
delete [] fDecodeBuffer; delete [] fDecodeBuffer;
} }
@@ -40,6 +43,8 @@ status_t
vorbisDecoder::Setup(media_format *ioEncodedFormat, vorbisDecoder::Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize) const void *infoBuffer, int32 infoSize)
{ {
debugger("vorbisDecoder::Setup");
TRACE("vorbisDecoder::Setup\n");
if ((ioEncodedFormat->type != B_MEDIA_UNKNOWN_TYPE) if ((ioEncodedFormat->type != B_MEDIA_UNKNOWN_TYPE)
&& (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO)) { && (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO)) {
TRACE("vorbisDecoder::Setup not called with audio/unknown stream: not vorbis"); TRACE("vorbisDecoder::Setup not called with audio/unknown stream: not vorbis");
@@ -49,13 +54,13 @@ vorbisDecoder::Setup(media_format *ioEncodedFormat,
TRACE("vorbisDecoder::Setup not called with ogg_packet info: not vorbis"); TRACE("vorbisDecoder::Setup not called with ogg_packet info: not vorbis");
return B_ERROR; return B_ERROR;
} }
ogg_packet * packet = (ogg_packet*)infoBuffer;
// parse header packet // parse header packet
if (vorbis_synthesis_headerin(&fInfo,&fComment,(ogg_packet*)infoBuffer) != 0) { if (vorbis_synthesis_headerin(&fInfo,&fComment,packet) != 0) {
TRACE("vorbisDecoder::Setup: vorbis_synthesis_headerin failed: not vorbis header"); TRACE("vorbisDecoder::Setup: vorbis_synthesis_headerin failed: not vorbis header");
return B_ERROR; return B_ERROR;
} }
// get comment packet // get comment packet
ogg_packet * packet;
int32 size; int32 size;
media_header mh; media_header mh;
if (GetNextChunk((void**)&packet, &size, &mh) != B_OK) { if (GetNextChunk((void**)&packet, &size, &mh) != B_OK) {
@@ -91,6 +96,8 @@ size_t get_audio_buffer_size(const media_raw_audio_format & raf) {
status_t status_t
vorbisDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat) vorbisDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
{ {
debugger("vorbisDecoder::NegotiateOutputFormat");
TRACE("vorbisDecoder::NegotiateOutputFormat\n");
// BeBook says: The codec will find and return in ioFormat its best matching format // BeBook says: The codec will find and return in ioFormat its best matching format
// => This means, we never return an error, and always change the format values // => This means, we never return an error, and always change the format values
// that we don't support to something more applicable // that we don't support to something more applicable
@@ -122,6 +129,7 @@ vorbisDecoder::Seek(uint32 seekTo,
bigtime_t seekTime, bigtime_t *time) bigtime_t seekTime, bigtime_t *time)
{ {
debugger("vorbisDecoder::Seek"); debugger("vorbisDecoder::Seek");
TRACE("vorbisDecoder::Seek\n");
fResidualBytes = 0; fResidualBytes = 0;
return B_OK; return B_OK;
} }
@@ -131,6 +139,8 @@ status_t
vorbisDecoder::Decode(void *buffer, int64 *frameCount, vorbisDecoder::Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info /* = 0 */) media_header *mediaHeader, media_decode_info *info /* = 0 */)
{ {
debugger("vorbisDecoder::Decode");
TRACE("vorbisDecoder::Decode\n");
uint8 * out_buffer = static_cast<uint8 *>(buffer); uint8 * out_buffer = static_cast<uint8 *>(buffer);
int32 out_bytes_needed = fOutputBufferSize; int32 out_bytes_needed = fOutputBufferSize;
@@ -165,6 +175,8 @@ vorbisDecoder::Decode(void *buffer, int64 *frameCount,
status_t status_t
vorbisDecoder::DecodeNextChunk() vorbisDecoder::DecodeNextChunk()
{ {
debugger("vorbisDecoder::DecodeNextChunk");
TRACE("vorbisDecoder::DecodeNextChunk\n");
void *chunkBuffer; void *chunkBuffer;
int32 chunkSize; int32 chunkSize;
media_header mh; media_header mh;