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:
@@ -107,8 +107,10 @@ status_t
|
|||||||
mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
||||||
media_header *mediaHeader, media_decode_info *info /* = 0 */)
|
media_header *mediaHeader, media_decode_info *info /* = 0 */)
|
||||||
{
|
{
|
||||||
|
status_t last_err = B_LAST_BUFFER_ERROR;
|
||||||
uint8 * out_buffer = static_cast<uint8 *>(buffer);
|
uint8 * out_buffer = static_cast<uint8 *>(buffer);
|
||||||
int32 out_bytes_needed = fOutputBufferSize;
|
int32 out_bytes_needed = fOutputBufferSize;
|
||||||
|
int32 out_bytes = 0;
|
||||||
|
|
||||||
mediaHeader->start_time = fStartTime;
|
mediaHeader->start_time = fStartTime;
|
||||||
//TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
|
//TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
|
||||||
@@ -120,6 +122,7 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
|||||||
fResidualBuffer += bytes;
|
fResidualBuffer += bytes;
|
||||||
fResidualBytes -= bytes;
|
fResidualBytes -= bytes;
|
||||||
out_buffer += bytes;
|
out_buffer += bytes;
|
||||||
|
out_bytes += bytes;
|
||||||
out_bytes_needed -= bytes;
|
out_bytes_needed -= bytes;
|
||||||
|
|
||||||
fStartTime += (1000000LL * (bytes / fFrameSize)) / fFrameRate;
|
fStartTime += (1000000LL * (bytes / fFrameSize)) / fFrameRate;
|
||||||
@@ -128,14 +131,14 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (B_OK != DecodeNextChunk())
|
last_err = DecodeNextChunk();
|
||||||
|
if (last_err != B_OK)
|
||||||
break;
|
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 > 0) ? B_OK : last_err;
|
||||||
return (out_bytes_needed == 0) ? B_OK : (out_bytes_needed == fOutputBufferSize) ? B_ERROR : B_LAST_BUFFER_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
@@ -144,10 +147,11 @@ mp3Decoder::DecodeNextChunk()
|
|||||||
void *chunkBuffer;
|
void *chunkBuffer;
|
||||||
int32 chunkSize;
|
int32 chunkSize;
|
||||||
media_header mh;
|
media_header mh;
|
||||||
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, &mh)) {
|
status_t err;
|
||||||
TRACE("mp3Decoder::Decode: GetNextChunk failed\n");
|
|
||||||
return B_ERROR;
|
err = GetNextChunk(&chunkBuffer, &chunkSize, &mh);
|
||||||
}
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
fStartTime = mh.start_time;
|
fStartTime = mh.start_time;
|
||||||
|
|
||||||
|
|||||||
@@ -232,19 +232,14 @@ mp3Reader::AllocateCookie(int32 streamNumber, void **cookie)
|
|||||||
data->framePosition = 0;
|
data->framePosition = 0;
|
||||||
data->framesPerFrame = frame_sample_count_table[layer_index];
|
data->framesPerFrame = frame_sample_count_table[layer_index];
|
||||||
|
|
||||||
// BMediaFormats formats;
|
|
||||||
media_format_description description;
|
media_format_description description;
|
||||||
description.family = B_MPEG_FORMAT_FAMILY;
|
description.family = B_MPEG_FORMAT_FAMILY;
|
||||||
description.u.mpeg.id = b_mpeg_id_table[mpeg_version_index][layer_index];
|
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.bit_rate = bit_rate;
|
||||||
data->format.u.encoded_audio.frame_size = frame_size;
|
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
|
// store the cookie
|
||||||
*cookie = data;
|
*cookie = data;
|
||||||
@@ -354,7 +349,7 @@ mp3Reader::GetNextChunk(void *cookie,
|
|||||||
|
|
||||||
int64 maxbytes = fDataSize - data->position;
|
int64 maxbytes = fDataSize - data->position;
|
||||||
if (maxbytes < 4)
|
if (maxbytes < 4)
|
||||||
return B_ERROR;
|
return B_LAST_BUFFER_ERROR;
|
||||||
|
|
||||||
mediaHeader->start_time = (data->framePosition * 1000000) / data->frameRate;
|
mediaHeader->start_time = (data->framePosition * 1000000) / data->frameRate;
|
||||||
mediaHeader->file_pos = data->position;
|
mediaHeader->file_pos = data->position;
|
||||||
@@ -383,6 +378,8 @@ retry:
|
|||||||
|
|
||||||
if (size > maxbytes)
|
if (size > maxbytes)
|
||||||
size = maxbytes;
|
size = maxbytes;
|
||||||
|
if (size == 0)
|
||||||
|
return B_LAST_BUFFER_ERROR;
|
||||||
|
|
||||||
if (size != Source()->ReadAt(fDataStart + data->position, data->chunkBuffer + 4, size)) {
|
if (size != Source()->ReadAt(fDataStart + data->position, data->chunkBuffer + 4, size)) {
|
||||||
TRACE("mp3Reader::GetNextChunk: unexpected read error\n");
|
TRACE("mp3Reader::GetNextChunk: unexpected read error\n");
|
||||||
|
|||||||
@@ -67,8 +67,11 @@ RawDecoder::Decode(void *buffer, int64 *frameCount,
|
|||||||
{
|
{
|
||||||
void *chunkBuffer;
|
void *chunkBuffer;
|
||||||
int32 chunkSize;
|
int32 chunkSize;
|
||||||
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, mediaHeader))
|
status_t err;
|
||||||
return B_ERROR;
|
|
||||||
|
err = GetNextChunk(&chunkBuffer, &chunkSize, mediaHeader);
|
||||||
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
memcpy(buffer, chunkBuffer, chunkSize);
|
memcpy(buffer, chunkBuffer, chunkSize);
|
||||||
*frameCount = chunkSize / fFrameSize;
|
*frameCount = chunkSize / fFrameSize;
|
||||||
|
|||||||
@@ -349,17 +349,16 @@ WavReader::GetNextChunk(void *cookie,
|
|||||||
media_header *mediaHeader)
|
media_header *mediaHeader)
|
||||||
{
|
{
|
||||||
wavdata *data = reinterpret_cast<wavdata *>(cookie);
|
wavdata *data = reinterpret_cast<wavdata *>(cookie);
|
||||||
status_t result = B_OK;
|
|
||||||
|
|
||||||
mediaHeader->start_time = (((8 * data->position) / data->bitsperframe) * 1000000LL) / data->fps;
|
mediaHeader->start_time = (((8 * data->position) / data->bitsperframe) * 1000000LL) / data->fps;
|
||||||
mediaHeader->file_pos = fDataStart + data->position;
|
mediaHeader->file_pos = fDataStart + data->position;
|
||||||
|
|
||||||
int64 maxreadsize = data->datasize - data->position;
|
int64 maxreadsize = data->datasize - data->position;
|
||||||
int32 readsize = data->buffersize;
|
int32 readsize = data->buffersize;
|
||||||
if (maxreadsize < readsize) {
|
if (maxreadsize < readsize)
|
||||||
readsize = maxreadsize;
|
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)) {
|
if (readsize != Source()->ReadAt(fDataStart + data->position, data->buffer, readsize)) {
|
||||||
TRACE("WavReader::GetNextChunk: unexpected read error\n");
|
TRACE("WavReader::GetNextChunk: unexpected read error\n");
|
||||||
@@ -371,7 +370,7 @@ WavReader::GetNextChunk(void *cookie,
|
|||||||
data->position += readsize;
|
data->position += readsize;
|
||||||
*chunkBuffer = data->buffer;
|
*chunkBuffer = data->buffer;
|
||||||
*chunkSize = readsize;
|
*chunkSize = readsize;
|
||||||
return result;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <Autolock.h>
|
||||||
|
|
||||||
MediaExtractor::MediaExtractor(BDataIO * source, int32 flags)
|
MediaExtractor::MediaExtractor(BDataIO * source, int32 flags)
|
||||||
{
|
{
|
||||||
@@ -148,6 +149,11 @@ MediaExtractor::GetNextChunk(int32 stream,
|
|||||||
//CALLED();
|
//CALLED();
|
||||||
// get buffered chunk
|
// 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
|
// XXX this should be done in a different thread, and double buffered for each stream
|
||||||
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer, chunkSize, mediaHeader);
|
return fReader->GetNextChunk(fStreamInfo[stream].cookie, chunkBuffer, chunkSize, mediaHeader);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user