Merge "Benchmark: Add support to configure encoders through test parameters" am: 239061853d
Change-Id: I96f09ee77fbf4c4a91e1ddb71d302d01ed352c18
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
index 48e1422..4202732 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
@@ -34,6 +34,7 @@
import com.android.media.benchmark.library.Native;
import com.android.media.benchmark.library.Stats;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,40 +58,87 @@
public class EncoderTest {
private static final Context mContext =
InstrumentationRegistry.getInstrumentation().getTargetContext();
+ private static final String mFileDirPath = mContext.getFilesDir() + "/";
private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
private static final String mOutputFilePath = mContext.getString(R.string.output_file_path);
private static final String mStatsFile =
mContext.getExternalFilesDir(null) + "/Encoder." + System.currentTimeMillis() + ".csv";
private static final String TAG = "EncoderTest";
- private static final long PER_TEST_TIMEOUT_MS = 120000;
private static final boolean DEBUG = false;
private static final boolean WRITE_OUTPUT = false;
+ private static final long PER_TEST_TIMEOUT_MS = 120000;
private static final int ENCODE_DEFAULT_FRAME_RATE = 25;
- private static final int ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
- private static final int ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
+ private static final int ENCODE_DEFAULT_VIDEO_BIT_RATE = 8000000 /* 8 Mbps */;
+ private static final int ENCODE_MIN_VIDEO_BIT_RATE = 600000 /* 600 Kbps */;
private static final int ENCODE_DEFAULT_AUDIO_BIT_RATE = 128000 /* 128 Kbps */;
+ private static int mColorFormat = COLOR_FormatYUV420Flexible;
+ private static File mDecodedFileQcif;
+ private static File mDecodedFileFullHd;
+ private static File mDecodedFileAudio;
private String mInputFile;
+ private String mMime;
+ private int mBitRate;
+ private int mIFrameInterval;
+ private int mWidth;
+ private int mHeight;
+ private int mProfile;
+ private int mLevel;
+ private int mSampleRate;
+ private int mNumChannel;
+ private static final String DECODE_FULLHD_INPUT = "crowd_1920x1080_25fps_4000kbps_h265.mkv";
+ private static final String DECODE_QCIF_INPUT = "crowd_176x144_25fps_6000kbps_mpeg4.mp4";
+ private static final String DECODE_AUDIO_INPUT = "bbb_48000hz_2ch_100kbps_opus_30sec.webm";
+ private static final String DECODE_FULLHD_UNPACKED = "crowd_1920x1080_25fps_4000kbps_h265.yuv";
+ private static final String DECODE_QCIF_UNPACKED = "crowd_176x144_25fps_6000kbps_mpeg4.yuv";
+ private static final String DECODE_AUDIO_UNPACKED = "bbb_48000hz_2ch_100kbps_opus_30sec.raw";
@Parameterized.Parameters
public static Collection<Object[]> inputFiles() {
return Arrays.asList(new Object[][]{
// Audio Test
- {"bbb_44100hz_2ch_128kbps_aac_30sec.mp4"},
- {"bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp"},
- {"bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp"},
- {"bbb_44100hz_2ch_600kbps_flac_30sec.mp4"},
- {"bbb_48000hz_2ch_100kbps_opus_30sec.webm"},
+ // Parameters: Filename, mimeType, bitrate, width, height, iFrameInterval,
+ // profile, level, sampleRate, channelCount
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AAC,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 44100, 2},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AMR_NB,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 8000, 1},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AMR_WB,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 16000, 1},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_FLAC,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 44100, 2},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_OPUS,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 48000, 2},
+
// Video Test
- {"crowd_1920x1080_25fps_4000kbps_vp8.webm"},
- {"crowd_1920x1080_25fps_6700kbps_h264.ts"},
- {"crowd_1920x1080_25fps_4000kbps_h265.mkv"},
- {"crowd_1920x1080_25fps_4000kbps_vp9.webm"},
- {"crowd_176x144_25fps_6000kbps_mpeg4.mp4"},
- {"crowd_176x144_25fps_6000kbps_h263.3gp"}});
+ // Parameters: Filename, mimeType, bitrate, width, height, iFrameInterval,
+ // profile, level, sampleRate, channelCount
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_VP8,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_AVC,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_HEVC,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_VP9,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_QCIF_UNPACKED, MediaFormat.MIMETYPE_VIDEO_MPEG4, ENCODE_MIN_VIDEO_BIT_RATE,
+ 176, 144, 1, -1, -1, -1, -1},
+ {DECODE_QCIF_UNPACKED, MediaFormat.MIMETYPE_VIDEO_H263, ENCODE_MIN_VIDEO_BIT_RATE,
+ 176, 144, 1, -1, -1, -1, -1}});
}
- public EncoderTest(String inputFileName) {
- this.mInputFile = inputFileName;
+ public EncoderTest(String filename, String mime, int bitrate, int width, int height,
+ int frameInterval, int profile, int level, int samplerate,
+ int channelCount) {
+ this.mInputFile = filename;
+ this.mMime = mime;
+ this.mBitRate = bitrate;
+ this.mIFrameInterval = frameInterval;
+ this.mWidth = width;
+ this.mHeight = height;
+ this.mProfile = profile;
+ this.mLevel = level;
+ this.mSampleRate = samplerate;
+ this.mNumChannel = channelCount;
}
@BeforeClass
@@ -101,33 +149,36 @@
Log.d(TAG, "Saving Benchmark results in: " + mStatsFile);
}
- @Test(timeout = PER_TEST_TIMEOUT_MS)
- public void testEncoder() throws Exception {
- int status;
- int frameSize;
- //Parameters for video
- int width = 0;
- int height = 0;
- int profile = 0;
- int level = 0;
- int frameRate = 0;
+ @BeforeClass
+ public static void prepareInput() throws IOException {
- //Parameters for audio
- int bitRate = 0;
- int sampleRate = 0;
- int numChannels = 0;
- File inputFile = new File(mInputFilePath + mInputFile);
- assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
- inputFile.exists());
+ mDecodedFileFullHd = new File(mFileDirPath + DECODE_FULLHD_UNPACKED);
+ int status = decodeFile(mInputFilePath + DECODE_FULLHD_INPUT, mDecodedFileFullHd);
+ assertEquals("Decoder returned error " + status, 0, status);
+
+ mDecodedFileQcif = new File(mFileDirPath + DECODE_QCIF_UNPACKED);
+ status = decodeFile(mInputFilePath + DECODE_QCIF_INPUT, mDecodedFileQcif);
+ assertEquals("Decoder returned error " + status, 0, status);
+
+ mDecodedFileAudio = new File(mFileDirPath + DECODE_AUDIO_UNPACKED);
+ status = decodeFile(mInputFilePath + DECODE_AUDIO_INPUT, mDecodedFileAudio);
+ assertEquals("Decoder returned error " + status, 0, status);
+ }
+
+ private static int decodeFile(String inputFileName, File outputDecodeFile) throws IOException {
+ int status = -1;
+ File inputFile = new File(inputFileName);
+ assertTrue("Cannot open input file " + inputFileName, inputFile.exists());
FileInputStream fileInput = new FileInputStream(inputFile);
FileDescriptor fileDescriptor = fileInput.getFD();
+ FileOutputStream decodeOutputStream = new FileOutputStream(outputDecodeFile);
+
Extractor extractor = new Extractor();
int trackCount = extractor.setUpExtractor(fileDescriptor);
- assertTrue("Extraction failed. No tracks for file: " + mInputFile, (trackCount > 0));
+ assertTrue("Extraction failed. No tracks for the given input file", (trackCount > 0));
ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
- int colorFormat = COLOR_FormatYUV420Flexible;
extractor.selectExtractorTrack(currentTrack);
MediaFormat format = extractor.getFormat(currentTrack);
// Get samples from extractor
@@ -146,163 +197,135 @@
bufInfo.presentationTimeUs + " size = " + bufInfo.size);
}
} while (sampleSize > 0);
- int tid = android.os.Process.myTid();
- File decodedFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
- FileOutputStream decodeOutputStream = new FileOutputStream(decodedFile);
Decoder decoder = new Decoder();
decoder.setupDecoder(decodeOutputStream);
status = decoder.decode(inputBuffer, frameInfo, false, format, "");
- assertEquals("Decoder returned error " + status + " for file: " + mInputFile, 0,
- status);
MediaFormat decoderFormat = decoder.getFormat();
+ if (decoderFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
+ mColorFormat = decoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
+ }
decoder.deInitCodec();
extractor.unselectExtractorTrack(currentTrack);
inputBuffer.clear();
frameInfo.clear();
- if (decodeOutputStream != null) {
- decodeOutputStream.close();
- }
- String mime = format.getString(MediaFormat.KEY_MIME);
- ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
- assertTrue("No suitable codecs found for file: " + mInputFile + " track : " +
- currentTrack + " mime: " + mime, (mediaCodecs.size() > 0));
- Boolean[] encodeMode = {true, false};
- /* Encoding the decoder's output */
- for (Boolean asyncMode : encodeMode) {
- for (String codecName : mediaCodecs) {
- FileOutputStream encodeOutputStream = null;
- if (WRITE_OUTPUT) {
- File outEncodeFile = new File(mOutputFilePath + "encoder.out");
- if (outEncodeFile.exists()) {
- assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
- outEncodeFile.delete());
- }
- assertTrue("Unable to create file to write encoder output: " +
- outEncodeFile.toString(), outEncodeFile.createNewFile());
- encodeOutputStream = new FileOutputStream(outEncodeFile);
- }
- File rawFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
- assertTrue("Cannot open file to write decoded output", rawFile.exists());
- if (DEBUG) {
- Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
- }
- FileInputStream eleStream = new FileInputStream(rawFile);
- if (mime.startsWith("video/")) {
- width = format.getInteger(MediaFormat.KEY_WIDTH);
- height = format.getInteger(MediaFormat.KEY_HEIGHT);
- if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
- frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
- } else if (frameRate <= 0) {
- frameRate = ENCODE_DEFAULT_FRAME_RATE;
- }
- if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
- bitRate = format.getInteger(MediaFormat.KEY_BIT_RATE);
- } else if (bitRate <= 0) {
- if (mime.contains("video/3gpp") || mime.contains("video/mp4v-es")) {
- bitRate = ENCODE_MIN_BIT_RATE;
- } else {
- bitRate = ENCODE_DEFAULT_BIT_RATE;
- }
- }
- if (format.containsKey(MediaFormat.KEY_PROFILE)) {
- profile = format.getInteger(MediaFormat.KEY_PROFILE);
- }
- if (format.containsKey(MediaFormat.KEY_PROFILE)) {
- level = format.getInteger(MediaFormat.KEY_LEVEL);
- }
- if (decoderFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
- colorFormat = decoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
- }
- } else {
- sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
- numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
- if (decoderFormat.containsKey(MediaFormat.KEY_BIT_RATE)) {
- bitRate = decoderFormat.getInteger(MediaFormat.KEY_BIT_RATE);
- } else {
- bitRate = ENCODE_DEFAULT_AUDIO_BIT_RATE;
- }
- }
- /*Setup Encode Format*/
- MediaFormat encodeFormat;
- if (mime.startsWith("video/")) {
- frameSize = width * height * 3 / 2;
- encodeFormat = MediaFormat.createVideoFormat(mime, width, height);
- encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
- encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
- encodeFormat.setInteger(MediaFormat.KEY_PROFILE, profile);
- encodeFormat.setInteger(MediaFormat.KEY_LEVEL, level);
- encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
- encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, frameSize);
- encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
- } else {
- encodeFormat = MediaFormat.createAudioFormat(mime, sampleRate, numChannels);
- encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
- frameSize = 4096;
- }
- Encoder encoder = new Encoder();
- encoder.setupEncoder(encodeOutputStream, eleStream);
- status = encoder.encode(codecName, encodeFormat, mime, frameRate, sampleRate,
- frameSize, asyncMode);
- encoder.deInitEncoder();
- assertEquals(
- codecName + " encoder returned error " + status + " for " + "file:" +
- " " + mInputFile, 0, status);
- encoder.dumpStatistics(mInputFile, codecName, (asyncMode ? "async" : "sync"),
- extractor.getClipDuration(), mStatsFile);
- Log.i(TAG, "Encoding complete for file: " + mInputFile + " with codec: " +
- codecName + " for aSyncMode = " + asyncMode);
- encoder.resetEncoder();
- eleStream.close();
- if (encodeOutputStream != null) {
- encodeOutputStream.close();
- }
-
- }
- }
- //Cleanup temporary input file
- if (decodedFile.exists()) {
- assertTrue(" Unable to delete decoded file" + decodedFile.toString(),
- decodedFile.delete());
- Log.i(TAG, "Successfully deleted decoded file");
- }
}
extractor.deinitExtractor();
fileInput.close();
+ decodeOutputStream.close();
+ return status;
}
@Test(timeout = PER_TEST_TIMEOUT_MS)
- public void testNativeEncoder() throws Exception {
- File inputFile = new File(mInputFilePath + mInputFile);
- assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
- inputFile.exists());
- int tid = android.os.Process.myTid();
- final String mDecodedFile = mContext.getFilesDir() + "/decoder_" + tid + ".out";
- FileInputStream fileInput = new FileInputStream(inputFile);
- FileDescriptor fileDescriptor = fileInput.getFD();
- Extractor extractor = new Extractor();
- int trackCount = extractor.setUpExtractor(fileDescriptor);
- assertTrue("Extraction failed. No tracks for file: ", trackCount > 0);
- for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
- extractor.selectExtractorTrack(currentTrack);
- MediaFormat format = extractor.getFormat(currentTrack);
- String mime = format.getString(MediaFormat.KEY_MIME);
- ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
- // Encoding the decoder's output
+ public void testEncoder() throws Exception {
+ int status;
+ int frameSize;
+
+ ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mMime, true);
+ assertTrue("No suitable codecs found for mimetype: " + mMime, (mediaCodecs.size() > 0));
+ Boolean[] encodeMode = {true, false};
+ // Encoding the decoded input file
+ for (Boolean asyncMode : encodeMode) {
for (String codecName : mediaCodecs) {
- Native nativeEncoder = new Native();
- int status = nativeEncoder
- .Encode(mInputFilePath, mInputFile, mDecodedFile, mStatsFile, codecName);
+ FileOutputStream encodeOutputStream = null;
+ if (WRITE_OUTPUT) {
+ File outEncodeFile = new File(mOutputFilePath + "encoder.out");
+ if (outEncodeFile.exists()) {
+ assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
+ outEncodeFile.delete());
+ }
+ assertTrue("Unable to create file to write encoder output: " +
+ outEncodeFile.toString(), outEncodeFile.createNewFile());
+ encodeOutputStream = new FileOutputStream(outEncodeFile);
+ }
+ File rawFile = new File(mFileDirPath + mInputFile);
+ assertTrue("Cannot open decoded input file", rawFile.exists());
+ if (DEBUG) {
+ Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
+ }
+ FileInputStream eleStream = new FileInputStream(rawFile);
+ // Setup Encode Format
+ MediaFormat encodeFormat;
+ if (mMime.startsWith("video/")) {
+ frameSize = mWidth * mHeight * 3 / 2;
+ encodeFormat = MediaFormat.createVideoFormat(mMime, mWidth, mHeight);
+ encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, ENCODE_DEFAULT_FRAME_RATE);
+ encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, mIFrameInterval);
+ encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+ encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mColorFormat);
+ if (mProfile != -1 && mLevel != -1) {
+ encodeFormat.setInteger(MediaFormat.KEY_PROFILE, mProfile);
+ encodeFormat.setInteger(MediaFormat.KEY_LEVEL, mLevel);
+ }
+ } else {
+ frameSize = 4096;
+ encodeFormat = MediaFormat.createAudioFormat(mMime, mSampleRate, mNumChannel);
+ encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+ }
+ Encoder encoder = new Encoder();
+ encoder.setupEncoder(encodeOutputStream, eleStream);
+ status = encoder.encode(codecName, encodeFormat, mMime, ENCODE_DEFAULT_FRAME_RATE,
+ mSampleRate, frameSize, asyncMode);
+ encoder.deInitEncoder();
assertEquals(
- codecName + " encoder returned error " + status + " for " + "file:" + " " +
- mInputFile, 0, status);
+ codecName + " encoder returned error " + status + " for " + "mime:" + " " +
+ mMime, 0, status);
+ String inputReference;
+ long durationUs;
+ if (mMime.startsWith("video/")) {
+ inputReference =
+ mInputFile + "_" + mWidth + "x" + mHeight + "_" + mBitRate + "bps";
+ durationUs = (((eleStream.getChannel().size() + frameSize - 1) / frameSize) /
+ ENCODE_DEFAULT_FRAME_RATE) * 1000000;
+ } else {
+ inputReference = mInputFile + "_" + mSampleRate + "hz_" + mNumChannel + "ch_" +
+ mBitRate + "bps";
+ durationUs =
+ (eleStream.getChannel().size() / (mSampleRate * mNumChannel)) * 1000000;
+ }
+ encoder.dumpStatistics(inputReference, codecName, (asyncMode ? "async" : "sync"),
+ durationUs, mStatsFile);
+ Log.i(TAG, "Encoding complete for mime: " + mMime + " with codec: " + codecName +
+ " for aSyncMode = " + asyncMode);
+ encoder.resetEncoder();
+ eleStream.close();
+ if (encodeOutputStream != null) {
+ encodeOutputStream.close();
+ }
}
}
- File decodedFile = new File(mDecodedFile);
- // Cleanup temporary input file
- if (decodedFile.exists()) {
- assertTrue("Unable to delete - " + mDecodedFile, decodedFile.delete());
- Log.i(TAG, "Successfully deleted - " + mDecodedFile);
+ }
+
+ @Test(timeout = PER_TEST_TIMEOUT_MS)
+ public void testNativeEncoder() {
+ ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mMime, true);
+ assertTrue("No suitable codecs found for mimetype: " + mMime, (mediaCodecs.size() > 0));
+ for (String codecName : mediaCodecs) {
+ Native nativeEncoder = new Native();
+ int status = nativeEncoder
+ .Encode(mFileDirPath, mInputFile, mStatsFile, codecName, mMime, mBitRate,
+ mColorFormat, mIFrameInterval, mWidth, mHeight, mProfile, mLevel,
+ mSampleRate, mNumChannel);
+ assertEquals(codecName + " encoder returned error " + status + " for " + "mime:" + " " +
+ mMime, 0, status);
}
- fileInput.close();
+ }
+
+ @AfterClass
+ public static void deleteDecodedFiles() {
+ if (mDecodedFileFullHd.exists()) {
+ assertTrue(" Unable to delete decoded file" + mDecodedFileFullHd.toString(),
+ mDecodedFileFullHd.delete());
+ Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileFullHd.toString());
+ }
+ if (mDecodedFileQcif.exists()) {
+ assertTrue(" Unable to delete decoded file" + mDecodedFileQcif.toString(),
+ mDecodedFileQcif.delete());
+ Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileQcif.toString());
+ }
+ if (mDecodedFileAudio.exists()) {
+ assertTrue(" Unable to delete decoded file" + mDecodedFileAudio.toString(),
+ mDecodedFileAudio.delete());
+ Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileAudio.toString());
+ }
}
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
index 1277c8b..2f658e3 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
@@ -30,189 +30,81 @@
#include <stdio.h>
constexpr int32_t ENCODE_DEFAULT_FRAME_RATE = 25;
-constexpr int32_t ENCODE_DEFAULT_AUDIO_BIT_RATE = 128000 /* 128 Kbps */;
-constexpr int32_t ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
-constexpr int32_t ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native_Encode(
- JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jOutFilePath,
- jstring jStatsFile, jstring jCodecName) {
+ JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jStatsFile,
+ jstring jCodecName, jstring jMime, jint jBitRate, jint jColorFormat, jint jFrameInterval,
+ jint jWidth, jint jHeight, jint jProfile, jint jLevel, jint jSampleRate,
+ jint jNumChannels) {
+ UNUSED(thiz);
const char *filePath = env->GetStringUTFChars(jFilePath, nullptr);
const char *fileName = env->GetStringUTFChars(jFileName, nullptr);
- string sFilePath = string(filePath) + string(fileName);
- UNUSED(thiz);
- FILE *inputFp = fopen(sFilePath.c_str(), "rb");
- env->ReleaseStringUTFChars(jFileName, fileName);
- env->ReleaseStringUTFChars(jFilePath, filePath);
- if (!inputFp) {
- ALOGE("Unable to open input file for reading");
+ string inputFile = string(filePath) + string(fileName);
+ const char *codecName = env->GetStringUTFChars(jCodecName, nullptr);
+ string sCodecName = string(codecName);
+ const char *mime = env->GetStringUTFChars(jMime, nullptr);
+
+ ifstream eleStream;
+ eleStream.open(inputFile, ifstream::binary | ifstream::ate);
+ if (!eleStream.is_open()) {
+ ALOGE("%s - File failed to open for reading!", fileName);
+ env->ReleaseStringUTFChars(jFileName, fileName);
return -1;
}
- Decoder *decoder = new Decoder();
- Extractor *extractor = decoder->getExtractor();
- if (!extractor) {
- ALOGE("Extractor creation failed");
- return -1;
- }
+ bool asyncMode[2] = {true, false};
+ for (bool mode : asyncMode) {
+ size_t eleSize = eleStream.tellg();
+ eleStream.seekg(0, ifstream::beg);
- // Read file properties
- struct stat buf;
- stat(sFilePath.c_str(), &buf);
- size_t fileSize = buf.st_size;
- if (fileSize > kMaxBufferSize) {
- ALOGE("File size greater than maximum buffer size");
- return -1;
- }
- int32_t fd = fileno(inputFp);
- int32_t trackCount = extractor->initExtractor(fd, fileSize);
- if (trackCount <= 0) {
- ALOGE("initExtractor failed");
- return -1;
- }
+ // Set encoder params
+ encParameter encParams;
+ encParams.width = jWidth;
+ encParams.height = jHeight;
+ encParams.bitrate = jBitRate;
+ encParams.iFrameInterval = jFrameInterval;
+ encParams.sampleRate = jSampleRate;
+ encParams.numChannels = jNumChannels;
+ encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
+ encParams.colorFormat = jColorFormat;
+ encParams.profile = jProfile;
+ encParams.level = jLevel;
- for (int curTrack = 0; curTrack < trackCount; curTrack++) {
- int32_t status = extractor->setupTrackFormat(curTrack);
- if (status != 0) {
- ALOGE("Track Format invalid");
- return -1;
- }
- uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
- if (!inputBuffer) {
- ALOGE("Insufficient memory");
- return -1;
- }
- vector<AMediaCodecBufferInfo> frameInfo;
- AMediaCodecBufferInfo info;
- uint32_t inputBufferOffset = 0;
-
- // Get frame data
- while (1) {
- status = extractor->getFrameSample(info);
- if (status || !info.size) break;
- // copy the meta data and buffer to be passed to decoder
- if (inputBufferOffset + info.size > kMaxBufferSize) {
- ALOGE("Memory allocated not sufficient");
- free(inputBuffer);
- return -1;
- }
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
- frameInfo.push_back(info);
- inputBufferOffset += info.size;
- }
- string decName = "";
- const char *outputFilePath = env->GetStringUTFChars(jOutFilePath, nullptr);
- FILE *outFp = fopen(outputFilePath, "wb");
- if (outFp == nullptr) {
- ALOGE("%s - File failed to open for writing!", outputFilePath);
- free(inputBuffer);
- return -1;
- }
- decoder->setupDecoder();
- status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+ Encoder *encoder = new Encoder();
+ encoder->setupEncoder();
+ auto status = encoder->encode(sCodecName, eleStream, eleSize, mode, encParams,
+ const_cast<char *>(mime));
if (status != AMEDIA_OK) {
- ALOGE("Decode returned error");
- free(inputBuffer);
+ ALOGE("Encoder returned error");
return -1;
}
-
- AMediaFormat *decoderFormat = decoder->getFormat();
- AMediaFormat *format = extractor->getFormat();
- if (inputBuffer) {
- free(inputBuffer);
- inputBuffer = nullptr;
+ ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(), mode);
+ encoder->deInitCodec();
+ const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
+ string inputReference;
+ int64_t clipDurationUs;
+ if (!strncmp(mime, "video/", 6)) {
+ inputReference = string(fileName) + "_" + to_string(jWidth) + "x" + to_string(jHeight) +
+ "_" + to_string(jBitRate) + "bps";
+ int32_t frameSize = jWidth * jHeight * 3 / 2;
+ clipDurationUs =
+ (((eleSize + frameSize - 1) / frameSize) / ENCODE_DEFAULT_FRAME_RATE) * 1000000;
+ } else {
+ inputReference = string(fileName) + "_" + to_string(jSampleRate) + "hz_" +
+ to_string(jNumChannels) + "ch_" + to_string(jBitRate) + "bps";
+ clipDurationUs = (eleSize / (jSampleRate * jNumChannels)) * 1000000;
}
- const char *mime = nullptr;
- AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
- if (!mime) {
- ALOGE("Error in AMediaFormat_getString");
- return -1;
- }
- ifstream eleStream;
- eleStream.open(outputFilePath, ifstream::binary | ifstream::ate);
- if (!eleStream.is_open()) {
- ALOGE("%s - File failed to open for reading!", outputFilePath);
- env->ReleaseStringUTFChars(jOutFilePath, outputFilePath);
- return -1;
- }
- const char *codecName = env->GetStringUTFChars(jCodecName, NULL);
- const char *inputReference = env->GetStringUTFChars(jFileName, nullptr);
- string sCodecName = string(codecName);
- string sInputReference = string(inputReference);
-
- bool asyncMode[2] = {true, false};
- for (int i = 0; i < 2; i++) {
- size_t eleSize = eleStream.tellg();
- eleStream.seekg(0, ifstream::beg);
-
- // Get encoder params
- encParameter encParams;
- if (!strncmp(mime, "video/", 6)) {
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &encParams.width);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &encParams.height);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &encParams.frameRate);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &encParams.bitrate);
- if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
- encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
- if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
- encParams.bitrate = ENCODE_MIN_BIT_RATE /* 600 Kbps */;
- } else {
- encParams.bitrate = ENCODE_DEFAULT_BIT_RATE /* 8 Mbps */;
- }
- }
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
- AMediaFormat_getInt32(decoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT,
- &encParams.colorFormat);
- } else {
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &encParams.sampleRate);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
- &encParams.numChannels);
- encParams.bitrate = ENCODE_DEFAULT_AUDIO_BIT_RATE;
- }
- Encoder *encoder = new Encoder();
- encoder->setupEncoder();
- status = encoder->encode(sCodecName, eleStream, eleSize, asyncMode[i], encParams,
- (char *)mime);
- if (status != AMEDIA_OK) {
- ALOGE("Encoder returned error");
- return -1;
- }
- ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(),
- asyncMode[i]);
- encoder->deInitCodec();
- const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
- encoder->dumpStatistics(sInputReference, extractor->getClipDuration(), sCodecName,
- (asyncMode[i] ? "async" : "sync"), statsFile);
- env->ReleaseStringUTFChars(jStatsFile, statsFile);
- encoder->resetEncoder();
- delete encoder;
- encoder = nullptr;
- }
- eleStream.close();
- if (outFp) {
- fclose(outFp);
- outFp = nullptr;
- }
- env->ReleaseStringUTFChars(jFileName, inputReference);
- env->ReleaseStringUTFChars(jCodecName, codecName);
- env->ReleaseStringUTFChars(jOutFilePath, outputFilePath);
- if (format) {
- AMediaFormat_delete(format);
- format = nullptr;
- }
- if (decoderFormat) {
- AMediaFormat_delete(decoderFormat);
- decoderFormat = nullptr;
- }
- decoder->deInitCodec();
- decoder->resetDecoder();
+ encoder->dumpStatistics(inputReference, clipDurationUs, sCodecName,
+ (mode ? "async" : "sync"), statsFile);
+ env->ReleaseStringUTFChars(jStatsFile, statsFile);
+ encoder->resetEncoder();
+ delete encoder;
+ encoder = nullptr;
}
- if (inputFp) {
- fclose(inputFp);
- inputFp = nullptr;
- }
- extractor->deInitExtractor();
- delete decoder;
+ eleStream.close();
+ env->ReleaseStringUTFChars(jFilePath, filePath);
+ env->ReleaseStringUTFChars(jFileName, fileName);
+ env->ReleaseStringUTFChars(jMime, mime);
+ env->ReleaseStringUTFChars(jCodecName, codecName);
return 0;
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
index 38b608a..3e3969c 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
@@ -27,6 +27,7 @@
public native int Decode(String inputFilePath, String inputFileName, String statsFile,
String codecName, boolean asyncMode);
- public native int Encode(String inputFilePath, String inputFileName, String outputFilePath,
- String statsFile, String codecName);
+ public native int Encode(String inputFilePath, String inputFileName, String statsFile,
+ String codecName, String mime, int bitRate, int colorFormat, int frameInterval,
+ int width, int height, int profile, int level, int sampleRate, int numChannel);
}
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
index 26fb1b9..15c479d 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -203,13 +203,13 @@
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_WIDTH, mParams.width);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_HEIGHT, mParams.height);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_FRAME_RATE, mParams.frameRate);
+ AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, mParams.iFrameInterval);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
- AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
- if (mParams.profile && mParams.level) {
+ AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, mParams.colorFormat);
+ if (mParams.profile != -1 && mParams.level != -1) {
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_PROFILE, mParams.profile);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_LEVEL, mParams.level);
}
- AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, mParams.colorFormat);
} else {
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, mParams.sampleRate);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mParams.numChannels);
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.h b/media/tests/benchmark/src/native/encoder/Encoder.h
index 5ad142b..324317c 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.h
+++ b/media/tests/benchmark/src/native/encoder/Encoder.h
@@ -23,10 +23,11 @@
#include <queue>
#include <thread>
-#include "media/NdkImage.h"
#include "BenchmarkCommon.h"
#include "Stats.h"
+// constant not defined in NDK api
+constexpr int32_t COLOR_FormatYUV420Flexible = 0x7F420888;
struct encParameter {
int32_t bitrate = -1;
@@ -38,9 +39,10 @@
int32_t width = 0;
int32_t height = 0;
int32_t frameRate = -1;
- int32_t profile = 0;
- int32_t level = 0;
- int32_t colorFormat = AIMAGE_FORMAT_YUV_420_888;
+ int32_t iFrameInterval = 0;
+ int32_t profile = -1;
+ int32_t level = -1;
+ int32_t colorFormat = COLOR_FormatYUV420Flexible;
};
class Encoder : public CallBackHandle {
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
index faac847..7e1681d 100644
--- a/media/tests/benchmark/tests/EncoderTest.cpp
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -23,6 +23,10 @@
#include "Decoder.h"
#include "Encoder.h"
+constexpr int32_t kEncodeDefaultVideoBitRate = 8000000 /* 8 Mbps */;
+constexpr int32_t kEncodeMinVideoBitRate = 600000 /* 600 Kbps */;
+constexpr int32_t kEncodeDefaultAudioBitRate = 128000 /* 128 Kbps */;
+
static BenchmarkTestEnvironment *gEnv = nullptr;
class EncoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
@@ -86,6 +90,7 @@
decoder->setupDecoder();
status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
ASSERT_EQ(status, AMEDIA_OK) << "Decode returned error : " << status;
+ AMediaFormat *decoderFormat = decoder->getFormat();
ifstream eleStream;
eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
@@ -108,11 +113,13 @@
if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
encParams.frameRate = 25;
if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
- encParams.bitrate = 600000 /* 600 Kbps */;
+ encParams.bitrate = kEncodeMinVideoBitRate;
} else {
- encParams.bitrate = 8000000 /* 8 Mbps */;
+ encParams.bitrate = kEncodeDefaultVideoBitRate;
}
}
+ AMediaFormat_getInt32(decoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT,
+ &encParams.colorFormat);
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
} else {
@@ -120,8 +127,7 @@
&encParams.sampleRate));
ASSERT_TRUE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
&encParams.numChannels));
- encParams.bitrate =
- encParams.sampleRate * encParams.numChannels * 16 /* bitsPerSample */;
+ encParams.bitrate = kEncodeDefaultAudioBitRate;
}
encoder->setupEncoder();
@@ -142,6 +148,10 @@
AMediaFormat_delete(format);
format = nullptr;
}
+ if (decoderFormat) {
+ AMediaFormat_delete(decoderFormat);
+ decoderFormat = nullptr;
+ }
encoder->resetEncoder();
decoder->deInitCodec();
free(inputBuffer);