mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1111413 - Part 1: Use MediaPromises for seeking. r=bholley
This commit is contained in:
parent
4c9e36f698
commit
98dd818ec6
@ -36,20 +36,6 @@ public:
|
||||
mTaskQueue = nullptr;
|
||||
}
|
||||
|
||||
virtual void OnSeekCompleted(nsresult aResult) MOZ_OVERRIDE {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!mTarget || !mTaskQueue) {
|
||||
// We've been shutdown, abort.
|
||||
return;
|
||||
}
|
||||
RefPtr<nsIRunnable> task(NS_NewRunnableMethodWithArg<nsresult>(mTarget,
|
||||
&Target::OnSeekCompleted,
|
||||
aResult));
|
||||
if (NS_FAILED(mTaskQueue->Dispatch(task))) {
|
||||
NS_WARNING("Failed to dispatch OnSeekCompleted task");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Monitor mMonitor;
|
||||
RefPtr<MediaTaskQueue> mTaskQueue;
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
|
||||
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason> AudioDataPromise;
|
||||
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason> VideoDataPromise;
|
||||
typedef MediaPromise<bool, nsresult> SeekPromise;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
|
||||
|
||||
@ -131,15 +132,12 @@ public:
|
||||
// ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
|
||||
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) { };
|
||||
|
||||
// Requests the Reader to seek and call OnSeekCompleted on the callback
|
||||
// once completed.
|
||||
// Moves the decode head to aTime microseconds. aStartTime and aEndTime
|
||||
// denote the start and end times of the media in usecs, and aCurrentTime
|
||||
// is the current playback position in microseconds.
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) = 0;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime) = 0;
|
||||
|
||||
// Called to move the reader into idle state. When the reader is
|
||||
// created it is assumed to be active (i.e. not idle). When the media
|
||||
@ -312,8 +310,6 @@ class RequestSampleCallback {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RequestSampleCallback)
|
||||
|
||||
virtual void OnSeekCompleted(nsresult aResult) = 0;
|
||||
|
||||
// Called during shutdown to break any reference cycles.
|
||||
virtual void BreakCycles() = 0;
|
||||
|
||||
|
@ -2306,10 +2306,10 @@ void MediaDecoderStateMachine::DecodeSeek()
|
||||
// the reader, since it could do I/O or deadlock some other way.
|
||||
res = mReader->ResetDecode();
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
mReader->Seek(seekTime,
|
||||
mStartTime,
|
||||
mEndTime,
|
||||
mCurrentTimeBeforeSeek);
|
||||
mReader->Seek(seekTime, mStartTime, mEndTime, mCurrentTimeBeforeSeek)
|
||||
->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnSeekCompleted,
|
||||
&MediaDecoderStateMachine::OnSeekFailed);
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(res)) {
|
||||
@ -2321,14 +2321,10 @@ void MediaDecoderStateMachine::DecodeSeek()
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnSeekCompleted(nsresult aResult)
|
||||
MediaDecoderStateMachine::OnSeekCompleted()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mWaitingForDecoderSeek = false;
|
||||
if (NS_FAILED(aResult)) {
|
||||
DecodeError();
|
||||
return;
|
||||
}
|
||||
|
||||
// We must decode the first samples of active streams, so we can determine
|
||||
// the new stream time. So dispatch tasks to do that.
|
||||
@ -2336,6 +2332,19 @@ MediaDecoderStateMachine::OnSeekCompleted(nsresult aResult)
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnSeekFailed(nsresult aResult)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mWaitingForDecoderSeek = false;
|
||||
// Sometimes we reject the promise for non-failure reasons, like
|
||||
// when we request a second seek before the previous one has
|
||||
// completed.
|
||||
if (NS_FAILED(aResult)) {
|
||||
DecodeError();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::SeekCompleted()
|
||||
{
|
||||
|
@ -387,7 +387,8 @@ public:
|
||||
OnNotDecoded(MediaData::VIDEO_DATA, aReason);
|
||||
}
|
||||
|
||||
void OnSeekCompleted(nsresult aResult);
|
||||
void OnSeekCompleted();
|
||||
void OnSeekFailed(nsresult aResult);
|
||||
|
||||
private:
|
||||
void AcquireMonitorAndInvokeDecodeError();
|
||||
|
@ -65,6 +65,24 @@ public:
|
||||
PROMISE_LOG("%s creating MediaPromise (%p)", mCreationSite, this);
|
||||
}
|
||||
|
||||
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
|
||||
CreateAndResolve(ResolveValueType aResolveValue, const char* aResolveSite)
|
||||
{
|
||||
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
|
||||
new MediaPromise<ResolveValueT, RejectValueT>(aResolveSite);
|
||||
p->Resolve(aResolveValue, aResolveSite);
|
||||
return p;
|
||||
}
|
||||
|
||||
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
|
||||
CreateAndReject(RejectValueType aRejectValue, const char* aRejectSite)
|
||||
{
|
||||
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
|
||||
new MediaPromise<ResolveValueT, RejectValueT>(aRejectSite);
|
||||
p->Reject(aRejectValue, aRejectSite);
|
||||
return p;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
|
@ -319,7 +319,8 @@ bool AndroidMediaReader::DecodeAudioData()
|
||||
source.mAudioChannels));
|
||||
}
|
||||
|
||||
void AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
@ -339,7 +340,7 @@ void AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndT
|
||||
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;
|
||||
}
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
AndroidMediaReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
|
||||
|
@ -69,7 +69,8 @@ public:
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsRefPtr<ShutdownPromise> Shutdown() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -492,7 +492,7 @@ AppleMP3Reader::SetupDecoder()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
AppleMP3Reader::Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
@ -518,8 +518,7 @@ AppleMP3Reader::Seek(int64_t aTime,
|
||||
|
||||
if (rv) {
|
||||
LOGE("Couldn't seek demuxer. Error code %x\n", rv);
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
LOGD("computed byte offset = %lld; estimated = %s\n",
|
||||
@ -530,7 +529,7 @@ AppleMP3Reader::Seek(int64_t aTime,
|
||||
|
||||
ResetDecode();
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -33,10 +33,11 @@ public:
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
void AudioSampleCallback(UInt32 aNumBytes,
|
||||
UInt32 aNumPackets,
|
||||
|
@ -367,14 +367,18 @@ DirectShowReader::HasVideo()
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
DirectShowReader::Seek(int64_t aTargetUs,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTargetUs);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -60,10 +60,11 @@ public:
|
||||
nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
void NotifyDataArrived(const char* aBuffer,
|
||||
uint32_t aLength,
|
||||
|
@ -783,7 +783,7 @@ MP4Reader::SkipVideoDemuxToNextKeyFrame(int64_t aTimeThreshold, uint32_t& parsed
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MP4Reader::Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
@ -793,8 +793,7 @@ MP4Reader::Seek(int64_t aTime,
|
||||
MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
|
||||
if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
|
||||
VLOG("Seek() END (Unseekable)");
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
mQueuedVideoSample = nullptr;
|
||||
@ -807,7 +806,7 @@ MP4Reader::Seek(int64_t aTime,
|
||||
mQueuedVideoSample ? mQueuedVideoSample->composition_timestamp : aTime);
|
||||
}
|
||||
LOG("MP4Reader::Seek(%lld) exit", aTime);
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -55,10 +55,11 @@ public:
|
||||
|
||||
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -787,10 +787,11 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
||||
return true;
|
||||
}
|
||||
|
||||
void GStreamerReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
GStreamerReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
@ -804,8 +805,7 @@ void GStreamerReader::Seek(int64_t aTarget,
|
||||
static_cast<GstSeekFlags>(flags),
|
||||
seekPos)) {
|
||||
LOG(PR_LOG_ERROR, "seek failed");
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
LOG(PR_LOG_DEBUG, "seek succeeded");
|
||||
GstMessage* message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE,
|
||||
@ -813,7 +813,7 @@ void GStreamerReader::Seek(int64_t aTarget,
|
||||
gst_message_unref(message);
|
||||
LOG(PR_LOG_DEBUG, "seek completed");
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
nsresult GStreamerReader::GetBuffered(dom::TimeRanges* aBuffered)
|
||||
|
@ -48,10 +48,11 @@ public:
|
||||
int64_t aTimeThreshold);
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
virtual void NotifyDataArrived(const char *aBuffer,
|
||||
|
@ -296,6 +296,8 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
||||
nsRefPtr<ShutdownPromise>
|
||||
MediaSourceReader::Shutdown()
|
||||
{
|
||||
mSeekPromise.RejectIfExists(NS_ERROR_FAILURE, __func__);
|
||||
|
||||
MOZ_ASSERT(mMediaSourceShutdownPromise.IsEmpty());
|
||||
nsRefPtr<ShutdownPromise> p = mMediaSourceShutdownPromise.Ensure(__func__);
|
||||
|
||||
@ -538,16 +540,19 @@ MediaSourceReader::NotifyTimeRangesChanged()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek(aTime=%lld, aStart=%lld, aEnd=%lld, aCurrent=%lld)",
|
||||
this, aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
|
||||
mSeekPromise.RejectIfExists(NS_OK, __func__);
|
||||
nsRefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
|
||||
|
||||
if (IsShutdown()) {
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
mSeekPromise.Reject(NS_ERROR_FAILURE, __func__);
|
||||
return p;
|
||||
}
|
||||
|
||||
// Store pending seek target in case the track buffers don't contain
|
||||
@ -575,20 +580,38 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
}
|
||||
|
||||
AttemptSeek();
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnSeekCompleted(nsresult aResult)
|
||||
MediaSourceReader::OnSeekCompleted()
|
||||
{
|
||||
mPendingSeeks--;
|
||||
FinalizeSeek();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnSeekFailed(nsresult aResult)
|
||||
{
|
||||
mPendingSeeks--;
|
||||
// Keep the most recent failed result (if any)
|
||||
if (NS_FAILED(aResult)) {
|
||||
mSeekResult = aResult;
|
||||
}
|
||||
FinalizeSeek();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::FinalizeSeek()
|
||||
{
|
||||
// Only dispatch the final event onto the state machine
|
||||
// since it's only expecting one response.
|
||||
if (!mPendingSeeks) {
|
||||
GetCallback()->OnSeekCompleted(mSeekResult);
|
||||
if (NS_FAILED(mSeekResult)) {
|
||||
mSeekPromise.Reject(mSeekResult, __func__);
|
||||
} else {
|
||||
mSeekPromise.Resolve(true, __func__);
|
||||
}
|
||||
mSeekResult = NS_OK;
|
||||
}
|
||||
}
|
||||
@ -620,7 +643,10 @@ MediaSourceReader::AttemptSeek()
|
||||
mAudioReader->Seek(mPendingSeekTime,
|
||||
mPendingStartTime,
|
||||
mPendingEndTime,
|
||||
mPendingCurrentTime);
|
||||
mPendingCurrentTime)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed);
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p", this, mAudioReader.get());
|
||||
}
|
||||
if (mVideoTrack) {
|
||||
@ -629,7 +655,10 @@ MediaSourceReader::AttemptSeek()
|
||||
mVideoReader->Seek(mPendingSeekTime,
|
||||
mPendingStartTime,
|
||||
mPendingEndTime,
|
||||
mPendingCurrentTime);
|
||||
mPendingCurrentTime)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed);
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p", this, mVideoReader.get());
|
||||
}
|
||||
{
|
||||
|
@ -55,7 +55,8 @@ public:
|
||||
void OnVideoDecoded(VideoData* aSample);
|
||||
void OnVideoNotDecoded(NotDecodedReason aReason);
|
||||
|
||||
void OnSeekCompleted(nsresult aResult);
|
||||
void OnSeekCompleted();
|
||||
void OnSeekFailed(nsresult aResult);
|
||||
|
||||
bool HasVideo() MOZ_OVERRIDE
|
||||
{
|
||||
@ -84,8 +85,9 @@ public:
|
||||
|
||||
nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
void ReadUpdatedMetadata(MediaInfo* aInfo) MOZ_OVERRIDE;
|
||||
void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
// Acquires the decoder monitor, and is thus callable on any thread.
|
||||
nsresult GetBuffered(dom::TimeRanges* aBuffered) MOZ_OVERRIDE;
|
||||
@ -129,6 +131,7 @@ private:
|
||||
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
|
||||
|
||||
void AttemptSeek();
|
||||
void FinalizeSeek();
|
||||
|
||||
nsRefPtr<MediaDecoderReader> mAudioReader;
|
||||
nsRefPtr<MediaDecoderReader> mVideoReader;
|
||||
@ -152,6 +155,7 @@ private:
|
||||
|
||||
// Temporary seek information while we wait for the data
|
||||
// to be added to the track buffer.
|
||||
MediaPromiseHolder<SeekPromise> mSeekPromise;
|
||||
int64_t mPendingSeekTime;
|
||||
int64_t mPendingStartTime;
|
||||
int64_t mPendingEndTime;
|
||||
|
@ -1424,13 +1424,18 @@ nsresult OggReader::SeekInUnbuffered(int64_t aTarget,
|
||||
return SeekBisection(seekTarget, k, SEEK_FUZZ_USECS);
|
||||
}
|
||||
|
||||
void OggReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
OggReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTarget, aStartTime, aEndTime, aCurrentTime);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult OggReader::SeekInternal(int64_t aTarget,
|
||||
|
@ -75,7 +75,8 @@ public:
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
@ -999,7 +999,7 @@ MediaCodecReader::DecodeVideoFrameSync(int64_t aTimeThreshold)
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaCodecReader::Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
@ -1031,8 +1031,7 @@ MediaCodecReader::Seek(int64_t aTime,
|
||||
options.setSeekTo(aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
|
||||
if (mVideoTrack.mSource->read(&source_buffer, &options) != OK ||
|
||||
source_buffer == nullptr) {
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
sp<MetaData> format = source_buffer->meta_data();
|
||||
if (format != nullptr) {
|
||||
@ -1056,7 +1055,7 @@ MediaCodecReader::Seek(int64_t aTime,
|
||||
MOZ_ASSERT(mAudioTrack.mTaskQueue->IsEmpty());
|
||||
DispatchAudioTask();
|
||||
}
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -100,10 +100,11 @@ public:
|
||||
// Moves the decode head to aTime microseconds. aStartTime and aEndTime
|
||||
// denote the start and end times of the media in usecs, and aCurrentTime
|
||||
// is the current playback position in microseconds.
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -545,7 +545,8 @@ bool MediaOmxReader::DecodeAudioData()
|
||||
source.mAudioChannels));
|
||||
}
|
||||
|
||||
void MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
EnsureActive();
|
||||
@ -571,7 +572,7 @@ void MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
||||
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;
|
||||
}
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void MediaOmxReader::SetIdle() {
|
||||
|
@ -98,7 +98,8 @@ public:
|
||||
virtual void PreReadMetadata() MOZ_OVERRIDE;
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -38,7 +38,7 @@ RtspMediaCodecReader::CreateExtractor()
|
||||
return mExtractor != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
RtspMediaCodecReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
@ -48,7 +48,7 @@ RtspMediaCodecReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
// RtspMediaResource.
|
||||
mRtspResource->SeekTime(aTime);
|
||||
|
||||
MediaCodecReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
return MediaCodecReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -36,8 +36,9 @@ public:
|
||||
virtual ~RtspMediaCodecReader();
|
||||
|
||||
// Implement a time-based seek instead of byte-based.
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
// Override GetBuffered() to do nothing for below reasons:
|
||||
// 1. Because the Rtsp stream is a/v separated. The buffered data in a/v
|
||||
|
@ -32,8 +32,9 @@ nsresult RtspOmxReader::InitOmxDecoder()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
// The seek function of Rtsp is time-based, we call the SeekTime function in
|
||||
// RtspMediaResource. The SeekTime function finally send a seek command to
|
||||
@ -48,7 +49,7 @@ void RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
// seek operation. The function will clear the |mVideoQueue| and |mAudioQueue|
|
||||
// that store the decoded data and also call the |DecodeToTarget| to pass
|
||||
// the seek time to OMX a/v decoders.
|
||||
MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
return MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
}
|
||||
|
||||
void RtspOmxReader::SetIdle() {
|
||||
|
@ -46,8 +46,9 @@ public:
|
||||
}
|
||||
|
||||
// Implement a time-based seek instead of byte-based..
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_FINAL MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
// Override GetBuffered() to do nothing for below reasons:
|
||||
// 1. Because the Rtsp stream is a/v separated. The buffered data in a/v
|
||||
|
@ -235,10 +235,15 @@ bool RawReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
return true;
|
||||
}
|
||||
|
||||
void RawReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
RawReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTime);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult RawReader::SeekInternal(int64_t aTime)
|
||||
|
@ -39,7 +39,9 @@ public:
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
@ -257,13 +257,14 @@ bool WaveReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
return false;
|
||||
}
|
||||
|
||||
void WaveReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
WaveReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget));
|
||||
|
||||
if (NS_FAILED(ResetDecode())) {
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
double d = BytesToTime(GetDataLength());
|
||||
NS_ASSERTION(d < INT64_MAX / USECS_PER_S, "Duration overflow");
|
||||
@ -273,7 +274,11 @@ void WaveReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int
|
||||
NS_ASSERTION(INT64_MAX - mWavePCMOffset > position, "Integer overflow during wave seek");
|
||||
position += mWavePCMOffset;
|
||||
nsresult res = mDecoder->GetResource()->Seek(nsISeekableStream::NS_SEEK_SET, position);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static double RoundToUsecs(double aSeconds) {
|
||||
|
@ -43,7 +43,9 @@ public:
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
// To seek in a buffered range, we just have to seek the stream.
|
||||
|
@ -951,11 +951,16 @@ void WebMReader::PushVideoPacket(NesteggPacketHolder* aItem)
|
||||
mVideoPackets.PushFront(aItem);
|
||||
}
|
||||
|
||||
void WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTarget, aStartTime);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult WebMReader::SeekInternal(int64_t aTarget, int64_t aStartTime)
|
||||
|
@ -155,8 +155,9 @@ public:
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength,
|
||||
int64_t aOffset);
|
||||
|
@ -888,14 +888,18 @@ WMFReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
WMFReader::Seek(int64_t aTargetUs,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTargetUs);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -43,10 +43,11 @@ public:
|
||||
nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user