Bug 1002320 - Switch video readers at the earliest possible point rather than the latest. r=cajbir

This commit is contained in:
Matthew Gregan 2014-04-27 22:11:00 +12:00
parent 01c16a7afc
commit 68673b84c7
3 changed files with 34 additions and 29 deletions

View File

@ -88,6 +88,11 @@ public:
MOZ_ASSERT(mPendingDecoders.IsEmpty());
return false;
}
if (MaybeSwitchVideoReaders(aTimeThreshold)) {
GetVideoReader()->DecodeToTarget(aTimeThreshold);
}
bool rv = GetVideoReader()->DecodeVideoFrame(aKeyFrameSkip, aTimeThreshold);
nsAutoTArray<VideoData*, 10> video;
@ -103,16 +108,6 @@ public:
MSE_DEBUG("%p MSR::DecodeVF %d (%p) returned false (readers=%u)",
this, mActiveVideoDecoder, mDecoders[mActiveVideoDecoder].get(), mDecoders.Length());
if (SwitchVideoReaders(aTimeThreshold)) {
rv = GetVideoReader()->DecodeVideoFrame(aKeyFrameSkip, aTimeThreshold);
nsAutoTArray<VideoData*, 10> video;
GetVideoReader()->VideoQueue().GetElementsAfter(-1, &video);
for (uint32_t i = 0; i < video.Length(); ++i) {
VideoQueue().Push(video[i]);
}
GetVideoReader()->VideoQueue().Empty();
}
return rv;
}
@ -136,14 +131,9 @@ public:
void CallDecoderInitialization();
private:
bool SwitchVideoReaders(int64_t aTimeThreshold) {
MOZ_ASSERT(mActiveVideoDecoder != -1);
// XXX: We switch when the first reader is depleted, but it might be
// better to switch as soon as the next reader is ready to decode and
// has data for the current media time.
bool MaybeSwitchVideoReaders(int64_t aTimeThreshold) {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
GetVideoReader()->SetIdle();
MOZ_ASSERT(mActiveVideoDecoder != -1);
WaitForPendingDecoders();
@ -151,14 +141,17 @@ private:
if (!mDecoders[i]->GetReader()->GetMediaInfo().HasVideo()) {
continue;
}
mActiveVideoDecoder = i;
MSE_DEBUG("%p MSR::DecodeVF switching to %d", this, mActiveVideoDecoder);
if (aTimeThreshold >= mDecoders[i]->GetMediaStartTime()) {
GetVideoReader()->SetIdle();
GetVideoReader()->SetActive();
GetVideoReader()->DecodeToTarget(aTimeThreshold);
mActiveVideoDecoder = i;
MSE_DEBUG("%p MSR::DecodeVF switching to %d", this, mActiveVideoDecoder);
return true;
GetVideoReader()->SetActive();
return true;
}
}
return false;
}
@ -337,9 +330,13 @@ MediaSourceReader::CallDecoderInitialization()
MediaInfo mi;
nsAutoPtr<MetadataTags> tags; // TODO: Handle metadata.
nsresult rv;
int64_t startTime = 0;
{
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
rv = reader->ReadMetadata(&mi, getter_Transfers(tags));
if (NS_SUCCEEDED(rv)) {
reader->FindStartTime(startTime);
}
}
reader->SetIdle();
if (NS_FAILED(rv)) {
@ -347,10 +344,12 @@ MediaSourceReader::CallDecoderInitialization()
MSE_DEBUG("%p: Reader %p failed to initialize, rv=%x", this, reader, rv);
continue;
}
decoder->SetMediaStartTime(startTime);
bool active = false;
if (mi.HasVideo() || mi.HasAudio()) {
MSE_DEBUG("%p: Reader %p has video=%d audio=%d", this, reader, mi.HasVideo(), mi.HasAudio());
MSE_DEBUG("%p: Reader %p has video=%d audio=%d startTime=%lld",
this, reader, mi.HasVideo(), mi.HasAudio(), startTime);
active = true;
}

View File

@ -196,16 +196,10 @@ SourceBuffer::GetBuffered(ErrorResult& aRv)
nsRefPtr<TimeRanges> r = new TimeRanges();
mDecoders[i]->GetBuffered(r);
if (r->Length() > 0) {
MSE_DEBUG("%p GetBuffered decoder=%u Length=%u Start=%f End=%f", this, i, r->Length(),
r->GetStartTime(), r->GetEndTime());
ranges->Add(r->GetStartTime(), r->GetEndTime());
} else {
MSE_DEBUG("%p GetBuffered decoder=%u Length=%u", this, i, r->Length());
}
}
ranges->Normalize();
MSE_DEBUG("%p GetBuffered Length=%u Start=%f End=%f", this, ranges->Length(),
ranges->GetStartTime(), ranges->GetEndTime());
return ranges.forget();
}

View File

@ -21,6 +21,7 @@ public:
// of the caller to manage the memory of the MediaResource object.
SubBufferDecoder(MediaResource* aResource, MediaSourceDecoder* aParentDecoder)
: BufferDecoder(aResource), mParentDecoder(aParentDecoder), mReader(nullptr)
, mMediaDuration(-1), mMediaStartTime(0)
{
}
@ -72,10 +73,21 @@ public:
return mMediaDuration;
}
int64_t GetMediaStartTime()
{
return mMediaStartTime;
}
void SetMediaStartTime(int64_t aMediaStartTime)
{
mMediaStartTime = aMediaStartTime;
}
private:
MediaSourceDecoder* mParentDecoder;
nsAutoPtr<MediaDecoderReader> mReader;
int64_t mMediaDuration;
int64_t mMediaStartTime;
};
} // namespace mozilla