Bug 1111413 - Part 1: Use MediaPromises for seeking. r=bholley

This commit is contained in:
Matt Woodrow 2014-12-16 22:52:57 +13:00
parent 4c9e36f698
commit 98dd818ec6
35 changed files with 209 additions and 122 deletions

View File

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

View File

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

View File

@ -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()
{

View File

@ -387,7 +387,8 @@ public:
OnNotDecoded(MediaData::VIDEO_DATA, aReason);
}
void OnSeekCompleted(nsresult aResult);
void OnSeekCompleted();
void OnSeekFailed(nsresult aResult);
private:
void AcquireMonitorAndInvokeDecodeError();

View File

@ -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:
/*

View File

@ -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) :

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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());
}
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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() {

View File

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

View File

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

View File

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

View File

@ -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() {

View File

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

View File

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

View File

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

View File

@ -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) {

View File

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

View File

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

View File

@ -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);

View File

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

View File

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