From fa4c6d578f9f0bb1ee939482c46bcb6bfcb5d3ec Mon Sep 17 00:00:00 2001 From: David McPaul Date: Fri, 10 Oct 2008 08:33:57 +0000 Subject: [PATCH] Handle duration for mp3 in wav container better, add FindKeyFrame function git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27948 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../plugins/wav_reader/WavReaderPlugin.cpp | 63 +++++++++++++++++-- .../plugins/wav_reader/WavReaderPlugin.h | 15 +++-- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp index 859beb26b3..cdd7e69cf0 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp @@ -207,9 +207,10 @@ WavReader::Sniff(int32 *streamCount) fFrameRate = UINT32(format.samples_per_sec); fBitsPerSample = UINT16(format.bits_per_sample); if (fBitsPerSample == 0) { - printf("WavReader::Sniff: Error, bits_per_sample = 0\n"); + printf("WavReader::Sniff: Error, bits_per_sample = 0 assuming 8\n"); fBitsPerSample = 8; } + fAvgBytesPerSec = format.avg_bytes_per_sec; fFrameCount = foundFact ? UINT32(fact.sample_length) : 0; fFormatCode = UINT16(format.format_tag); if (fFormatCode == 0xfffe && foundFmtExt) @@ -266,7 +267,16 @@ WavReader::AllocateCookie(int32 streamNumber, void **cookie) data->buffersize = (BUFFER_SIZE / fBlockAlign) * fBlockAlign; data->buffer = malloc(data->buffersize); data->framecount = fFrameCount ? fFrameCount : (8 * fDataSize) / data->bitsperframe; - data->duration = (data->framecount * 1000000LL) / data->fps; + if (fFormatCode == 0x0055) { + // mp3 in wav file + if (fAvgBytesPerSec) { + data->duration = (data->datasize * 1000000LL) / fAvgBytesPerSec; + } else { + data->duration = (data->framecount * 1000000LL) / data->fps / fBitsPerSample * fChannelCount; + } + } else { + data->duration = (data->framecount * 1000000LL) / data->fps; + } data->raw = fFormatCode == 0x0001; TRACE(" bitsperframe %ld\n", data->bitsperframe); @@ -351,20 +361,21 @@ WavReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration, status_t WavReader::Seek(void *cookie, - uint32 seekTo, + uint32 flags, int64 *frame, bigtime_t *time) { + // Seek to the given position wavdata *data = reinterpret_cast(cookie); uint64 pos; - if (seekTo & B_MEDIA_SEEK_TO_FRAME) { + if (flags & B_MEDIA_SEEK_TO_FRAME) { if (data->raw) pos = (*frame * data->bitsperframe) / 8; else pos = (*frame * fDataSize) / data->framecount; pos = (pos / fBlockAlign) * fBlockAlign; // round down to a block start TRACE("WavReader::Seek to frame %Ld, pos %Ld\n", *frame, pos); - } else if (seekTo & B_MEDIA_SEEK_TO_TIME) { + } else if (flags & B_MEDIA_SEEK_TO_TIME) { if (data->raw) pos = (*time * data->fps * data->bitsperframe) / (1000000LL * 8); else @@ -393,6 +404,48 @@ WavReader::Seek(void *cookie, return B_OK; } +status_t +WavReader::FindKeyFrame(void* cookie, uint32 flags, + int64* frame, bigtime_t* time) +{ + // Find a seek position without actually seeking + wavdata *data = reinterpret_cast(cookie); + uint64 pos; + + if (flags & B_MEDIA_SEEK_TO_FRAME) { + if (data->raw) + pos = (*frame * data->bitsperframe) / 8; + else + pos = (*frame * fDataSize) / data->framecount; + pos = (pos / fBlockAlign) * fBlockAlign; // round down to a block start + TRACE("WavReader::Seek to frame %Ld, pos %Ld\n", *frame, pos); + } else if (flags & B_MEDIA_SEEK_TO_TIME) { + if (data->raw) + pos = (*time * data->fps * data->bitsperframe) / (1000000LL * 8); + else + pos = (*time * fDataSize) / data->duration; + pos = (pos / fBlockAlign) * fBlockAlign; // round down to a block start + TRACE("WavReader::Seek to time %Ld, pos %Ld\n", *time, pos); + } else { + return B_ERROR; + } + + if (data->raw) + *frame = (8 * pos) / data->bitsperframe; + else + *frame = (pos * data->framecount) / fDataSize; + *time = (*frame * 1000000LL) / data->fps; + + TRACE("WavReader::Seek newtime %Ld\n", *time); + TRACE("WavReader::Seek newframe %Ld\n", *frame); + + if (pos < 0 || pos > data->datasize) { + TRACE("WavReader::Seek invalid position %Ld\n", pos); + return B_ERROR; + } + + return B_OK; +} status_t WavReader::GetNextChunk(void *cookie, diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h index 648a2d0a3a..077b3736e3 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h @@ -44,15 +44,17 @@ public: status_t FreeCookie(void *cookie); status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration, - media_format *format, const void **infoBuffer, size_t *infoSize); + media_format *format, const void **infoBuffer, size_t *infoSize); - status_t Seek(void *cookie, - uint32 seekTo, - int64 *frame, bigtime_t *time); + status_t Seek(void *cookie, uint32 flags, + int64 *frame, bigtime_t *time); + + status_t FindKeyFrame(void* cookie, uint32 flags, + int64* frame, bigtime_t* time); status_t GetNextChunk(void *cookie, - const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); + const void **chunkBuffer, size_t *chunkSize, + media_header *mediaHeader); BPositionIO *Source() { return fSource; } @@ -68,6 +70,7 @@ private: int fBitsPerSample; uint16 fFormatCode; uint16 fBlockAlign; + uint16 fAvgBytesPerSec; };