Merge "Benchmark: Add CSV support"

am: d7fad5f8ed

Change-Id: I2d235a535228c95c0a049a6ecd6085f599c44931
gugelfrei
Neelkamal Semwal 5 years ago committed by android-build-merger
commit d8037809d1

@ -28,7 +28,9 @@ import com.android.media.benchmark.library.CodecUtils;
import com.android.media.benchmark.library.Decoder;
import com.android.media.benchmark.library.Extractor;
import com.android.media.benchmark.library.Native;
import com.android.media.benchmark.library.Stats;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -54,6 +56,8 @@ public class DecoderTest {
InstrumentationRegistry.getInstrumentation().getTargetContext();
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.getFilesDir() + "/Decoder." + System.currentTimeMillis() + ".csv";
private static final String TAG = "DecoderTest";
private static final long PER_TEST_TIMEOUT_MS = 60000;
private static final boolean DEBUG = false;
@ -105,6 +109,13 @@ public class DecoderTest {
{"crowd_1920x1080_25fps_4000kbps_h265.mkv", true}});
}
@BeforeClass
public static void writeStatsHeaderToFile() throws IOException {
Stats mStats = new Stats();
boolean status = mStats.writeStatsHeader(mStatsFile);
assertTrue("Unable to open stats file for writing!", status);
}
@Test(timeout = PER_TEST_TIMEOUT_MS)
public void testDecoder() throws IOException {
File inputFile = new File(mInputFilePath + mInputFile);
@ -162,7 +173,8 @@ public class DecoderTest {
decoder.deInitCodec();
assertEquals("Decoder returned error " + status + " for file: " + mInputFile +
" with codec: " + codecName, 0, status);
decoder.dumpStatistics(mInputFile + " " + codecName, extractor.getClipDuration());
decoder.dumpStatistics(mInputFile, codecName, (mAsyncMode ? "async" : "sync"),
extractor.getClipDuration(), mStatsFile);
Log.i(TAG, "Decoding Successful for file: " + mInputFile + " with codec: " +
codecName);
decoder.resetDecoder();
@ -196,8 +208,8 @@ public class DecoderTest {
for (String codecName : mediaCodecs) {
Log.i("Test: %s\n", mInputFile);
Native nativeDecoder = new Native();
int status =
nativeDecoder.Decode(mInputFilePath, mInputFile, codecName, mAsyncMode);
int status = nativeDecoder.Decode(
mInputFilePath, mInputFile, mStatsFile, codecName, mAsyncMode);
assertEquals("Decoder returned error " + status + " for file: " + mInputFile, 0,
status);
}

@ -29,7 +29,9 @@ import com.android.media.benchmark.library.Decoder;
import com.android.media.benchmark.library.Encoder;
import com.android.media.benchmark.library.Extractor;
import com.android.media.benchmark.library.Native;
import com.android.media.benchmark.library.Stats;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -38,6 +40,7 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@ -53,6 +56,8 @@ public class EncoderTest {
InstrumentationRegistry.getInstrumentation().getTargetContext();
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.getFilesDir() + "/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;
@ -60,7 +65,6 @@ public class EncoderTest {
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 String mInputFile;
@Parameterized.Parameters
@ -85,6 +89,13 @@ public class EncoderTest {
this.mInputFile = inputFileName;
}
@BeforeClass
public static void writeStatsHeaderToFile() throws IOException {
Stats mStats = new Stats();
boolean status = mStats.writeStatsHeader(mStatsFile);
assertTrue("Unable to open stats file for writing!", status);
}
@Test(timeout = PER_TEST_TIMEOUT_MS)
public void sampleEncoderTest() throws Exception {
int status;
@ -220,9 +231,8 @@ public class EncoderTest {
assertEquals(
codecName + " encoder returned error " + status + " for " + "file:" +
" " + mInputFile, 0, status);
encoder.dumpStatistics(
mInputFile + "with " + codecName + " for " + "aSyncMode = " + asyncMode,
extractor.getClipDuration());
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();
@ -264,8 +274,8 @@ public class EncoderTest {
// Encoding the decoder's output
for (String codecName : mediaCodecs) {
Native nativeEncoder = new Native();
int status =
nativeEncoder.Encode(mInputFilePath, mInputFile, mDecodedFile, codecName);
int status = nativeEncoder.Encode(
mInputFilePath, mInputFile, mDecodedFile, mStatsFile, codecName);
assertEquals(
codecName + " encoder returned error " + status + " for " + "file:" + " " +
mInputFile, 0, status);

@ -19,12 +19,15 @@ package com.android.media.benchmark.tests;
import com.android.media.benchmark.R;
import com.android.media.benchmark.library.Extractor;
import com.android.media.benchmark.library.Native;
import com.android.media.benchmark.library.Stats;
import android.content.Context;
import android.media.MediaFormat;
import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -32,6 +35,7 @@ import org.junit.runners.Parameterized;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
@ -39,11 +43,15 @@ import java.util.Collection;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(Parameterized.class)
public class ExtractorTest {
private static Context mContext =
InstrumentationRegistry.getInstrumentation().getTargetContext();
private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
private static final String mStatsFile =
mContext.getFilesDir() + "/Extractor." + System.currentTimeMillis() + ".csv";
private static final String TAG = "ExtractorTest";
private String mInputFileName;
private int mTrackId;
@ -71,6 +79,13 @@ public class ExtractorTest {
this.mTrackId = track;
}
@BeforeClass
public static void writeStatsHeaderToFile() throws IOException {
Stats mStats = new Stats();
boolean status = mStats.writeStatsHeader(mStatsFile);
assertTrue("Unable to open stats file for writing!", status);
}
@Test
public void sampleExtractTest() throws IOException {
File inputFile = new File(mInputFilePath + mInputFileName);
@ -80,11 +95,13 @@ public class ExtractorTest {
FileDescriptor fileDescriptor = fileInput.getFD();
Extractor extractor = new Extractor();
extractor.setUpExtractor(fileDescriptor);
MediaFormat format = extractor.getFormat(mTrackId);
String mime = format.getString(MediaFormat.KEY_MIME);
int status = extractor.extractSample(mTrackId);
assertEquals("Extraction failed for " + mInputFileName, 0, status);
Log.i(TAG, "Extracted " + mInputFileName + " successfully.");
extractor.deinitExtractor();
extractor.dumpStatistics(mInputFileName);
extractor.dumpStatistics(mInputFileName, mime, mStatsFile);
fileInput.close();
}
@ -95,7 +112,7 @@ public class ExtractorTest {
assertTrue("Cannot find " + mInputFileName + " in directory " + mInputFilePath,
inputFile.exists());
FileInputStream fileInput = new FileInputStream(inputFile);
int status = nativeExtractor.Extract(mInputFilePath, mInputFileName);
int status = nativeExtractor.Extract(mInputFilePath, mInputFileName, mStatsFile);
fileInput.close();
assertEquals("Extraction failed for " + mInputFileName, 0, status);
Log.i(TAG, "Extracted " + mInputFileName + " successfully.");

@ -19,6 +19,7 @@ import com.android.media.benchmark.R;
import com.android.media.benchmark.library.Extractor;
import com.android.media.benchmark.library.Muxer;
import com.android.media.benchmark.library.Native;
import com.android.media.benchmark.library.Stats;
import androidx.test.platform.app.InstrumentationRegistry;
@ -28,6 +29,7 @@ import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.util.Log;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -35,6 +37,7 @@ import org.junit.runners.Parameterized;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@ -47,11 +50,15 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
@RunWith(Parameterized.class)
public class MuxerTest {
private static Context mContext =
InstrumentationRegistry.getInstrumentation().getTargetContext();
private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
private static final String mStatsFile =
mContext.getFilesDir() + "/Muxer." + System.currentTimeMillis() + ".csv";
private static final String TAG = "MuxerTest";
private static final Map<String, Integer> mMapFormat = new Hashtable<String, Integer>() {
{
@ -94,6 +101,13 @@ public class MuxerTest {
this.mFormat = outputFormat;
}
@BeforeClass
public static void writeStatsHeaderToFile() throws IOException {
Stats mStats = new Stats();
boolean status = mStats.writeStatsHeader(mStatsFile);
assertTrue("Unable to open stats file for writing!", status);
}
@Test
public void sampleMuxerTest() throws IOException {
File inputFile = new File(mInputFilePath + mInputFileName);
@ -132,7 +146,7 @@ public class MuxerTest {
assertEquals("Cannot perform write operation for " + mInputFileName, 0, status);
Log.i(TAG, "Muxed " + mInputFileName + " successfully.");
muxer.deInitMuxer();
muxer.dumpStatistics(mInputFileName, extractor.getClipDuration());
muxer.dumpStatistics(mInputFileName, mFormat, extractor.getClipDuration(), mStatsFile);
muxer.resetMuxer();
extractor.unselectExtractorTrack(currentTrack);
inputBufferInfo.clear();
@ -151,7 +165,8 @@ public class MuxerTest {
inputFile.exists());
int tid = android.os.Process.myTid();
String mMuxOutputFile = (mContext.getFilesDir() + "/mux_" + tid + ".out");
int status = nativeMuxer.Mux(mInputFilePath, mInputFileName, mMuxOutputFile, mFormat);
int status = nativeMuxer.Mux(
mInputFilePath, mInputFileName, mMuxOutputFile, mStatsFile, mFormat);
assertEquals("Cannot perform write operation for " + mInputFileName, 0, status);
Log.i(TAG, "Muxed " + mInputFileName + " successfully.");
File muxedFile = new File(mMuxOutputFile);

@ -18,6 +18,7 @@
#define LOG_TAG "NativeDecoder"
#include <jni.h>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@ -27,8 +28,8 @@
#include "Decoder.h"
extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native_Decode(
JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jCodecName,
jboolean asyncMode) {
JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jStatsFile,
jstring jCodecName, jboolean asyncMode) {
const char *filePath = env->GetStringUTFChars(jFilePath, nullptr);
const char *fileName = env->GetStringUTFChars(jFileName, nullptr);
string sFilePath = string(filePath) + string(fileName);
@ -69,7 +70,7 @@ extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native
return -1;
}
uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
uint8_t *inputBuffer = (uint8_t *) malloc(fileSize);
if (!inputBuffer) {
ALOGE("Insufficient memory");
return -1;
@ -105,18 +106,21 @@ extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native
return -1;
}
decoder->deInitCodec();
env->ReleaseStringUTFChars(jCodecName, codecName);
const char *inputReference = env->GetStringUTFChars(jFileName, nullptr);
const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
string sInputReference = string(inputReference);
decoder->dumpStatistics(sInputReference);
decoder->dumpStatistics(sInputReference, sCodecName, (asyncMode ? "async" : "sync"),
statsFile);
env->ReleaseStringUTFChars(jCodecName, codecName);
env->ReleaseStringUTFChars(jStatsFile, statsFile);
env->ReleaseStringUTFChars(jFileName, inputReference);
if(inputBuffer) {
if (inputBuffer) {
free(inputBuffer);
inputBuffer = nullptr;
}
decoder->resetDecoder();
}
if(inputFp) {
if (inputFp) {
fclose(inputFp);
inputFp = nullptr;
}

@ -31,7 +31,7 @@
extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native_Encode(
JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jOutFilePath,
jstring jCodecName) {
jstring jStatsFile, jstring jCodecName) {
const char *filePath = env->GetStringUTFChars(jFilePath, nullptr);
const char *fileName = env->GetStringUTFChars(jFileName, nullptr);
string sFilePath = string(filePath) + string(fileName);
@ -72,7 +72,7 @@ extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native
ALOGE("Track Format invalid");
return -1;
}
uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
uint8_t *inputBuffer = (uint8_t *) malloc(fileSize);
if (!inputBuffer) {
ALOGE("Insufficient memory");
return -1;
@ -111,7 +111,7 @@ extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native
return -1;
}
AMediaFormat *format = extractor->getFormat();
if(inputBuffer) {
if (inputBuffer) {
free(inputBuffer);
inputBuffer = nullptr;
}
@ -165,11 +165,14 @@ extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native
Encoder *encoder = new Encoder();
encoder->setupEncoder();
status = encoder->encode(sCodecName, eleStream, eleSize, asyncMode[i], encParams,
(char *)mime);
(char *) mime);
encoder->deInitCodec();
cout << "codec : " << codecName << endl;
ALOGV(" asyncMode = %d \n", asyncMode[i]);
encoder->dumpStatistics(sInputReference, extractor->getClipDuration());
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;
@ -189,7 +192,7 @@ extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native
decoder->deInitCodec();
decoder->resetDecoder();
}
if(inputFp) {
if (inputFp) {
fclose(inputFp);
inputFp = nullptr;
}

@ -18,16 +18,15 @@
#define LOG_TAG "NativeExtractor"
#include <jni.h>
#include <fstream>
#include <string>
#include <sys/stat.h>
#include "Extractor.h"
extern "C"
JNIEXPORT int32_t JNICALL
Java_com_android_media_benchmark_library_Native_Extract(JNIEnv *env, jobject thiz,
jstring jInputFilePath,
jstring jInputFileName) {
extern "C" JNIEXPORT int32_t JNICALL Java_com_android_media_benchmark_library_Native_Extract(
JNIEnv *env, jobject thiz, jstring jInputFilePath, jstring jInputFileName,
jstring jStatsFile) {
UNUSED(thiz);
const char *inputFilePath = env->GetStringUTFChars(jInputFilePath, nullptr);
const char *inputFileName = env->GetStringUTFChars(jInputFileName, nullptr);
@ -41,25 +40,39 @@ Java_com_android_media_benchmark_library_Native_Extract(JNIEnv *env, jobject thi
int32_t fd = fileno(inputFp);
Extractor *extractObj = new Extractor();
int32_t trackCount = extractObj->initExtractor((long)fd, fileSize);
int32_t trackCount = extractObj->initExtractor((long) fd, fileSize);
if (trackCount <= 0) {
ALOGE("initExtractor failed");
return -1;
}
int32_t trackID = 0;
const char *mime = nullptr;
int32_t status = extractObj->extract(trackID);
if (status != AMEDIA_OK) {
ALOGE("Extraction failed");
return -1;
}
if (inputFp) {
fclose(inputFp);
inputFp = nullptr;
}
status = extractObj->setupTrackFormat(trackID);
AMediaFormat *format = extractObj->getFormat();
if (!format) {
ALOGE("format is null!");
return -1;
}
AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
if (!mime) {
ALOGE("mime is null!");
return -1;
}
extractObj->deInitExtractor();
extractObj->dumpStatistics(inputFileName);
const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
extractObj->dumpStatistics(string(inputFileName), string(mime), statsFile);
env->ReleaseStringUTFChars(jStatsFile, statsFile);
env->ReleaseStringUTFChars(jInputFilePath, inputFilePath);
env->ReleaseStringUTFChars(jInputFileName, inputFileName);

@ -18,6 +18,7 @@
#define LOG_TAG "NativeMuxer"
#include <jni.h>
#include <fstream>
#include <string>
#include <sys/stat.h>
@ -25,11 +26,9 @@
MUXER_OUTPUT_T getMuxerOutFormat(const char *fmt);
extern "C"
JNIEXPORT int32_t JNICALL
Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
jstring jInputFilePath, jstring jInputFileName,
jstring jOutputFilePath, jstring jFormat) {
extern "C" JNIEXPORT int32_t JNICALL Java_com_android_media_benchmark_library_Native_Mux(
JNIEnv *env, jobject thiz, jstring jInputFilePath, jstring jInputFileName,
jstring jOutputFilePath, jstring jStatsFile, jstring jFormat) {
UNUSED(thiz);
ALOGV("Mux the samples given by extractor");
const char *inputFilePath = env->GetStringUTFChars(jInputFilePath, nullptr);
@ -43,7 +42,6 @@ Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
const char *fmt = env->GetStringUTFChars(jFormat, nullptr);
MUXER_OUTPUT_T outputFormat = getMuxerOutFormat(fmt);
env->ReleaseStringUTFChars(jFormat, fmt);
if (outputFormat == MUXER_OUTPUT_FORMAT_INVALID) {
ALOGE("output format is MUXER_OUTPUT_FORMAT_INVALID");
return MUXER_OUTPUT_FORMAT_INVALID;
@ -75,7 +73,7 @@ Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
return -1;
}
uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
uint8_t *inputBuffer = (uint8_t *) malloc(fileSize);
if (!inputBuffer) {
ALOGE("Allocation Failed");
return -1;
@ -105,7 +103,7 @@ Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
}
const char *outputFilePath = env->GetStringUTFChars(jOutputFilePath, nullptr);
FILE *outputFp = fopen(((string)outputFilePath).c_str(), "w+b");
FILE *outputFp = fopen(((string) outputFilePath).c_str(), "w+b");
env->ReleaseStringUTFChars(jOutputFilePath, outputFilePath);
if (!outputFp) {
@ -118,7 +116,7 @@ Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
}
int32_t outFd = fileno(outputFp);
status = muxerObj->initMuxer(outFd, (MUXER_OUTPUT_T)outputFormat);
status = muxerObj->initMuxer(outFd, (MUXER_OUTPUT_T) outputFormat);
if (status != 0) {
ALOGE("initMuxer failed");
if (inputBuffer) {
@ -138,7 +136,10 @@ Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
return -1;
}
muxerObj->deInitMuxer();
muxerObj->dumpStatistics(inputFileName);
const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
string muxFormat(fmt);
muxerObj->dumpStatistics(string(inputFileName), muxFormat, statsFile);
env->ReleaseStringUTFChars(jStatsFile, statsFile);
env->ReleaseStringUTFChars(jInputFilePath, inputFilePath);
env->ReleaseStringUTFChars(jInputFileName, inputFileName);
@ -156,6 +157,7 @@ Java_com_android_media_benchmark_library_Native_Mux(JNIEnv *env, jobject thiz,
fclose(inputFp);
inputFp = nullptr;
}
env->ReleaseStringUTFChars(jFormat, fmt);
extractor->deInitExtractor();
delete muxerObj;
@ -166,10 +168,10 @@ MUXER_OUTPUT_T getMuxerOutFormat(const char *fmt) {
static const struct {
const char *name;
int value;
} kFormatMaps[] = {{"mp4", MUXER_OUTPUT_FORMAT_MPEG_4},
} kFormatMaps[] = {{"mp4", MUXER_OUTPUT_FORMAT_MPEG_4},
{"webm", MUXER_OUTPUT_FORMAT_WEBM},
{"3gpp", MUXER_OUTPUT_FORMAT_3GPP},
{"ogg", MUXER_OUTPUT_FORMAT_OGG}};
{"ogg", MUXER_OUTPUT_FORMAT_OGG}};
int32_t muxOutputFormat = MUXER_OUTPUT_FORMAT_INVALID;
for (auto kFormatMap : kFormatMaps) {
@ -178,5 +180,5 @@ MUXER_OUTPUT_T getMuxerOutFormat(const char *fmt) {
break;
}
}
return (MUXER_OUTPUT_T)muxOutputFormat;
return (MUXER_OUTPUT_T) muxOutputFormat;
}

@ -239,11 +239,16 @@ public class Decoder {
* Prints out the statistics in the information log
*
* @param inputReference The operation being performed, in this case decode
* @param componentName Name of the component/codec
* @param mode The operating mode: Sync/Async
* @param durationUs Duration of the clip in microseconds
* @param statsFile The output file where the stats data is written
*/
public void dumpStatistics(String inputReference, long durationUs) {
public void dumpStatistics(String inputReference, String componentName, String mode,
long durationUs, String statsFile) throws IOException {
String operation = "decode";
mStats.dumpStatistics(operation, inputReference, durationUs);
mStats.dumpStatistics(
inputReference, operation, componentName, mode, durationUs, statsFile);
}
/**

@ -326,12 +326,17 @@ public class Encoder {
/**
* Prints out the statistics in the information log
*
* @param inputReference The operation being performed, in this case encode
* @param inputReference The operation being performed, in this case decode
* @param componentName Name of the component/codec
* @param mode The operating mode: Sync/Async
* @param durationUs Duration of the clip in microseconds
* @param statsFile The output file where the stats data is written
*/
public void dumpStatistics(String inputReference, long durationUs) {
public void dumpStatistics(String inputReference, String componentName, String mode,
long durationUs, String statsFile) throws IOException {
String operation = "encode";
mStats.dumpStatistics(operation, inputReference, durationUs);
mStats.dumpStatistics(
inputReference, operation, componentName, mode, durationUs, statsFile);
}
/**

@ -167,9 +167,12 @@ public class Extractor {
* Write the benchmark logs for the given input file
*
* @param inputReference Name of the input file
* @param mimeType Mime type of the muxed file
* @param statsFile The output file where the stats data is written
*/
public void dumpStatistics(String inputReference) {
public void dumpStatistics(String inputReference, String mimeType, String statsFile)
throws IOException {
String operation = "extract";
mStats.dumpStatistics(operation, inputReference, mDurationUs);
mStats.dumpStatistics(inputReference, operation, mimeType, "", mDurationUs, statsFile);
}
}

@ -101,10 +101,13 @@ public class Muxer {
* Write the benchmark logs for the given input file
*
* @param inputReference Name of the input file
* @param muxFormat Format of the muxed output
* @param clipDuration Duration of the given inputReference file
* @param statsFile The output file where the stats data is written
*/
public void dumpStatistics(String inputReference, long clipDuration) {
public void dumpStatistics(String inputReference, String muxFormat, long clipDuration,
String statsFile) throws IOException {
String operation = "mux";
mStats.dumpStatistics(operation, inputReference, clipDuration);
mStats.dumpStatistics(inputReference, operation, muxFormat, "", clipDuration, statsFile);
}
}

@ -19,14 +19,14 @@ package com.android.media.benchmark.library;
public class Native {
static { System.loadLibrary("mediabenchmark_jni"); }
public native int Extract(String inputFilePath, String inputFileName);
public native int Extract(String inputFilePath, String inputFileName, String statsFile);
public native int Mux(String inputFilePath, String inputFileName, String outputFilePath,
String format);
String statsFile, String format);
public native int Decode(String inputFilePath, String inputFileName, String codecName,
boolean asyncMode);
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 codecName);
String statsFile, String codecName);
}

@ -18,6 +18,10 @@ package com.android.media.benchmark.library;
import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
/**
@ -90,15 +94,39 @@ public class Stats {
return totalSize;
}
/**
* Writes the stats header to a file
* <p>
* \param statsFile file where the stats data is to be written
**/
public boolean writeStatsHeader(String statsFile) throws IOException {
File outputFile = new File(statsFile);
FileOutputStream out = new FileOutputStream(outputFile, true);
if (!outputFile.exists())
return false;
String statsHeader =
"currentTime, fileName, operation, componentName, NDK/SDK, sync/async, setupTime, "
+ "destroyTime, minimumTime, maximumTime, "
+ "averageTime, timeToProcess1SecContent, totalBytesProcessedPerSec, "
+ "timeToFirstFrame, totalSizeInBytes, totalTime\n";
out.write(statsHeader.getBytes());
out.close();
return true;
}
/**
* Dumps the stats of the operation for a given input media.
* <p>
* \param inputReference input media
* \param operation describes the operation performed on the input media
* (i.e. extract/mux/decode/encode)
* \param inputReference input media
* \param durationUs is a duration of the input media in microseconds.
* \param componentName name of the codec/muxFormat/mime
* \param mode the operating mode: sync/async.
* \param durationUs is a duration of the input media in microseconds.
* \param statsFile the file where the stats data is to be written.
*/
public void dumpStatistics(String operation, String inputReference, long durationUs) {
public void dumpStatistics(String inputReference, String operation, String componentName,
String mode, long durationUs, String statsFile) throws IOException {
if (mOutputTimer.size() == 0) {
Log.e(TAG, "No output produced");
return;
@ -121,18 +149,30 @@ public class Stats {
maxTimeTakenNs = intervalNs;
}
}
// Print the Stats
Log.i(TAG, "Input Reference : " + inputReference);
Log.i(TAG, "Setup Time in nano sec : " + mInitTimeNs);
Log.i(TAG, "Average Time in nano sec : " + totalTimeTakenNs / mOutputTimer.size());
Log.i(TAG, "Time to first frame in nano sec : " + timeToFirstFrameNs);
Log.i(TAG, "Time taken (in nano sec) to " + operation + " 1 sec of content : " +
timeTakenPerSec);
Log.i(TAG, "Total bytes " + operation + "ed : " + size);
Log.i(TAG, "Number of bytes " + operation + "ed per second : " +
(size * 1000000000) / totalTimeTakenNs);
Log.i(TAG, "Minimum Time in nano sec : " + minTimeTakenNs);
Log.i(TAG, "Maximum Time in nano sec : " + maxTimeTakenNs);
Log.i(TAG, "Destroy Time in nano sec : " + mDeInitTimeNs);
// Write the stats row data to file
String rowData = "";
rowData += System.nanoTime() + ", ";
rowData += inputReference + ", ";
rowData += operation + ", ";
rowData += componentName + ", ";
rowData += "SDK, ";
rowData += mode + ", ";
rowData += mInitTimeNs + ", ";
rowData += mDeInitTimeNs + ", ";
rowData += minTimeTakenNs + ", ";
rowData += maxTimeTakenNs + ", ";
rowData += totalTimeTakenNs / mOutputTimer.size() + ", ";
rowData += timeTakenPerSec + ", ";
rowData += (size * 1000000000) / totalTimeTakenNs + ", ";
rowData += timeToFirstFrameNs + ", ";
rowData += size + ", ";
rowData += totalTimeTakenNs + "\n";
File outputFile = new File(statsFile);
FileOutputStream out = new FileOutputStream(outputFile, true);
assert outputFile.exists() : "Failed to open the stats file for writing!";
out.write(rowData.getBytes());
out.close();
}
}
}

@ -17,8 +17,10 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Stats"
#include <ctime>
#include <iostream>
#include <stdint.h>
#include <fstream>
#include "Stats.h"
@ -28,16 +30,20 @@
* \param operation describes the operation performed on the input media
* (i.e. extract/mux/decode/encode)
* \param inputReference input media
* \param duarationUs is a duration of the input media in microseconds.
* \param durationUs is a duration of the input media in microseconds.
* \param componentName describes the codecName/muxFormat/mimeType.
* \param mode the operating mode: sync/async.
* \param statsFile the file where the stats data is to be written.
*/
void Stats::dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs) {
void Stats::dumpStatistics(string operation, string inputReference, int64_t durationUs,
string componentName, string mode, string statsFile) {
ALOGV("In %s", __func__);
if (!mOutputTimer.size()) {
ALOGE("No output produced");
return;
}
nsecs_t totalTimeTakenNs = getTotalTime();
nsecs_t timeTakenPerSec = (totalTimeTakenNs * 1000000) / duarationUs;
nsecs_t timeTakenPerSec = (totalTimeTakenNs * 1000000) / durationUs;
nsecs_t timeToFirstFrameNs = *mOutputTimer.begin() - mStartTimeNs;
int32_t size = std::accumulate(mFrameSizes.begin(), mFrameSizes.end(), 0);
// get min and max output intervals.
@ -52,15 +58,32 @@ void Stats::dumpStatistics(std::string operation, std::string inputReference, in
else if (maxTimeTakenNs < intervalNs) maxTimeTakenNs = intervalNs;
}
// Print the Stats
ALOGI("Input Reference : %s \n", inputReference.c_str());
ALOGI("Setup Time in nano sec : %" PRId64 "\n", mInitTimeNs);
ALOGI("Average Time in nano sec : %" PRId64 "\n", totalTimeTakenNs / mOutputTimer.size());
ALOGI("Time to first frame in nano sec : %" PRId64 "\n", timeToFirstFrameNs);
ALOGI("Time taken (in nano sec) to %s 1 sec of content : %" PRId64 "\n", operation.c_str(),
timeTakenPerSec);
ALOGI("Total bytes %sed : %d\n", operation.c_str(), size);
ALOGI("Minimum Time in nano sec : %" PRId64 "\n", minTimeTakenNs);
ALOGI("Maximum Time in nano sec : %" PRId64 "\n", maxTimeTakenNs);
ALOGI("Destroy Time in nano sec : %" PRId64 "\n", mDeInitTimeNs);
// Write the stats data to file.
int64_t dataSize = size;
int64_t bytesPerSec = ((int64_t)dataSize * 1000000000) / totalTimeTakenNs;
string rowData = "";
rowData.append(to_string(systemTime(CLOCK_MONOTONIC)) + ", ");
rowData.append(inputReference + ", ");
rowData.append(operation + ", ");
rowData.append(componentName + ", ");
rowData.append("NDK, ");
rowData.append(mode + ", ");
rowData.append(to_string(mInitTimeNs) + ", ");
rowData.append(to_string(mDeInitTimeNs) + ", ");
rowData.append(to_string(minTimeTakenNs) + ", ");
rowData.append(to_string(maxTimeTakenNs) + ", ");
rowData.append(to_string(totalTimeTakenNs / mOutputTimer.size()) + ", ");
rowData.append(to_string(timeTakenPerSec) + ", ");
rowData.append(to_string(bytesPerSec) + ", ");
rowData.append(to_string(timeToFirstFrameNs) + ", ");
rowData.append(to_string(size) + ",");
rowData.append(to_string(totalTimeTakenNs) + ",\n");
ofstream out(statsFile, ios::out | ios::app);
if(out.bad()) {
ALOGE("Failed to open stats file for writing!");
return;
}
out << rowData;
out.close();
}

@ -102,7 +102,8 @@ class Stats {
return (*(mOutputTimer.end() - 1) - mStartTimeNs);
}
void dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs);
void dumpStatistics(string operation, string inputReference, int64_t duarationUs,
string codecName = "", string mode = "", string statsFile = "");
};
#endif // __STATS_H__

@ -238,10 +238,11 @@ void Decoder::deInitCodec() {
mStats->setDeInitTime(timeTaken);
}
void Decoder::dumpStatistics(string inputReference) {
void Decoder::dumpStatistics(string inputReference, string componentName, string mode,
string statsFile) {
int64_t durationUs = mExtractor->getClipDuration();
string operation = "decode";
mStats->dumpStatistics(operation, inputReference, durationUs);
mStats->dumpStatistics(operation, inputReference, durationUs, componentName, mode, statsFile);
}
void Decoder::resetDecoder() {

@ -71,7 +71,8 @@ class Decoder : public CallBackHandle {
int32_t decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
string &codecName, bool asyncMode, FILE *outFp = nullptr);
void dumpStatistics(string inputReference);
void dumpStatistics(string inputReference, string componentName = "", string mode = "",
string statsFile = "");
private:
AMediaCodec *mCodec;

@ -174,9 +174,10 @@ void Encoder::resetEncoder() {
memset(&mParams, 0, sizeof mParams);
}
void Encoder::dumpStatistics(string inputReference, int64_t durationUs) {
void Encoder::dumpStatistics(string inputReference, int64_t durationUs, string componentName,
string mode, string statsFile) {
string operation = "encode";
mStats->dumpStatistics(operation, inputReference, durationUs);
mStats->dumpStatistics(operation, inputReference, durationUs, componentName, mode, statsFile);
}
int32_t Encoder::encode(string &codecName, ifstream &eleStream, size_t eleSize,

@ -75,7 +75,8 @@ class Encoder : public CallBackHandle {
int32_t encode(std::string &codecName, std::ifstream &eleStream, size_t eleSize, bool asyncMode,
encParameter encParams, char *mime);
void dumpStatistics(string inputReference, int64_t durationUs);
void dumpStatistics(string inputReference, int64_t durationUs, string codecName = "",
string mode = "", string statsFile = "");
private:
AMediaCodec *mCodec;

@ -111,9 +111,9 @@ int32_t Extractor::extract(int32_t trackId) {
return AMEDIA_OK;
}
void Extractor::dumpStatistics(string inputReference) {
void Extractor::dumpStatistics(string inputReference, string componentName, string statsFile) {
string operation = "extract";
mStats->dumpStatistics(operation, inputReference, mDurationUs);
mStats->dumpStatistics(operation, inputReference, mDurationUs, componentName, "", statsFile);
}
void Extractor::deInitExtractor() {

@ -45,7 +45,7 @@ class Extractor {
int32_t extract(int32_t trackId);
void dumpStatistics(std::string inputReference);
void dumpStatistics(string inputReference, string componentName = "", string statsFile = "");
void deInitExtractor();

@ -66,9 +66,10 @@ void Muxer::resetMuxer() {
if (mStats) mStats->reset();
}
void Muxer::dumpStatistics(string inputReference) {
void Muxer::dumpStatistics(string inputReference, string componentName, string statsFile) {
string operation = "mux";
mStats->dumpStatistics(operation, inputReference, mExtractor->getClipDuration());
mStats->dumpStatistics(operation, inputReference, mExtractor->getClipDuration(), componentName,
"", statsFile);
}
int32_t Muxer::mux(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfos) {

@ -51,7 +51,7 @@ class Muxer {
/* Process the frames and give Muxed output */
int32_t mux(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameSizes);
void dumpStatistics(string inputReference);
void dumpStatistics(string inputReference, string codecName = "", string statsFile = "");
private:
AMediaFormat *mFormat;

Loading…
Cancel
Save