mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1097375 - Implement MediaSource::setDuration. r=kinetik
--HG-- extra : rebase_source : 7e5f5387de5db3deccc6e74222b32f461359beb2
This commit is contained in:
parent
16cff43fd3
commit
b370384d2c
@ -166,7 +166,8 @@ MediaSource::Duration()
|
||||
if (mReadyState == MediaSourceReadyState::Closed) {
|
||||
return UnspecifiedNaN<double>();
|
||||
}
|
||||
return mDuration;
|
||||
MOZ_ASSERT(mDecoder);
|
||||
return mDecoder->GetMediaSourceDuration();
|
||||
}
|
||||
|
||||
void
|
||||
@ -183,7 +184,7 @@ MediaSource::SetDuration(double aDuration, ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
DurationChange(aDuration, aRv);
|
||||
mDecoder->SetMediaSourceDuration(aDuration);
|
||||
}
|
||||
|
||||
already_AddRefed<SourceBuffer>
|
||||
@ -271,7 +272,7 @@ MediaSource::EndOfStream(const Optional<MediaSourceEndOfStreamError>& aError, Er
|
||||
mSourceBuffers->Ended();
|
||||
mDecoder->Ended();
|
||||
if (!aError.WasPassed()) {
|
||||
DurationChange(mSourceBuffers->GetHighestBufferedEndTime(), aRv);
|
||||
mDecoder->SetMediaSourceDuration(mSourceBuffers->GetHighestBufferedEndTime());
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
@ -336,7 +337,6 @@ MediaSource::Detach()
|
||||
mDecoder = nullptr;
|
||||
mFirstSourceBufferInitialized = false;
|
||||
SetReadyState(MediaSourceReadyState::Closed);
|
||||
mDuration = UnspecifiedNaN<double>();
|
||||
if (mActiveSourceBuffers) {
|
||||
mActiveSourceBuffers->Clear();
|
||||
}
|
||||
@ -347,7 +347,6 @@ MediaSource::Detach()
|
||||
|
||||
MediaSource::MediaSource(nsPIDOMWindow* aWindow)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mDuration(UnspecifiedNaN<double>())
|
||||
, mDecoder(nullptr)
|
||||
, mPrincipal(nullptr)
|
||||
, mReadyState(MediaSourceReadyState::Closed)
|
||||
@ -416,23 +415,19 @@ MediaSource::QueueAsyncSimpleEvent(const char* aName)
|
||||
}
|
||||
|
||||
void
|
||||
MediaSource::DurationChange(double aNewDuration, ErrorResult& aRv)
|
||||
MediaSource::DurationChange(double aOldDuration, double aNewDuration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MSE_DEBUG("MediaSource(%p)::DurationChange(aNewDuration=%f)", this, aNewDuration);
|
||||
if (mDuration == aNewDuration) {
|
||||
return;
|
||||
}
|
||||
double oldDuration = mDuration;
|
||||
mDuration = aNewDuration;
|
||||
if (aNewDuration < oldDuration) {
|
||||
mSourceBuffers->Remove(aNewDuration, oldDuration, aRv);
|
||||
if (aRv.Failed()) {
|
||||
|
||||
if (aNewDuration < aOldDuration) {
|
||||
ErrorResult rv;
|
||||
mSourceBuffers->Remove(aNewDuration, aOldDuration, rv);
|
||||
if (rv.Failed()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// TODO: If partial audio frames/text cues exist, clamp duration based on mSourceBuffers.
|
||||
// TODO: Update media element's duration and run element's duration change algorithm.
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -120,12 +120,10 @@ private:
|
||||
void DispatchSimpleEvent(const char* aName);
|
||||
void QueueAsyncSimpleEvent(const char* aName);
|
||||
|
||||
void DurationChange(double aNewDuration, ErrorResult& aRv);
|
||||
void DurationChange(double aOldDuration, double aNewDuration);
|
||||
|
||||
void InitializationEvent();
|
||||
|
||||
double mDuration;
|
||||
|
||||
nsRefPtr<SourceBufferList> mSourceBuffers;
|
||||
nsRefPtr<SourceBufferList> mActiveSourceBuffers;
|
||||
|
||||
|
@ -33,6 +33,7 @@ class SourceBufferDecoder;
|
||||
|
||||
MediaSourceDecoder::MediaSourceDecoder(dom::HTMLMediaElement* aElement)
|
||||
: mMediaSource(nullptr)
|
||||
, mMediaSourceDuration(UnspecifiedNaN<double>())
|
||||
{
|
||||
Init(aElement);
|
||||
}
|
||||
@ -171,15 +172,74 @@ MediaSourceDecoder::IsExpectingMoreData()
|
||||
return !mReader->IsEnded();
|
||||
}
|
||||
|
||||
class DurationChangedRunnable : public nsRunnable {
|
||||
public:
|
||||
explicit DurationChangedRunnable(MediaSourceDecoder* aDecoder,
|
||||
double aOldDuration,
|
||||
double aNewDuration)
|
||||
: mDecoder(aDecoder)
|
||||
, mOldDuration(aOldDuration)
|
||||
, mNewDuration(aNewDuration)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL {
|
||||
mDecoder->DurationChanged(mOldDuration, mNewDuration);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<MediaSourceDecoder> mDecoder;
|
||||
double mOldDuration;
|
||||
double mNewDuration;
|
||||
};
|
||||
|
||||
void
|
||||
MediaSourceDecoder::DurationChanged(double aOldDuration, double aNewDuration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Run the MediaSource duration changed algorithm
|
||||
if (mMediaSource) {
|
||||
mMediaSource->DurationChange(aOldDuration, aNewDuration);
|
||||
}
|
||||
// Run the MediaElement duration changed algorithm
|
||||
MediaDecoder::DurationChanged();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::SetDecodedDuration(int64_t aDuration)
|
||||
{
|
||||
// Only use the decoded duration if one wasn't already
|
||||
// set.
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
if (!mMediaSource || !IsNaN(mMediaSourceDuration)) {
|
||||
return;
|
||||
}
|
||||
double duration = aDuration;
|
||||
duration /= USECS_PER_S;
|
||||
SetMediaSourceDuration(duration);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceDecoder::SetMediaSourceDuration(double aDuration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mMediaSource) {
|
||||
return;
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
double oldDuration = mMediaSourceDuration;
|
||||
mMediaSourceDuration = aDuration;
|
||||
mDecoderStateMachine->SetDuration(aDuration * USECS_PER_S);
|
||||
if (NS_IsMainThread()) {
|
||||
DurationChanged(oldDuration, aDuration);
|
||||
} else {
|
||||
nsRefPtr<nsIRunnable> task =
|
||||
new DurationChangedRunnable(this, oldDuration, aDuration);
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
ErrorResult dummy;
|
||||
mMediaSource->DurationChange(aDuration, dummy);
|
||||
}
|
||||
|
||||
double
|
||||
MediaSourceDecoder::GetMediaSourceDuration()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
return mMediaSourceDuration;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -54,7 +54,10 @@ public:
|
||||
void Ended();
|
||||
bool IsExpectingMoreData() MOZ_OVERRIDE;
|
||||
|
||||
void SetDecodedDuration(int64_t aDuration);
|
||||
void SetMediaSourceDuration(double aDuration);
|
||||
double GetMediaSourceDuration();
|
||||
void DurationChanged(double aOldDuration, double aNewDuration);
|
||||
|
||||
// Called whenever a TrackBuffer has new data appended or a new decoder
|
||||
// initializes. Safe to call from any thread.
|
||||
@ -74,6 +77,9 @@ private:
|
||||
// mMediaSource.
|
||||
dom::MediaSource* mMediaSource;
|
||||
nsRefPtr<MediaSourceReader> mReader;
|
||||
|
||||
// Protected by GetReentrantMonitor()
|
||||
double mMediaSourceDuration;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -630,13 +630,7 @@ MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
|
||||
}
|
||||
|
||||
if (maxDuration != -1) {
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecoder->SetMediaDuration(maxDuration);
|
||||
nsRefPtr<nsIRunnable> task (
|
||||
NS_NewRunnableMethodWithArg<double>(static_cast<MediaSourceDecoder*>(mDecoder),
|
||||
&MediaSourceDecoder::SetMediaSourceDuration,
|
||||
static_cast<double>(maxDuration) / USECS_PER_S));
|
||||
NS_DispatchToMainThread(task);
|
||||
static_cast<MediaSourceDecoder*>(mDecoder)->SetDecodedDuration(maxDuration);
|
||||
}
|
||||
|
||||
*aInfo = mInfo;
|
||||
|
Loading…
Reference in New Issue
Block a user