Bug 1139271 - Part 1: Add logging when encountering invalid atoms. r=k17e, a=lsblakk
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 16 Mar 2015 23:08:55 +1100
changeset 250421 202177831c59
parent 250420 3eeb35bbafd2
child 250422 21384861c447
push id4583
push userryanvm@gmail.com
push date2015-03-18 16:53 +0000
treeherdermozilla-beta@067f83e99f66 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersk17e, lsblakk
bugs1139271
milestone37.0
Bug 1139271 - Part 1: Add logging when encountering invalid atoms. r=k17e, a=lsblakk
media/libstagefright/binding/MoofParser.cpp
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -2,16 +2,33 @@
  * 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/. */
 
 #include "mp4_demuxer/MoofParser.h"
 #include "mp4_demuxer/Box.h"
 #include "mp4_demuxer/SinfParser.h"
 #include <limits>
 
+#include "prlog.h"
+
+#ifdef PR_LOGGING
+extern PRLogModuleInfo* GetDemuxerLog();
+
+/* Polyfill __func__ on MSVC to pass to the log. */
+#ifdef _MSC_VER
+#define __func__ __FUNCTION__
+#endif
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+#define LOG(name, arg, ...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (TOSTRING(name) "(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#else
+#define LOG(...)
+#endif
+
 namespace mp4_demuxer
 {
 
 using namespace stagefright;
 using namespace mozilla;
 
 void
 MoofParser::RebuildFragmentedIndex(
@@ -334,33 +351,37 @@ public:
   }
 };
 
 void
 Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
 {
   if (!aTfhd.IsValid() || !aTfdt.IsValid() ||
       !aMdhd.IsValid() || !aEdts.IsValid()) {
+    LOG(Moof, "Invalid dependencies: aTfhd(%d) aTfdt(%d) aMdhd(%d) aEdts(%d)",
+        aTfhd.IsValid(), aTfdt.IsValid(), aMdhd.IsValid(), !aEdts.IsValid());
     return;
   }
 
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Moof, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   if ((flags & 0x404) == 0x404) {
     // Can't use these flags together
     reader->DiscardRemaining();
     mValid = true;
     return;
   }
   uint8_t version = flags >> 24;
 
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Moof, "Incomplete Box (missing sampleCount)");
     return;
   }
   uint32_t sampleCount = reader->ReadU32();
   if (sampleCount == 0) {
     mValid = true;
     return;
   }
 
@@ -369,16 +390,18 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
     ((flags & 4) ? sizeof(uint32_t) : 0);
   uint16_t flag[] = { 0x100, 0x200, 0x400, 0x800, 0 };
   for (size_t i = 0; flag[i]; i++) {
     if (flags & flag[i]) {
       need += sizeof(uint32_t) * sampleCount;
     }
   }
   if (reader->Remaining() < need) {
+    LOG(Moof, "Incomplete Box (have:%lld need:%lld)",
+        reader->Remaining(), need);
     return;
   }
 
   uint64_t offset = aTfhd.mBaseDataOffset + (flags & 1 ? reader->ReadU32() : 0);
   bool hasFirstSampleFlags = flags & 4;
   uint32_t firstSampleFlags = hasFirstSampleFlags ? reader->ReadU32() : 0;
   uint64_t decodeTime = aTfdt.mBaseMediaDecodeTime;
   nsTArray<Interval<Microseconds>> timeRanges;
@@ -429,23 +452,26 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
       ctsOrder.LastElement()->mCompositionRange.end);
   mValid = true;
 }
 
 Tkhd::Tkhd(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Tkhd, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   uint8_t version = flags >> 24;
   size_t need =
     3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(int32_t);
   if (reader->Remaining() < need) {
+    LOG(Tkhd, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
   if (version == 0) {
     mCreationTime = reader->ReadU32();
     mModificationTime = reader->ReadU32();
     mTrackId = reader->ReadU32();
     uint32_t reserved = reader->ReadU32();
     NS_ASSERTION(!reserved, "reserved should be 0");
@@ -462,23 +488,26 @@ Tkhd::Tkhd(Box& aBox)
   reader->DiscardRemaining();
   mValid = true;
 }
 
 Mdhd::Mdhd(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Mdhd, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   uint8_t version = flags >> 24;
   size_t need =
     3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(uint32_t);
   if (reader->Remaining() < need) {
+    LOG(Mdhd, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
 
   if (version == 0) {
     mCreationTime = reader->ReadU32();
     mModificationTime = reader->ReadU32();
     mTimescale = reader->ReadU32();
     mDuration = reader->ReadU32();
@@ -494,16 +523,18 @@ Mdhd::Mdhd(Box& aBox)
     mValid = true;
   }
 }
 
 Trex::Trex(Box& aBox)
 {
   BoxReader reader(aBox);
   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();
@@ -514,27 +545,30 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex)
   : Trex(aTrex)
 {
   MOZ_ASSERT(aBox.IsType("tfhd"));
   MOZ_ASSERT(aBox.Parent()->IsType("traf"));
   MOZ_ASSERT(aBox.Parent()->Parent()->IsType("moof"));
 
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Tfhd, "Incomplete Box (missing flags)");
     return;
   }
   mFlags = reader->ReadU32();
   size_t need = sizeof(uint32_t) /* trackid */;
   uint8_t flag[] = { 1, 2, 8, 0x10, 0x20, 0 };
   for (size_t i = 0; flag[i]; i++) {
     if (mFlags & flag[i]) {
       need += sizeof(uint32_t);
     }
   }
   if (reader->Remaining() < need) {
+    LOG(Tfhd, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
   mBaseDataOffset =
     mFlags & 1 ? reader->ReadU32() : aBox.Parent()->Parent()->Offset();
   mTrackId = reader->ReadU32();
   if (mFlags & 2) {
     mDefaultSampleDescriptionIndex = reader->ReadU32();
   }
@@ -549,22 +583,25 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex)
   }
   mValid = true;
 }
 
 Tfdt::Tfdt(Box& aBox)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Tfdt, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   uint8_t version = flags >> 24;
   size_t need = version ? sizeof(uint64_t) : sizeof(uint32_t) ;
   if (reader->Remaining() < need) {
+    LOG(Tfdt, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
   if (version == 0) {
     mBaseMediaDecodeTime = reader->ReadU32();
   } else if (version == 1) {
     mBaseMediaDecodeTime = reader->ReadU64();
   }
   reader->DiscardRemaining();
@@ -576,23 +613,26 @@ Edts::Edts(Box& aBox)
 {
   Box child = aBox.FirstChild();
   if (!child.IsType("elst")) {
     return;
   }
 
   BoxReader reader(child);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Edts, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   uint8_t version = flags >> 24;
   size_t need =
     sizeof(uint32_t) + 2*(version ? sizeof(int64_t) : sizeof(uint32_t));
   if (reader->Remaining() < need) {
+    LOG(Edts, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
   uint32_t entryCount = reader->ReadU32();
   NS_ASSERTION(entryCount == 1, "Can't handle videos with multiple edits");
   if (entryCount != 1) {
     reader->DiscardRemaining();
     return;
   }
@@ -610,71 +650,82 @@ Edts::Edts(Box& aBox)
 }
 
 Saiz::Saiz(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Saiz, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   uint8_t version = flags >> 24;
   size_t need =
     ((flags & 1) ? 2*sizeof(uint32_t) : 0) + sizeof(uint8_t) + sizeof(uint32_t);
   if (reader->Remaining() < need) {
+    LOG(Saiz, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
   if (flags & 1) {
     mAuxInfoType = reader->ReadU32();
     mAuxInfoTypeParameter = reader->ReadU32();
   }
   uint8_t defaultSampleInfoSize = reader->ReadU8();
   uint32_t count = reader->ReadU32();
   if (defaultSampleInfoSize) {
     for (int i = 0; i < count; i++) {
       mSampleInfoSize.AppendElement(defaultSampleInfoSize);
     }
   } else {
     if (!reader->ReadArray(mSampleInfoSize, count)) {
+      LOG(Saiz, "Incomplete Box (missing count:%u)", count);
       return;
     }
   }
   mValid = true;
 }
 
 Saio::Saio(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
   BoxReader reader(aBox);
   if (!reader->CanReadType<uint32_t>()) {
+    LOG(Saio, "Incomplete Box (missing flags)");
     return;
   }
   uint32_t flags = reader->ReadU32();
   uint8_t version = flags >> 24;
   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();
   }
   size_t count = reader->ReadU32();
   need = (version ? sizeof(uint64_t) : sizeof(uint32_t)) * count;
   if (reader->Remaining() < count) {
+    LOG(Saio, "Incomplete Box (have:%lld need:%lld)",
+        (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
   mOffsets.SetCapacity(count);
   if (version == 0) {
     for (size_t i = 0; i < count; i++) {
       mOffsets.AppendElement(reader->ReadU32());
     }
   } else {
     for (size_t i = 0; i < count; i++) {
       mOffsets.AppendElement(reader->ReadU64());
     }
   }
   mValid = true;
 }
+
+#undef LOG
 }