fixed timing information returned in media_header

added GetFileFormatInfo to reader api


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5595 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-12-06 20:32:40 +00:00
parent 1b1b7ddf8f
commit abf9e66abe
9 changed files with 112 additions and 24 deletions
+2
View File
@@ -21,6 +21,8 @@ public:
virtual status_t Sniff(int32 *streamCount) = 0;
virtual void GetFileFormatInfo(media_file_format *mff) = 0;
virtual status_t AllocateCookie(int32 streamNumber, void **cookie) = 0;
virtual status_t FreeCookie(void *cookie) = 0;
@@ -44,6 +44,7 @@ mp3Decoder::Setup(media_format *ioEncodedFormat, media_format *ioDecodedFormat,
ioDecodedFormat->u.raw_audio.buffer_size = OUTPUT_BUFFER_SIZE;
ioDecodedFormat->u.raw_audio.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
fFrameSize = 4;
fFps = 44100;
return B_OK;
}
@@ -67,6 +68,9 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
uint8 * out_buffer = static_cast<uint8 *>(buffer);
int32 out_bytes_needed = OUTPUT_BUFFER_SIZE;
mediaHeader->start_time = fStartTime;
//TRACE("mp3Decoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
while (out_bytes_needed > 0) {
if (fResidualBytes) {
int32 bytes = min_c(fResidualBytes, out_bytes_needed);
@@ -75,32 +79,51 @@ mp3Decoder::Decode(void *buffer, int64 *frameCount,
fResidualBytes -= bytes;
out_buffer += bytes;
out_bytes_needed -= bytes;
fStartTime += (1000000LL * (bytes / fFrameSize)) / fFps;
//TRACE("mp3Decoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0);
continue;
}
void *chunkBuffer;
int32 chunkSize;
if (B_OK != GetNextChunk(&chunkBuffer, &chunkSize, mediaHeader)) {
TRACE("mp3Decoder::Decode: GetNextChunk failed\n");
return B_ERROR;
}
int outsize;
int result;
result = decodeMP3(&fMpgLibPrivate, (char *)chunkBuffer, chunkSize, (char *)fDecodeBuffer, DECODE_BUFFER_SIZE, &outsize);
if (result == MP3_ERR) {
TRACE("mp3Decoder::Decode: decodeMP3 returned MP3_ERR\n");
return B_ERROR;
}
//printf("mp3Decoder::Decode: decoded %d bytes into %d bytes\n",chunkSize, outsize);
fResidualBuffer = fDecodeBuffer;
fResidualBytes = outsize;
if (B_OK != DecodeNextChunk())
break;
}
*frameCount = OUTPUT_BUFFER_SIZE / fFrameSize;
*frameCount = (OUTPUT_BUFFER_SIZE - 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 == OUTPUT_BUFFER_SIZE) ? B_ERROR : B_LAST_BUFFER_ERROR;
}
status_t
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;
}
fStartTime = mh.start_time;
//TRACE("mp3Decoder: fStartTime reset to %.6f\n", fStartTime / 1000000.0);
int outsize;
int result;
result = decodeMP3(&fMpgLibPrivate, (char *)chunkBuffer, chunkSize, (char *)fDecodeBuffer, DECODE_BUFFER_SIZE, &outsize);
if (result == MP3_ERR) {
TRACE("mp3Decoder::Decode: decodeMP3 returned MP3_ERR\n");
return B_ERROR;
}
//printf("mp3Decoder::Decode: decoded %d bytes into %d bytes\n",chunkSize, outsize);
fResidualBuffer = fDecodeBuffer;
fResidualBytes = outsize;
return B_OK;
}
@@ -18,12 +18,17 @@ public:
status_t Decode(void *buffer, int64 *frameCount,
media_header *mediaHeader, media_decode_info *info);
status_t DecodeNextChunk();
private:
struct mpstr fMpgLibPrivate;
int32 fResidualBytes;
uint8 * fResidualBuffer;
uint8 * fDecodeBuffer;
int32 fFrameSize;
int32 fFrameSize;
int32 fFps;
bigtime_t fStartTime;
};
@@ -69,6 +69,15 @@ static const int frame_rate_table[4][4] =
{ 44100, 48000, 32000, 0} // mpeg version 1
};
// name_table[mpeg_version_index][layer_index]
static const char * name_table[4][4] =
{
{ 0, "MPEG 2.5 Audio Layer 3", "MPEG 2.5 Audio Layer 2", "MPEG 2.5 Audio Layer 1" },
{ 0, 0, 0, 0 },
{ 0, "MPEG 2 Audio Layer 3", "MPEG 2 Audio Layer 2", "MPEG 2 Audio Layer 1" },
{ 0, "MPEG 1 Audio Layer 3", "MPEG 1 Audio Layer 2", "MPEG 1 Audio Layer 1" },
};
// frame_sample_count_table[layer_index]
static const int frame_sample_count_table[4] = { 0, 1152, 1152, 384 };
@@ -106,6 +115,7 @@ struct mp3Reader::fhg_vbr_info
{
};
mp3Reader::mp3Reader()
: fXingVbrInfo(0),
fFhgVbrInfo(0)
@@ -113,11 +123,13 @@ mp3Reader::mp3Reader()
TRACE("mp3Reader::mp3Reader\n");
}
mp3Reader::~mp3Reader()
{
delete fXingVbrInfo;
delete fFhgVbrInfo;
}
const char *
mp3Reader::Copyright()
@@ -125,7 +137,7 @@ mp3Reader::Copyright()
return "mp3 reader, " B_UTF8_COPYRIGHT " by Marcus Overhagen";
}
status_t
mp3Reader::Sniff(int32 *streamCount)
{
@@ -158,6 +170,26 @@ mp3Reader::Sniff(int32 *streamCount)
}
void
mp3Reader::GetFileFormatInfo(media_file_format *mff)
{
mff->capabilities = media_file_format::B_READABLE
| media_file_format::B_KNOWS_ENCODED_AUDIO
| media_file_format::B_IMPERFECTLY_SEEKABLE;
mff->family = B_MPEG_FORMAT_FAMILY;
mff->version = 100;
strcpy(mff->mime_type, "audio/mpeg");
strcpy(mff->file_extension, "mp3");
uint8 header[4];
Source()->ReadAt(fDataStart, header, sizeof(header));
int mpeg_version_index = (header[1] >> 3) & 0x03;
int layer_index = (header[1] >> 1) & 0x03;
strcpy(mff->short_name, name_table[mpeg_version_index][layer_index]);
strcpy(mff->pretty_name, name_table[mpeg_version_index][layer_index]);
}
status_t
mp3Reader::AllocateCookie(int32 streamNumber, void **cookie)
{
@@ -306,6 +338,8 @@ mp3Reader::Seek(void *cookie,
}
data->position = pos + ofs;
data->framePosition = *frame; // this is not exact
TRACE("mp3Reader::Seek: synchronized at position %Ld\n", data->position);
return B_OK;
}
@@ -322,7 +356,7 @@ mp3Reader::GetNextChunk(void *cookie,
if (maxbytes < 4)
return B_ERROR;
mediaHeader->start_time = (data->framePosition * 1000000) / data->frameCount;
mediaHeader->start_time = (data->framePosition * 1000000) / data->frameRate;
mediaHeader->file_pos = data->position;
if (4 != Source()->ReadAt(fDataStart + data->position, data->chunkBuffer, 4)) {
@@ -15,6 +15,8 @@ public:
status_t Sniff(int32 *streamCount);
void GetFileFormatInfo(media_file_format *mff);
status_t AllocateCookie(int32 streamNumber, void **cookie);
status_t FreeCookie(void *cookie);
@@ -98,6 +98,21 @@ WavReader::Sniff(int32 *streamCount)
}
void
WavReader::GetFileFormatInfo(media_file_format *mff)
{
mff->capabilities = media_file_format::B_READABLE
| media_file_format::B_KNOWS_ENCODED_AUDIO
| media_file_format::B_IMPERFECTLY_SEEKABLE;
mff->family = B_WAV_FORMAT_FAMILY;
mff->version = 100;
strcpy(mff->mime_type, "audio/x-wav");
strcpy(mff->file_extension, "wav");
strcpy(mff->short_name, "RIFF WAV audio");
strcpy(mff->pretty_name, "RIFF WAV audio");
}
status_t
WavReader::AllocateCookie(int32 streamNumber, void **cookie)
{
@@ -11,6 +11,8 @@ public:
status_t Sniff(int32 *streamCount);
void GetFileFormatInfo(media_file_format *mff);
status_t AllocateCookie(int32 streamNumber, void **cookie);
status_t FreeCookie(void *cookie);
+1 -1
View File
@@ -96,7 +96,7 @@ const char *
BMediaFile::Copyright(void) const
{
UNIMPLEMENTED();
return "BMediaFile::Copyright";
return "";
}
int32
+5
View File
@@ -40,6 +40,8 @@ _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BData
return B_ERROR;
}
(*reader)->GetFileFormatInfo(mff);
printf("_CreateReader leave\n");
return B_OK;
@@ -71,6 +73,9 @@ _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *for
return B_ERROR;
}
strcpy(mci->short_name, " mci short_name");
strcpy(mci->pretty_name, " mci pretty_name");
printf("_CreateDecoder leave\n");
return B_OK;