fixed playback of small files by properly returning errors
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5617 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2c24a8d065
commit
2d923d67f0
@ -107,8 +107,10 @@ status_t
|
||||
mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
||||
media_header *mediaHeader, media_decode_info *info /* = 0 */)
|
||||
{
|
||||
status_t last_err = B_LAST_BUFFER_ERROR;
|
||||
uint8 * out_buffer = static_cast<uint8 *>(buffer);
|
||||
int32 out_bytes_needed = fOutputBufferSize;
|
||||
int32 out_bytes = 0;
|
||||
|
||||
mediaHeader->start_time = fStartTime;
|
||||
//TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
|
||||
@ -120,6 +122,7 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
||||
fResidualBuffer += bytes;
|
||||
fResidualBytes -= bytes;
|
||||
out_buffer += bytes;
|
||||
out_bytes += bytes;
|
||||
out_bytes_needed -= bytes;
|
||||
|
||||
fStartTime += (1000000LL * (bytes / fFrameSize)) / fFrameRate;
|
||||
@ -128,14 +131,14 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (B_OK != DecodeNextChunk())
|
||||
last_err = DecodeNextChunk();
|
||||
if (last_err != B_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
*frameCount = (fOutputBufferSize - out_bytes_needed) / fFrameSize;
|
||||
*frameCount = out_bytes / 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;
|
||||
return (out_bytes > 0) ? B_OK : last_err;
|
||||
}
|
||||
|
||||
status_t
|
||||
@ -144,10 +147,11 @@ mp3Decoder::DecodeNextChunk()
|
||||
void *chunkBuffer;
|
||||
int32 chunkSize;
|
||||
media_header mh;
|
||||
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, &mh)) {
|
||||
TRACE("mp3Decoder::Decode: GetNextChunk failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
status_t err;
|
||||
|
||||
err = GetNextChunk(&chunkBuffer, &chunkSize, &mh);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
fStartTime = mh.start_time;
|
||||
|
||||
|
@ -232,19 +232,14 @@ mp3Reader::AllocateCookie(int32 streamNumber, void **cookie)
|
||||
data->framePosition = 0;
|
||||
data->framesPerFrame = frame_sample_count_table[layer_index];
|
||||
|
||||
// BMediaFormats formats;
|
||||
media_format_description description;
|
||||
description.family = B_MPEG_FORMAT_FAMILY;
|
||||
description.u.mpeg.id = b_mpeg_id_table[mpeg_version_index][layer_index];
|
||||
// formats.GetFormatFor(description, &data->format);
|
||||
BMediaFormats formats;
|
||||
formats.GetFormatFor(description, &data->format);
|
||||
|
||||
_get_format_for_description(&data->format, description);
|
||||
|
||||
// data->format.u.encoded_audio.encoding = media_encoded_audio_format::B_ANY;
|
||||
data->format.u.encoded_audio.bit_rate = bit_rate;
|
||||
data->format.u.encoded_audio.frame_size = frame_size;
|
||||
// data->format.u.encoded_audio.output.frame_rate = data->frameRate;
|
||||
// data->format.u.encoded_audio.output.channel_count = 2;
|
||||
|
||||
// store the cookie
|
||||
*cookie = data;
|
||||
@ -354,7 +349,7 @@ mp3Reader::GetNextChunk(void *cookie,
|
||||
|
||||
int64 maxbytes = fDataSize - data->position;
|
||||
if (maxbytes < 4)
|
||||
return B_ERROR;
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
|
||||
mediaHeader->start_time = (data->framePosition * 1000000) / data->frameRate;
|
||||
mediaHeader->file_pos = data->position;
|
||||
@ -383,6 +378,8 @@ retry:
|
||||
|
||||
if (size > maxbytes)
|
||||
size = maxbytes;
|
||||
if (size == 0)
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
|
||||
if (size != Source()->ReadAt(fDataStart + data->position, data->chunkBuffer + 4, size)) {
|
||||
TRACE("mp3Reader::GetNextChunk: unexpected read error\n");
|
||||
|
@ -67,8 +67,11 @@ RawDecoder::Decode(void *buffer, int64 *frameCount,
|
||||
{
|
||||
void *chunkBuffer;
|
||||
int32 chunkSize;
|
||||
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, mediaHeader))
|
||||
return B_ERROR;
|
||||
status_t err;
|
||||
|
||||
err = GetNextChunk(&chunkBuffer, &chunkSize, mediaHeader);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
|
||||
memcpy(buffer, chunkBuffer, chunkSize);
|
||||
*frameCount = chunkSize / fFrameSize;
|
||||
|
@ -349,17 +349,16 @@ WavReader::GetNextChunk(void *cookie,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
wavdata *data = reinterpret_cast<wavdata *>(cookie);
|
||||
status_t result = B_OK;
|
||||
|
||||
mediaHeader->start_time = (((8 * data->position) / data->bitsperframe) * 1000000LL) / data->fps;
|
||||
mediaHeader->file_pos = fDataStart + data->position;
|
||||
|
||||
int64 maxreadsize = data->datasize - data->position;
|
||||
int32 readsize = data->buffersize;
|
||||
if (maxreadsize < readsize) {
|
||||
if (maxreadsize < readsize)
|
||||
readsize = maxreadsize;
|
||||
result = B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
if (readsize == 0)
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
|
||||
if (readsize != Source()->ReadAt(fDataStart + data->position, data->buffer, readsize)) {
|
||||
TRACE("WavReader::GetNextChunk: unexpected read error\n");
|
||||
@ -371,7 +370,7 @@ WavReader::GetNextChunk(void *cookie,
|
||||
data->position += readsize;
|
||||
*chunkBuffer = data->buffer;
|
||||
*chunkSize = readsize;
|
||||
return result;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <Autolock.h>
|
||||
|
||||
MediaExtractor::MediaExtractor(BDataIO * source, int32 flags)
|
||||
{
|
||||
@ -148,6 +149,11 @@ MediaExtractor::GetNextChunk(int32 stream,
|
||||
//CALLED();
|
||||
// get buffered chunk
|
||||
|
||||
// XXX until this is done in a single extractor thread,
|
||||
// XXX make calls to GetNextChunk thread save
|
||||
static BLocker locker;
|
||||
BAutolock lock(locker);
|
||||
|
||||
// XXX this should be done in a different thread, and double buffered for each stream
|
||||
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer, chunkSize, mediaHeader);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user