Transcoder: Improve AV transcoding speed by enforcing sequential sample access.

MediaSampleReader was bottlenecking the transcoding pipeline due to
non-sequential sample access. This commit adds an option to the sample
reader to enforce sequential sample access by blocking reads until
the underlying extractor advances to that specific track.
Follow-up: b/165374867 Make MediaSampleWriter robust against buffering track transcoders

Fixes: 160268606
Test: Transcoder unit tests, and benchmark tests.
Change-Id: Id2a363d06df927ea3e547462c52803594e0511e1
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
index ed702db..fbed5c2 100644
--- a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
@@ -133,6 +133,12 @@
 
     mTracksAdded.insert(transcoder);
     if (mTracksAdded.size() == mTrackTranscoders.size()) {
+        // Enable sequential access mode on the sample reader to achieve optimal read performance.
+        // This has to wait until all tracks have delivered their output formats and the sample
+        // writer is started. Otherwise the tracks will not get their output sample queues drained
+        // and the transcoder could hang due to one track running out of buffers and blocking the
+        // other tracks from reading source samples before they could output their formats.
+        mSampleReader->setEnforceSequentialAccess(true);
         LOG(INFO) << "Starting sample writer.";
         bool started = mSampleWriter->start();
         if (!started) {
@@ -229,6 +235,12 @@
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
+    media_status_t status = mSampleReader->selectTrack(trackIndex);
+    if (status != AMEDIA_OK) {
+        LOG(ERROR) << "Unable to select track " << trackIndex;
+        return status;
+    }
+
     std::shared_ptr<MediaTrackTranscoder> transcoder;
     std::shared_ptr<AMediaFormat> format;
 
@@ -270,7 +282,7 @@
         format = std::shared_ptr<AMediaFormat>(mergedFormat, &AMediaFormat_delete);
     }
 
-    media_status_t status = transcoder->configure(mSampleReader, trackIndex, format);
+    transcoder->configure(mSampleReader, trackIndex, format);
     if (status != AMEDIA_OK) {
         LOG(ERROR) << "Configure track transcoder for track #" << trackIndex << " returned error "
                    << status;
@@ -344,6 +356,7 @@
     }
 
     mSampleWriter->stop();
+    mSampleReader->setEnforceSequentialAccess(false);
     for (auto& transcoder : mTrackTranscoders) {
         transcoder->stop();
     }