зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1297036: [MSE] P4. Only report end of stream when reaching the end. r=gerald
MozReview-Commit-ID: 5EWhBVnscXY --HG-- extra : rebase_source : 914aa1b8abb8d4026993281dbd68b1ba2ef04642
This commit is contained in:
Родитель
90f7e263a7
Коммит
8d676d83a6
|
@ -379,6 +379,8 @@ MediaSourceTrackDemuxer::BreakCycles()
|
|||
RefPtr<MediaSourceTrackDemuxer::SeekPromise>
|
||||
MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
|
||||
{
|
||||
typedef TrackBuffersManager::GetSampleResult Result;
|
||||
|
||||
TimeIntervals buffered = mManager->Buffered(mType);
|
||||
// Fuzz factor represents a +/- threshold. So when seeking it allows the gap
|
||||
// to be twice as big as the fuzz value. We only want to allow EOS_FUZZ gap.
|
||||
|
@ -395,9 +397,8 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
|
|||
if (!buffered.Contains(seekTime)) {
|
||||
if (!buffered.Contains(aTime)) {
|
||||
// We don't have the data to seek to.
|
||||
return SeekPromise::CreateAndReject(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
|
||||
__func__);
|
||||
}
|
||||
// Theoretically we should reject the promise with WAITING_FOR_DATA,
|
||||
// however, to avoid unwanted regressions we assume that if at this time
|
||||
|
@ -409,12 +410,12 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
|
|||
seekTime = buffered[index].mStart;
|
||||
}
|
||||
seekTime = mManager->Seek(mType, seekTime, MediaSourceDemuxer::EOS_FUZZ / 2);
|
||||
bool error;
|
||||
Result result;
|
||||
RefPtr<MediaRawData> sample =
|
||||
mManager->GetSample(mType,
|
||||
media::TimeUnit(),
|
||||
error);
|
||||
MOZ_ASSERT(!error && sample);
|
||||
result);
|
||||
MOZ_ASSERT(result != Result::ERROR && sample);
|
||||
mNextSample = Some(sample);
|
||||
mReset = false;
|
||||
{
|
||||
|
@ -428,33 +429,39 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
|
|||
RefPtr<MediaSourceTrackDemuxer::SamplesPromise>
|
||||
MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
|
||||
{
|
||||
typedef TrackBuffersManager::GetSampleResult Result;
|
||||
|
||||
if (mReset) {
|
||||
// If a seek (or reset) was recently performed, we ensure that the data
|
||||
// we are about to retrieve is still available.
|
||||
TimeIntervals buffered = mManager->Buffered(mType);
|
||||
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
|
||||
|
||||
if (!buffered.Length() && mManager->IsEnded()) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM,
|
||||
__func__);
|
||||
}
|
||||
if (!buffered.Contains(TimeUnit::FromMicroseconds(0))) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
|
||||
__func__);
|
||||
}
|
||||
mReset = false;
|
||||
}
|
||||
bool error = false;
|
||||
RefPtr<MediaRawData> sample;
|
||||
if (mNextSample) {
|
||||
sample = mNextSample.ref();
|
||||
mNextSample.reset();
|
||||
} else {
|
||||
sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, error);
|
||||
Result result;
|
||||
sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, result);
|
||||
if (!sample) {
|
||||
if (error) {
|
||||
if (result == Result::ERROR) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
}
|
||||
return SamplesPromise::CreateAndReject(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
(result == Result::EOS && mManager->IsEnded())
|
||||
? DemuxerFailureReason::END_OF_STREAM
|
||||
: DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
}
|
||||
RefPtr<SamplesHolder> samples = new SamplesHolder;
|
||||
|
|
|
@ -2138,17 +2138,19 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
already_AddRefed<MediaRawData>
|
||||
TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
const TimeUnit& aFuzz,
|
||||
bool& aError)
|
||||
GetSampleResult& aResult)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& trackData = GetTracksData(aTrack);
|
||||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||
|
||||
aError = false;
|
||||
aResult = GetSampleResult::WAITING_FOR_DATA;
|
||||
|
||||
if (!track.Length()) {
|
||||
aResult = GetSampleResult::EOS;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (trackData.mNextGetSampleIndex.isNothing() &&
|
||||
trackData.mNextSampleTimecode == TimeUnit()) {
|
||||
// First demux, get first sample.
|
||||
|
@ -2156,6 +2158,10 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
}
|
||||
|
||||
if (trackData.mNextGetSampleIndex.isSome()) {
|
||||
if (trackData.mNextGetSampleIndex.ref() >= track.Length()) {
|
||||
aResult = GetSampleResult::EOS;
|
||||
return nullptr;
|
||||
}
|
||||
const MediaRawData* sample =
|
||||
GetSample(aTrack,
|
||||
trackData.mNextGetSampleIndex.ref(),
|
||||
|
@ -2168,7 +2174,7 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
|
||||
RefPtr<MediaRawData> p = sample->Clone();
|
||||
if (!p) {
|
||||
aError = true;
|
||||
aResult = GetSampleResult::ERROR;
|
||||
return nullptr;
|
||||
}
|
||||
trackData.mNextGetSampleIndex.ref()++;
|
||||
|
@ -2177,9 +2183,18 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
|
||||
trackData.mNextSampleTime =
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
aResult = GetSampleResult::NO_ERROR;
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
if (trackData.mNextSampleTimecode.ToMicroseconds() >
|
||||
track.LastElement()->mTimecode + track.LastElement()->mDuration) {
|
||||
// The next element is past our last sample. We're done.
|
||||
trackData.mNextGetSampleIndex = Some(uint32_t(track.Length()));
|
||||
aResult = GetSampleResult::EOS;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Our previous index has been overwritten, attempt to find the new one.
|
||||
int32_t pos = FindCurrentPosition(aTrack, aFuzz);
|
||||
if (pos < 0) {
|
||||
|
@ -2193,7 +2208,7 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
RefPtr<MediaRawData> p = sample->Clone();
|
||||
if (!p) {
|
||||
// OOM
|
||||
aError = true;
|
||||
aResult = GetSampleResult::ERROR;
|
||||
return nullptr;
|
||||
}
|
||||
trackData.mNextGetSampleIndex = Some(uint32_t(pos)+1);
|
||||
|
@ -2201,6 +2216,7 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
|
||||
trackData.mNextSampleTime =
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
aResult = GetSampleResult::NO_ERROR;
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -153,9 +153,18 @@ public:
|
|||
const media::TimeUnit& aTimeThreadshold,
|
||||
const media::TimeUnit& aFuzz,
|
||||
bool& aFound);
|
||||
|
||||
enum class GetSampleResult
|
||||
{
|
||||
NO_ERROR,
|
||||
ERROR,
|
||||
WAITING_FOR_DATA,
|
||||
EOS
|
||||
};
|
||||
|
||||
already_AddRefed<MediaRawData> GetSample(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aFuzz,
|
||||
bool& aError);
|
||||
GetSampleResult& aResult);
|
||||
int32_t FindCurrentPosition(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aFuzz);
|
||||
media::TimeUnit GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
|
|
Загрузка…
Ссылка в новой задаче