Merge "Benchmark: add Encoder" am: 0647d8c5f6 am: 8c8ce72cac am: 8d92a02dbe

am: dc6a107f11

Change-Id: Ide4dc79d7f660f6f961d6f02e52af89163e108f8
gugelfrei
Rakesh Kumar 5 years ago committed by android-build-merger
commit 20ea1ca9e0

@ -48,3 +48,13 @@ Setup steps are same as extractor.
```
adb shell /data/local/tmp/muxerTest -P /sdcard/res/
```
## Encoder
The test encodes input stream and benchmarks the encoders available in NDK.
Setup steps are same as extractor.
```
adb shell /data/local/tmp/encoderTest -P /sdcard/res/
```

@ -96,6 +96,15 @@ void Decoder::onOutputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx,
return;
}
if (mOutFp != nullptr) {
size_t bufSize;
uint8_t *buf = AMediaCodec_getOutputBuffer(mCodec, bufIdx, &bufSize);
if (buf) {
fwrite(buf, sizeof(char), bufferInfo->size, mOutFp);
ALOGV("bytes written into file %d\n", bufferInfo->size);
}
}
AMediaCodec_releaseOutputBuffer(mCodec, bufIdx, false);
mSawOutputEOS = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
mNumOutputFrame++;
@ -123,11 +132,12 @@ void Decoder::setupDecoder() {
}
int32_t Decoder::decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
string &codecName, bool asyncMode) {
string &codecName, bool asyncMode, FILE *outFp) {
ALOGV("In %s", __func__);
mInputBuffer = inputBuffer;
mFrameMetaData = frameInfo;
mOffset = 0;
mOutFp = outFp;
const char *mime = nullptr;
AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);

@ -39,7 +39,8 @@ class Decoder : public CallBackHandle {
mSawInputEOS(false),
mSawOutputEOS(false),
mSignalledError(false),
mInputBuffer(nullptr) {
mInputBuffer(nullptr),
mOutFp(nullptr) {
mExtractor = new Extractor();
}
@ -69,7 +70,7 @@ class Decoder : public CallBackHandle {
// Process the frames and give decoded output
int32_t decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
string &codecName, bool asyncMode);
string &codecName, bool asyncMode, FILE *outFp = nullptr);
void dumpStatistics(string inputReference);
@ -91,6 +92,7 @@ class Decoder : public CallBackHandle {
int32_t mOffset;
uint8_t *mInputBuffer;
vector<AMediaCodecBufferInfo> mFrameMetaData;
FILE *mOutFp;
/* Asynchronous locks */
mutex mMutex;

@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 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.
*/
cc_library_static {
name: "libbenchmark_encoder",
defaults: [
"libbenchmark_common-defaults",
"libbenchmark_soft_sanitize_all-defaults",
],
srcs: ["Encoder.cpp"],
static_libs: ["libbenchmark_extractor",
"libbenchmark_decoder",
],
export_include_dirs: ["."],
ldflags: ["-Wl,-Bsymbolic"]
}

@ -0,0 +1,274 @@
/*
* Copyright (C) 2019 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.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "encoder"
#include <fstream>
#include "Encoder.h"
void Encoder::onInputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx) {
ALOGV("In %s", __func__);
if (mediaCodec == mCodec && mediaCodec) {
if (mSawInputEOS || bufIdx < 0) return;
if (mSignalledError) {
CallBackHandle::mSawError = true;
mEncoderDoneCondition.notify_one();
return;
}
size_t bufSize = 0;
char *buf = (char *)AMediaCodec_getInputBuffer(mCodec, bufIdx, &bufSize);
if (!buf) {
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
}
if (mInputBufferSize < mOffset) {
ALOGE("Out of bound access of input buffer\n");
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
}
size_t bytesRead = mParams.frameSize;
if (mInputBufferSize - mOffset < mParams.frameSize) {
bytesRead = mInputBufferSize - mOffset;
}
if (bufSize < bytesRead) {
ALOGE("bytes to read %zu bufSize %zu \n", bytesRead, bufSize);
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
}
if (bytesRead < mParams.frameSize && mNumInputFrame < mParams.numFrames - 1) {
ALOGE("Partial frame at frameID %d bytesRead %zu frameSize %d total numFrames %d\n",
mNumInputFrame, bytesRead, mParams.frameSize, mParams.numFrames);
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
}
mEleStream->read(buf, bytesRead);
size_t bytesgcount = mEleStream->gcount();
if (bytesgcount != bytesRead) {
ALOGE("bytes to read %zu actual bytes read %zu \n", bytesRead, bytesgcount);
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
}
uint32_t flag = 0;
if (mNumInputFrame == mParams.numFrames - 1 || bytesRead == 0) {
ALOGD("Sending EOS on input Last frame\n");
flag |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
}
uint64_t presentationTimeUs;
if (!strncmp(mMime, "video/", 6)) {
presentationTimeUs = mNumInputFrame * (1000000 / mParams.frameRate);
} else {
presentationTimeUs =
(uint64_t)mNumInputFrame * mParams.frameSize * 1000000 / mParams.sampleRate;
}
if (flag == AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) mSawInputEOS = true;
ALOGV("%s bytesRead : %zd presentationTimeUs : %" PRIu64 " mSawInputEOS : %s", __FUNCTION__,
bytesRead, presentationTimeUs, mSawInputEOS ? "TRUE" : "FALSE");
int status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */, bytesRead,
presentationTimeUs, flag);
if (AMEDIA_OK != status) {
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
}
mNumInputFrame++;
mOffset += bytesRead;
}
}
void Encoder::onOutputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx,
AMediaCodecBufferInfo *bufferInfo) {
ALOGV("In %s", __func__);
if (mediaCodec == mCodec && mediaCodec) {
if (mSawOutputEOS || bufIdx < 0) return;
if (mSignalledError) {
CallBackHandle::mSawError = true;
mEncoderDoneCondition.notify_one();
return;
}
AMediaCodec_releaseOutputBuffer(mCodec, bufIdx, false);
mSawOutputEOS = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
mNumOutputFrame++;
ALOGV("%s index : %d mSawOutputEOS : %s count : %u", __FUNCTION__, bufIdx,
mSawOutputEOS ? "TRUE" : "FALSE", mNumOutputFrame);
if (mSawOutputEOS) {
CallBackHandle::mIsDone = true;
mEncoderDoneCondition.notify_one();
}
}
}
void Encoder::onFormatChanged(AMediaCodec *mediaCodec, AMediaFormat *format) {
ALOGV("In %s", __func__);
if (mediaCodec == mCodec && mediaCodec) {
ALOGV("%s { %s }", __FUNCTION__, AMediaFormat_toString(format));
mFormat = format;
}
}
void Encoder::setupEncoder() {
if (!mFormat) mFormat = AMediaFormat_new();
if (!mTimer) mTimer = new Timer();
}
void Encoder::deInitCodec() {
int64_t sTime = mTimer->getCurTime();
if (mFormat) {
AMediaFormat_delete(mFormat);
mFormat = nullptr;
}
AMediaCodec_stop(mCodec);
AMediaCodec_delete(mCodec);
int64_t eTime = mTimer->getCurTime();
int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
mTimer->setDeInitTime(timeTaken);
}
void Encoder::resetEncoder() {
if (mTimer) mTimer->resetTimers();
if (mEleStream) mEleStream = nullptr;
if (mMime) mMime = nullptr;
mInputBufferSize = 0;
memset(&mParams, 0, sizeof mParams);
}
void Encoder::dumpStatistics(string inputReference, int64_t durationUs) {
string operation = "encode";
mTimer->dumpStatistics(operation, inputReference, durationUs);
}
int32_t Encoder::encode(string &codecName, ifstream &eleStream, size_t eleSize,
bool asyncMode, encParameter encParams, char *mime) {
ALOGV("In %s", __func__);
mEleStream = &eleStream;
mInputBufferSize = eleSize;
mParams = encParams;
mOffset = 0;
mMime = mime;
AMediaFormat_setString(mFormat, AMEDIAFORMAT_KEY_MIME, mMime);
// Set Format
if (!strncmp(mMime, "video/", 6)) {
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_BIT_RATE, mParams.bitrate);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
if (mParams.profile && mParams.level) {
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_PROFILE, mParams.profile);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_LEVEL, mParams.level);
}
} else {
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, mParams.sampleRate);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mParams.numChannels);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
}
const char *s = AMediaFormat_toString(mFormat);
ALOGV("Input format: %s\n", s);
int64_t sTime = mTimer->getCurTime();
mCodec = createMediaCodec(mFormat, mMime, codecName, true /*isEncoder*/);
if (!mCodec) return AMEDIA_ERROR_INVALID_OBJECT;
int64_t eTime = mTimer->getCurTime();
int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
if (!strncmp(mMime, "video/", 6)) {
mParams.frameSize = mParams.width * mParams.height * 3 / 2;
} else {
mParams.frameSize = 4096;
// Get mInputMaxBufSize
AMediaFormat *inputFormat = AMediaCodec_getInputFormat(mCodec);
AMediaFormat_getInt32(inputFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &mParams.maxFrameSize);
if (mParams.maxFrameSize < 0) {
ALOGE("Invalid mParams.maxFrameSize %d\n", mParams.maxFrameSize);
return AMEDIA_ERROR_INVALID_PARAMETER;
}
if (mParams.frameSize > mParams.maxFrameSize) {
mParams.frameSize = mParams.maxFrameSize;
}
}
mParams.numFrames = (mInputBufferSize + mParams.frameSize - 1) / mParams.frameSize;
sTime = mTimer->getCurTime();
if (asyncMode) {
AMediaCodecOnAsyncNotifyCallback aCB = {OnInputAvailableCB, OnOutputAvailableCB,
OnFormatChangedCB, OnErrorCB};
AMediaCodec_setAsyncNotifyCallback(mCodec, aCB, this);
CallBackHandle *callbackHandle = new CallBackHandle();
callbackHandle->mIOThread = thread(&CallBackHandle::ioThread, this);
}
AMediaCodec_start(mCodec);
eTime = mTimer->getCurTime();
timeTaken += mTimer->getTimeDiff(sTime, eTime);
mTimer->setInitTime(timeTaken);
mTimer->setStartTime();
if (!asyncMode) {
while (!mSawOutputEOS && !mSignalledError) {
// Queue input data
if (!mSawInputEOS) {
ssize_t inIdx = AMediaCodec_dequeueInputBuffer(mCodec, kQueueDequeueTimeoutUs);
if (inIdx < 0 && inIdx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
return AMEDIA_ERROR_IO;
} else if (inIdx >= 0) {
mTimer->addInputTime();
onInputAvailable(mCodec, inIdx);
}
}
// Dequeue output data
AMediaCodecBufferInfo info;
ssize_t outIdx = AMediaCodec_dequeueOutputBuffer(mCodec, &info, kQueueDequeueTimeoutUs);
if (outIdx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
mFormat = AMediaCodec_getOutputFormat(mCodec);
const char *s = AMediaFormat_toString(mFormat);
ALOGI("Output format: %s\n", s);
} else if (outIdx >= 0) {
mTimer->addOutputTime();
onOutputAvailable(mCodec, outIdx, &info);
} else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
ALOGE("AMediaCodec_dequeueOutputBuffer returned invalid index %zd\n", outIdx);
return AMEDIA_ERROR_IO;
}
}
} else {
unique_lock<mutex> lock(mMutex);
mEncoderDoneCondition.wait(lock, [this]() { return (mSawOutputEOS || mSignalledError); });
}
if (codecName.empty()) {
char *encName;
AMediaCodec_getName(mCodec, &encName);
codecName.assign(encName);
AMediaCodec_releaseName(mCodec, encName);
}
return AMEDIA_OK;
}

@ -0,0 +1,104 @@
/*
* Copyright (C) 2019 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.
*/
#ifndef __ENCODER_H__
#define __ENCODER_H__
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include "BenchmarkCommon.h"
#include "Timer.h"
struct encParameter {
int32_t bitrate = -1;
int32_t numFrames = -1;
int32_t frameSize = -1;
int32_t sampleRate = 0;
int32_t numChannels = 0;
int32_t maxFrameSize = -1;
int32_t width = 0;
int32_t height = 0;
int32_t frameRate = -1;
int32_t profile = 0;
int32_t level = 0;
};
class Encoder : public CallBackHandle {
public:
Encoder()
: mCodec(nullptr),
mFormat(nullptr),
mTimer(nullptr),
mNumInputFrame(0),
mNumOutputFrame(0),
mSawInputEOS(false),
mSawOutputEOS(false),
mSignalledError(false) {}
virtual ~Encoder() {
if (mTimer) delete mTimer;
}
Timer *getTimer() override { return mTimer; }
// Encoder related utilities
void setupEncoder();
void deInitCodec();
void resetEncoder();
// Async callback APIs
void onInputAvailable(AMediaCodec *codec, int32_t index) override;
void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) override;
void onOutputAvailable(AMediaCodec *codec, int32_t index,
AMediaCodecBufferInfo *bufferInfo) override;
// Process the frames and give encoded output
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);
private:
AMediaCodec *mCodec;
AMediaFormat *mFormat;
Timer *mTimer;
int32_t mNumInputFrame;
int32_t mNumOutputFrame;
bool mSawInputEOS;
bool mSawOutputEOS;
bool mSignalledError;
char *mMime;
int32_t mOffset;
std::ifstream *mEleStream;
size_t mInputBufferSize;
encParameter mParams;
// Asynchronous locks
std::mutex mMutex;
std::condition_variable mEncoderDoneCondition;
};
#endif // __ENCODER_H__

@ -58,3 +58,20 @@ cc_test {
"libbenchmark_muxer",
],
}
cc_test {
name: "encoderTest",
gtest: true,
defaults: [
"libbenchmark_common-defaults",
"libbenchmark_soft_sanitize_all-defaults",
],
srcs: ["EncoderTest.cpp"],
static_libs: [
"libbenchmark_extractor",
"libbenchmark_decoder",
"libbenchmark_encoder",
],
}

@ -0,0 +1,251 @@
/*
* Copyright (C) 2019 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.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "encoderTest"
#include <fstream>
#include "BenchmarkTestEnvironment.h"
#include "Encoder.h"
#include "Decoder.h"
static BenchmarkTestEnvironment *gEnv = nullptr;
class EncoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
TEST_P(EncoderTest, Encode) {
ALOGD("Encode test for all codecs");
tuple<string /* InputFile */, string /* CodecName */, bool /* asyncMode */> params = GetParam();
string inputFile = gEnv->getRes() + get<0>(params);
FILE *inputFp = fopen(inputFile.c_str(), "rb");
if (!inputFp) {
cout << "[ WARN ] Test Skipped. Unable to open input file for reading \n";
return;
}
Decoder *decoder = new Decoder();
Extractor *extractor = decoder->getExtractor();
if (!extractor) {
cout << "[ WARN ] Test Skipped. Extractor creation failed \n";
return;
}
// Read file properties
fseek(inputFp, 0, SEEK_END);
size_t fileSize = ftell(inputFp);
fseek(inputFp, 0, SEEK_SET);
int32_t fd = fileno(inputFp);
int32_t trackCount = extractor->initExtractor(fd, fileSize);
if (trackCount <= 0) {
cout << "[ WARN ] Test Skipped. initExtractor failed\n";
return;
}
Encoder *encoder = new Encoder();
for (int curTrack = 0; curTrack < trackCount; curTrack++) {
int32_t status = extractor->setupTrackFormat(curTrack);
if (status != 0) {
cout << "[ WARN ] Test Skipped. Track Format invalid \n";
return;
}
uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
if (!inputBuffer) {
cout << "[ WARN ] Test Skipped. Insufficient memory \n";
return;
}
vector<AMediaCodecBufferInfo> frameInfo;
AMediaCodecBufferInfo info;
uint32_t inputBufferOffset = 0;
int32_t idx = 0;
// Get CSD data
while (1) {
void *csdBuffer = extractor->getCSDSample(info, idx);
if (!csdBuffer || !info.size) break;
// copy the meta data and buffer to be passed to decoder
if (inputBufferOffset + info.size > kMaxBufferSize) {
cout << "[ WARN ] Test Skipped. Memory allocated not sufficient\n";
free(inputBuffer);
return;
}
memcpy(inputBuffer + inputBufferOffset, csdBuffer, info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
idx++;
}
// 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) {
cout << "[ WARN ] Test Skipped. Memory allocated not sufficient\n";
free(inputBuffer);
return;
}
memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
}
string decName = "";
string outputFileName = "decode.out";
FILE *outFp = fopen(outputFileName.c_str(), "wb");
if (outFp == nullptr) {
ALOGE("Unable to open output file for writing");
return;
}
decoder->setupDecoder();
status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
if (status != AMEDIA_OK) {
cout << "[ WARN ] Test Skipped. Decode returned error \n";
return;
}
ifstream eleStream;
eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
ASSERT_EQ(eleStream.is_open(), true) << outputFileName.c_str() << " - file not found";
size_t eleSize = eleStream.tellg();
eleStream.seekg(0, ifstream::beg);
AMediaFormat *format = extractor->getFormat();
const char *mime = nullptr;
AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
if (!mime) {
ALOGE("Error in AMediaFormat_getString");
return;
}
// 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 = 25;
if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
encParams.bitrate = 600000 /* 600 Kbps */;
} else {
encParams.bitrate = 8000000 /* 8 Mbps */;
}
}
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
} else {
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &encParams.sampleRate);
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &encParams.numChannels);
encParams.bitrate =
encParams.sampleRate * encParams.numChannels * 16 /* bitsPerSample */;
}
encoder->setupEncoder();
string codecName = get<1>(params);
bool asyncMode = get<2>(params);
status = encoder->encode(codecName, eleStream, eleSize, asyncMode, encParams, (char *)mime);
ASSERT_EQ(status, 0);
encoder->deInitCodec();
cout << "codec : " << codecName << endl;
string inputReference = get<0>(params);
encoder->dumpStatistics(inputReference, extractor->getClipDuration());
eleStream.close();
if (outFp) fclose(outFp);
if (format) {
AMediaFormat_delete(format);
format = nullptr;
}
encoder->resetEncoder();
decoder->deInitCodec();
free(inputBuffer);
decoder->resetDecoder();
}
delete encoder;
fclose(inputFp);
extractor->deInitExtractor();
delete decoder;
}
INSTANTIATE_TEST_SUITE_P(
AudioEncoderSyncTest, EncoderTest,
::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", false),
make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", false),
make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", false),
make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", false)));
INSTANTIATE_TEST_SUITE_P(
AudioEncoderAsyncTest, EncoderTest,
::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", true),
make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", true),
make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", true),
make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", true)));
INSTANTIATE_TEST_SUITE_P(VideEncoderSyncTest, EncoderTest,
::testing::Values(
// Hardware codecs
make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", false),
make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", false),
make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", false),
// Software codecs
make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
"c2.android.vp9.encoder", false),
make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
"c2.android.vp8.encoder", false),
make_tuple("crowd_176x144_25fps_6000kbps_mpeg4.mp4",
"c2.android.mpeg4.encoder", false),
make_tuple("crowd_176x144_25fps_6000kbps_h263.3gp",
"c2.android.h263.encoder", false),
make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
"c2.android.avc.encoder", false),
make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
"c2.android.hevc.encoder", false)));
INSTANTIATE_TEST_SUITE_P(VideoEncoderAsyncTest, EncoderTest,
::testing::Values(
// Hardware codecs
make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", true),
make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", true),
make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", true),
// Software codecs
make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
"c2.android.vp9.encoder", true),
make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
"c2.android.vp8.encoder", true),
make_tuple("crowd_176x144_25fps_6000kbps_mpeg4.mp4",
"c2.android.mpeg4.encoder", true),
make_tuple("crowd_176x144_25fps_6000kbps_h263.3gp",
"c2.android.h263.encoder", true),
make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
"c2.android.avc.encoder", true),
make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
"c2.android.hevc.encoder", true)));
int main(int argc, char **argv) {
gEnv = new BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
if (status == 0) {
status = RUN_ALL_TESTS();
ALOGD("Encoder Test result = %d\n", status);
}
return status;
}
Loading…
Cancel
Save