diff --git a/src/add-ons/media/plugins/ape_reader/APEReader.cpp b/src/add-ons/media/plugins/ape_reader/APEReader.cpp index 33d179d880..78ad2b57b1 100644 --- a/src/add-ons/media/plugins/ape_reader/APEReader.cpp +++ b/src/add-ons/media/plugins/ape_reader/APEReader.cpp @@ -81,20 +81,22 @@ TAPEReader::GetNextChunk(void* oCookie, const void** oChunkBuffer, int64 aOutSize; // check whether song is finished or not - if ( mReadPosTotal-mReadPos+mPlayPos >= mDataSize ) + if (mReadPosTotal - mReadPos + mPlayPos >= mDataSize) return B_ERROR; + // reading data - if ( mPlayPos >= mReadPos ) { + if (mPlayPos >= mReadPos ) ReadBlocks(); - } + // passing data - if ( mReadPos-mPlayPos >= BUFFER_SIZE ) { + if (mReadPos-mPlayPos >= BUFFER_SIZE) aOutSize = BUFFER_SIZE; - } else { + else aOutSize = mReadPos-mPlayPos; - } + *oChunkBuffer = &mDecodedData[mPlayPos]; mPlayPos += aOutSize; + // passing info *oChunkSize = aOutSize; oMediaHeader->start_time = CurrentTime(); @@ -108,8 +110,9 @@ TAPEReader::GetStreamInfo(void* oCookie, int64* oFrameCount, bigtime_t* oDuration, media_format* oFormat, const void** oInfoBuffer, size_t* oInfoSize) { - if ( LoadAPECheck() != B_OK ) + if (LoadAPECheck() != B_OK) return LoadAPECheck(); + *oFrameCount = mDataSize / (mDecomp->GetInfo(APE_INFO_BITS_PER_SAMPLE) / 8 * mDecomp->GetInfo(APE_INFO_CHANNELS)); *oDuration = mDecomp->GetInfo(APE_INFO_LENGTH_MS) @@ -118,11 +121,11 @@ TAPEReader::GetStreamInfo(void* oCookie, int64* oFrameCount, oFormat->type = B_MEDIA_RAW_AUDIO; oFormat->u.raw_audio.frame_rate = mDecomp->GetInfo(APE_INFO_SAMPLE_RATE); oFormat->u.raw_audio.channel_count = mDecomp->GetInfo(APE_INFO_CHANNELS); - if ( mDecomp->GetInfo(APE_INFO_BITS_PER_SAMPLE) == 16 ) { + if ( mDecomp->GetInfo(APE_INFO_BITS_PER_SAMPLE) == 16 ) oFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT; - } else { + else oFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_UCHAR; - } + oFormat->u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN; oFormat->u.raw_audio.buffer_size = BUFFER_SIZE; oInfoBuffer = NULL; @@ -141,12 +144,12 @@ TAPEReader::LoadAPECheck() const status_t TAPEReader::ReadBlocks() { - int aBlocksRead; - int aRetVal = 0; + int aBlocksRead; + int aRetVal = 0; aRetVal = mDecomp->GetData(reinterpret_cast(mDecodedData), BLOCK_COUNT, &aBlocksRead); - if ( aRetVal != ERROR_SUCCESS ) + if (aRetVal != ERROR_SUCCESS) return B_ERROR; mPlayPos = 0; @@ -160,12 +163,12 @@ status_t TAPEReader::FindKeyFrame(void* cookie, uint32 flags, int64* frame, bigtime_t* time) { - if ( flags & B_MEDIA_SEEK_TO_FRAME ) { + if (flags & B_MEDIA_SEEK_TO_FRAME) { *time = *frame * 1000 / mDecomp->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) * mDecomp->GetInfo(APE_DECOMPRESS_LENGTH_MS); printf("FindKeyFrame for frame %Ld: %Ld\n", *frame, *time); - } else if ( flags & B_MEDIA_SEEK_TO_TIME ) { - *frame = (*time)/1000*mDecomp->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) + } else if (flags & B_MEDIA_SEEK_TO_TIME) { + *frame = (*time) / 1000 * mDecomp->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) / mDecomp->GetInfo(APE_DECOMPRESS_LENGTH_MS); printf("FindKeyFrame for time %Ld: %Ld\n", *time, *frame); } else @@ -178,21 +181,28 @@ TAPEReader::FindKeyFrame(void* cookie, uint32 flags, int64* frame, status_t TAPEReader::Seek(void *cookie, uint32 flags, int64 *frame, bigtime_t *time) { - int32 aNewBlock; + int32 aNewBlock; - if ( flags & B_MEDIA_SEEK_TO_FRAME ) { + if (flags & B_MEDIA_SEEK_TO_FRAME) { printf("Seek to frame %Ld\n", *frame); aNewBlock = *frame; - } else if ( flags & B_MEDIA_SEEK_TO_TIME ) { + } else if (flags & B_MEDIA_SEEK_TO_TIME) { printf("Seek for time %Ld\n", *time); - aNewBlock = (*time)/1000*mDecomp->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) + aNewBlock = (*time) / 1000 * mDecomp->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS) / mDecomp->GetInfo(APE_DECOMPRESS_LENGTH_MS); } else return B_ERROR; - mReadPosTotal = aNewBlock*mDecomp->GetInfo(APE_INFO_BLOCK_ALIGN); - mDecomp->Seek(aNewBlock); - ReadBlocks(); + int64 aNewTime = aNewBlock * mDecomp->GetInfo(APE_INFO_BLOCK_ALIGN); + if (mReadPosTotal - mReadPos < aNewTime && mReadPosTotal > aNewTime) { + // Requested seek frame is already in the current buffer, no need to + // actually seek, just set the play position + mPlayPos = aNewTime - mReadPosTotal + mReadPos; + } else { + mReadPosTotal = aNewBlock * mDecomp->GetInfo(APE_INFO_BLOCK_ALIGN); + mDecomp->Seek(aNewBlock); + ReadBlocks(); + } return B_OK; } @@ -203,12 +213,14 @@ TAPEReader::Sniff(int32* oStreamCount) Unset(); // prepare about file mSrcPIO = dynamic_cast(Source()); - if ( mSrcPIO == NULL ) + if (mSrcPIO == NULL) return B_ERROR; + mPositionBridgeIO.SetPositionIO(mSrcPIO); mDecomp = CreateIAPEDecompressEx(&mPositionBridgeIO); - if ( mDecomp == NULL ) + if (mDecomp == NULL) return B_ERROR; + // prepare about data mDataSize = static_cast(mDecomp->GetInfo(APE_DECOMPRESS_TOTAL_BLOCKS)) *mDecomp->GetInfo(APE_INFO_BLOCK_ALIGN); diff --git a/src/add-ons/media/plugins/ape_reader/APEReader.h b/src/add-ons/media/plugins/ape_reader/APEReader.h index 5400523841..8ca5333cbc 100644 --- a/src/add-ons/media/plugins/ape_reader/APEReader.h +++ b/src/add-ons/media/plugins/ape_reader/APEReader.h @@ -1,23 +1,24 @@ #ifndef ___APEReader_H_ #define ___APEReader_H_ -//------------------------------------------------------------------------------ -// BeOS -// MAC + + #include "MACLib.h" #include "MonkeysAudioMIMEType.h" #include "PositionBridgeIO.h" -// Proj + #include "ReaderPlugin.h" // Haiku private header -//------------------------------------------------------------------------------ -const int32 BLOCK_COUNT = 1024*4; // number of blocks, get from MACLib at once -const int32 BUFFER_SIZE = 1024*4; // size of audio data passing to Media Kit + + +const int32 BLOCK_COUNT = 1024*4; // number of blocks, get from MACLib at once +const int32 BUFFER_SIZE = 1024*4; // size of audio data passing to Media Kit const int32 MEDIA_FILE_FORMAT_VERSION = 100; // media_file_format::version -//============================================================================== + + class TAPEReader : public Reader { public: TAPEReader(); - virtual ~TAPEReader(); + virtual ~TAPEReader(); virtual const char* Copyright(); @@ -28,16 +29,18 @@ public: virtual status_t AllocateCookie(int32 oStreamNumber, void** oCookie); virtual status_t FreeCookie(void* oCookie); - virtual status_t GetStreamInfo(void* oCookie, int64* oFrameCount, bigtime_t* oDuration, media_format* oFormat, - const void** oInfoBuffer, size_t* oInfoSize); + virtual status_t GetStreamInfo(void* oCookie, int64* oFrameCount, + bigtime_t* oDuration, media_format* oFormat, + const void** oInfoBuffer, size_t* oInfoSize); virtual status_t Seek(void *cookie, uint32 flags, - int64 *frame, bigtime_t *time); + int64 *frame, bigtime_t *time); virtual status_t FindKeyFrame(void* cookie, uint32 flags, int64* frame, bigtime_t* time); - virtual status_t GetNextChunk(void* oCookie, const void** oChunkBuffer, size_t* oChunkSize, media_header* oMediaHeader); + virtual status_t GetNextChunk(void* oCookie, const void** oChunkBuffer, + size_t* oChunkSize, media_header* oMediaHeader); private: typedef Reader SUPER; @@ -57,7 +60,8 @@ private: IAPEDecompress* mDecomp; TPositionBridgeIO mPositionBridgeIO; }; -//============================================================================== + + class TAPEReaderPlugin : public ReaderPlugin { public: @@ -66,7 +70,9 @@ public: virtual Reader* NewReader(); }; -//============================================================================== + + MediaPlugin* instantiate_plugin(); -//============================================================================== + + #endif // ___APEReader_H_