diff --git a/src/add-ons/media/plugins/ogg/OggSeekable.cpp b/src/add-ons/media/plugins/ogg/OggSeekable.cpp index 66bde1fbf2..2fda467bb1 100644 --- a/src/add-ons/media/plugins/ogg/OggSeekable.cpp +++ b/src/add-ons/media/plugins/ogg/OggSeekable.cpp @@ -428,6 +428,8 @@ status_t OggSeekable::GetNextChunk(void **chunkBuffer, int32 *chunkSize, media_header *mediaHeader) { + mediaHeader->start_time = fCurrentTime; + mediaHeader->file_pos = fPosition; status_t result = GetPacket(&fChunkPacket); if (result != B_OK) { TRACE("OggSeekable::GetNextChunk failed: GetPacket = %s\n", strerror(result)); @@ -435,6 +437,8 @@ OggSeekable::GetNextChunk(void **chunkBuffer, int32 *chunkSize, } *chunkBuffer = &fChunkPacket; *chunkSize = sizeof(fChunkPacket); + fCurrentFrame++; + fCurrentTime = (bigtime_t)((fCurrentFrame * 1000000LL) / fFrameRate); return B_OK; } diff --git a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp b/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp index 58f5eb878c..5afa0f03db 100644 --- a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp +++ b/src/add-ons/media/plugins/ogg/OggSpeexSeekable.cpp @@ -112,7 +112,7 @@ OggSpeexSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, } else { format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; } - format->u.encoded_audio.output.frame_rate = header->rate; + fFrameRate = format->u.encoded_audio.output.frame_rate = header->rate; format->u.encoded_audio.output.channel_count = header->nb_channels; // allocate buffer, round up to nearest speex output_length size int buffer_size = AudioBufferSize(&format->u.encoded_audio.output); @@ -144,29 +144,16 @@ OggSpeexSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, // TODO: count the frames in the first page.. somehow.. :-/ int64 frames = 0; - // seek back to the start - int64 frame = 0; - bigtime_t time = 0; - result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time); - if (result != B_OK) { - return result; - } - ogg_page page; // read the first page result = ReadPage(&page); if (result != B_OK) { return result; } - int64 first_granulepos = ogg_page_granulepos(&page); - if (first_granulepos < 0) { - // negative start granulepos indicates that we discard that many frames - frames -= first_granulepos; - first_granulepos = 0; - } - + int64 fFirstGranulepos = ogg_page_granulepos(&page); + TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos); // read our last page - off_t last = Seek(GetLastPagePosition(), SEEK_SET); + off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET); if (last < 0) { return last; } @@ -177,15 +164,18 @@ OggSpeexSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, int64 last_granulepos = ogg_page_granulepos(&page); // seek back to the start + int64 frame = 0; + bigtime_t time = 0; result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time); if (result != B_OK) { return result; } // compute frame count and duration from sample count - frames += last_granulepos - first_granulepos; + frames = last_granulepos - fFirstGranulepos; + *frameCount = frames; - *duration = (1000000LL * frames) / (long long)format->u.encoded_audio.output.frame_rate; + *duration = (1000000LL * frames) / (long long)fFrameRate; return B_OK; } diff --git a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h b/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h index 08054a11be..a1a6065a1c 100644 --- a/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h +++ b/src/add-ons/media/plugins/ogg/OggSpeexSeekable.h @@ -6,6 +6,8 @@ namespace BPrivate { namespace media { class OggSpeexSeekable : public OggSeekable { +private: + typedef OggSeekable inherited; public: static bool IsValidHeader(const ogg_packet & packet); public: diff --git a/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp b/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp index 50623473e2..0c1d494cf4 100644 --- a/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp +++ b/src/add-ons/media/plugins/speex/speexCodecPlugin.cpp @@ -266,6 +266,7 @@ SpeexDecoder::Decode(void *buffer, int64 *frameCount, TRACE("SpeexDecoder::Decode: GetNextChunk failed\n"); return status; } + fStartTime = mh.start_time; speex_bits_read_from(&fBits, (char*)chunkBuffer, chunkSize); for (int frame = 0 ; frame < fHeader->frames_per_packet ; frame++) { int ret = speex_decode(fDecoderState, &fBits, out_buffer); @@ -293,7 +294,7 @@ SpeexDecoder::Decode(void *buffer, int64 *frameCount, done: uint samples = ((uint8*)out_buffer - (uint8*)buffer) / fFrameSize; - fStartTime += (1000000LL * samples) / fHeader->rate; + //fStartTime += (1000000LL * samples) / fHeader->rate; //TRACE("SpeexDecoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0); *frameCount = (fOutputBufferSize - out_bytes_needed) / fFrameSize; diff --git a/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.cpp b/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.cpp index bc7669ef78..2d34aff557 100644 --- a/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.cpp +++ b/src/add-ons/media/plugins/vorbis/vorbisCodecPlugin.cpp @@ -194,6 +194,7 @@ VorbisDecoder::Decode(void *buffer, int64 *frameCount, TRACE("VorbisDecoder::Decode: chunk not ogg_packet-sized\n"); return B_ERROR; } + fStartTime = mh.start_time; ogg_packet * packet = static_cast(chunkBuffer); if (vorbis_synthesis(&fBlock,packet)==0) { vorbis_synthesis_blockin(&fDspState,&fBlock); @@ -226,7 +227,7 @@ VorbisDecoder::Decode(void *buffer, int64 *frameCount, // report back how many samples we consumed vorbis_synthesis_read(&fDspState,samples); - fStartTime += (1000000LL * samples) / fInfo.rate; + //fStartTime += (1000000LL * samples) / fInfo.rate; //TRACE("VorbisDecoder: fStartTime inc'd to %.6f\n", fStartTime / 1000000.0); }