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
--- 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