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