зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1508434 - p1: Support explicitly resetting seek threshold. r=jya
Usually the threshold is reset internally in MediaDataDecoder subclasses that support the hint in their Flush() implementations so the value will start fresh after seeking completed. But sometimes when there are consecutive seek requests, MediaFormatReader::DecoderData::Flush() could return early because DecoderData::mFlushed stays true when there is no sample demuxed yet, and the threshold will not be cleared. Also, in MediaFormatReader::SetVideoDecodeThreshold() we decide not to set the hint when the seek target is close to EOS by checking the existence of the next keyframe, and that could fail when there are gaps between MSE buffered ranges. To make sure the hint is never out of date, we should clear it rather than leaving it untouched. Differential Revision: https://phabricator.services.mozilla.com/D15227 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6b77f9e5ee
Коммит
2a6faa6bf8
|
@ -2890,10 +2890,9 @@ void MediaFormatReader::SetVideoDecodeThreshold() {
|
|||
|
||||
// If the key frame is invalid/infinite, it means the target position is
|
||||
// closing to end of stream. We don't want to skip any frame at this point.
|
||||
if (!keyframe.IsValid() || keyframe.IsInfinite()) {
|
||||
return;
|
||||
}
|
||||
threshold = mOriginalSeekTarget.GetTime();
|
||||
threshold = keyframe.IsValid() && !keyframe.IsInfinite()
|
||||
? mOriginalSeekTarget.GetTime()
|
||||
: TimeUnit::Invalid();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ parent:
|
|||
async Flush();
|
||||
async Drain();
|
||||
async Shutdown();
|
||||
|
||||
// To clear the threshold, call with INT64_MIN.
|
||||
async SetSeekThreshold(int64_t time);
|
||||
|
||||
async __delete__();
|
||||
|
|
|
@ -37,7 +37,7 @@ parent:
|
|||
async Flush();
|
||||
async Drain();
|
||||
async Shutdown();
|
||||
|
||||
// To clear the threshold, call with INT64_MIN.
|
||||
async SetSeekThreshold(int64_t time);
|
||||
|
||||
async __delete__();
|
||||
|
|
|
@ -289,7 +289,7 @@ nsCString RemoteVideoDecoderChild::GetDescriptionName() const {
|
|||
void RemoteVideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime) {
|
||||
AssertOnManagerThread();
|
||||
if (mCanSend) {
|
||||
SendSetSeekThreshold(aTime.ToMicroseconds());
|
||||
SendSetSeekThreshold(aTime.IsValid() ? aTime.ToMicroseconds() : INT64_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -204,7 +204,9 @@ mozilla::ipc::IPCResult RemoteVideoDecoderParent::RecvSetSeekThreshold(
|
|||
const int64_t& aTime) {
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
MOZ_ASSERT(OnManagerThread());
|
||||
mDecoder->SetSeekThreshold(TimeUnit::FromMicroseconds(aTime));
|
||||
mDecoder->SetSeekThreshold(aTime == INT64_MIN
|
||||
? TimeUnit::Invalid()
|
||||
: TimeUnit::FromMicroseconds(aTime));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ nsCString VideoDecoderChild::GetDescriptionName() const {
|
|||
void VideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime) {
|
||||
AssertOnManagerThread();
|
||||
if (mCanSend) {
|
||||
SendSetSeekThreshold(aTime.ToMicroseconds());
|
||||
SendSetSeekThreshold(aTime.IsValid() ? aTime.ToMicroseconds() : INT64_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,9 @@ mozilla::ipc::IPCResult VideoDecoderParent::RecvSetSeekThreshold(
|
|||
const int64_t& aTime) {
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
MOZ_ASSERT(OnManagerThread());
|
||||
mDecoder->SetSeekThreshold(TimeUnit::FromMicroseconds(aTime));
|
||||
mDecoder->SetSeekThreshold(aTime == INT64_MIN
|
||||
? TimeUnit::Invalid()
|
||||
: TimeUnit::FromMicroseconds(aTime));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -319,7 +319,8 @@ class MediaDataDecoder : public DecoderDoctorLifeLogger<MediaDataDecoder> {
|
|||
|
||||
// Set a hint of seek target time to decoder. Decoder will drop any decoded
|
||||
// data which pts is smaller than this value. This threshold needs to be clear
|
||||
// after reset decoder.
|
||||
// after reset decoder. To clear it explicitly, call this method with
|
||||
// TimeUnit::Invalid().
|
||||
// Decoder may not honor this value. However, it'd be better that
|
||||
// video decoder implements this API to improve seek performance.
|
||||
// Note: it should be called before Input() or after Flush().
|
||||
|
|
|
@ -221,8 +221,13 @@ class RemoteVideoDecoder : public RemoteDataDecoder {
|
|||
void SetSeekThreshold(const TimeUnit& aTime) override {
|
||||
RefPtr<RemoteVideoDecoder> self = this;
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
|
||||
"RemoteVideoDecoder::SetSeekThreshold",
|
||||
[self, aTime]() { self->mSeekTarget = Some(aTime); });
|
||||
"RemoteVideoDecoder::SetSeekThreshold", [self, aTime]() {
|
||||
if (aTime.IsValid()) {
|
||||
self->mSeekTarget = Some(aTime);
|
||||
} else {
|
||||
self->mSeekTarget.reset();
|
||||
}
|
||||
});
|
||||
nsresult rv = mTaskQueue->Dispatch(runnable.forget());
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
||||
Unused << rv;
|
||||
|
|
|
@ -246,7 +246,11 @@ AppleVTDecoder::AppleFrameRef* AppleVTDecoder::CreateAppleFrameRef(
|
|||
|
||||
void AppleVTDecoder::SetSeekThreshold(const media::TimeUnit& aTime) {
|
||||
LOG("SetSeekThreshold %lld", aTime.ToMicroseconds());
|
||||
mSeekTargetThreshold = Some(aTime);
|
||||
if (aTime.IsValid()) {
|
||||
mSeekTargetThreshold = Some(aTime);
|
||||
} else {
|
||||
mSeekTargetThreshold.reset();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -58,7 +58,11 @@ class MFTManager {
|
|||
virtual nsCString GetDescriptionName() const = 0;
|
||||
|
||||
virtual void SetSeekThreshold(const media::TimeUnit& aTime) {
|
||||
mSeekTargetThreshold = Some(aTime);
|
||||
if (aTime.IsValid()) {
|
||||
mSeekTargetThreshold = Some(aTime);
|
||||
} else {
|
||||
mSeekTargetThreshold.reset();
|
||||
}
|
||||
}
|
||||
|
||||
virtual MediaDataDecoder::ConversionRequired NeedsConversion() const {
|
||||
|
|
Загрузка…
Ссылка в новой задаче