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:
Jean-Yves Avenard 2016-08-28 01:00:39 +12:00
Родитель 90f7e263a7
Коммит 8d676d83a6
3 изменённых файлов: 51 добавлений и 19 удалений

Просмотреть файл

@ -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,