new Decode implementation

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5772 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty
2003-12-27 23:00:38 +00:00
parent 272d533500
commit a2b3fc7c80
3 changed files with 30 additions and 69 deletions
@@ -214,7 +214,7 @@ oggReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
ogg_stream_state * stream = static_cast<ogg_stream_state *>(cookie);
memset(format, 0, sizeof(*format));
*frameCount = 1024*1024; // don't know
*duration = 1024*1024; // don't know
*duration = 1024*1024*1024; // don't know
ogg_packet * packet = &fInitialHeaderPackets[stream->serialno];
*infoBuffer = (void*)packet;
*infoSize = sizeof(ogg_packet);
@@ -162,81 +162,44 @@ vorbisDecoder::Decode(void *buffer, int64 *frameCount,
//TRACE("vorbisDecoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
while (out_bytes_needed > 0) {
if (fResidualBytes) {
int32 bytes = min_c(fResidualBytes, out_bytes_needed);
memcpy(out_buffer, fResidualBuffer, bytes);
fResidualBuffer += bytes;
fResidualBytes -= bytes;
out_buffer += bytes;
out_bytes_needed -= bytes;
fStartTime += (1000000LL * (bytes / fFrameSize)) / fInfo.rate;
//TRACE("vorbisDecoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0);
continue;
int samples;
float **pcm;
while ((samples = vorbis_synthesis_pcmout(&fDspState,&pcm)) == 0) {
// get a new packet
void *chunkBuffer;
int32 chunkSize;
media_header mh;
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, &mh)) {
TRACE("vorbisDecoder::Decode: GetNextChunk failed\n");
return B_ERROR;
}
if (chunkSize != sizeof(ogg_packet)) {
TRACE("vorbisDecoder::Decode: chunk not ogg_packet-sized\n");
return B_ERROR;
}
ogg_packet * packet = static_cast<ogg_packet*>(chunkBuffer);
if (vorbis_synthesis(&fBlock,packet)==0) {
vorbis_synthesis_blockin(&fDspState,&fBlock);
}
}
// reduce samples to the amount of samples we will actually consume
samples = min_c(samples,out_bytes_needed/fFrameSize);
int bytes = samples*fFrameSize;
memcpy(out_buffer,pcm,bytes);
out_buffer += bytes;
out_bytes_needed -= bytes;
// report back how many samples we consumed
vorbis_synthesis_read(&fDspState,samples);
if (B_OK != DecodeNextChunk())
break;
fStartTime += (1000000LL * (bytes / fFrameSize)) / fInfo.rate;
//TRACE("vorbisDecoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0);
}
*frameCount = (fOutputBufferSize - out_bytes_needed) / fFrameSize;
// XXX this doesn't guarantee that we always return B_LAST_BUFFER_ERROR bofore returning B_ERROR
return (out_bytes_needed == 0) ? B_OK : (out_bytes_needed == fOutputBufferSize) ? B_ERROR : B_LAST_BUFFER_ERROR;
}
status_t
vorbisDecoder::DecodeNextChunk()
{
debugger("vorbisDecoder::DecodeNextChunk");
TRACE("vorbisDecoder::DecodeNextChunk\n");
void *chunkBuffer;
int32 chunkSize;
media_header mh;
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, &mh)) {
TRACE("vorbisDecoder::Decode: GetNextChunk failed\n");
return B_ERROR;
}
if (chunkSize != sizeof(ogg_packet)) {
TRACE("vorbisDecoder::Decode: chunk not ogg_packet-sized\n");
return B_ERROR;
}
ogg_packet * packet = static_cast<ogg_packet*>(chunkBuffer);
//fStartTime = mh.start_time;
//TRACE("vorbisDecoder: fStartTime reset to %.6f\n", fStartTime / 1000000.0);
if (vorbis_synthesis(&fBlock,packet)==0) {
vorbis_synthesis_blockin(&fDspState,&fBlock);
}
int convsize = DECODE_BUFFER_SIZE / fInfo.channels;
int samples;
float **pcm;
ogg_int16_t * ptr;
while ((samples = vorbis_synthesis_pcmout(&fDspState,&pcm)) > 0) {
int bout = (samples < convsize ? samples : convsize) ;
for(int i = 0; (i < fInfo.channels) ; i++) {
ptr = (ogg_int16_t *)fDecodeBuffer;
float * mono = pcm[i];
for(int j = 0; (j < bout) ; j++) {
*ptr = *reinterpret_cast<ogg_int16_t*>(&mono[j]);
ptr += fInfo.channels;
}
}
vorbis_synthesis_read(&fDspState,bout);
}
//printf("vorbisDecoder::Decode: decoded %d bytes into %d bytes\n",chunkSize, outsize);
fResidualBuffer = fDecodeBuffer;
fResidualBytes = (uint8 *)ptr - fDecodeBuffer;
return B_OK;
}
Decoder *
vorbisDecoderPlugin::NewDecoder()
{
@@ -21,8 +21,6 @@ public:
status_t Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info);
status_t DecodeNextChunk();
private:
void CopyInfoToEncodedFormat(media_format * format);
void CopyInfoToDecodedFormat(media_raw_audio_format * raf);