summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-09-04 20:53:31 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-09-04 20:53:31 +0200
commit580084e9e1d0355c96a54a9641df6c1fee894948 (patch)
tree5aff416b5aed2ca9e326054567d837f28c20ed25 /media
parentfc61780b35af913801d72086456f493f63197da6 (diff)
parentb28ab55f9675f2e97dda9a4fcac0d4f5267a2bb9 (diff)
downloadUXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar.gz
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar.lz
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar.xz
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.zip
Merge branch 'master' into Basilisk-releasev2018.09.05
Diffstat (limited to 'media')
-rw-r--r--media/ffvpx/README_MCP7
-rw-r--r--media/libstagefright/binding/Index.cpp64
-rw-r--r--media/libstagefright/binding/MoofParser.cpp479
-rw-r--r--media/libstagefright/binding/SinfParser.cpp24
-rw-r--r--media/libstagefright/binding/include/mp4_demuxer/Box.h6
-rw-r--r--media/libstagefright/binding/include/mp4_demuxer/BufferReader.h225
-rw-r--r--media/libstagefright/binding/include/mp4_demuxer/ByteReader.h38
-rw-r--r--media/libstagefright/binding/include/mp4_demuxer/Index.h3
-rw-r--r--media/libstagefright/binding/include/mp4_demuxer/MoofParser.h55
-rw-r--r--media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp1
-rw-r--r--media/libstagefright/moz.build1
-rwxr-xr-xmedia/webrtc/signaling/src/media-conduit/AudioConduit.cpp9
-rw-r--r--media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp8
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp109
-rw-r--r--media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp16
15 files changed, 800 insertions, 245 deletions
diff --git a/media/ffvpx/README_MCP b/media/ffvpx/README_MCP
index 4555e08da..5ed4d8d94 100644
--- a/media/ffvpx/README_MCP
+++ b/media/ffvpx/README_MCP
@@ -7,10 +7,6 @@ Currently, we only use the vp8 and vp9 portion of the library, and only on x86
based platforms. If this changes, configuration files will most likely
need to be updated.
-AVX2 must be disabled on Linux 32 bits due to the use of yasm 1.1 on the build bots.
-Once yasm is upgraded to 1.2 or later, AVX2 code could be re-enabled.
-Add --disable-avx2 to configure on those platforms.
-
configuration files were generated as follow using the configure script:
./configure --disable-everything --disable-protocols --disable-demuxers --disable-muxers --disable-filters --disable-programs --disable-doc --disable-parsers --enable-parser=vp8 --enable-parser=vp9 --enable-decoder=vp8 --enable-decoder=vp9 --disable-static --enable-shared --disable-debug --disable-sdl2 --disable-libxcb --disable-securetransport --disable-iconv --disable-swresample --disable-swscale --disable-avdevice --disable-avfilter --disable-avformat --disable-d3d11va --disable-dxva2 --disable-vaapi --disable-vda --disable-vdpau --disable-videotoolbox --enable-decoder=flac --enable-asm --enable-x86asm
@@ -18,13 +14,12 @@ config*:
replace: /HAVE_(MALLOC_H|ARC4RANDOM|LOCALTIME_R|MEMALIGN|POSIX_MEMALIGN)/d
config_darwin32.h:
-add to configure command: --disable-asm --disable-yasm --cc='clang -m32'
+add to configure command: --disable-asm --disable-x86asm --cc='clang -m32'
config_unix32.h:
add to configure command: --disable-asm --disable-x86asm --cc='clang -m32'
replace: s/HAVE_SYSCTL 1/HAVE_SYSCTL 0/ and s/HAVE_MEMALIGN 1/HAVE_MEMALIGN 0/ and s/HAVE_POSIX_MEMALIGN 1/HAVE_POSIX_MEMALIGN 0/
-
config_unix32.h/config_unix64.h/config_unix64.asm:
replace: s/HAVE_SYSCTL 1/HAVE_SYSCTL 0
diff --git a/media/libstagefright/binding/Index.cpp b/media/libstagefright/binding/Index.cpp
index 9d6ab5028..eb039b5d6 100644
--- a/media/libstagefright/binding/Index.cpp
+++ b/media/libstagefright/binding/Index.cpp
@@ -143,6 +143,11 @@ already_AddRefed<MediaRawData> SampleIterator::GetNext()
writer->mCrypto.mValid = true;
writer->mCrypto.mIVSize = ivSize;
+ CencSampleEncryptionInfoEntry* sampleInfo = GetSampleEncryptionEntry();
+ if (sampleInfo) {
+ writer->mCrypto.mKeyId.AppendElements(sampleInfo->mKeyId);
+ }
+
if (!reader.ReadArray(writer->mCrypto.mIV, ivSize)) {
return nullptr;
}
@@ -170,6 +175,65 @@ already_AddRefed<MediaRawData> SampleIterator::GetNext()
return sample.forget();
}
+CencSampleEncryptionInfoEntry* SampleIterator::GetSampleEncryptionEntry()
+{
+ nsTArray<Moof>& moofs = mIndex->mMoofParser->Moofs();
+ Moof* currentMoof = &moofs[mCurrentMoof];
+ SampleToGroupEntry* sampleToGroupEntry = nullptr;
+
+ // Default to using the sample to group entries for the fragment, otherwise
+ // fall back to the sample to group entries for the track.
+ nsTArray<SampleToGroupEntry>* sampleToGroupEntries =
+ currentMoof->mFragmentSampleToGroupEntries.Length() != 0
+ ? &currentMoof->mFragmentSampleToGroupEntries
+ : &mIndex->mMoofParser->mTrackSampleToGroupEntries;
+
+ uint32_t seen = 0;
+
+ for (SampleToGroupEntry& entry : *sampleToGroupEntries) {
+ if (seen + entry.mSampleCount > mCurrentSample) {
+ sampleToGroupEntry = &entry;
+ break;
+ }
+ seen += entry.mSampleCount;
+ }
+
+ // ISO-14496-12 Section 8.9.2.3 and 8.9.4 : group description index
+ // (1) ranges from 1 to the number of sample group entries in the track
+ // level SampleGroupDescription Box, or (2) takes the value 0 to
+ // indicate that this sample is a member of no group, in this case, the
+ // sample is associated with the default values specified in
+ // TrackEncryption Box, or (3) starts at 0x10001, i.e. the index value
+ // 1, with the value 1 in the top 16 bits, to reference fragment-local
+ // SampleGroupDescription Box.
+
+ // According to the spec, ISO-14496-12, the sum of the sample counts in this
+ // box should be equal to the total number of samples, and, if less, the
+ // reader should behave as if an extra SampleToGroupEntry existed, with
+ // groupDescriptionIndex 0.
+
+ if (!sampleToGroupEntry || sampleToGroupEntry->mGroupDescriptionIndex == 0) {
+ return nullptr;
+ }
+
+ nsTArray<CencSampleEncryptionInfoEntry>* entries =
+ &mIndex->mMoofParser->mTrackSampleEncryptionInfoEntries;
+
+ uint32_t groupIndex = sampleToGroupEntry->mGroupDescriptionIndex;
+
+ // If the first bit is set to a one, then we should use the sample group
+ // descriptions from the fragment.
+ if (groupIndex > SampleToGroupEntry::kFragmentGroupDescriptionIndexBase) {
+ groupIndex -= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase;
+ entries = &currentMoof->mFragmentSampleEncryptionInfoEntries;
+ }
+
+ // The group_index is one based.
+ return groupIndex > entries->Length()
+ ? nullptr
+ : &entries->ElementAt(groupIndex - 1);
+}
+
Sample* SampleIterator::Get()
{
if (!mIndex->mMoofParser) {
diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp
index ced054282..771be3428 100644
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -27,6 +27,8 @@ namespace mp4_demuxer
using namespace stagefright;
using namespace mozilla;
+const uint32_t kKeyIdSize = 16;
+
bool
MoofParser::RebuildFragmentedIndex(const MediaByteRangeSet& aByteRanges)
{
@@ -330,6 +332,18 @@ MoofParser::ParseStbl(Box& aBox)
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("stsd")) {
ParseStsd(box);
+ } else if (box.IsType("sgpd")) {
+ Sgpd sgpd(box);
+ if (sgpd.IsValid() && sgpd.mGroupingType == "seig") {
+ mTrackSampleEncryptionInfoEntries.Clear();
+ mTrackSampleEncryptionInfoEntries.AppendElements(sgpd.mEntries);
+ }
+ } else if (box.IsType("sbgp")) {
+ Sbgp sbgp(box);
+ if (sbgp.IsValid() && sbgp.mGroupingType == "seig") {
+ mTrackSampleToGroupEntries.Clear();
+ mTrackSampleToGroupEntries.AppendElements(sbgp.mEntries);
+ }
}
}
}
@@ -495,12 +509,25 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, S
MOZ_ASSERT(aDecodeTime);
Tfhd tfhd(aTrex);
Tfdt tfdt;
+
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("tfhd")) {
tfhd = Tfhd(box, aTrex);
} else if (!aTrex.mTrackId || tfhd.mTrackId == aTrex.mTrackId) {
if (box.IsType("tfdt")) {
tfdt = Tfdt(box);
+ } else if (box.IsType("sgpd")) {
+ Sgpd sgpd(box);
+ if (sgpd.IsValid() && sgpd.mGroupingType == "seig") {
+ mFragmentSampleEncryptionInfoEntries.Clear();
+ mFragmentSampleEncryptionInfoEntries.AppendElements(sgpd.mEntries);
+ }
+ } else if (box.IsType("sbgp")) {
+ Sbgp sbgp(box);
+ if (sbgp.IsValid() && sbgp.mGroupingType == "seig") {
+ mFragmentSampleToGroupEntries.Clear();
+ mFragmentSampleToGroupEntries.AppendElements(sbgp.mEntries);
+ }
} else if (box.IsType("saiz")) {
mSaizs.AppendElement(Saiz(box, aSinf.mDefaultEncryptionType));
} else if (box.IsType("saio")) {
@@ -550,14 +577,20 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u
LOG(Moof, "Incomplete Box (missing flags)");
return false;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return false;
+ }
uint8_t version = flags >> 24;
if (!reader->CanReadType<uint32_t>()) {
LOG(Moof, "Incomplete Box (missing sampleCount)");
return false;
}
- uint32_t sampleCount = reader->ReadU32();
+ uint32_t sampleCount;
+ if (!reader->ReadU32(sampleCount)) {
+ return false;
+ }
if (sampleCount == 0) {
return true;
}
@@ -577,9 +610,21 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u
return false;
}
- uint64_t offset = aTfhd.mBaseDataOffset + (flags & 1 ? reader->ReadU32() : 0);
- uint32_t firstSampleFlags =
- flags & 4 ? reader->ReadU32() : aTfhd.mDefaultSampleFlags;
+ uint64_t offset = aTfhd.mBaseDataOffset;
+ if (flags & 1) {
+ uint32_t baseOffset;
+ if (!reader->ReadU32(baseOffset)) {
+ return false;
+ }
+ offset += baseOffset;
+ }
+ uint32_t firstSampleFlags = aTfhd.mDefaultSampleFlags;
+ if (flags & 4) {
+ if (!reader->ReadU32(firstSampleFlags)) {
+ return false;
+ }
+ }
+
uint64_t decodeTime = *aDecodeTime;
nsTArray<Interval<Microseconds>> timeRanges;
@@ -589,16 +634,29 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u
}
for (size_t i = 0; i < sampleCount; i++) {
- uint32_t sampleDuration =
- flags & 0x100 ? reader->ReadU32() : aTfhd.mDefaultSampleDuration;
- uint32_t sampleSize =
- flags & 0x200 ? reader->ReadU32() : aTfhd.mDefaultSampleSize;
- uint32_t sampleFlags =
- flags & 0x400 ? reader->ReadU32()
- : i ? aTfhd.mDefaultSampleFlags : firstSampleFlags;
+ uint32_t sampleDuration = aTfhd.mDefaultSampleDuration;
+ if (flags & 0x100) {
+ if (!reader->ReadU32(sampleDuration)) {
+ return false;
+ }
+ }
+ uint32_t sampleSize = aTfhd.mDefaultSampleSize;
+ if (flags & 0x200) {
+ if (!reader->ReadU32(sampleSize)) {
+ return false;
+ }
+ }
+ uint32_t sampleFlags = i ? aTfhd.mDefaultSampleFlags : firstSampleFlags;
+ if (flags & 0x400) {
+ if (!reader->ReadU32(sampleFlags)) {
+ return false;
+ }
+ }
int32_t ctsOffset = 0;
if (flags & 0x800) {
- ctsOffset = reader->Read32();
+ if (!reader->Read32(ctsOffset)) {
+ return false;
+ }
}
Sample sample;
@@ -635,7 +693,10 @@ Tkhd::Tkhd(Box& aBox)
LOG(Tkhd, "Incomplete Box (missing flags)");
return;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
uint8_t version = flags >> 24;
size_t need =
3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(int32_t);
@@ -645,19 +706,30 @@ Tkhd::Tkhd(Box& aBox)
return;
}
if (version == 0) {
- mCreationTime = reader->ReadU32();
- mModificationTime = reader->ReadU32();
- mTrackId = reader->ReadU32();
- uint32_t reserved = reader->ReadU32();
+ uint32_t createTime, modificationTime, trackId, reserved, duration;
+ if (!reader->ReadU32(createTime) ||
+ !reader->ReadU32(modificationTime) ||
+ !reader->ReadU32(trackId) ||
+ !reader->ReadU32(reserved) ||
+ !reader->ReadU32(duration)) {
+ return;
+ }
NS_ASSERTION(!reserved, "reserved should be 0");
- mDuration = reader->ReadU32();
+ mCreationTime = createTime;
+ mModificationTime = modificationTime;
+ mTrackId = trackId;
+ mDuration = duration;
} else if (version == 1) {
- mCreationTime = reader->ReadU64();
- mModificationTime = reader->ReadU64();
- mTrackId = reader->ReadU32();
- uint32_t reserved = reader->ReadU32();
+ uint32_t trackId, reserved;
+ if (!reader->ReadU64(mCreationTime) ||
+ !reader->ReadU64(mModificationTime) ||
+ !reader->ReadU32(trackId) ||
+ !reader->ReadU32(reserved) ||
+ !reader->ReadU64(mDuration)) {
+ return;
+ }
NS_ASSERTION(!reserved, "reserved should be 0");
- mDuration = reader->ReadU64();
+ mTrackId = trackId;
}
// We don't care about whatever else may be in the box.
mValid = true;
@@ -670,10 +742,13 @@ Mvhd::Mvhd(Box& aBox)
LOG(Mdhd, "Incomplete Box (missing flags)");
return;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
uint8_t version = flags >> 24;
size_t need =
- 3*(version ? sizeof(int64_t) : sizeof(int32_t)) + sizeof(uint32_t);
+ 3 * (version ? sizeof(int64_t) : sizeof(int32_t)) + sizeof(uint32_t);
if (reader->Remaining() < need) {
LOG(Mvhd, "Incomplete Box (have:%lld need:%lld)",
(uint64_t)reader->Remaining(), (uint64_t)need);
@@ -681,15 +756,23 @@ Mvhd::Mvhd(Box& aBox)
}
if (version == 0) {
- mCreationTime = reader->ReadU32();
- mModificationTime = reader->ReadU32();
- mTimescale = reader->ReadU32();
- mDuration = reader->ReadU32();
+ uint32_t createTime, modificationTime, duration;
+ if (!reader->ReadU32(createTime) ||
+ !reader->ReadU32(modificationTime) ||
+ !reader->ReadU32(mTimescale) ||
+ !reader->ReadU32(duration)) {
+ return;
+ }
+ mCreationTime = createTime;
+ mModificationTime = modificationTime;
+ mDuration = duration;
} else if (version == 1) {
- mCreationTime = reader->ReadU64();
- mModificationTime = reader->ReadU64();
- mTimescale = reader->ReadU32();
- mDuration = reader->ReadU64();
+ if (!reader->ReadU64(mCreationTime) ||
+ !reader->ReadU64(mModificationTime) ||
+ !reader->ReadU32(mTimescale) ||
+ !reader->ReadU64(mDuration)) {
+ return;
+ }
} else {
return;
}
@@ -707,18 +790,19 @@ Mdhd::Mdhd(Box& aBox)
Trex::Trex(Box& aBox)
{
BoxReader reader(aBox);
- if (reader->Remaining() < 6*sizeof(uint32_t)) {
+ if (reader->Remaining() < 6 * sizeof(uint32_t)) {
LOG(Trex, "Incomplete Box (have:%lld need:%lld)",
(uint64_t)reader->Remaining(), (uint64_t)6*sizeof(uint32_t));
return;
}
- mFlags = reader->ReadU32();
- mTrackId = reader->ReadU32();
- mDefaultSampleDescriptionIndex = reader->ReadU32();
- mDefaultSampleDuration = reader->ReadU32();
- mDefaultSampleSize = reader->ReadU32();
- mDefaultSampleFlags = reader->ReadU32();
- mValid = true;
+ if (!reader->ReadU32(mFlags) ||
+ !reader->ReadU32(mTrackId) ||
+ !reader->ReadU32(mDefaultSampleDescriptionIndex) ||
+ !reader->ReadU32(mDefaultSampleDuration) ||
+ !reader->ReadU32(mDefaultSampleSize) ||
+ !reader->ReadU32(mDefaultSampleFlags)) {
+ return;
+ }
}
Tfhd::Tfhd(Box& aBox, Trex& aTrex)
@@ -733,7 +817,9 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex)
LOG(Tfhd, "Incomplete Box (missing flags)");
return;
}
- mFlags = reader->ReadU32();
+ if (!reader->ReadU32(mFlags)) {
+ return;
+ }
size_t need = sizeof(uint32_t) /* trackid */;
uint8_t flag[] = { 1, 2, 8, 0x10, 0x20, 0 };
uint8_t flagSize[] = { sizeof(uint64_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t) };
@@ -747,20 +833,34 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex)
(uint64_t)reader->Remaining(), (uint64_t)need);
return;
}
- mTrackId = reader->ReadU32();
- mBaseDataOffset =
- mFlags & 1 ? reader->ReadU64() : aBox.Parent()->Parent()->Offset();
+ if (!reader->ReadU32(mTrackId)) {
+ return;
+ }
+ mBaseDataOffset = aBox.Parent()->Parent()->Offset();
+ if (mFlags & 1) {
+ if (!reader->ReadU64(mBaseDataOffset)) {
+ return;
+ }
+ }
if (mFlags & 2) {
- mDefaultSampleDescriptionIndex = reader->ReadU32();
+ if (!reader->ReadU32(mDefaultSampleDescriptionIndex)) {
+ return;
+ }
}
if (mFlags & 8) {
- mDefaultSampleDuration = reader->ReadU32();
+ if (!reader->ReadU32(mDefaultSampleDuration)) {
+ return;
+ }
}
if (mFlags & 0x10) {
- mDefaultSampleSize = reader->ReadU32();
+ if (!reader->ReadU32(mDefaultSampleSize)) {
+ return;
+ }
}
if (mFlags & 0x20) {
- mDefaultSampleFlags = reader->ReadU32();
+ if (!reader->ReadU32(mDefaultSampleFlags)) {
+ return;
+ }
}
mValid = true;
}
@@ -772,7 +872,10 @@ Tfdt::Tfdt(Box& aBox)
LOG(Tfdt, "Incomplete Box (missing flags)");
return;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
uint8_t version = flags >> 24;
size_t need = version ? sizeof(uint64_t) : sizeof(uint32_t) ;
if (reader->Remaining() < need) {
@@ -781,9 +884,15 @@ Tfdt::Tfdt(Box& aBox)
return;
}
if (version == 0) {
- mBaseMediaDecodeTime = reader->ReadU32();
+ uint32_t baseDecodeTime;
+ if (!reader->ReadU32(baseDecodeTime)) {
+ return;
+ }
+ mBaseMediaDecodeTime = baseDecodeTime;
} else if (version == 1) {
- mBaseMediaDecodeTime = reader->ReadU64();
+ if (!reader->ReadU64(mBaseMediaDecodeTime)) {
+ return;
+ }
}
mValid = true;
}
@@ -802,7 +911,10 @@ Edts::Edts(Box& aBox)
LOG(Edts, "Incomplete Box (missing flags)");
return;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
uint8_t version = flags >> 24;
size_t need =
sizeof(uint32_t) + 2*(version ? sizeof(int64_t) : sizeof(uint32_t));
@@ -812,16 +924,27 @@ Edts::Edts(Box& aBox)
return;
}
bool emptyEntry = false;
- uint32_t entryCount = reader->ReadU32();
+ uint32_t entryCount;
+ if (!reader->ReadU32(entryCount)) {
+ return;
+ }
for (uint32_t i = 0; i < entryCount; i++) {
uint64_t segment_duration;
int64_t media_time;
if (version == 1) {
- segment_duration = reader->ReadU64();
- media_time = reader->Read64();
+ if (!reader->ReadU64(segment_duration) ||
+ !reader->Read64(media_time)) {
+ return;
+ }
} else {
- segment_duration = reader->ReadU32();
- media_time = reader->Read32();
+ uint32_t duration;
+ int32_t time;
+ if (!reader->ReadU32(duration) ||
+ !reader->Read32(time)) {
+ return;
+ }
+ segment_duration = duration;
+ media_time = time;
}
if (media_time == -1 && i) {
LOG(Edts, "Multiple empty edit, not handled");
@@ -834,8 +957,12 @@ Edts::Edts(Box& aBox)
} else {
mMediaStart = media_time;
}
- reader->ReadU32(); // media_rate_integer and media_rate_fraction
+ // media_rate_integer and media_rate_fraction
+ if (!reader->Skip(4)) {
+ return;
+ }
}
+ mValid = true;
}
Saiz::Saiz(Box& aBox, AtomType aDefaultType)
@@ -847,7 +974,10 @@ Saiz::Saiz(Box& aBox, AtomType aDefaultType)
LOG(Saiz, "Incomplete Box (missing flags)");
return;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
uint8_t version = flags >> 24;
size_t need =
((flags & 1) ? 2*sizeof(uint32_t) : 0) + sizeof(uint8_t) + sizeof(uint32_t);
@@ -857,11 +987,19 @@ Saiz::Saiz(Box& aBox, AtomType aDefaultType)
return;
}
if (flags & 1) {
- mAuxInfoType = reader->ReadU32();
- mAuxInfoTypeParameter = reader->ReadU32();
+ uint32_t auxType;
+ if (!reader->ReadU32(auxType) ||
+ !reader->ReadU32(mAuxInfoTypeParameter)) {
+ return;
+ }
+ mAuxInfoType = auxType;
+ }
+ uint8_t defaultSampleInfoSize;
+ uint32_t count;
+ if (!reader->ReadU8(defaultSampleInfoSize) ||
+ !reader->ReadU32(count)) {
+ return;
}
- uint8_t defaultSampleInfoSize = reader->ReadU8();
- uint32_t count = reader->ReadU32();
if (defaultSampleInfoSize) {
if (!mSampleInfoSize.SetLength(count, fallible)) {
LOG(Saiz, "OOM");
@@ -886,19 +1024,29 @@ Saio::Saio(Box& aBox, AtomType aDefaultType)
LOG(Saio, "Incomplete Box (missing flags)");
return;
}
- uint32_t flags = reader->ReadU32();
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
uint8_t version = flags >> 24;
- size_t need = ((flags & 1) ? (2*sizeof(uint32_t)) : 0) + sizeof(uint32_t);
+ size_t need = ((flags & 1) ? (2 * sizeof(uint32_t)) : 0) + sizeof(uint32_t);
if (reader->Remaining() < need) {
LOG(Saio, "Incomplete Box (have:%lld need:%lld)",
(uint64_t)reader->Remaining(), (uint64_t)need);
return;
}
if (flags & 1) {
- mAuxInfoType = reader->ReadU32();
- mAuxInfoTypeParameter = reader->ReadU32();
+ uint32_t auxType;
+ if (!reader->ReadU32(auxType) ||
+ !reader->ReadU32(mAuxInfoTypeParameter)) {
+ return;
+ }
+ mAuxInfoType = auxType;
+ }
+ uint32_t count;
+ if (!reader->ReadU32(count)) {
+ return;
}
- size_t count = reader->ReadU32();
need = (version ? sizeof(uint64_t) : sizeof(uint32_t)) * count;
if (reader->Remaining() < need) {
LOG(Saio, "Incomplete Box (have:%lld need:%lld)",
@@ -910,16 +1058,203 @@ Saio::Saio(Box& aBox, AtomType aDefaultType)
return;
}
if (version == 0) {
+ uint32_t offset;
for (size_t i = 0; i < count; i++) {
- MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU32(), fallible));
+ if (!reader->ReadU32(offset)) {
+ return;
+ }
+ MOZ_ALWAYS_TRUE(mOffsets.AppendElement(offset, fallible));
}
} else {
+ uint64_t offset;
for (size_t i = 0; i < count; i++) {
- MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU64(), fallible));
+ if (!reader->ReadU64(offset)) {
+ return;
+ }
+ MOZ_ALWAYS_TRUE(mOffsets.AppendElement(offset, fallible));
+ }
+ }
+ mValid = true;
+}
+
+Sbgp::Sbgp(Box& aBox)
+{
+ BoxReader reader(aBox);
+
+ if (!reader->CanReadType<uint32_t>()) {
+ LOG(Sbgp, "Incomplete Box (missing flags)");
+ return;
+ }
+
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
+ const uint8_t version = flags >> 24;
+ flags = flags & 0xffffff;
+
+ // Make sure we have enough bytes to read as far as the count.
+ uint32_t need = (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2;
+ if (reader->Remaining() < need) {
+ LOG(Sbgp, "Incomplete Box (have:%lld, need:%lld)",
+ (uint64_t)reader->Remaining(), (uint64_t)need);
+ return;
+ }
+
+ uint32_t groupType;
+ if (!reader->ReadU32(groupType)) {
+ return;
+ }
+ mGroupingType = groupType;
+
+ if (version == 1) {
+ if (reader->ReadU32(mGroupingTypeParam)) {
+ false;
+ }
+ }
+
+ uint32_t count;
+ if (!reader->ReadU32(count)) {
+ return;
+ }
+
+ // Make sure we can read all the entries.
+ need = sizeof(uint32_t) * 2 * count;
+ if (reader->Remaining() < need) {
+ LOG(Sbgp, "Incomplete Box (have:%lld, need:%lld). Failed to read entries",
+ (uint64_t)reader->Remaining(), (uint64_t)need);
+ return;
+ }
+
+ for (uint32_t i = 0; i < count; i++) {
+ uint32_t sampleCount;
+ uint32_t groupDescriptionIndex;
+ if (!reader->ReadU32(sampleCount) ||
+ !reader->ReadU32(groupDescriptionIndex)) {
+ return;
}
+
+ SampleToGroupEntry entry(sampleCount, groupDescriptionIndex);
+ mEntries.AppendElement(entry);
}
+
mValid = true;
}
+Sgpd::Sgpd(Box& aBox)
+{
+ BoxReader reader(aBox);
+
+ if (!reader->CanReadType<uint32_t>()) {
+ LOG(Sgpd, "Incomplete Box (missing flags)");
+ return;
+ }
+
+ uint32_t flags;
+ if (!reader->ReadU32(flags)) {
+ return;
+ }
+ const uint8_t version = flags >> 24;
+ flags = flags & 0xffffff;
+
+ uint32_t need = ((flags & 1) ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2;
+ if (reader->Remaining() < need) {
+ LOG(Sgpd, "Incomplete Box (have:%lld need:%lld)",
+ (uint64_t)reader->Remaining(), (uint64_t)need);
+ return;
+ }
+
+ uint32_t groupType;
+ if (!reader->ReadU32(groupType)) {
+ return;
+ }
+ mGroupingType = groupType;
+
+ const uint32_t entrySize = sizeof(uint32_t) + kKeyIdSize;
+ uint32_t defaultLength = 0;
+
+ if (version == 1) {
+ if (!reader->ReadU32(defaultLength)) {
+ return;
+ }
+ if (defaultLength < entrySize && defaultLength != 0) {
+ return;
+ }
+ }
+
+ uint32_t count;
+ if (!reader->ReadU32(count)) {
+ return;
+ }
+
+ // Make sure we have sufficient remaining bytes to read the entries.
+ need =
+ count * (sizeof(uint32_t) * (version == 1 && defaultLength == 0 ? 2 : 1) +
+ kKeyIdSize * sizeof(uint8_t));
+ if (reader->Remaining() < need) {
+ LOG(Sgpd, "Incomplete Box (have:%lld need:%lld). Failed to read entries",
+ (uint64_t)reader->Remaining(), (uint64_t)need);
+ return;
+ }
+ for (uint32_t i = 0; i < count; ++i) {
+ if (version == 1 && defaultLength == 0) {
+ uint32_t descriptionLength;
+ if (!reader->ReadU32(descriptionLength)) {
+ return;
+ }
+ if (descriptionLength < entrySize) {
+ return;
+ }
+ }
+
+ CencSampleEncryptionInfoEntry entry;
+ bool valid = entry.Init(reader);
+ if (!valid) {
+ return;
+ }
+ mEntries.AppendElement(entry);
+ }
+
+ mValid = true;
+}
+
+bool CencSampleEncryptionInfoEntry::Init(BoxReader& aReader)
+{
+ // Skip a reserved byte.
+ uint8_t skip;
+ if (!aReader->ReadU8(skip)) {
+ return false;
+ }
+
+ uint8_t possiblePatternInfo;
+ uint8_t flag;
+ if (!aReader->ReadU8(possiblePatternInfo) ||
+ !aReader->ReadU8(flag) ||
+ !aReader->ReadU8(mIVSize)) {
+ return false;
+ }
+
+ // Read the key id.
+ uint8_t key;
+ for (uint32_t i = 0; i < kKeyIdSize; ++i) {
+ if (!aReader->ReadU8(key)) {
+ return false;
+ }
+ mKeyId.AppendElement(key);
+ }
+
+ mIsEncrypted = flag != 0;
+
+ if (mIsEncrypted) {
+ if (mIVSize != 8 && mIVSize != 16) {
+ return false;
+ }
+ } else if (mIVSize != 0) {
+ return false;
+ }
+
+ return true;
+}
+
#undef LOG
}
diff --git a/media/libstagefright/binding/SinfParser.cpp b/media/libstagefright/binding/SinfParser.cpp
index 5cf3aa553..5f3a2889e 100644
--- a/media/libstagefright/binding/SinfParser.cpp
+++ b/media/libstagefright/binding/SinfParser.cpp
@@ -39,8 +39,13 @@ SinfParser::ParseSchm(Box& aBox)
return;
}
- mozilla::Unused << reader->ReadU32(); // flags -- ignore
- mSinf.mDefaultEncryptionType = reader->ReadU32();
+ uint32_t type;
+ if (!reader->Skip(4) ||
+ !reader->ReadU32(type)) {
+ NS_WARNING("Failed to parse schm data");
+ return;
+ }
+ mSinf.mDefaultEncryptionType = type;
}
void
@@ -62,11 +67,16 @@ SinfParser::ParseTenc(Box& aBox)
return;
}
- mozilla::Unused << reader->ReadU32(); // flags -- ignore
-
- uint32_t isEncrypted = reader->ReadU24();
- mSinf.mDefaultIVSize = reader->ReadU8();
- memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16);
+ uint32_t isEncrypted;
+ const uint8_t* key;
+ if (!reader->Skip(4) || // flags -- ignore
+ !reader->ReadU24(isEncrypted) ||
+ !reader->ReadU8(mSinf.mDefaultIVSize) ||
+ !reader->Read(16, &key)) {
+ NS_WARNING("Failed to parse tenc data");
+ return;
+ }
+ memcpy(mSinf.mDefaultKeyID, key, 16);
}
}
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;
}
diff --git a/media/libstagefright/binding/include/mp4_demuxer/Index.h b/media/libstagefright/binding/include/mp4_demuxer/Index.h
index d566c9459..ca254f73d 100644
--- a/media/libstagefright/binding/include/mp4_demuxer/Index.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/Index.h
@@ -32,6 +32,9 @@ public:
Microseconds GetNextKeyframeTime();
private:
Sample* Get();
+
+ CencSampleEncryptionInfoEntry* GetSampleEncryptionEntry();
+
void Next();
RefPtr<Index> mIndex;
friend class Index;
diff --git a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
index 814f806fc..bb895555c 100644
--- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
@@ -17,6 +17,7 @@ typedef int64_t Microseconds;
class Box;
class BoxContext;
+class BoxReader;
class Moof;
class Mvhd : public Atom
@@ -160,6 +161,53 @@ public:
FallibleTArray<uint64_t> mOffsets;
};
+struct SampleToGroupEntry
+{
+public:
+ static const uint32_t kTrackGroupDescriptionIndexBase = 0;
+ static const uint32_t kFragmentGroupDescriptionIndexBase = 0x10000;
+
+ SampleToGroupEntry(uint32_t aSampleCount, uint32_t aGroupDescriptionIndex)
+ : mSampleCount(aSampleCount)
+ , mGroupDescriptionIndex(aGroupDescriptionIndex)
+ {
+ }
+
+ uint32_t mSampleCount;
+ uint32_t mGroupDescriptionIndex;
+};
+
+class Sbgp final : public Atom // SampleToGroup box.
+{
+public:
+ explicit Sbgp(Box& aBox);
+
+ AtomType mGroupingType;
+ uint32_t mGroupingTypeParam;
+ nsTArray<SampleToGroupEntry> mEntries;
+};
+
+struct CencSampleEncryptionInfoEntry final
+{
+public:
+ CencSampleEncryptionInfoEntry() { }
+
+ bool Init(BoxReader& aReader);
+
+ bool mIsEncrypted = false;
+ uint8_t mIVSize = 0;
+ nsTArray<uint8_t> mKeyId;
+};
+
+class Sgpd final : public Atom // SampleGroupDescription box.
+{
+public:
+ explicit Sgpd(Box& aBox);
+
+ AtomType mGroupingType;
+ nsTArray<CencSampleEncryptionInfoEntry> mEntries;
+};
+
class AuxInfo {
public:
AuxInfo(int64_t aMoofOffset, Saiz& aSaiz, Saio& aSaio);
@@ -182,6 +230,9 @@ public:
Interval<Microseconds> mTimeRange;
FallibleTArray<Sample> mIndex;
+ nsTArray<CencSampleEncryptionInfoEntry> mFragmentSampleEncryptionInfoEntries;
+ nsTArray<SampleToGroupEntry> mFragmentSampleToGroupEntries;
+
nsTArray<Saiz> mSaizs;
nsTArray<Saio> mSaios;
@@ -246,6 +297,10 @@ public:
Tfdt mTfdt;
Edts mEdts;
Sinf mSinf;
+
+ nsTArray<CencSampleEncryptionInfoEntry> mTrackSampleEncryptionInfoEntries;
+ nsTArray<SampleToGroupEntry> mTrackSampleToGroupEntries;
+
nsTArray<Moof>& Moofs() { return mMoofs; }
private:
void ScanForMetadata(mozilla::MediaByteRange& aFtyp,
diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
index e881e0262..5667f04d8 100644
--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
@@ -753,7 +753,6 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
case FOURCC('m', 'o', 'o', 'f'):
case FOURCC('t', 'r', 'a', 'f'):
case FOURCC('m', 'f', 'r', 'a'):
- case FOURCC('u', 'd', 't', 'a'):
case FOURCC('i', 'l', 's', 't'):
case FOURCC('s', 'i', 'n', 'f'):
case FOURCC('s', 'c', 'h', 'i'):
diff --git a/media/libstagefright/moz.build b/media/libstagefright/moz.build
index c6072d840..5a8c9521a 100644
--- a/media/libstagefright/moz.build
+++ b/media/libstagefright/moz.build
@@ -53,6 +53,7 @@ EXPORTS.mp4_demuxer += [
'binding/include/mp4_demuxer/Atom.h',
'binding/include/mp4_demuxer/AtomType.h',
'binding/include/mp4_demuxer/BitReader.h',
+ 'binding/include/mp4_demuxer/BufferReader.h',
'binding/include/mp4_demuxer/BufferStream.h',
'binding/include/mp4_demuxer/ByteReader.h',
'binding/include/mp4_demuxer/ByteWriter.h',
diff --git a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
index 2c57431e7..e36b8b6cf 100755
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -706,15 +706,6 @@ WebrtcAudioConduit::GetAudioFrame(int16_t speechData[],
if (GetAVStats(&jitter_buffer_delay_ms,
&playout_buffer_delay_ms,
&avsync_offset_ms)) {
-#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- if (avsync_offset_ms < 0) {
- Telemetry::Accumulate(Telemetry::WEBRTC_AVSYNC_WHEN_VIDEO_LAGS_AUDIO_MS,
- -avsync_offset_ms);
- } else {
- Telemetry::Accumulate(Telemetry::WEBRTC_AVSYNC_WHEN_AUDIO_LAGS_VIDEO_MS,
- avsync_offset_ms);
- }
-#endif
CSFLogError(logTag,
"A/V sync: sync delta: %dms, audio jitter delay %dms, playout delay %dms",
avsync_offset_ms, jitter_buffer_delay_ms, playout_buffer_delay_ms);
diff --git a/media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp b/media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp
index eb03c0bf8..da40a59ea 100644
--- a/media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp
+++ b/media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp
@@ -124,8 +124,6 @@ void VideoCodecStatistics::ReceiveStateChange(const int aChannel,
TimeDuration timeDelta = TimeStamp::Now() - mReceiveFailureTime;
CSFLogError(logTag, "Video error duration: %u ms",
static_cast<uint32_t>(timeDelta.ToMilliseconds()));
- Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_ERROR_RECOVERY_MS,
- static_cast<uint32_t>(timeDelta.ToMilliseconds()));
mRecoveredLosses++; // to calculate losses per minute
mTotalLossTime += timeDelta; // To calculate % time in recovery
@@ -147,16 +145,10 @@ void VideoCodecStatistics::EndOfCallStats()
if (callDelta.ToSeconds() != 0) {
uint32_t recovered_per_min = mRecoveredBeforeLoss/(callDelta.ToSeconds()/60);
CSFLogError(logTag, "Video recovery before error per min %u", recovered_per_min);
- Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_RECOVERY_BEFORE_ERROR_PER_MIN,
- recovered_per_min);
uint32_t err_per_min = mRecoveredLosses/(callDelta.ToSeconds()/60);
CSFLogError(logTag, "Video recovery after error per min %u", err_per_min);
- Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_RECOVERY_AFTER_ERROR_PER_MIN,
- err_per_min);
float percent = (mTotalLossTime.ToSeconds()*100)/callDelta.ToSeconds();
CSFLogError(logTag, "Video error time percentage %f%%", percent);
- Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_DECODE_ERROR_TIME_PERMILLE,
- static_cast<uint32_t>(percent*10));
}
}
#endif
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index 33422ed7a..43d10ca86 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -2245,22 +2245,6 @@ PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, un
CSFLogDebug(logTag, "AddIceCandidate: %s", aCandidate);
-#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- // When remote candidates are added before our ICE ctx is up and running
- // (the transition to New is async through STS, so this is not impossible),
- // we won't record them as trickle candidates. Is this what we want?
- if(!mIceStartTime.IsNull()) {
- TimeDuration timeDelta = TimeStamp::Now() - mIceStartTime;
- if (mIceConnectionState == PCImplIceConnectionState::Failed) {
- Telemetry::Accumulate(Telemetry::WEBRTC_ICE_LATE_TRICKLE_ARRIVAL_TIME,
- timeDelta.ToMilliseconds());
- } else {
- Telemetry::Accumulate(Telemetry::WEBRTC_ICE_ON_TIME_TRICKLE_ARRIVAL_TIME,
- timeDelta.ToMilliseconds());
- }
- }
-#endif
-
nsresult res = mJsepSession->AddRemoteIceCandidate(aCandidate, aMid, aLevel);
if (NS_SUCCEEDED(res)) {
@@ -3011,49 +2995,7 @@ PeerConnectionImpl::PluginCrash(uint32_t aPluginID,
void
PeerConnectionImpl::RecordEndOfCallTelemetry() const
{
- if (!mJsepSession) {
- return;
- }
-
-#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- // Bitmask used for WEBRTC/LOOP_CALL_TYPE telemetry reporting
- static const uint32_t kAudioTypeMask = 1;
- static const uint32_t kVideoTypeMask = 2;
- static const uint32_t kDataChannelTypeMask = 4;
-
- // Report end-of-call Telemetry
- if (mJsepSession->GetNegotiations() > 0) {
- Telemetry::Accumulate(Telemetry::WEBRTC_RENEGOTIATIONS,
- mJsepSession->GetNegotiations()-1);
- }
- Telemetry::Accumulate(Telemetry::WEBRTC_MAX_VIDEO_SEND_TRACK,
- mMaxSending[SdpMediaSection::MediaType::kVideo]);
- Telemetry::Accumulate(Telemetry::WEBRTC_MAX_VIDEO_RECEIVE_TRACK,
- mMaxReceiving[SdpMediaSection::MediaType::kVideo]);
- Telemetry::Accumulate(Telemetry::WEBRTC_MAX_AUDIO_SEND_TRACK,
- mMaxSending[SdpMediaSection::MediaType::kAudio]);
- Telemetry::Accumulate(Telemetry::WEBRTC_MAX_AUDIO_RECEIVE_TRACK,
- mMaxReceiving[SdpMediaSection::MediaType::kAudio]);
- // DataChannels appear in both Sending and Receiving
- Telemetry::Accumulate(Telemetry::WEBRTC_DATACHANNEL_NEGOTIATED,
- mMaxSending[SdpMediaSection::MediaType::kApplication]);
- // Enumerated/bitmask: 1 = Audio, 2 = Video, 4 = DataChannel
- // A/V = 3, A/V/D = 7, etc
- uint32_t type = 0;
- if (mMaxSending[SdpMediaSection::MediaType::kAudio] ||
- mMaxReceiving[SdpMediaSection::MediaType::kAudio]) {
- type = kAudioTypeMask;
- }
- if (mMaxSending[SdpMediaSection::MediaType::kVideo] ||
- mMaxReceiving[SdpMediaSection::MediaType::kVideo]) {
- type |= kVideoTypeMask;
- }
- if (mMaxSending[SdpMediaSection::MediaType::kApplication]) {
- type |= kDataChannelTypeMask;
- }
- Telemetry::Accumulate(Telemetry::WEBRTC_CALL_TYPE,
- type);
-#endif
+ /* STUB */
}
nsresult
@@ -3109,13 +3051,6 @@ PeerConnectionImpl::ShutdownMedia()
pair.second->RemovePrincipalChangeObserver(this);
}
}
-
- // End of call to be recorded in Telemetry
- if (!mStartTime.IsNull()){
- TimeDuration timeDelta = TimeStamp::Now() - mStartTime;
- Telemetry::Accumulate(Telemetry::WEBRTC_CALL_DURATION,
- timeDelta.ToSeconds());
- }
#endif
// Forget the reference so that we can transfer it to
@@ -3423,33 +3358,6 @@ void PeerConnectionImpl::IceConnectionStateChange(
return;
}
-#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- if (!isDone(mIceConnectionState) && isDone(domState)) {
- // mIceStartTime can be null if going directly from New to Closed, in which
- // case we don't count it as a success or a failure.
- if (!mIceStartTime.IsNull()){
- TimeDuration timeDelta = TimeStamp::Now() - mIceStartTime;
- if (isSucceeded(domState)) {
- Telemetry::Accumulate(Telemetry::WEBRTC_ICE_SUCCESS_TIME,
- timeDelta.ToMilliseconds());
- } else if (isFailed(domState)) {
- Telemetry::Accumulate(Telemetry::WEBRTC_ICE_FAILURE_TIME,
- timeDelta.ToMilliseconds());
- }
- }
-
- if (isSucceeded(domState)) {
- Telemetry::Accumulate(
- Telemetry::WEBRTC_ICE_ADD_CANDIDATE_ERRORS_GIVEN_SUCCESS,
- mAddCandidateErrorCount);
- } else if (isFailed(domState)) {
- Telemetry::Accumulate(
- Telemetry::WEBRTC_ICE_ADD_CANDIDATE_ERRORS_GIVEN_FAILURE,
- mAddCandidateErrorCount);
- }
- }
-#endif
-
mIceConnectionState = domState;
if (mIceConnectionState == PCImplIceConnectionState::Connected ||
@@ -3467,10 +3375,6 @@ void PeerConnectionImpl::IceConnectionStateChange(
STAMP_TIMECARD(mTimeCard, "Ice state: new");
break;
case PCImplIceConnectionState::Checking:
-#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- // For telemetry
- mIceStartTime = TimeStamp::Now();
-#endif
STAMP_TIMECARD(mTimeCard, "Ice state: checking");
break;
case PCImplIceConnectionState::Connected:
@@ -4067,16 +3971,7 @@ PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream)
//Telemetry for when calls start
void
PeerConnectionImpl::startCallTelem() {
- if (!mStartTime.IsNull()) {
- return;
- }
-
- // Start time for calls
- mStartTime = TimeStamp::Now();
-
- // Increment session call counter
- // If we want to track Loop calls independently here, we need two histograms.
- Telemetry::Accumulate(Telemetry::WEBRTC_CALL_COUNT_2, 1);
+ /* STUB */
}
#endif
diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
index 96bdd5b70..f283d6111 100644
--- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
+++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
@@ -1194,18 +1194,8 @@ static void GetStatsForLongTermStorage_s(
rate_limit_bit_pattern |= 2;
}
- if (query->failed) {
- Telemetry::Accumulate(
- Telemetry::WEBRTC_STUN_RATE_LIMIT_EXCEEDED_BY_TYPE_GIVEN_FAILURE,
- rate_limit_bit_pattern);
- } else {
- Telemetry::Accumulate(
- Telemetry::WEBRTC_STUN_RATE_LIMIT_EXCEEDED_BY_TYPE_GIVEN_SUCCESS,
- rate_limit_bit_pattern);
- }
-
- // Even if Telemetry::Accumulate is threadsafe, we still need to send the
- // query back to main, since that is where it must be destroyed.
+ // We still need to send the query back to main, since that is where
+ // it must be destroyed.
NS_DispatchToMainThread(
WrapRunnableNM(
&StoreLongTermICEStatisticsImpl_m,
@@ -1216,8 +1206,6 @@ static void GetStatsForLongTermStorage_s(
void WebrtcGlobalInformation::StoreLongTermICEStatistics(
PeerConnectionImpl& aPc) {
- Telemetry::Accumulate(Telemetry::WEBRTC_ICE_FINAL_CONNECTION_STATE,
- static_cast<uint32_t>(aPc.IceConnectionState()));
if (aPc.IceConnectionState() == PCImplIceConnectionState::New) {
// ICE has not started; we won't have any remote candidates, so recording