Bug 1262276 - part3 : allow the format reader to request video data during audio seeking. r=padenot

Audio and video demuxer are independent, so seeking the audio demuxer
won't affect requesting a data from the video demuxer.

Differential Revision: https://phabricator.services.mozilla.com/D159127
This commit is contained in:
alwu 2022-10-17 18:28:17 +00:00
Родитель 42422f8885
Коммит 0bebdcfdd9
2 изменённых файлов: 27 добавлений и 15 удалений

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

@ -1412,12 +1412,16 @@ Maybe<TimeUnit> MediaFormatReader::ShouldSkip(TimeUnit aTimeThreshold,
RefPtr<MediaFormatReader::VideoDataPromise> MediaFormatReader::RequestVideoData( RefPtr<MediaFormatReader::VideoDataPromise> MediaFormatReader::RequestVideoData(
const TimeUnit& aTimeThreshold, bool aRequestNextVideoKeyFrame) { const TimeUnit& aTimeThreshold, bool aRequestNextVideoKeyFrame) {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(),
"No sample requests allowed while seeking");
MOZ_DIAGNOSTIC_ASSERT(!mVideo.HasPromise(), "No duplicate sample requests"); MOZ_DIAGNOSTIC_ASSERT(!mVideo.HasPromise(), "No duplicate sample requests");
MOZ_DIAGNOSTIC_ASSERT(!mVideo.mSeekRequest.Exists() || // Requesting video can be done independently from audio, even during audio
mVideo.mTimeThreshold.isSome()); // seeking. But it shouldn't happen if we're doing video seek.
MOZ_DIAGNOSTIC_ASSERT(!IsSeeking(), "called mid-seek"); if (!IsAudioOnlySeeking()) {
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(),
"No sample requests allowed while seeking");
MOZ_DIAGNOSTIC_ASSERT(!mVideo.mSeekRequest.Exists() ||
mVideo.mTimeThreshold.isSome());
MOZ_DIAGNOSTIC_ASSERT(!IsSeeking(), "called mid-seek");
}
LOGV("RequestVideoData(%" PRId64 "), requestNextKeyFrame=%d", LOGV("RequestVideoData(%" PRId64 "), requestNextKeyFrame=%d",
aTimeThreshold.ToMicroseconds(), aRequestNextVideoKeyFrame); aTimeThreshold.ToMicroseconds(), aRequestNextVideoKeyFrame);
@ -1566,11 +1570,15 @@ RefPtr<MediaFormatReader::AudioDataPromise>
MediaFormatReader::RequestAudioData() { MediaFormatReader::RequestAudioData() {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(!mAudio.HasPromise(), "No duplicate sample requests"); MOZ_DIAGNOSTIC_ASSERT(!mAudio.HasPromise(), "No duplicate sample requests");
MOZ_DIAGNOSTIC_ASSERT(IsVideoSeeking() || mSeekPromise.IsEmpty(), // Requesting audio can be done independently from video, even during video
"No sample requests allowed while seeking"); // seeking. But it shouldn't happen if we're doing audio seek.
MOZ_DIAGNOSTIC_ASSERT(IsVideoSeeking() || !mAudio.mSeekRequest.Exists() || if (!IsVideoOnlySeeking()) {
mAudio.mTimeThreshold.isSome()); MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty(),
MOZ_DIAGNOSTIC_ASSERT(IsVideoSeeking() || !IsSeeking(), "called mid-seek"); "No sample requests allowed while seeking");
MOZ_DIAGNOSTIC_ASSERT(!mAudio.mSeekRequest.Exists() ||
mAudio.mTimeThreshold.isSome());
MOZ_DIAGNOSTIC_ASSERT(!IsSeeking(), "called mid-seek");
}
LOGV(""); LOGV("");
if (!HasAudio()) { if (!HasAudio()) {
@ -1859,17 +1867,18 @@ bool MediaFormatReader::UpdateReceivedNewData(TrackType aTrack) {
} }
if (!mSeekPromise.IsEmpty() && if (!mSeekPromise.IsEmpty() &&
(!IsVideoSeeking() || aTrack == TrackInfo::kVideoTrack)) { (!IsVideoOnlySeeking() || aTrack == TrackInfo::kVideoTrack)) {
MOZ_ASSERT(!decoder.HasPromise()); MOZ_ASSERT(!decoder.HasPromise());
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
(IsVideoSeeking() || !mAudio.mTimeThreshold) && !mVideo.mTimeThreshold, (IsVideoOnlySeeking() || !mAudio.mTimeThreshold) &&
!mVideo.mTimeThreshold,
"InternalSeek must have been aborted when Seek was first called"); "InternalSeek must have been aborted when Seek was first called");
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
(IsVideoSeeking() || !mAudio.HasWaitingPromise()) && (IsVideoOnlySeeking() || !mAudio.HasWaitingPromise()) &&
!mVideo.HasWaitingPromise(), !mVideo.HasWaitingPromise(),
"Waiting promises must have been rejected when Seek was first called"); "Waiting promises must have been rejected when Seek was first called");
if (mVideo.mSeekRequest.Exists() || if (mVideo.mSeekRequest.Exists() ||
(!IsVideoSeeking() && mAudio.mSeekRequest.Exists())) { (!IsVideoOnlySeeking() && mAudio.mSeekRequest.Exists())) {
// Already waiting for a seek to complete. Nothing more to do. // Already waiting for a seek to complete. Nothing more to do.
return true; return true;
} }

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

@ -753,9 +753,12 @@ class MediaFormatReader final
// Seeking objects. // Seeking objects.
void SetSeekTarget(const SeekTarget& aTarget); void SetSeekTarget(const SeekTarget& aTarget);
bool IsSeeking() const { return mPendingSeekTime.isSome(); } bool IsSeeking() const { return mPendingSeekTime.isSome(); }
bool IsVideoSeeking() const { bool IsVideoOnlySeeking() const {
return IsSeeking() && mOriginalSeekTarget.IsVideoOnly(); return IsSeeking() && mOriginalSeekTarget.IsVideoOnly();
} }
bool IsAudioOnlySeeking() const {
return IsSeeking() && mOriginalSeekTarget.IsAudioOnly();
}
void ScheduleSeek(); void ScheduleSeek();
void AttemptSeek(); void AttemptSeek();
void OnSeekFailed(TrackType aTrack, const MediaResult& aError); void OnSeekFailed(TrackType aTrack, const MediaResult& aError);