зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1125469: Part1. Don't attempt to seek on time found with fuzz search. r=mattwoodrow
Instead seek to the actual time available.
This commit is contained in:
Родитель
72355abc0d
Коммит
173a0c1120
|
@ -125,7 +125,7 @@ MediaSourceReader::RequestAudioData()
|
||||||
}
|
}
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!mAudioSeekRequest.Exists());
|
MOZ_DIAGNOSTIC_ASSERT(!mAudioSeekRequest.Exists());
|
||||||
|
|
||||||
SwitchSourceResult ret = SwitchAudioSource(mLastAudioTime);
|
SwitchSourceResult ret = SwitchAudioSource(&mLastAudioTime);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case SOURCE_NEW:
|
case SOURCE_NEW:
|
||||||
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
|
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
|
||||||
|
@ -233,7 +233,7 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can find a different source that can pick up where we left off.
|
// See if we can find a different source that can pick up where we left off.
|
||||||
if (SwitchAudioSource(mLastAudioTime) == SOURCE_NEW) {
|
if (SwitchAudioSource(&mLastAudioTime) == SOURCE_NEW) {
|
||||||
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
|
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mLastAudioTime), 0)
|
||||||
->RefableThen(GetTaskQueue(), __func__, this,
|
->RefableThen(GetTaskQueue(), __func__, this,
|
||||||
&MediaSourceReader::CompleteAudioSeekAndDoRequest,
|
&MediaSourceReader::CompleteAudioSeekAndDoRequest,
|
||||||
|
@ -267,7 +267,7 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
||||||
}
|
}
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!mVideoSeekRequest.Exists());
|
MOZ_DIAGNOSTIC_ASSERT(!mVideoSeekRequest.Exists());
|
||||||
|
|
||||||
SwitchSourceResult ret = SwitchVideoSource(mLastVideoTime);
|
SwitchSourceResult ret = SwitchVideoSource(&mLastVideoTime);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case SOURCE_NEW:
|
case SOURCE_NEW:
|
||||||
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
|
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
|
||||||
|
@ -351,7 +351,7 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can find a different reader that can pick up where we left off.
|
// See if we can find a different reader that can pick up where we left off.
|
||||||
if (SwitchVideoSource(mLastVideoTime) == SOURCE_NEW) {
|
if (SwitchVideoSource(&mLastVideoTime) == SOURCE_NEW) {
|
||||||
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
|
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mLastVideoTime), 0)
|
||||||
->RefableThen(GetTaskQueue(), __func__, this,
|
->RefableThen(GetTaskQueue(), __func__, this,
|
||||||
&MediaSourceReader::CompleteVideoSeekAndDoRequest,
|
&MediaSourceReader::CompleteVideoSeekAndDoRequest,
|
||||||
|
@ -485,7 +485,7 @@ MediaSourceReader::HaveData(int64_t aTarget, MediaData::Type aType)
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSourceReader::SwitchSourceResult
|
MediaSourceReader::SwitchSourceResult
|
||||||
MediaSourceReader::SwitchAudioSource(int64_t aTarget)
|
MediaSourceReader::SwitchAudioSource(int64_t* aTarget)
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
// XXX: Can't handle adding an audio track after ReadMetadata.
|
// XXX: Can't handle adding an audio track after ReadMetadata.
|
||||||
|
@ -496,23 +496,36 @@ MediaSourceReader::SwitchAudioSource(int64_t aTarget)
|
||||||
// We first search without the tolerance and then search with it, so that, in
|
// We first search without the tolerance and then search with it, so that, in
|
||||||
// the case of perfectly-aligned data, we don't prematurely jump to a new
|
// the case of perfectly-aligned data, we don't prematurely jump to a new
|
||||||
// reader and skip the last few samples of the current one.
|
// reader and skip the last few samples of the current one.
|
||||||
|
bool usedFuzz = false;
|
||||||
nsRefPtr<SourceBufferDecoder> newDecoder =
|
nsRefPtr<SourceBufferDecoder> newDecoder =
|
||||||
SelectDecoder(aTarget, /* aTolerance = */ 0, mAudioTrack->Decoders());
|
SelectDecoder(*aTarget, /* aTolerance = */ 0, mAudioTrack->Decoders());
|
||||||
if (!newDecoder) {
|
if (!newDecoder) {
|
||||||
newDecoder = SelectDecoder(aTarget, EOS_FUZZ_US, mAudioTrack->Decoders());
|
newDecoder = SelectDecoder(*aTarget, EOS_FUZZ_US, mAudioTrack->Decoders());
|
||||||
|
usedFuzz = true;
|
||||||
}
|
}
|
||||||
if (newDecoder && newDecoder != mAudioSourceDecoder) {
|
if (newDecoder && newDecoder != mAudioSourceDecoder) {
|
||||||
GetAudioReader()->SetIdle();
|
GetAudioReader()->SetIdle();
|
||||||
mAudioSourceDecoder = newDecoder;
|
mAudioSourceDecoder = newDecoder;
|
||||||
MSE_DEBUGV("MediaSourceReader(%p)::SwitchAudioSource switched decoder to %p",
|
if (usedFuzz) {
|
||||||
this, mAudioSourceDecoder.get());
|
// A decoder buffered range is continuous. We would have failed the exact
|
||||||
|
// search but succeeded the fuzzy one if our target was shortly before
|
||||||
|
// start time.
|
||||||
|
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
|
||||||
|
newDecoder->GetBuffered(ranges);
|
||||||
|
int64_t startTime = ranges->GetStartTime() * USECS_PER_S;
|
||||||
|
if (*aTarget < startTime) {
|
||||||
|
*aTarget = startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MSE_DEBUGV("MediaSourceReader(%p)::SwitchAudioSource switched decoder to %p (fuzz:%d)",
|
||||||
|
this, mAudioSourceDecoder.get(), usedFuzz);
|
||||||
return SOURCE_NEW;
|
return SOURCE_NEW;
|
||||||
}
|
}
|
||||||
return newDecoder ? SOURCE_EXISTING : SOURCE_ERROR;
|
return newDecoder ? SOURCE_EXISTING : SOURCE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSourceReader::SwitchSourceResult
|
MediaSourceReader::SwitchSourceResult
|
||||||
MediaSourceReader::SwitchVideoSource(int64_t aTarget)
|
MediaSourceReader::SwitchVideoSource(int64_t* aTarget)
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
// XXX: Can't handle adding a video track after ReadMetadata.
|
// XXX: Can't handle adding a video track after ReadMetadata.
|
||||||
|
@ -523,16 +536,29 @@ MediaSourceReader::SwitchVideoSource(int64_t aTarget)
|
||||||
// We first search without the tolerance and then search with it, so that, in
|
// We first search without the tolerance and then search with it, so that, in
|
||||||
// the case of perfectly-aligned data, we don't prematurely jump to a new
|
// the case of perfectly-aligned data, we don't prematurely jump to a new
|
||||||
// reader and skip the last few samples of the current one.
|
// reader and skip the last few samples of the current one.
|
||||||
|
bool usedFuzz = false;
|
||||||
nsRefPtr<SourceBufferDecoder> newDecoder =
|
nsRefPtr<SourceBufferDecoder> newDecoder =
|
||||||
SelectDecoder(aTarget, /* aTolerance = */ 0, mVideoTrack->Decoders());
|
SelectDecoder(*aTarget, /* aTolerance = */ 0, mVideoTrack->Decoders());
|
||||||
if (!newDecoder) {
|
if (!newDecoder) {
|
||||||
newDecoder = SelectDecoder(aTarget, EOS_FUZZ_US, mVideoTrack->Decoders());
|
newDecoder = SelectDecoder(*aTarget, EOS_FUZZ_US, mVideoTrack->Decoders());
|
||||||
|
usedFuzz = true;
|
||||||
}
|
}
|
||||||
if (newDecoder && newDecoder != mVideoSourceDecoder) {
|
if (newDecoder && newDecoder != mVideoSourceDecoder) {
|
||||||
GetVideoReader()->SetIdle();
|
GetVideoReader()->SetIdle();
|
||||||
mVideoSourceDecoder = newDecoder;
|
mVideoSourceDecoder = newDecoder;
|
||||||
MSE_DEBUGV("MediaSourceReader(%p)::SwitchVideoSource switched decoder to %p",
|
if (usedFuzz) {
|
||||||
this, mVideoSourceDecoder.get());
|
// A decoder buffered range is continuous. We would have failed the exact
|
||||||
|
// search but succeeded the fuzzy one if our target was shortly before
|
||||||
|
// start time.
|
||||||
|
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
|
||||||
|
newDecoder->GetBuffered(ranges);
|
||||||
|
int64_t startTime = ranges->GetStartTime() * USECS_PER_S;
|
||||||
|
if (*aTarget < startTime) {
|
||||||
|
*aTarget = startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MSE_DEBUGV("MediaSourceReader(%p)::SwitchVideoSource switched decoder to %p (fuzz:%d)",
|
||||||
|
this, mVideoSourceDecoder.get(), usedFuzz);
|
||||||
return SOURCE_NEW;
|
return SOURCE_NEW;
|
||||||
}
|
}
|
||||||
return newDecoder ? SOURCE_EXISTING : SOURCE_ERROR;
|
return newDecoder ? SOURCE_EXISTING : SOURCE_ERROR;
|
||||||
|
@ -775,7 +801,7 @@ MediaSourceReader::OnVideoSeekFailed(nsresult aResult)
|
||||||
void
|
void
|
||||||
MediaSourceReader::DoAudioSeek()
|
MediaSourceReader::DoAudioSeek()
|
||||||
{
|
{
|
||||||
SwitchAudioSource(mPendingSeekTime);
|
SwitchAudioSource(&mPendingSeekTime);
|
||||||
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mPendingSeekTime), 0)
|
mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mPendingSeekTime), 0)
|
||||||
->RefableThen(GetTaskQueue(), __func__, this,
|
->RefableThen(GetTaskQueue(), __func__, this,
|
||||||
&MediaSourceReader::OnAudioSeekCompleted,
|
&MediaSourceReader::OnAudioSeekCompleted,
|
||||||
|
@ -835,7 +861,7 @@ MediaSourceReader::AttemptSeek()
|
||||||
void
|
void
|
||||||
MediaSourceReader::DoVideoSeek()
|
MediaSourceReader::DoVideoSeek()
|
||||||
{
|
{
|
||||||
SwitchVideoSource(mPendingSeekTime);
|
SwitchVideoSource(&mPendingSeekTime);
|
||||||
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mPendingSeekTime), 0)
|
mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mPendingSeekTime), 0)
|
||||||
->RefableThen(GetTaskQueue(), __func__, this,
|
->RefableThen(GetTaskQueue(), __func__, this,
|
||||||
&MediaSourceReader::OnVideoSeekCompleted,
|
&MediaSourceReader::OnVideoSeekCompleted,
|
||||||
|
|
|
@ -157,14 +157,16 @@ private:
|
||||||
// Switch the current audio/video source to the source that
|
// Switch the current audio/video source to the source that
|
||||||
// contains aTarget (or up to aTolerance after target). Both
|
// contains aTarget (or up to aTolerance after target). Both
|
||||||
// aTarget and aTolerance are in microseconds.
|
// aTarget and aTolerance are in microseconds.
|
||||||
|
// Search can be made using a fuzz factor. Should an approximated value be
|
||||||
|
// found instead, aTarget will be updated to the actual target found.
|
||||||
enum SwitchSourceResult {
|
enum SwitchSourceResult {
|
||||||
SOURCE_ERROR = -1,
|
SOURCE_ERROR = -1,
|
||||||
SOURCE_EXISTING = 0,
|
SOURCE_EXISTING = 0,
|
||||||
SOURCE_NEW = 1,
|
SOURCE_NEW = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
SwitchSourceResult SwitchAudioSource(int64_t aTarget);
|
SwitchSourceResult SwitchAudioSource(int64_t* aTarget);
|
||||||
SwitchSourceResult SwitchVideoSource(int64_t aTarget);
|
SwitchSourceResult SwitchVideoSource(int64_t* aTarget);
|
||||||
|
|
||||||
void DoAudioRequest();
|
void DoAudioRequest();
|
||||||
void DoVideoRequest();
|
void DoVideoRequest();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче