mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1309516 part 1 - retrieve start time before resolving the metadata promise; r=jya
MozReview-Commit-ID: FhnoFi1BSHM --HG-- extra : rebase_source : 3c1a1efa936fa0f4decdfb12c90bcce607c5edba
This commit is contained in:
parent
42a1f53991
commit
5bc83d3772
@ -732,10 +732,50 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
|
||||
return;
|
||||
}
|
||||
|
||||
mTags = Move(tags);
|
||||
mInitDone = true;
|
||||
|
||||
// Try to get the start time.
|
||||
// For MSE case, the start time of each track is assumed to be 0.
|
||||
// For others, we must demux the first sample to know the start time for each
|
||||
// track.
|
||||
if (ForceZeroStartTime()) {
|
||||
mAudio.mFirstDemuxedSampleTime.emplace(TimeUnit::FromMicroseconds(0));
|
||||
mVideo.mFirstDemuxedSampleTime.emplace(TimeUnit::FromMicroseconds(0));
|
||||
} else {
|
||||
if (HasAudio()) {
|
||||
RequestDemuxSamples(TrackInfo::kAudioTrack);
|
||||
}
|
||||
|
||||
if (HasVideo()) {
|
||||
RequestDemuxSamples(TrackInfo::kVideoTrack);
|
||||
}
|
||||
}
|
||||
|
||||
MaybeResolveMetadataPromise();
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::MaybeResolveMetadataPromise()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
if ((HasAudio() && mAudio.mFirstDemuxedSampleTime.isNothing()) ||
|
||||
(HasVideo() && mVideo.mFirstDemuxedSampleTime.isNothing())) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimeUnit startTime =
|
||||
std::min(mAudio.mFirstDemuxedSampleTime.refOr(TimeUnit::FromInfinity()),
|
||||
mVideo.mFirstDemuxedSampleTime.refOr(TimeUnit::FromInfinity()));
|
||||
|
||||
if (!startTime.IsInfinite()) {
|
||||
mInfo.mStartTime = startTime; // mInfo.mStartTime is initialized to 0.
|
||||
}
|
||||
|
||||
RefPtr<MetadataHolder> metadata = new MetadataHolder();
|
||||
metadata->mInfo = mInfo;
|
||||
metadata->mTags = tags->Count() ? tags.release() : nullptr;
|
||||
metadata->mTags = mTags->Count() ? mTags.release() : nullptr;
|
||||
mMetadataPromise.Resolve(metadata, __func__);
|
||||
}
|
||||
|
||||
@ -863,10 +903,22 @@ MediaFormatReader::OnDemuxFailed(TrackType aTrack, const MediaResult& aError)
|
||||
void
|
||||
MediaFormatReader::DoDemuxVideo()
|
||||
{
|
||||
mVideo.mDemuxRequest.Begin(mVideo.mTrackDemuxer->GetSamples(1)
|
||||
->Then(OwnerThread(), __func__, this,
|
||||
&MediaFormatReader::OnVideoDemuxCompleted,
|
||||
&MediaFormatReader::OnVideoDemuxFailed));
|
||||
auto p = mVideo.mTrackDemuxer->GetSamples(1);
|
||||
|
||||
if (mVideo.mFirstDemuxedSampleTime.isNothing()) {
|
||||
RefPtr<MediaFormatReader> self = this;
|
||||
p = p->Then(OwnerThread(), __func__,
|
||||
[self] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
|
||||
self->OnFirstDemuxCompleted(TrackInfo::kVideoTrack, aSamples);
|
||||
},
|
||||
[self] (const MediaResult& aError) {
|
||||
self->OnFirstDemuxFailed(TrackInfo::kVideoTrack, aError);
|
||||
})->CompletionPromise();
|
||||
}
|
||||
|
||||
mVideo.mDemuxRequest.Begin(p->Then(OwnerThread(), __func__, this,
|
||||
&MediaFormatReader::OnVideoDemuxCompleted,
|
||||
&MediaFormatReader::OnVideoDemuxFailed));
|
||||
}
|
||||
|
||||
void
|
||||
@ -917,10 +969,22 @@ MediaFormatReader::RequestAudioData()
|
||||
void
|
||||
MediaFormatReader::DoDemuxAudio()
|
||||
{
|
||||
mAudio.mDemuxRequest.Begin(mAudio.mTrackDemuxer->GetSamples(1)
|
||||
->Then(OwnerThread(), __func__, this,
|
||||
&MediaFormatReader::OnAudioDemuxCompleted,
|
||||
&MediaFormatReader::OnAudioDemuxFailed));
|
||||
auto p = mAudio.mTrackDemuxer->GetSamples(1);
|
||||
|
||||
if (mAudio.mFirstDemuxedSampleTime.isNothing()) {
|
||||
RefPtr<MediaFormatReader> self = this;
|
||||
p = p->Then(OwnerThread(), __func__,
|
||||
[self] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
|
||||
self->OnFirstDemuxCompleted(TrackInfo::kAudioTrack, aSamples);
|
||||
},
|
||||
[self] (const MediaResult& aError) {
|
||||
self->OnFirstDemuxFailed(TrackInfo::kAudioTrack, aError);
|
||||
})->CompletionPromise();
|
||||
}
|
||||
|
||||
mAudio.mDemuxRequest.Begin(p->Then(OwnerThread(), __func__, this,
|
||||
&MediaFormatReader::OnAudioDemuxCompleted,
|
||||
&MediaFormatReader::OnAudioDemuxFailed));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1204,11 +1268,6 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ForceZeroStartTime() && decoder.mFirstDemuxedSampleTime.isNothing()) {
|
||||
decoder.mFirstDemuxedSampleTime.emplace(
|
||||
media::TimeUnit::FromMicroseconds(decoder.mQueuedSamples[0]->mTime));
|
||||
}
|
||||
|
||||
LOGV("Giving %s input to decoder", TrackTypeToStr(aTrack));
|
||||
|
||||
// Decode all our demuxed frames.
|
||||
@ -2340,4 +2399,37 @@ MediaFormatReader::SetBlankDecode(TrackType aTrack, bool aIsBlankDecode)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnFirstDemuxCompleted(TrackInfo::TrackType aType,
|
||||
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
if (mShutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& decoder = GetDecoderData(aType);
|
||||
MOZ_ASSERT(decoder.mFirstDemuxedSampleTime.isNothing());
|
||||
decoder.mFirstDemuxedSampleTime.emplace(
|
||||
TimeUnit::FromMicroseconds(aSamples->mSamples[0]->mTime));
|
||||
MaybeResolveMetadataPromise();
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnFirstDemuxFailed(TrackInfo::TrackType aType,
|
||||
const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
if (mShutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& decoder = GetDecoderData(aType);
|
||||
MOZ_ASSERT(decoder.mFirstDemuxedSampleTime.isNothing());
|
||||
decoder.mFirstDemuxedSampleTime.emplace(TimeUnit::FromInfinity());
|
||||
MaybeResolveMetadataPromise();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -595,6 +595,15 @@ private:
|
||||
UniquePtr<DecoderFactory> mDecoderFactory;
|
||||
|
||||
MediaEventListener mCompositorUpdatedListener;
|
||||
|
||||
void OnFirstDemuxCompleted(TrackInfo::TrackType aType,
|
||||
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
|
||||
|
||||
void OnFirstDemuxFailed(TrackInfo::TrackType aType, const MediaResult& aError);
|
||||
|
||||
void MaybeResolveMetadataPromise();
|
||||
|
||||
UniquePtr<MetadataTags> mTags;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -503,6 +503,10 @@ public:
|
||||
bool mMediaSeekableOnlyInBufferedRanges = false;
|
||||
|
||||
EncryptionInfo mCrypto;
|
||||
|
||||
// The minimum of start times of audio and video tracks.
|
||||
// Use to map the zero time on the media timeline to the first frame.
|
||||
media::TimeUnit mStartTime;
|
||||
};
|
||||
|
||||
class SharedTrackInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user