mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Basic audio/video encoder/decoder test.
Bug: 32023356 TODO: cleanup the test code b/37719510 ComponentTest :- 1. allocatePortBuffers cleanup 2. More than one test fixture performs State transitions (Loaded <-> Idle <-> Execute). So, this is moved to a routine and invoked when needed. 3. Dispatch input/output buffers code section is moved to a routine 4. Seperated Test fixtures StateTransitions_Flush 5. Added Doc string 6. Test component port population AudioDecTest :- 1. Backport Cleanup changes from ComponentTest to AudioDecTest 2. Added elementary streams for the following codecs mp3, amr-nb & Updated paths to elementary streams in audio decoder test Test: Tested ComponentTest and AudioDecTest for mp3 Change-Id: I90decde4dfab55c3d456dfd88b474dd5abe8eebc List Available components (roles) in android media framework Change-Id: I210665843e997e60b167f2d680c87b1cc4f90c58 add README.md Change-Id: I3a2a057d10b18f4f374928a996b8b4ea4b084770 add basic video decoder tests for a given component test for successful decoding of an input clip Test: tested for softavc decoder Change-Id: I2f4c034c34a456e1ed0c2d32ef381ca48aeda8ff add basic audio encoder tests for a given component, test for successful encoding of an input clip Test: tested on softaac, softamrnb, softamrwb & softflac components Change-Id: I05f5646ffed37143a21ea72f0fd782c2bb5c4d82 add basic video encoder tests For a given component test successful encoding of nframes of a raw video clip Test: tested on softavc encoder. Change-Id: Ia1d754061e8362f6c08a2be3d6384c95589a36de
This commit is contained in:
committed by
Zhuoyao Zhang
parent
1fd47b29b3
commit
f9c4003fcd
1
media/Android.bp
Executable file → Normal file
1
media/Android.bp
Executable file → Normal file
@@ -5,4 +5,5 @@ subdirs = [
|
||||
"omx/1.0/vts/functional/audio",
|
||||
"omx/1.0/vts/functional/component",
|
||||
"omx/1.0/vts/functional/master",
|
||||
"omx/1.0/vts/functional/video",
|
||||
]
|
||||
|
||||
49
media/omx/1.0/vts/functional/README.md
Normal file
49
media/omx/1.0/vts/functional/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
## Codec OMX Tests
|
||||
---
|
||||
|
||||
The current directory contains the following folders: audio, common, component, master
|
||||
and video.
|
||||
|
||||
Besides common, all other folders contain basic OMX unit tests for testing audio and video decoder-encoder
|
||||
components. common constitutes files that are used across test applications.
|
||||
|
||||
## master
|
||||
Enumerates all the omx components (and their roles) available in android media framework.
|
||||
|
||||
Usage:
|
||||
|
||||
VtsHalMediaOmxV1\_0TargetMasterTest -I default
|
||||
|
||||
## component
|
||||
This folder includes test fixtures that tests aspects common to all OMX compatible components. For instance, port enabling/disabling, enumerating port formats, state transitions, flush etc. stay common to all components irrespective of the service they offer. In a way this tests the OMX Core. Every standard OMX compatible component is expected to pass these tests.
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
VtsHalMediaOmxV1\_0TargetComponentTest -I default -C <component name> -R <component role>
|
||||
|
||||
## audio
|
||||
This folder includes test fixtures associated with audio encoder/decoder components such as encoding/decoding, EOS test, timestamp test etc. These tests are aimed towards testing the component specific aspects.
|
||||
|
||||
Usage:
|
||||
|
||||
VtsHalMediaOmxV1\_0TargetAudioDecTest -I default -C <component name> -R audio_decoder.<class>
|
||||
|
||||
VtsHalMediaOmxV1\_0TargetAudioEncTest -I default -C <component name> -R audio_encoder.<class>
|
||||
|
||||
## video
|
||||
This folder includes test fixtures associated with video encoder/decoder components like encoding/decoding, EOS test, timestamp test etc. These tests are aimed towards testing the component specific aspects.
|
||||
|
||||
Usage:
|
||||
|
||||
VtsHalMediaOmxV1\_0TargetVideoDecTest -I default -C <component name> -R video_decoder.<class>
|
||||
|
||||
VtsHalMediaOmxV1\_0TargetVideoEncTest -I default -C <component name> -R video_encoder.<class>
|
||||
|
||||
## notes
|
||||
Every component shall be tested by two applications,
|
||||
|
||||
* ComponentTest.
|
||||
|
||||
* AudioDecTest/AudioEncTest/VideoDecTest/VideoEncTest depending on the component class.
|
||||
|
||||
@@ -155,7 +155,7 @@ class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
const StringToName kStringToName[] = {
|
||||
{"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
|
||||
{"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
|
||||
{"pcm", pcm}, {"flac", flac},
|
||||
{"pcm", pcm},
|
||||
};
|
||||
const size_t kNumStringToName =
|
||||
sizeof(kStringToName) / sizeof(kStringToName[0]);
|
||||
@@ -184,7 +184,6 @@ class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
{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]);
|
||||
@@ -213,7 +212,6 @@ class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
vorbis,
|
||||
opus,
|
||||
pcm,
|
||||
flac,
|
||||
unknown_comp,
|
||||
};
|
||||
|
||||
@@ -222,14 +220,21 @@ class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
sp<IOmxNode> omxNode;
|
||||
standardComp compName;
|
||||
OMX_AUDIO_CODINGTYPE eEncoding;
|
||||
|
||||
protected:
|
||||
static void description(const std::string& description) {
|
||||
RecordProperty("description", description);
|
||||
}
|
||||
};
|
||||
|
||||
// Set Default port param.
|
||||
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);
|
||||
@@ -246,18 +251,25 @@ void setDefaultPortParam(
|
||||
setupPCMPort(omxNode, portIndex, nChannels, eNumData, nBitPerSample,
|
||||
nSampleRate);
|
||||
break;
|
||||
case OMX_AUDIO_CodingAAC:
|
||||
setupAACPort(omxNode, portIndex, OMX_AUDIO_AACObjectNull,
|
||||
OMX_AUDIO_AACStreamFormatMP4ADTS, nChannels, 0,
|
||||
nSampleRate);
|
||||
default:
|
||||
ASSERT_TRUE(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// In decoder components, often the input port parameters get updated upon
|
||||
// parsing the header of elementary stream. Client needs to collect this
|
||||
// information to reconfigure other ports that share data with this input
|
||||
// port.
|
||||
void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
|
||||
OMX_AUDIO_CODINGTYPE eEncoding, int32_t* nChannels,
|
||||
int32_t* nSampleRate) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
*nChannels = 0;
|
||||
*nSampleRate = 0;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
|
||||
switch ((int)eEncoding) {
|
||||
case OMX_AUDIO_CodingPCM: {
|
||||
@@ -280,16 +292,6 @@ void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
|
||||
*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,
|
||||
@@ -337,6 +339,7 @@ void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
|
||||
}
|
||||
}
|
||||
|
||||
// LookUpTable of clips and metadata for component testing
|
||||
void GetURLForComponent(AudioDecHidlTest::standardComp comp, const char** mURL,
|
||||
const char** info) {
|
||||
struct CompToURL {
|
||||
@@ -346,20 +349,26 @@ void GetURLForComponent(AudioDecHidlTest::standardComp comp, const char** mURL,
|
||||
};
|
||||
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"},
|
||||
"/sdcard/media/bbb_mp3_stereo_192kbps_48000hz.mp3",
|
||||
"/sdcard/media/bbb_mp3_stereo_192kbps_48000hz.info"},
|
||||
{AudioDecHidlTest::standardComp::aac,
|
||||
"/sdcard/raw/H264_500_AAC_128.audio.aac",
|
||||
"/sdcard/raw/H264_500_AAC_128.audio.info"},
|
||||
"/sdcard/media/bbb_aac_stereo_128kbps_48000hz.aac",
|
||||
"/sdcard/media/bbb_aac_stereo_128kbps_48000hz.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, "", ""},
|
||||
"/sdcard/media/sine_amrnb_1ch_12kbps_8000hz.amrnb",
|
||||
"/sdcard/media/sine_amrnb_1ch_12kbps_8000hz.info"},
|
||||
{AudioDecHidlTest::standardComp::amrwb,
|
||||
"/sdcard/media/sine_amrwb_1ch_24kbps_16000hz.amrwb",
|
||||
"/sdcard/media/sine_amrwb_1ch_24kbps_16000hz.info"},
|
||||
{AudioDecHidlTest::standardComp::vorbis,
|
||||
"/sdcard/media/bbb_vorbis_stereo_128kbps_48000hz.vorbis",
|
||||
"/sdcard/media/bbb_vorbis_stereo_128kbps_48000hz.info"},
|
||||
{AudioDecHidlTest::standardComp::opus,
|
||||
"/sdcard/media/bbb_opus_stereo_128kbps_48000hz.opus",
|
||||
"/sdcard/media/bbb_opus_stereo_128kbps_48000hz.info"},
|
||||
};
|
||||
|
||||
*mURL = *info = nullptr;
|
||||
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
|
||||
if (kCompToURL[i].comp == comp) {
|
||||
*mURL = kCompToURL[i].mURL;
|
||||
@@ -369,42 +378,7 @@ void GetURLForComponent(AudioDecHidlTest::standardComp comp, const char** mURL,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Decode N Frames
|
||||
void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
@@ -420,115 +394,140 @@ void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
}
|
||||
// dispatch input buffers
|
||||
int bytesCount = 0;
|
||||
for (size_t i = 0; i < iBuffer->size(); i++) {
|
||||
uint32_t flags = 0;
|
||||
uint64_t timestamp = 0;
|
||||
for (size_t i = 0; i < iBuffer->size() && nFrames != 0; i++) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
|
||||
if (!(eleInfo >> bytesCount)) break;
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[i].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
ASSERT_EQ(eleStream.gcount(), bytesCount);
|
||||
dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, 0);
|
||||
eleInfo >> flags;
|
||||
eleInfo >> timestamp;
|
||||
dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, timestamp);
|
||||
nFrames--;
|
||||
}
|
||||
|
||||
while (nFrames != 0) {
|
||||
while (1) {
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
|
||||
// Port Reconfiguration
|
||||
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);
|
||||
msg.type == Message::Type::EVENT) {
|
||||
if (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 = 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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
// set Port Params
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
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);
|
||||
// dispatch output buffers
|
||||
for (size_t i = 0; i < oBuffer->size(); i++) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, i);
|
||||
}
|
||||
} else {
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
} else {
|
||||
ASSERT_TRUE(false);
|
||||
EXPECT_TRUE(false);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nFrames == 0) break;
|
||||
|
||||
// Dispatch input buffer
|
||||
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;
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[index].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
ASSERT_EQ(eleStream.gcount(), bytesCount);
|
||||
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0, 0);
|
||||
eleInfo >> flags;
|
||||
eleInfo >> timestamp;
|
||||
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0,
|
||||
timestamp);
|
||||
nFrames--;
|
||||
}
|
||||
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, index);
|
||||
}
|
||||
nFrames--;
|
||||
}
|
||||
}
|
||||
|
||||
// Set Component Role
|
||||
TEST_F(AudioDecHidlTest, SetRole) {
|
||||
description("Test Set Component Role");
|
||||
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) {
|
||||
description("Test Component on Mandatory Port Parameters (Port Format)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
@@ -546,8 +545,8 @@ TEST_F(AudioDecHidlTest, EnumeratePortFormat) {
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// Decode Test
|
||||
TEST_F(AudioDecHidlTest, DecodeTest) {
|
||||
description("Tests Port Reconfiguration and Decode");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
@@ -570,105 +569,30 @@ TEST_F(AudioDecHidlTest, DecodeTest) {
|
||||
eleInfo.open(info);
|
||||
ASSERT_EQ(eleInfo.is_open(), true);
|
||||
|
||||
if (eEncoding == OMX_AUDIO_CodingPCM)
|
||||
setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
|
||||
int32_t nChannels;
|
||||
int32_t nSampleRate;
|
||||
int32_t nChannels, nSampleRate;
|
||||
// Configure input port
|
||||
setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
|
||||
getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
|
||||
&nSampleRate);
|
||||
// Configure output port
|
||||
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);
|
||||
|
||||
// set state to idle
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
// 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);
|
||||
kPortIndexInput, kPortIndexOutput, 1024, eleStream, eleInfo);
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to executing
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
eleInfo.close();
|
||||
eleStream.close();
|
||||
|
||||
@@ -153,9 +153,7 @@ class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
standardComp CompName;
|
||||
};
|
||||
const StringToName kStringToName[] = {
|
||||
{"mp3", mp3}, {"amrnb", amrnb}, {"amrwb", amrwb},
|
||||
{"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
|
||||
{"pcm", pcm}, {"flac", flac},
|
||||
{"amrnb", amrnb}, {"amrwb", amrwb}, {"aac", aac}, {"flac", flac},
|
||||
};
|
||||
const size_t kNumStringToName =
|
||||
sizeof(kStringToName) / sizeof(kStringToName[0]);
|
||||
@@ -177,13 +175,9 @@ class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
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 =
|
||||
@@ -206,13 +200,9 @@ class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
}
|
||||
|
||||
enum standardComp {
|
||||
mp3,
|
||||
amrnb,
|
||||
amrwb,
|
||||
aac,
|
||||
vorbis,
|
||||
opus,
|
||||
pcm,
|
||||
flac,
|
||||
unknown_comp,
|
||||
};
|
||||
@@ -222,17 +212,146 @@ class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
sp<IOmxNode> omxNode;
|
||||
standardComp compName;
|
||||
OMX_AUDIO_CODINGTYPE eEncoding;
|
||||
|
||||
protected:
|
||||
static void description(const std::string& description) {
|
||||
RecordProperty("description", description);
|
||||
}
|
||||
};
|
||||
|
||||
// Set Component Role
|
||||
// Set Default port param.
|
||||
void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_AUDIO_CODINGTYPE eEncoding,
|
||||
AudioEncHidlTest::standardComp comp, int32_t nChannels,
|
||||
int32_t nSampleRate, int32_t nBitRate) {
|
||||
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_CodingFLAC:
|
||||
setupFLACPort(omxNode, portIndex, nChannels, nSampleRate,
|
||||
5 /* nCompressionLevel */);
|
||||
break;
|
||||
case OMX_AUDIO_CodingAMR:
|
||||
setupAMRPort(omxNode, portIndex, nBitRate,
|
||||
(comp == AudioEncHidlTest::standardComp::amrwb));
|
||||
break;
|
||||
case OMX_AUDIO_CodingAAC:
|
||||
setupAACPort(omxNode, portIndex, OMX_AUDIO_AACObjectNull,
|
||||
OMX_AUDIO_AACStreamFormatMP4FF, nChannels, nBitRate,
|
||||
nSampleRate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// LookUpTable of clips and metadata for component testing
|
||||
void GetURLForComponent(AudioEncHidlTest::standardComp comp,
|
||||
const char** mURL) {
|
||||
struct CompToURL {
|
||||
AudioEncHidlTest::standardComp comp;
|
||||
const char* mURL;
|
||||
};
|
||||
static const CompToURL kCompToURL[] = {
|
||||
{AudioEncHidlTest::standardComp::aac,
|
||||
"/sdcard/media/bbb_raw_2ch_48khz_s16le.raw"},
|
||||
{AudioEncHidlTest::standardComp::amrnb,
|
||||
"/sdcard/media/bbb_raw_1ch_8khz_s16le.raw"},
|
||||
{AudioEncHidlTest::standardComp::amrwb,
|
||||
"/sdcard/media/bbb_raw_1ch_16khz_s16le.raw"},
|
||||
{AudioEncHidlTest::standardComp::flac,
|
||||
"/sdcard/media/bbb_raw_2ch_48khz_s16le.raw"},
|
||||
};
|
||||
|
||||
*mURL = nullptr;
|
||||
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
|
||||
if (kCompToURL[i].comp == comp) {
|
||||
*mURL = kCompToURL[i].mURL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Encode N Frames
|
||||
void encodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer, uint32_t nFrames,
|
||||
int32_t samplesPerFrame, int32_t nChannels,
|
||||
int32_t nSampleRate, std::ifstream& eleStream) {
|
||||
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 = samplesPerFrame * nChannels * 2;
|
||||
int32_t timestampIncr =
|
||||
(int)(((float)samplesPerFrame / nSampleRate) * 1000000);
|
||||
uint64_t timestamp = 0;
|
||||
for (size_t i = 0; i < iBuffer->size() && nFrames != 0; i++) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[i].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
if (eleStream.gcount() != bytesCount) break;
|
||||
dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, timestamp);
|
||||
timestamp += timestampIncr;
|
||||
nFrames--;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
|
||||
if (status == android::hardware::media::omx::V1_0::Status::OK)
|
||||
ASSERT_TRUE(false);
|
||||
|
||||
if (nFrames == 0) break;
|
||||
|
||||
// Dispatch input buffer
|
||||
size_t index = 0;
|
||||
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[index].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
if (eleStream.gcount() != bytesCount) break;
|
||||
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0,
|
||||
timestamp);
|
||||
timestamp += timestampIncr;
|
||||
nFrames--;
|
||||
}
|
||||
// Dispatch output buffer
|
||||
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AudioEncHidlTest, SetRole) {
|
||||
description("Test Set Component Role");
|
||||
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) {
|
||||
description("Test Component on Mandatory Port Parameters (Port Format)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
@@ -250,6 +369,86 @@ TEST_F(AudioEncHidlTest, EnumeratePortFormat) {
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
TEST_F(AudioEncHidlTest, EncodeTest) {
|
||||
description("Tests Encode");
|
||||
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;
|
||||
GetURLForComponent(compName, &mURL);
|
||||
EXPECT_NE(mURL, nullptr);
|
||||
|
||||
std::ifstream eleStream;
|
||||
eleStream.open(mURL, std::ifstream::binary);
|
||||
ASSERT_EQ(eleStream.is_open(), true);
|
||||
|
||||
// Configure input port
|
||||
int32_t nChannels = 2;
|
||||
int32_t nSampleRate = 44100;
|
||||
int32_t samplesPerFrame = 1024;
|
||||
int32_t nBitRate = 128000;
|
||||
switch (compName) {
|
||||
case amrnb:
|
||||
nChannels = 1;
|
||||
nSampleRate = 8000;
|
||||
samplesPerFrame = 160;
|
||||
nBitRate = 7400;
|
||||
break;
|
||||
case amrwb:
|
||||
nChannels = 1;
|
||||
nSampleRate = 16000;
|
||||
samplesPerFrame = 160;
|
||||
nBitRate = 15850;
|
||||
break;
|
||||
case aac:
|
||||
nChannels = 2;
|
||||
nSampleRate = 48000;
|
||||
samplesPerFrame = 1024;
|
||||
nBitRate = 128000;
|
||||
break;
|
||||
case flac:
|
||||
nChannels = 2;
|
||||
nSampleRate = 48000;
|
||||
samplesPerFrame = 1152;
|
||||
nBitRate = 128000;
|
||||
break;
|
||||
default:
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
setupPCMPort(omxNode, kPortIndexInput, nChannels, OMX_NumericalDataSigned,
|
||||
16, nSampleRate);
|
||||
// Configure output port
|
||||
setDefaultPortParam(omxNode, kPortIndexOutput, eEncoding, compName,
|
||||
nChannels, nSampleRate, nBitRate);
|
||||
|
||||
android::Vector<BufferInfo> iBuffer, oBuffer;
|
||||
|
||||
// set state to idle
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
|
||||
encodeNFrames(omxNode, observer, &iBuffer, &oBuffer, 1024, samplesPerFrame,
|
||||
nChannels, nSampleRate, eleStream);
|
||||
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to executing
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
eleStream.close();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
gEnv = new ComponentTestEnvironment();
|
||||
::testing::AddGlobalTestEnvironment(gEnv);
|
||||
|
||||
@@ -45,6 +45,7 @@ using ::android::sp;
|
||||
#include <media_hidl_test_common.h>
|
||||
#include <memory>
|
||||
|
||||
// allocate buffers needed on a component port
|
||||
void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
OMX_U32 portIndex) {
|
||||
@@ -54,18 +55,19 @@ void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
buffArray->clear();
|
||||
|
||||
sp<IAllocator> allocator = IAllocator::getService("ashmem");
|
||||
EXPECT_NE(allocator, nullptr);
|
||||
EXPECT_NE(allocator.get(), 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;
|
||||
bool success = false;
|
||||
allocator->allocate(
|
||||
portDef.nBufferSize,
|
||||
[&success, &buffer](bool _s,
|
||||
@@ -74,6 +76,7 @@ void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
buffer.omxBuffer.sharedMemory = mem;
|
||||
});
|
||||
ASSERT_EQ(success, true);
|
||||
ASSERT_EQ(buffer.omxBuffer.sharedMemory.size(), portDef.nBufferSize);
|
||||
buffer.mMemory = mapMemory(buffer.omxBuffer.sharedMemory);
|
||||
ASSERT_NE(buffer.mMemory, nullptr);
|
||||
omxNode->useBuffer(
|
||||
@@ -88,6 +91,143 @@ void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
}
|
||||
}
|
||||
|
||||
// State Transition : Loaded -> Idle
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateLoadedtoIdle(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;
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// Dont switch states until the ports are populated
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on input port
|
||||
allocatePortBuffers(omxNode, iBuffer, kPortIndexInput);
|
||||
|
||||
// Dont switch states until the ports are populated
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on output port
|
||||
allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
|
||||
|
||||
// As the ports are populated, check if the state transition is complete
|
||||
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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Idle -> Loaded
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateIdletoLoaded(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;
|
||||
|
||||
// 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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Idle -> Execute
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateIdletoExecute(sp<IOmxNode> omxNode,
|
||||
sp<CodecObserver> observer) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// set state to execute
|
||||
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);
|
||||
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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Execute -> Idle
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// 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);
|
||||
|
||||
// test if client got all its buffers back
|
||||
for (size_t i = 0; i < oBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*oBuffer)[i].owner, client);
|
||||
}
|
||||
for (size_t i = 0; i < iBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*iBuffer)[i].owner, client);
|
||||
}
|
||||
}
|
||||
|
||||
// get empty buffer index
|
||||
size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray) {
|
||||
for (size_t i = 0; i < buffArray->size(); i++) {
|
||||
if ((*buffArray)[i].owner == client) return i;
|
||||
@@ -95,6 +235,7 @@ size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray) {
|
||||
return buffArray->size();
|
||||
}
|
||||
|
||||
// dispatch buffer to input port
|
||||
void dispatchInputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex, int bytesCount, uint32_t flags,
|
||||
@@ -116,6 +257,7 @@ void dispatchInputBuffer(sp<IOmxNode> omxNode,
|
||||
buffArray->editItemAt(bufferIndex).owner = component;
|
||||
}
|
||||
|
||||
// dispatch buffer to output port
|
||||
void dispatchOutputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex) {
|
||||
@@ -135,6 +277,45 @@ void dispatchOutputBuffer(sp<IOmxNode> omxNode,
|
||||
buffArray->editItemAt(bufferIndex).owner = component;
|
||||
}
|
||||
|
||||
// Flush input and output ports
|
||||
void flushPorts(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 input port
|
||||
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);
|
||||
}
|
||||
|
||||
// Flush output port
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding) {
|
||||
OMX_U32 index = 0;
|
||||
@@ -190,7 +371,7 @@ void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nChannels = nChannels;
|
||||
param.eNumData = eNumData;
|
||||
param.eEndian = OMX_EndianBig;
|
||||
param.eEndian = OMX_EndianLittle;
|
||||
param.bInterleaved = OMX_TRUE;
|
||||
param.nBitPerSample = nBitPerSample;
|
||||
param.nSamplingRate = nSamplingRate;
|
||||
@@ -207,13 +388,12 @@ void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
EXPECT_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;
|
||||
int32_t nBitRate, int32_t nSampleRate) {
|
||||
OMX_AUDIO_PARAM_MP3TYPE param;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, ¶m);
|
||||
@@ -226,13 +406,11 @@ void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
: OMX_AUDIO_ChannelModeStereo;
|
||||
param.eFormat = eFormat;
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
EXPECT_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;
|
||||
int32_t nSampleRate, int32_t nCompressionLevel) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_FLACTYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, ¶m);
|
||||
@@ -241,12 +419,11 @@ void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t 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);
|
||||
EXPECT_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;
|
||||
int32_t nBitRate, int32_t nSampleRate) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
|
||||
status =
|
||||
@@ -259,27 +436,47 @@ void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
status =
|
||||
setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
|
||||
portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
|
||||
if (isAMRWB) {
|
||||
if (bps <= 6600) return OMX_AUDIO_AMRBandModeWB0;
|
||||
if (bps <= 8850) return OMX_AUDIO_AMRBandModeWB1;
|
||||
if (bps <= 12650) return OMX_AUDIO_AMRBandModeWB2;
|
||||
if (bps <= 14250) return OMX_AUDIO_AMRBandModeWB3;
|
||||
if (bps <= 15850) return OMX_AUDIO_AMRBandModeWB4;
|
||||
if (bps <= 18250) return OMX_AUDIO_AMRBandModeWB5;
|
||||
if (bps <= 19850) return OMX_AUDIO_AMRBandModeWB6;
|
||||
if (bps <= 23050) return OMX_AUDIO_AMRBandModeWB7;
|
||||
return OMX_AUDIO_AMRBandModeWB8;
|
||||
} else {
|
||||
if (bps <= 4750) return OMX_AUDIO_AMRBandModeNB0;
|
||||
if (bps <= 5150) return OMX_AUDIO_AMRBandModeNB1;
|
||||
if (bps <= 5900) return OMX_AUDIO_AMRBandModeNB2;
|
||||
if (bps <= 6700) return OMX_AUDIO_AMRBandModeNB3;
|
||||
if (bps <= 7400) return OMX_AUDIO_AMRBandModeNB4;
|
||||
if (bps <= 7950) return OMX_AUDIO_AMRBandModeNB5;
|
||||
if (bps <= 10200) return OMX_AUDIO_AMRBandModeNB6;
|
||||
return OMX_AUDIO_AMRBandModeNB7;
|
||||
}
|
||||
}
|
||||
|
||||
void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
|
||||
OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder) {
|
||||
if (isEncoder == false) return;
|
||||
bool isAMRWB) {
|
||||
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;
|
||||
param.eAMRBandMode = pickModeFromBitRate(isAMRWB, nBitRate);
|
||||
status = setPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
EXPECT_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;
|
||||
int32_t nBitRate, int32_t nSampleRate, int32_t nQuality) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_VORBISTYPE param;
|
||||
status =
|
||||
@@ -291,15 +488,13 @@ void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
param.nQuality = nQuality;
|
||||
status =
|
||||
setPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, ¶m);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
EXPECT_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;
|
||||
int32_t nChannels, int32_t nBitRate, int32_t nSampleRate) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_AUDIO_PARAM_AACPROFILETYPE param;
|
||||
status = getPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, ¶m);
|
||||
@@ -312,5 +507,5 @@ void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
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);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,22 @@ void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
OMX_U32 portIndex);
|
||||
|
||||
void changeStateLoadedtoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput);
|
||||
|
||||
void changeStateIdletoLoaded(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput);
|
||||
|
||||
void changeStateIdletoExecute(sp<IOmxNode> omxNode, sp<CodecObserver> observer);
|
||||
|
||||
void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer);
|
||||
|
||||
size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);
|
||||
|
||||
void dispatchInputBuffer(sp<IOmxNode> omxNode,
|
||||
@@ -41,6 +57,11 @@ void dispatchOutputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex);
|
||||
|
||||
void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
|
||||
OMX_U32 kPortIndexOutput);
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding);
|
||||
|
||||
@@ -53,26 +74,23 @@ void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
|
||||
void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
|
||||
int32_t nBitRate, int32_t nSampleRate);
|
||||
|
||||
void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nSampleRate, int32_t nCompressionLevel,
|
||||
bool isEncoder);
|
||||
int32_t nSampleRate, int32_t nCompressionLevel);
|
||||
|
||||
void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
|
||||
int32_t nBitRate, int32_t nSampleRate);
|
||||
|
||||
void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
|
||||
OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder);
|
||||
bool isAMRWB);
|
||||
|
||||
void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
|
||||
int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
|
||||
bool isEncoder);
|
||||
int32_t nBitRate, int32_t nSampleRate, int32_t nQuality);
|
||||
|
||||
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);
|
||||
int32_t nChannels, int32_t nBitRate, int32_t nSampleRate);
|
||||
|
||||
#endif // MEDIA_AUDIO_HIDL_TEST_COMMON_H
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <media/openmax/OMX_Component.h>
|
||||
#include <media/openmax/OMX_IndexExt.h>
|
||||
#include <media/openmax/OMX_AudioExt.h>
|
||||
#include <media/openmax/OMX_VideoExt.h>
|
||||
|
||||
/*
|
||||
* TODO: Borrowed from Conversion.h. This is not the ideal way to do it.
|
||||
|
||||
@@ -172,10 +172,6 @@ class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
}
|
||||
}
|
||||
ASSERT_NE(compClass, unknown_class) << "Invalid Component Class";
|
||||
|
||||
allocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(
|
||||
"ashmem");
|
||||
ASSERT_NE(allocator, nullptr);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
@@ -196,13 +192,19 @@ class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
sp<IOmx> omx;
|
||||
sp<CodecObserver> observer;
|
||||
sp<IOmxNode> omxNode;
|
||||
sp<IAllocator> allocator;
|
||||
standardCompClass compClass;
|
||||
|
||||
protected:
|
||||
static void description(const std::string& description) {
|
||||
RecordProperty("description", description);
|
||||
}
|
||||
};
|
||||
|
||||
// Random Index used for monkey testing while get/set parameters
|
||||
#define RANDOM_INDEX 1729
|
||||
|
||||
void allocatePortBuffers(sp<IOmxNode> omxNode, sp<IAllocator> allocator,
|
||||
// allocate buffers needed on a component port
|
||||
void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
OMX_U32 portIndex) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
@@ -210,16 +212,20 @@ void allocatePortBuffers(sp<IOmxNode> omxNode, sp<IAllocator> allocator,
|
||||
|
||||
buffArray->clear();
|
||||
|
||||
sp<IAllocator> allocator = IAllocator::getService("ashmem");
|
||||
EXPECT_NE(allocator.get(), 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;
|
||||
bool success = false;
|
||||
allocator->allocate(
|
||||
portDef.nBufferSize,
|
||||
[&success, &buffer](bool _s,
|
||||
@@ -228,6 +234,7 @@ void allocatePortBuffers(sp<IOmxNode> omxNode, sp<IAllocator> allocator,
|
||||
buffer.omxBuffer.sharedMemory = mem;
|
||||
});
|
||||
ASSERT_EQ(success, true);
|
||||
ASSERT_EQ(buffer.omxBuffer.sharedMemory.size(), portDef.nBufferSize);
|
||||
|
||||
omxNode->useBuffer(
|
||||
portIndex, buffer.omxBuffer,
|
||||
@@ -241,6 +248,223 @@ void allocatePortBuffers(sp<IOmxNode> omxNode, sp<IAllocator> allocator,
|
||||
}
|
||||
}
|
||||
|
||||
// State Transition : Loaded -> Idle
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateLoadedtoIdle(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;
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// Dont switch states until the ports are populated
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on input port
|
||||
allocatePortBuffers(omxNode, iBuffer, kPortIndexInput);
|
||||
|
||||
// Dont switch states until the ports are populated
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on output port
|
||||
allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
|
||||
|
||||
// As the ports are populated, check if the state transition is complete
|
||||
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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Idle -> Loaded
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateIdletoLoaded(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;
|
||||
|
||||
// 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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Idle -> Execute
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateIdletoExecute(sp<IOmxNode> omxNode,
|
||||
sp<CodecObserver> observer) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// set state to execute
|
||||
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);
|
||||
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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Execute -> Idle
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// 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);
|
||||
|
||||
// test if client got all its buffers back
|
||||
for (size_t i = 0; i < oBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*oBuffer)[i].owner, client);
|
||||
}
|
||||
for (size_t i = 0; i < iBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*iBuffer)[i].owner, client);
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch buffer to output port
|
||||
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;
|
||||
}
|
||||
|
||||
// dispatch buffer to input port
|
||||
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;
|
||||
}
|
||||
|
||||
// Flush input and output ports
|
||||
void flushPorts(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 input port
|
||||
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);
|
||||
}
|
||||
|
||||
// Flush output port
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_CODINGTYPE compressionFormat, OMX_COLOR_FORMATTYPE colorFormat,
|
||||
@@ -262,6 +486,8 @@ Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
|
||||
eCompressionFormat.push_back(portFormat.eCompressionFormat);
|
||||
index++;
|
||||
if (index == 512) {
|
||||
// enumerated way too many formats, highly unusual for this to
|
||||
// happen.
|
||||
EXPECT_LE(index, 512U)
|
||||
<< "Expecting OMX_ErrorNoMore but not received";
|
||||
break;
|
||||
@@ -317,6 +543,8 @@ Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
|
||||
eEncoding.push_back(portFormat.eEncoding);
|
||||
index++;
|
||||
if (index == 512) {
|
||||
// enumerated way too many formats, highly unusual for this to
|
||||
// happen.
|
||||
EXPECT_LE(index, 512U)
|
||||
<< "Expecting OMX_ErrorNoMore but not received";
|
||||
break;
|
||||
@@ -348,22 +576,23 @@ Return<android::hardware::media::omx::V1_0::Status> setRole(
|
||||
return setParam(omxNode, OMX_IndexParamStandardComponentRole, ¶ms);
|
||||
}
|
||||
|
||||
// Set Component Role
|
||||
TEST_F(ComponentHidlTest, SetRole) {
|
||||
description("Test Set Component Role");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// Get Number of Ports and their Indices for all Domains
|
||||
// (Audio/Video/Image/Other)
|
||||
TEST_F(ComponentHidlTest, GetPortIndices) {
|
||||
description("Test Component on Mandatory Port Parameters (Port ID's)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_PORT_PARAM_TYPE params;
|
||||
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// Get Number of Ports and their Indices for all Domains
|
||||
// (Audio/Video/Image/Other)
|
||||
// All standard OMX components shall support following OMX Index types
|
||||
status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
@@ -375,8 +604,8 @@ TEST_F(ComponentHidlTest, GetPortIndices) {
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
// Enumerate Port Format
|
||||
TEST_F(ComponentHidlTest, EnumeratePortFormat) {
|
||||
description("Test Component on Mandatory Port Parameters (Port Format)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
|
||||
@@ -397,6 +626,7 @@ TEST_F(ComponentHidlTest, EnumeratePortFormat) {
|
||||
OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420Planar;
|
||||
OMX_U32 frameRate = 24 << 16;
|
||||
|
||||
// Enumerate Port Format
|
||||
if (compClass == audio_encoder) {
|
||||
status =
|
||||
setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
|
||||
@@ -432,8 +662,9 @@ TEST_F(ComponentHidlTest, EnumeratePortFormat) {
|
||||
}
|
||||
}
|
||||
|
||||
// r/w default i/o port parameters
|
||||
TEST_F(ComponentHidlTest, SetDefaultPortParams) {
|
||||
description(
|
||||
"Test Component on Mandatory Port Parameters (Port Definition)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
|
||||
@@ -451,15 +682,15 @@ TEST_F(ComponentHidlTest, SetDefaultPortParams) {
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
|
||||
// r/w default i/o port parameters
|
||||
OMX_PARAM_PORTDEFINITIONTYPE iPortDef;
|
||||
status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
|
||||
kPortIndexInput, &iPortDef);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
if (status == android::hardware::media::omx::V1_0::Status::OK) {
|
||||
EXPECT_EQ(iPortDef.eDir, OMX_DirInput);
|
||||
EXPECT_EQ(iPortDef.bEnabled, OMX_TRUE);
|
||||
EXPECT_EQ(iPortDef.bPopulated, 0);
|
||||
EXPECT_EQ(iPortDef.bPopulated, OMX_FALSE);
|
||||
EXPECT_GE(iPortDef.nBufferCountMin, 1U);
|
||||
EXPECT_GE(iPortDef.nBufferCountActual, iPortDef.nBufferCountMin);
|
||||
if (compClass == audio_encoder || compClass == audio_decoder) {
|
||||
@@ -495,12 +726,8 @@ TEST_F(ComponentHidlTest, SetDefaultPortParams) {
|
||||
if ((iPortDef.eDir != OMX_DirInput) ||
|
||||
(iPortDef.nBufferCountMin != dummy.nBufferCountMin) ||
|
||||
(iPortDef.nBufferSize != dummy.nBufferSize)) {
|
||||
ALOGI(
|
||||
"Warning, Component does not seem to preserve Read-Only "
|
||||
"fields");
|
||||
printf(
|
||||
"Warning, Component does not seem to preserve Read-Only fields "
|
||||
"\n");
|
||||
std::cerr << "[ ] Warning ! Component input port does not "
|
||||
"preserve Read-Only fields \n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,7 +738,7 @@ TEST_F(ComponentHidlTest, SetDefaultPortParams) {
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
EXPECT_EQ(oPortDef.eDir, OMX_DirOutput);
|
||||
EXPECT_EQ(oPortDef.bEnabled, OMX_TRUE);
|
||||
EXPECT_EQ(oPortDef.bPopulated, 0);
|
||||
EXPECT_EQ(oPortDef.bPopulated, OMX_FALSE);
|
||||
EXPECT_GE(oPortDef.nBufferCountMin, 1U);
|
||||
EXPECT_GE(oPortDef.nBufferCountActual, oPortDef.nBufferCountMin);
|
||||
if (compClass == audio_encoder || compClass == audio_decoder) {
|
||||
@@ -547,18 +774,82 @@ TEST_F(ComponentHidlTest, SetDefaultPortParams) {
|
||||
if ((oPortDef.eDir != OMX_DirOutput) ||
|
||||
(oPortDef.nBufferCountMin != dummy.nBufferCountMin) ||
|
||||
(oPortDef.nBufferSize != dummy.nBufferSize)) {
|
||||
ALOGI(
|
||||
"Warning, Component does not seem to preserve Read-Only "
|
||||
"fields");
|
||||
printf(
|
||||
"Warning, Component does not seem to preserve Read-Only fields "
|
||||
"\n");
|
||||
std::cerr << "[ ] Warning ! Component output port does "
|
||||
"not preserve Read-Only fields \n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test State Transitions & Flush
|
||||
TEST_F(ComponentHidlTest, StateTransitions_Flush) {
|
||||
TEST_F(ComponentHidlTest, PopulatePort) {
|
||||
description("Verify bPopulated field of a component port");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_U32 portBase = 0;
|
||||
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
OMX_PORT_PARAM_TYPE params;
|
||||
if (compClass == audio_decoder || compClass == audio_encoder) {
|
||||
status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
|
||||
} else {
|
||||
status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
|
||||
}
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
portBase = params.nStartPortNumber;
|
||||
}
|
||||
|
||||
sp<IAllocator> allocator = IAllocator::getService("ashmem");
|
||||
EXPECT_NE(allocator.get(), nullptr);
|
||||
|
||||
OMX_PARAM_PORTDEFINITIONTYPE portDef;
|
||||
status =
|
||||
getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
ASSERT_EQ(portDef.bPopulated, OMX_FALSE);
|
||||
|
||||
android::Vector<BufferInfo> pBuffer;
|
||||
pBuffer.clear();
|
||||
uint32_t nBufferSize = portDef.nBufferSize >> 1;
|
||||
|
||||
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 = false;
|
||||
allocator->allocate(
|
||||
nBufferSize,
|
||||
[&success, &buffer](bool _s,
|
||||
::android::hardware::hidl_memory const& mem) {
|
||||
success = _s;
|
||||
buffer.omxBuffer.sharedMemory = mem;
|
||||
});
|
||||
ASSERT_EQ(success, true);
|
||||
ASSERT_EQ(buffer.omxBuffer.sharedMemory.size(), nBufferSize);
|
||||
|
||||
omxNode->useBuffer(
|
||||
portBase, buffer.omxBuffer,
|
||||
[&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
|
||||
uint32_t id) {
|
||||
status = _s;
|
||||
buffer.id = id;
|
||||
});
|
||||
pBuffer.push(buffer);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
status =
|
||||
getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef);
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
// A port is populated when all of the buffers indicated by
|
||||
// nBufferCountActual
|
||||
// with a size of at least nBufferSizehave been allocated on the port.
|
||||
ASSERT_EQ(portDef.bPopulated, OMX_FALSE);
|
||||
}
|
||||
|
||||
TEST_F(ComponentHidlTest, Flush) {
|
||||
description("Test Flush");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
Message msg;
|
||||
@@ -580,163 +871,79 @@ TEST_F(ComponentHidlTest, StateTransitions_Flush) {
|
||||
android::Vector<BufferInfo> iBuffer, oBuffer;
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// Dont switch states until the ports got their buffers
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on input port
|
||||
allocatePortBuffers(omxNode, allocator, &iBuffer, kPortIndexInput);
|
||||
|
||||
// Dont switch states until the ports got their buffers
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on output port
|
||||
allocatePortBuffers(omxNode, allocator, &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);
|
||||
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
// set state to executing
|
||||
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);
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < oBuffer.size(); ++i) {
|
||||
native_handle_t* fenceNh = native_handle_create(0, 0);
|
||||
status = omxNode->fillBuffer(oBuffer[i].id, t, fenceNh);
|
||||
native_handle_close(fenceNh);
|
||||
native_handle_delete(fenceNh);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
oBuffer.editItemAt(i).owner = component;
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
// dispatch buffers
|
||||
for (size_t i = 0; i < oBuffer.size(); i++) {
|
||||
dispatchOutputBuffer(omxNode, &oBuffer, i);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// test if client got all its buffers back
|
||||
for (size_t i = 0; i < oBuffer.size(); ++i) {
|
||||
EXPECT_EQ(oBuffer[i].owner, client);
|
||||
// flush port
|
||||
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
|
||||
kPortIndexOutput);
|
||||
// dispatch buffers
|
||||
for (size_t i = 0; i < iBuffer.size(); i++) {
|
||||
dispatchInputBuffer(omxNode, &iBuffer, i, 0, 0, 0);
|
||||
}
|
||||
|
||||
// set state to executing
|
||||
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);
|
||||
|
||||
for (size_t i = 0; i < oBuffer.size(); i += 2) {
|
||||
native_handle_t* fenceNh = native_handle_create(0, 0);
|
||||
status = omxNode->fillBuffer(oBuffer[i].id, t, fenceNh);
|
||||
native_handle_close(fenceNh);
|
||||
native_handle_delete(fenceNh);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
oBuffer.editItemAt(i).owner = component;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
// flush ports
|
||||
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
|
||||
kPortIndexOutput);
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to loaded
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
}
|
||||
|
||||
TEST_F(ComponentHidlTest, StateTransitions) {
|
||||
description("Test State Transitions");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
Message msg;
|
||||
|
||||
status = setRole(omxNode, gEnv->getRole().c_str());
|
||||
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
OMX_PORT_PARAM_TYPE params;
|
||||
if (compClass == audio_decoder || compClass == audio_encoder) {
|
||||
status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
|
||||
} else {
|
||||
status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
|
||||
}
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
kPortIndexInput = params.nStartPortNumber;
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
|
||||
android::Vector<BufferInfo> iBuffer, oBuffer;
|
||||
|
||||
// set state to idle
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
// dispatch buffers
|
||||
for (size_t i = 0; i < oBuffer.size(); i++) {
|
||||
dispatchOutputBuffer(omxNode, &oBuffer, i);
|
||||
}
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
// dispatch buffers
|
||||
for (size_t i = 0; i < iBuffer.size(); i++) {
|
||||
dispatchInputBuffer(omxNode, &iBuffer, i, 0, 0, 0);
|
||||
}
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to loaded
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
}
|
||||
|
||||
// Test State Transitions
|
||||
TEST_F(ComponentHidlTest, StateTransitions_M) {
|
||||
description("Test State Transitions monkeying");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
Message msg;
|
||||
@@ -768,21 +975,8 @@ TEST_F(ComponentHidlTest, StateTransitions_M) {
|
||||
EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// allocate buffers on i/o port
|
||||
allocatePortBuffers(omxNode, allocator, &iBuffer, kPortIndexInput);
|
||||
allocatePortBuffers(omxNode, allocator, &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);
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
// set state to idle ; receive error OMX_ErrorSameState
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
@@ -790,16 +984,7 @@ TEST_F(ComponentHidlTest, StateTransitions_M) {
|
||||
EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// set state to executing
|
||||
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);
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
|
||||
// set state to executing ; receive error OMX_ErrorSameState
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
@@ -812,43 +997,15 @@ TEST_F(ComponentHidlTest, StateTransitions_M) {
|
||||
EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// 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);
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
|
||||
// set state to Loaded
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateLoaded);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
}
|
||||
|
||||
// Enable and Disable Input and Output ports when the component is in Loaded
|
||||
// State
|
||||
TEST_F(ComponentHidlTest, PortEnableDisable_Loaded) {
|
||||
description("Test Port Enable and Disable (Component State :: Loaded)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_U32 portBase = 0;
|
||||
Message msg;
|
||||
@@ -895,8 +1052,8 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Loaded) {
|
||||
}
|
||||
}
|
||||
|
||||
// Enable and Disable Input and Output ports when the component is in Idle State
|
||||
TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
|
||||
description("Test Port Enable and Disable (Component State :: Idle)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
OMX_U32 portBase = 0;
|
||||
@@ -918,22 +1075,10 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
|
||||
|
||||
// Component State :: Idle
|
||||
android::Vector<BufferInfo> pBuffer[2];
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// allocate buffers on input port
|
||||
allocatePortBuffers(omxNode, allocator, &pBuffer[0], kPortIndexInput);
|
||||
allocatePortBuffers(omxNode, allocator, &pBuffer[1], kPortIndexOutput);
|
||||
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
|
||||
&pBuffer[1]);
|
||||
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);
|
||||
changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1],
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
for (size_t i = portBase; i < portBase + 2; i++) {
|
||||
status =
|
||||
@@ -982,7 +1127,7 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
|
||||
ASSERT_EQ(status,
|
||||
android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
allocatePortBuffers(omxNode, allocator, &pBuffer[i - portBase], i);
|
||||
allocatePortBuffers(omxNode, &pBuffer[i - portBase], i);
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
|
||||
&pBuffer[0], &pBuffer[1]);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
@@ -994,10 +1139,14 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
// set state to Loaded
|
||||
changeStateIdletoLoaded(omxNode, observer, &pBuffer[0], &pBuffer[1],
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
}
|
||||
|
||||
// Enable and Disable Input and Output ports when the component is in execute
|
||||
TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
|
||||
description("Test Port Enable and Disable (Component State :: Execute)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
OMX_U32 portBase = 0;
|
||||
@@ -1019,48 +1168,17 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
|
||||
|
||||
// Component State :: Idle
|
||||
android::Vector<BufferInfo> pBuffer[2];
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1],
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
// allocate buffers on input port
|
||||
allocatePortBuffers(omxNode, allocator, &pBuffer[0], kPortIndexInput);
|
||||
allocatePortBuffers(omxNode, allocator, &pBuffer[1], kPortIndexOutput);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
|
||||
&pBuffer[1]);
|
||||
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);
|
||||
|
||||
// Component State :: Execute
|
||||
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, &pBuffer[0],
|
||||
&pBuffer[1]);
|
||||
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);
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < pBuffer[1].size(); ++i) {
|
||||
native_handle_t* fenceNh = native_handle_create(0, 0);
|
||||
status = omxNode->fillBuffer(pBuffer[1][i].id, t, fenceNh);
|
||||
native_handle_close(fenceNh);
|
||||
native_handle_delete(fenceNh);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
pBuffer[1].editItemAt(i).owner = component;
|
||||
// dispatch buffers
|
||||
for (size_t i = 0; i < pBuffer[1].size(); i++) {
|
||||
dispatchOutputBuffer(omxNode, &pBuffer[1], i);
|
||||
}
|
||||
|
||||
for (size_t i = portBase; i < portBase + 2; i++) {
|
||||
@@ -1113,7 +1231,7 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
|
||||
ASSERT_EQ(status,
|
||||
android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
allocatePortBuffers(omxNode, allocator, &pBuffer[i - portBase], i);
|
||||
allocatePortBuffers(omxNode, &pBuffer[i - portBase], i);
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
|
||||
&pBuffer[0], &pBuffer[1]);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
@@ -1125,10 +1243,18 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
// set state to Idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1]);
|
||||
|
||||
// set state to Loaded
|
||||
changeStateIdletoLoaded(omxNode, observer, &pBuffer[0], &pBuffer[1],
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
}
|
||||
|
||||
// Enable and Disable Input and Output ports, (in loaded state)
|
||||
TEST_F(ComponentHidlTest, PortEnableDisable_M) {
|
||||
description(
|
||||
"Test Port Enable and Disable Monkeying (Component State :: Loaded)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_U32 portBase = 0;
|
||||
Message msg;
|
||||
|
||||
@@ -105,6 +105,13 @@ TEST_F(MasterHidlTest, ListNodes) {
|
||||
nodeList = _nl;
|
||||
})
|
||||
.isOk());
|
||||
for (size_t i = 0; i < nodeList.size(); i++) {
|
||||
printf("%s", nodeList[i].mName.c_str());
|
||||
for (size_t j = 0; j < ((nodeList[i]).mRoles).size(); j++) {
|
||||
printf("\t %s", nodeList[i].mRoles[j].c_str());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
77
media/omx/1.0/vts/functional/video/Android.bp
Normal file
77
media/omx/1.0/vts/functional/video/Android.bp
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// 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_0TargetVideoDecTest",
|
||||
defaults: ["hidl_defaults"],
|
||||
srcs: ["VtsHalMediaOmxV1_0TargetVideoDecTest.cpp",
|
||||
"media_video_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_0TargetVideoEncTest",
|
||||
defaults: ["hidl_defaults"],
|
||||
srcs: ["VtsHalMediaOmxV1_0TargetVideoEncTest.cpp",
|
||||
"media_video_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,551 @@
|
||||
/*
|
||||
* 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_video_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_hidl_test_common.h>
|
||||
#include <media_video_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 VideoDecHidlTest : 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[] = {
|
||||
{"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
|
||||
{"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
|
||||
};
|
||||
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 CompToCompression {
|
||||
standardComp CompName;
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat;
|
||||
};
|
||||
static const CompToCompression kCompToCompression[] = {
|
||||
{h263, OMX_VIDEO_CodingH263}, {avc, OMX_VIDEO_CodingAVC},
|
||||
{mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
|
||||
{hevc, OMX_VIDEO_CodingHEVC}, {vp8, OMX_VIDEO_CodingVP8},
|
||||
{vp9, OMX_VIDEO_CodingVP9},
|
||||
};
|
||||
static const size_t kNumCompToCompression =
|
||||
sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
|
||||
size_t i;
|
||||
for (i = 0; i < kNumCompToCompression; ++i) {
|
||||
if (kCompToCompression[i].CompName == compName) {
|
||||
eCompressionFormat = kCompToCompression[i].eCompressionFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(i, kNumCompToCompression);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
if (omxNode != nullptr) {
|
||||
EXPECT_TRUE((omxNode->freeNode()).isOk());
|
||||
omxNode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
enum standardComp {
|
||||
h263,
|
||||
avc,
|
||||
mpeg2,
|
||||
mpeg4,
|
||||
hevc,
|
||||
vp8,
|
||||
vp9,
|
||||
unknown_comp,
|
||||
};
|
||||
|
||||
sp<IOmx> omx;
|
||||
sp<CodecObserver> observer;
|
||||
sp<IOmxNode> omxNode;
|
||||
standardComp compName;
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat;
|
||||
|
||||
protected:
|
||||
static void description(const std::string& description) {
|
||||
RecordProperty("description", description);
|
||||
}
|
||||
};
|
||||
|
||||
// Set Default port param.
|
||||
void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat,
|
||||
OMX_COLOR_FORMATTYPE eColorFormat,
|
||||
OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
|
||||
OMX_U32 nBitrate = 0,
|
||||
OMX_U32 xFramerate = (24U << 16)) {
|
||||
switch ((int)eCompressionFormat) {
|
||||
case OMX_VIDEO_CodingUnused:
|
||||
setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
|
||||
nBitrate, xFramerate, eColorFormat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// In decoder components, often the input port parameters get updated upon
|
||||
// parsing the header of elementary stream. Client needs to collect this
|
||||
// information to reconfigure other ports that share data with this input
|
||||
// port.
|
||||
void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
|
||||
uint32_t* nFrameWidth, uint32_t* nFrameHeight,
|
||||
uint32_t* xFramerate) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
*nFrameWidth = 352;
|
||||
*nFrameHeight = 288;
|
||||
*xFramerate = (24U << 16);
|
||||
|
||||
OMX_PARAM_PORTDEFINITIONTYPE portDef;
|
||||
status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
|
||||
kPortIndexInput, &portDef);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
*nFrameWidth = portDef.format.video.nFrameWidth;
|
||||
*nFrameHeight = portDef.format.video.nFrameHeight;
|
||||
*xFramerate = portDef.format.video.xFramerate;
|
||||
}
|
||||
}
|
||||
|
||||
// LookUpTable of clips and metadata for component testing
|
||||
void GetURLForComponent(VideoDecHidlTest::standardComp comp, const char** mURL,
|
||||
const char** info) {
|
||||
struct CompToURL {
|
||||
VideoDecHidlTest::standardComp comp;
|
||||
const char* mURL;
|
||||
const char* info;
|
||||
};
|
||||
static const CompToURL kCompToURL[] = {
|
||||
{VideoDecHidlTest::standardComp::avc,
|
||||
"/sdcard/media/bbb_avc_1920x1080_5000kbps_30fps.h264",
|
||||
"/sdcard/media/bbb_avc_1920x1080_5000kbps_30fps.info"},
|
||||
};
|
||||
|
||||
*mURL = *info = nullptr;
|
||||
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 portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
|
||||
Message msg) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
|
||||
if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
|
||||
ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
|
||||
if (msg.data.eventData.data2 == 0) {
|
||||
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);
|
||||
|
||||
// set Port Params
|
||||
uint32_t nFrameWidth, nFrameHeight, xFramerate;
|
||||
OMX_COLOR_FORMATTYPE eColorFormat =
|
||||
OMX_COLOR_FormatYUV420Planar;
|
||||
getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
|
||||
&nFrameHeight, &xFramerate);
|
||||
setDefaultPortParam(omxNode, kPortIndexOutput,
|
||||
OMX_VIDEO_CodingUnused, eColorFormat,
|
||||
nFrameWidth, nFrameHeight, 0, xFramerate);
|
||||
|
||||
// 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);
|
||||
}
|
||||
} else if (msg.data.eventData.data2 ==
|
||||
OMX_IndexConfigCommonOutputCrop) {
|
||||
std::cerr << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
|
||||
"OMX_IndexConfigCommonOutputCrop not handled \n";
|
||||
} else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
|
||||
std::cerr << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
|
||||
"kDescribeColorAspectsIndex not handled \n";
|
||||
}
|
||||
} else if (msg.data.eventData.event == OMX_EventError) {
|
||||
std::cerr << "[ ] Warning ! OMX_EventError/ "
|
||||
"Decode Frame Call might be failed \n";
|
||||
return;
|
||||
} else {
|
||||
// something unexpected happened
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Decode N Frames
|
||||
void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
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;
|
||||
uint32_t sampleflags = 0, flags = 0;
|
||||
uint64_t timestamp = 0;
|
||||
for (size_t i = 0; i < iBuffer->size() && nFrames != 0; i++) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
|
||||
if (!(eleInfo >> bytesCount)) break;
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[i].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
ASSERT_EQ(eleStream.gcount(), bytesCount);
|
||||
eleInfo >> sampleflags;
|
||||
eleInfo >> timestamp;
|
||||
flags = 0;
|
||||
// Map MediaExtractor flags to OMX Buffer flags
|
||||
if (sampleflags & 1) flags |= OMX_BUFFERFLAG_SYNCFRAME;
|
||||
dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, flags, timestamp);
|
||||
nFrames--;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
|
||||
// Port Reconfiguration
|
||||
if (status == android::hardware::media::omx::V1_0::Status::OK &&
|
||||
msg.type == Message::Type::EVENT) {
|
||||
portReconfiguration(omxNode, observer, iBuffer, oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput, msg);
|
||||
}
|
||||
|
||||
if (nFrames == 0) break;
|
||||
|
||||
// Dispatch input buffer
|
||||
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;
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[index].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
ASSERT_EQ(eleStream.gcount(), bytesCount);
|
||||
eleInfo >> sampleflags;
|
||||
eleInfo >> timestamp;
|
||||
flags = 0;
|
||||
// Map MediaExtractor flags to OMX Buffer flags
|
||||
if (sampleflags & 1) flags |= OMX_BUFFERFLAG_SYNCFRAME;
|
||||
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, flags,
|
||||
timestamp);
|
||||
nFrames--;
|
||||
}
|
||||
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VideoDecHidlTest, SetRole) {
|
||||
description("Test Set Component Role");
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_F(VideoDecHidlTest, EnumeratePortFormat) {
|
||||
description("Test Component on Mandatory Port Parameters (Port Format)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
||||
OMX_U32 xFramerate = (24U << 16);
|
||||
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_IndexParamVideoInit, ¶ms);
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
kPortIndexInput = params.nStartPortNumber;
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
|
||||
OMX_COLOR_FormatUnused, 0U);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
status =
|
||||
setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
|
||||
eColorFormat, xFramerate);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
TEST_F(VideoDecHidlTest, DecodeTest) {
|
||||
description("Tests Port Reconfiguration and Decode");
|
||||
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_IndexParamVideoInit, ¶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);
|
||||
|
||||
// set Port Params
|
||||
uint32_t nFrameWidth, nFrameHeight, xFramerate;
|
||||
OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
||||
getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
|
||||
&xFramerate);
|
||||
setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
|
||||
eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
|
||||
|
||||
android::Vector<BufferInfo> iBuffer, oBuffer;
|
||||
|
||||
// set state to idle
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
// Port Reconfiguration
|
||||
decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
|
||||
kPortIndexOutput, 1024, eleStream, eleInfo);
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to executing
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
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,425 @@
|
||||
/*
|
||||
* 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_video_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_hidl_test_common.h>
|
||||
#include <media_video_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 VideoEncHidlTest : 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[] = {
|
||||
{"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
|
||||
{"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
|
||||
};
|
||||
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 CompToCompression {
|
||||
standardComp CompName;
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat;
|
||||
};
|
||||
static const CompToCompression kCompToCompression[] = {
|
||||
{h263, OMX_VIDEO_CodingH263}, {avc, OMX_VIDEO_CodingAVC},
|
||||
{mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
|
||||
{hevc, OMX_VIDEO_CodingHEVC}, {vp8, OMX_VIDEO_CodingVP8},
|
||||
{vp9, OMX_VIDEO_CodingVP9},
|
||||
};
|
||||
static const size_t kNumCompToCompression =
|
||||
sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
|
||||
size_t i;
|
||||
for (i = 0; i < kNumCompToCompression; ++i) {
|
||||
if (kCompToCompression[i].CompName == compName) {
|
||||
eCompressionFormat = kCompToCompression[i].eCompressionFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NE(i, kNumCompToCompression);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {
|
||||
if (omxNode != nullptr) {
|
||||
EXPECT_TRUE((omxNode->freeNode()).isOk());
|
||||
omxNode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
enum standardComp {
|
||||
h263,
|
||||
avc,
|
||||
mpeg2,
|
||||
mpeg4,
|
||||
hevc,
|
||||
vp8,
|
||||
vp9,
|
||||
unknown_comp,
|
||||
};
|
||||
|
||||
sp<IOmx> omx;
|
||||
sp<CodecObserver> observer;
|
||||
sp<IOmxNode> omxNode;
|
||||
standardComp compName;
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat;
|
||||
|
||||
protected:
|
||||
static void description(const std::string& description) {
|
||||
RecordProperty("description", description);
|
||||
}
|
||||
};
|
||||
|
||||
// Set Default port param.
|
||||
void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat,
|
||||
OMX_U32 nBitrate, OMX_U32 xFramerate) {
|
||||
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.video.nBitrate = nBitrate;
|
||||
portDef.format.video.xFramerate = xFramerate;
|
||||
portDef.format.video.bFlagErrorConcealment = OMX_TRUE;
|
||||
portDef.format.video.eCompressionFormat = eCompressionFormat;
|
||||
portDef.format.video.eColorFormat = OMX_COLOR_FormatUnused;
|
||||
status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
|
||||
&portDef);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
switch ((int)eCompressionFormat) {
|
||||
case OMX_VIDEO_CodingAVC:
|
||||
setupAVCPort(omxNode, portIndex, OMX_VIDEO_AVCProfileBaseline,
|
||||
OMX_VIDEO_AVCLevel31, xFramerate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// LookUpTable of clips and metadata for component testing
|
||||
void GetURLForComponent(VideoEncHidlTest::standardComp comp,
|
||||
const char** mURL) {
|
||||
struct CompToURL {
|
||||
VideoEncHidlTest::standardComp comp;
|
||||
const char* mURL;
|
||||
};
|
||||
static const CompToURL kCompToURL[] = {
|
||||
{VideoEncHidlTest::standardComp::avc,
|
||||
"/sdcard/media/bbb_480x360_420p_30fps_32frames.yuv"},
|
||||
};
|
||||
|
||||
*mURL = nullptr;
|
||||
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
|
||||
if (kCompToURL[i].comp == comp) {
|
||||
*mURL = kCompToURL[i].mURL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Encode N Frames
|
||||
void encodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer, uint32_t nFrames,
|
||||
uint32_t xFramerate, int bytesCount,
|
||||
std::ifstream& eleStream) {
|
||||
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
|
||||
int32_t timestampIncr = (int)((float)1000000 / (xFramerate >> 16));
|
||||
uint64_t timestamp = 0;
|
||||
for (size_t i = 0; i < iBuffer->size() && nFrames != 0; i++) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[i].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
if (eleStream.gcount() != bytesCount) break;
|
||||
dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, timestamp);
|
||||
timestamp += timestampIncr;
|
||||
nFrames--;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
status =
|
||||
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
|
||||
if (status == android::hardware::media::omx::V1_0::Status::OK)
|
||||
ASSERT_TRUE(false);
|
||||
|
||||
if (nFrames == 0) break;
|
||||
|
||||
// Dispatch input buffer
|
||||
size_t index = 0;
|
||||
if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
|
||||
char* ipBuffer = static_cast<char*>(
|
||||
static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
|
||||
ASSERT_LE(bytesCount,
|
||||
static_cast<int>((*iBuffer)[index].mMemory->getSize()));
|
||||
eleStream.read(ipBuffer, bytesCount);
|
||||
if (eleStream.gcount() != bytesCount) break;
|
||||
dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0,
|
||||
timestamp);
|
||||
timestamp += timestampIncr;
|
||||
nFrames--;
|
||||
}
|
||||
if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
|
||||
dispatchOutputBuffer(omxNode, oBuffer, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VideoEncHidlTest, SetRole) {
|
||||
description("Test Set Component Role");
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_F(VideoEncHidlTest, EnumeratePortFormat) {
|
||||
description("Test Component on Mandatory Port Parameters (Port Format)");
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
|
||||
OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
||||
OMX_U32 xFramerate = (30U << 16);
|
||||
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_IndexParamVideoInit, ¶ms);
|
||||
if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
|
||||
ASSERT_EQ(params.nPorts, 2U);
|
||||
kPortIndexInput = params.nStartPortNumber;
|
||||
kPortIndexOutput = kPortIndexInput + 1;
|
||||
}
|
||||
status =
|
||||
setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused,
|
||||
eColorFormat, xFramerate);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
status = setVideoPortFormat(omxNode, kPortIndexOutput, eCompressionFormat,
|
||||
OMX_COLOR_FormatUnused, 0U);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
TEST_F(VideoEncHidlTest, EncodeTest) {
|
||||
description("Test Encode");
|
||||
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_IndexParamVideoInit, ¶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;
|
||||
GetURLForComponent(compName, &mURL);
|
||||
EXPECT_NE(mURL, nullptr);
|
||||
|
||||
std::ifstream eleStream;
|
||||
eleStream.open(mURL, std::ifstream::binary);
|
||||
ASSERT_EQ(eleStream.is_open(), true);
|
||||
|
||||
// Configure input port
|
||||
uint32_t nFrameWidth = 480;
|
||||
uint32_t nFrameHeight = 360;
|
||||
uint32_t xFramerate = (30U << 16);
|
||||
OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
||||
setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
|
||||
xFramerate, eColorFormat);
|
||||
// Configure output port
|
||||
uint32_t nBitRate = 768000;
|
||||
setDefaultPortParam(omxNode, kPortIndexOutput, eCompressionFormat, nBitRate,
|
||||
xFramerate);
|
||||
|
||||
android::Vector<BufferInfo> iBuffer, oBuffer;
|
||||
|
||||
// set state to idle
|
||||
changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
// set state to executing
|
||||
changeStateIdletoExecute(omxNode, observer);
|
||||
|
||||
encodeNFrames(omxNode, observer, &iBuffer, &oBuffer, 1024, xFramerate,
|
||||
(nFrameWidth * nFrameHeight * 3) >> 1, eleStream);
|
||||
// set state to idle
|
||||
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
|
||||
// set state to executing
|
||||
changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
|
||||
kPortIndexInput, kPortIndexOutput);
|
||||
|
||||
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,451 @@
|
||||
/*
|
||||
* 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_video_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_hidl_test_common.h>
|
||||
#include <media_video_hidl_test_common.h>
|
||||
#include <memory>
|
||||
|
||||
// allocate buffers needed on a component port
|
||||
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.get(), 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 = false;
|
||||
allocator->allocate(
|
||||
portDef.nBufferSize,
|
||||
[&success, &buffer](bool _s,
|
||||
::android::hardware::hidl_memory const& mem) {
|
||||
success = _s;
|
||||
buffer.omxBuffer.sharedMemory = mem;
|
||||
});
|
||||
ASSERT_EQ(success, true);
|
||||
ASSERT_EQ(buffer.omxBuffer.sharedMemory.size(), portDef.nBufferSize);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// State Transition : Loaded -> Idle
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateLoadedtoIdle(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;
|
||||
|
||||
// set state to idle
|
||||
status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
|
||||
OMX_StateIdle);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
|
||||
|
||||
// Dont switch states until the ports are populated
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on input port
|
||||
allocatePortBuffers(omxNode, iBuffer, kPortIndexInput);
|
||||
|
||||
// Dont switch states until the ports are populated
|
||||
status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
|
||||
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
|
||||
|
||||
// allocate buffers on output port
|
||||
allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
|
||||
|
||||
// As the ports are populated, check if the state transition is complete
|
||||
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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Idle -> Loaded
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateIdletoLoaded(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;
|
||||
|
||||
// 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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Idle -> Execute
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateIdletoExecute(sp<IOmxNode> omxNode,
|
||||
sp<CodecObserver> observer) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// set state to execute
|
||||
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);
|
||||
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);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// State Transition : Execute -> Idle
|
||||
// Note: This function does not make any background checks for this transition.
|
||||
// The callee holds the reponsibility to ensure the legality of the transition.
|
||||
void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
Message msg;
|
||||
|
||||
// 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);
|
||||
|
||||
// test if client got all its buffers back
|
||||
for (size_t i = 0; i < oBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*oBuffer)[i].owner, client);
|
||||
}
|
||||
for (size_t i = 0; i < iBuffer->size(); ++i) {
|
||||
EXPECT_EQ((*iBuffer)[i].owner, client);
|
||||
}
|
||||
}
|
||||
|
||||
// get empty buffer index
|
||||
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();
|
||||
}
|
||||
|
||||
// dispatch buffer to output port
|
||||
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;
|
||||
}
|
||||
|
||||
// dispatch buffer to input port
|
||||
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;
|
||||
}
|
||||
|
||||
// Flush input and output ports
|
||||
void flushPorts(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 input port
|
||||
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);
|
||||
}
|
||||
|
||||
// Flush output port
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
|
||||
OMX_U32 xFramerate) {
|
||||
OMX_U32 index = 0;
|
||||
OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
|
||||
std::vector<OMX_COLOR_FORMATTYPE> arrColorFormat;
|
||||
std::vector<OMX_VIDEO_CODINGTYPE> arrCompressionFormat;
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
|
||||
while (1) {
|
||||
portFormat.nIndex = index;
|
||||
status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
|
||||
&portFormat);
|
||||
if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
|
||||
if (eCompressionFormat == OMX_VIDEO_CodingUnused)
|
||||
arrColorFormat.push_back(portFormat.eColorFormat);
|
||||
else
|
||||
arrCompressionFormat.push_back(portFormat.eCompressionFormat);
|
||||
index++;
|
||||
if (index == 512) {
|
||||
// enumerated way too many formats, highly unusual for this to
|
||||
// happen.
|
||||
EXPECT_LE(index, 512U)
|
||||
<< "Expecting OMX_ErrorNoMore but not received";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!index) return status;
|
||||
if (eCompressionFormat == OMX_VIDEO_CodingUnused) {
|
||||
for (index = 0; index < arrColorFormat.size(); index++) {
|
||||
if (arrColorFormat[index] == eColorFormat) {
|
||||
portFormat.eColorFormat = arrColorFormat[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == arrColorFormat.size()) {
|
||||
ALOGI("setting default color format");
|
||||
portFormat.eColorFormat = arrColorFormat[0];
|
||||
}
|
||||
portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
|
||||
} else {
|
||||
for (index = 0; index < arrCompressionFormat.size(); index++) {
|
||||
if (arrCompressionFormat[index] == eCompressionFormat) {
|
||||
portFormat.eCompressionFormat = arrCompressionFormat[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == arrCompressionFormat.size()) {
|
||||
ALOGI("setting default compression format");
|
||||
portFormat.eCompressionFormat = arrCompressionFormat[0];
|
||||
}
|
||||
portFormat.eColorFormat = OMX_COLOR_FormatUnused;
|
||||
}
|
||||
portFormat.nIndex = 0;
|
||||
portFormat.xFramerate = xFramerate;
|
||||
status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, 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 setupRAWPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 nFrameWidth,
|
||||
OMX_U32 nFrameHeight, OMX_U32 nBitrate, OMX_U32 xFramerate,
|
||||
OMX_COLOR_FORMATTYPE eColorFormat) {
|
||||
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.video.nFrameWidth = nFrameWidth;
|
||||
portDef.format.video.nFrameHeight = nFrameHeight;
|
||||
portDef.format.video.nStride = (((nFrameWidth + 15) >> 4) << 4);
|
||||
portDef.format.video.nSliceHeight = (((nFrameHeight + 15) >> 4) << 4);
|
||||
portDef.format.video.nBitrate = nBitrate;
|
||||
portDef.format.video.xFramerate = xFramerate;
|
||||
portDef.format.video.bFlagErrorConcealment = OMX_TRUE;
|
||||
portDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
|
||||
portDef.format.video.eColorFormat = eColorFormat;
|
||||
status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
|
||||
&portDef);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupAVCPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_AVCPROFILETYPE eProfile,
|
||||
OMX_VIDEO_AVCLEVELTYPE eLevel, OMX_U32 xFramerate) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_VIDEO_PARAM_AVCTYPE param;
|
||||
(void)xFramerate; // necessary for intra frame spacing
|
||||
|
||||
status = getPortParam(omxNode, OMX_IndexParamVideoAvc, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.nSliceHeaderSpacing = 0;
|
||||
param.nPFrames = 0xFFFFFFFE;
|
||||
param.nBFrames = 0;
|
||||
param.bUseHadamard = OMX_TRUE;
|
||||
param.nRefFrames = 1;
|
||||
param.eProfile = eProfile;
|
||||
param.eLevel = eLevel;
|
||||
param.nAllowedPictureTypes =
|
||||
OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
|
||||
param.bFrameMBsOnly = OMX_TRUE;
|
||||
param.bEntropyCodingCABAC = OMX_FALSE;
|
||||
param.bWeightedPPrediction = OMX_FALSE;
|
||||
param.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
|
||||
status = setPortParam(omxNode, OMX_IndexParamVideoAvc, portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
|
||||
void setupHEVCPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_HEVCPROFILETYPE eProfile,
|
||||
OMX_VIDEO_HEVCLEVELTYPE eLevel) {
|
||||
android::hardware::media::omx::V1_0::Status status;
|
||||
OMX_VIDEO_PARAM_HEVCTYPE param;
|
||||
|
||||
status = getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc,
|
||||
portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
param.eProfile = eProfile;
|
||||
param.eLevel = eLevel;
|
||||
param.nKeyFrameInterval = 0xFFFFFFFE;
|
||||
status = setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc,
|
||||
portIndex, ¶m);
|
||||
EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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_VIDEO_HIDL_TEST_COMMON_H
|
||||
#define MEDIA_VIDEO_HIDL_TEST_COMMON_H
|
||||
|
||||
/*
|
||||
* Random Index used for monkey testing while get/set parameters
|
||||
*/
|
||||
#define RANDOM_INDEX 1729
|
||||
|
||||
/*
|
||||
* Common video utils
|
||||
*/
|
||||
void allocatePortBuffers(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
OMX_U32 portIndex);
|
||||
|
||||
void changeStateLoadedtoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput);
|
||||
|
||||
void changeStateIdletoLoaded(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer,
|
||||
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput);
|
||||
|
||||
void changeStateIdletoExecute(sp<IOmxNode> omxNode, sp<CodecObserver> observer);
|
||||
|
||||
void changeStateExecutetoIdle(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer);
|
||||
|
||||
size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);
|
||||
|
||||
void dispatchOutputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex);
|
||||
|
||||
void dispatchInputBuffer(sp<IOmxNode> omxNode,
|
||||
android::Vector<BufferInfo>* buffArray,
|
||||
size_t bufferIndex, int bytesCount, uint32_t flags,
|
||||
uint64_t timestamp);
|
||||
|
||||
void flushPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
|
||||
android::Vector<BufferInfo>* iBuffer,
|
||||
android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
|
||||
OMX_U32 kPortIndexOutput);
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
|
||||
sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_CODINGTYPE eCompressionFormat, OMX_COLOR_FORMATTYPE eColorFormat,
|
||||
OMX_U32 xFramerate);
|
||||
|
||||
Return<android::hardware::media::omx::V1_0::Status> setRole(
|
||||
sp<IOmxNode> omxNode, const char* role);
|
||||
|
||||
void setupRAWPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_U32 nFrameWidth,
|
||||
OMX_U32 nFrameHeight, OMX_U32 nBitrate, OMX_U32 xFramerate,
|
||||
OMX_COLOR_FORMATTYPE eColorFormat);
|
||||
|
||||
void setupAVCPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_AVCPROFILETYPE eProfile,
|
||||
OMX_VIDEO_AVCLEVELTYPE eLevel, OMX_U32 xFramerate);
|
||||
|
||||
void setupHEVCPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
|
||||
OMX_VIDEO_HEVCPROFILETYPE eProfile,
|
||||
OMX_VIDEO_HEVCLEVELTYPE eLevel);
|
||||
|
||||
#endif // MEDIA_VIDEO_HIDL_TEST_COMMON_H
|
||||
1
media/res/bbb_480x360_420p_30fps_32frames.yuv
Normal file
1
media/res/bbb_480x360_420p_30fps_32frames.yuv
Normal file
File diff suppressed because one or more lines are too long
BIN
media/res/bbb_avc_1920x1080_5000kbps_30fps.h264
Normal file
BIN
media/res/bbb_avc_1920x1080_5000kbps_30fps.h264
Normal file
Binary file not shown.
242
media/res/bbb_avc_1920x1080_5000kbps_30fps.info
Normal file
242
media/res/bbb_avc_1920x1080_5000kbps_30fps.info
Normal file
@@ -0,0 +1,242 @@
|
||||
31 0 0
|
||||
8 0 0
|
||||
481702 1 0
|
||||
137895 0 33333
|
||||
81863 0 100000
|
||||
98914 0 133333
|
||||
6855 0 166666
|
||||
2738 0 200000
|
||||
1340 0 266666
|
||||
1680 0 300000
|
||||
2217 0 333333
|
||||
3275 0 366666
|
||||
3509 0 433333
|
||||
4688 0 466666
|
||||
4996 0 500000
|
||||
6057 0 533333
|
||||
7061 0 600000
|
||||
7427 0 633333
|
||||
7484 0 666666
|
||||
8361 0 700000
|
||||
7803 0 766666
|
||||
8506 0 800000
|
||||
8132 0 833333
|
||||
8651 0 866666
|
||||
8424 0 933333
|
||||
8861 0 966666
|
||||
9004 0 1000000
|
||||
9431 0 1033333
|
||||
8854 0 1100000
|
||||
9681 0 1133333
|
||||
9498 0 1166666
|
||||
9694 0 1200000
|
||||
17571 0 1266666
|
||||
10029 0 1300000
|
||||
10022 0 1333333
|
||||
9939 0 1366666
|
||||
8427 0 1433333
|
||||
9522 0 1466666
|
||||
7192 0 1500000
|
||||
9844 0 1533333
|
||||
5693 0 1600000
|
||||
8057 0 1633333
|
||||
5997 0 1666666
|
||||
4028 0 1700000
|
||||
2303 0 1766666
|
||||
845 0 1800000
|
||||
191414 1 1833333
|
||||
13266 0 1866666
|
||||
16120 0 1933333
|
||||
19751 0 1966666
|
||||
6559 0 2000000
|
||||
8098 0 2033333
|
||||
8596 0 2100000
|
||||
9331 0 2133333
|
||||
9908 0 2166666
|
||||
13843 0 2200000
|
||||
13776 0 2266666
|
||||
14556 0 2300000
|
||||
14524 0 2333333
|
||||
15089 0 2366666
|
||||
14666 0 2433333
|
||||
15552 0 2466666
|
||||
15020 0 2500000
|
||||
16506 0 2533333
|
||||
15664 0 2600000
|
||||
16499 0 2633333
|
||||
16113 0 2666666
|
||||
16924 0 2700000
|
||||
15948 0 2766666
|
||||
17219 0 2800000
|
||||
16448 0 2833333
|
||||
17729 0 2866666
|
||||
16884 0 2933333
|
||||
17941 0 2966666
|
||||
17215 0 3000000
|
||||
18159 0 3033333
|
||||
17424 0 3100000
|
||||
18479 0 3133333
|
||||
17255 0 3166666
|
||||
18463 0 3200000
|
||||
18723 0 3266666
|
||||
19291 0 3300000
|
||||
18297 0 3333333
|
||||
19633 0 3366666
|
||||
18719 0 3433333
|
||||
20323 0 3466666
|
||||
17035 0 3500000
|
||||
19071 0 3533333
|
||||
17921 0 3600000
|
||||
19198 0 3633333
|
||||
18723 0 3666666
|
||||
19036 0 3700000
|
||||
18735 0 3766666
|
||||
19613 0 3800000
|
||||
18537 0 3833333
|
||||
20868 0 3866666
|
||||
16731 0 3933333
|
||||
19380 0 3966666
|
||||
18409 0 4000000
|
||||
19580 0 4033333
|
||||
18465 0 4100000
|
||||
20104 0 4133333
|
||||
16783 0 4166666
|
||||
19341 0 4200000
|
||||
18674 0 4266666
|
||||
19983 0 4300000
|
||||
19154 0 4333333
|
||||
19750 0 4366666
|
||||
19483 0 4433333
|
||||
21206 0 4466666
|
||||
17608 0 4500000
|
||||
20220 0 4533333
|
||||
18918 0 4600000
|
||||
19494 0 4633333
|
||||
19072 0 4666666
|
||||
19786 0 4700000
|
||||
18540 0 4766666
|
||||
19638 0 4800000
|
||||
18656 0 4833333
|
||||
19453 0 4866666
|
||||
19673 0 4933333
|
||||
17616 0 4966666
|
||||
18317 0 5000000
|
||||
18749 0 5033333
|
||||
18193 0 5100000
|
||||
18732 0 5133333
|
||||
18186 0 5166666
|
||||
18271 0 5200000
|
||||
18256 0 5266666
|
||||
16806 0 5300000
|
||||
17119 0 5333333
|
||||
16466 0 5366666
|
||||
15315 0 5433333
|
||||
14877 0 5466666
|
||||
13235 0 5500000
|
||||
13025 0 5533333
|
||||
10305 0 5600000
|
||||
10120 0 5633333
|
||||
7706 0 5666666
|
||||
112698 1 5700000
|
||||
1544 0 5766666
|
||||
1285 0 5800000
|
||||
1576 0 5833333
|
||||
1714 0 5866666
|
||||
1384 0 5933333
|
||||
1551 0 5966666
|
||||
3916 0 6000000
|
||||
8019 0 6033333
|
||||
8304 0 6100000
|
||||
8416 0 6133333
|
||||
8086 0 6166666
|
||||
8452 0 6200000
|
||||
9205 0 6266666
|
||||
11098 0 6300000
|
||||
19805 0 6333333
|
||||
18292 0 6366666
|
||||
14974 0 6433333
|
||||
10425 0 6466666
|
||||
9997 0 6500000
|
||||
8832 0 6533333
|
||||
7909 0 6600000
|
||||
6400 0 6633333
|
||||
5939 0 6666666
|
||||
5965 0 6700000
|
||||
6221 0 6766666
|
||||
6522 0 6800000
|
||||
7062 0 6833333
|
||||
6877 0 6866666
|
||||
6859 0 6933333
|
||||
6550 0 6966666
|
||||
6127 0 7000000
|
||||
5386 0 7033333
|
||||
5092 0 7100000
|
||||
4370 0 7133333
|
||||
4048 0 7166666
|
||||
3922 0 7200000
|
||||
11453 0 7266666
|
||||
16041 0 7300000
|
||||
16756 0 7333333
|
||||
8616 0 7366666
|
||||
9856 0 7433333
|
||||
14997 0 7466666
|
||||
18365 0 7500000
|
||||
21295 0 7533333
|
||||
19335 0 7600000
|
||||
13689 0 7633333
|
||||
14147 0 7666666
|
||||
13198 0 7700000
|
||||
10999 0 7766666
|
||||
7726 0 7800000
|
||||
8744 0 7833333
|
||||
11321 0 7866666
|
||||
14840 0 7933333
|
||||
21702 0 7966666
|
||||
27091 0 8000000
|
||||
28992 0 8033333
|
||||
26391 0 8100000
|
||||
13809 0 8133333
|
||||
11196 0 8166666
|
||||
10494 0 8200000
|
||||
9921 0 8266666
|
||||
7637 0 8300000
|
||||
7301 0 8333333
|
||||
6890 0 8366666
|
||||
9059 0 8433333
|
||||
9324 0 8466666
|
||||
10277 0 8500000
|
||||
10436 0 8533333
|
||||
10635 0 8600000
|
||||
9554 0 8633333
|
||||
8268 0 8666666
|
||||
8450 0 8700000
|
||||
8430 0 8766666
|
||||
8258 0 8800000
|
||||
8879 0 8833333
|
||||
8050 0 8866666
|
||||
7963 0 8933333
|
||||
8974 0 8966666
|
||||
10037 0 9000000
|
||||
8547 0 9033333
|
||||
6424 0 9100000
|
||||
5672 0 9133333
|
||||
6159 0 9166666
|
||||
6498 0 9200000
|
||||
7064 0 9266666
|
||||
6673 0 9300000
|
||||
6959 0 9333333
|
||||
6226 0 9366666
|
||||
6312 0 9433333
|
||||
8893 0 9466666
|
||||
8253 0 9500000
|
||||
5876 0 9533333
|
||||
5867 0 9600000
|
||||
6212 0 9633333
|
||||
6984 0 9666666
|
||||
6220 0 9700000
|
||||
6993 0 9766666
|
||||
15014 0 9800000
|
||||
22390 0 9833333
|
||||
29552 0 9866666
|
||||
24024 0 9933333
|
||||
15820 0 9966666
|
||||
414
media/res/bbb_mp3_stereo_192kbps_48000hz.info
Normal file
414
media/res/bbb_mp3_stereo_192kbps_48000hz.info
Normal file
@@ -0,0 +1,414 @@
|
||||
576 1 0
|
||||
576 1 24000
|
||||
576 1 48000
|
||||
576 1 72000
|
||||
576 1 96000
|
||||
576 1 120000
|
||||
576 1 144000
|
||||
576 1 168000
|
||||
576 1 192000
|
||||
576 1 216000
|
||||
576 1 240000
|
||||
576 1 264000
|
||||
576 1 288000
|
||||
576 1 312000
|
||||
576 1 336000
|
||||
576 1 360000
|
||||
576 1 384000
|
||||
576 1 408000
|
||||
576 1 432000
|
||||
576 1 456000
|
||||
576 1 480000
|
||||
576 1 504000
|
||||
576 1 528000
|
||||
576 1 552000
|
||||
576 1 576000
|
||||
576 1 600000
|
||||
576 1 624000
|
||||
576 1 648000
|
||||
576 1 672000
|
||||
576 1 696000
|
||||
576 1 720000
|
||||
576 1 744000
|
||||
576 1 768000
|
||||
576 1 792000
|
||||
576 1 816000
|
||||
576 1 840000
|
||||
576 1 864000
|
||||
576 1 888000
|
||||
576 1 912000
|
||||
576 1 936000
|
||||
576 1 960000
|
||||
576 1 984000
|
||||
576 1 1008000
|
||||
576 1 1032000
|
||||
576 1 1056000
|
||||
576 1 1080000
|
||||
576 1 1104000
|
||||
576 1 1128000
|
||||
576 1 1152000
|
||||
576 1 1176000
|
||||
576 1 1200000
|
||||
576 1 1224000
|
||||
576 1 1248000
|
||||
576 1 1272000
|
||||
576 1 1296000
|
||||
576 1 1320000
|
||||
576 1 1344000
|
||||
576 1 1368000
|
||||
576 1 1392000
|
||||
576 1 1416000
|
||||
576 1 1440000
|
||||
576 1 1464000
|
||||
576 1 1488000
|
||||
576 1 1512000
|
||||
576 1 1536000
|
||||
576 1 1560000
|
||||
576 1 1584000
|
||||
576 1 1608000
|
||||
576 1 1632000
|
||||
576 1 1656000
|
||||
576 1 1680000
|
||||
576 1 1704000
|
||||
576 1 1728000
|
||||
576 1 1752000
|
||||
576 1 1776000
|
||||
576 1 1800000
|
||||
576 1 1824000
|
||||
576 1 1848000
|
||||
576 1 1872000
|
||||
576 1 1896000
|
||||
576 1 1920000
|
||||
576 1 1944000
|
||||
576 1 1968000
|
||||
576 1 1992000
|
||||
576 1 2016000
|
||||
576 1 2040000
|
||||
576 1 2064000
|
||||
576 1 2088000
|
||||
576 1 2112000
|
||||
576 1 2136000
|
||||
576 1 2160000
|
||||
576 1 2184000
|
||||
576 1 2208000
|
||||
576 1 2232000
|
||||
576 1 2256000
|
||||
576 1 2280000
|
||||
576 1 2304000
|
||||
576 1 2328000
|
||||
576 1 2352000
|
||||
576 1 2376000
|
||||
576 1 2400000
|
||||
576 1 2424000
|
||||
576 1 2448000
|
||||
576 1 2472000
|
||||
576 1 2496000
|
||||
576 1 2520000
|
||||
576 1 2544000
|
||||
576 1 2568000
|
||||
576 1 2592000
|
||||
576 1 2616000
|
||||
576 1 2640000
|
||||
576 1 2664000
|
||||
576 1 2688000
|
||||
576 1 2712000
|
||||
576 1 2736000
|
||||
576 1 2760000
|
||||
576 1 2784000
|
||||
576 1 2808000
|
||||
576 1 2832000
|
||||
576 1 2856000
|
||||
576 1 2880000
|
||||
576 1 2904000
|
||||
576 1 2928000
|
||||
576 1 2952000
|
||||
576 1 2976000
|
||||
576 1 3000000
|
||||
576 1 3024000
|
||||
576 1 3048000
|
||||
576 1 3072000
|
||||
576 1 3096000
|
||||
576 1 3120000
|
||||
576 1 3144000
|
||||
576 1 3168000
|
||||
576 1 3192000
|
||||
576 1 3216000
|
||||
576 1 3240000
|
||||
576 1 3264000
|
||||
576 1 3288000
|
||||
576 1 3312000
|
||||
576 1 3336000
|
||||
576 1 3360000
|
||||
576 1 3384000
|
||||
576 1 3408000
|
||||
576 1 3432000
|
||||
576 1 3456000
|
||||
576 1 3480000
|
||||
576 1 3504000
|
||||
576 1 3528000
|
||||
576 1 3552000
|
||||
576 1 3576000
|
||||
576 1 3600000
|
||||
576 1 3624000
|
||||
576 1 3648000
|
||||
576 1 3672000
|
||||
576 1 3696000
|
||||
576 1 3720000
|
||||
576 1 3744000
|
||||
576 1 3768000
|
||||
576 1 3792000
|
||||
576 1 3816000
|
||||
576 1 3840000
|
||||
576 1 3864000
|
||||
576 1 3888000
|
||||
576 1 3912000
|
||||
576 1 3936000
|
||||
576 1 3960000
|
||||
576 1 3984000
|
||||
576 1 4008000
|
||||
576 1 4032000
|
||||
576 1 4056000
|
||||
576 1 4080000
|
||||
576 1 4104000
|
||||
576 1 4128000
|
||||
576 1 4152000
|
||||
576 1 4176000
|
||||
576 1 4200000
|
||||
576 1 4224000
|
||||
576 1 4248000
|
||||
576 1 4272000
|
||||
576 1 4296000
|
||||
576 1 4320000
|
||||
576 1 4344000
|
||||
576 1 4368000
|
||||
576 1 4392000
|
||||
576 1 4416000
|
||||
576 1 4440000
|
||||
576 1 4464000
|
||||
576 1 4488000
|
||||
576 1 4512000
|
||||
576 1 4536000
|
||||
576 1 4560000
|
||||
576 1 4584000
|
||||
576 1 4608000
|
||||
576 1 4632000
|
||||
576 1 4656000
|
||||
576 1 4680000
|
||||
576 1 4704000
|
||||
576 1 4728000
|
||||
576 1 4752000
|
||||
576 1 4776000
|
||||
576 1 4800000
|
||||
576 1 4824000
|
||||
576 1 4848000
|
||||
576 1 4872000
|
||||
576 1 4896000
|
||||
576 1 4920000
|
||||
576 1 4944000
|
||||
576 1 4968000
|
||||
576 1 4992000
|
||||
576 1 5016000
|
||||
576 1 5040000
|
||||
576 1 5064000
|
||||
576 1 5088000
|
||||
576 1 5112000
|
||||
576 1 5136000
|
||||
576 1 5160000
|
||||
576 1 5184000
|
||||
576 1 5208000
|
||||
576 1 5232000
|
||||
576 1 5256000
|
||||
576 1 5280000
|
||||
576 1 5304000
|
||||
576 1 5328000
|
||||
576 1 5352000
|
||||
576 1 5376000
|
||||
576 1 5400000
|
||||
576 1 5424000
|
||||
576 1 5448000
|
||||
576 1 5472000
|
||||
576 1 5496000
|
||||
576 1 5520000
|
||||
576 1 5544000
|
||||
576 1 5568000
|
||||
576 1 5592000
|
||||
576 1 5616000
|
||||
576 1 5640000
|
||||
576 1 5664000
|
||||
576 1 5688000
|
||||
576 1 5712000
|
||||
576 1 5736000
|
||||
576 1 5760000
|
||||
576 1 5784000
|
||||
576 1 5808000
|
||||
576 1 5832000
|
||||
576 1 5856000
|
||||
576 1 5880000
|
||||
576 1 5904000
|
||||
576 1 5928000
|
||||
576 1 5952000
|
||||
576 1 5976000
|
||||
576 1 6000000
|
||||
576 1 6024000
|
||||
576 1 6048000
|
||||
576 1 6072000
|
||||
576 1 6096000
|
||||
576 1 6120000
|
||||
576 1 6144000
|
||||
576 1 6168000
|
||||
576 1 6192000
|
||||
576 1 6216000
|
||||
576 1 6240000
|
||||
576 1 6264000
|
||||
576 1 6288000
|
||||
576 1 6312000
|
||||
576 1 6336000
|
||||
576 1 6360000
|
||||
576 1 6384000
|
||||
576 1 6408000
|
||||
576 1 6432000
|
||||
576 1 6456000
|
||||
576 1 6480000
|
||||
576 1 6504000
|
||||
576 1 6528000
|
||||
576 1 6552000
|
||||
576 1 6576000
|
||||
576 1 6600000
|
||||
576 1 6624000
|
||||
576 1 6648000
|
||||
576 1 6672000
|
||||
576 1 6696000
|
||||
576 1 6720000
|
||||
576 1 6744000
|
||||
576 1 6768000
|
||||
576 1 6792000
|
||||
576 1 6816000
|
||||
576 1 6840000
|
||||
576 1 6864000
|
||||
576 1 6888000
|
||||
576 1 6912000
|
||||
576 1 6936000
|
||||
576 1 6960000
|
||||
576 1 6984000
|
||||
576 1 7008000
|
||||
576 1 7032000
|
||||
576 1 7056000
|
||||
576 1 7080000
|
||||
576 1 7104000
|
||||
576 1 7128000
|
||||
576 1 7152000
|
||||
576 1 7176000
|
||||
576 1 7200000
|
||||
576 1 7224000
|
||||
576 1 7248000
|
||||
576 1 7272000
|
||||
576 1 7296000
|
||||
576 1 7320000
|
||||
576 1 7344000
|
||||
576 1 7368000
|
||||
576 1 7392000
|
||||
576 1 7416000
|
||||
576 1 7440000
|
||||
576 1 7464000
|
||||
576 1 7488000
|
||||
576 1 7512000
|
||||
576 1 7536000
|
||||
576 1 7560000
|
||||
576 1 7584000
|
||||
576 1 7608000
|
||||
576 1 7632000
|
||||
576 1 7656000
|
||||
576 1 7680000
|
||||
576 1 7704000
|
||||
576 1 7728000
|
||||
576 1 7752000
|
||||
576 1 7776000
|
||||
576 1 7800000
|
||||
576 1 7824000
|
||||
576 1 7848000
|
||||
576 1 7872000
|
||||
576 1 7896000
|
||||
576 1 7920000
|
||||
576 1 7944000
|
||||
576 1 7968000
|
||||
576 1 7992000
|
||||
576 1 8016000
|
||||
576 1 8040000
|
||||
576 1 8064000
|
||||
576 1 8088000
|
||||
576 1 8112000
|
||||
576 1 8136000
|
||||
576 1 8160000
|
||||
576 1 8184000
|
||||
576 1 8208000
|
||||
576 1 8232000
|
||||
576 1 8256000
|
||||
576 1 8280000
|
||||
576 1 8304000
|
||||
576 1 8328000
|
||||
576 1 8352000
|
||||
576 1 8376000
|
||||
576 1 8400000
|
||||
576 1 8424000
|
||||
576 1 8448000
|
||||
576 1 8472000
|
||||
576 1 8496000
|
||||
576 1 8520000
|
||||
576 1 8544000
|
||||
576 1 8568000
|
||||
576 1 8592000
|
||||
576 1 8616000
|
||||
576 1 8640000
|
||||
576 1 8664000
|
||||
576 1 8688000
|
||||
576 1 8712000
|
||||
576 1 8736000
|
||||
576 1 8760000
|
||||
576 1 8784000
|
||||
576 1 8808000
|
||||
576 1 8832000
|
||||
576 1 8856000
|
||||
576 1 8880000
|
||||
576 1 8904000
|
||||
576 1 8928000
|
||||
576 1 8952000
|
||||
576 1 8976000
|
||||
576 1 9000000
|
||||
576 1 9024000
|
||||
576 1 9048000
|
||||
576 1 9072000
|
||||
576 1 9096000
|
||||
576 1 9120000
|
||||
576 1 9144000
|
||||
576 1 9168000
|
||||
576 1 9192000
|
||||
576 1 9216000
|
||||
576 1 9240000
|
||||
576 1 9264000
|
||||
576 1 9288000
|
||||
576 1 9312000
|
||||
576 1 9336000
|
||||
576 1 9360000
|
||||
576 1 9384000
|
||||
576 1 9408000
|
||||
576 1 9432000
|
||||
576 1 9456000
|
||||
576 1 9480000
|
||||
576 1 9504000
|
||||
576 1 9528000
|
||||
576 1 9552000
|
||||
576 1 9576000
|
||||
576 1 9600000
|
||||
576 1 9624000
|
||||
576 1 9648000
|
||||
576 1 9672000
|
||||
576 1 9696000
|
||||
576 1 9720000
|
||||
576 1 9744000
|
||||
576 1 9768000
|
||||
576 1 9792000
|
||||
576 1 9816000
|
||||
576 1 9840000
|
||||
576 1 9864000
|
||||
576 1 9888000
|
||||
576 1 9912000
|
||||
BIN
media/res/bbb_mp3_stereo_192kbps_48000hz.mp3
Normal file
BIN
media/res/bbb_mp3_stereo_192kbps_48000hz.mp3
Normal file
Binary file not shown.
BIN
media/res/bbb_raw_1ch_16khz_s16le.raw
Normal file
BIN
media/res/bbb_raw_1ch_16khz_s16le.raw
Normal file
Binary file not shown.
BIN
media/res/bbb_raw_1ch_8khz_s16le.raw
Normal file
BIN
media/res/bbb_raw_1ch_8khz_s16le.raw
Normal file
Binary file not shown.
BIN
media/res/bbb_raw_2ch_48khz_s16le.raw
Normal file
BIN
media/res/bbb_raw_2ch_48khz_s16le.raw
Normal file
Binary file not shown.
BIN
media/res/sine_amrnb_1ch_12kbps_8000hz.amrnb
Normal file
BIN
media/res/sine_amrnb_1ch_12kbps_8000hz.amrnb
Normal file
Binary file not shown.
833
media/res/sine_amrnb_1ch_12kbps_8000hz.info
Normal file
833
media/res/sine_amrnb_1ch_12kbps_8000hz.info
Normal file
@@ -0,0 +1,833 @@
|
||||
32 1 0
|
||||
32 1 20000
|
||||
32 1 40000
|
||||
32 1 60000
|
||||
32 1 80000
|
||||
32 1 100000
|
||||
32 1 120000
|
||||
32 1 140000
|
||||
32 1 160000
|
||||
32 1 180000
|
||||
32 1 200000
|
||||
32 1 220000
|
||||
32 1 240000
|
||||
32 1 260000
|
||||
32 1 280000
|
||||
32 1 300000
|
||||
32 1 320000
|
||||
32 1 340000
|
||||
32 1 360000
|
||||
32 1 380000
|
||||
32 1 400000
|
||||
32 1 420000
|
||||
32 1 440000
|
||||
32 1 460000
|
||||
32 1 480000
|
||||
32 1 500000
|
||||
32 1 520000
|
||||
32 1 540000
|
||||
32 1 560000
|
||||
32 1 580000
|
||||
32 1 600000
|
||||
32 1 620000
|
||||
32 1 640000
|
||||
32 1 660000
|
||||
32 1 680000
|
||||
32 1 700000
|
||||
32 1 720000
|
||||
32 1 740000
|
||||
32 1 760000
|
||||
32 1 780000
|
||||
32 1 800000
|
||||
32 1 820000
|
||||
32 1 840000
|
||||
32 1 860000
|
||||
32 1 880000
|
||||
32 1 900000
|
||||
32 1 920000
|
||||
32 1 940000
|
||||
32 1 960000
|
||||
32 1 980000
|
||||
32 1 1000000
|
||||
32 1 1020000
|
||||
32 1 1040000
|
||||
32 1 1060000
|
||||
32 1 1080000
|
||||
32 1 1100000
|
||||
32 1 1120000
|
||||
32 1 1140000
|
||||
32 1 1160000
|
||||
32 1 1180000
|
||||
32 1 1200000
|
||||
32 1 1220000
|
||||
32 1 1240000
|
||||
32 1 1260000
|
||||
32 1 1280000
|
||||
32 1 1300000
|
||||
32 1 1320000
|
||||
32 1 1340000
|
||||
32 1 1360000
|
||||
32 1 1380000
|
||||
32 1 1400000
|
||||
32 1 1420000
|
||||
32 1 1440000
|
||||
32 1 1460000
|
||||
32 1 1480000
|
||||
32 1 1500000
|
||||
32 1 1520000
|
||||
32 1 1540000
|
||||
32 1 1560000
|
||||
32 1 1580000
|
||||
32 1 1600000
|
||||
32 1 1620000
|
||||
32 1 1640000
|
||||
32 1 1660000
|
||||
32 1 1680000
|
||||
32 1 1700000
|
||||
32 1 1720000
|
||||
32 1 1740000
|
||||
32 1 1760000
|
||||
32 1 1780000
|
||||
32 1 1800000
|
||||
32 1 1820000
|
||||
32 1 1840000
|
||||
32 1 1860000
|
||||
32 1 1880000
|
||||
32 1 1900000
|
||||
32 1 1920000
|
||||
32 1 1940000
|
||||
32 1 1960000
|
||||
32 1 1980000
|
||||
32 1 2000000
|
||||
32 1 2020000
|
||||
32 1 2040000
|
||||
32 1 2060000
|
||||
32 1 2080000
|
||||
32 1 2100000
|
||||
32 1 2120000
|
||||
32 1 2140000
|
||||
32 1 2160000
|
||||
32 1 2180000
|
||||
32 1 2200000
|
||||
32 1 2220000
|
||||
32 1 2240000
|
||||
32 1 2260000
|
||||
32 1 2280000
|
||||
32 1 2300000
|
||||
32 1 2320000
|
||||
32 1 2340000
|
||||
32 1 2360000
|
||||
32 1 2380000
|
||||
32 1 2400000
|
||||
32 1 2420000
|
||||
32 1 2440000
|
||||
32 1 2460000
|
||||
32 1 2480000
|
||||
32 1 2500000
|
||||
32 1 2520000
|
||||
32 1 2540000
|
||||
32 1 2560000
|
||||
32 1 2580000
|
||||
32 1 2600000
|
||||
32 1 2620000
|
||||
32 1 2640000
|
||||
32 1 2660000
|
||||
32 1 2680000
|
||||
32 1 2700000
|
||||
32 1 2720000
|
||||
32 1 2740000
|
||||
32 1 2760000
|
||||
32 1 2780000
|
||||
32 1 2800000
|
||||
32 1 2820000
|
||||
32 1 2840000
|
||||
32 1 2860000
|
||||
32 1 2880000
|
||||
32 1 2900000
|
||||
32 1 2920000
|
||||
32 1 2940000
|
||||
32 1 2960000
|
||||
32 1 2980000
|
||||
32 1 3000000
|
||||
32 1 3020000
|
||||
32 1 3040000
|
||||
32 1 3060000
|
||||
32 1 3080000
|
||||
32 1 3100000
|
||||
32 1 3120000
|
||||
32 1 3140000
|
||||
32 1 3160000
|
||||
32 1 3180000
|
||||
32 1 3200000
|
||||
32 1 3220000
|
||||
32 1 3240000
|
||||
32 1 3260000
|
||||
32 1 3280000
|
||||
32 1 3300000
|
||||
32 1 3320000
|
||||
32 1 3340000
|
||||
32 1 3360000
|
||||
32 1 3380000
|
||||
32 1 3400000
|
||||
32 1 3420000
|
||||
32 1 3440000
|
||||
32 1 3460000
|
||||
32 1 3480000
|
||||
32 1 3500000
|
||||
32 1 3520000
|
||||
32 1 3540000
|
||||
32 1 3560000
|
||||
32 1 3580000
|
||||
32 1 3600000
|
||||
32 1 3620000
|
||||
32 1 3640000
|
||||
32 1 3660000
|
||||
32 1 3680000
|
||||
32 1 3700000
|
||||
32 1 3720000
|
||||
32 1 3740000
|
||||
32 1 3760000
|
||||
32 1 3780000
|
||||
32 1 3800000
|
||||
32 1 3820000
|
||||
32 1 3840000
|
||||
32 1 3860000
|
||||
32 1 3880000
|
||||
32 1 3900000
|
||||
32 1 3920000
|
||||
32 1 3940000
|
||||
32 1 3960000
|
||||
32 1 3980000
|
||||
32 1 4000000
|
||||
32 1 4020000
|
||||
32 1 4040000
|
||||
32 1 4060000
|
||||
32 1 4080000
|
||||
32 1 4100000
|
||||
32 1 4120000
|
||||
32 1 4140000
|
||||
32 1 4160000
|
||||
32 1 4180000
|
||||
32 1 4200000
|
||||
32 1 4220000
|
||||
32 1 4240000
|
||||
32 1 4260000
|
||||
32 1 4280000
|
||||
32 1 4300000
|
||||
32 1 4320000
|
||||
32 1 4340000
|
||||
32 1 4360000
|
||||
32 1 4380000
|
||||
32 1 4400000
|
||||
32 1 4420000
|
||||
32 1 4440000
|
||||
32 1 4460000
|
||||
32 1 4480000
|
||||
32 1 4500000
|
||||
32 1 4520000
|
||||
32 1 4540000
|
||||
32 1 4560000
|
||||
32 1 4580000
|
||||
32 1 4600000
|
||||
32 1 4620000
|
||||
32 1 4640000
|
||||
32 1 4660000
|
||||
32 1 4680000
|
||||
32 1 4700000
|
||||
32 1 4720000
|
||||
32 1 4740000
|
||||
32 1 4760000
|
||||
32 1 4780000
|
||||
32 1 4800000
|
||||
32 1 4820000
|
||||
32 1 4840000
|
||||
32 1 4860000
|
||||
32 1 4880000
|
||||
32 1 4900000
|
||||
32 1 4920000
|
||||
32 1 4940000
|
||||
32 1 4960000
|
||||
32 1 4980000
|
||||
32 1 5000000
|
||||
32 1 5020000
|
||||
32 1 5040000
|
||||
32 1 5060000
|
||||
32 1 5080000
|
||||
32 1 5100000
|
||||
32 1 5120000
|
||||
32 1 5140000
|
||||
32 1 5160000
|
||||
32 1 5180000
|
||||
32 1 5200000
|
||||
32 1 5220000
|
||||
32 1 5240000
|
||||
32 1 5260000
|
||||
32 1 5280000
|
||||
32 1 5300000
|
||||
32 1 5320000
|
||||
32 1 5340000
|
||||
32 1 5360000
|
||||
32 1 5380000
|
||||
32 1 5400000
|
||||
32 1 5420000
|
||||
32 1 5440000
|
||||
32 1 5460000
|
||||
32 1 5480000
|
||||
32 1 5500000
|
||||
32 1 5520000
|
||||
32 1 5540000
|
||||
32 1 5560000
|
||||
32 1 5580000
|
||||
32 1 5600000
|
||||
32 1 5620000
|
||||
32 1 5640000
|
||||
32 1 5660000
|
||||
32 1 5680000
|
||||
32 1 5700000
|
||||
32 1 5720000
|
||||
32 1 5740000
|
||||
32 1 5760000
|
||||
32 1 5780000
|
||||
32 1 5800000
|
||||
32 1 5820000
|
||||
32 1 5840000
|
||||
32 1 5860000
|
||||
32 1 5880000
|
||||
32 1 5900000
|
||||
32 1 5920000
|
||||
32 1 5940000
|
||||
32 1 5960000
|
||||
32 1 5980000
|
||||
32 1 6000000
|
||||
32 1 6020000
|
||||
32 1 6040000
|
||||
32 1 6060000
|
||||
32 1 6080000
|
||||
32 1 6100000
|
||||
32 1 6120000
|
||||
32 1 6140000
|
||||
32 1 6160000
|
||||
32 1 6180000
|
||||
32 1 6200000
|
||||
32 1 6220000
|
||||
32 1 6240000
|
||||
32 1 6260000
|
||||
32 1 6280000
|
||||
32 1 6300000
|
||||
32 1 6320000
|
||||
32 1 6340000
|
||||
32 1 6360000
|
||||
32 1 6380000
|
||||
32 1 6400000
|
||||
32 1 6420000
|
||||
32 1 6440000
|
||||
32 1 6460000
|
||||
32 1 6480000
|
||||
32 1 6500000
|
||||
32 1 6520000
|
||||
32 1 6540000
|
||||
32 1 6560000
|
||||
32 1 6580000
|
||||
32 1 6600000
|
||||
32 1 6620000
|
||||
32 1 6640000
|
||||
32 1 6660000
|
||||
32 1 6680000
|
||||
32 1 6700000
|
||||
32 1 6720000
|
||||
32 1 6740000
|
||||
32 1 6760000
|
||||
32 1 6780000
|
||||
32 1 6800000
|
||||
32 1 6820000
|
||||
32 1 6840000
|
||||
32 1 6860000
|
||||
32 1 6880000
|
||||
32 1 6900000
|
||||
32 1 6920000
|
||||
32 1 6940000
|
||||
32 1 6960000
|
||||
32 1 6980000
|
||||
32 1 7000000
|
||||
32 1 7020000
|
||||
32 1 7040000
|
||||
32 1 7060000
|
||||
32 1 7080000
|
||||
32 1 7100000
|
||||
32 1 7120000
|
||||
32 1 7140000
|
||||
32 1 7160000
|
||||
32 1 7180000
|
||||
32 1 7200000
|
||||
32 1 7220000
|
||||
32 1 7240000
|
||||
32 1 7260000
|
||||
32 1 7280000
|
||||
32 1 7300000
|
||||
32 1 7320000
|
||||
32 1 7340000
|
||||
32 1 7360000
|
||||
32 1 7380000
|
||||
32 1 7400000
|
||||
32 1 7420000
|
||||
32 1 7440000
|
||||
32 1 7460000
|
||||
32 1 7480000
|
||||
32 1 7500000
|
||||
32 1 7520000
|
||||
32 1 7540000
|
||||
32 1 7560000
|
||||
32 1 7580000
|
||||
32 1 7600000
|
||||
32 1 7620000
|
||||
32 1 7640000
|
||||
32 1 7660000
|
||||
32 1 7680000
|
||||
32 1 7700000
|
||||
32 1 7720000
|
||||
32 1 7740000
|
||||
32 1 7760000
|
||||
32 1 7780000
|
||||
32 1 7800000
|
||||
32 1 7820000
|
||||
32 1 7840000
|
||||
32 1 7860000
|
||||
32 1 7880000
|
||||
32 1 7900000
|
||||
32 1 7920000
|
||||
32 1 7940000
|
||||
32 1 7960000
|
||||
32 1 7980000
|
||||
32 1 8000000
|
||||
32 1 8020000
|
||||
32 1 8040000
|
||||
32 1 8060000
|
||||
32 1 8080000
|
||||
32 1 8100000
|
||||
32 1 8120000
|
||||
32 1 8140000
|
||||
32 1 8160000
|
||||
32 1 8180000
|
||||
32 1 8200000
|
||||
32 1 8220000
|
||||
32 1 8240000
|
||||
32 1 8260000
|
||||
32 1 8280000
|
||||
32 1 8300000
|
||||
32 1 8320000
|
||||
32 1 8340000
|
||||
32 1 8360000
|
||||
32 1 8380000
|
||||
32 1 8400000
|
||||
32 1 8420000
|
||||
32 1 8440000
|
||||
32 1 8460000
|
||||
32 1 8480000
|
||||
32 1 8500000
|
||||
32 1 8520000
|
||||
32 1 8540000
|
||||
32 1 8560000
|
||||
32 1 8580000
|
||||
32 1 8600000
|
||||
32 1 8620000
|
||||
32 1 8640000
|
||||
32 1 8660000
|
||||
32 1 8680000
|
||||
32 1 8700000
|
||||
32 1 8720000
|
||||
32 1 8740000
|
||||
32 1 8760000
|
||||
32 1 8780000
|
||||
32 1 8800000
|
||||
32 1 8820000
|
||||
32 1 8840000
|
||||
32 1 8860000
|
||||
32 1 8880000
|
||||
32 1 8900000
|
||||
32 1 8920000
|
||||
32 1 8940000
|
||||
32 1 8960000
|
||||
32 1 8980000
|
||||
32 1 9000000
|
||||
32 1 9020000
|
||||
32 1 9040000
|
||||
32 1 9060000
|
||||
32 1 9080000
|
||||
32 1 9100000
|
||||
32 1 9120000
|
||||
32 1 9140000
|
||||
32 1 9160000
|
||||
32 1 9180000
|
||||
32 1 9200000
|
||||
32 1 9220000
|
||||
32 1 9240000
|
||||
32 1 9260000
|
||||
32 1 9280000
|
||||
32 1 9300000
|
||||
32 1 9320000
|
||||
32 1 9340000
|
||||
32 1 9360000
|
||||
32 1 9380000
|
||||
32 1 9400000
|
||||
32 1 9420000
|
||||
32 1 9440000
|
||||
32 1 9460000
|
||||
32 1 9480000
|
||||
32 1 9500000
|
||||
32 1 9520000
|
||||
32 1 9540000
|
||||
32 1 9560000
|
||||
32 1 9580000
|
||||
32 1 9600000
|
||||
32 1 9620000
|
||||
32 1 9640000
|
||||
32 1 9660000
|
||||
32 1 9680000
|
||||
32 1 9700000
|
||||
32 1 9720000
|
||||
32 1 9740000
|
||||
32 1 9760000
|
||||
32 1 9780000
|
||||
32 1 9800000
|
||||
32 1 9820000
|
||||
32 1 9840000
|
||||
32 1 9860000
|
||||
32 1 9880000
|
||||
32 1 9900000
|
||||
32 1 9920000
|
||||
32 1 9940000
|
||||
32 1 9960000
|
||||
32 1 9980000
|
||||
32 1 10000000
|
||||
32 1 10020000
|
||||
32 1 10040000
|
||||
32 1 10060000
|
||||
32 1 10080000
|
||||
32 1 10100000
|
||||
32 1 10120000
|
||||
32 1 10140000
|
||||
32 1 10160000
|
||||
32 1 10180000
|
||||
32 1 10200000
|
||||
32 1 10220000
|
||||
32 1 10240000
|
||||
32 1 10260000
|
||||
32 1 10280000
|
||||
32 1 10300000
|
||||
32 1 10320000
|
||||
32 1 10340000
|
||||
32 1 10360000
|
||||
32 1 10380000
|
||||
32 1 10400000
|
||||
32 1 10420000
|
||||
32 1 10440000
|
||||
32 1 10460000
|
||||
32 1 10480000
|
||||
32 1 10500000
|
||||
32 1 10520000
|
||||
32 1 10540000
|
||||
32 1 10560000
|
||||
32 1 10580000
|
||||
32 1 10600000
|
||||
32 1 10620000
|
||||
32 1 10640000
|
||||
32 1 10660000
|
||||
32 1 10680000
|
||||
32 1 10700000
|
||||
32 1 10720000
|
||||
32 1 10740000
|
||||
32 1 10760000
|
||||
32 1 10780000
|
||||
32 1 10800000
|
||||
32 1 10820000
|
||||
32 1 10840000
|
||||
32 1 10860000
|
||||
32 1 10880000
|
||||
32 1 10900000
|
||||
32 1 10920000
|
||||
32 1 10940000
|
||||
32 1 10960000
|
||||
32 1 10980000
|
||||
32 1 11000000
|
||||
32 1 11020000
|
||||
32 1 11040000
|
||||
32 1 11060000
|
||||
32 1 11080000
|
||||
32 1 11100000
|
||||
32 1 11120000
|
||||
32 1 11140000
|
||||
32 1 11160000
|
||||
32 1 11180000
|
||||
32 1 11200000
|
||||
32 1 11220000
|
||||
32 1 11240000
|
||||
32 1 11260000
|
||||
32 1 11280000
|
||||
32 1 11300000
|
||||
32 1 11320000
|
||||
32 1 11340000
|
||||
32 1 11360000
|
||||
32 1 11380000
|
||||
32 1 11400000
|
||||
32 1 11420000
|
||||
32 1 11440000
|
||||
32 1 11460000
|
||||
32 1 11480000
|
||||
32 1 11500000
|
||||
32 1 11520000
|
||||
32 1 11540000
|
||||
32 1 11560000
|
||||
32 1 11580000
|
||||
32 1 11600000
|
||||
32 1 11620000
|
||||
32 1 11640000
|
||||
32 1 11660000
|
||||
32 1 11680000
|
||||
32 1 11700000
|
||||
32 1 11720000
|
||||
32 1 11740000
|
||||
32 1 11760000
|
||||
32 1 11780000
|
||||
32 1 11800000
|
||||
32 1 11820000
|
||||
32 1 11840000
|
||||
32 1 11860000
|
||||
32 1 11880000
|
||||
32 1 11900000
|
||||
32 1 11920000
|
||||
32 1 11940000
|
||||
32 1 11960000
|
||||
32 1 11980000
|
||||
32 1 12000000
|
||||
32 1 12020000
|
||||
32 1 12040000
|
||||
32 1 12060000
|
||||
32 1 12080000
|
||||
32 1 12100000
|
||||
32 1 12120000
|
||||
32 1 12140000
|
||||
32 1 12160000
|
||||
32 1 12180000
|
||||
32 1 12200000
|
||||
32 1 12220000
|
||||
32 1 12240000
|
||||
32 1 12260000
|
||||
32 1 12280000
|
||||
32 1 12300000
|
||||
32 1 12320000
|
||||
32 1 12340000
|
||||
32 1 12360000
|
||||
32 1 12380000
|
||||
32 1 12400000
|
||||
32 1 12420000
|
||||
32 1 12440000
|
||||
32 1 12460000
|
||||
32 1 12480000
|
||||
32 1 12500000
|
||||
32 1 12520000
|
||||
32 1 12540000
|
||||
32 1 12560000
|
||||
32 1 12580000
|
||||
32 1 12600000
|
||||
32 1 12620000
|
||||
32 1 12640000
|
||||
32 1 12660000
|
||||
32 1 12680000
|
||||
32 1 12700000
|
||||
32 1 12720000
|
||||
32 1 12740000
|
||||
32 1 12760000
|
||||
32 1 12780000
|
||||
32 1 12800000
|
||||
32 1 12820000
|
||||
32 1 12840000
|
||||
32 1 12860000
|
||||
32 1 12880000
|
||||
32 1 12900000
|
||||
32 1 12920000
|
||||
32 1 12940000
|
||||
32 1 12960000
|
||||
32 1 12980000
|
||||
32 1 13000000
|
||||
32 1 13020000
|
||||
32 1 13040000
|
||||
32 1 13060000
|
||||
32 1 13080000
|
||||
32 1 13100000
|
||||
32 1 13120000
|
||||
32 1 13140000
|
||||
32 1 13160000
|
||||
32 1 13180000
|
||||
32 1 13200000
|
||||
32 1 13220000
|
||||
32 1 13240000
|
||||
32 1 13260000
|
||||
32 1 13280000
|
||||
32 1 13300000
|
||||
32 1 13320000
|
||||
32 1 13340000
|
||||
32 1 13360000
|
||||
32 1 13380000
|
||||
32 1 13400000
|
||||
32 1 13420000
|
||||
32 1 13440000
|
||||
32 1 13460000
|
||||
32 1 13480000
|
||||
32 1 13500000
|
||||
32 1 13520000
|
||||
32 1 13540000
|
||||
32 1 13560000
|
||||
32 1 13580000
|
||||
32 1 13600000
|
||||
32 1 13620000
|
||||
32 1 13640000
|
||||
32 1 13660000
|
||||
32 1 13680000
|
||||
32 1 13700000
|
||||
32 1 13720000
|
||||
32 1 13740000
|
||||
32 1 13760000
|
||||
32 1 13780000
|
||||
32 1 13800000
|
||||
32 1 13820000
|
||||
32 1 13840000
|
||||
32 1 13860000
|
||||
32 1 13880000
|
||||
32 1 13900000
|
||||
32 1 13920000
|
||||
32 1 13940000
|
||||
32 1 13960000
|
||||
32 1 13980000
|
||||
32 1 14000000
|
||||
32 1 14020000
|
||||
32 1 14040000
|
||||
32 1 14060000
|
||||
32 1 14080000
|
||||
32 1 14100000
|
||||
32 1 14120000
|
||||
32 1 14140000
|
||||
32 1 14160000
|
||||
32 1 14180000
|
||||
32 1 14200000
|
||||
32 1 14220000
|
||||
32 1 14240000
|
||||
32 1 14260000
|
||||
32 1 14280000
|
||||
32 1 14300000
|
||||
32 1 14320000
|
||||
32 1 14340000
|
||||
32 1 14360000
|
||||
32 1 14380000
|
||||
32 1 14400000
|
||||
32 1 14420000
|
||||
32 1 14440000
|
||||
32 1 14460000
|
||||
32 1 14480000
|
||||
32 1 14500000
|
||||
32 1 14520000
|
||||
32 1 14540000
|
||||
32 1 14560000
|
||||
32 1 14580000
|
||||
32 1 14600000
|
||||
32 1 14620000
|
||||
32 1 14640000
|
||||
32 1 14660000
|
||||
32 1 14680000
|
||||
32 1 14700000
|
||||
32 1 14720000
|
||||
32 1 14740000
|
||||
32 1 14760000
|
||||
32 1 14780000
|
||||
32 1 14800000
|
||||
32 1 14820000
|
||||
32 1 14840000
|
||||
32 1 14860000
|
||||
32 1 14880000
|
||||
32 1 14900000
|
||||
32 1 14920000
|
||||
32 1 14940000
|
||||
32 1 14960000
|
||||
32 1 14980000
|
||||
32 1 15000000
|
||||
32 1 15020000
|
||||
32 1 15040000
|
||||
32 1 15060000
|
||||
32 1 15080000
|
||||
32 1 15100000
|
||||
32 1 15120000
|
||||
32 1 15140000
|
||||
32 1 15160000
|
||||
32 1 15180000
|
||||
32 1 15200000
|
||||
32 1 15220000
|
||||
32 1 15240000
|
||||
32 1 15260000
|
||||
32 1 15280000
|
||||
32 1 15300000
|
||||
32 1 15320000
|
||||
32 1 15340000
|
||||
32 1 15360000
|
||||
32 1 15380000
|
||||
32 1 15400000
|
||||
32 1 15420000
|
||||
32 1 15440000
|
||||
32 1 15460000
|
||||
32 1 15480000
|
||||
32 1 15500000
|
||||
32 1 15520000
|
||||
32 1 15540000
|
||||
32 1 15560000
|
||||
32 1 15580000
|
||||
32 1 15600000
|
||||
32 1 15620000
|
||||
32 1 15640000
|
||||
32 1 15660000
|
||||
32 1 15680000
|
||||
32 1 15700000
|
||||
32 1 15720000
|
||||
32 1 15740000
|
||||
32 1 15760000
|
||||
32 1 15780000
|
||||
32 1 15800000
|
||||
32 1 15820000
|
||||
32 1 15840000
|
||||
32 1 15860000
|
||||
32 1 15880000
|
||||
32 1 15900000
|
||||
32 1 15920000
|
||||
32 1 15940000
|
||||
32 1 15960000
|
||||
32 1 15980000
|
||||
32 1 16000000
|
||||
32 1 16020000
|
||||
32 1 16040000
|
||||
32 1 16060000
|
||||
32 1 16080000
|
||||
32 1 16100000
|
||||
32 1 16120000
|
||||
32 1 16140000
|
||||
32 1 16160000
|
||||
32 1 16180000
|
||||
32 1 16200000
|
||||
32 1 16220000
|
||||
32 1 16240000
|
||||
32 1 16260000
|
||||
32 1 16280000
|
||||
32 1 16300000
|
||||
32 1 16320000
|
||||
32 1 16340000
|
||||
32 1 16360000
|
||||
32 1 16380000
|
||||
32 1 16400000
|
||||
32 1 16420000
|
||||
32 1 16440000
|
||||
32 1 16460000
|
||||
32 1 16480000
|
||||
32 1 16500000
|
||||
32 1 16520000
|
||||
32 1 16540000
|
||||
32 1 16560000
|
||||
32 1 16580000
|
||||
32 1 16600000
|
||||
32 1 16620000
|
||||
32 1 16640000
|
||||
Reference in New Issue
Block a user