Bug 1152658: Use MediaRawDataWriter to access MediaRawData::mCrypto. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 14 Apr 2015 15:15:46 +1000
changeset 257879 aab2b0807340e7078b77f325c5b018cbe55aec86
parent 257878 e17f5910da7539c9193518cab9d139559d7f2774
child 257880 818a69e48d385ef4df7e055d6910f4172a58b2c1
push id8007
push userraliiev@mozilla.com
push dateMon, 11 May 2015 19:23:16 +0000
treeherdermozilla-aurora@e2ce1aac996e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1152658
milestone40.0a1
Bug 1152658: Use MediaRawDataWriter to access MediaRawData::mCrypto. r=cpearce
dom/media/MediaData.cpp
dom/media/MediaData.h
dom/media/fmp4/eme/EMEDecoderModule.cpp
dom/media/gtest/TestMP4Demuxer.cpp
media/libstagefright/binding/Adts.cpp
media/libstagefright/binding/Index.cpp
media/libstagefright/binding/mp4_demuxer.cpp
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -483,25 +483,27 @@ VideoData::Create(VideoInfo& aInfo,
 #define RAW_DATA_ALIGNMENT 31U
 
 #define RAW_DATA_DEFAULT_SIZE 4096
 
 MediaRawData::MediaRawData()
   : MediaData(RAW_DATA)
   , mData(nullptr)
   , mSize(0)
+  , mCrypto(mCryptoInternal)
   , mBuffer(new LargeDataBuffer(RAW_DATA_DEFAULT_SIZE))
   , mPadding(0)
 {
 }
 
 MediaRawData::MediaRawData(const uint8_t* aData, size_t aSize)
   : MediaData(RAW_DATA)
   , mData(nullptr)
   , mSize(0)
+  , mCrypto(mCryptoInternal)
   , mBuffer(new LargeDataBuffer(RAW_DATA_DEFAULT_SIZE))
   , mPadding(0)
 {
   if (!EnsureCapacity(aSize)) {
     return;
   }
   mBuffer->AppendElements(aData, aSize);
   mBuffer->AppendElements(RAW_DATA_ALIGNMENT);
@@ -513,16 +515,17 @@ MediaRawData::Clone() const
 {
   nsRefPtr<MediaRawData> s = new MediaRawData;
   s->mTimecode = mTimecode;
   s->mTime = mTime;
   s->mDuration = mDuration;
   s->mOffset = mOffset;
   s->mKeyframe = mKeyframe;
   s->mExtraData = mExtraData;
+  s->mCryptoInternal = mCryptoInternal;
   if (mSize) {
     if (!s->EnsureCapacity(mSize)) {
       return nullptr;
     }
     s->mBuffer->AppendElements(mData, mSize);
     s->mBuffer->AppendElements(RAW_DATA_ALIGNMENT);
     s->mSize = mSize;
   }
@@ -579,16 +582,17 @@ MediaRawDataWriter*
 MediaRawData::CreateWriter()
 {
   return new MediaRawDataWriter(this);
 }
 
 MediaRawDataWriter::MediaRawDataWriter(MediaRawData* aMediaRawData)
   : mData(nullptr)
   , mSize(0)
+  , mCrypto(aMediaRawData->mCryptoInternal)
   , mTarget(aMediaRawData)
   , mBuffer(aMediaRawData->mBuffer.get())
 {
   if (aMediaRawData->mData) {
     mData = mBuffer->Elements() + mTarget->mPadding;
     mSize = mTarget->mSize;
   }
 }
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -344,16 +344,18 @@ class MediaRawData;
 
 class MediaRawDataWriter
 {
 public:
   // Pointer to data or null if not-yet allocated
   uint8_t* mData;
   // Writeable size of buffer.
   size_t mSize;
+  // Writeable reference to MediaRawData::mCryptoInternal
+  CryptoSample& mCrypto;
 
   // Data manipulation methods. mData and mSize may be updated accordingly.
 
   // Set size of buffer, allocating memory as required.
   // If size is increased, new buffer area is filled with 0.
   bool SetSize(size_t aSize);
   // Add aData at the beginning of buffer.
   bool Prepend(const uint8_t* aData, size_t aSize);
@@ -375,17 +377,17 @@ public:
   MediaRawData();
   MediaRawData(const uint8_t* aData, size_t mSize);
 
   // Pointer to data or null if not-yet allocated
   const uint8_t* mData;
   // Size of buffer.
   size_t mSize;
 
-  CryptoSample mCrypto;
+  const CryptoSample& mCrypto;
   nsRefPtr<DataBuffer> mExtraData;
 
   // Return a deep copy or nullptr if out of memory.
   virtual already_AddRefed<MediaRawData> Clone() const;
   // Create a MediaRawDataWriter for this MediaRawData. The caller must
   // delete the writer once done. The writer is not thread-safe.
   virtual MediaRawDataWriter* CreateWriter();
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
@@ -397,16 +399,17 @@ private:
   friend class MediaRawDataWriter;
   // Ensure that the backend buffer can hold aSize data. Will update mData.
   // Will enforce that the start of allocated data is always 32 bytes
   // aligned and that it has sufficient end padding to allow for 32 bytes block
   // read as required by some data decoders.
   // Returns false if memory couldn't be allocated.
   bool EnsureCapacity(size_t aSize);
   nsRefPtr<LargeDataBuffer> mBuffer;
+  CryptoSample mCryptoInternal;
   uint32_t mPadding;
   MediaRawData(const MediaRawData&); // Not implemented
 };
 
   // LargeDataBuffer is a ref counted fallible TArray.
   // It is designed to share potentially big byte arrays.
 class LargeDataBuffer : public FallibleTArray<uint8_t> {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LargeDataBuffer);
--- a/dom/media/fmp4/eme/EMEDecoderModule.cpp
+++ b/dom/media/fmp4/eme/EMEDecoderModule.cpp
@@ -86,18 +86,19 @@ public:
     // for keys to become usable, and once they do we need to dispatch an event
     // to run the PDM on the same task queue, but since the decode task queue
     // is waiting in MP4Reader::Decode() for output our task would never run.
     // So we dispatch tasks to make all calls into the wrapped decoder.
     if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
       return NS_OK;
     }
 
+    nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
     mProxy->GetSessionIdsForKeyId(aSample->mCrypto.mKeyId,
-                                  aSample->mCrypto.mSessionIds);
+                                  writer->mCrypto.mSessionIds);
 
     mProxy->Decrypt(aSample, new DeliverDecrypted(this, mTaskQueue));
     return NS_OK;
   }
 
   void Decrypted(MediaRawData* aSample) {
     MOZ_ASSERT(!mIsShutdown);
     nsresult rv = mTaskQueue->Dispatch(
@@ -181,18 +182,19 @@ private:
 
 nsresult
 EMEMediaDataDecoderProxy::Input(MediaRawData* aSample)
 {
   if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
     return NS_OK;
   }
 
+  nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
   mProxy->GetSessionIdsForKeyId(aSample->mCrypto.mKeyId,
-                                aSample->mCrypto.mSessionIds);
+                                writer->mCrypto.mSessionIds);
 
   return MediaDataDecoderProxy::Input(aSample);
 }
 
 nsresult
 EMEMediaDataDecoderProxy::Shutdown()
 {
   nsresult rv = MediaDataDecoderProxy::Shutdown();
--- a/dom/media/gtest/TestMP4Demuxer.cpp
+++ b/dom/media/gtest/TestMP4Demuxer.cpp
@@ -59,17 +59,17 @@ TEST(MP4Demuxer, Seek)
     }
     d->SeekVideo(samples[i]->mTime);
     sample = d->DemuxVideoSample();
     EXPECT_EQ(keyFrame, sample->mTimecode);
   }
 }
 
 static nsCString
-ToCryptoString(CryptoSample& aCrypto)
+ToCryptoString(const CryptoSample& aCrypto)
 {
   nsCString res;
   if (aCrypto.mValid) {
     res.AppendPrintf("%d %d ", aCrypto.mMode, aCrypto.mIVSize);
     for (size_t i = 0; i < aCrypto.mKeyId.Length(); i++) {
       res.AppendPrintf("%02x", aCrypto.mKeyId[i]);
     }
     res.Append(" ");
--- a/media/libstagefright/binding/Adts.cpp
+++ b/media/libstagefright/binding/Adts.cpp
@@ -58,18 +58,18 @@ Adts::ConvertSample(uint16_t aChannelCou
 
   nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
   if (!writer->Prepend(&header[0], ArrayLength(header))) {
     return false;
   }
 
   if (aSample->mCrypto.mValid) {
     if (aSample->mCrypto.mPlainSizes.Length() == 0) {
-      aSample->mCrypto.mPlainSizes.AppendElement(kADTSHeaderSize);
-      aSample->mCrypto.mEncryptedSizes.AppendElement(aSample->mSize - kADTSHeaderSize);
+      writer->mCrypto.mPlainSizes.AppendElement(kADTSHeaderSize);
+      writer->mCrypto.mEncryptedSizes.AppendElement(aSample->mSize - kADTSHeaderSize);
     } else {
-      aSample->mCrypto.mPlainSizes[0] += kADTSHeaderSize;
+      writer->mCrypto.mPlainSizes[0] += kADTSHeaderSize;
     }
   }
 
   return true;
 }
 }
--- a/media/libstagefright/binding/Index.cpp
+++ b/media/libstagefright/binding/Index.cpp
@@ -122,38 +122,38 @@ already_AddRefed<MediaRawData> SampleIte
     // The size comes from an 8 bit field
     nsAutoTArray<uint8_t, 256> cenc;
     cenc.SetLength(s->mCencRange.Length());
     if (!mIndex->mSource->ReadAt(s->mCencRange.mStart, cenc.Elements(), cenc.Length(),
                                  &bytesRead) || bytesRead != cenc.Length()) {
       return nullptr;
     }
     ByteReader reader(cenc);
-    sample->mCrypto.mValid = true;
-    sample->mCrypto.mIVSize = ivSize;
+    writer->mCrypto.mValid = true;
+    writer->mCrypto.mIVSize = ivSize;
 
-    if (!reader.ReadArray(sample->mCrypto.mIV, ivSize)) {
+    if (!reader.ReadArray(writer->mCrypto.mIV, ivSize)) {
       return nullptr;
     }
 
     if (reader.CanRead16()) {
       uint16_t count = reader.ReadU16();
 
       if (reader.Remaining() < count * 6) {
         return nullptr;
       }
 
       for (size_t i = 0; i < count; i++) {
-        sample->mCrypto.mPlainSizes.AppendElement(reader.ReadU16());
-        sample->mCrypto.mEncryptedSizes.AppendElement(reader.ReadU32());
+        writer->mCrypto.mPlainSizes.AppendElement(reader.ReadU16());
+        writer->mCrypto.mEncryptedSizes.AppendElement(reader.ReadU32());
       }
     } else {
       // No subsample information means the entire sample is encrypted.
-      sample->mCrypto.mPlainSizes.AppendElement(0);
-      sample->mCrypto.mEncryptedSizes.AppendElement(sample->mSize);
+      writer->mCrypto.mPlainSizes.AppendElement(0);
+      writer->mCrypto.mEncryptedSizes.AppendElement(sample->mSize);
     }
   }
 
   Next();
 
   return sample.forget();
 }
 
--- a/media/libstagefright/binding/mp4_demuxer.cpp
+++ b/media/libstagefright/binding/mp4_demuxer.cpp
@@ -217,37 +217,39 @@ MP4Demuxer::DemuxAudioSample()
 {
   mMonitor->AssertCurrentThreadOwns();
   if (!mPrivate->mAudioIterator) {
     return nullptr;
   }
   nsRefPtr<mozilla::MediaRawData> sample(mPrivate->mAudioIterator->GetNext());
   if (sample) {
     if (sample->mCrypto.mValid) {
-      sample->mCrypto.mMode = mAudioConfig.crypto.mMode;
-      sample->mCrypto.mIVSize = mAudioConfig.crypto.mIVSize;
-      sample->mCrypto.mKeyId.AppendElements(mAudioConfig.crypto.mKeyId);
+      nsAutoPtr<MediaRawDataWriter> writer(sample->CreateWriter());
+      writer->mCrypto.mMode = mAudioConfig.crypto.mMode;
+      writer->mCrypto.mIVSize = mAudioConfig.crypto.mIVSize;
+      writer->mCrypto.mKeyId.AppendElements(mAudioConfig.crypto.mKeyId);
     }
   }
   return sample.forget();
 }
 
 already_AddRefed<MediaRawData>
 MP4Demuxer::DemuxVideoSample()
 {
   mMonitor->AssertCurrentThreadOwns();
   if (!mPrivate->mVideoIterator) {
     return nullptr;
   }
   nsRefPtr<mozilla::MediaRawData> sample(mPrivate->mVideoIterator->GetNext());
   if (sample) {
     sample->mExtraData = mVideoConfig.extra_data;
     if (sample->mCrypto.mValid) {
-      sample->mCrypto.mMode = mVideoConfig.crypto.mMode;
-      sample->mCrypto.mKeyId.AppendElements(mVideoConfig.crypto.mKeyId);
+      nsAutoPtr<MediaRawDataWriter> writer(sample->CreateWriter());
+      writer->mCrypto.mMode = mVideoConfig.crypto.mMode;
+      writer->mCrypto.mKeyId.AppendElements(mVideoConfig.crypto.mKeyId);
     }
     if (sample->mTime >= mNextKeyframeTime) {
       mNextKeyframeTime = mPrivate->mVideoIterator->GetNextKeyframeTime();
     }
   }
   return sample.forget();
 }