Bug 1364828 - Use nsTArray (with fallible append) in mp4_demuxer::ByteWriter - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Wed, 07 Jun 2017 14:21:09 +1200
changeset 589978 b14d2cf540239a7bd80b069df67706eb3d6084f7
parent 589954 5801aa478de12a62b2b2982659e787fcc4268d67
child 632056 bebf0250b12f3bc3e79dbf8be076775ed62f08ea
push id62560
push usergsquelart@mozilla.com
push dateWed, 07 Jun 2017 02:23:19 +0000
reviewersjya
bugs1364828
milestone55.0a1
Bug 1364828 - Use nsTArray (with fallible append) in mp4_demuxer::ByteWriter - r?jya mfbt's Vector is actually infallible by default, so it would crash in case of OOM. I'm switching to nsTArray, and using fallible AppendElements in ByteWriter. MozReview-Commit-ID: F7TBpCyIlg
media/libstagefright/binding/AnnexB.cpp
media/libstagefright/binding/include/mp4_demuxer/ByteWriter.h
--- a/media/libstagefright/binding/AnnexB.cpp
+++ b/media/libstagefright/binding/AnnexB.cpp
@@ -33,17 +33,17 @@ AnnexB::ConvertSampleToAnnexB(mozilla::M
 
   if (aSample->Size() < 4) {
     // Nothing to do, it's corrupted anyway.
     return true;
   }
 
   ByteReader reader(aSample->Data(), aSample->Size());
 
-  mozilla::Vector<uint8_t> tmp;
+  nsTArray<uint8_t> tmp;
   ByteWriter writer(tmp);
 
   while (reader.Remaining() >= 4) {
     uint32_t nalLen = reader.ReadU32();
     const uint8_t* p = reader.Read(nalLen);
 
     if (!writer.Write(kAnnexBDelimiter, ArrayLength(kAnnexBDelimiter))) {
       return false;
@@ -53,17 +53,17 @@ AnnexB::ConvertSampleToAnnexB(mozilla::M
     }
     if (!writer.Write(p, nalLen)) {
       return false;
     }
   }
 
   nsAutoPtr<MediaRawDataWriter> samplewriter(aSample->CreateWriter());
 
-  if (!samplewriter->Replace(tmp.begin(), tmp.length())) {
+  if (!samplewriter->Replace(tmp.Elements(), tmp.Length())) {
     return false;
   }
 
   // Prepend the Annex B NAL with SPS and PPS tables to keyframes.
   if (aAddSPS && aSample->mKeyframe) {
     RefPtr<MediaByteBuffer> annexB =
       ConvertExtraDataToAnnexB(aSample->mExtraData);
     if (!samplewriter->Prepend(annexB->Elements(), annexB->Length())) {
@@ -237,25 +237,25 @@ AnnexB::ConvertSampleToAVCC(mozilla::Med
   if (IsAVCC(aSample)) {
     return ConvertSampleTo4BytesAVCC(aSample);
   }
   if (!IsAnnexB(aSample)) {
     // Not AnnexB, nothing to convert.
     return true;
   }
 
-  mozilla::Vector<uint8_t> nalu;
+  nsTArray<uint8_t> nalu;
   ByteWriter writer(nalu);
   ByteReader reader(aSample->Data(), aSample->Size());
 
   if (!ParseNALUnits(writer, reader)) {
     return false;
   }
   nsAutoPtr<MediaRawDataWriter> samplewriter(aSample->CreateWriter());
-  if (!samplewriter->Replace(nalu.begin(), nalu.length())) {
+  if (!samplewriter->Replace(nalu.Elements(), nalu.Length())) {
     return false;
   }
   // Create the AVCC header.
   RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
   static const uint8_t kFakeExtraData[] = {
     1 /* version */,
     0x64 /* profile (High) */,
     0 /* profile compat (0) */,
@@ -274,21 +274,21 @@ AnnexB::ConvertSampleToAVCC(mozilla::Med
 already_AddRefed<mozilla::MediaByteBuffer>
 AnnexB::ExtractExtraData(const mozilla::MediaRawData* aSample)
 {
   MOZ_ASSERT(IsAVCC(aSample));
 
   RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
 
   // SPS content
-  mozilla::Vector<uint8_t> sps;
+  nsTArray<uint8_t> sps;
   ByteWriter spsw(sps);
   int numSps = 0;
   // PPS content
-  mozilla::Vector<uint8_t> pps;
+  nsTArray<uint8_t> pps;
   ByteWriter ppsw(pps);
   int numPps = 0;
 
   int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
 
   size_t sampleSize = aSample->Size();
   if (aSample->mCrypto.mValid) {
     // The content is encrypted, we can only parse the non-encrypted data.
@@ -328,27 +328,27 @@ AnnexB::ExtractExtraData(const mozilla::
       numPps++;
       if (!ppsw.WriteU16(nalLen)
           || !ppsw.Write(p, nalLen)) {
         return extradata.forget();
       }
     }
   }
 
-  if (numSps && sps.length() > 5) {
+  if (numSps && sps.Length() > 5) {
     extradata->AppendElement(1);        // version
     extradata->AppendElement(sps[3]);   // profile
     extradata->AppendElement(sps[4]);   // profile compat
     extradata->AppendElement(sps[5]);   // level
     extradata->AppendElement(0xfc | 3); // nal size - 1
     extradata->AppendElement(0xe0 | numSps);
-    extradata->AppendElements(sps.begin(), sps.length());
+    extradata->AppendElements(sps.Elements(), sps.Length());
     extradata->AppendElement(numPps);
     if (numPps) {
-      extradata->AppendElements(pps.begin(), pps.length());
+      extradata->AppendElements(pps.Elements(), pps.Length());
     }
   }
 
   return extradata.forget();
 }
 
 bool
 AnnexB::HasSPS(const mozilla::MediaRawData* aSample)
@@ -378,17 +378,17 @@ AnnexB::ConvertSampleTo4BytesAVCC(mozill
 {
   MOZ_ASSERT(IsAVCC(aSample));
 
   int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
 
   if (nalLenSize == 4) {
     return true;
   }
-  mozilla::Vector<uint8_t> dest;
+  nsTArray<uint8_t> dest;
   ByteWriter writer(dest);
   ByteReader reader(aSample->Data(), aSample->Size());
   while (reader.Remaining() > nalLenSize) {
     uint32_t nalLen;
     switch (nalLenSize) {
       case 1: nalLen = reader.ReadU8();  break;
       case 2: nalLen = reader.ReadU16(); break;
       case 3: nalLen = reader.ReadU24(); break;
@@ -399,17 +399,17 @@ AnnexB::ConvertSampleTo4BytesAVCC(mozill
       return true;
     }
     if (!writer.WriteU32(nalLen)
         || !writer.Write(p, nalLen)) {
       return false;
     }
   }
   nsAutoPtr<MediaRawDataWriter> samplewriter(aSample->CreateWriter());
-  return samplewriter->Replace(dest.begin(), dest.length());
+  return samplewriter->Replace(dest.Elements(), dest.Length());
 }
 
 bool
 AnnexB::IsAVCC(const mozilla::MediaRawData* aSample)
 {
   return aSample->Size() >= 3 && aSample->mExtraData &&
     aSample->mExtraData->Length() >= 7 && (*aSample->mExtraData)[0] == 1;
 }
--- a/media/libstagefright/binding/include/mp4_demuxer/ByteWriter.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/ByteWriter.h
@@ -1,25 +1,24 @@
 /* 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 BYTE_WRITER_H_
 #define BYTE_WRITER_H_
 
 #include "mozilla/EndianUtils.h"
-#include "mozilla/Vector.h"
 #include "nsTArray.h"
 
 namespace mp4_demuxer {
 
 class ByteWriter
 {
 public:
-  explicit ByteWriter(mozilla::Vector<uint8_t>& aData)
+  explicit ByteWriter(nsTArray<uint8_t>& aData)
     : mPtr(aData)
   {
   }
   ~ByteWriter()
   {
   }
 
   MOZ_MUST_USE bool WriteU8(uint8_t aByte)
@@ -59,18 +58,18 @@ public:
   {
     uint8_t c[8];
     mozilla::BigEndian::writeInt64(&c[0], aLongLong);
     return Write(&c[0], 8);
   }
 
   MOZ_MUST_USE bool Write(const uint8_t* aSrc, size_t aCount)
   {
-    return mPtr.append(aSrc, aCount);
+    return mPtr.AppendElements(aSrc, aCount, mozilla::fallible);
   }
 
 private:
-  mozilla::Vector<uint8_t>& mPtr;
+  nsTArray<uint8_t>& mPtr;
 };
 
 } // namespace mp4_demuxer
 
 #endif