зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1126465 - Use a MediaPromiseConsumerHolder to track subdecoder seeks. r=mattwoodrow
This commit is contained in:
Родитель
c6856d1350
Коммит
6359f5e202
|
@ -50,8 +50,6 @@ MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder)
|
|||
, mLastVideoTime(0)
|
||||
, mPendingSeekTime(-1)
|
||||
, mWaitingForSeekData(false)
|
||||
, mAudioIsSeeking(false)
|
||||
, mVideoIsSeeking(false)
|
||||
, mTimeThreshold(0)
|
||||
, mDropAudioBeforeThreshold(false)
|
||||
, mDropVideoBeforeThreshold(false)
|
||||
|
@ -124,13 +122,15 @@ MediaSourceReader::RequestAudioData()
|
|||
mAudioPromise.Reject(CANCELED, __func__);
|
||||
return p;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(!mSeekRequest.Exists());
|
||||
|
||||
SwitchReaderResult ret = SwitchAudioReader(mLastAudioTime);
|
||||
switch (ret) {
|
||||
case READER_NEW:
|
||||
mAudioReader->Seek(mLastAudioTime, 0)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::RequestAudioDataComplete,
|
||||
&MediaSourceReader::RequestAudioDataFailed);
|
||||
mSeekRequest.Begin(mAudioReader->Seek(mLastAudioTime, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::CompleteSeekAndDoAudioRequest,
|
||||
&MediaSourceReader::CompleteSeekAndRejectAudioPromise));
|
||||
break;
|
||||
case READER_ERROR:
|
||||
if (mLastAudioTime) {
|
||||
|
@ -145,17 +145,6 @@ MediaSourceReader::RequestAudioData()
|
|||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::RequestAudioDataComplete(int64_t aTime)
|
||||
{
|
||||
if (IsSeeking()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestAudioDataComplete called mid-seek. Rejecting.", this);
|
||||
MOZ_RELEASE_ASSERT(mAudioPromise.IsEmpty()); // Already rejected in ::Seek().
|
||||
return;
|
||||
}
|
||||
DoAudioRequest();
|
||||
}
|
||||
|
||||
void MediaSourceReader::DoAudioRequest()
|
||||
{
|
||||
mAudioRequest.Begin(mAudioReader->RequestAudioData()
|
||||
|
@ -164,12 +153,6 @@ void MediaSourceReader::DoAudioRequest()
|
|||
&MediaSourceReader::OnAudioNotDecoded));
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::RequestAudioDataFailed(nsresult aResult)
|
||||
{
|
||||
mAudioPromise.Reject(DECODE_ERROR, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnAudioDecoded(AudioData* aSample)
|
||||
{
|
||||
|
@ -245,10 +228,10 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
|
|||
// EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug
|
||||
// 1065207.
|
||||
if (SwitchAudioReader(mLastAudioTime, EOS_FUZZ_US) == READER_NEW) {
|
||||
mAudioReader->Seek(mLastAudioTime, 0)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::RequestAudioDataComplete,
|
||||
&MediaSourceReader::RequestAudioDataFailed);
|
||||
mSeekRequest.Begin(mAudioReader->Seek(mLastAudioTime, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::CompleteSeekAndDoAudioRequest,
|
||||
&MediaSourceReader::CompleteSeekAndRejectAudioPromise));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -277,13 +260,15 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
|||
mVideoPromise.Reject(CANCELED, __func__);
|
||||
return p;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(!mSeekRequest.Exists());
|
||||
|
||||
SwitchReaderResult ret = SwitchVideoReader(mLastVideoTime);
|
||||
switch (ret) {
|
||||
case READER_NEW:
|
||||
mVideoReader->Seek(mLastVideoTime, 0)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::RequestVideoDataComplete,
|
||||
&MediaSourceReader::RequestVideoDataFailed);
|
||||
mSeekRequest.Begin(mVideoReader->Seek(mLastVideoTime, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::CompleteSeekAndDoVideoRequest,
|
||||
&MediaSourceReader::CompleteSeekAndRejectVideoPromise));
|
||||
break;
|
||||
case READER_ERROR:
|
||||
if (mLastVideoTime) {
|
||||
|
@ -299,17 +284,6 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
|||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::RequestVideoDataComplete(int64_t aTime)
|
||||
{
|
||||
if (IsSeeking()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestVideoDataComplete called mid-seek. Rejecting.", this);
|
||||
MOZ_ASSERT(mVideoPromise.IsEmpty()); // Already rejected in ::Seek().
|
||||
return;
|
||||
}
|
||||
DoVideoRequest();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::DoVideoRequest()
|
||||
{
|
||||
|
@ -319,12 +293,6 @@ MediaSourceReader::DoVideoRequest()
|
|||
&MediaSourceReader::OnVideoNotDecoded));
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::RequestVideoDataFailed(nsresult aResult)
|
||||
{
|
||||
mVideoPromise.Reject(DECODE_ERROR, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnVideoDecoded(VideoData* aSample)
|
||||
{
|
||||
|
@ -372,10 +340,10 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
|||
// EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug
|
||||
// 1065207.
|
||||
if (SwitchVideoReader(mLastVideoTime, EOS_FUZZ_US) == READER_NEW) {
|
||||
mVideoReader->Seek(mLastVideoTime, 0)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::RequestVideoDataComplete,
|
||||
&MediaSourceReader::RequestVideoDataFailed);
|
||||
mSeekRequest.Begin(mVideoReader->Seek(mLastVideoTime, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::CompleteSeekAndDoVideoRequest,
|
||||
&MediaSourceReader::CompleteSeekAndRejectVideoPromise));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -702,6 +670,10 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aIgnored /* Used only for ogg whi
|
|||
mAudioPromise.RejectIfExists(CANCELED, __func__);
|
||||
mVideoPromise.RejectIfExists(CANCELED, __func__);
|
||||
|
||||
// Finally, if we were midway seeking a new reader to find a sample, abandon
|
||||
// that too.
|
||||
mSeekRequest.DisconnectIfExists();
|
||||
|
||||
// Store pending seek target in case the track buffers don't contain
|
||||
// the desired time and we delay doing the seek.
|
||||
mPendingSeekTime = aTime;
|
||||
|
@ -720,27 +692,22 @@ MediaSourceReader::CancelSeek()
|
|||
{
|
||||
MOZ_ASSERT(OnDecodeThread());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
if (mWaitingForSeekData) {
|
||||
mSeekPromise.Reject(NS_OK, __func__);
|
||||
mWaitingForSeekData = false;
|
||||
mPendingSeekTime = -1;
|
||||
} else if (mVideoIsSeeking) {
|
||||
// NB: Currently all readers have sync Seeks(), so this is a no-op.
|
||||
mVideoReader->CancelSeek();
|
||||
} else if (mAudioIsSeeking) {
|
||||
// NB: Currently all readers have sync Seeks(), so this is a no-op.
|
||||
mWaitingForSeekData = false;
|
||||
mPendingSeekTime = -1;
|
||||
mSeekRequest.DisconnectIfExists();
|
||||
if (mAudioReader) {
|
||||
mAudioReader->CancelSeek();
|
||||
} else {
|
||||
MOZ_ASSERT(mSeekPromise.IsEmpty());
|
||||
}
|
||||
if (mVideoReader) {
|
||||
mVideoReader->CancelSeek();
|
||||
}
|
||||
mSeekPromise.RejectIfExists(NS_OK, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnVideoSeekCompleted(int64_t aTime)
|
||||
{
|
||||
MOZ_ASSERT(mVideoIsSeeking);
|
||||
MOZ_ASSERT(!mAudioIsSeeking);
|
||||
mVideoIsSeeking = false;
|
||||
mSeekRequest.Complete();
|
||||
|
||||
if (mAudioTrack) {
|
||||
mPendingSeekTime = aTime;
|
||||
|
@ -754,23 +721,18 @@ MediaSourceReader::OnVideoSeekCompleted(int64_t aTime)
|
|||
void
|
||||
MediaSourceReader::DoAudioSeek()
|
||||
{
|
||||
mAudioIsSeeking = true;
|
||||
SwitchAudioReader(mPendingSeekTime);
|
||||
mAudioReader->Seek(mPendingSeekTime, 0)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnAudioSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed);
|
||||
mSeekRequest.Begin(mAudioReader->Seek(mPendingSeekTime, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnAudioSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed));
|
||||
MSE_DEBUG("MediaSourceReader(%p)::DoAudioSeek reader=%p", this, mAudioReader.get());
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnAudioSeekCompleted(int64_t aTime)
|
||||
{
|
||||
mPendingSeekTime = aTime;
|
||||
MOZ_ASSERT(mAudioIsSeeking);
|
||||
MOZ_ASSERT(!mVideoIsSeeking);
|
||||
mAudioIsSeeking = false;
|
||||
|
||||
mSeekRequest.Complete();
|
||||
mPendingSeekTime = -1;
|
||||
mSeekPromise.Resolve(aTime, __func__);
|
||||
}
|
||||
|
@ -778,18 +740,7 @@ MediaSourceReader::OnAudioSeekCompleted(int64_t aTime)
|
|||
void
|
||||
MediaSourceReader::OnSeekFailed(nsresult aResult)
|
||||
{
|
||||
MOZ_ASSERT(mVideoIsSeeking || mAudioIsSeeking);
|
||||
|
||||
if (mVideoIsSeeking) {
|
||||
MOZ_ASSERT(!mAudioIsSeeking);
|
||||
mVideoIsSeeking = false;
|
||||
}
|
||||
|
||||
if (mAudioIsSeeking) {
|
||||
MOZ_ASSERT(!mVideoIsSeeking);
|
||||
mAudioIsSeeking = false;
|
||||
}
|
||||
|
||||
mSeekRequest.Complete();
|
||||
mPendingSeekTime = -1;
|
||||
mSeekPromise.Reject(aResult, __func__);
|
||||
}
|
||||
|
@ -828,12 +779,11 @@ MediaSourceReader::AttemptSeek()
|
|||
void
|
||||
MediaSourceReader::DoVideoSeek()
|
||||
{
|
||||
mVideoIsSeeking = true;
|
||||
SwitchVideoReader(mPendingSeekTime);
|
||||
mVideoReader->Seek(mPendingSeekTime, 0)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnVideoSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed);
|
||||
mSeekRequest.Begin(mVideoReader->Seek(mPendingSeekTime, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnVideoSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed));
|
||||
MSE_DEBUG("MediaSourceReader(%p)::DoVideoSeek reader=%p", this, mVideoReader.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -163,10 +163,30 @@ private:
|
|||
void DoAudioRequest();
|
||||
void DoVideoRequest();
|
||||
|
||||
void RequestAudioDataComplete(int64_t aTime);
|
||||
void RequestAudioDataFailed(nsresult aResult);
|
||||
void RequestVideoDataComplete(int64_t aTime);
|
||||
void RequestVideoDataFailed(nsresult aResult);
|
||||
void CompleteSeekAndDoAudioRequest()
|
||||
{
|
||||
mSeekRequest.Complete();
|
||||
DoAudioRequest();
|
||||
}
|
||||
|
||||
void CompleteSeekAndDoVideoRequest()
|
||||
{
|
||||
mSeekRequest.Complete();
|
||||
DoVideoRequest();
|
||||
}
|
||||
|
||||
void CompleteSeekAndRejectAudioPromise()
|
||||
{
|
||||
mSeekRequest.Complete();
|
||||
mAudioPromise.Reject(DECODE_ERROR, __func__);
|
||||
}
|
||||
|
||||
void CompleteSeekAndRejectVideoPromise()
|
||||
{
|
||||
mSeekRequest.Complete();
|
||||
mVideoPromise.Reject(DECODE_ERROR, __func__);
|
||||
}
|
||||
|
||||
// Will reject the MediaPromise with END_OF_STREAM if mediasource has ended
|
||||
// or with WAIT_FOR_DATA otherwise.
|
||||
void CheckForWaitOrEndOfStream(MediaData::Type aType, int64_t aTime /* microseconds */);
|
||||
|
@ -211,13 +231,13 @@ private:
|
|||
int64_t mLastAudioTime;
|
||||
int64_t mLastVideoTime;
|
||||
|
||||
MediaPromiseConsumerHolder<SeekPromise> mSeekRequest;
|
||||
MediaPromiseHolder<SeekPromise> mSeekPromise;
|
||||
|
||||
// Temporary seek information while we wait for the data
|
||||
// to be added to the track buffer.
|
||||
MediaPromiseHolder<SeekPromise> mSeekPromise;
|
||||
int64_t mPendingSeekTime;
|
||||
bool mWaitingForSeekData;
|
||||
bool mAudioIsSeeking;
|
||||
bool mVideoIsSeeking;
|
||||
|
||||
int64_t mTimeThreshold;
|
||||
bool mDropAudioBeforeThreshold;
|
||||
|
|
Загрузка…
Ссылка в новой задаче