Test: extractorTest --gtest_repeat=10 -P /sdcard/res/ Bug: 140051680 Change-Id: Ia877298920823337ec791081b40e5c42718a1b65gugelfrei
parent
1b4180698c
commit
dc204de26d
@ -0,0 +1,13 @@
|
||||
BasedOnStyle: Google
|
||||
Standard: Cpp11
|
||||
AccessModifierOffset: -2
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: NOLINT:.*
|
||||
DerivePointerAlignment: false
|
||||
IncludeBlocks: Preserve
|
||||
IndentWidth: 4
|
||||
ContinuationIndentWidth: 8
|
||||
PointerAlignment: Right
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
subdirs = [
|
||||
"src",
|
||||
"tests",
|
||||
]
|
@ -0,0 +1,30 @@
|
||||
# Benchmark tests
|
||||
|
||||
Run the following steps to build the test suite:
|
||||
```
|
||||
mmm frameworks/av/media/tests/benchmark/
|
||||
```
|
||||
|
||||
The binaries will be created in the following path : ${OUT}/data/nativetest64/
|
||||
|
||||
adb push $(OUT)/data/nativetest64/* /data/local/tmp/
|
||||
|
||||
Eg. adb push $(OUT)/data/nativetest64/extractorTest/extractorTest /data/local/tmp/
|
||||
|
||||
To run the binary, follow the commands mentioned below under each module.
|
||||
|
||||
The resource files for the tests are taken from [here](https://drive.google.com/open?id=1ghMr17BBJ7n0pqbm7oREiTN_MNemJUqy)
|
||||
|
||||
## Extractor
|
||||
|
||||
The test extracts elementary stream and benchmarks the extractors available in NDK.
|
||||
|
||||
Push the resource files to /sdcard/res on the device.
|
||||
|
||||
You can use a different location, but you have to modify the rest of the instructions to replace /sdcard/res with wherever you chose to put the files.
|
||||
|
||||
The path to these files on the device is required to be given for the test.
|
||||
|
||||
```
|
||||
adb shell /data/local/tmp/extractorTest -P /sdcard/res/
|
||||
```
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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_extractor",
|
||||
defaults: [
|
||||
"libbenchmark_common-defaults",
|
||||
"libbenchmark_soft_sanitize_all-defaults",
|
||||
],
|
||||
|
||||
srcs: ["Extractor.cpp"],
|
||||
|
||||
export_include_dirs: ["."],
|
||||
|
||||
ldflags: ["-Wl,-Bsymbolic"]
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 "extractor"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Extractor.h"
|
||||
|
||||
int32_t Extractor::initExtractor(int32_t fd, size_t fileSize) {
|
||||
mTimer = new Timer();
|
||||
|
||||
mFrameBuf = (uint8_t *)calloc(kMaxBufferSize, sizeof(uint8_t));
|
||||
if (!mFrameBuf) return -1;
|
||||
|
||||
int64_t sTime = mTimer->getCurTime();
|
||||
|
||||
mExtractor = AMediaExtractor_new();
|
||||
if (!mExtractor) return AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE;
|
||||
media_status_t status = AMediaExtractor_setDataSourceFd(mExtractor, fd, 0, fileSize);
|
||||
if (status != AMEDIA_OK) return status;
|
||||
|
||||
int64_t eTime = mTimer->getCurTime();
|
||||
int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
|
||||
mTimer->setInitTime(timeTaken);
|
||||
|
||||
return AMediaExtractor_getTrackCount(mExtractor);
|
||||
}
|
||||
|
||||
void *Extractor::getCSDSample(AMediaCodecBufferInfo &frameInfo, int32_t csdIndex) {
|
||||
char csdName[kMaxCSDStrlen];
|
||||
void *csdBuffer = nullptr;
|
||||
frameInfo.presentationTimeUs = 0;
|
||||
frameInfo.flags = AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
|
||||
snprintf(csdName, sizeof(csdName), "csd-%d", csdIndex);
|
||||
|
||||
size_t size;
|
||||
bool csdFound = AMediaFormat_getBuffer(mFormat, csdName, &csdBuffer, &size);
|
||||
if (!csdFound) return nullptr;
|
||||
frameInfo.size = (int32_t)size;
|
||||
|
||||
return csdBuffer;
|
||||
}
|
||||
|
||||
int32_t Extractor::getFrameSample(AMediaCodecBufferInfo &frameInfo) {
|
||||
int32_t size = AMediaExtractor_readSampleData(mExtractor, mFrameBuf, kMaxBufferSize);
|
||||
if (size < 0) return -1;
|
||||
|
||||
frameInfo.flags = AMediaExtractor_getSampleFlags(mExtractor);
|
||||
frameInfo.size = size;
|
||||
frameInfo.presentationTimeUs = AMediaExtractor_getSampleTime(mExtractor);
|
||||
AMediaExtractor_advance(mExtractor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Extractor::setupTrackFormat(int32_t trackId) {
|
||||
AMediaExtractor_selectTrack(mExtractor, trackId);
|
||||
mFormat = AMediaExtractor_getTrackFormat(mExtractor, trackId);
|
||||
if (!mFormat) return AMEDIA_ERROR_INVALID_OBJECT;
|
||||
|
||||
bool durationFound = AMediaFormat_getInt64(mFormat, AMEDIAFORMAT_KEY_DURATION, &mDurationUs);
|
||||
if (!durationFound) return AMEDIA_ERROR_INVALID_OBJECT;
|
||||
|
||||
return AMEDIA_OK;
|
||||
}
|
||||
|
||||
int32_t Extractor::extract(int32_t trackId) {
|
||||
int32_t status = setupTrackFormat(trackId);
|
||||
if (status != AMEDIA_OK) return status;
|
||||
|
||||
int32_t idx = 0;
|
||||
AMediaCodecBufferInfo frameInfo;
|
||||
while (1) {
|
||||
memset(&frameInfo, 0, sizeof(AMediaCodecBufferInfo));
|
||||
void *csdBuffer = getCSDSample(frameInfo, idx);
|
||||
if (!csdBuffer || !frameInfo.size) break;
|
||||
idx++;
|
||||
}
|
||||
|
||||
mTimer->setStartTime();
|
||||
while (1) {
|
||||
int32_t status = getFrameSample(frameInfo);
|
||||
if (status || !frameInfo.size) break;
|
||||
mTimer->addOutputTime();
|
||||
}
|
||||
|
||||
if (mFormat) {
|
||||
AMediaFormat_delete(mFormat);
|
||||
mFormat = nullptr;
|
||||
}
|
||||
|
||||
AMediaExtractor_unselectTrack(mExtractor, trackId);
|
||||
|
||||
return AMEDIA_OK;
|
||||
}
|
||||
|
||||
void Extractor::dumpStatistics(string inputReference) {
|
||||
string operation = "extract";
|
||||
mTimer->dumpStatistics(operation, inputReference, mDurationUs);
|
||||
}
|
||||
|
||||
void Extractor::deInitExtractor() {
|
||||
if (mFrameBuf) {
|
||||
free(mFrameBuf);
|
||||
mFrameBuf = nullptr;
|
||||
}
|
||||
|
||||
int64_t sTime = mTimer->getCurTime();
|
||||
if (mExtractor) {
|
||||
// TODO: (b/140128505) Multiple calls result in DoS.
|
||||
// Uncomment call to AMediaExtractor_delete() once this is resolved
|
||||
// AMediaExtractor_delete(mExtractor);
|
||||
mExtractor = nullptr;
|
||||
}
|
||||
int64_t eTime = mTimer->getCurTime();
|
||||
int64_t deInitTime = mTimer->getTimeDiff(sTime, eTime);
|
||||
mTimer->setDeInitTime(deInitTime);
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 __EXTRACTOR_H__
|
||||
#define __EXTRACTOR_H__
|
||||
|
||||
#include <media/NdkMediaExtractor.h>
|
||||
|
||||
#include "BenchmarkCommon.h"
|
||||
#include "Timer.h"
|
||||
|
||||
class Extractor {
|
||||
public:
|
||||
Extractor()
|
||||
: mFormat(nullptr),
|
||||
mExtractor(nullptr),
|
||||
mTimer(nullptr),
|
||||
mFrameBuf{nullptr},
|
||||
mDurationUs{0} {}
|
||||
|
||||
~Extractor() {
|
||||
if (mTimer) delete mTimer;
|
||||
}
|
||||
|
||||
int32_t initExtractor(int32_t fd, size_t fileSize);
|
||||
|
||||
int32_t setupTrackFormat(int32_t trackId);
|
||||
|
||||
void *getCSDSample(AMediaCodecBufferInfo &frameInfo, int32_t csdIndex);
|
||||
|
||||
int32_t getFrameSample(AMediaCodecBufferInfo &frameInfo);
|
||||
|
||||
int32_t extract(int32_t trackId);
|
||||
|
||||
void dumpStatistics(std::string inputReference);
|
||||
|
||||
void deInitExtractor();
|
||||
|
||||
AMediaFormat *getFormat() { return mFormat; }
|
||||
|
||||
uint8_t *getFrameBuf() { return mFrameBuf; }
|
||||
|
||||
int64_t getClipDuration() { return mDurationUs; }
|
||||
|
||||
private:
|
||||
AMediaFormat *mFormat;
|
||||
AMediaExtractor *mExtractor;
|
||||
Timer *mTimer;
|
||||
uint8_t *mFrameBuf;
|
||||
int64_t mDurationUs;
|
||||
};
|
||||
|
||||
#endif // __EXTRACTOR_H__
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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_test {
|
||||
name: "extractorTest",
|
||||
gtest: true,
|
||||
defaults: [
|
||||
"libbenchmark_common-defaults",
|
||||
"libbenchmark_soft_sanitize_all-defaults",
|
||||
],
|
||||
|
||||
srcs: ["ExtractorTest.cpp"],
|
||||
|
||||
static_libs: ["libbenchmark_extractor"]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 __BENCHMARK_TEST_ENVIRONMENT_H__
|
||||
#define __BENCHMARK_TEST_ENVIRONMENT_H__
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BenchmarkTestEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
BenchmarkTestEnvironment() : res("/sdcard/media/") {}
|
||||
|
||||
// Parses the command line argument
|
||||
int initFromOptions(int argc, char **argv);
|
||||
|
||||
void setRes(const char *_res) { res = _res; }
|
||||
|
||||
const string getRes() const { return res; }
|
||||
|
||||
private:
|
||||
string res;
|
||||
};
|
||||
|
||||
int BenchmarkTestEnvironment::initFromOptions(int argc, char **argv) {
|
||||
static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
|
||||
|
||||
while (true) {
|
||||
int index = 0;
|
||||
int c = getopt_long(argc, argv, "P:", options, &index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'P': {
|
||||
setRes(optarg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
fprintf(stderr,
|
||||
"unrecognized option: %s\n\n"
|
||||
"usage: %s <gtest options> <test options>\n\n"
|
||||
"test options are:\n\n"
|
||||
"-P, --path: Resource files directory location\n",
|
||||
argv[optind ?: 1], argv[0]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // __BENCHMARK_TEST_ENVIRONMENT_H__
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 "extractorTest"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Extractor.h"
|
||||
#include "BenchmarkTestEnvironment.h"
|
||||
|
||||
static BenchmarkTestEnvironment *gEnv = nullptr;
|
||||
|
||||
class ExtractorTest : public ::testing::TestWithParam<pair<string, int32_t>> {};
|
||||
|
||||
TEST_P(ExtractorTest, Extract) {
|
||||
Extractor *extractObj = new Extractor();
|
||||
|
||||
string inputFile = gEnv->getRes() + GetParam().first;
|
||||
FILE *inputFp = fopen(inputFile.c_str(), "rb");
|
||||
if (!inputFp) {
|
||||
cout << "[ WARN ] Test Skipped. Unable to open input file for reading \n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Read file properties
|
||||
size_t fileSize = 0;
|
||||
fseek(inputFp, 0, SEEK_END);
|
||||
fileSize = ftell(inputFp);
|
||||
fseek(inputFp, 0, SEEK_SET);
|
||||
int32_t fd = fileno(inputFp);
|
||||
|
||||
int32_t trackCount = extractObj->initExtractor(fd, fileSize);
|
||||
if (trackCount <= 0) {
|
||||
cout << "[ WARN ] Test Skipped. initExtractor failed\n";
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t trackID = GetParam().second;
|
||||
int32_t status = extractObj->extract(trackID);
|
||||
if (status != AMEDIA_OK) {
|
||||
cout << "[ WARN ] Test Skipped. Extraction failed \n";
|
||||
return;
|
||||
}
|
||||
|
||||
extractObj->deInitExtractor();
|
||||
|
||||
extractObj->dumpStatistics(GetParam().first);
|
||||
|
||||
fclose(inputFp);
|
||||
delete extractObj;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ExtractorTestAll, ExtractorTest,
|
||||
::testing::Values(make_pair("crowd_1920x1080_25fps_4000kbps_vp9.webm", 0),
|
||||
make_pair("crowd_1920x1080_25fps_6000kbps_h263.3gp", 0),
|
||||
make_pair("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", 0),
|
||||
make_pair("crowd_1920x1080_25fps_6700kbps_h264.ts", 0),
|
||||
make_pair("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", 0),
|
||||
make_pair("crowd_1920x1080_25fps_4000kbps_av1.webm", 0),
|
||||
make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", 0),
|
||||
make_pair("crowd_1920x1080_25fps_4000kbps_vp8.webm", 0),
|
||||
make_pair("bbb_44100hz_2ch_128kbps_aac_5mins.mp4", 0),
|
||||
make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 0),
|
||||
make_pair("bbb_44100hz_2ch_600kbps_flac_5mins.flac", 0),
|
||||
make_pair("bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", 0),
|
||||
make_pair("bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", 0),
|
||||
make_pair("bbb_44100hz_2ch_80kbps_vorbis_5mins.mp4", 0),
|
||||
make_pair("bbb_48000hz_2ch_100kbps_opus_5mins.webm", 0)));
|
||||
|
||||
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(" Extractor Test result = %d\n", status);
|
||||
}
|
||||
return status;
|
||||
}
|
Loading…
Reference in new issue