Bug 1062514 - Fix range handling for regular MP4 with b-frames; r=rillian
authorAnthony Jones <ajones@mozilla.com>
Thu, 11 Sep 2014 15:57:32 +1200
changeset 204727 f68c40ef23276ca3e6f4d612046545afc77a7334
parent 204726 47d2dd4ecad1ddd3b05a064c4b2c261e9b75db6e
child 204728 3331b49ff9e6063c4f2347e2a729631bbbca760a
push id48987
push userajones@mozilla.com
push dateThu, 11 Sep 2014 03:58:47 +0000
treeherdermozilla-inbound@2097b83ffbab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian
bugs1062514
milestone35.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 1062514 - Fix range handling for regular MP4 with b-frames; r=rillian
media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
@@ -3719,16 +3719,22 @@ status_t MPEG4Source::fragmentedRead(
 
         *out = mBuffer;
         mBuffer = NULL;
 
         return OK;
     }
 }
 
+static int compositionOrder(MediaSource::Indice* const* indice0,
+        MediaSource::Indice* const* indice1)
+{
+  return (*indice0)->start_composition - (*indice1)->start_composition;
+}
+
 Vector<MediaSource::Indice> MPEG4Source::exportIndex()
 {
   Vector<Indice> index;
   if (!mTimescale) {
     return index;
   }
 
   for (uint32_t sampleIndex = 0; sampleIndex < mSampleTable->countSamples();
@@ -3743,22 +3749,41 @@ Vector<MediaSource::Indice> MPEG4Source:
                                              &isSyncSample) != OK) {
           ALOGE("Unexpected sample table problem");
           continue;
       }
 
       Indice indice;
       indice.start_offset = offset;
       indice.end_offset = offset + size;
-      indice.start_composition = (compositionTime * 1000000ll) / mTimescale,
+      indice.start_composition = (compositionTime * 1000000ll) / mTimescale;
+      // end_composition is overwritten everywhere except the last frame, where
+      // the presentation duration is equal to the sample duration.
       indice.end_composition = ((compositionTime + duration) * 1000000ll) /
               mTimescale;
       indice.sync = isSyncSample;
       index.add(indice);
   }
+
+  // Fix up composition durations so we don't end up with any unsightly gaps.
+  if (index.size() != 0) {
+      Indice* array = index.editArray();
+      Vector<Indice*> composition_order;
+      composition_order.reserve(index.size());
+      for (uint32_t i = 0; i < index.size(); i++) {
+          composition_order.add(&array[i]);
+      }
+
+      composition_order.sort(compositionOrder);
+      for (uint32_t i = 0; i + 1 < composition_order.size(); i++) {
+        composition_order[i]->end_composition =
+                composition_order[i + 1]->start_composition;
+      }
+  }
+
   return index;
 }
 
 MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
         const char *mimePrefix) {
     for (Track *track = mFirstTrack; track != NULL; track = track->next) {
         const char *mime;
         if (track->meta != NULL