mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1151299: Part1. Only attempt to decode first frame when available. r=mattwoodrow
Don't rely on the demuxer to be blocking when attempting to decode the first MSE frame.
This commit is contained in:
parent
7a51dcf194
commit
51a0437eb8
@ -168,12 +168,16 @@ MediaSourceReader::RequestAudioData()
|
|||||||
&MediaSourceReader::CompleteAudioSeekAndRejectPromise));
|
&MediaSourceReader::CompleteAudioSeekAndRejectPromise));
|
||||||
break;
|
break;
|
||||||
case SOURCE_NONE:
|
case SOURCE_NONE:
|
||||||
if (mLastAudioTime) {
|
if (!mLastAudioTime) {
|
||||||
|
// This is the first call to RequestAudioData.
|
||||||
|
// Fallback to using decoder with earliest data.
|
||||||
|
mAudioSourceDecoder = FirstDecoder(MediaData::AUDIO_DATA);
|
||||||
|
}
|
||||||
|
if (mLastAudioTime || !mAudioSourceDecoder) {
|
||||||
CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime);
|
CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Fallback to using first reader
|
// Fallback to getting first frame from first decoder.
|
||||||
mAudioSourceDecoder = mAudioTrack->Decoders()[0];
|
|
||||||
default:
|
default:
|
||||||
DoAudioRequest();
|
DoAudioRequest();
|
||||||
break;
|
break;
|
||||||
@ -338,12 +342,16 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
|||||||
&MediaSourceReader::CompleteVideoSeekAndRejectPromise));
|
&MediaSourceReader::CompleteVideoSeekAndRejectPromise));
|
||||||
break;
|
break;
|
||||||
case SOURCE_NONE:
|
case SOURCE_NONE:
|
||||||
if (mLastVideoTime) {
|
if (!mLastVideoTime) {
|
||||||
|
// This is the first call to RequestVideoData.
|
||||||
|
// Fallback to using decoder with earliest data.
|
||||||
|
mVideoSourceDecoder = FirstDecoder(MediaData::VIDEO_DATA);
|
||||||
|
}
|
||||||
|
if (mLastVideoTime || !mVideoSourceDecoder) {
|
||||||
CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA, mLastVideoTime);
|
CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA, mLastVideoTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Fallback to using first reader.
|
// Fallback to getting first frame from first decoder.
|
||||||
mVideoSourceDecoder = mVideoTrack->Decoders()[0];
|
|
||||||
default:
|
default:
|
||||||
DoVideoRequest();
|
DoVideoRequest();
|
||||||
break;
|
break;
|
||||||
@ -1033,6 +1041,36 @@ MediaSourceReader::GetBuffered(dom::TimeRanges* aBuffered)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<SourceBufferDecoder>
|
||||||
|
MediaSourceReader::FirstDecoder(MediaData::Type aType)
|
||||||
|
{
|
||||||
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
|
TrackBuffer* trackBuffer =
|
||||||
|
aType == MediaData::AUDIO_DATA ? mAudioTrack : mVideoTrack;
|
||||||
|
MOZ_ASSERT(trackBuffer);
|
||||||
|
const nsTArray<nsRefPtr<SourceBufferDecoder>>& decoders = trackBuffer->Decoders();
|
||||||
|
if (decoders.IsEmpty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<SourceBufferDecoder> firstDecoder;
|
||||||
|
double lowestStartTime = PositiveInfinity<double>();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < decoders.Length(); ++i) {
|
||||||
|
nsRefPtr<TimeRanges> r = new TimeRanges();
|
||||||
|
decoders[i]->GetBuffered(r);
|
||||||
|
double start = r->GetStartTime();
|
||||||
|
if (start < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (start < lowestStartTime) {
|
||||||
|
firstDecoder = decoders[i];
|
||||||
|
lowestStartTime = start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstDecoder.forget();
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<MediaDecoderReader::WaitForDataPromise>
|
nsRefPtr<MediaDecoderReader::WaitForDataPromise>
|
||||||
MediaSourceReader::WaitForData(MediaData::Type aType)
|
MediaSourceReader::WaitForData(MediaData::Type aType)
|
||||||
{
|
{
|
||||||
@ -1053,13 +1091,23 @@ MediaSourceReader::MaybeNotifyHaveData()
|
|||||||
// The next Request*Data will handle END_OF_STREAM or going back into waiting
|
// The next Request*Data will handle END_OF_STREAM or going back into waiting
|
||||||
// mode.
|
// mode.
|
||||||
if (!IsSeeking() && mAudioTrack) {
|
if (!IsSeeking() && mAudioTrack) {
|
||||||
haveAudio = HaveData(mLastAudioTime, MediaData::AUDIO_DATA);
|
if (!mLastAudioTime) {
|
||||||
|
nsRefPtr<SourceBufferDecoder> d = FirstDecoder(MediaData::AUDIO_DATA);
|
||||||
|
haveAudio = !!d;
|
||||||
|
} else {
|
||||||
|
haveAudio = HaveData(mLastAudioTime, MediaData::AUDIO_DATA);
|
||||||
|
}
|
||||||
if (ended || haveAudio) {
|
if (ended || haveAudio) {
|
||||||
WaitPromise(MediaData::AUDIO_DATA).ResolveIfExists(MediaData::AUDIO_DATA, __func__);
|
WaitPromise(MediaData::AUDIO_DATA).ResolveIfExists(MediaData::AUDIO_DATA, __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!IsSeeking() && mVideoTrack) {
|
if (!IsSeeking() && mVideoTrack) {
|
||||||
haveVideo = HaveData(mLastVideoTime, MediaData::VIDEO_DATA);
|
if (!mLastVideoTime) {
|
||||||
|
nsRefPtr<SourceBufferDecoder> d = FirstDecoder(MediaData::VIDEO_DATA);
|
||||||
|
haveVideo = !!d;
|
||||||
|
} else {
|
||||||
|
haveVideo = HaveData(mLastVideoTime, MediaData::VIDEO_DATA);
|
||||||
|
}
|
||||||
if (ended || haveVideo) {
|
if (ended || haveVideo) {
|
||||||
WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__);
|
WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__);
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,7 @@ private:
|
|||||||
int64_t aTolerance /* microseconds */,
|
int64_t aTolerance /* microseconds */,
|
||||||
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
|
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
|
||||||
bool HaveData(int64_t aTarget, MediaData::Type aType);
|
bool HaveData(int64_t aTarget, MediaData::Type aType);
|
||||||
|
already_AddRefed<SourceBufferDecoder> FirstDecoder(MediaData::Type aType);
|
||||||
|
|
||||||
void AttemptSeek();
|
void AttemptSeek();
|
||||||
bool IsSeeking() { return mPendingSeekTime != -1; }
|
bool IsSeeking() { return mPendingSeekTime != -1; }
|
||||||
|
Loading…
Reference in New Issue
Block a user