Bug 936352 - Media Recording - Fix wrong pointer usage in encoder module from Bug 919905. r=roc
authorRandy Lin <rlin@mozilla.com>
Sun, 10 Nov 2013 06:30:01 +0800
changeset 154427 8156dd4fdf96424a2d21d1c244824d9251518495
parent 154426 4eea9a74a8bb134174f88a4cb00d0b2b7329005f
child 154428 535c1520bc3e55af6374e2f1001d4531da44ce3e
push id36083
push userryanvm@gmail.com
push dateMon, 11 Nov 2013 20:55:33 +0000
treeherdermozilla-inbound@fcc73e099a0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs936352, 919905
milestone28.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 936352 - Media Recording - Fix wrong pointer usage in encoder module from Bug 919905. r=roc
content/media/encoder/ContainerWriter.h
content/media/encoder/EncodedFrameContainer.h
content/media/encoder/OpusTrackEncoder.cpp
content/media/encoder/OpusTrackEncoder.h
content/media/encoder/TrackEncoder.h
content/media/ogg/OggWriter.cpp
content/media/ogg/OggWriter.h
--- a/content/media/encoder/ContainerWriter.h
+++ b/content/media/encoder/ContainerWriter.h
@@ -37,17 +37,17 @@ public:
                                      uint32_t aFlags = 0) = 0;
 
   /**
    * Set the meta data pointer into muxer
    * This function will check the integrity of aMetadata.
    * If the meta data isn't well format, this function will return NS_ERROR_FAILURE to caller,
    * else save the pointer to mMetadata and return NS_OK.
    */
-  virtual nsresult SetMetadata(nsRefPtr<TrackMetadataBase> aMetadata) = 0;
+  virtual nsresult SetMetadata(TrackMetadataBase* aMetadata) = 0;
 
   enum {
     FLUSH_NEEDED = 1 << 0,
     GET_HEADER = 1 << 1
   };
 
   /**
    * Copies the final container data to a buffer if it has accumulated enough
@@ -56,13 +56,12 @@ public:
    * aFlags is true with FLUSH_NEEDED will force OggWriter to flush an ogg page
    * even it is not full, and copy these container data to a buffer for
    * aOutputBufs to append.
    */
   virtual nsresult GetContainerData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
                                     uint32_t aFlags = 0) = 0;
 
 protected:
-  nsRefPtr<TrackMetadataBase> mMetadata;
   bool mInitialized;
 };
 }
 #endif
--- a/content/media/encoder/EncodedFrameContainer.h
+++ b/content/media/encoder/EncodedFrameContainer.h
@@ -21,29 +21,30 @@ class EncodedFrameContainer
 {
 public:
   // Append encoded frame data
   void AppendEncodedFrame(EncodedFrame* aEncodedFrame)
   {
     mEncodedFrames.AppendElement(aEncodedFrame);
   }
   // Retrieve all of the encoded frames
-  const nsTArray<nsAutoPtr<EncodedFrame> >& GetEncodedFrames() const
+  const nsTArray<nsRefPtr<EncodedFrame> >& GetEncodedFrames() const
   {
     return mEncodedFrames;
   }
 private:
   // This container is used to store the video or audio encoded packets.
   // Muxer should check mFrameType and get the encoded data type from mEncodedFrames.
-  nsTArray<nsAutoPtr<EncodedFrame> > mEncodedFrames;
+  nsTArray<nsRefPtr<EncodedFrame> > mEncodedFrames;
 };
 
 // Represent one encoded frame
 class EncodedFrame
 {
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EncodedFrame)
 public:
   EncodedFrame() :
     mTimeStamp(0),
     mDuration(0),
     mFrameType(UNKNOW)
   {}
   enum FrameType {
     I_FRAME,      // intraframe
--- a/content/media/encoder/OpusTrackEncoder.cpp
+++ b/content/media/encoder/OpusTrackEncoder.cpp
@@ -181,32 +181,32 @@ OpusTrackEncoder::GetOutputSampleRate()
 }
 
 int
 OpusTrackEncoder::GetPacketDuration()
 {
   return GetOutputSampleRate() * kFrameDurationMs / 1000;
 }
 
-nsRefPtr<TrackMetadataBase>
+already_AddRefed<TrackMetadataBase>
 OpusTrackEncoder::GetMetadata()
 {
   {
     // Wait if mEncoder is not initialized.
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     while (!mCanceled && !mEncoder) {
       mReentrantMonitor.Wait();
     }
   }
 
   if (mCanceled || mDoneEncoding) {
     return nullptr;
   }
 
-  OpusMetadata* meta = new OpusMetadata();
+  nsRefPtr<OpusMetadata> meta = new OpusMetadata();
 
   mLookahead = 0;
   int error = opus_encoder_ctl(mEncoder, OPUS_GET_LOOKAHEAD(&mLookahead));
   if (error != OPUS_OK) {
     mLookahead = 0;
   }
 
   // The ogg time stamping and pre-skip is always timed at 48000.
@@ -217,17 +217,17 @@ OpusTrackEncoder::GetMetadata()
   vendor.AppendASCII(opus_get_version_string());
 
   nsTArray<nsCString> comments;
   comments.AppendElement(NS_LITERAL_CSTRING("ENCODER=Mozilla" MOZ_APP_UA_VERSION));
 
   SerializeOpusCommentHeader(vendor, comments,
                              &meta->mCommentHeader);
 
-  return meta;
+  return meta.forget();
 }
 
 nsresult
 OpusTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
 {
   {
     // Move all the samples from mRawSegment to mSourceSegment. We only hold
     // the monitor in this block.
@@ -276,17 +276,17 @@ OpusTrackEncoder::GetEncodedTrack(Encode
       memset(pcm.Elements() + frameCopied * mChannels, 0,
              frameToCopy * mChannels * sizeof(AudioDataValue));
     }
 
     frameCopied += frameToCopy;
     iter.Next();
   }
 
-  EncodedFrame* audiodata = new EncodedFrame();
+  nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
   audiodata->SetFrameType(EncodedFrame::AUDIO_FRAME);
   if (mResampler) {
     nsAutoTArray<AudioDataValue, 9600> resamplingDest;
     // We want to consume all the input data, so we slightly oversize the
     // resampled data buffer so we can fit the output data in. We cannot really
     // predict the output frame count at each call.
     uint32_t outframes = frameCopied * kOpusSamplingRate / mSamplingRate + 1;
     uint32_t inframes = frameCopied;
--- a/content/media/encoder/OpusTrackEncoder.h
+++ b/content/media/encoder/OpusTrackEncoder.h
@@ -27,17 +27,17 @@ public:
 };
 
 class OpusTrackEncoder : public AudioTrackEncoder
 {
 public:
   OpusTrackEncoder();
   virtual ~OpusTrackEncoder();
 
-  nsRefPtr<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
+  already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
 
   nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE;
 
 protected:
   int GetPacketDuration() MOZ_OVERRIDE;
 
   nsresult Init(int aChannels, int aSamplingRate) MOZ_OVERRIDE;
 
--- a/content/media/encoder/TrackEncoder.h
+++ b/content/media/encoder/TrackEncoder.h
@@ -47,17 +47,17 @@ public:
    * Notified by the same callback of MediaEncoder when it has been removed from
    * MediaStreamGraph. Called on the MediaStreamGraph thread.
    */
   virtual void NotifyRemoved(MediaStreamGraph* aGraph) = 0;
 
   /**
    * Creates and sets up meta data for a specific codec
    */
-  virtual nsRefPtr<TrackMetadataBase> GetMetadata() = 0;
+  virtual already_AddRefed<TrackMetadataBase> GetMetadata() = 0;
 
   /**
    * Encodes raw segments. Result data is returned in aData.
    */
   virtual nsresult GetEncodedTrack(EncodedFrameContainer& aData) = 0;
 };
 
 class AudioTrackEncoder : public TrackEncoder
--- a/content/media/ogg/OggWriter.cpp
+++ b/content/media/ogg/OggWriter.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* 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 "OggWriter.h"
 #include "prtime.h"
-#include "OpusTrackEncoder.h"
 
 #undef LOG
 #ifdef MOZ_WIDGET_GONK
 #include <android/log.h>
 #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediaEncoder", ## args);
 #else
 #define LOG(args, ...)
 #endif
@@ -163,30 +162,29 @@ OggWriter::GetContainerData(nsTArray<nsT
   if (rc) {
     ProduceOggPage(aOutputBufs);
   }
 
   return (rc > 0) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
-OggWriter::SetMetadata(nsRefPtr<TrackMetadataBase> aMetadata)
+OggWriter::SetMetadata(TrackMetadataBase* aMetadata)
 {
   if (aMetadata->GetKind() != TrackMetadataBase::METADATA_OPUS) {
     LOG("wrong meta data type!");
     return NS_ERROR_FAILURE;
   }
   // Validate each field of METADATA
-  OpusMetadata* meta = static_cast<OpusMetadata*>(aMetadata.get());
-  if (meta->mIdHeader.Length() == 0) {
+  mMetadata = static_cast<OpusMetadata*>(aMetadata);
+  if (mMetadata->mIdHeader.Length() == 0) {
     LOG("miss mIdHeader!");
     return NS_ERROR_FAILURE;
   }
-  if (meta->mCommentHeader.Length() == 0) {
+  if (mMetadata->mCommentHeader.Length() == 0) {
     LOG("miss mCommentHeader!");
     return NS_ERROR_FAILURE;
   }
 
-  mMetadata = aMetadata;
   return NS_OK;
 }
 
 }
--- a/content/media/ogg/OggWriter.h
+++ b/content/media/ogg/OggWriter.h
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #ifndef OggWriter_h_
 #define OggWriter_h_
 
 #include "ContainerWriter.h"
+#include "OpusTrackEncoder.h"
 #include <ogg/ogg.h>
 
 namespace mozilla {
 /**
  * WriteEncodedTrack inserts raw packets into Ogg stream (ogg_stream_state), and
  * GetContainerData outputs an ogg_page when enough packets have been written
  * to the Ogg stream.
  * For more details, please reference:
@@ -24,24 +25,26 @@ public:
 
   nsresult WriteEncodedTrack(const EncodedFrameContainer &aData,
                              uint32_t aFlags = 0) MOZ_OVERRIDE;
 
   nsresult GetContainerData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
                             uint32_t aFlags = 0) MOZ_OVERRIDE;
 
   // Check metadata type integrity and reject unacceptable track encoder.
-  nsresult SetMetadata(nsRefPtr<TrackMetadataBase> aMetadata) MOZ_OVERRIDE;
+  nsresult SetMetadata(TrackMetadataBase* aMetadata) MOZ_OVERRIDE;
 
 private:
   nsresult Init();
 
   nsresult WriteEncodedData(const nsTArray<uint8_t>& aBuffer, int aDuration,
                             uint32_t aFlags = 0);
 
   void ProduceOggPage(nsTArray<nsTArray<uint8_t> >* aOutputBufs);
+  // Store the Medatata from track encoder
+  nsRefPtr<OpusMetadata> mMetadata;
 
   ogg_stream_state mOggStreamState;
   ogg_page mOggPage;
   ogg_packet mPacket;
 };
 }
 #endif