Bug 1276272 - part 3 - implement promise-based HTMLMediaElement::seekToNextFrame(); r=jwwang
MozReview-Commit-ID: JaUQe5GK6bF
This commit is contained in:
@@ -1466,19 +1466,19 @@ HTMLMediaElement::FastSeek(double aTime, ErrorResult& aRv)
|
||||
{
|
||||
LOG(LogLevel::Debug, ("Reporting telemetry VIDEO_FASTSEEK_USED"));
|
||||
Telemetry::Accumulate(Telemetry::VIDEO_FASTSEEK_USED, 1);
|
||||
Seek(aTime, SeekTarget::PrevSyncPoint, aRv);
|
||||
RefPtr<Promise> tobeDropped = Seek(aTime, SeekTarget::PrevSyncPoint, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
HTMLMediaElement::SeekToNextFrame(ErrorResult& aRv)
|
||||
{
|
||||
Seek(CurrentTime(), SeekTarget::NextFrame, aRv);
|
||||
return Seek(CurrentTime(), SeekTarget::NextFrame, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLMediaElement::SetCurrentTime(double aCurrentTime, ErrorResult& aRv)
|
||||
{
|
||||
Seek(aCurrentTime, SeekTarget::Accurate, aRv);
|
||||
RefPtr<Promise> tobeDropped = Seek(aCurrentTime, SeekTarget::Accurate, aRv);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1519,7 +1519,7 @@ IsInRanges(dom::TimeRanges& aRanges,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
HTMLMediaElement::Seek(double aTime,
|
||||
SeekTarget::Type aSeekType,
|
||||
ErrorResult& aRv)
|
||||
@@ -1527,6 +1527,19 @@ HTMLMediaElement::Seek(double aTime,
|
||||
// aTime should be non-NaN.
|
||||
MOZ_ASSERT(!mozilla::IsNaN(aTime));
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(OwnerDoc()->GetInnerWindow());
|
||||
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Detect if user has interacted with element by seeking so that
|
||||
// play will not be blocked when initiated by a script.
|
||||
if (EventStateManager::IsHandlingUserInput() || nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
||||
@@ -1537,7 +1550,8 @@ HTMLMediaElement::Seek(double aTime,
|
||||
|
||||
if (mSrcStream) {
|
||||
// do nothing since media streams have an empty Seekable range.
|
||||
return;
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (mPlayed && mCurrentPlayRangeStart != -1.0) {
|
||||
@@ -1554,27 +1568,30 @@ HTMLMediaElement::Seek(double aTime,
|
||||
|
||||
if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
|
||||
mDefaultPlaybackStartPosition = aTime;
|
||||
return;
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (!mDecoder) {
|
||||
// mDecoder must always be set in order to reach this point.
|
||||
NS_ASSERTION(mDecoder, "SetCurrentTime failed: no decoder");
|
||||
return;
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// Clamp the seek target to inside the seekable ranges.
|
||||
RefPtr<dom::TimeRanges> seekable = new dom::TimeRanges(ToSupports(OwnerDoc()));
|
||||
media::TimeIntervals seekableIntervals = mDecoder->GetSeekable();
|
||||
if (seekableIntervals.IsInvalid()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); // This will reject the promise.
|
||||
return promise.forget();
|
||||
}
|
||||
seekableIntervals.ToTimeRanges(seekable);
|
||||
uint32_t length = 0;
|
||||
seekable->GetLength(&length);
|
||||
if (!length) {
|
||||
return;
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// If the position we want to seek to is not in a seekable range, we seek
|
||||
@@ -1585,8 +1602,8 @@ HTMLMediaElement::Seek(double aTime,
|
||||
int32_t range = 0;
|
||||
bool isInRange = false;
|
||||
if (NS_FAILED(IsInRanges(*seekable, aTime, isInRange, range))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); // This will reject the promise.
|
||||
return promise.forget();
|
||||
}
|
||||
if (!isInRange) {
|
||||
if (range != -1) {
|
||||
@@ -1596,11 +1613,11 @@ HTMLMediaElement::Seek(double aTime,
|
||||
double leftBound, rightBound;
|
||||
if (NS_FAILED(seekable->End(range, &leftBound))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
return promise.forget();
|
||||
}
|
||||
if (NS_FAILED(seekable->Start(range + 1, &rightBound))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
return promise.forget();
|
||||
}
|
||||
double distanceLeft = Abs(leftBound - aTime);
|
||||
double distanceRight = Abs(rightBound - aTime);
|
||||
@@ -1615,7 +1632,7 @@ HTMLMediaElement::Seek(double aTime,
|
||||
// Clamp the seek target to the end of the last seekable range.
|
||||
if (NS_FAILED(seekable->End(length - 1, &aTime))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
return promise.forget();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1641,13 +1658,15 @@ HTMLMediaElement::Seek(double aTime,
|
||||
// The media backend is responsible for dispatching the timeupdate
|
||||
// event if it changes the playback position as a result of the seek.
|
||||
LOG(LogLevel::Debug, ("%p SetCurrentTime(%f) starting seek", this, aTime));
|
||||
nsresult rv = mDecoder->Seek(aTime, aSeekType);
|
||||
nsresult rv = mDecoder->Seek(aTime, aSeekType, promise);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
}
|
||||
|
||||
// We changed whether we're seeking so we need to AddRemoveSelfReference.
|
||||
AddRemoveSelfReference();
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP HTMLMediaElement::SetCurrentTime(double aCurrentTime)
|
||||
|
||||
Reference in New Issue
Block a user