Bug 799344 - Un-templatify nsBuiltinDecoderReader::DecodeToFirstData() so that we don't need to know nsBuiltinDecoderStateMachine's interface in nsBuiltinDecoderReader.h. This means that nsBuiltinDecoderReader.h doesn't need to include nsBuiltinDecoderStateMachine.h when we move the state machine declaration from nsBuiltinDecoder.h to nsBuiltinDecoderStateMachine.h (in a later patch). nsBuiltinDecoderStateMachine.h needs to include nsBuiltinDecoderReader.h, so if nsBuiltinDecoderReader.h needed to include nsBuiltinDecoderStateMachine.h we'd have an include cycle, which is bad. r=roc
authorChris Pearce <cpearce@mozilla.com>
Wed, 07 Nov 2012 11:33:01 +1300
changeset 112764 325b40aaa768db062e479bc148edbde099ca930b
parent 112763 0af82e65292b88caf318983dc408609069b27401
child 112765 dee39125618290b7348f5dd62aa99e9c7fe450f5
push id17766
push usercpearce@mozilla.com
push dateFri, 09 Nov 2012 02:17:07 +0000
treeherdermozilla-inbound@b1b3cbf7a889 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs799344
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 799344 - Un-templatify nsBuiltinDecoderReader::DecodeToFirstData() so that we don't need to know nsBuiltinDecoderStateMachine's interface in nsBuiltinDecoderReader.h. This means that nsBuiltinDecoderReader.h doesn't need to include nsBuiltinDecoderStateMachine.h when we move the state machine declaration from nsBuiltinDecoder.h to nsBuiltinDecoderStateMachine.h (in a later patch). nsBuiltinDecoderStateMachine.h needs to include nsBuiltinDecoderReader.h, so if nsBuiltinDecoderReader.h needed to include nsBuiltinDecoderStateMachine.h we'd have an include cycle, which is bad. r=roc
content/media/dash/nsDASHReader.cpp
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderReader.h
content/media/nsBuiltinDecoderStateMachine.cpp
--- a/content/media/dash/nsDASHReader.cpp
+++ b/content/media/dash/nsDASHReader.cpp
@@ -269,28 +269,24 @@ nsDASHReader::FindStartTime(int64_t& aOu
   int64_t videoStartTime = INT64_MAX;
   int64_t audioStartTime = INT64_MAX;
   VideoData* videoData = nullptr;
 
   ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
                                          mDecoder->GetReentrantMonitor());
   if (HasVideo()) {
     // Forward to video reader.
-    videoData
-       = mVideoReader->DecodeToFirstData(&nsBuiltinDecoderReader::DecodeVideoFrame,
-                                         VideoQueue());
+    videoData = mVideoReader->DecodeToFirstVideoData();
     if (videoData) {
       videoStartTime = videoData->mTime;
     }
   }
   if (HasAudio()) {
     // Forward to audio reader.
-    AudioData* audioData
-        = mAudioReader->DecodeToFirstData(&nsBuiltinDecoderReader::DecodeAudioData,
-                                          AudioQueue());
+    AudioData* audioData = mAudioReader->DecodeToFirstAudioData();
     if (audioData) {
       audioStartTime = audioData->mTime;
     }
   }
 
   int64_t startTime = NS_MIN(videoStartTime, audioStartTime);
   if (startTime != INT64_MAX) {
     aOutStartTime = startTime;
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GonkIOSurfaceImage.h"
+#include "nsBuiltinDecoderReader.h"
 #include "nsBuiltinDecoder.h"
-#include "nsBuiltinDecoderReader.h"
 #include "nsBuiltinDecoderStateMachine.h"
 #include "VideoUtils.h"
 #include "ImageContainer.h"
 
 #include "mozilla/mozalloc.h"
 #include "mozilla/StandardInteger.h"
 
 using namespace mozilla;
@@ -337,37 +337,68 @@ nsresult nsBuiltinDecoderReader::ResetDe
   nsresult res = NS_OK;
 
   mVideoQueue.Reset();
   mAudioQueue.Reset();
 
   return res;
 }
 
+VideoData* nsBuiltinDecoderReader::DecodeToFirstVideoData()
+{
+  bool eof = false;
+  while (!eof && mVideoQueue.GetSize() == 0) {
+    {
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+      if (mDecoder->GetStateMachine()->IsShutdown()) {
+        return nullptr;
+      }
+    }
+    bool keyframeSkip = false;
+    eof = !DecodeVideoFrame(keyframeSkip, 0);
+  }
+  VideoData* d = nullptr;
+  return (d = mVideoQueue.PeekFront()) ? d : nullptr;
+}
+
+AudioData* nsBuiltinDecoderReader::DecodeToFirstAudioData()
+{
+  bool eof = false;
+  while (!eof && mAudioQueue.GetSize() == 0) {
+    {
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+      if (mDecoder->GetStateMachine()->IsShutdown()) {
+        return nullptr;
+      }
+    }
+    eof = !DecodeAudioData();
+  }
+  AudioData* d = nullptr;
+  return (d = mAudioQueue.PeekFront()) ? d : nullptr;
+}
+
 VideoData* nsBuiltinDecoderReader::FindStartTime(int64_t& aOutStartTime)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
   // Extract the start times of the bitstreams in order to calculate
   // the duration.
   int64_t videoStartTime = INT64_MAX;
   int64_t audioStartTime = INT64_MAX;
   VideoData* videoData = nullptr;
 
   if (HasVideo()) {
-    videoData = DecodeToFirstData(&nsBuiltinDecoderReader::DecodeVideoFrame,
-                                  mVideoQueue);
+    videoData = DecodeToFirstVideoData();
     if (videoData) {
       videoStartTime = videoData->mTime;
     }
   }
   if (HasAudio()) {
-    AudioData* audioData = DecodeToFirstData(&nsBuiltinDecoderReader::DecodeAudioData,
-                                             mAudioQueue);
+    AudioData* audioData = DecodeToFirstAudioData();
     if (audioData) {
       audioStartTime = audioData->mTime;
     }
   }
 
   int64_t startTime = NS_MIN(videoStartTime, audioStartTime);
   if (startTime != INT64_MAX) {
     aOutStartTime = startTime;
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -8,16 +8,20 @@
 
 #include <nsDeque.h>
 #include "nsSize.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "MediaStreamGraph.h"
 #include "SharedBuffer.h"
 #include "ImageLayers.h"
 #include "AudioSampleFormat.h"
+#include "MediaResource.h"
+#include "nsHTMLMediaElement.h"
+
+class nsBuiltinDecoder;
 
 // Stores info relevant to presenting media frames.
 class nsVideoInfo {
 public:
   nsVideoInfo()
     : mAudioRate(44100),
       mAudioChannels(2),
       mDisplay(0,0),
@@ -26,18 +30,18 @@ public:
       mHasVideo(false)
   {}
 
   // Returns true if it's safe to use aPicture as the picture to be
   // extracted inside a frame of size aFrame, and scaled up to and displayed
   // at a size of aDisplay. You should validate the frame, picture, and
   // display regions before using them to display video frames.
   static bool ValidateVideoRegion(const nsIntSize& aFrame,
-                                    const nsIntRect& aPicture,
-                                    const nsIntSize& aDisplay);
+                                  const nsIntRect& aPicture,
+                                  const nsIntSize& aDisplay);
 
   // Sample rate.
   uint32_t mAudioRate;
 
   // Number of audio channels.
   uint32_t mAudioChannels;
 
   // Size in pixels at which the video is rendered. This is after it has
@@ -223,22 +227,22 @@ template <class T> class MediaQueue : pr
    typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
    typedef mozilla::ReentrantMonitor ReentrantMonitor;
 
    MediaQueue()
      : nsDeque(new MediaQueueDeallocator<T>()),
        mReentrantMonitor("mediaqueue"),
        mEndOfStream(false)
    {}
-  
+
   ~MediaQueue() {
     Reset();
   }
 
-  inline int32_t GetSize() { 
+  inline int32_t GetSize() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return nsDeque::GetSize();
   }
 
   inline void Push(T* aItem) {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsDeque::Push(aItem);
   }
@@ -252,22 +256,22 @@ template <class T> class MediaQueue : pr
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::Pop());
   }
 
   inline T* PopFront() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::PopFront());
   }
-  
+
   inline T* Peek() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::Peek());
   }
-  
+
   inline T* PeekFront() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::PeekFront());
   }
 
   inline void Empty() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsDeque::Empty();
@@ -467,46 +471,18 @@ public:
   virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
   virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
 
   // Returns a pointer to the decoder.
   nsBuiltinDecoder* GetDecoder() {
     return mDecoder;
   }
 
-  // Reader decode function. Matches DecodeVideoFrame() and
-  // DecodeAudioData().
-  typedef bool (nsBuiltinDecoderReader::*DecodeFn)();
-
-  // Calls aDecodeFn on *this until aQueue has an item, whereupon
-  // we return the first item. Note: Inline defn. for external accessibility.
-  template<class Data>
-  Data* DecodeToFirstData(DecodeFn aDecodeFn,
-                          MediaQueue<Data>& aQueue)
-  {
-    bool eof = false;
-    while (!eof && aQueue.GetSize() == 0) {
-      {
-        ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
-        if (mDecoder->GetStateMachine()->IsShutdown()) {
-          return nullptr;
-        }
-      }
-      eof = !(this->*aDecodeFn)();
-    }
-    Data* d = nullptr;
-    return (d = aQueue.PeekFront()) ? d : nullptr;
-  }
-
-  // Wrapper so that DecodeVideoFrame(bool&,int64_t) can be called from
-  // DecodeToFirstData().
-  bool DecodeVideoFrame() {
-    bool f = false;
-    return DecodeVideoFrame(f, 0);
-  }
+  AudioData* DecodeToFirstAudioData();
+  VideoData* DecodeToFirstVideoData();
 
   // Sets range for initialization bytes; used by DASH.
   virtual void SetInitByteRange(MediaByteRange &aByteRange) { }
 
   // Sets range for index frame bytes; used by DASH.
   virtual void SetIndexByteRange(MediaByteRange &aByteRange) { }
 
   // Returns list of ranges for index frame start/end offsets. Used by DASH.
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -1,19 +1,19 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "nsBuiltinDecoderStateMachine.h"
 #include <limits>
 #include "nsAudioStream.h"
 #include "nsTArray.h"
 #include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderReader.h"
-#include "nsBuiltinDecoderStateMachine.h"
 #include "mozilla/mozalloc.h"
 #include "VideoUtils.h"
 #include "nsTimeRanges.h"
 #include "nsDeque.h"
 #include "AudioSegment.h"
 #include "VideoSegment.h"
 #include "ImageContainer.h"