From fa635d6dce160aaca2561d8fddc519aeb87360bf Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 22 Dec 2003 21:26:51 +0000 Subject: [PATCH] Implemented support for encoded data (like mp3) inside the WAV container. The start_time information on seek and especially during reading isn't very exact. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5729 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../plugins/wav_reader/WavReaderPlugin.cpp | 48 +++++++++++++++---- .../plugins/wav_reader/WavReaderPlugin.h | 1 + 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp index 2a27e602f8..63b5710787 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.cpp @@ -33,6 +33,8 @@ struct wavdata int64 framecount; bigtime_t duration; + bool raw; + media_format format; }; @@ -179,16 +181,21 @@ WavReader::Sniff(int32 *streamCount) printf("WavReader::Sniff: Error, bits_per_sample = 0\n"); fBitsPerSample = 8; } - fBlockAlign = UINT16(format.block_align); - int min_align = (fBitsPerSample * fChannelCount + 7) / 8; - if (fBlockAlign < min_align) - fBlockAlign = min_align; + fFrameCount = foundFact ? UINT32(fact.sample_length) : 0; fFormatCode = UINT16(format.format_tag); if (fFormatCode == 0xfffe && foundFmtExt) fFormatCode = (format_ext.guid[1] << 8) | format_ext.guid[0]; + fBlockAlign = UINT16(format.block_align); + int min_align = (fFormatCode == 0x0001) ? (fBitsPerSample * fChannelCount + 7) / 8 : 1; + if (fBlockAlign < min_align) + fBlockAlign = min_align; + + TRACE(" fDataStart %Ld\n", fDataStart); + TRACE(" fDataSize %Ld\n", fDataSize); TRACE(" fChannelCount %ld\n", fChannelCount); TRACE(" fFrameRate %ld\n", fFrameRate); + TRACE(" fFrameCount %Ld\n", fFrameCount); TRACE(" fBitsPerSample %d\n", fBitsPerSample); TRACE(" fBlockAlign %d\n", fBlockAlign); TRACE(" min_align %d\n", min_align); @@ -229,14 +236,16 @@ WavReader::AllocateCookie(int32 streamNumber, void **cookie) data->fps = fFrameRate; data->buffersize = (BUFFER_SIZE / fBlockAlign) * fBlockAlign; data->buffer = malloc(data->buffersize); - data->framecount = (8 * fDataSize) / data->bitsperframe; + data->framecount = fFrameCount ? fFrameCount : (8 * fDataSize) / data->bitsperframe; data->duration = (data->framecount * 1000000LL) / data->fps; + data->raw = fFormatCode == 0x0001; TRACE(" bitsperframe %ld\n", data->bitsperframe); TRACE(" fps %ld\n", data->fps); TRACE(" buffersize %ld\n", data->buffersize); TRACE(" framecount %Ld\n", data->framecount); TRACE(" duration %Ld\n", data->duration); + TRACE(" raw %d\n", data->raw); BMediaFormats formats; if (fFormatCode == 0x0001) { @@ -319,18 +328,27 @@ WavReader::Seek(void *cookie, uint64 pos; if (seekTo & B_MEDIA_SEEK_TO_FRAME) { - pos = (*frame * data->bitsperframe) / 8; + 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) { - pos = (*time * data->fps * data->bitsperframe) / (1000000LL * 8); + 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; } - *frame = (8 * pos) / data->bitsperframe; + 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); @@ -353,9 +371,21 @@ WavReader::GetNextChunk(void *cookie, { wavdata *data = reinterpret_cast(cookie); - mediaHeader->start_time = (((8 * data->position) / data->bitsperframe) * 1000000LL) / data->fps; + // XXX it might be much better to not return any start_time information for encoded formats here, + // XXX and instead use the last time returned from seek and count forward after decoding. + if (data->raw) + mediaHeader->start_time = (((8 * data->position) / data->bitsperframe) * 1000000LL) / data->fps; + else + mediaHeader->start_time = (data->position * data->duration) / fDataSize; mediaHeader->file_pos = fDataStart + data->position; +/* + printf("position = %9Ld\n", data->position); + printf("fDataSize = %9Ld\n", fDataSize); + printf("duration = %9Ld\n", data->duration); + printf("start_time = %9Ld\n", mediaHeader->start_time); +*/ + int64 maxreadsize = data->datasize - data->position; int32 readsize = data->buffersize; if (maxreadsize < readsize) diff --git a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h index 37feb26fe8..4c2d98a6a9 100644 --- a/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h +++ b/src/add-ons/media/plugins/wav_reader/WavReaderPlugin.h @@ -35,6 +35,7 @@ private: int64 fDataStart; int64 fDataSize; + int64 fFrameCount; int32 fChannelCount; int32 fFrameRate; int fBitsPerSample;