Bug 1316211. P1 - make some functions pure virtual for they will be overridden by MFR. draft
authorJW Wang <jwwang@mozilla.com>
Wed, 19 Jul 2017 11:24:51 +0800
changeset 611835 603aaf9ca727aaf2aebb11513c06beb750ebf6d2
parent 611714 eb1d92b2b6a4161492561250f51bae5bafeda68a
child 611836 cad566abe4d511d19d8f0e4c38bf9e9ad0bf2858
push id69302
push userjwwang@mozilla.com
push dateThu, 20 Jul 2017 02:52:36 +0000
bugs1316211
milestone56.0a1
Bug 1316211. P1 - make some functions pure virtual for they will be overridden by MFR. MozReview-Commit-ID: 9l8MbDRjLR0
dom/media/MediaDecoderReader.cpp
dom/media/MediaDecoderReader.h
--- 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();