Transcoder: Preserve source track duration.

Preserve the source track's duration by sending an
EOS sample with the appropriate PTS to the muxer.
Modified MediaSampleWriterTests to verify the extra
EOS sample.

Bug: 159732935
Test: MediaTranscoder and MediaSampleWriter unit tests.
Change-Id: I6792eff8932db126e8734e5d3d6fe8aee2ffb4a1
diff --git a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp b/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
index 0fdb0b7..91dbf78 100644
--- a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
+++ b/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
@@ -122,7 +122,12 @@
         return false;
     }
 
-    mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex));
+    int64_t durationUs;
+    if (!AMediaFormat_getInt64(trackFormat.get(), AMEDIAFORMAT_KEY_DURATION, &durationUs)) {
+        durationUs = 0;
+    }
+
+    mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex), durationUs);
     return true;
 }
 
@@ -200,10 +205,23 @@
                 } else if (sample->info.flags & SAMPLE_FLAG_END_OF_STREAM) {
                     // Track reached end of stream.
                     track.mReachedEos = true;
-                    break;
+
+                    // Preserve source track duration by setting the appropriate timestamp on the
+                    // empty End-Of-Stream sample.
+                    if (track.mDurationUs > 0 && track.mFirstSampleTimeSet) {
+                        sample->info.presentationTimeUs =
+                                track.mDurationUs + track.mFirstSampleTimeUs;
+                    }
+                } else {
+                    samplesLeft = true;
                 }
 
-                samplesLeft = true;
+                // Record the first sample's timestamp in order to translate duration to EOS time
+                // for tracks that does not start at 0.
+                if (!track.mFirstSampleTimeSet) {
+                    track.mFirstSampleTimeUs = sample->info.presentationTimeUs;
+                    track.mFirstSampleTimeSet = true;
+                }
 
                 bufferInfo.offset = sample->dataOffset;
                 bufferInfo.size = sample->info.size;
@@ -217,7 +235,7 @@
                     return status;
                 }
 
-            } while (sample->info.presentationTimeUs < segmentEndTimeUs);
+            } while (sample->info.presentationTimeUs < segmentEndTimeUs && !track.mReachedEos);
         }
 
         segmentEndTimeUs += mTrackSegmentLengthUs;