mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "media.omx VTS test baseline" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9eeda9561f
3
media/Android.bp
Normal file → Executable file
3
media/Android.bp
Normal file → Executable file
@@ -2,4 +2,7 @@
|
||||
subdirs = [
|
||||
"1.0",
|
||||
"omx/1.0",
|
||||
"omx/1.0/vts/functional/master",
|
||||
"omx/1.0/vts/functional/component",
|
||||
"omx/1.0/vts/functional/audio",
|
||||
]
|
||||
|
||||
79
media/omx/1.0/vts/functional/audio/Android.bp
Normal file
79
media/omx/1.0/vts/functional/audio/Android.bp
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright (C) 2017 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: "VtsHalMediaOmxV1_0TargetAudioEncTest",
|
||||
defaults: ["hidl_defaults"],
|
||||
srcs: ["VtsHalMediaOmxV1_0TargetAudioEncTest.cpp",
|
||||
"media_audio_hidl_test_common.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libhidlmemory",
|
||||
"libhidltransport",
|
||||
"libhwbinder",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"libstagefright_foundation",
|
||||
"android.hidl.allocator@1.0",
|
||||
"android.hidl.memory@1.0",
|
||||
"android.hardware.media.omx@1.0",
|
||||
],
|
||||
static_libs: ["VtsHalHidlTargetTestBase"],
|
||||
cflags: [
|
||||
"-O0",
|
||||
"-g",
|
||||
],
|
||||
include_dirs: [
|
||||
"frameworks/native/include/media/openmax/",
|
||||
"hardware/interfaces/media/omx/1.0/vts/functional/common",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalMediaOmxV1_0TargetAudioDecTest",
|
||||
defaults: ["hidl_defaults"],
|
||||
srcs: ["VtsHalMediaOmxV1_0TargetAudioDecTest.cpp",
|
||||
"media_audio_hidl_test_common.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libhidlmemory",
|
||||
"libhidltransport",
|
||||
"libhwbinder",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"libstagefright_foundation",
|
||||
"android.hidl.allocator@1.0",
|
||||
"android.hidl.memory@1.0",
|
||||
"android.hardware.media.omx@1.0",
|
||||
],
|
||||
static_libs: ["VtsHalHidlTargetTestBase"],
|
||||
cflags: [
|
||||
"-O0",
|
||||
"-g",
|
||||
],
|
||||
include_dirs: [
|
||||
"frameworks/native/include/media/openmax/",
|
||||
"hardware/interfaces/media/omx/1.0/vts/functional/common",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,687 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_TAG "media_omx_hidl_audio_dec_test"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android/hardware/media/omx/1.0/IOmx.h>
|
||||
#include <android/hardware/media/omx/1.0/IOmxNode.h>
|
||||
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
|
||||
#include <android/hardware/media/omx/1.0/types.h>
|
||||
#include <android/hidl/allocator/1.0/IAllocator.h>
|
||||
#include <android/hidl/memory/1.0/IMapper.h>
|
||||
#include <android/hidl/memory/1.0/IMemory.h>
|
||||
|
||||
using ::android::hardware::media::omx::V1_0::IOmx;
|
||||
using ::android::hardware::media::omx::V1_0::IOmxObserver;
|
||||
using ::android::hardware::media::omx::V1_0::IOmxNode;
|
||||
using ::android::hardware::media::omx::V1_0::Message;
|
||||
using ::android::hardware::media::omx::V1_0::CodecBuffer;
|
||||
using ::android::hidl::allocator::V1_0::IAllocator;
|
||||
using ::android::hidl::memory::V1_0::IMemory;
|
||||
using ::android::hidl::memory::V1_0::IMapper;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
#include <getopt.h>
|
||||
#include <media_audio_hidl_test_common.h>
|
||||
#include <media_hidl_test_common.h>
|
||||
#include <fstream>
|
||||
|
||||
// A class for test environment setup
|
||||
class ComponentTestEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
ComponentTestEnvironment() : instance("default") {}
|
||||
|
||||
void setInstance(const char* _instance) { instance = _instance; }
|
||||
|
||||
void setComponent(const char* _component) { component = _component; }
|
||||
|
||||
void setRole(const char* _role) { role = _role; }
|
||||
|
||||
void setQuirks(int _quirks) { quirks = _quirks; }
|
||||
|
||||
const hidl_string getInstance() const { return instance; }
|
||||
|
||||
const hidl_string getComponent() const { return component; }
|
||||
|
||||
const hidl_string getRole() const { return role; }
|
||||
|
||||
int getQuirks() const { return quirks; }
|
||||
|
||||
int initFromOptions(int argc, char** argv) {
|
||||
static struct option options[] = {
|
||||
{"instance", required_argument, 0, 'I'},
|
||||
{"component", required_argument, 0, 'C'},
|
||||
{"role", required_argument, 0, 'R'},
|
||||
{"quirks", required_argument, 0, 'Q'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
while (true) {
|
||||
int index = 0;
|
||||
int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'I':
|
||||
setInstance(optarg);
|
||||
break;
|
||||
case 'C':
|
||||
setComponent(optarg);
|
||||
break;
|
||||
case 'Q':
|
||||
setQuirks(atoi(optarg));
|
||||
break;
|
||||
case 'R':
|
||||
setRole(optarg);
|
||||
break;
|
||||
case '?':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
fprintf(stderr,
|
||||
"unrecognized option: %s\n\n"
|
||||
"usage: %s <gtest options> <test options>\n\n"
|
||||
"test options are:\n\n"
|
||||
"-I, --instance: HAL instance to test\n"
|
||||
"-C, --component: OMX component to test\n"
|
||||
"-R, --Role: OMX component Role\n"
|
||||
"-Q, --quirks: Component quirks\n",
|
||||
argv[optind ?: 1], argv[0]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
hidl_string instance;
|
||||
hidl_string component;
|
||||
hidl_string role;
|
||||
// to be removed when IOmxNode::setQuirks is removed
|
||||
int quirks;
|
||||
};
|
||||
|
||||
static ComponentTestEnvironment* gEnv = nullptr;
|
||||
|
||||
class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
|
||||
gEnv->getInstance());
|
||||
ASSERT_NE(omx, nullptr);
|
||||
observer = new CodecObserver();
|
||||
ASSERT_NE(observer, nullptr);
|
||||
ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
|
||||
<< "Invalid Component Name";
|
||||
EXPECT_TRUE(omx->allocateNode(
|
||||
gEnv->getComponent(), observer,
|
||||
[&](android::hardware::media::omx::V1_0::Status _s,
|
||||
sp<IOmxNode> const& _nl) {
|
||||
status = _s;
|
||||
this->omxNode = _nl;
|
||||
})
|
||||
.isOk());
|
||||
ASSERT_NE(omxNode, nullptr);
|
||||
ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
|
||||
struct StringToName {
|
||||
const char* Name;
|
||||
standardComp CompName;
|
||||
};
|
||||
const StringToName kStringToName[] = {
|
||||
{"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
|
||||
{"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
|
||||
{"pcm", pcm}, {"flac", flac},
|
||||
};
|
||||
const size_t kNumStringToName =
|
||||
sizeof(kStringToName) / sizeof(kStringToName[0]);
|
||||
const char* pch;
|
||||
char substring[OMX_MAX_STRINGNAME_SIZE];
|
||||
strcpy(substring, gEnv->getRole().c_str());
|
||||
pch = strchr(substring, '.');
|
||||
ASSERT_NE(pch, nullptr);
|
||||
compName = unknown_comp;
|
||||
for (size_t i = 0; i < kNumStringToName; ++i) {
|
||||
if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
|
||||
compName = kStringToName[i].CompName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(compName, unknown_comp);
|
||||
struct CompToCoding {
|
||||
standardComp CompName;
|
||||
OMX_AUDIO_CODINGTYPE eEncoding;
|
||||
};
|
||||
static const CompToCoding kCompToCoding[] = {
|
||||
{mp3, OMX_AUDIO_CodingMP3},
|
||||
{amrnb, OMX_AUDIO_CodingAMR},
|
||||
{amrwb, OMX_AUDIO_CodingAMR},
|
||||
{aac, OMX_AUDIO_CodingAAC},
|
||||
{vorbis, OMX_AUDIO_CodingVORBIS},
|
||||
{pcm, OMX_AUDIO_CodingPCM},
|
||||
{opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
|
||||
{flac, OMX_AUDIO_CodingFLAC},
|
||||
};
|
||||
static const size_t kNumCompToCoding =
|
||||
sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
|
||||
size_t i;
|
||||
for (i = 0; i < kNumCompToCoding; ++i) {
|
||||
if (kCompToCoding[i].CompName == compName) {
|
||||
eEncoding = kCompToCoding[i].eEncoding;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(i, kNumCompToCoding);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
if (omxNode != nullptr) {
|
||||
EXPECT_TRUE((omxNode->freeNode()).isOk());
|
||||
omxNode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
enum standardComp {
|
||||
mp3,
|
||||
amrnb,
|
||||
amrwb,
|
||||
aac,
|
||||
vorbis,
|
||||
opus,
|
||||
pcm,
|
||||
flac,
|
||||
unknown_comp,
|
||||
};
|
||||
|
||||
sp<IOmx> omx;
|
||||
sp<CodecObserver> observer;
|
||||
sp<IOmxNode> omxNode;
|
||||
standardComp compName;
|
||||
OMX_AUDIO_CODINGTYPE eEncoding;
|
||||
};
|
||||
|
||||
void setDefaultPortParam(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding,
|
||||
int32_t nChannels = 2, int32_t nSampleRate = 44100,
|
||||
OMX_NUMERICALDATATYPE eNumData = OMX_NumericalDataSigned,
|
||||
int32_t nBitPerSample = 16) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_PARAM_PORTDEFINITIONTYPE portDef;
|
||||
status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
|
||||
&portDef);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
portDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
|
||||
portDef.format.audio.eEncoding = eEncoding;
|
||||
status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
|
||||
&portDef);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
switch ((int)eEncoding) {
|
||||
case OMX_AUDIO_CodingPCM:
|
||||
setupPCMPort(omxNode, portIndex, nChannels, eNumData, nBitPerSample,
|
||||
nSampleRate);
|
||||
break;
|
||||
default:
|
||||
ASSERT_TRUE(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
|
||||
OMX_AUDIO_CODINGTYPE eEncoding, int32_t* nChannels,
|
||||
int32_t* nSampleRate) {
|
||||
*nChannels = 0;
|
||||
*nSampleRate = 0;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
|
||||
switch ((int)eEncoding) {
|
||||
case OMX_AUDIO_CodingPCM: {
|
||||
OMX_AUDIO_PARAM_PCMMODETYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioPcm,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = param.nSamplingRate;
|
||||
break;
|
||||
}
|
||||
case OMX_AUDIO_CodingMP3: {
|
||||
OMX_AUDIO_PARAM_MP3TYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioMp3,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = param.nSampleRate;
|
||||
break;
|
||||
}
|
||||
case OMX_AUDIO_CodingFLAC: {
|
||||
OMX_AUDIO_PARAM_FLACTYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioFlac,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = param.nSampleRate;
|
||||
break;
|
||||
}
|
||||
case OMX_AUDIO_CodingAndroidOPUS: {
|
||||
OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
|
||||
status = getPortParam(omxNode,
|
||||
(OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = param.nSampleRate;
|
||||
break;
|
||||
}
|
||||
case OMX_AUDIO_CodingVORBIS: {
|
||||
OMX_AUDIO_PARAM_VORBISTYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioVorbis,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = param.nSampleRate;
|
||||
break;
|
||||
}
|
||||
case OMX_AUDIO_CodingAMR: {
|
||||
OMX_AUDIO_PARAM_AMRTYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioAmr,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = 8000;
|
||||
break;
|
||||
}
|
||||
case OMX_AUDIO_CodingAAC: {
|
||||
OMX_AUDIO_PARAM_AACPROFILETYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioAac,
|
||||
kPortIndexInput, ¶m);
|
||||
ASSERT_EQ(status,
|
||||
::android::hardware::media::omx::V1_0::Status::OK);
|
||||
*nChannels = param.nChannels;
|
||||
*nSampleRate = param.nSampleRate;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ASSERT_TRUE(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GetURLForComponent(AudioDecHidlTest::standardComp comp, const char** mURL,
|
||||
const char** info) {
|
||||
struct CompToURL {
|
||||
AudioDecHidlTest::standardComp comp;
|
||||
const char* mURL;
|
||||
const char* info;
|
||||
};
|
||||
static const CompToURL kCompToURL[] = {
|
||||
{AudioDecHidlTest::standardComp::mp3,
|
||||
"/sdcard/raw/MP3_48KHz_128kbps_s_1_17_CBR.audio.mp3",
|
||||
"/sdcard/raw/MP3_48KHz_128kbps_s_1_17_CBR.audio.info"},
|
||||
{AudioDecHidlTest::standardComp::aac,
|
||||
"/sdcard/raw/H264_500_AAC_128.audio.aac",
|
||||
"/sdcard/raw/H264_500_AAC_128.audio.info"},
|
||||
{AudioDecHidlTest::standardComp::amrnb,
|
||||
"/sdcard/raw/H264_320_AMRNB_6.audio.amr",
|
||||
"/sdcard/raw/H264_320_AMRNB_6.audio.info"},
|
||||
{AudioDecHidlTest::standardComp::amrwb, "", ""},
|
||||
{AudioDecHidlTest::standardComp::vorbis, "", ""},
|
||||
{AudioDecHidlTest::standardComp::opus, "", ""},
|
||||
{AudioDecHidlTest::standardComp::flac, "", ""},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
|
||||
if (kCompToURL[i].comp == comp) {
|
||||
*mURL = kCompToURL[i].mURL;
|
||||
*info = kCompToURL[i].info;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flushAllPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
// Flush
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
|
||||
kPortIndexInput);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
|
||||
ASSERT_EQ(msg.data.eventData.data2, kPortIndexInput);
|
||||
// test if client got all its buffers back
|
||||
for (size_t i = 0; i < iBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*iBuffer)[i].owner, client);
|
||||
}
|
||||
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
|
||||
kPortIndexOutput);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
|
||||
ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
|
||||
// test if client got all its buffers back
|
||||
for (size_t i = 0; i < oBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*oBuffer)[i].owner, client);
|
||||
}
|
||||
}
|
||||
|
||||
void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_AUDIO_CODINGTYPE eEncoding, OMX_U32 kPortIndexInput,
|
||||
OMX_U32 kPortIndexOutput, uint32_t nFrames,
|
||||
std::ifstream& eleStream, std::ifstream& eleInfo) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// dispatch output buffers
|
||||
for (size_t i = 0; i < oBuffer->size(); i++) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, i);
|
||||
}
|
||||
// dispatch input buffers
|
||||
int bytesCount = 0;
|
||||
for (size_t i = 0; i < iBuffer->size(); i++) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
|
||||
if (!(eleInfo >> bytesCount)) break;
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
ASSERT_EQ(eleStream.gcount(), bytesCount);
|
||||
dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, 0);
|
||||
}
|
||||
|
||||
while (nFrames != 0) {
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
if (status == android::hardware::media::omx::V1_0::Status::OK &&
|
||||
msg.type == Message::Type::EVENT &&
|
||||
msg.data.eventData.event == OMX_EventPortSettingsChanged) {
|
||||
ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
|
||||
|
||||
status = omxNode->sendCommand(
|
||||
toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
|
||||
oBuffer);
|
||||
if (status ==
|
||||
android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
|
||||
for (size_t i = 0; i < oBuffer->size(); ++i) {
|
||||
// test if client got all its buffers back
|
||||
EXPECT_EQ((*oBuffer)[i].owner, client);
|
||||
// free the buffers
|
||||
status =
|
||||
omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
|
||||
ASSERT_EQ(status,
|
||||
android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
|
||||
iBuffer, oBuffer);
|
||||
ASSERT_EQ(status,
|
||||
android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
|
||||
ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
|
||||
|
||||
// Port Reconfigurations
|
||||
int32_t nChannels;
|
||||
int32_t nSampleRate;
|
||||
getInputChannelInfo(omxNode, kPortIndexInput, eEncoding,
|
||||
&nChannels, &nSampleRate);
|
||||
setDefaultPortParam(omxNode, kPortIndexOutput,
|
||||
OMX_AUDIO_CodingPCM, nChannels,
|
||||
nSampleRate);
|
||||
|
||||
// If you can disable a port, then you should be able to enable
|
||||
// it as well
|
||||
status = omxNode->sendCommand(
|
||||
toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
|
||||
ASSERT_EQ(status,
|
||||
android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// do not enable the port until all the buffers are supplied
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
|
||||
iBuffer, oBuffer);
|
||||
ASSERT_EQ(
|
||||
status,
|
||||
android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
|
||||
iBuffer, oBuffer);
|
||||
ASSERT_EQ(status,
|
||||
android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
|
||||
ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
|
||||
|
||||
// dispatch output buffers
|
||||
for (size_t i = 0; i < oBuffer->size(); i++) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, i);
|
||||
}
|
||||
} else {
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
size_t index = 0;
|
||||
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
|
||||
if (!(eleInfo >> bytesCount)) break;
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
ASSERT_EQ(eleStream.gcount(), bytesCount);
|
||||
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0, 0);
|
||||
}
|
||||
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, index);
|
||||
}
|
||||
nFrames--;
|
||||
}
|
||||
}
|
||||
|
||||
// Set Component Role
|
||||
TEST_F(AudioDecHidlTest, SetRole) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// Enumerate Port Format
|
||||
TEST_F(AudioDecHidlTest, EnumeratePortFormat) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
OMX_PORT_PARAM_TYPE params;
|
||||
status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
kPortIndexInput = params.nStartPortNumber;
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
status = setAudioPortFormat(omxNode, kPortIndexInput, eEncoding);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
status = setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// Decode Test
|
||||
TEST_F(AudioDecHidlTest, DecodeTest) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
OMX_PORT_PARAM_TYPE params;
|
||||
status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
kPortIndexInput = params.nStartPortNumber;
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
const char *mURL = nullptr, *info = nullptr;
|
||||
GetURLForComponent(compName, &mURL, &info);
|
||||
EXPECT_NE(mURL, nullptr);
|
||||
EXPECT_NE(info, nullptr);
|
||||
|
||||
std::ifstream eleStream, eleInfo;
|
||||
eleStream.open(mURL, std::ifstream::binary);
|
||||
ASSERT_EQ(eleStream.is_open(), true);
|
||||
eleInfo.open(info);
|
||||
ASSERT_EQ(eleInfo.is_open(), true);
|
||||
|
||||
if (eEncoding == OMX_AUDIO_CodingPCM)
|
||||
setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
|
||||
int32_t nChannels;
|
||||
int32_t nSampleRate;
|
||||
getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
|
||||
&nSampleRate);
|
||||
setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
|
||||
nChannels, nSampleRate);
|
||||
|
||||
Message msg;
|
||||
android::Vector<BufferInfo> iBuffer, oBuffer;
|
||||
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
allocatePortBuffers(omxNode, &iBuffer, kPortIndexInput);
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
allocatePortBuffers(omxNode, &oBuffer, kPortIndexOutput);
|
||||
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
|
||||
ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
|
||||
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateExecuting);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
|
||||
ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
|
||||
|
||||
// Port Reconfiguration
|
||||
decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
|
||||
kPortIndexInput, kPortIndexOutput, (1 << 12), eleStream,
|
||||
eleInfo);
|
||||
|
||||
// flush
|
||||
flushAllPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
|
||||
kPortIndexOutput);
|
||||
|
||||
// set state to Idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
|
||||
ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
|
||||
|
||||
// set state to Loaded
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateLoaded);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// dont change state until all buffers are freed
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
for (size_t i = 0; i < iBuffer.size(); ++i) {
|
||||
status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// dont change state until all buffers are freed
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
for (size_t i = 0; i < oBuffer.size(); ++i) {
|
||||
status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(msg.type, Message::Type::EVENT);
|
||||
ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
|
||||
ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
|
||||
ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
|
||||
|
||||
eleInfo.close();
|
||||
eleStream.close();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
gEnv = new ComponentTestEnvironment();
|
||||
::testing::AddGlobalTestEnvironment(gEnv);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int status = gEnv->initFromOptions(argc, argv);
|
||||
if (status == 0) {
|
||||
status = RUN_ALL_TESTS();
|
||||
ALOGI("Test result = %d", status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_TAG "media_omx_hidl_audio_enc_test"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android/hardware/media/omx/1.0/IOmx.h>
|
||||
#include <android/hardware/media/omx/1.0/IOmxNode.h>
|
||||
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
|
||||
#include <android/hardware/media/omx/1.0/types.h>
|
||||
#include <android/hidl/allocator/1.0/IAllocator.h>
|
||||
#include <android/hidl/memory/1.0/IMapper.h>
|
||||
#include <android/hidl/memory/1.0/IMemory.h>
|
||||
|
||||
using ::android::hardware::media::omx::V1_0::IOmx;
|
||||
using ::android::hardware::media::omx::V1_0::IOmxObserver;
|
||||
using ::android::hardware::media::omx::V1_0::IOmxNode;
|
||||
using ::android::hardware::media::omx::V1_0::Message;
|
||||
using ::android::hardware::media::omx::V1_0::CodecBuffer;
|
||||
using ::android::hidl::allocator::V1_0::IAllocator;
|
||||
using ::android::hidl::memory::V1_0::IMemory;
|
||||
using ::android::hidl::memory::V1_0::IMapper;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
#include <getopt.h>
|
||||
#include <media_audio_hidl_test_common.h>
|
||||
#include <media_hidl_test_common.h>
|
||||
#include <fstream>
|
||||
|
||||
// A class for test environment setup
|
||||
class ComponentTestEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
ComponentTestEnvironment() : instance("default") {}
|
||||
|
||||
void setInstance(const char* _instance) { instance = _instance; }
|
||||
|
||||
void setComponent(const char* _component) { component = _component; }
|
||||
|
||||
void setRole(const char* _role) { role = _role; }
|
||||
|
||||
void setQuirks(int _quirks) { quirks = _quirks; }
|
||||
|
||||
const hidl_string getInstance() const { return instance; }
|
||||
|
||||
const hidl_string getComponent() const { return component; }
|
||||
|
||||
const hidl_string getRole() const { return role; }
|
||||
|
||||
int getQuirks() const { return quirks; }
|
||||
|
||||
int initFromOptions(int argc, char** argv) {
|
||||
static struct option options[] = {
|
||||
{"instance", required_argument, 0, 'I'},
|
||||
{"component", required_argument, 0, 'C'},
|
||||
{"role", required_argument, 0, 'R'},
|
||||
{"quirks", required_argument, 0, 'Q'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
while (true) {
|
||||
int index = 0;
|
||||
int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'I':
|
||||
setInstance(optarg);
|
||||
break;
|
||||
case 'C':
|
||||
setComponent(optarg);
|
||||
break;
|
||||
case 'Q':
|
||||
setQuirks(atoi(optarg));
|
||||
break;
|
||||
case 'R':
|
||||
setRole(optarg);
|
||||
break;
|
||||
case '?':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
fprintf(stderr,
|
||||
"unrecognized option: %s\n\n"
|
||||
"usage: %s <gtest options> <test options>\n\n"
|
||||
"test options are:\n\n"
|
||||
"-I, --instance: HAL instance to test\n"
|
||||
"-C, --component: OMX component to test\n"
|
||||
"-R, --Role: OMX component Role\n"
|
||||
"-Q, --quirks: Component quirks\n",
|
||||
argv[optind ?: 1], argv[0]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
hidl_string instance;
|
||||
hidl_string component;
|
||||
hidl_string role;
|
||||
// to be removed when IOmxNode::setQuirks is removed
|
||||
int quirks;
|
||||
};
|
||||
|
||||
static ComponentTestEnvironment* gEnv = nullptr;
|
||||
|
||||
class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
|
||||
gEnv->getInstance());
|
||||
ASSERT_NE(omx, nullptr);
|
||||
observer = new CodecObserver();
|
||||
ASSERT_NE(observer, nullptr);
|
||||
ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
|
||||
<< "Invalid Component Name";
|
||||
EXPECT_TRUE(omx->allocateNode(
|
||||
gEnv->getComponent(), observer,
|
||||
[&](android::hardware::media::omx::V1_0::Status _s,
|
||||
sp<IOmxNode> const& _nl) {
|
||||
status = _s;
|
||||
this->omxNode = _nl;
|
||||
})
|
||||
.isOk());
|
||||
ASSERT_NE(omxNode, nullptr);
|
||||
ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
|
||||
struct StringToName {
|
||||
const char* Name;
|
||||
standardComp CompName;
|
||||
};
|
||||
const StringToName kStringToName[] = {
|
||||
{"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
|
||||
{"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
|
||||
{"pcm", pcm}, {"flac", flac},
|
||||
};
|
||||
const size_t kNumStringToName =
|
||||
sizeof(kStringToName) / sizeof(kStringToName[0]);
|
||||
const char* pch;
|
||||
char substring[OMX_MAX_STRINGNAME_SIZE];
|
||||
strcpy(substring, gEnv->getRole().c_str());
|
||||
pch = strchr(substring, '.');
|
||||
ASSERT_NE(pch, nullptr);
|
||||
compName = unknown_comp;
|
||||
for (size_t i = 0; i < kNumStringToName; ++i) {
|
||||
if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
|
||||
compName = kStringToName[i].CompName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(compName, unknown_comp);
|
||||
struct CompToCoding {
|
||||
standardComp CompName;
|
||||
OMX_AUDIO_CODINGTYPE eEncoding;
|
||||
};
|
||||
static const CompToCoding kCompToCoding[] = {
|
||||
{mp3, OMX_AUDIO_CodingMP3},
|
||||
{amrnb, OMX_AUDIO_CodingAMR},
|
||||
{amrwb, OMX_AUDIO_CodingAMR},
|
||||
{aac, OMX_AUDIO_CodingAAC},
|
||||
{vorbis, OMX_AUDIO_CodingVORBIS},
|
||||
{pcm, OMX_AUDIO_CodingPCM},
|
||||
{opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
|
||||
{flac, OMX_AUDIO_CodingFLAC},
|
||||
};
|
||||
static const size_t kNumCompToCoding =
|
||||
sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
|
||||
size_t i;
|
||||
for (i = 0; i < kNumCompToCoding; ++i) {
|
||||
if (kCompToCoding[i].CompName == compName) {
|
||||
eEncoding = kCompToCoding[i].eEncoding;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(i, kNumCompToCoding);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
if (omxNode != nullptr) {
|
||||
EXPECT_TRUE((omxNode->freeNode()).isOk());
|
||||
omxNode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
enum standardComp {
|
||||
mp3,
|
||||
amrnb,
|
||||
amrwb,
|
||||
aac,
|
||||
vorbis,
|
||||
opus,
|
||||
pcm,
|
||||
flac,
|
||||
unknown_comp,
|
||||
};
|
||||
|
||||
sp<IOmx> omx;
|
||||
sp<CodecObserver> observer;
|
||||
sp<IOmxNode> omxNode;
|
||||
standardComp compName;
|
||||
OMX_AUDIO_CODINGTYPE eEncoding;
|
||||
};
|
||||
|
||||
// Set Component Role
|
||||
TEST_F(AudioEncHidlTest, SetRole) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// Enumerate Port Format
|
||||
TEST_F(AudioEncHidlTest, EnumeratePortFormat) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
OMX_PORT_PARAM_TYPE params;
|
||||
status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
kPortIndexInput = params.nStartPortNumber;
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
status = setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
status = setAudioPortFormat(omxNode, kPortIndexOutput, eEncoding);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
gEnv = new ComponentTestEnvironment();
|
||||
::testing::AddGlobalTestEnvironment(gEnv);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int status = gEnv->initFromOptions(argc, argv);
|
||||
if (status == 0) {
|
||||
status = RUN_ALL_TESTS();
|
||||
ALOGI("Test result = %d", status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_TAG "media_omx_hidl_audio_test_common"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android/hardware/media/omx/1.0/IOmx.h>
|
||||
#include <android/hardware/media/omx/1.0/IOmxNode.h>
|
||||
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
|
||||
#include <android/hardware/media/omx/1.0/types.h>
|
||||
#include <android/hidl/allocator/1.0/IAllocator.h>
|
||||
#include <android/hidl/memory/1.0/IMapper.h>
|
||||
#include <android/hidl/memory/1.0/IMemory.h>
|
||||
|
||||
using ::android::hardware::media::omx::V1_0::IOmx;
|
||||
using ::android::hardware::media::omx::V1_0::IOmxObserver;
|
||||
using ::android::hardware::media::omx::V1_0::IOmxNode;
|
||||
using ::android::hardware::media::omx::V1_0::Message;
|
||||
using ::android::hardware::media::omx::V1_0::CodecBuffer;
|
||||
using ::android::hidl::allocator::V1_0::IAllocator;
|
||||
using ::android::hidl::memory::V1_0::IMemory;
|
||||
using ::android::hidl::memory::V1_0::IMapper;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
#include <hidlmemory/mapping.h>
|
||||
#include <media_audio_hidl_test_common.h>
|
||||
#include <media_hidl_test_common.h>
|
||||
#include <memory>
|
||||
|
||||
void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
OMX_U32 portIndex) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_PARAM_PORTDEFINITIONTYPE portDef;
|
||||
|
||||
buffArray->clear();
|
||||
|
||||
sp<IAllocator> allocator = IAllocator::getService("ashmem");
|
||||
EXPECT_NE(allocator, nullptr);
|
||||
|
||||
status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
|
||||
&portDef);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
|
||||
BufferInfo buffer;
|
||||
buffer.owner = client;
|
||||
buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
|
||||
buffer.omxBuffer.attr.preset.rangeOffset = 0;
|
||||
buffer.omxBuffer.attr.preset.rangeLength = 0;
|
||||
bool success;
|
||||
allocator->allocate(
|
||||
portDef.nBufferSize,
|
||||
[&success, &buffer](bool _s,
|
||||
::android::hardware::hidl_memory const& mem) {
|
||||
success = _s;
|
||||
buffer.omxBuffer.sharedMemory = mem;
|
||||
});
|
||||
ASSERT_EQ(success, true);
|
||||
buffer.mMemory = mapMemory(buffer.omxBuffer.sharedMemory);
|
||||
ASSERT_NE(buffer.mMemory, nullptr);
|
||||
omxNode->useBuffer(
|
||||
portIndex, buffer.omxBuffer,
|
||||
[&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
|
||||
uint32_t id) {
|
||||
status = _s;
|
||||
buffer.id = id;
|
||||
});
|
||||
buffArray->push(buffer);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
}
|
||||
|
||||
size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray) {
|
||||
for (size_t i = 0; i < buffArray->size(); i++) {
|
||||
if ((*buffArray)[i].owner == client) return i;
|
||||
}
|
||||
return buffArray->size();
|
||||
}
|
||||
|
||||
void dispatchInputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex, int bytesCount, uint32_t flags,
|
||||
uint64_t timestamp) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
CodecBuffer t;
|
||||
t.sharedMemory = android::hardware::hidl_memory();
|
||||
t.nativeHandle = android::hardware::hidl_handle();
|
||||
t.type = CodecBuffer::Type::PRESET;
|
||||
t.attr.preset.rangeOffset = 0;
|
||||
t.attr.preset.rangeLength = bytesCount;
|
||||
native_handle_t* fenceNh = native_handle_create(0, 0);
|
||||
ASSERT_NE(fenceNh, nullptr);
|
||||
status = omxNode->emptyBuffer((*buffArray)[bufferIndex].id, t, flags,
|
||||
timestamp, fenceNh);
|
||||
native_handle_close(fenceNh);
|
||||
native_handle_delete(fenceNh);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
buffArray->editItemAt(bufferIndex).owner = component;
|
||||
}
|
||||
|
||||
void dispatchOutputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
CodecBuffer t;
|
||||
t.sharedMemory = android::hardware::hidl_memory();
|
||||
t.nativeHandle = android::hardware::hidl_handle();
|
||||
t.type = CodecBuffer::Type::PRESET;
|
||||
t.attr.preset.rangeOffset = 0;
|
||||
t.attr.preset.rangeLength = 0;
|
||||
native_handle_t* fenceNh = native_handle_create(0, 0);
|
||||
ASSERT_NE(fenceNh, nullptr);
|
||||
status = omxNode->fillBuffer((*buffArray)[bufferIndex].id, t, fenceNh);
|
||||
native_handle_close(fenceNh);
|
||||
native_handle_delete(fenceNh);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
buffArray->editItemAt(bufferIndex).owner = component;
|
||||
}
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding) {
|
||||
OMX_U32 index = 0;
|
||||
OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
|
||||
std::vector<OMX_AUDIO_CODINGTYPE> eEncoding;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
|
||||
while (1) {
|
||||
portFormat.nIndex = index;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
|
||||
&portFormat);
|
||||
if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
|
||||
eEncoding.push_back(portFormat.eEncoding);
|
||||
index++;
|
||||
if (index == 512) {
|
||||
EXPECT_LE(index, 512U)
|
||||
<< "Expecting OMX_ErrorNoMore but not received";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!index) return status;
|
||||
for (index = 0; index < eEncoding.size(); index++) {
|
||||
if (eEncoding[index] == encoding) {
|
||||
portFormat.eEncoding = eEncoding[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == eEncoding.size()) {
|
||||
ALOGI("setting default Port format");
|
||||
portFormat.eEncoding = eEncoding[0];
|
||||
}
|
||||
// In setParam call nIndex shall be ignored as per omx-il specification.
|
||||
// see how this holds up by corrupting nIndex
|
||||
portFormat.nIndex = RANDOM_INDEX;
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
|
||||
&portFormat);
|
||||
return status;
|
||||
}
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setRole(
|
||||
sp<IOmxNode> omxNode, const char* role) {
|
||||
OMX_PARAM_COMPONENTROLETYPE params;
|
||||
strcpy((char*)params.cRole, role);
|
||||
return setParam(omxNode, OMX_IndexParamStandardComponentRole, ¶ms);
|
||||
}
|
||||
|
||||
void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
OMX_NUMERICALDATATYPE eNumData, int32_t nBitPerSample,
|
||||
int32_t nSamplingRate) {
|
||||
OMX_AUDIO_PARAM_PCMMODETYPE param;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.eNumData = eNumData;
|
||||
param.eEndian = OMX_EndianBig;
|
||||
param.bInterleaved = OMX_TRUE;
|
||||
param.nBitPerSample = nBitPerSample;
|
||||
param.nSamplingRate = nSamplingRate;
|
||||
param.ePCMMode = OMX_AUDIO_PCMModeLinear;
|
||||
switch (nChannels) {
|
||||
case 1:
|
||||
param.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
|
||||
break;
|
||||
case 2:
|
||||
param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
|
||||
param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
|
||||
break;
|
||||
default:
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
OMX_AUDIO_PARAM_MP3TYPE param;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.nBitRate = nBitRate;
|
||||
param.nSampleRate = nSampleRate;
|
||||
param.nAudioBandWidth = 0;
|
||||
param.eChannelMode = (nChannels == 1) ? OMX_AUDIO_ChannelModeMono
|
||||
: OMX_AUDIO_ChannelModeStereo;
|
||||
param.eFormat = eFormat;
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nSampleRate, int32_t nCompressionLevel,
|
||||
bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_FLACTYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.nSampleRate = nSampleRate;
|
||||
param.nCompressionLevel = nCompressionLevel;
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
|
||||
status =
|
||||
getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
|
||||
portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.nBitRate = nBitRate;
|
||||
param.nSampleRate = nSampleRate;
|
||||
status =
|
||||
setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
|
||||
portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
|
||||
OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_AMRTYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = 1;
|
||||
param.nBitRate = nBitRate;
|
||||
param.eAMRBandMode = eAMRBandMode;
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
|
||||
bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_VORBISTYPE param;
|
||||
status =
|
||||
getPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.nBitRate = nBitRate;
|
||||
param.nSampleRate = nSampleRate;
|
||||
param.nQuality = nQuality;
|
||||
status =
|
||||
setPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_AUDIO_AACPROFILETYPE eAACProfile,
|
||||
OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat,
|
||||
int32_t nChannels, int32_t nBitRate, int32_t nSampleRate,
|
||||
bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_AACPROFILETYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.nSampleRate = nSampleRate;
|
||||
param.nBitRate = nBitRate;
|
||||
param.eAACProfile = eAACProfile;
|
||||
param.eAACStreamFormat = eAACStreamFormat;
|
||||
param.eChannelMode = (nChannels == 1) ? OMX_AUDIO_ChannelModeMono
|
||||
: OMX_AUDIO_ChannelModeStereo;
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2016, 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 MEDIA_AUDIO_HIDL_TEST_COMMON_H
|
||||
#define MEDIA_AUDIO_HIDL_TEST_COMMON_H
|
||||
|
||||
#include <media_hidl_test_common.h>
|
||||
/*
|
||||
* Random Index used for monkey testing while get/set parameters
|
||||
*/
|
||||
#define RANDOM_INDEX 1729
|
||||
|
||||
/*
|
||||
* Common audio utils
|
||||
*/
|
||||
void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
OMX_U32 portIndex);
|
||||
|
||||
size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);
|
||||
|
||||
void dispatchInputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex, int bytesCount, uint32_t flags,
|
||||
uint64_t timestamp);
|
||||
|
||||
void dispatchOutputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex);
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding);
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setRole(
|
||||
sp<IOmxNode> omxNode, const char* role);
|
||||
|
||||
void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
OMX_NUMERICALDATATYPE eNumData, int32_t nBitPerSample,
|
||||
int32_t nSamplingRate);
|
||||
|
||||
void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
|
||||
|
||||
void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nSampleRate, int32_t nCompressionLevel,
|
||||
bool isEncoder);
|
||||
|
||||
void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
|
||||
|
||||
void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
|
||||
OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder);
|
||||
|
||||
void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
|
||||
bool isEncoder);
|
||||
|
||||
void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_AUDIO_AACPROFILETYPE eAACProfile,
|
||||
OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat,
|
||||
int32_t nChannels, int32_t nBitRate, int32_t nSampleRate,
|
||||
bool isEncoder);
|
||||
|
||||
#endif // MEDIA_AUDIO_HIDL_TEST_COMMON_H
|
||||
206
media/omx/1.0/vts/functional/common/media_hidl_test_common.h
Normal file
206
media/omx/1.0/vts/functional/common/media_hidl_test_common.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2016, 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 MEDIA_HIDL_TEST_COMMON_H
|
||||
#define MEDIA_HIDL_TEST_COMMON_H
|
||||
|
||||
#include <media/stagefright/foundation/ALooper.h>
|
||||
#include <utils/Condition.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/Mutex.h>
|
||||
|
||||
#include <media/openmax/OMX_Index.h>
|
||||
#include <media/openmax/OMX_Core.h>
|
||||
#include <media/openmax/OMX_Component.h>
|
||||
#include <media/openmax/OMX_IndexExt.h>
|
||||
#include <media/openmax/OMX_AudioExt.h>
|
||||
|
||||
/*
|
||||
* TODO: Borrowed from Conversion.h. This is not the ideal way to do it.
|
||||
* Loose these definitions once you include Conversion.h
|
||||
*/
|
||||
inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
|
||||
return static_cast<uint32_t>(l);
|
||||
}
|
||||
|
||||
inline android::hardware::media::omx::V1_0::Status toStatus(
|
||||
android::status_t l) {
|
||||
return static_cast<android::hardware::media::omx::V1_0::Status>(l);
|
||||
}
|
||||
|
||||
inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
|
||||
hidl_vec<uint8_t> t;
|
||||
t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
|
||||
return t;
|
||||
}
|
||||
|
||||
inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
|
||||
return static_cast<uint32_t>(l);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle Callback functions EmptythisBuffer(), FillthisBuffer(),
|
||||
* EventHandler()
|
||||
*/
|
||||
#define DEFAULT_TIMEOUT 40000
|
||||
|
||||
enum bufferOwner {
|
||||
client,
|
||||
component,
|
||||
unknown,
|
||||
};
|
||||
|
||||
struct BufferInfo {
|
||||
uint32_t id;
|
||||
bufferOwner owner;
|
||||
android::hardware::media::omx::V1_0::CodecBuffer omxBuffer;
|
||||
::android::sp<IMemory> mMemory;
|
||||
};
|
||||
|
||||
struct CodecObserver : public IOmxObserver {
|
||||
public:
|
||||
Return<void> onMessages(const hidl_vec<Message>& messages) override {
|
||||
android::Mutex::Autolock autoLock(msgLock);
|
||||
for (hidl_vec<Message>::const_iterator it = messages.begin();
|
||||
it != messages.end(); ++it) {
|
||||
msgQueue.push_back(*it);
|
||||
}
|
||||
msgCondition.signal();
|
||||
return Void();
|
||||
}
|
||||
android::hardware::media::omx::V1_0::Status dequeueMessage(
|
||||
Message* msg, int64_t timeoutUs,
|
||||
android::Vector<BufferInfo>* iBuffers = nullptr,
|
||||
android::Vector<BufferInfo>* oBuffers = nullptr) {
|
||||
int64_t finishBy = android::ALooper::GetNowUs() + timeoutUs;
|
||||
for (;;) {
|
||||
android::Mutex::Autolock autoLock(msgLock);
|
||||
android::List<Message>::iterator it = msgQueue.begin();
|
||||
while (it != msgQueue.end()) {
|
||||
if (it->type ==
|
||||
android::hardware::media::omx::V1_0::Message::Type::EVENT) {
|
||||
*msg = *it;
|
||||
msgQueue.erase(it);
|
||||
return ::android::hardware::media::omx::V1_0::Status::OK;
|
||||
} else if (it->type == android::hardware::media::omx::V1_0::
|
||||
Message::Type::FILL_BUFFER_DONE) {
|
||||
if (oBuffers) {
|
||||
size_t i;
|
||||
for (i = 0; i < oBuffers->size(); ++i) {
|
||||
if ((*oBuffers)[i].id ==
|
||||
it->data.bufferData.buffer) {
|
||||
oBuffers->editItemAt(i).owner = client;
|
||||
msgQueue.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_LE(i, oBuffers->size());
|
||||
}
|
||||
} else if (it->type == android::hardware::media::omx::V1_0::
|
||||
Message::Type::EMPTY_BUFFER_DONE) {
|
||||
if (iBuffers) {
|
||||
size_t i;
|
||||
for (i = 0; i < iBuffers->size(); ++i) {
|
||||
if ((*iBuffers)[i].id ==
|
||||
it->data.bufferData.buffer) {
|
||||
iBuffers->editItemAt(i).owner = client;
|
||||
msgQueue.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_LE(i, iBuffers->size());
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
android::status_t err =
|
||||
(timeoutUs < 0)
|
||||
? msgCondition.wait(msgLock)
|
||||
: msgCondition.waitRelative(
|
||||
msgLock,
|
||||
(finishBy - android::ALooper::GetNowUs()) * 1000);
|
||||
if (err == android::TIMED_OUT) return toStatus(err);
|
||||
}
|
||||
}
|
||||
|
||||
android::List<Message> msgQueue;
|
||||
android::Mutex msgLock;
|
||||
android::Condition msgCondition;
|
||||
};
|
||||
|
||||
/*
|
||||
* Useful Wrapper utilities
|
||||
*/
|
||||
template <class T>
|
||||
void InitOMXParams(T* params) {
|
||||
params->nSize = sizeof(T);
|
||||
params->nVersion.s.nVersionMajor = 1;
|
||||
params->nVersion.s.nVersionMinor = 0;
|
||||
params->nVersion.s.nRevision = 0;
|
||||
params->nVersion.s.nStep = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Return<android::hardware::media::omx::V1_0::Status> getParam(
|
||||
sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
InitOMXParams(params);
|
||||
omxNode->getParameter(
|
||||
toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
|
||||
[&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
|
||||
hidl_vec<uint8_t> const& outParams) {
|
||||
status = _s;
|
||||
std::copy(outParams.data(), outParams.data() + outParams.size(),
|
||||
static_cast<uint8_t*>(static_cast<void*>(params)));
|
||||
});
|
||||
return status;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Return<android::hardware::media::omx::V1_0::Status> setParam(
|
||||
sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
|
||||
InitOMXParams(params);
|
||||
return omxNode->setParameter(toRawIndexType(omxIdx),
|
||||
inHidlBytes(params, sizeof(*params)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Return<android::hardware::media::omx::V1_0::Status> getPortParam(
|
||||
sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
InitOMXParams(params);
|
||||
params->nPortIndex = nPortIndex;
|
||||
omxNode->getParameter(
|
||||
toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
|
||||
[&status, ¶ms](android::hardware::media::omx::V1_0::Status _s,
|
||||
hidl_vec<uint8_t> const& outParams) {
|
||||
status = _s;
|
||||
std::copy(outParams.data(), outParams.data() + outParams.size(),
|
||||
static_cast<uint8_t*>(static_cast<void*>(params)));
|
||||
});
|
||||
return status;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Return<android::hardware::media::omx::V1_0::Status> setPortParam(
|
||||
sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
|
||||
InitOMXParams(params);
|
||||
params->nPortIndex = nPortIndex;
|
||||
return omxNode->setParameter(toRawIndexType(omxIdx),
|
||||
inHidlBytes(params, sizeof(*params)));
|
||||
}
|
||||
|
||||
#endif // MEDIA_HIDL_TEST_COMMON_H
|
||||
45
media/omx/1.0/vts/functional/component/Android.bp
Normal file
45
media/omx/1.0/vts/functional/component/Android.bp
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Copyright (C) 2017 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: "VtsHalMediaOmxV1_0TargetComponentTest",
|
||||
defaults: ["hidl_defaults"],
|
||||
srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"libhwbinder",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"libstagefright_foundation",
|
||||
"android.hidl.allocator@1.0",
|
||||
"android.hidl.memory@1.0",
|
||||
"android.hardware.media.omx@1.0",
|
||||
],
|
||||
static_libs: ["VtsHalHidlTargetTestBase"],
|
||||
cflags: [
|
||||
"-O0",
|
||||
"-g",
|
||||
],
|
||||
include_dirs: [
|
||||
"frameworks/native/include/media/openmax/",
|
||||
"hardware/interfaces/media/omx/1.0/vts/functional/common",
|
||||
],
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
38
media/omx/1.0/vts/functional/master/Android.bp
Normal file
38
media/omx/1.0/vts/functional/master/Android.bp
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright (C) 2017 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: "VtsHalMediaOmxV1_0TargetMasterTest",
|
||||
defaults: ["hidl_defaults"],
|
||||
srcs: ["VtsHalMediaOmxV1_0TargetMasterTest.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"libhwbinder",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"android.hardware.media.omx@1.0",
|
||||
],
|
||||
static_libs: ["VtsHalHidlTargetTestBase"],
|
||||
cflags: [
|
||||
"-O0",
|
||||
"-g",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_TAG "media_omx_hidl_master_test"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android/hardware/media/omx/1.0/IOmx.h>
|
||||
#include <android/hardware/media/omx/1.0/types.h>
|
||||
#include <getopt.h>
|
||||
#include <log/log.h>
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
|
||||
using ::android::hardware::media::omx::V1_0::IOmx;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
// A class for test environment setup
|
||||
class ComponentTestEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
ComponentTestEnvironment() : instance("default") {}
|
||||
|
||||
void setInstance(const char* _instance) { instance = _instance; }
|
||||
|
||||
const hidl_string getInstance() const { return instance; }
|
||||
|
||||
int initFromOptions(int argc, char** argv) {
|
||||
static struct option options[] = {
|
||||
{"instance", required_argument, 0, 'I'}, {0, 0, 0, 0}};
|
||||
|
||||
while (true) {
|
||||
int index = 0;
|
||||
int c = getopt_long(argc, argv, "I:", options, &index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'I':
|
||||
setInstance(optarg);
|
||||
break;
|
||||
case '?':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
fprintf(stderr,
|
||||
"unrecognized option: %s\n\n"
|
||||
"usage: %s <gtest options> <test options>\n\n"
|
||||
"test options are:\n\n"
|
||||
"-I, --instance: HAL instance to test\n",
|
||||
argv[optind ?: 1], argv[0]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
hidl_string instance;
|
||||
};
|
||||
|
||||
static ComponentTestEnvironment* gEnv = nullptr;
|
||||
|
||||
class MasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
|
||||
gEnv->getInstance());
|
||||
ASSERT_NE(omx, nullptr);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {}
|
||||
|
||||
sp<IOmx> omx;
|
||||
};
|
||||
|
||||
// enumerate list of components and roles
|
||||
TEST_F(MasterHidlTest, ListNodes) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
hidl_vec<IOmx::ComponentInfo> nodeList;
|
||||
EXPECT_TRUE(
|
||||
omx->listNodes([&status, &nodeList](
|
||||
android::hardware::media::omx::V1_0::Status _s,
|
||||
hidl_vec<IOmx::ComponentInfo> const& _nl) {
|
||||
status = _s;
|
||||
nodeList = _nl;
|
||||
})
|
||||
.isOk());
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
gEnv = new ComponentTestEnvironment();
|
||||
::testing::AddGlobalTestEnvironment(gEnv);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int status = gEnv->initFromOptions(argc, argv);
|
||||
if (status == 0) {
|
||||
status = RUN_ALL_TESTS();
|
||||
ALOGI("Test result = %d", status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
Reference in New Issue
Block a user