Bug 1351574. P1 - let MediaDecoderReader::RequestVideoData() take TimeUnit instead of int64_t.
MozReview-Commit-ID: DOsYkcJ77Em
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -233,17 +233,17 @@ MediaDecoderReader::AsyncReadMetadata()
// Success!
return MetadataPromise::CreateAndResolve(metadata, __func__);
}
class ReRequestVideoWithSkipTask : public Runnable
{
public:
ReRequestVideoWithSkipTask(MediaDecoderReader* aReader,
- int64_t aTimeThreshold)
+ const media::TimeUnit& aTimeThreshold)
: mReader(aReader)
, mTimeThreshold(aTimeThreshold)
{
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(mReader->OnTaskQueue());
@@ -253,17 +253,17 @@ public:
mReader->RequestVideoData(/* aSkip = */ true, mTimeThreshold);
}
return NS_OK;
}
private:
RefPtr<MediaDecoderReader> mReader;
- const int64_t mTimeThreshold;
+ const media::TimeUnit mTimeThreshold;
};
class ReRequestAudioTask : public Runnable
{
public:
explicit ReRequestAudioTask(MediaDecoderReader* aReader)
: mReader(aReader)
{
@@ -282,30 +282,31 @@ public:
}
private:
RefPtr<MediaDecoderReader> mReader;
};
RefPtr<MediaDecoderReader::VideoDataPromise>
MediaDecoderReader::RequestVideoData(bool aSkipToNextKeyframe,
- int64_t aTimeThreshold)
+ const media::TimeUnit& aTimeThreshold)
{
RefPtr<VideoDataPromise> p = mBaseVideoPromise.Ensure(__func__);
bool skip = aSkipToNextKeyframe;
while (VideoQueue().GetSize() == 0 &&
!VideoQueue().IsFinished()) {
- if (!DecodeVideoFrame(skip, aTimeThreshold)) {
+ if (!DecodeVideoFrame(skip, aTimeThreshold.ToMicroseconds())) {
VideoQueue().Finish();
} else if (skip) {
// We still need to decode more data in order to skip to the next
// keyframe. Post another task to the decode task queue to decode
// again. We don't just decode straight in a loop here, as that
// would hog the decode task queue.
- RefPtr<nsIRunnable> task(new ReRequestVideoWithSkipTask(this, aTimeThreshold));
+ RefPtr<nsIRunnable> task(
+ new ReRequestVideoWithSkipTask(this, aTimeThreshold));
mTaskQueue->Dispatch(task.forget());
return p;
}
}
if (VideoQueue().GetSize() > 0) {
RefPtr<VideoData> v = VideoQueue().PopFront();
mBaseVideoPromise.Resolve(v, __func__);
} else if (VideoQueue().IsFinished()) {
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -144,19 +144,20 @@ public:
//
// The decode should be performed asynchronously, and the promise should
// be resolved when it is complete.
virtual RefPtr<AudioDataPromise> RequestAudioData();
// Requests one video sample from the reader.
//
// If aSkipToKeyframe is true, the decode should skip ahead to the
- // the next keyframe at or after aTimeThreshold microseconds.
+ // the next keyframe at or after aTimeThreshold.
virtual RefPtr<VideoDataPromise>
- RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold);
+ RequestVideoData(bool aSkipToNextKeyframe,
+ const media::TimeUnit& aTimeThreshold);
// By default, the state machine polls the reader once per second when it's
// in buffering mode. Some readers support a promise-based mechanism by which
// they notify the state machine when the data arrives.
virtual bool IsWaitForDataSupported() const { return false; }
virtual RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType)
{
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -60,29 +60,30 @@ MediaDecoderReaderWrapper::RequestAudioD
RefPtr<MediaDecoderReaderWrapper::VideoDataPromise>
MediaDecoderReaderWrapper::RequestVideoData(bool aSkipToNextKeyframe,
media::TimeUnit aTimeThreshold)
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
MOZ_ASSERT(!mShutdown);
- if (aTimeThreshold.ToMicroseconds() > 0) {
+ if (aTimeThreshold > media::TimeUnit::Zero()) {
aTimeThreshold += StartTime();
}
int64_t startTime = StartTime().ToMicroseconds();
- return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
- &MediaDecoderReader::RequestVideoData,
- aSkipToNextKeyframe, aTimeThreshold.ToMicroseconds())
- ->Then(mOwnerThread, __func__,
- [startTime] (VideoData* aVideo) {
- aVideo->AdjustForStartTime(startTime);
- },
- [] (const MediaResult& aError) {});
+ return InvokeAsync<bool, media::TimeUnit&&>(
+ mReader->OwnerThread(), mReader.get(), __func__,
+ &MediaDecoderReader::RequestVideoData,
+ aSkipToNextKeyframe, aTimeThreshold)
+ ->Then(mOwnerThread, __func__,
+ [startTime] (VideoData* aVideo) {
+ aVideo->AdjustForStartTime(startTime);
+ },
+ [] (const MediaResult& aError) {});
}
RefPtr<MediaDecoderReader::SeekPromise>
MediaDecoderReaderWrapper::Seek(const SeekTarget& aTarget)
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
SeekTarget adjustedTarget = aTarget;
adjustedTarget.SetTime(adjustedTarget.GetTime() + StartTime());
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1510,26 +1510,27 @@ MediaFormatReader::ShouldSkip(bool aSkip
|| (mVideo.mTimeThreshold
&& mVideo.mTimeThreshold.ref().EndTime() < aTimeThreshold))
&& nextKeyframe.ToMicroseconds() >= 0
&& !nextKeyframe.IsInfinite();
}
RefPtr<MediaDecoderReader::VideoDataPromise>
MediaFormatReader::RequestVideoData(bool aSkipToNextKeyframe,
- int64_t aTimeThreshold)
+ const media::TimeUnit& aTimeThreshold)
{
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.mSeekRequest.Exists()
|| mVideo.mTimeThreshold.isSome());
MOZ_DIAGNOSTIC_ASSERT(!IsSeeking(), "called mid-seek");
- LOGV("RequestVideoData(%d, %" PRId64 ")", aSkipToNextKeyframe, aTimeThreshold);
+ LOGV("RequestVideoData(%d, %" PRId64 ")",
+ aSkipToNextKeyframe, aTimeThreshold.ToMicroseconds());
if (!HasVideo()) {
LOG("called with no video track");
return VideoDataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
__func__);
}
if (IsSeeking()) {
@@ -1539,24 +1540,22 @@ MediaFormatReader::RequestVideoData(bool
}
if (mShutdown) {
NS_WARNING("RequestVideoData on shutdown MediaFormatReader!");
return VideoDataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_CANCELED,
__func__);
}
- media::TimeUnit timeThreshold{ media::TimeUnit::FromMicroseconds(
- aTimeThreshold) };
// Ensure we have no pending seek going as ShouldSkip could return out of date
// information.
if (!mVideo.HasInternalSeekPending()
- && ShouldSkip(aSkipToNextKeyframe, timeThreshold)) {
+ && ShouldSkip(aSkipToNextKeyframe, aTimeThreshold)) {
RefPtr<VideoDataPromise> p = mVideo.EnsurePromise(__func__);
- SkipVideoDemuxToNextKeyFrame(timeThreshold);
+ SkipVideoDemuxToNextKeyFrame(aTimeThreshold);
return p;
}
RefPtr<VideoDataPromise> p = mVideo.EnsurePromise(__func__);
ScheduleUpdate(TrackInfo::kVideoTrack);
return p;
}
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -33,17 +33,18 @@ public:
VideoFrameContainer* aVideoFrameContainer = nullptr);
virtual ~MediaFormatReader();
size_t SizeOfVideoQueueInFrames() override;
size_t SizeOfAudioQueueInFrames() override;
RefPtr<VideoDataPromise>
- RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) override;
+ RequestVideoData(bool aSkipToNextKeyframe,
+ const media::TimeUnit& aTimeThreshold) override;
RefPtr<AudioDataPromise> RequestAudioData() override;
RefPtr<MetadataPromise> AsyncReadMetadata() override;
void ReadUpdatedMetadata(MediaInfo* aInfo) override;
RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) override;