blob: ca5b959b5df7086e549e17ff4157373125c51ad8 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.mediav2.cts;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.util.Log;
import android.util.Pair;
import android.view.Surface;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(Parameterized.class)
public class CodecEncoderSurfaceTest {
private static final String LOG_TAG = CodecEncoderSurfaceTest.class.getSimpleName();
private static final String mInpPrefix = WorkDir.getMediaDirString();
private static final boolean ENABLE_LOGS = false;
private final String mCompName;
private final String mMime;
private final String mTestFile;
private final int mBitrate;
private final int mFrameRate;
private final int mMaxBFrames;
private int mLatency;
private boolean mReviseLatency;
private MediaFormat mEncoderFormat;
private MediaExtractor mExtractor;
private MediaCodec mEncoder;
private CodecAsyncHandler mAsyncHandleEncoder;
private String mDecoderName;
private MediaCodec mDecoder;
private MediaFormat mDecoderFormat;
private CodecAsyncHandler mAsyncHandleDecoder;
private boolean mIsCodecInAsyncMode;
private boolean mSignalEOSWithLastFrame;
private boolean mSawDecInputEOS;
private boolean mSawDecOutputEOS;
private boolean mSawEncOutputEOS;
private int mDecInputCount;
private int mDecOutputCount;
private int mEncOutputCount;
private boolean mSaveToMem;
private OutputManager mOutputBuff;
private Surface mSurface;
private MediaMuxer mMuxer;
private int mTrackID = -1;
static {
android.os.Bundle args = InstrumentationRegistry.getArguments();
CodecTestBase.mimeSelKeys = args.getString(CodecTestBase.MIME_SEL_KEY);
}
public CodecEncoderSurfaceTest(String encoder, String mime, String testFile, int bitrate,
int frameRate) {
mCompName = encoder;
mMime = mime;
mTestFile = testFile;
mBitrate = bitrate;
mFrameRate = frameRate;
mMaxBFrames = 0;
mLatency = mMaxBFrames;
mReviseLatency = false;
mAsyncHandleDecoder = new CodecAsyncHandler();
mAsyncHandleEncoder = new CodecAsyncHandler();
}
@Before
public void setUp() throws IOException {
if (mCompName.startsWith(CodecTestBase.INVALID_CODEC)) {
fail("no valid component available for current test ");
}
mDecoderFormat = setUpSource(mTestFile);
ArrayList<MediaFormat> decoderFormatList = new ArrayList<>();
decoderFormatList.add(mDecoderFormat);
String decoderMediaType = mDecoderFormat.getString(MediaFormat.KEY_MIME);
if (CodecTestBase.doesAnyFormatHaveHDRProfile(decoderMediaType, decoderFormatList) ||
mTestFile.contains("10bit")) {
// Check if encoder is capable of supporting HDR profiles.
// Previous check doesn't verify this as profile isn't set in the format
Assume.assumeTrue(mCompName + " doesn't support HDR encoding",
CodecTestBase.doesCodecSupportHDRProfile(mCompName, mMime));
}
MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
mDecoderName = codecList.findDecoderForFormat(mDecoderFormat);
Assume.assumeNotNull(mDecoderFormat.toString() + " not supported by any decoder.",
mDecoderName);
mEncoderFormat = setUpEncoderFormat(mDecoderFormat);
}
@Parameterized.Parameters(name = "{index}({0}_{1})")
public static Collection<Object[]> input() {
final boolean isEncoder = true;
final boolean needAudio = false;
final boolean needVideo = true;
final List<Object[]> exhaustiveArgsList = new ArrayList<>(Arrays.asList(new Object[][]{
// Video - CodecMime, test file, bit rate, frame rate
{MediaFormat.MIMETYPE_VIDEO_H263, "bbb_176x144_128kbps_15fps_h263.3gp", 128000, 15},
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_128x96_64kbps_12fps_mpeg4.mp4", 64000, 12},
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_cif_768kbps_30fps_avc.mp4", 512000, 30},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_cif_768kbps_30fps_avc.mp4", 512000, 30},
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_cif_768kbps_30fps_avc.mp4", 512000, 30},
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_cif_768kbps_30fps_avc.mp4", 512000, 30},
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_cif_768kbps_30fps_avc.mp4", 512000, 30},
}));
// P010 support was added in Android T, hence limit the following tests to Android T and
// above
if (CodecTestBase.IS_AT_LEAST_T) {
exhaustiveArgsList.addAll(Arrays.asList(new Object[][]{
{MediaFormat.MIMETYPE_VIDEO_AVC, "cosmat_520x390_24fps_crf22_avc_10bit.mkv",
512000, 30},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "cosmat_520x390_24fps_crf22_hevc_10bit.mkv",
512000, 30},
{MediaFormat.MIMETYPE_VIDEO_VP9, "cosmat_520x390_24fps_crf22_vp9_10bit.mkv",
512000, 30},
{MediaFormat.MIMETYPE_VIDEO_AV1, "cosmat_520x390_24fps_768kbps_av1_10bit.mkv",
512000, 30},
}));
}
return CodecTestBase.prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo,
true);
}
private boolean hasSeenError() {
return mAsyncHandleDecoder.hasSeenError() || mAsyncHandleEncoder.hasSeenError();
}
private MediaFormat setUpSource(String srcFile) throws IOException {
mExtractor = new MediaExtractor();
mExtractor.setDataSource(mInpPrefix + srcFile);
for (int trackID = 0; trackID < mExtractor.getTrackCount(); trackID++) {
MediaFormat format = mExtractor.getTrackFormat(trackID);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) {
mExtractor.selectTrack(trackID);
ArrayList<MediaFormat> formatList = new ArrayList<>();
formatList.add(format);
boolean selectHBD = CodecTestBase.doesAnyFormatHaveHDRProfile(mime, formatList) ||
srcFile.contains("10bit");
if (selectHBD) {
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010);
} else {
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
}
return format;
}
}
mExtractor.release();
fail("No video track found in file: " + srcFile);
return null;
}
private void resetContext(boolean isAsync, boolean signalEOSWithLastFrame) {
mAsyncHandleDecoder.resetContext();
mAsyncHandleEncoder.resetContext();
mIsCodecInAsyncMode = isAsync;
mSignalEOSWithLastFrame = signalEOSWithLastFrame;
mSawDecInputEOS = false;
mSawDecOutputEOS = false;
mSawEncOutputEOS = false;
mDecInputCount = 0;
mDecOutputCount = 0;
mEncOutputCount = 0;
}
private void configureCodec(MediaFormat decFormat, MediaFormat encFormat, boolean isAsync,
boolean signalEOSWithLastFrame) {
resetContext(isAsync, signalEOSWithLastFrame);
mAsyncHandleEncoder.setCallBack(mEncoder, isAsync);
mEncoder.configure(encFormat, null, MediaCodec.CONFIGURE_FLAG_ENCODE, null);
if (mEncoder.getInputFormat().containsKey(MediaFormat.KEY_LATENCY)) {
mReviseLatency = true;
mLatency = mEncoder.getInputFormat().getInteger(MediaFormat.KEY_LATENCY);
}
mSurface = mEncoder.createInputSurface();
assertTrue("Surface is not valid", mSurface.isValid());
mAsyncHandleDecoder.setCallBack(mDecoder, isAsync);
mDecoder.configure(decFormat, mSurface, null, 0);
if (ENABLE_LOGS) {
Log.v(LOG_TAG, "codec configured");
}
}
private void enqueueDecoderEOS(int bufferIndex) {
if (!mSawDecInputEOS) {
mDecoder.queueInputBuffer(bufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
mSawDecInputEOS = true;
if (ENABLE_LOGS) {
Log.v(LOG_TAG, "Queued End of Stream");
}
}
}
private void enqueueDecoderInput(int bufferIndex) {
if (mExtractor.getSampleSize() < 0) {
enqueueDecoderEOS(bufferIndex);
} else {
ByteBuffer inputBuffer = mDecoder.getInputBuffer(bufferIndex);
mExtractor.readSampleData(inputBuffer, 0);
int size = (int) mExtractor.getSampleSize();
long pts = mExtractor.getSampleTime();
int extractorFlags = mExtractor.getSampleFlags();
int codecFlags = 0;
if ((extractorFlags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
codecFlags |= MediaCodec.BUFFER_FLAG_KEY_FRAME;
}
if ((extractorFlags & MediaExtractor.SAMPLE_FLAG_PARTIAL_FRAME) != 0) {
codecFlags |= MediaCodec.BUFFER_FLAG_PARTIAL_FRAME;
}
if (!mExtractor.advance() && mSignalEOSWithLastFrame) {
codecFlags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
mSawDecInputEOS = true;
}
if (ENABLE_LOGS) {
Log.v(LOG_TAG, "input: id: " + bufferIndex + " size: " + size + " pts: " + pts +
" flags: " + codecFlags);
}
mDecoder.queueInputBuffer(bufferIndex, 0, size, pts, codecFlags);
if (size > 0 && (codecFlags & (MediaCodec.BUFFER_FLAG_CODEC_CONFIG |
MediaCodec.BUFFER_FLAG_PARTIAL_FRAME)) == 0) {
mOutputBuff.saveInPTS(pts);
mDecInputCount++;
}
}
}
private void dequeueDecoderOutput(int bufferIndex, MediaCodec.BufferInfo info) {
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mSawDecOutputEOS = true;
}
if (ENABLE_LOGS) {
Log.v(LOG_TAG, "output: id: " + bufferIndex + " flags: " + info.flags + " size: " +
info.size + " timestamp: " + info.presentationTimeUs);
}
if (info.size > 0 && (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
mDecOutputCount++;
}
mDecoder.releaseOutputBuffer(bufferIndex, mSurface != null);
}
private void dequeueEncoderOutput(int bufferIndex, MediaCodec.BufferInfo info) {
if (ENABLE_LOGS) {
Log.v(LOG_TAG, "encoder output: id: " + bufferIndex + " flags: " + info.flags +
" size: " + info.size + " timestamp: " + info.presentationTimeUs);
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
mSawEncOutputEOS = true;
}
if (info.size > 0) {
ByteBuffer buf = mEncoder.getOutputBuffer(bufferIndex);
if (mSaveToMem) {
mOutputBuff.saveToMemory(buf, info);
}
if (mMuxer != null) {
if (mTrackID == -1) {
mTrackID = mMuxer.addTrack(mEncoder.getOutputFormat());
mMuxer.start();
}
mMuxer.writeSampleData(mTrackID, buf, info);
}
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
mOutputBuff.saveOutPTS(info.presentationTimeUs);
mEncOutputCount++;
}
}
mEncoder.releaseOutputBuffer(bufferIndex, false);
}
private void tryEncoderOutput(long timeOutUs) throws InterruptedException {
if (mIsCodecInAsyncMode) {
if (!hasSeenError() && !mSawEncOutputEOS) {
int retry = 0;
while (mReviseLatency) {
if (mAsyncHandleEncoder.hasOutputFormatChanged()) {
mReviseLatency = false;
int actualLatency = mAsyncHandleEncoder.getOutputFormat()
.getInteger(MediaFormat.KEY_LATENCY, mLatency);
if (mLatency < actualLatency) {
mLatency = actualLatency;
return;
}
} else {
if (retry > CodecTestBase.RETRY_LIMIT) throw new InterruptedException(
"did not receive output format changed for encoder after " +
CodecTestBase.Q_DEQ_TIMEOUT_US * CodecTestBase.RETRY_LIMIT +
" us");
Thread.sleep(CodecTestBase.Q_DEQ_TIMEOUT_US / 1000);
retry ++;
}
}
Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandleEncoder.getOutput();
if (element != null) {
dequeueEncoderOutput(element.first, element.second);
}
}
} else {
MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
if (!mSawEncOutputEOS) {
int outputBufferId = mEncoder.dequeueOutputBuffer(outInfo, timeOutUs);
if (outputBufferId >= 0) {
dequeueEncoderOutput(outputBufferId, outInfo);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
mLatency = mEncoder.getOutputFormat()
.getInteger(MediaFormat.KEY_LATENCY, mLatency);
}
}
}
}
private void waitForAllEncoderOutputs() throws InterruptedException {
if (mIsCodecInAsyncMode) {
while (!hasSeenError() && !mSawEncOutputEOS) {
tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
}
} else {
while (!mSawEncOutputEOS) {
tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
}
}
}
private void queueEOS() throws InterruptedException {
if (mIsCodecInAsyncMode) {
while (!mAsyncHandleDecoder.hasSeenError() && !mSawDecInputEOS) {
Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandleDecoder.getWork();
if (element != null) {
int bufferID = element.first;
MediaCodec.BufferInfo info = element.second;
if (info != null) {
dequeueDecoderOutput(bufferID, info);
} else {
enqueueDecoderEOS(element.first);
}
}
}
} else {
MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
while (!mSawDecInputEOS) {
int outputBufferId =
mDecoder.dequeueOutputBuffer(outInfo, CodecTestBase.Q_DEQ_TIMEOUT_US);
if (outputBufferId >= 0) {
dequeueDecoderOutput(outputBufferId, outInfo);
}
int inputBufferId = mDecoder.dequeueInputBuffer(CodecTestBase.Q_DEQ_TIMEOUT_US);
if (inputBufferId != -1) {
enqueueDecoderEOS(inputBufferId);
}
}
}
if (mIsCodecInAsyncMode) {
while (!hasSeenError() && !mSawDecOutputEOS) {
Pair<Integer, MediaCodec.BufferInfo> decOp = mAsyncHandleDecoder.getOutput();
if (decOp != null) dequeueDecoderOutput(decOp.first, decOp.second);
if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
if (mDecOutputCount - mEncOutputCount > mLatency) {
tryEncoderOutput(-1);
}
}
} else {
MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
while (!mSawDecOutputEOS) {
int outputBufferId =
mDecoder.dequeueOutputBuffer(outInfo, CodecTestBase.Q_DEQ_TIMEOUT_US);
if (outputBufferId >= 0) {
dequeueDecoderOutput(outputBufferId, outInfo);
}
if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
if (mDecOutputCount - mEncOutputCount > mLatency) {
tryEncoderOutput(-1);
}
}
}
}
private void doWork(int frameLimit) throws InterruptedException {
int frameCnt = 0;
if (mIsCodecInAsyncMode) {
// dequeue output after inputEOS is expected to be done in waitForAllOutputs()
while (!hasSeenError() && !mSawDecInputEOS && frameCnt < frameLimit) {
Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandleDecoder.getWork();
if (element != null) {
int bufferID = element.first;
MediaCodec.BufferInfo info = element.second;
if (info != null) {
// <id, info> corresponds to output callback. Handle it accordingly
dequeueDecoderOutput(bufferID, info);
} else {
// <id, null> corresponds to input callback. Handle it accordingly
enqueueDecoderInput(bufferID);
frameCnt++;
}
}
// check decoder EOS
if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
// encoder output
if (mDecOutputCount - mEncOutputCount > mLatency) {
tryEncoderOutput(-1);
}
}
} else {
MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
while (!mSawDecInputEOS && frameCnt < frameLimit) {
// decoder input
int inputBufferId = mDecoder.dequeueInputBuffer(CodecTestBase.Q_DEQ_TIMEOUT_US);
if (inputBufferId != -1) {
enqueueDecoderInput(inputBufferId);
frameCnt++;
}
// decoder output
int outputBufferId =
mDecoder.dequeueOutputBuffer(outInfo, CodecTestBase.Q_DEQ_TIMEOUT_US);
if (outputBufferId >= 0) {
dequeueDecoderOutput(outputBufferId, outInfo);
}
// check decoder EOS
if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
// encoder output
if (mDecOutputCount - mEncOutputCount > mLatency) {
tryEncoderOutput(-1);
}
}
}
}
private MediaFormat setUpEncoderFormat(MediaFormat decoderFormat) {
MediaFormat encoderFormat = new MediaFormat();
encoderFormat.setString(MediaFormat.KEY_MIME, mMime);
encoderFormat.setInteger(MediaFormat.KEY_WIDTH,
decoderFormat.getInteger(MediaFormat.KEY_WIDTH));
encoderFormat.setInteger(MediaFormat.KEY_HEIGHT,
decoderFormat.getInteger(MediaFormat.KEY_HEIGHT));
encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
encoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitrate);
encoderFormat.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 1.0f);
encoderFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
encoderFormat.setInteger(MediaFormat.KEY_MAX_B_FRAMES, mMaxBFrames);
return encoderFormat;
}
/**
* Tests listed encoder components for sync and async mode in surface mode.The output has to
* be consistent (not flaky) in all runs.
*/
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
public void testSimpleEncodeFromSurface() throws IOException, InterruptedException {
mDecoder = MediaCodec.createByCodecName(mDecoderName);
boolean muxOutput = true;
{
mEncoder = MediaCodec.createByCodecName(mCompName);
/* TODO(b/149027258) */
mSaveToMem = false;
OutputManager ref = new OutputManager();
OutputManager test = new OutputManager();
int loopCounter = 0;
boolean[] boolStates = {true, false};
for (boolean isAsync : boolStates) {
mExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
mOutputBuff = loopCounter == 0 ? ref : test;
mOutputBuff.reset();
if (muxOutput && loopCounter == 0) {
String tmpPath;
int muxerFormat;
if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP8) ||
mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM;
tmpPath = File.createTempFile("tmp", ".webm").getAbsolutePath();
} else {
muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4;
tmpPath = File.createTempFile("tmp", ".mp4").getAbsolutePath();
}
mMuxer = new MediaMuxer(tmpPath, muxerFormat);
}
configureCodec(mDecoderFormat, mEncoderFormat, isAsync, false);
mEncoder.start();
mDecoder.start();
doWork(Integer.MAX_VALUE);
queueEOS();
waitForAllEncoderOutputs();
if (muxOutput) {
if (mTrackID != -1) {
mMuxer.stop();
mTrackID = -1;
}
if (mMuxer != null) {
mMuxer.release();
mMuxer = null;
}
}
/* TODO(b/147348711) */
if (false) mDecoder.stop();
else mDecoder.reset();
/* TODO(b/147348711) */
if (false) mEncoder.stop();
else mEncoder.reset();
String log = String.format(
"format: %s \n codec: %s, file: %s, mode: %s:: ",
mEncoderFormat, mCompName, mTestFile, (isAsync ? "async" : "sync"));
assertTrue(log + " unexpected error", !hasSeenError());
assertTrue(log + "no input sent", 0 != mDecInputCount);
assertTrue(log + "no decoder output received", 0 != mDecOutputCount);
assertTrue(log + "no encoder output received", 0 != mEncOutputCount);
assertTrue(log + "decoder input count != output count, act/exp: " +
mDecOutputCount +
" / " + mDecInputCount, mDecInputCount == mDecOutputCount);
/* TODO(b/153127506)
* Currently disabling all encoder output checks. Added checks only for encoder
* timeStamp is in increasing order or not.
* Once issue is fixed remove increasing timestamp check and enable encoder checks.
*/
/*assertTrue(log + "encoder output count != decoder output count, act/exp: " +
mEncOutputCount + " / " + mDecOutputCount,
mEncOutputCount == mDecOutputCount);
if (loopCounter != 0) {
assertTrue(log + "encoder output is flaky", ref.equals(test));
} else {
assertTrue(log + " input pts list and output pts list are not identical",
ref.isOutPtsListIdenticalToInpPtsList((false)));
}*/
if (loopCounter != 0) {
assertTrue("test output pts is not strictly increasing",
test.isPtsStrictlyIncreasing(Long.MIN_VALUE));
} else {
assertTrue("ref output pts is not strictly increasing",
ref.isPtsStrictlyIncreasing(Long.MIN_VALUE));
}
loopCounter++;
mSurface.release();
mSurface = null;
}
mEncoder.release();
}
mDecoder.release();
mExtractor.release();
}
private native boolean nativeTestSimpleEncode(String encoder, String decoder, String mime,
String testFile, String muxFile, int bitrate, int framerate, int colorFormat);
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
public void testSimpleEncodeFromSurfaceNative() throws IOException {
{
String tmpPath;
if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP8) ||
mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
tmpPath = File.createTempFile("tmp", ".webm").getAbsolutePath();
} else {
tmpPath = File.createTempFile("tmp", ".mp4").getAbsolutePath();
}
int colorFormat = mDecoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT, -1);
assertTrue(nativeTestSimpleEncode(mCompName, mDecoderName, mMime,
mInpPrefix + mTestFile, tmpPath, mBitrate, mFrameRate, colorFormat));
}
}
}