Transcoder: Send more granular heartbeats on transcoder start up.

The transcoder watchdog timer starts when a request is sent to
the transcoder. But configuring and starting the transcoder may
delay the first heartbeat under high load. This CL mitigates this
in three ways:
- Send heartbeat during transcoder configuration.
- Send heartbeat when track produce output formats during start.
- Count samples written to the muxer from all track as progress.

Fixes: 183388518
Test: Transcoding unit tests.
Change-Id: I0fe935b33bc0601a0671e6ba39e1e3f528d1132b
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index a063565..b19e711 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -366,6 +366,12 @@
         return AMEDIA_ERROR_INVALID_OPERATION;
     }
 
+    // Unwrap the callback and send heartbeats to the client after each operation during setup.
+    auto callback = mCallback.lock();
+    if (callback == nullptr) {
+        return AMEDIA_ERROR_INVALID_OPERATION;
+    }
+
     Status status;
     ::ndk::ScopedFileDescriptor srcFd, dstFd;
     int srcFdInt = request.sourceFd.get();
@@ -379,6 +385,8 @@
         srcFdInt = srcFd.get();
     }
 
+    callback->onHeartBeat(clientId, sessionId);
+
     int dstFdInt = request.destinationFd.get();
     if (dstFdInt < 0) {
         // Open dest file with "rw", as the transcoder could potentially reuse part of it
@@ -393,6 +401,8 @@
         dstFdInt = dstFd.get();
     }
 
+    callback->onHeartBeat(clientId, sessionId);
+
     mCurrentClientId = clientId;
     mCurrentSessionId = sessionId;
     mCurrentCallingUid = callingUid;
@@ -405,6 +415,8 @@
         return AMEDIA_ERROR_UNKNOWN;
     }
 
+    callback->onHeartBeat(clientId, sessionId);
+
     media_status_t err = mTranscoder->configureSource(srcFdInt);
     if (err != AMEDIA_OK) {
         ALOGE("failed to configure source: %d", err);
@@ -412,6 +424,8 @@
         return err;
     }
 
+    callback->onHeartBeat(clientId, sessionId);
+
     std::vector<std::shared_ptr<AMediaFormat>> trackFormats = mTranscoder->getTrackFormats();
     if (trackFormats.size() == 0) {
         ALOGE("failed to get track formats!");
@@ -419,6 +433,8 @@
         return AMEDIA_ERROR_MALFORMED;
     }
 
+    callback->onHeartBeat(clientId, sessionId);
+
     for (int i = 0; i < trackFormats.size(); ++i) {
         std::shared_ptr<AMediaFormat> format;
         const char* mime = nullptr;
@@ -437,6 +453,8 @@
             *failureReason = TranscodingLogger::SessionEndedReason::CONFIG_TRACK_FAILED;
             return err;
         }
+
+        callback->onHeartBeat(clientId, sessionId);
     }
 
     err = mTranscoder->configureDestination(dstFdInt);
@@ -446,6 +464,8 @@
         return err;
     }
 
+    callback->onHeartBeat(clientId, sessionId);
+
     return AMEDIA_OK;
 }
 
diff --git a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp b/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
index 88c1c42..10b2e80 100644
--- a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
+++ b/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
@@ -328,8 +328,8 @@
                 }
                 lastProgressUpdate = progress;
             }
-            progressSinceLastReport = true;
         }
+        progressSinceLastReport = true;
     }
 
     return AMEDIA_OK;
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
index 413f049..879241e 100644
--- a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
@@ -158,6 +158,11 @@
         return;
     }
 
+    // The sample writer is not yet started so notify the caller that progress is still made.
+    if (mHeartBeatIntervalUs > 0) {
+        mCallbacks->onHeartBeat(this);
+    }
+
     MediaTrackTranscoder* mutableTranscoder = const_cast<MediaTrackTranscoder*>(transcoder);
     mutableTranscoder->setSampleConsumer(consumer);