Bug 1127656 - Remove class inheritance hierarchy from gonk PlatformDeocdeModule. r=ajones
authorAlfredo Yang <ayang>
Mon, 04 May 2015 19:34:00 +0200
changeset 242322 b41ebad8dbe7290febcfff30d038cb2f5fc4e328
parent 242321 c5d30567f41915f45a4864472b9ee030241ce1e8
child 242323 1163109f289589484509b584a58927141d98a173
push id59376
push usercbook@mozilla.com
push dateTue, 05 May 2015 07:09:04 +0000
treeherdermozilla-inbound@1163109f2895 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajones
bugs1127656
milestone40.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 1127656 - Remove class inheritance hierarchy from gonk PlatformDeocdeModule. r=ajones
dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp
dom/media/fmp4/gonk/GonkAudioDecoderManager.h
dom/media/fmp4/gonk/GonkDecoderModule.cpp
dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
dom/media/fmp4/gonk/GonkMediaDataDecoder.h
dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp
dom/media/fmp4/gonk/GonkVideoDecoderManager.h
--- a/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp
+++ b/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp
@@ -33,25 +33,23 @@ PRLogModuleInfo* GetDemuxerLog();
 #endif
 #define READ_OUTPUT_BUFFER_TIMEOUT_US  3000
 
 using namespace android;
 typedef android::MediaCodecProxy MediaCodecProxy;
 
 namespace mozilla {
 
-GonkAudioDecoderManager::GonkAudioDecoderManager(
-  MediaTaskQueue* aTaskQueue,
-  const AudioInfo& aConfig)
-  : GonkDecoderManager(aTaskQueue)
-  , mAudioChannels(aConfig.mChannels)
+GonkAudioDecoderManager::GonkAudioDecoderManager(const AudioInfo& aConfig)
+  : mAudioChannels(aConfig.mChannels)
   , mAudioRate(aConfig.mRate)
   , mAudioProfile(aConfig.mProfile)
   , mUseAdts(true)
   , mAudioBuffer(nullptr)
+  , mMonitor("GonkAudioDecoderManager")
 {
   MOZ_COUNT_CTOR(GonkAudioDecoderManager);
   MOZ_ASSERT(mAudioChannels);
   mCodecSpecificData = aConfig.mCodecSpecificConfig;
   mMimeType = aConfig.mMimeType;
 
   // Pass through mp3 without applying an ADTS header.
   if (!aConfig.mMimeType.EqualsLiteral("audio/mp4a-latm")) {
@@ -106,23 +104,63 @@ GonkAudioDecoderManager::Init(MediaDataD
   if (rv == OK) {
     return mDecoder;
   } else {
     GADM_LOG("Failed to input codec specific data!");
     return nullptr;
   }
 }
 
-status_t
-GonkAudioDecoderManager::SendSampleToOMX(MediaRawData* aSample)
+bool
+GonkAudioDecoderManager::HasQueuedSample()
+{
+    MonitorAutoLock mon(mMonitor);
+    return mQueueSample.Length();
+}
+
+nsresult
+GonkAudioDecoderManager::Input(MediaRawData* aSample)
 {
-  return mDecoder->Input(reinterpret_cast<const uint8_t*>(aSample->mData),
-                         aSample->mSize,
-                         aSample->mTime,
-                         0);
+  MonitorAutoLock mon(mMonitor);
+  nsRefPtr<MediaRawData> sample;
+
+  if (aSample) {
+    sample = aSample;
+    if (!PerformFormatSpecificProcess(sample)) {
+      return NS_ERROR_FAILURE;
+    }
+  } else {
+    // It means EOS with empty sample.
+    sample = new MediaRawData();
+  }
+
+  mQueueSample.AppendElement(sample);
+
+  status_t rv;
+  while (mQueueSample.Length()) {
+    nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
+    {
+      MonitorAutoUnlock mon_exit(mMonitor);
+      rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->mData),
+                           data->mSize,
+                           data->mTime,
+                           0);
+    }
+    if (rv == OK) {
+      mQueueSample.RemoveElementAt(0);
+    } else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
+      // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
+      // buffer on time.
+      return NS_OK;
+    } else {
+      return NS_ERROR_UNEXPECTED;
+    }
+  }
+
+  return NS_OK;
 }
 
 bool
 GonkAudioDecoderManager::PerformFormatSpecificProcess(MediaRawData* aSample)
 {
   if (aSample && mUseAdts) {
     int8_t frequency_index =
         mp4_demuxer::Adts::GetFrequencyIndex(mAudioRate);
@@ -178,16 +216,31 @@ GonkAudioDecoderManager::CreateAudioData
                                                 mAudioChannels,
                                                 mAudioRate);
   ReleaseAudioBuffer();
   audioData.forget(v);
   return NS_OK;
 }
 
 nsresult
+GonkAudioDecoderManager::Flush()
+{
+  {
+    MonitorAutoLock mon(mMonitor);
+    mQueueSample.Clear();
+  }
+
+  if (mDecoder->flush() != OK) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+nsresult
 GonkAudioDecoderManager::Output(int64_t aStreamOffset,
                                 nsRefPtr<MediaData>& aOutData)
 {
   aOutData = nullptr;
   status_t err;
   err = mDecoder->Output(&mAudioBuffer, READ_OUTPUT_BUFFER_TIMEOUT_US);
 
   switch (err) {
@@ -253,20 +306,9 @@ GonkAudioDecoderManager::Output(int64_t 
 }
 
 void GonkAudioDecoderManager::ReleaseAudioBuffer() {
   if (mAudioBuffer) {
     mDecoder->ReleaseMediaBuffer(mAudioBuffer);
     mAudioBuffer = nullptr;
   }
 }
-
-nsresult
-GonkAudioDecoderManager::Flush()
-{
-  GonkDecoderManager::Flush();
-  status_t err = mDecoder->flush();
-  if (err != OK) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
 } // namespace mozilla
--- a/dom/media/fmp4/gonk/GonkAudioDecoderManager.h
+++ b/dom/media/fmp4/gonk/GonkAudioDecoderManager.h
@@ -18,46 +18,55 @@ struct MOZ_EXPORT ALooper;
 class MOZ_EXPORT MediaBuffer;
 } // namespace android
 
 namespace mozilla {
 
 class GonkAudioDecoderManager : public GonkDecoderManager {
 typedef android::MediaCodecProxy MediaCodecProxy;
 public:
-  GonkAudioDecoderManager(MediaTaskQueue* aTaskQueue,
-                          const AudioInfo& aConfig);
-  ~GonkAudioDecoderManager();
+  GonkAudioDecoderManager(const AudioInfo& aConfig);
+
+  virtual ~GonkAudioDecoderManager() override;
 
   virtual android::sp<MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) override;
 
+  virtual nsresult Input(MediaRawData* aSample) override;
+
   virtual nsresult Output(int64_t aStreamOffset,
                           nsRefPtr<MediaData>& aOutput) override;
 
   virtual nsresult Flush() override;
 
-protected:
-  virtual bool PerformFormatSpecificProcess(MediaRawData* aSample) override;
-
-  virtual status_t SendSampleToOMX(MediaRawData* aSample) override;
+  virtual bool HasQueuedSample() override;
 
 private:
+  bool PerformFormatSpecificProcess(MediaRawData* aSample);
 
   nsresult CreateAudioData(int64_t aStreamOffset,
                               AudioData** aOutData);
 
   void ReleaseAudioBuffer();
-  // MediaCodedc's wrapper that performs the decoding.
-  android::sp<MediaCodecProxy> mDecoder;
 
   const uint32_t mAudioChannels;
   const uint32_t mAudioRate;
   const uint32_t mAudioProfile;
   bool mUseAdts;
 
   MediaDataDecoderCallback*  mReaderCallback;
   android::MediaBuffer* mAudioBuffer;
   android::sp<ALooper> mLooper;
+
+  // MediaCodedc's wrapper that performs the decoding.
+  android::sp<android::MediaCodecProxy> mDecoder;
+
+  // This monitor protects mQueueSample.
+  Monitor mMonitor;
+
+  // An queue with the MP4 samples which are waiting to be sent into OMX.
+  // If an element is an empty MP4Sample, that menas EOS. There should not
+  // any sample be queued after EOS.
+  nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
 };
 
 } // namespace mozilla
 
 #endif // GonkAudioDecoderManager_h_
--- a/dom/media/fmp4/gonk/GonkDecoderModule.cpp
+++ b/dom/media/fmp4/gonk/GonkDecoderModule.cpp
@@ -29,29 +29,28 @@ GonkDecoderModule::Init()
 already_AddRefed<MediaDataDecoder>
 GonkDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig,
                                      mozilla::layers::LayersBackend aLayersBackend,
                                      mozilla::layers::ImageContainer* aImageContainer,
                                      FlushableMediaTaskQueue* aVideoTaskQueue,
                                      MediaDataDecoderCallback* aCallback)
 {
   nsRefPtr<MediaDataDecoder> decoder =
-  new GonkMediaDataDecoder(new GonkVideoDecoderManager(aVideoTaskQueue,
-                                                       aImageContainer, aConfig),
+  new GonkMediaDataDecoder(new GonkVideoDecoderManager(aImageContainer, aConfig),
                            aVideoTaskQueue, aCallback);
   return decoder.forget();
 }
 
 already_AddRefed<MediaDataDecoder>
 GonkDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig,
                                       FlushableMediaTaskQueue* aAudioTaskQueue,
                                       MediaDataDecoderCallback* aCallback)
 {
   nsRefPtr<MediaDataDecoder> decoder =
-  new GonkMediaDataDecoder(new GonkAudioDecoderManager(aAudioTaskQueue, aConfig),
+  new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig),
                            aAudioTaskQueue, aCallback);
   return decoder.forget();
 }
 
 PlatformDecoderModule::ConversionRequired
 GonkDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
 {
   if (aConfig.IsVideo()) {
--- a/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
+++ b/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
@@ -20,68 +20,16 @@ PRLogModuleInfo* GetDemuxerLog();
 #else
 #define LOG(...)
 #endif
 
 using namespace android;
 
 namespace mozilla {
 
-GonkDecoderManager::GonkDecoderManager(MediaTaskQueue* aTaskQueue)
-  : mMonitor("GonkDecoderManager")
-{
-}
-
-nsresult
-GonkDecoderManager::Input(MediaRawData* aSample)
-{
-  ReentrantMonitorAutoEnter mon(mMonitor);
-  nsRefPtr<MediaRawData> sample;
-
-  if (!aSample) {
-    // It means EOS with empty sample.
-    sample = new MediaRawData();
-  } else {
-    sample = aSample;
-    if (!PerformFormatSpecificProcess(sample)) {
-      return NS_ERROR_FAILURE;
-    }
-  }
-
-  mQueueSample.AppendElement(sample);
-
-  status_t rv;
-  while (mQueueSample.Length()) {
-    nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
-    {
-      ReentrantMonitorAutoExit mon_exit(mMonitor);
-      rv = SendSampleToOMX(data);
-    }
-    if (rv == OK) {
-      mQueueSample.RemoveElementAt(0);
-    } else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
-      // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
-      // buffer on time.
-      return NS_OK;
-    } else {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
-GonkDecoderManager::Flush()
-{
-  ReentrantMonitorAutoEnter mon(mMonitor);
-  mQueueSample.Clear();
-  return NS_OK;
-}
-
 GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
                                            FlushableMediaTaskQueue* aTaskQueue,
                                            MediaDataDecoderCallback* aCallback)
   : mTaskQueue(aTaskQueue)
   , mCallback(aCallback)
   , mManager(aManager)
   , mSignaledEOS(false)
   , mDrainComplete(false)
--- a/dom/media/fmp4/gonk/GonkMediaDataDecoder.h
+++ b/dom/media/fmp4/gonk/GonkMediaDataDecoder.h
@@ -14,63 +14,41 @@ class MediaCodecProxy;
 } // namespace android
 
 namespace mozilla {
 class MediaRawData;
 
 // Manage the data flow from inputting encoded data and outputting decode data.
 class GonkDecoderManager {
 public:
-  GonkDecoderManager(MediaTaskQueue* aTaskQueue);
-
   virtual ~GonkDecoderManager() {}
 
   // Creates and initializs the GonkDecoder.
   // Returns nullptr on failure.
   virtual android::sp<android::MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) = 0;
 
   // Add samples into OMX decoder or queue them if decoder is out of input buffer.
-  virtual nsresult Input(MediaRawData* aSample);
+  virtual nsresult Input(MediaRawData* aSample) = 0;
 
   // Produces decoded output, it blocks until output can be produced or a timeout
   // is expired or until EOS. Returns NS_OK on success, or NS_ERROR_NOT_AVAILABLE
   // if there's not enough data to produce more output. If this returns a failure
   // code other than NS_ERROR_NOT_AVAILABLE, an error will be reported to the
   // MP4Reader.
   // The overrided class should follow the same behaviour.
   virtual nsresult Output(int64_t aStreamOffset,
                           nsRefPtr<MediaData>& aOutput) = 0;
 
   // Flush the queued sample.
-  // It this function is overrided by subclass, this functino should be called
-  // in the overrided function.
-  virtual nsresult Flush();
+  virtual nsresult Flush() = 0;
 
-  // It should be called in MediaTask thread.
-  bool HasQueuedSample() {
-    ReentrantMonitorAutoEnter mon(mMonitor);
-    return mQueueSample.Length();
-  }
+  // True if sample is queued.
+  virtual bool HasQueuedSample() = 0;
 
 protected:
-  // It performs special operation to MP4 sample, the real action is depended on
-  // the codec type.
-  virtual bool PerformFormatSpecificProcess(MediaRawData* aSample) { return true; }
-
-  // It sends MP4Sample to OMX layer. It must be overrided by subclass.
-  virtual android::status_t SendSampleToOMX(MediaRawData* aSample) = 0;
-
-  // This monitor protects mQueueSample.
-  ReentrantMonitor mMonitor;
-
-  // An queue with the MP4 samples which are waiting to be sent into OMX.
-  // If an element is an empty MP4Sample, that menas EOS. There should not
-  // any sample be queued after EOS.
-  nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
-
   nsRefPtr<MediaByteBuffer> mCodecSpecificData;
 
   nsAutoCString mMimeType;
 };
 
 // Samples are decoded using the GonkDecoder (MediaCodec)
 // created by the GonkDecoderManager. This class implements
 // the higher-level logic that drives mapping the Gonk to the async
--- a/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp
+++ b/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp
@@ -39,26 +39,25 @@ PRLogModuleInfo* GetDemuxerLog();
 #endif
 using namespace mozilla::layers;
 using namespace android;
 typedef android::MediaCodecProxy MediaCodecProxy;
 
 namespace mozilla {
 
 GonkVideoDecoderManager::GonkVideoDecoderManager(
-  MediaTaskQueue* aTaskQueue,
   mozilla::layers::ImageContainer* aImageContainer,
   const VideoInfo& aConfig)
-  : GonkDecoderManager(aTaskQueue)
-  , mImageContainer(aImageContainer)
+  : mImageContainer(aImageContainer)
   , mReaderCallback(nullptr)
   , mLastDecodedTime(0)
   , mColorConverterBufferSize(0)
   , mNativeWindow(nullptr)
   , mPendingVideoBuffersLock("GonkVideoDecoderManager::mPendingVideoBuffersLock")
+  , mMonitor("GonkVideoDecoderManager")
 {
   MOZ_COUNT_CTOR(GonkVideoDecoderManager);
   mMimeType = aConfig.mMimeType;
   mVideoWidth  = aConfig.mDisplay.width;
   mVideoHeight = aConfig.mDisplay.height;
   mDisplayWidth = aConfig.mDisplay.width;
   mDisplayHeight = aConfig.mDisplay.height;
   mInfo.mVideo = aConfig;
@@ -113,16 +112,62 @@ GonkVideoDecoderManager::Init(MediaDataD
       MediaCodecProxy::kCanExposeGraphicBuffer)) {
     mNativeWindow = new GonkNativeWindow();
   }
 
   return mDecoder;
 }
 
 nsresult
+GonkVideoDecoderManager::Input(MediaRawData* aSample)
+{
+  MonitorAutoLock mon(mMonitor);
+  nsRefPtr<MediaRawData> sample;
+
+  if (!aSample) {
+    // It means EOS with empty sample.
+    sample = new MediaRawData();
+  } else {
+    sample = aSample;
+  }
+
+  mQueueSample.AppendElement(sample);
+
+  status_t rv;
+  while (mQueueSample.Length()) {
+    nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
+    {
+      MonitorAutoUnlock mon_unlock(mMonitor);
+      rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->mData),
+                           data->mSize,
+                           data->mTime,
+                           0);
+    }
+    if (rv == OK) {
+      mQueueSample.RemoveElementAt(0);
+    } else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
+      // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
+      // buffer on time.
+      return NS_OK;
+    } else {
+      return NS_ERROR_UNEXPECTED;
+    }
+  }
+
+  return NS_OK;
+}
+
+bool
+GonkVideoDecoderManager::HasQueuedSample()
+{
+    MonitorAutoLock mon(mMonitor);
+    return mQueueSample.Length();
+}
+
+nsresult
 GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v)
 {
   *v = nullptr;
   nsRefPtr<VideoData> data;
   int64_t timeUs;
   int32_t keyFrame;
 
   if (mVideoBuffer == nullptr) {
@@ -300,16 +345,33 @@ GonkVideoDecoderManager::SetVideoFormat(
       return false;
     }
     return true;
   }
   GVDM_LOG("Fail to get output format");
   return false;
 }
 
+nsresult
+GonkVideoDecoderManager::Flush()
+{
+  {
+    MonitorAutoLock mon(mMonitor);
+    mQueueSample.Clear();
+  }
+
+ mLastDecodedTime = 0;
+
+  if (mDecoder->flush() != OK) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
 // Blocks until decoded sample is produced by the deoder.
 nsresult
 GonkVideoDecoderManager::Output(int64_t aStreamOffset,
                                 nsRefPtr<MediaData>& aOutData)
 {
   aOutData = nullptr;
   status_t err;
   if (mDecoder == nullptr) {
@@ -388,37 +450,16 @@ GonkVideoDecoderManager::Output(int64_t 
 
 void GonkVideoDecoderManager::ReleaseVideoBuffer() {
   if (mVideoBuffer) {
     mDecoder->ReleaseMediaBuffer(mVideoBuffer);
     mVideoBuffer = nullptr;
   }
 }
 
-status_t
-GonkVideoDecoderManager::SendSampleToOMX(MediaRawData* aSample)
-{
-  return mDecoder->Input(reinterpret_cast<const uint8_t*>(aSample->mData),
-                         aSample->mSize,
-                         aSample->mTime,
-                         0);
-}
-
-nsresult
-GonkVideoDecoderManager::Flush()
-{
-  GonkDecoderManager::Flush();
-  mLastDecodedTime = 0;
-  status_t err = mDecoder->flush();
-  if (err != OK) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
 void
 GonkVideoDecoderManager::codecReserved()
 {
   GVDM_LOG("codecReserved");
   sp<AMessage> format = new AMessage;
   sp<Surface> surface;
   status_t rv = OK;
   // Fixed values
@@ -569,17 +610,9 @@ void GonkVideoDecoderManager::ReleaseAll
     android::MediaBuffer *buffer;
     buffer = releasingVideoBuffers[i];
     mDecoder->ReleaseMediaBuffer(buffer);
     buffer = nullptr;
   }
   releasingVideoBuffers.clear();
 }
 
-void GonkVideoDecoderManager::ReleaseMediaResources() {
-  GVDM_LOG("ReleseMediaResources");
-  if (mDecoder == nullptr) {
-    return;
-  }
-  ReleaseAllPendingVideoBuffers();
-  mDecoder->ReleaseMediaResources();
-}
 } // namespace mozilla
--- a/dom/media/fmp4/gonk/GonkVideoDecoderManager.h
+++ b/dom/media/fmp4/gonk/GonkVideoDecoderManager.h
@@ -33,36 +33,34 @@ namespace layers {
 class TextureClient;
 } // namespace mozilla::layers
 
 class GonkVideoDecoderManager : public GonkDecoderManager {
 typedef android::MediaCodecProxy MediaCodecProxy;
 typedef mozilla::layers::TextureClient TextureClient;
 
 public:
-  GonkVideoDecoderManager(MediaTaskQueue* aTaskQueue,
-                          mozilla::layers::ImageContainer* aImageContainer,
+  GonkVideoDecoderManager(mozilla::layers::ImageContainer* aImageContainer,
                           const VideoInfo& aConfig);
 
-  ~GonkVideoDecoderManager();
+  virtual ~GonkVideoDecoderManager() override;
 
   virtual android::sp<MediaCodecProxy> Init(MediaDataDecoderCallback* aCallback) override;
 
+  virtual nsresult Input(MediaRawData* aSample) override;
+
   virtual nsresult Output(int64_t aStreamOffset,
                           nsRefPtr<MediaData>& aOutput) override;
 
   virtual nsresult Flush() override;
 
-  virtual void ReleaseMediaResources();
+  virtual bool HasQueuedSample() override;
 
   static void RecycleCallback(TextureClient* aClient, void* aClosure);
 
-protected:
-  virtual android::status_t SendSampleToOMX(MediaRawData* aSample) override;
-
 private:
   struct FrameInfo
   {
     int32_t mWidth = 0;
     int32_t mHeight = 0;
     int32_t mStride = 0;
     int32_t mSliceHeight = 0;
     int32_t mColorFormat = 0;
@@ -124,17 +122,16 @@ private:
 
   uint32_t mVideoWidth;
   uint32_t mVideoHeight;
   uint32_t mDisplayWidth;
   uint32_t mDisplayHeight;
   nsIntRect mPicture;
   nsIntSize mInitialFrame;
 
-  android::sp<MediaCodecProxy> mDecoder;
   nsRefPtr<layers::ImageContainer> mImageContainer;
 
   android::MediaBuffer* mVideoBuffer;
 
   MediaDataDecoderCallback*  mReaderCallback;
   MediaInfo mInfo;
   android::sp<VideoResourceListener> mVideoListener;
   android::sp<MessageHandler> mHandler;
@@ -155,13 +152,23 @@ private:
   };
 
   // Hold video's MediaBuffers that are released.
   // The holded MediaBuffers are released soon after flush.
   Vector<android::MediaBuffer*> mPendingVideoBuffers;
   // The lock protects mPendingVideoBuffers.
   Mutex mPendingVideoBuffersLock;
 
+  // MediaCodedc's wrapper that performs the decoding.
+  android::sp<android::MediaCodecProxy> mDecoder;
+
+  // This monitor protects mQueueSample.
+  Monitor mMonitor;
+
+  // An queue with the MP4 samples which are waiting to be sent into OMX.
+  // If an element is an empty MP4Sample, that menas EOS. There should not
+  // any sample be queued after EOS.
+  nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
 };
 
 } // namespace mozilla
 
 #endif // GonkVideoDecoderManager_h_