Bug 1016150 - Fix Windows date assert in libstagefright demuxer; r=cpearce
authorAnthony Jones <ajones@mozilla.com>
Mon, 09 Jun 2014 18:07:46 +1200
changeset 206744 7987a44a68140f5341f9659b08729e1305e0e909
parent 206743 b70ca6c774c92d2de4caf763196a08245e6d3f72
child 206745 c3696dc117434c51338e1201cf84d7579e1e1d3e
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1016150
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1016150 - Fix Windows date assert in libstagefright demuxer; r=cpearce
media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
media/libstagefright/patches/frameworks/av.patch
--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
@@ -722,16 +722,21 @@ static bool underMetaDataPath(const Vect
         && path[2] == FOURCC('m', 'e', 't', 'a')
         && path[3] == FOURCC('i', 'l', 's', 't');
 }
 
 // Given a time in seconds since Jan 1 1904, produce a human-readable string.
 static void convertTimeToDate(int64_t time_1904, String8 *s) {
     time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
 
+    if (time_1970 < 0) {
+        s->clear();
+        return;
+    }
+
     char tmp[32];
     strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
 
     s->setTo(tmp);
 }
 
 status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
     ALOGV("entering parseChunk %lld/%d", *offset, depth);
@@ -1649,18 +1654,19 @@ status_t MPEG4Extractor::parseChunk(off6
                 return ERROR_MALFORMED;
             } else {
                 creationTime = U32_AT(&header[4]);
                 mHeaderTimescale = U32_AT(&header[12]);
             }
 
             String8 s;
             convertTimeToDate(creationTime, &s);
-
-            mFileMetaData->setCString(kKeyDate, s.string());
+            if (s.length()) {
+                mFileMetaData->setCString(kKeyDate, s.string());
+            }
 
             *offset += chunk_size;
             break;
         }
 
         case FOURCC('m', 'd', 'a', 't'):
         {
             ALOGV("mdat chunk, drm: %d", mIsDrm);
--- a/media/libstagefright/patches/frameworks/av.patch
+++ b/media/libstagefright/patches/frameworks/av.patch
@@ -573,17 +573,17 @@ index 4a0c35c..ccf60e3 100644
      return OK;
  }
  
 -}  // namespace android
 +}  // namespace stagefright
  
 +#undef LOG_TAG
 diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
-index ad985ee..f0165e5 100644
+index ad985ee..71a0613 100644
 --- a/media/libstagefright/MPEG4Extractor.cpp
 +++ b/media/libstagefright/MPEG4Extractor.cpp
 @@ -15,6 +15,7 @@
   */
  
  //#define LOG_NDEBUG 0
 +#undef LOG_TAG
  #define LOG_TAG "MPEG4Extractor"
@@ -593,52 +593,76 @@ index ad985ee..f0165e5 100644
  #include <media/stagefright/MetaData.h>
  #include <utils/String8.h>
  
 -namespace android {
 +namespace stagefright {
  
  class MPEG4Source : public MediaSource {
  public:
-@@ -1248,6 +1249,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
+@@ -726,6 +727,11 @@ static bool underMetaDataPath(const Vector<uint32_t> &path) {
+ static void convertTimeToDate(int64_t time_1904, String8 *s) {
+     time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
+ 
++    if (time_1970 < 0) {
++      s->clear();
++      return;
++    }
++
+     char tmp[32];
+     strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
+ 
+@@ -1248,6 +1254,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
              ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
                     chunk, num_channels, sample_size, sample_rate);
              mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
 +            mLastTrack->meta->setInt32(kKeySampleSize, sample_size);
              mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
  
              off64_t stop_offset = *offset + chunk_size;
-@@ -2278,6 +2280,10 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
+@@ -1652,8 +1659,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
+ 
+             String8 s;
+             convertTimeToDate(creationTime, &s);
+-
+-            mFileMetaData->setCString(kKeyDate, s.string());
++            if (s.length()) {
++                mFileMetaData->setCString(kKeyDate, s.string());
++            }
+ 
+             *offset += chunk_size;
+             break;
+@@ -2278,6 +2286,10 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
          objectType = 32 + br.getBits(6);
      }
  
 +    if (objectType >= 1 && objectType <= 4) {
 +      mLastTrack->meta->setInt32(kKeyAACProfile, objectType);
 +    }
 +
      uint32_t freqIndex = br.getBits(4);
  
      int32_t sampleRate = 0;
-@@ -3154,6 +3160,7 @@ status_t MPEG4Source::read(
+@@ -3154,6 +3166,7 @@ status_t MPEG4Source::read(
              CHECK(mBuffer != NULL);
              mBuffer->set_range(0, size);
              mBuffer->meta_data()->clear();
 +            mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
              mBuffer->meta_data()->setInt64(
                      kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
  
-@@ -3276,6 +3283,7 @@ status_t MPEG4Source::read(
+@@ -3276,6 +3289,7 @@ status_t MPEG4Source::read(
          }
  
          mBuffer->meta_data()->clear();
 +        mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
          mBuffer->meta_data()->setInt64(
                  kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
  
-@@ -3360,6 +3368,18 @@ status_t MPEG4Source::fragmentedRead(
+@@ -3360,6 +3374,18 @@ status_t MPEG4Source::fragmentedRead(
              // move to next fragment
              Sample lastSample = mCurrentSamples[mCurrentSamples.size() - 1];
              off64_t nextMoof = mNextMoofOffset; // lastSample.offset + lastSample.size;
 +
 +            // If we're pointing to a sidx box then we skip it.
 +            uint32_t hdr[2];
 +            if (mDataSource->readAt(nextMoof, hdr, 8) < 8) {
 +                return ERROR_END_OF_STREAM;
@@ -647,25 +671,25 @@ index ad985ee..f0165e5 100644
 +            uint32_t chunk_type = ntohl(hdr[1]);
 +            if (chunk_type == FOURCC('s', 'i', 'd', 'x')) {
 +                nextMoof += chunk_size;
 +            }
 +
              mCurrentMoofOffset = nextMoof;
              mCurrentSamples.clear();
              mCurrentSampleIndex = 0;
-@@ -3626,6 +3646,7 @@ static bool isCompatibleBrand(uint32_t fourcc) {
+@@ -3626,6 +3652,7 @@ static bool isCompatibleBrand(uint32_t fourcc) {
      return false;
  }
  
 +#if 0
  // Attempt to actually parse the 'ftyp' atom and determine if a suitable
  // compatible brand is present.
  // Also try to identify where this file's metadata ends
-@@ -3756,5 +3777,8 @@ bool SniffMPEG4(
+@@ -3756,5 +3783,8 @@ bool SniffMPEG4(
  
      return false;
  }
 +#endif
 +
 +}  // namespace stagefright
  
 -}  // namespace android