Bug 1316211. P1 - make some functions pure virtual for they will be overridden by MFR.
MozReview-Commit-ID: 9l8MbDRjLR0
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -169,69 +169,32 @@ MediaDecoderReader::DecodeToFirstVideoDa
// We don't have a way to differentiate EOS, error, and shutdown here. :-(
p->Reject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
});
return p.forget();
}
void
-MediaDecoderReader::UpdateBuffered()
-{
- MOZ_ASSERT(OnTaskQueue());
- NS_ENSURE_TRUE_VOID(!mShutdown);
- mBuffered = GetBuffered();
-}
-
-void
MediaDecoderReader::VisibilityChanged()
{}
media::TimeIntervals
MediaDecoderReader::GetBuffered()
{
MOZ_ASSERT(OnTaskQueue());
if (mDuration.isNothing()) {
return TimeIntervals();
}
AutoPinned<MediaResource> stream(mResource);
return GetEstimatedBufferedTimeRanges(stream, mDuration->ToMicroseconds());
}
-RefPtr<MediaDecoderReader::MetadataPromise>
-MediaDecoderReader::AsyncReadMetadata()
-{
- MOZ_ASSERT(OnTaskQueue());
- DECODER_LOG("MediaDecoderReader::AsyncReadMetadata");
-
- // Attempt to read the metadata.
- MetadataHolder metadata;
- metadata.mInfo = MakeUnique<MediaInfo>();
- MetadataTags* tags = nullptr;
- nsresult rv = ReadMetadata(metadata.mInfo.get(), &tags);
- metadata.mTags.reset(tags);
- metadata.mInfo->AssertValid();
-
- // Update the buffer ranges before resolving the metadata promise. Bug 1320258.
- UpdateBuffered();
-
- // We're not waiting for anything. If we didn't get the metadata, that's an
- // error.
- if (NS_FAILED(rv) || !metadata.mInfo->HasValidMedia()) {
- DECODER_WARN("ReadMetadata failed, rv=%" PRIx32 " HasValidMedia=%d",
- static_cast<uint32_t>(rv), metadata.mInfo->HasValidMedia());
- return MetadataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
- }
-
- // Success!
- return MetadataPromise::CreateAndResolve(Move(metadata), __func__);
-}
-
class ReRequestVideoWithSkipTask : public Runnable
{
public:
ReRequestVideoWithSkipTask(MediaDecoderReader* aReader,
const media::TimeUnit& aTimeThreshold)
: Runnable("ReRequestVideoWithSkipTask")
, mReader(aReader)
, mTimeThreshold(aTimeThreshold)
@@ -275,83 +238,16 @@ public:
return NS_OK;
}
private:
RefPtr<MediaDecoderReader> mReader;
};
-RefPtr<MediaDecoderReader::VideoDataPromise>
-MediaDecoderReader::RequestVideoData(const media::TimeUnit& aTimeThreshold)
-{
- RefPtr<VideoDataPromise> p = mBaseVideoPromise.Ensure(__func__);
- bool skip = false;
- while (VideoQueue().GetSize() == 0 &&
- !VideoQueue().IsFinished()) {
- if (!DecodeVideoFrame(skip, aTimeThreshold)) {
- 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));
- mTaskQueue->Dispatch(task.forget());
- return p;
- }
- }
- if (VideoQueue().GetSize() > 0) {
- RefPtr<VideoData> v = VideoQueue().PopFront();
- mBaseVideoPromise.Resolve(v, __func__);
- } else if (VideoQueue().IsFinished()) {
- mBaseVideoPromise.Reject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
- } else {
- MOZ_ASSERT(false, "Dropping this promise on the floor");
- }
-
- return p;
-}
-
-RefPtr<MediaDecoderReader::AudioDataPromise>
-MediaDecoderReader::RequestAudioData()
-{
- RefPtr<AudioDataPromise> p = mBaseAudioPromise.Ensure(__func__);
- while (AudioQueue().GetSize() == 0 &&
- !AudioQueue().IsFinished()) {
- if (!DecodeAudioData()) {
- AudioQueue().Finish();
- break;
- }
- // AudioQueue size is still zero, post a task to try again. Don't spin
- // waiting in this while loop since it somehow prevents audio EOS from
- // coming in gstreamer 1.x when there is still video buffer waiting to be
- // consumed. (|mVideoSinkBufferCount| > 0)
- if (AudioQueue().GetSize() == 0) {
- RefPtr<nsIRunnable> task(new ReRequestAudioTask(this));
- mTaskQueue->Dispatch(task.forget());
- return p;
- }
- }
- if (AudioQueue().GetSize() > 0) {
- RefPtr<AudioData> a = AudioQueue().PopFront();
- mBaseAudioPromise.Resolve(a, __func__);
- } else if (AudioQueue().IsFinished()) {
- mBaseAudioPromise.Reject(mHitAudioDecodeError
- ? NS_ERROR_DOM_MEDIA_FATAL_ERR
- : NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
- mHitAudioDecodeError = false;
- } else {
- MOZ_ASSERT(false, "Dropping this promise on the floor");
- }
-
- return p;
-}
-
RefPtr<ShutdownPromise>
MediaDecoderReader::Shutdown()
{
MOZ_ASSERT(OnTaskQueue());
mShutdown = true;
mBaseAudioPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
mBaseVideoPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -117,32 +117,32 @@ public:
// Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
// on failure.
nsresult Init();
// Called by MDSM in dormant state to release resources allocated by this
// reader. The reader can resume decoding by calling Seek() to a specific
// position.
- virtual void ReleaseResources() { }
+ virtual void ReleaseResources() = 0;
// Destroys the decoding state. The reader cannot be made usable again.
// This is different from ReleaseMediaResources() as it is irreversable,
// whereas ReleaseMediaResources() is. Must be called on the decode
// thread.
virtual RefPtr<ShutdownPromise> Shutdown();
virtual bool OnTaskQueue() const
{
return OwnerThread()->IsCurrentThreadIn();
}
void UpdateDuration(const media::TimeUnit& aDuration);
- virtual void UpdateCompositor(already_AddRefed<layers::KnowsCompositor>) {}
+ virtual void UpdateCompositor(already_AddRefed<layers::KnowsCompositor>) = 0;
// Resets all state related to decoding, emptying all buffers etc.
// Cancels all pending Request*Data() request callbacks, rejects any
// outstanding seek promises, and flushes the decode pipeline. The
// decoder must not call any of the callbacks for outstanding
// Request*Data() calls after this is called. Calls to Request*Data()
// made after this should be processed as usual.
//
@@ -153,79 +153,71 @@ public:
virtual nsresult ResetDecode(
TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
TrackInfo::kVideoTrack));
// Requests one audio sample from the reader.
//
// The decode should be performed asynchronously, and the promise should
// be resolved when it is complete.
- virtual RefPtr<AudioDataPromise> RequestAudioData();
+ virtual RefPtr<AudioDataPromise> RequestAudioData() = 0;
// Requests one video sample from the reader.
virtual RefPtr<VideoDataPromise>
- RequestVideoData(const media::TimeUnit& aTimeThreshold);
+ RequestVideoData(const media::TimeUnit& aTimeThreshold) = 0;
// 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 bool IsWaitForDataSupported() const = 0;
- virtual RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType)
- {
- MOZ_CRASH();
- }
+ virtual RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType) = 0;
// The default implementation of AsyncReadMetadata is implemented in terms of
// synchronous ReadMetadata() calls. Implementations may also
// override AsyncReadMetadata to create a more proper async implementation.
- virtual RefPtr<MetadataPromise> AsyncReadMetadata();
+ virtual RefPtr<MetadataPromise> AsyncReadMetadata() = 0;
// Fills aInfo with the latest cached data required to present the media,
// ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
- virtual void ReadUpdatedMetadata(MediaInfo* aInfo) {}
+ virtual void ReadUpdatedMetadata(MediaInfo* aInfo) = 0;
// Moves the decode head to aTime microseconds.
virtual RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) = 0;
- virtual void SetCDMProxy(CDMProxy* aProxy) {}
+ virtual void SetCDMProxy(CDMProxy* aProxy) = 0;
// Tell the reader that the data decoded are not for direct playback, so it
// can accept more files, in particular those which have more channels than
// available in the audio output.
void SetIgnoreAudioOutputFormat()
{
mIgnoreAudioOutputFormat = true;
}
// The MediaDecoderStateMachine uses various heuristics that assume that
// raw media data is arriving sequentially from a network channel. This
// makes sense in the <video src="foo"> case, but not for more advanced use
// cases like MSE.
- virtual bool UseBufferingHeuristics() const { return true; }
+ virtual bool UseBufferingHeuristics() const = 0;
// Returns the number of bytes of memory allocated by structures/frames in
// the video queue.
size_t SizeOfVideoQueueInBytes() const;
// Returns the number of bytes of memory allocated by structures/frames in
// the audio queue.
size_t SizeOfAudioQueueInBytes() const;
virtual size_t SizeOfVideoQueueInFrames();
virtual size_t SizeOfAudioQueueInFrames();
// Called once new data has been cached by the MediaResource.
// mBuffered should be recalculated and updated accordingly.
- virtual void NotifyDataArrived()
- {
- MOZ_ASSERT(OnTaskQueue());
- NS_ENSURE_TRUE_VOID(!mShutdown);
- UpdateBuffered();
- }
+ virtual void NotifyDataArrived() = 0;
virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
AbstractCanonical<media::TimeIntervals>* CanonicalBuffered()
{
return &mBuffered;
}
@@ -234,21 +226,21 @@ public:
{
return mTaskQueue;
}
// Returns true if the reader implements RequestAudioData()
// and RequestVideoData() asynchronously, rather than using the
// implementation in this class to adapt the old synchronous to
// the newer async model.
- virtual bool IsAsync() const { return false; }
+ virtual bool IsAsync() const = 0;
// Returns true if this decoder reader uses hardware accelerated video
// decoding.
- virtual bool VideoIsHardwareAccelerated() const { return false; }
+ virtual bool VideoIsHardwareAccelerated() const = 0;
TimedMetadataEventSource& TimedMetadataEvent()
{
return mTimedMetadataEvent;
}
// Notified by the OggDemuxer during playback when chained ogg is detected.
MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
@@ -288,23 +280,23 @@ public:
MediaEventSource<MediaResult>& OnDecodeWarning()
{
return mOnDecodeWarning;
}
// Switch the video decoder to NullDecoderModule. It might takes effective
// since a few samples later depends on how much demuxed samples are already
// queued in the original video decoder.
- virtual void SetVideoNullDecode(bool aIsNullDecode) { }
+ virtual void SetVideoNullDecode(bool aIsNullDecode) = 0;
protected:
virtual ~MediaDecoderReader();
// Recomputes mBuffered.
- virtual void UpdateBuffered();
+ virtual void UpdateBuffered() = 0;
RefPtr<VideoDataPromise> DecodeToFirstVideoData();
// Queue of audio frames. This queue is threadsafe, and is accessed from
// the audio, decoder, state machine, and main threads.
MediaQueue<AudioData> mAudioQueue;
// Queue of video frames. This queue is threadsafe, and is accessed from
@@ -356,17 +348,17 @@ protected:
MediaEventProducer<void> mOnWaitingForKey;
MediaEventProducer<MediaResult> mOnDecodeWarning;
RefPtr<MediaResource> mResource;
private:
- virtual nsresult InitInternal() { return NS_OK; }
+ virtual nsresult InitInternal() = 0;
// Read header data for all bitstreams in the file. Fills aInfo with
// the data required to present the media, and optionally fills *aTags
// with tag metadata from the file.
// Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
virtual nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
{
MOZ_CRASH();