Transcoder: Added MediaTranscoder and unit test.

MediaTranscoder is the API for the native transcoding library.

Test: Unit tests.
Bug: 156003955, 152091443, 155918341
Change-Id: I24b52d174db0faecea8f331ef6d8a3dc4e473c4e
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index 311e9be..3818545 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -30,6 +30,11 @@
 static_assert(SAMPLE_FLAG_PARTIAL_FRAME == AMEDIACODEC_BUFFER_FLAG_PARTIAL_FRAME,
               "Sample flag mismatch: PARTIAL_FRAME");
 
+// Color format defined by surface. (See MediaCodecInfo.CodecCapabilities#COLOR_FormatSurface.)
+static constexpr int32_t kColorFormatSurface = 0x7f000789;
+// Default key frame interval in seconds.
+static constexpr float kDefaultKeyFrameIntervalSeconds = 1.0f;
+
 template <typename T>
 void VideoTrackTranscoder::BlockingQueue<T>::push(T const& value, bool front) {
     {
@@ -113,11 +118,24 @@
     media_status_t status = AMEDIA_OK;
 
     if (destinationFormat == nullptr) {
-        LOG(ERROR) << "Destination format is null";
+        LOG(ERROR) << "Destination format is null, use passthrough transcoder";
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
-    mDestinationFormat = destinationFormat;
+    AMediaFormat* encoderFormat = AMediaFormat_new();
+    if (!encoderFormat || AMediaFormat_copy(encoderFormat, destinationFormat.get()) != AMEDIA_OK) {
+        LOG(ERROR) << "Unable to copy destination format";
+        return AMEDIA_ERROR_INVALID_PARAMETER;
+    }
+
+    float tmp;
+    if (!AMediaFormat_getFloat(encoderFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, &tmp)) {
+        AMediaFormat_setFloat(encoderFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+                              kDefaultKeyFrameIntervalSeconds);
+    }
+    AMediaFormat_setInt32(encoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, kColorFormatSurface);
+
+    mDestinationFormat = std::shared_ptr<AMediaFormat>(encoderFormat, &AMediaFormat_delete);
 
     // Create and configure the encoder.
     const char* destinationMime = nullptr;
@@ -276,7 +294,7 @@
         sample->info.flags = bufferInfo.flags;
         sample->info.presentationTimeUs = bufferInfo.presentationTimeUs;
 
-        const bool aborted = mOutputQueue.enqueue(sample);
+        const bool aborted = mOutputQueue->enqueue(sample);
         if (aborted) {
             LOG(ERROR) << "Output sample queue was aborted. Stopping transcode.";
             mStatus = AMEDIA_ERROR_IO;  // TODO: Define custom error codes?
@@ -321,7 +339,8 @@
     }
 
     AMediaCodec_stop(mDecoder);
-    AMediaCodec_stop(mEncoder.get());
+    // TODO: Stop invalidates all buffers. Stop encoder when last buffer is released.
+    //    AMediaCodec_stop(mEncoder.get());
     return mStatus;
 }
 
@@ -330,4 +349,8 @@
     mCodecMessageQueue.push([this] { mStopRequested = true; }, true /* front */);
 }
 
+std::shared_ptr<AMediaFormat> VideoTrackTranscoder::getOutputFormat() const {
+    return mDestinationFormat;
+}
+
 }  // namespace android