diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-07-22 17:49:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-22 17:49:14 +0200 |
commit | 72e628874a7b96d33fa550626be56e334dda50c8 (patch) | |
tree | fad6ef6a185545083e56c63983540186c0d51f8d /media/libstagefright/binding/include | |
parent | 14c53fcf71dbcae1472b4713817ac3851cd22b77 (diff) | |
parent | 0adebd32d9edaf37ef2396408d4fd76a9b255872 (diff) | |
download | UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar.gz UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar.lz UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar.xz UXP-72e628874a7b96d33fa550626be56e334dda50c8.zip |
Merge pull request #665 from trav90/media-work
Add some error handling when parsing MP4 files
Diffstat (limited to 'media/libstagefright/binding/include')
3 files changed, 248 insertions, 21 deletions
diff --git a/media/libstagefright/binding/include/mp4_demuxer/Box.h b/media/libstagefright/binding/include/mp4_demuxer/Box.h index f53404a1d..6612f6b49 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/Box.h +++ b/media/libstagefright/binding/include/mp4_demuxer/Box.h @@ -12,7 +12,7 @@ #include "MediaResource.h" #include "mozilla/EndianUtils.h" #include "mp4_demuxer/AtomType.h" -#include "mp4_demuxer/ByteReader.h" +#include "mp4_demuxer/BufferReader.h" using namespace mozilla; @@ -73,11 +73,11 @@ public: , mReader(mBuffer.Elements(), mBuffer.Length()) { } - ByteReader* operator->() { return &mReader; } + BufferReader* operator->() { return &mReader; } private: nsTArray<uint8_t> mBuffer; - ByteReader mReader; + BufferReader mReader; }; } diff --git a/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h b/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h new file mode 100644 index 000000000..160c97fa0 --- /dev/null +++ b/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h @@ -0,0 +1,225 @@ +/* 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 BUFFER_READER_H_ +#define BUFFER_READER_H_ + +#include "mozilla/EndianUtils.h" +#include "mozilla/Vector.h" +#include "nsTArray.h" +#include "MediaData.h" + +namespace mp4_demuxer { + +class MOZ_RAII BufferReader +{ +public: + BufferReader() : mPtr(nullptr), mRemaining(0) {} + explicit BufferReader(const mozilla::Vector<uint8_t>& aData) + : mPtr(aData.begin()), mRemaining(aData.length()), mLength(aData.length()) + { + } + BufferReader(const uint8_t* aData, size_t aSize) + : mPtr(aData), mRemaining(aSize), mLength(aSize) + { + } + template<size_t S> + explicit BufferReader(const AutoTArray<uint8_t, S>& aData) + : mPtr(aData.Elements()), mRemaining(aData.Length()), mLength(aData.Length()) + { + } + explicit BufferReader(const nsTArray<uint8_t>& aData) + : mPtr(aData.Elements()), mRemaining(aData.Length()), mLength(aData.Length()) + { + } + explicit BufferReader(const mozilla::MediaByteBuffer* aData) + : mPtr(aData->Elements()), mRemaining(aData->Length()), mLength(aData->Length()) + { + } + + void SetData(const nsTArray<uint8_t>& aData) + { + MOZ_ASSERT(!mPtr && !mRemaining); + mPtr = aData.Elements(); + mRemaining = aData.Length(); + mLength = mRemaining; + } + + ~BufferReader() + { + } + + size_t Offset() const + { + return mLength - mRemaining; + } + + size_t Remaining() const { return mRemaining; } + + bool CanRead8() const { return mRemaining >= 1; } + + bool ReadU8(uint8_t& aU8) + { + const uint8_t* ptr; + if (!Read(1, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + aU8 = *ptr; + return true; + } + + bool CanRead16() { return mRemaining >= 2; } + + bool ReadU16(uint16_t& u16) + { + const uint8_t* ptr; + if (!Read(2, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u16 = mozilla::BigEndian::readUint16(ptr); + return true; + } + + bool CanRead32() { return mRemaining >= 4; } + + bool ReadU32(uint32_t& u32) + { + const uint8_t* ptr; + if (!Read(4, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u32 = mozilla::BigEndian::readUint32(ptr); + return true; + } + + bool Read32(int32_t& i32) + { + const uint8_t* ptr; + if (!Read(4, &ptr)) { + NS_WARNING("Failed to read data"); + return 0; + } + i32 = mozilla::BigEndian::readInt32(ptr); + return true; + } + + bool ReadU64(uint64_t& u64) + { + const uint8_t* ptr; + if (!Read(8, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u64 = mozilla::BigEndian::readUint64(ptr); + return true; + } + + bool Read64(int64_t& i64) + { + const uint8_t* ptr; + if (!Read(8, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + i64 = mozilla::BigEndian::readInt64(ptr); + return true; + } + + bool ReadU24(uint32_t& u32) + { + const uint8_t* ptr; + if (!Read(3, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u32 = ptr[0] << 16 | ptr[1] << 8 | ptr[2]; + return true; + } + + bool Skip(size_t aCount) + { + const uint8_t* ptr; + if (!Read(aCount, &ptr)) { + NS_WARNING("Failed to skip data"); + return false; + } + return true; + } + + bool Read(size_t aCount, const uint8_t** aPtr) + { + if (aCount > mRemaining) { + mRemaining = 0; + return false; + } + mRemaining -= aCount; + + *aPtr = mPtr; + mPtr += aCount; + + return true; + } + + uint32_t Align() const + { + return 4 - ((intptr_t)mPtr & 3); + } + + template <typename T> bool CanReadType() const { return mRemaining >= sizeof(T); } + + template <typename T> T ReadType() + { + const uint8_t* ptr; + if (!Read(sizeof(T), &ptr)) { + NS_WARNING("ReadType failed"); + return 0; + } + return *reinterpret_cast<const T*>(ptr); + } + + template <typename T> + MOZ_MUST_USE bool ReadArray(nsTArray<T>& aDest, size_t aLength) + { + const uint8_t* ptr; + if (!Read(aLength * sizeof(T), &ptr)) { + NS_WARNING("ReadArray failed"); + return false; + } + + aDest.Clear(); + aDest.AppendElements(reinterpret_cast<const T*>(ptr), aLength); + return true; + } + + template <typename T> + MOZ_MUST_USE bool ReadArray(FallibleTArray<T>& aDest, size_t aLength) + { + const uint8_t* ptr; + if (!Read(aLength * sizeof(T), &ptr)) { + NS_WARNING("ReadArray failed"); + return false; + } + + aDest.Clear(); + if (!aDest.SetCapacity(aLength, mozilla::fallible)) { + return false; + } + MOZ_ALWAYS_TRUE(aDest.AppendElements(reinterpret_cast<const T*>(ptr), + aLength, + mozilla::fallible)); + return true; + } + +private: + const uint8_t* mPtr; + size_t mRemaining; + size_t mLength; +}; + +} // namespace mp4_demuxer + +#endif diff --git a/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h b/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h index 9c7df04bd..f316daa41 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h +++ b/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h @@ -63,7 +63,7 @@ public: { auto ptr = Read(1); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return *ptr; @@ -75,7 +75,7 @@ public: { auto ptr = Read(2); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readUint16(ptr); @@ -85,7 +85,7 @@ public: { auto ptr = Read(2); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::LittleEndian::readInt16(ptr); @@ -95,7 +95,7 @@ public: { auto ptr = Read(3); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; @@ -110,7 +110,7 @@ public: { auto ptr = Read(3); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } int32_t result = int32_t(ptr[2] << 16 | ptr[1] << 8 | ptr[0]); @@ -126,7 +126,7 @@ public: { auto ptr = Read(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readUint32(ptr); @@ -136,7 +136,7 @@ public: { auto ptr = Read(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readInt32(ptr); @@ -146,7 +146,7 @@ public: { auto ptr = Read(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readUint64(ptr); @@ -156,7 +156,7 @@ public: { auto ptr = Read(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readInt64(ptr); @@ -192,7 +192,7 @@ public: { auto ptr = Peek(1); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return *ptr; @@ -202,7 +202,7 @@ public: { auto ptr = Peek(2); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readUint16(ptr); @@ -212,7 +212,7 @@ public: { auto ptr = Peek(3); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; @@ -227,7 +227,7 @@ public: { auto ptr = Peek(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readUint32(ptr); @@ -237,7 +237,7 @@ public: { auto ptr = Peek(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readInt32(ptr); @@ -247,7 +247,7 @@ public: { auto ptr = Peek(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readUint64(ptr); @@ -257,7 +257,7 @@ public: { auto ptr = Peek(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readInt64(ptr); @@ -274,7 +274,7 @@ public: const uint8_t* Seek(size_t aOffset) { if (aOffset >= mLength) { - MOZ_ASSERT(false); + NS_WARNING("Seek failed"); return nullptr; } @@ -301,7 +301,7 @@ public: { auto ptr = Read(sizeof(T)); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("ReadType failed"); return 0; } return *reinterpret_cast<const T*>(ptr); @@ -312,6 +312,7 @@ public: { auto ptr = Read(aLength * sizeof(T)); if (!ptr) { + NS_WARNING("ReadArray failed"); return false; } @@ -325,6 +326,7 @@ public: { auto ptr = Read(aLength * sizeof(T)); if (!ptr) { + NS_WARNING("ReadArray failed"); return false; } |