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()
{
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);
}
@@ -38,8 +44,7 @@ status_t
oggReader::GetPage(ogg_page * page, int read_size, bool short_page)
{
TRACE("oggReader::GetPage\n");
ogg_sync_pageout(&fSync,page); // clear the buffer
int result = 0;
int result = ogg_sync_pageout(&fSync,page); // first read leftovers
while (result == 0) {
char * buffer = ogg_sync_buffer(&fSync,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;
#endif
}
ogg_stream_state stream;
fStreams[serialno] = stream;
if (ogg_stream_init(&fStreams[serialno],serialno) != 0) {
ogg_stream_state * stream = new ogg_stream_state;
if (ogg_stream_init(stream,serialno) != 0) {
TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n");
return B_ERROR;
}
fStreams[serialno] = stream;
} else if (ogg_page_bos(page) > 0) {
TRACE("oggReader::GetPage: bos packet with duplicate serialno\n");
#ifdef STRICT_OGG
return B_ERROR;
#else
if (ogg_stream_destroy(&fStreams[serialno]) != 0) {
if (ogg_stream_clear(fStreams[serialno]) != 0) {
TRACE("oggReader::GetPage: ogg_stream_destroy failed?: error\n");
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");
return B_ERROR;
}
#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");
return B_ERROR;
}
@@ -137,14 +142,17 @@ oggReader::Sniff(int32 *streamCount)
while (ogg_page_bos(&page) > 0) {
int serialno = ogg_page_serialno(&page);
ogg_stream_state * stream = &fStreams[serialno];
ogg_stream_state * stream = fStreams[serialno];
ogg_packet packet;
fInitialHeaderPackets[serialno] = packet;
if (ogg_stream_packetout(stream,&fInitialHeaderPackets[serialno]) != 1) {
if (ogg_stream_packetout(stream,&packet) != 1) {
#ifdef STRICT_OGG
return B_ERROR;
#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) {
return B_ERROR;
}
@@ -185,7 +193,7 @@ oggReader::AllocateCookie(int32 streamNumber, void **cookie)
streamNumber--;
}
// store the cookie
*cookie = (void*)(&i->second);
*cookie = (void*)(i->second);
return B_OK;
}
@@ -203,13 +211,13 @@ oggReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
media_format *format, void **infoBuffer, int32 *infoSize)
{
TRACE("oggReader::GetStreamInfo\n");
debugger("oggReader::GetStreamInfo");
ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie);
memset(format, 0, sizeof(*format));
*frameCount = -1; // don't know
*duration = -1; // don't know
*infoBuffer = (void*)fInitialHeaderPackets[stream->serialno].packet;
*infoSize = (int32)fInitialHeaderPackets[stream->serialno].bytes;
ogg_packet * packet = &fInitialHeaderPackets[stream->serialno];
*infoBuffer = (void*)packet;
*infoSize = sizeof(ogg_packet);
return B_OK;
}
@@ -249,13 +257,11 @@ oggReader::GetNextChunk(void *cookie,
}
} while (ogg_page_serialno(&page) != stream->serialno);
}
if (fPackets.find(stream->serialno) == fPackets.end()) {
ogg_packet packet;
fPackets[stream->serialno] = packet;
}
if (ogg_stream_packetout(stream,&fPackets[stream->serialno]) != 1) {
ogg_packet packet;
if (ogg_stream_packetout(stream,&packet) != 1) {
return B_ERROR;
}
fPackets[stream->serialno] = packet;
*chunkBuffer = (void*)&fPackets[stream->serialno];
*chunkSize = sizeof(ogg_packet);
@@ -7,7 +7,7 @@
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;
class oggReader : public Reader
@@ -17,6 +17,7 @@
vorbisDecoder::vorbisDecoder()
{
TRACE("vorbisDecoder::vorbisDecoder\n");
vorbis_info_init(&fInfo);
vorbis_comment_init(&fComment);
@@ -32,6 +33,8 @@ vorbisDecoder::vorbisDecoder()
vorbisDecoder::~vorbisDecoder()
{
debugger("vorbisDecoder::~vorbisDecoder");
TRACE("vorbisDecoder::~vorbisDecoder\n");
delete [] fDecodeBuffer;
}
@@ -40,6 +43,8 @@ status_t
vorbisDecoder::Setup(media_format *ioEncodedFormat,
const void *infoBuffer, int32 infoSize)
{
debugger("vorbisDecoder::Setup");
TRACE("vorbisDecoder::Setup\n");
if ((ioEncodedFormat->type != B_MEDIA_UNKNOWN_TYPE)
&& (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO)) {
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");
return B_ERROR;
}
ogg_packet * packet = (ogg_packet*)infoBuffer;
// 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");
return B_ERROR;
}
// get comment packet
ogg_packet * packet;
int32 size;
media_header mh;
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
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
// => This means, we never return an error, and always change the format values
// that we don't support to something more applicable
@@ -122,6 +129,7 @@ vorbisDecoder::Seek(uint32 seekTo,
bigtime_t seekTime, bigtime_t *time)
{
debugger("vorbisDecoder::Seek");
TRACE("vorbisDecoder::Seek\n");
fResidualBytes = 0;
return B_OK;
}
@@ -131,6 +139,8 @@ status_t
vorbisDecoder::Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info /* = 0 */)
{
debugger("vorbisDecoder::Decode");
TRACE("vorbisDecoder::Decode\n");
uint8 * out_buffer = static_cast<uint8 *>(buffer);
int32 out_bytes_needed = fOutputBufferSize;
@@ -165,6 +175,8 @@ vorbisDecoder::Decode(void *buffer, int64 *frameCount,
status_t
vorbisDecoder::DecodeNextChunk()
{
debugger("vorbisDecoder::DecodeNextChunk");
TRACE("vorbisDecoder::DecodeNextChunk\n");
void *chunkBuffer;
int32 chunkSize;
media_header mh;