fixes for start_time returned from vorbis/speex, makes nplay work better in seeking. I note that this also made MediaPlayer stop reporting a bunch of dropped frames at every seek.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6627 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3f71285861
commit
eaa176da6c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<ogg_packet*>(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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user