diff --git a/media/codec2/hidl/1.0/vts/OWNERS b/media/codec2/hidl/1.0/vts/OWNERS index 6733e0cbd1..dbe89cfa6b 100644 --- a/media/codec2/hidl/1.0/vts/OWNERS +++ b/media/codec2/hidl/1.0/vts/OWNERS @@ -5,5 +5,4 @@ taklee@google.com wonsik@google.com # VTS team -yim@google.com -zhuoyao@google.com +dshi@google.com diff --git a/media/codec2/hidl/1.0/vts/functional/Android.bp b/media/codec2/hidl/1.0/vts/functional/Android.bp new file mode 100644 index 0000000000..5f0ba7dc81 --- /dev/null +++ b/media/codec2/hidl/1.0/vts/functional/Android.bp @@ -0,0 +1,101 @@ +// +// Copyright (C) 2020 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. +// + +filegroup { + name: "media_c2_v1_audio_decode_res", + path: "res", + srcs: [ + "res/bbb_aac_stereo_128kbps_48000hz.aac", + "res/bbb_aac_stereo_128kbps_48000hz.info", + "res/bbb_aac_stereo_128kbps_48000hz_multi_frame.info", + "res/bbb_amrwb_1ch_14kbps_16000hz.amrwb", + "res/bbb_amrwb_1ch_14kbps_16000hz.info", + "res/bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info", + "res/bbb_flac_stereo_680kbps_48000hz.flac", + "res/bbb_flac_stereo_680kbps_48000hz.info", + "res/bbb_g711alaw_1ch_8khz.info", + "res/bbb_g711alaw_1ch_8khz.raw", + "res/bbb_g711mulaw_1ch_8khz.info", + "res/bbb_g711mulaw_1ch_8khz.raw", + "res/bbb_gsm_1ch_8khz_13kbps.info", + "res/bbb_gsm_1ch_8khz_13kbps.raw", + "res/bbb_mp3_stereo_192kbps_48000hz.info", + "res/bbb_mp3_stereo_192kbps_48000hz.mp3", + "res/bbb_mp3_stereo_192kbps_48000hz_multi_frame.info", + "res/bbb_opus_stereo_128kbps_48000hz.info", + "res/bbb_opus_stereo_128kbps_48000hz.opus", + "res/bbb_raw_1ch_8khz_s32le.info", + "res/bbb_raw_1ch_8khz_s32le.raw", + "res/bbb_vorbis_stereo_128kbps_48000hz.info", + "res/bbb_vorbis_stereo_128kbps_48000hz.vorbis", + "res/sine_amrnb_1ch_12kbps_8000hz.amrnb", + "res/sine_amrnb_1ch_12kbps_8000hz.info", + "res/sine_amrnb_1ch_12kbps_8000hz_multi_frame.info", + ], +} + +filegroup { + name: "media_c2_v1_audio_encode_res", + path: "res", + srcs: [ + "res/bbb_raw_2ch_48khz_s16le.raw", + "res/bbb_raw_1ch_8khz_s16le.raw", + "res/bbb_raw_1ch_16khz_s16le.raw", + ], +} + +filegroup { + name: "media_c2_v1_video_decode_res", + path: "res", + srcs: [ + "res/bbb_avc_176x144_300kbps_60fps.h264", + "res/bbb_avc_640x360_768kbps_30fps.h264", + "res/bbb_avc_176x144_300kbps_60fps.info", + "res/bbb_avc_640x360_768kbps_30fps.info", + "res/bbb_hevc_176x144_176kbps_60fps.hevc", + "res/bbb_hevc_640x360_1600kbps_30fps.hevc", + "res/bbb_hevc_176x144_176kbps_60fps.info", + "res/bbb_hevc_640x360_1600kbps_30fps.info", + "res/bbb_mpeg2_176x144_105kbps_25fps.m2v", + "res/bbb_mpeg2_352x288_1mbps_60fps.m2v", + "res/bbb_mpeg2_176x144_105kbps_25fps.info", + "res/bbb_mpeg2_352x288_1mbps_60fps.info", + "res/bbb_h263_352x288_300kbps_12fps.h263", + "res/bbb_h263_352x288_300kbps_12fps.info", + "res/bbb_mpeg4_352x288_512kbps_30fps.m4v", + "res/bbb_mpeg4_352x288_512kbps_30fps.info", + "res/bbb_vp8_176x144_240kbps_60fps.vp8", + "res/bbb_vp8_640x360_2mbps_30fps.vp8", + "res/bbb_vp8_176x144_240kbps_60fps.info", + "res/bbb_vp8_640x360_2mbps_30fps.info", + "res/bbb_vp9_176x144_285kbps_60fps.vp9", + "res/bbb_vp9_640x360_1600kbps_30fps.vp9", + "res/bbb_vp9_176x144_285kbps_60fps.info", + "res/bbb_vp9_640x360_1600kbps_30fps.info", + "res/bbb_av1_640_360.av1", + "res/bbb_av1_176_144.av1", + "res/bbb_av1_640_360.info", + "res/bbb_av1_176_144.info", + ], +} + +filegroup { + name: "media_c2_v1_video_encode_res", + path: "res", + srcs: [ + "res/bbb_352x288_420p_30fps_32frames.yuv", + ], +} \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp index 65f0d09c6b..014cbe980c 100644 --- a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp +++ b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp @@ -16,18 +16,22 @@ cc_test { name: "VtsHalMediaC2V1_0TargetAudioDecTest", + stem: "vts_media_c2_v1_0_audio_dec_test", defaults: ["VtsHalMediaC2V1_0Defaults"], srcs: [ "VtsHalMediaC2V1_0TargetAudioDecTest.cpp", - //"media_audio_hidl_test_common.cpp" ], + data: [":media_c2_v1_audio_decode_res"], + test_config: "VtsHalMediaC2V1_0TargetAudioDecTest.xml", } cc_test { name: "VtsHalMediaC2V1_0TargetAudioEncTest", + stem: "vts_media_c2_v1_0_audio_enc_test", defaults: ["VtsHalMediaC2V1_0Defaults"], srcs: [ "VtsHalMediaC2V1_0TargetAudioEncTest.cpp", - //"media_audio_hidl_test_common.cpp" ], + data: [":media_c2_v1_audio_encode_res"], + test_config: "VtsHalMediaC2V1_0TargetAudioEncTest.xml", } diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp index 20f466559d..264abba632 100644 --- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp +++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp @@ -19,21 +19,20 @@ #include #include -#include +#include #include +#include #include -#include #include -#include -#include #include #include +#include +#include +#include using android::C2AllocatorIon; -#include -#include "media_c2_audio_hidl_test_common.h" #include "media_c2_hidl_test_common.h" struct FrameInfo { @@ -42,57 +41,44 @@ struct FrameInfo { int64_t timestamp; }; +static std::vector> + kDecodeTestParameters; + +// Resource directory +static std::string sResourceDir = ""; + class LinearBuffer : public C2Buffer { - public: + public: explicit LinearBuffer(const std::shared_ptr& block) - : C2Buffer( - {block->share(block->offset(), block->size(), ::C2Fence())}) {} + : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {} }; -static ComponentTestEnvironment* gEnv = nullptr; - namespace { -class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { - private: - typedef ::testing::VtsHalHidlTargetTestBase Super; - - public: - ::std::string getTestCaseInfo() const override { - return ::std::string() + - "Component: " + gEnv->getComponent().c_str() + " | " + - "Instance: " + gEnv->getInstance().c_str() + " | " + - "Res: " + gEnv->getRes().c_str(); - } - +class Codec2AudioDecHidlTestBase : public ::testing::Test { + public: // google.codec2 Audio test setup virtual void SetUp() override { - Super::SetUp(); + getParams(); mDisableTest = false; ALOGV("Codec2AudioDecHidlTest SetUp"); mClient = android::Codec2Client::CreateFromService( - gEnv->getInstance().c_str(), - !bool(android::Codec2Client::CreateFromService("default", true))); + mInstanceName.c_str(), + !bool(android::Codec2Client::CreateFromService("default", true))); ASSERT_NE(mClient, nullptr); - mListener.reset(new CodecListener( - [this](std::list>& workItems) { - handleWorkDone(workItems); - })); + mListener.reset(new CodecListener([this](std::list>& workItems) { + handleWorkDone(workItems); + })); ASSERT_NE(mListener, nullptr); for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) { mWorkQueue.emplace_back(new C2Work); } - mClient->createComponent(gEnv->getComponent().c_str(), mListener, - &mComponent); + mClient->createComponent(mComponentName, mListener, &mComponent); ASSERT_NE(mComponent, nullptr); - std::shared_ptr store = - android::GetCodec2PlatformAllocatorStore(); - CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, - &mLinearAllocator), - C2_OK); - mLinearPool = std::make_shared(mLinearAllocator, - mBlockPoolId++); + std::shared_ptr store = android::GetCodec2PlatformAllocatorStore(); + CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator), C2_OK); + mLinearPool = std::make_shared(mLinearAllocator, mBlockPoolId++); ASSERT_NE(mLinearPool, nullptr); mCompName = unknown_comp; @@ -101,27 +87,17 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { standardComp CompName; }; const StringToName kStringToName[] = { - {"xaac", xaac}, - {"mp3", mp3}, - {"amrnb", amrnb}, - {"amrwb", amrwb}, - {"aac", aac}, - {"vorbis", vorbis}, - {"opus", opus}, - {"pcm", pcm}, - {"g711.alaw", g711alaw}, - {"g711.mlaw", g711mlaw}, - {"gsm", gsm}, - {"raw", raw}, - {"flac", flac}, + {"xaac", xaac}, {"mp3", mp3}, {"amrnb", amrnb}, + {"amrwb", amrwb}, {"aac", aac}, {"vorbis", vorbis}, + {"opus", opus}, {"pcm", pcm}, {"g711.alaw", g711alaw}, + {"g711.mlaw", g711mlaw}, {"gsm", gsm}, {"raw", raw}, + {"flac", flac}, }; - const size_t kNumStringToName = - sizeof(kStringToName) / sizeof(kStringToName[0]); + const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]); // Find the component type - std::string comp = std::string(gEnv->getComponent()); for (size_t i = 0; i < kNumStringToName; ++i) { - if (strcasestr(comp.c_str(), kStringToName[i].Name)) { + if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) { mCompName = kStringToName[i].CompName; break; } @@ -140,9 +116,11 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { mComponent->release(); mComponent = nullptr; } - Super::TearDown(); } + // Get the test parameters from GetParam call. + virtual void getParams() {} + struct outputMetaData { uint64_t timestampUs; uint32_t rangeLength; @@ -155,25 +133,27 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { // previous timestamp bool codecConfig = ((work->worklets.front()->output.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0); - if (!codecConfig && - !work->worklets.front()->output.buffers.empty()) { + if (!codecConfig && !work->worklets.front()->output.buffers.empty()) { EXPECT_GE(work->worklets.front()->output.ordinal.timestamp.peeku(), - mTimestampUs); - mTimestampUs = - work->worklets.front()->output.ordinal.timestamp.peeku(); - uint32_t rangeLength = - work->worklets.front()->output.buffers[0]->data() - .linearBlocks().front().map().get().capacity(); - //List of timestamp values and output size to calculate timestamp + mTimestampUs); + mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku(); + uint32_t rangeLength = work->worklets.front() + ->output.buffers[0] + ->data() + .linearBlocks() + .front() + .map() + .get() + .capacity(); + // List of timestamp values and output size to calculate timestamp if (mTimestampDevTest) { outputMetaData meta = {mTimestampUs, rangeLength}; oBufferMetaData.push_back(meta); } } bool mCsd = false; - workDone(mComponent, work, mFlushedIndices, mQueueLock, - mQueueCondition, mWorkQueue, mEos, mCsd, - mFramesReceived); + workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue, + mEos, mCsd, mFramesReceived); (void)mCsd; } } @@ -196,6 +176,8 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { unknown_comp, }; + std::string mInstanceName; + std::string mComponentName; bool mEos; bool mDisableTest; bool mTimestampDevTest; @@ -218,15 +200,23 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { std::shared_ptr mListener; std::shared_ptr mComponent; - protected: + protected: static void description(const std::string& description) { RecordProperty("description", description); } }; -void validateComponent( - const std::shared_ptr& component, - Codec2AudioDecHidlTest::standardComp compName, bool& disableTest) { +class Codec2AudioDecHidlTest + : public Codec2AudioDecHidlTestBase, + public ::testing::WithParamInterface> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } +}; + +void validateComponent(const std::shared_ptr& component, + Codec2AudioDecHidlTest::standardComp compName, bool& disableTest) { // Validate its a C2 Component if (component->getName().find("c2") == std::string::npos) { ALOGE("Not a c2 component"); @@ -241,14 +231,12 @@ void validateComponent( return; } std::vector> queried; - c2_status_t c2err = - component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, - C2_DONT_BLOCK, &queried); + c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, + C2_DONT_BLOCK, &queried); if (c2err != C2_OK && queried.size() == 0) { ALOGE("Query media type failed => %d", c2err); } else { - std::string inputDomain = - ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; + std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; if (inputDomain.find("audio/") == std::string::npos) { ALOGE("Expected Audio Component"); disableTest = true; @@ -266,16 +254,14 @@ void validateComponent( } // Set Default config param. -bool setupConfigParam( - const std::shared_ptr& component, - int32_t* bitStreamInfo) { +bool setupConfigParam(const std::shared_ptr& component, + int32_t* bitStreamInfo) { std::vector> failures; C2StreamSampleRateInfo::output sampleRateInfo(0u, bitStreamInfo[0]); C2StreamChannelCountInfo::output channelCountInfo(0u, bitStreamInfo[1]); std::vector configParam{&sampleRateInfo, &channelCountInfo}; - c2_status_t status = - component->config(configParam, C2_DONT_BLOCK, &failures); + c2_status_t status = component->config(configParam, C2_DONT_BLOCK, &failures); if (status == C2_OK && failures.size() == 0u) return true; return false; } @@ -283,17 +269,15 @@ bool setupConfigParam( // In decoder components, often the input parameters get updated upon // parsing the header of elementary stream. Client needs to collect this // information and reconfigure -void getInputChannelInfo( - const std::shared_ptr& component, - Codec2AudioDecHidlTest::standardComp compName, int32_t* bitStreamInfo) { +void getInputChannelInfo(const std::shared_ptr& component, + Codec2AudioDecHidlTest::standardComp compName, int32_t* bitStreamInfo) { // query nSampleRate and nChannels std::initializer_list indices{ - C2StreamSampleRateInfo::output::PARAM_TYPE, - C2StreamChannelCountInfo::output::PARAM_TYPE, + C2StreamSampleRateInfo::output::PARAM_TYPE, + C2StreamChannelCountInfo::output::PARAM_TYPE, }; std::vector> inParams; - c2_status_t status = - component->query({}, indices, C2_DONT_BLOCK, &inParams); + c2_status_t status = component->query({}, indices, C2_DONT_BLOCK, &inParams); if (status != C2_OK && inParams.size() == 0) { ALOGE("Query media type failed => %d", status); ASSERT_TRUE(false); @@ -328,8 +312,8 @@ void getInputChannelInfo( #define STREAM_COUNT 2 // LookUpTable of clips and metadata for component testing -void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL, - char* info, size_t streamIndex = 0) { +void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL, char* info, + size_t streamIndex = 0) { struct CompToURL { Codec2AudioDecHidlTest::standardComp comp; const char mURL[STREAM_COUNT][512]; @@ -338,52 +322,47 @@ void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL, ASSERT_TRUE(streamIndex < STREAM_COUNT); static const CompToURL kCompToURL[] = { - {Codec2AudioDecHidlTest::standardComp::xaac, - {"bbb_aac_stereo_128kbps_48000hz.aac", - "bbb_aac_stereo_128kbps_48000hz.aac"}, - {"bbb_aac_stereo_128kbps_48000hz.info", - "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}}, - {Codec2AudioDecHidlTest::standardComp::mp3, - {"bbb_mp3_stereo_192kbps_48000hz.mp3", - "bbb_mp3_stereo_192kbps_48000hz.mp3"}, - {"bbb_mp3_stereo_192kbps_48000hz.info", - "bbb_mp3_stereo_192kbps_48000hz_multi_frame.info"}}, - {Codec2AudioDecHidlTest::standardComp::aac, - {"bbb_aac_stereo_128kbps_48000hz.aac", - "bbb_aac_stereo_128kbps_48000hz.aac"}, - {"bbb_aac_stereo_128kbps_48000hz.info", - "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}}, - {Codec2AudioDecHidlTest::standardComp::amrnb, - {"sine_amrnb_1ch_12kbps_8000hz.amrnb", - "sine_amrnb_1ch_12kbps_8000hz.amrnb"}, - {"sine_amrnb_1ch_12kbps_8000hz.info", - "sine_amrnb_1ch_12kbps_8000hz_multi_frame.info"}}, - {Codec2AudioDecHidlTest::standardComp::amrwb, - {"bbb_amrwb_1ch_14kbps_16000hz.amrwb", - "bbb_amrwb_1ch_14kbps_16000hz.amrwb"}, - {"bbb_amrwb_1ch_14kbps_16000hz.info", - "bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info"}}, - {Codec2AudioDecHidlTest::standardComp::vorbis, - {"bbb_vorbis_stereo_128kbps_48000hz.vorbis", ""}, - {"bbb_vorbis_stereo_128kbps_48000hz.info", ""}}, - {Codec2AudioDecHidlTest::standardComp::opus, - {"bbb_opus_stereo_128kbps_48000hz.opus", ""}, - {"bbb_opus_stereo_128kbps_48000hz.info", ""}}, - {Codec2AudioDecHidlTest::standardComp::g711alaw, - {"bbb_g711alaw_1ch_8khz.raw", ""}, - {"bbb_g711alaw_1ch_8khz.info", ""}}, - {Codec2AudioDecHidlTest::standardComp::g711mlaw, - {"bbb_g711mulaw_1ch_8khz.raw", ""}, - {"bbb_g711mulaw_1ch_8khz.info", ""}}, - {Codec2AudioDecHidlTest::standardComp::gsm, - {"bbb_gsm_1ch_8khz_13kbps.raw", ""}, - {"bbb_gsm_1ch_8khz_13kbps.info", ""}}, - {Codec2AudioDecHidlTest::standardComp::raw, - {"bbb_raw_1ch_8khz_s32le.raw", ""}, - {"bbb_raw_1ch_8khz_s32le.info", ""}}, - {Codec2AudioDecHidlTest::standardComp::flac, - {"bbb_flac_stereo_680kbps_48000hz.flac", ""}, - {"bbb_flac_stereo_680kbps_48000hz.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::xaac, + {"bbb_aac_stereo_128kbps_48000hz.aac", "bbb_aac_stereo_128kbps_48000hz.aac"}, + {"bbb_aac_stereo_128kbps_48000hz.info", + "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}}, + {Codec2AudioDecHidlTest::standardComp::mp3, + {"bbb_mp3_stereo_192kbps_48000hz.mp3", "bbb_mp3_stereo_192kbps_48000hz.mp3"}, + {"bbb_mp3_stereo_192kbps_48000hz.info", + "bbb_mp3_stereo_192kbps_48000hz_multi_frame.info"}}, + {Codec2AudioDecHidlTest::standardComp::aac, + {"bbb_aac_stereo_128kbps_48000hz.aac", "bbb_aac_stereo_128kbps_48000hz.aac"}, + {"bbb_aac_stereo_128kbps_48000hz.info", + "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}}, + {Codec2AudioDecHidlTest::standardComp::amrnb, + {"sine_amrnb_1ch_12kbps_8000hz.amrnb", "sine_amrnb_1ch_12kbps_8000hz.amrnb"}, + {"sine_amrnb_1ch_12kbps_8000hz.info", + "sine_amrnb_1ch_12kbps_8000hz_multi_frame.info"}}, + {Codec2AudioDecHidlTest::standardComp::amrwb, + {"bbb_amrwb_1ch_14kbps_16000hz.amrwb", "bbb_amrwb_1ch_14kbps_16000hz.amrwb"}, + {"bbb_amrwb_1ch_14kbps_16000hz.info", + "bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info"}}, + {Codec2AudioDecHidlTest::standardComp::vorbis, + {"bbb_vorbis_stereo_128kbps_48000hz.vorbis", ""}, + {"bbb_vorbis_stereo_128kbps_48000hz.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::opus, + {"bbb_opus_stereo_128kbps_48000hz.opus", ""}, + {"bbb_opus_stereo_128kbps_48000hz.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::g711alaw, + {"bbb_g711alaw_1ch_8khz.raw", ""}, + {"bbb_g711alaw_1ch_8khz.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::g711mlaw, + {"bbb_g711mulaw_1ch_8khz.raw", ""}, + {"bbb_g711mulaw_1ch_8khz.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::gsm, + {"bbb_gsm_1ch_8khz_13kbps.raw", ""}, + {"bbb_gsm_1ch_8khz_13kbps.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::raw, + {"bbb_raw_1ch_8khz_s32le.raw", ""}, + {"bbb_raw_1ch_8khz_s32le.info", ""}}, + {Codec2AudioDecHidlTest::standardComp::flac, + {"bbb_flac_stereo_680kbps_48000hz.flac", ""}, + {"bbb_flac_stereo_680kbps_48000hz.info", ""}}, }; for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) { @@ -396,13 +375,11 @@ void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL, } void decodeNFrames(const std::shared_ptr& component, - std::mutex &queueLock, std::condition_variable& queueCondition, + std::mutex& queueLock, std::condition_variable& queueCondition, std::list>& workQueue, - std::list& flushedIndices, - std::shared_ptr& linearPool, - std::ifstream& eleStream, - android::Vector* Info, - int offset, int range, bool signalEOS = true) { + std::list& flushedIndices, std::shared_ptr& linearPool, + std::ifstream& eleStream, android::Vector* Info, int offset, + int range, bool signalEOS = true) { typedef std::unique_lock ULock; int frameID = offset; int maxRetry = 0; @@ -426,8 +403,7 @@ void decodeNFrames(const std::shared_ptr& comp } int64_t timestamp = (*Info)[frameID].timestamp; if ((*Info)[frameID].flags) flags = 1u << ((*Info)[frameID].flags - 1); - if (signalEOS && ((frameID == (int)Info->size() - 1) || - (frameID == (offset + range - 1)))) + if (signalEOS && ((frameID == (int)Info->size() - 1) || (frameID == (offset + range - 1)))) flags |= C2FrameData::FLAG_END_OF_STREAM; work->input.flags = (C2FrameData::flags_t)flags; @@ -448,9 +424,8 @@ void decodeNFrames(const std::shared_ptr& comp if (size) { std::shared_ptr block; ASSERT_EQ(C2_OK, - linearPool->fetchLinearBlock( - size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, - &block)); + linearPool->fetchLinearBlock( + size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block)); ASSERT_TRUE(block); // Write View @@ -482,45 +457,49 @@ void decodeNFrames(const std::shared_ptr& comp } } -TEST_F(Codec2AudioDecHidlTest, validateCompName) { - if (mDisableTest) return; +TEST_P(Codec2AudioDecHidlTest, validateCompName) { + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ALOGV("Checks if the given component is a valid audio component"); validateComponent(mComponent, mCompName, mDisableTest); ASSERT_EQ(mDisableTest, false); } -TEST_F(Codec2AudioDecHidlTest, configComp) { +TEST_P(Codec2AudioDecHidlTest, configComp) { description("Tests component specific configuration"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ASSERT_EQ(mComponent->start(), C2_OK); int32_t bitStreamInfo[2] = {0}; - ASSERT_NO_FATAL_FAILURE( - getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); + ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); setupConfigParam(mComponent, bitStreamInfo); ASSERT_EQ(mComponent->stop(), C2_OK); } class Codec2AudioDecDecodeTest - : public Codec2AudioDecHidlTest, - public ::testing::WithParamInterface> { + : public Codec2AudioDecHidlTestBase, + public ::testing::WithParamInterface< + std::tuple> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } }; TEST_P(Codec2AudioDecDecodeTest, DecodeTest) { description("Decodes input file"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; - uint32_t streamIndex = GetParam().first; - bool signalEOS = GetParam().second; + uint32_t streamIndex = std::stoi(std::get<2>(GetParam())); + ; + bool signalEOS = !std::get<3>(GetParam()).compare("true"); mTimestampDevTest = true; char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info, streamIndex); - if (!strcmp(mURL, gEnv->getRes().c_str())) { - ALOGV("EMPTY INPUT gEnv->getRes().c_str() %s mURL %s ", - gEnv->getRes().c_str(), mURL); + if (!strcmp(mURL, sResourceDir.c_str())) { + ALOGV("EMPTY INPUT sResourceDir.c_str() %s mURL %s ", sResourceDir.c_str(), mURL); return; } @@ -534,10 +513,8 @@ TEST_P(Codec2AudioDecDecodeTest, DecodeTest) { if (!(eleInfo >> bytesCount)) break; eleInfo >> flags; eleInfo >> timestamp; - bool codecConfig = - ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0; - if (mTimestampDevTest && !codecConfig) - mTimestampUslist.push_back(timestamp); + bool codecConfig = ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0; + if (mTimestampDevTest && !codecConfig) mTimestampUslist.push_back(timestamp); Info.push_back({bytesCount, flags, timestamp}); } eleInfo.close(); @@ -549,8 +526,7 @@ TEST_P(Codec2AudioDecDecodeTest, DecodeTest) { bitStreamInfo[0] = 8000; bitStreamInfo[1] = 1; } else { - ASSERT_NO_FATAL_FAILURE( - getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); + ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); } if (!setupConfigParam(mComponent, bitStreamInfo)) { std::cout << "[ WARN ] Test Skipped \n"; @@ -560,29 +536,25 @@ TEST_P(Codec2AudioDecDecodeTest, DecodeTest) { ALOGV("mURL : %s", mURL); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, (int)Info.size(), signalEOS)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + (int)Info.size(), signalEOS)); // If EOS is not sent, sending empty input with EOS flag size_t infoSize = Info.size(); if (!signalEOS) { - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); - ASSERT_NO_FATAL_FAILURE( - testInputBuffer(mComponent, mQueueLock, mWorkQueue, - C2FrameData::FLAG_END_OF_STREAM, false)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); + ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue, + C2FrameData::FLAG_END_OF_STREAM, false)); infoSize += 1; } // blocking call to ensures application to Wait till all the inputs are // consumed - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); eleStream.close(); if (mFramesReceived != infoSize) { ALOGE("Input buffer count and Output buffer count mismatch"); - ALOGE("framesReceived : %d inputFrames : %zu", mFramesReceived, - infoSize); + ALOGE("framesReceived : %d inputFrames : %zu", mFramesReceived, infoSize); ASSERT_TRUE(false); } ASSERT_EQ(mEos, true); @@ -590,8 +562,7 @@ TEST_P(Codec2AudioDecDecodeTest, DecodeTest) { uint64_t expTs; uint32_t samplesReceived = 0; // Update SampleRate and ChannelCount - ASSERT_NO_FATAL_FAILURE( - getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); + ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); int nSampleRate = bitStreamInfo[0]; int nChannels = bitStreamInfo[1]; std::list::iterator itIn = mTimestampUslist.begin(); @@ -614,23 +585,17 @@ TEST_P(Codec2AudioDecDecodeTest, DecodeTest) { } ASSERT_EQ(mComponent->stop(), C2_OK); } -// DecodeTest with StreamIndex and EOS / No EOS -INSTANTIATE_TEST_CASE_P(StreamIndexAndEOS, Codec2AudioDecDecodeTest, - ::testing::Values(std::make_pair(0, false), - std::make_pair(0, true), - std::make_pair(1, false), - std::make_pair(1, true))); // thumbnail test -TEST_F(Codec2AudioDecHidlTest, ThumbnailTest) { +TEST_P(Codec2AudioDecHidlTest, ThumbnailTest) { description("Test Request for thumbnail"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info); eleInfo.open(info); @@ -651,8 +616,7 @@ TEST_F(Codec2AudioDecHidlTest, ThumbnailTest) { bitStreamInfo[0] = 8000; bitStreamInfo[1] = 1; } else { - ASSERT_NO_FATAL_FAILURE( - getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); + ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); } if (!setupConfigParam(mComponent, bitStreamInfo)) { std::cout << "[ WARN ] Test Skipped \n"; @@ -672,20 +636,19 @@ TEST_F(Codec2AudioDecHidlTest, ThumbnailTest) { } while (!(flags & SYNC_FRAME)); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, i + 1)); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + i + 1)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); eleStream.close(); EXPECT_GE(mFramesReceived, 1U); ASSERT_EQ(mEos, true); ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2AudioDecHidlTest, EOSTest) { +TEST_P(Codec2AudioDecHidlTest, EOSTest) { description("Test empty input buffer with EOS flag"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; typedef std::unique_lock ULock; ASSERT_EQ(mComponent->start(), C2_OK); std::unique_ptr work; @@ -723,15 +686,15 @@ TEST_F(Codec2AudioDecHidlTest, EOSTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2AudioDecHidlTest, FlushTest) { +TEST_P(Codec2AudioDecHidlTest, FlushTest) { description("Tests Flush calls"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; typedef std::unique_lock ULock; char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info); eleInfo.open(info); @@ -753,8 +716,7 @@ TEST_F(Codec2AudioDecHidlTest, FlushTest) { bitStreamInfo[0] = 8000; bitStreamInfo[1] = 1; } else { - ASSERT_NO_FATAL_FAILURE( - getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); + ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); } if (!setupConfigParam(mComponent, bitStreamInfo)) { std::cout << "[ WARN ] Test Skipped \n"; @@ -768,29 +730,25 @@ TEST_F(Codec2AudioDecHidlTest, FlushTest) { // frame after this so that the below section can be covered for all // components uint32_t numFramesFlushed = 128; - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, numFramesFlushed, false)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + numFramesFlushed, false)); // flush std::list> flushedWork; - c2_status_t err = - mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); + c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); uint64_t frameIndex; { - //Update mFlushedIndices based on the index received from flush() + // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); frameIndex = work->input.ordinal.frameIndex.peeku(); std::list::iterator frameIndexIt = - std::find(mFlushedIndices.begin(), mFlushedIndices.end(), - frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -814,29 +772,24 @@ TEST_F(Codec2AudioDecHidlTest, FlushTest) { index++; } if (keyFrame) { - ASSERT_NO_FATAL_FAILURE( - decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, &Info, index, - (int)Info.size() - index)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, index, + (int)Info.size() - index)); } eleStream.close(); - err = - mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); + err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); { - //Update mFlushedIndices based on the index received from flush() + // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); frameIndex = work->input.ordinal.frameIndex.peeku(); std::list::iterator frameIndexIt = - std::find(mFlushedIndices.begin(), mFlushedIndices.end(), - frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -848,15 +801,15 @@ TEST_F(Codec2AudioDecHidlTest, FlushTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) { +TEST_P(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) { description("Decode with multiple empty input frames"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info); eleInfo.open(info); @@ -871,15 +824,16 @@ TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) { // and empty input frames at an interval of 5 frames. while (1) { if (!(frameId % 5)) { - if (!(frameId % 20)) flags = 32; - else flags = 0; + if (!(frameId % 20)) + flags = 32; + else + flags = 0; bytesCount = 0; } else { if (!(eleInfo >> bytesCount)) break; eleInfo >> flags; eleInfo >> timestamp; - codecConfig = flags ? - ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; + codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; } Info.push_back({bytesCount, flags, timestamp}); frameId++; @@ -890,8 +844,7 @@ TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) { bitStreamInfo[0] = 8000; bitStreamInfo[1] = 1; } else { - ASSERT_NO_FATAL_FAILURE( - getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); + ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo)); } if (!setupConfigParam(mComponent, bitStreamInfo)) { std::cout << "[ WARN ] Test Skipped \n"; @@ -901,40 +854,59 @@ TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) { ALOGV("mURL : %s", mURL); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, (int)Info.size())); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + (int)Info.size())); // blocking call to ensures application to Wait till all the inputs are // consumed if (!mEos) { ALOGV("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); } eleStream.close(); if (mFramesReceived != Info.size()) { ALOGE("Input buffer count and Output buffer count mismatch"); - ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, - Info.size()); + ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, Info.size()); ASSERT_TRUE(false); } ASSERT_EQ(mComponent->stop(), C2_OK); } +INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioDecHidlTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + +// DecodeTest with StreamIndex and EOS / No EOS +INSTANTIATE_TEST_SUITE_P(StreamIndexAndEOS, Codec2AudioDecDecodeTest, + testing::ValuesIn(kDecodeTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + } // anonymous namespace int main(int argc, char** argv) { - gEnv = new ComponentTestEnvironment(); - ::testing::AddGlobalTestEnvironment(gEnv); - ::testing::InitGoogleTest(&argc, argv); - gEnv->init(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - int status = RUN_ALL_TESTS(); - LOG(INFO) << "C2 Test result = " << status; + kTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER); + for (auto params : kTestParameters) { + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "false")); + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "true")); + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "false")); + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "true")); + } + + // Set the resource directory based on command line args. + // Test will fail to set up if the argument is not set. + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-P") == 0 && i < argc - 1) { + sResourceDir = argv[i + 1]; + break; + } } - return status; -} + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.xml b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.xml new file mode 100644 index 0000000000..a22f8cf132 --- /dev/null +++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp index ab6bfb2bd6..5f3ae41fb0 100644 --- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp +++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp @@ -19,74 +19,60 @@ #include #include +#include #include -#include #include +#include -#include #include -#include -#include #include #include +#include +#include +#include using android::C2AllocatorIon; -#include -#include "media_c2_audio_hidl_test_common.h" #include "media_c2_hidl_test_common.h" +static std::vector> + kEncodeTestParameters; + +// Resource directory +static std::string sResourceDir = ""; + class LinearBuffer : public C2Buffer { - public: + public: explicit LinearBuffer(const std::shared_ptr& block) - : C2Buffer( - {block->share(block->offset(), block->size(), ::C2Fence())}) {} + : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {} }; -static ComponentTestEnvironment* gEnv = nullptr; - namespace { -class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { - private: - typedef ::testing::VtsHalHidlTargetTestBase Super; - - public: - ::std::string getTestCaseInfo() const override { - return ::std::string() + - "Component: " + gEnv->getComponent().c_str() + " | " + - "Instance: " + gEnv->getInstance().c_str() + " | " + - "Res: " + gEnv->getRes().c_str(); - } - +class Codec2AudioEncHidlTestBase : public ::testing::Test { + public: // google.codec2 Audio test setup virtual void SetUp() override { - Super::SetUp(); + getParams(); mDisableTest = false; ALOGV("Codec2AudioEncHidlTest SetUp"); mClient = android::Codec2Client::CreateFromService( - gEnv->getInstance().c_str(), - !bool(android::Codec2Client::CreateFromService("default", true))); + mInstanceName.c_str(), + !bool(android::Codec2Client::CreateFromService("default", true))); ASSERT_NE(mClient, nullptr); - mListener.reset(new CodecListener( - [this](std::list>& workItems) { - handleWorkDone(workItems); - })); + mListener.reset(new CodecListener([this](std::list>& workItems) { + handleWorkDone(workItems); + })); ASSERT_NE(mListener, nullptr); for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) { mWorkQueue.emplace_back(new C2Work); } - mClient->createComponent(gEnv->getComponent().c_str(), mListener, - &mComponent); + mClient->createComponent(mComponentName, mListener, &mComponent); ASSERT_NE(mComponent, nullptr); - std::shared_ptr store = - android::GetCodec2PlatformAllocatorStore(); - CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, - &mLinearAllocator), - C2_OK); - mLinearPool = std::make_shared(mLinearAllocator, - mBlockPoolId++); + std::shared_ptr store = android::GetCodec2PlatformAllocatorStore(); + CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator), C2_OK); + mLinearPool = std::make_shared(mLinearAllocator, mBlockPoolId++); ASSERT_NE(mLinearPool, nullptr); mCompName = unknown_comp; @@ -95,19 +81,13 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { standardComp CompName; }; const StringToName kStringToName[] = { - {"aac", aac}, - {"flac", flac}, - {"opus", opus}, - {"amrnb", amrnb}, - {"amrwb", amrwb}, + {"aac", aac}, {"flac", flac}, {"opus", opus}, {"amrnb", amrnb}, {"amrwb", amrwb}, }; - const size_t kNumStringToName = - sizeof(kStringToName) / sizeof(kStringToName[0]); + const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]); // Find the component type - std::string comp = std::string(gEnv->getComponent()); for (size_t i = 0; i < kNumStringToName; ++i) { - if (strcasestr(comp.c_str(), kStringToName[i].Name)) { + if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) { mCompName = kStringToName[i].CompName; break; } @@ -126,15 +106,17 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { mComponent->release(); mComponent = nullptr; } - Super::TearDown(); } + + // Get the test parameters from GetParam call. + virtual void getParams() {} + // callback function to process onWorkDone received by Listener void handleWorkDone(std::list>& workItems) { for (std::unique_ptr& work : workItems) { if (!work->worklets.empty()) { - workDone(mComponent, work, mFlushedIndices, mQueueLock, - mQueueCondition, mWorkQueue, mEos, mCsd, - mFramesReceived); + workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue, + mEos, mCsd, mFramesReceived); } } } @@ -147,6 +129,8 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { unknown_comp, }; + std::string mInstanceName; + std::string mComponentName; bool mEos; bool mCsd; bool mDisableTest; @@ -167,7 +151,7 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { std::shared_ptr mListener; std::shared_ptr mComponent; - protected: + protected: static void description(const std::string& description) { RecordProperty("description", description); } @@ -176,9 +160,8 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { void getInputMaxBufSize() { int32_t bitStreamInfo[1] = {0}; std::vector> inParams; - c2_status_t status = mComponent->query( - {}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE}, C2_DONT_BLOCK, - &inParams); + c2_status_t status = mComponent->query({}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE}, + C2_DONT_BLOCK, &inParams); if (status != C2_OK && inParams.size() == 0) { ALOGE("Query MaxBufferSizeInfo failed => %d", status); ASSERT_TRUE(false); @@ -191,12 +174,19 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { } mInputMaxBufSize = bitStreamInfo[0]; } +}; +class Codec2AudioEncHidlTest + : public Codec2AudioEncHidlTestBase, + public ::testing::WithParamInterface> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } }; -void validateComponent( - const std::shared_ptr& component, - Codec2AudioEncHidlTest::standardComp compName, bool& disableTest) { +void validateComponent(const std::shared_ptr& component, + Codec2AudioEncHidlTest::standardComp compName, bool& disableTest) { // Validate its a C2 Component if (component->getName().find("c2") == std::string::npos) { ALOGE("Not a c2 component"); @@ -211,14 +201,12 @@ void validateComponent( return; } std::vector> queried; - c2_status_t c2err = - component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, - C2_DONT_BLOCK, &queried); + c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, + C2_DONT_BLOCK, &queried); if (c2err != C2_OK && queried.size() == 0) { ALOGE("Query media type failed => %d", c2err); } else { - std::string inputDomain = - ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; + std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; if (inputDomain.find("audio/") == std::string::npos) { ALOGE("Expected Audio Component"); disableTest = true; @@ -236,16 +224,14 @@ void validateComponent( } // Set Default config param. -bool setupConfigParam( - const std::shared_ptr& component, - int32_t nChannels, int32_t nSampleRate) { +bool setupConfigParam(const std::shared_ptr& component, + int32_t nChannels, int32_t nSampleRate) { std::vector> failures; C2StreamSampleRateInfo::input sampleRateInfo(0u, nSampleRate); C2StreamChannelCountInfo::input channelCountInfo(0u, nChannels); std::vector configParam{&sampleRateInfo, &channelCountInfo}; - c2_status_t status = - component->config(configParam, C2_DONT_BLOCK, &failures); + c2_status_t status = component->config(configParam, C2_DONT_BLOCK, &failures); if (status == C2_OK && failures.size() == 0u) return true; return false; } @@ -257,16 +243,11 @@ void GetURLForComponent(Codec2AudioEncHidlTest::standardComp comp, char* mURL) { const char* mURL; }; static const CompToURL kCompToURL[] = { - {Codec2AudioEncHidlTest::standardComp::aac, - "bbb_raw_2ch_48khz_s16le.raw"}, - {Codec2AudioEncHidlTest::standardComp::amrnb, - "bbb_raw_1ch_8khz_s16le.raw"}, - {Codec2AudioEncHidlTest::standardComp::amrwb, - "bbb_raw_1ch_16khz_s16le.raw"}, - {Codec2AudioEncHidlTest::standardComp::flac, - "bbb_raw_2ch_48khz_s16le.raw"}, - {Codec2AudioEncHidlTest::standardComp::opus, - "bbb_raw_2ch_48khz_s16le.raw"}, + {Codec2AudioEncHidlTest::standardComp::aac, "bbb_raw_2ch_48khz_s16le.raw"}, + {Codec2AudioEncHidlTest::standardComp::amrnb, "bbb_raw_1ch_8khz_s16le.raw"}, + {Codec2AudioEncHidlTest::standardComp::amrwb, "bbb_raw_1ch_16khz_s16le.raw"}, + {Codec2AudioEncHidlTest::standardComp::flac, "bbb_raw_2ch_48khz_s16le.raw"}, + {Codec2AudioEncHidlTest::standardComp::opus, "bbb_raw_2ch_48khz_s16le.raw"}, }; for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) { @@ -278,21 +259,18 @@ void GetURLForComponent(Codec2AudioEncHidlTest::standardComp comp, char* mURL) { } void encodeNFrames(const std::shared_ptr& component, - std::mutex &queueLock, std::condition_variable& queueCondition, + std::mutex& queueLock, std::condition_variable& queueCondition, std::list>& workQueue, - std::list& flushedIndices, - std::shared_ptr& linearPool, - std::ifstream& eleStream, uint32_t nFrames, - int32_t samplesPerFrame, int32_t nChannels, - int32_t nSampleRate, bool flushed = false, + std::list& flushedIndices, std::shared_ptr& linearPool, + std::ifstream& eleStream, uint32_t nFrames, int32_t samplesPerFrame, + int32_t nChannels, int32_t nSampleRate, bool flushed = false, bool signalEOS = true) { typedef std::unique_lock ULock; uint32_t frameID = 0; uint32_t maxRetry = 0; int bytesCount = samplesPerFrame * nChannels * 2; - int32_t timestampIncr = - (int)(((float)samplesPerFrame / nSampleRate) * 1000000); + int32_t timestampIncr = (int)(((float)samplesPerFrame / nSampleRate) * 1000000); uint64_t timestamp = 0; while (1) { if (nFrames == 0) break; @@ -312,8 +290,7 @@ void encodeNFrames(const std::shared_ptr& comp if (!work && (maxRetry >= MAX_RETRY)) { ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout"; } - if (signalEOS && (nFrames == 1)) - flags |= C2FrameData::FLAG_END_OF_STREAM; + if (signalEOS && (nFrames == 1)) flags |= C2FrameData::FLAG_END_OF_STREAM; if (flushed) { flags |= SYNC_FRAME; flushed = false; @@ -330,10 +307,9 @@ void encodeNFrames(const std::shared_ptr& comp eleStream.read(data, bytesCount); ASSERT_EQ(eleStream.gcount(), bytesCount); std::shared_ptr block; - ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock( - bytesCount, {C2MemoryUsage::CPU_READ, - C2MemoryUsage::CPU_WRITE}, - &block)); + ASSERT_EQ(C2_OK, + linearPool->fetchLinearBlock( + bytesCount, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block)); ASSERT_TRUE(block); // Write View C2WriteView view = block->map().get(); @@ -365,27 +341,33 @@ void encodeNFrames(const std::shared_ptr& comp } } -TEST_F(Codec2AudioEncHidlTest, validateCompName) { - if (mDisableTest) return; +TEST_P(Codec2AudioEncHidlTest, validateCompName) { + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ALOGV("Checks if the given component is a valid audio component"); validateComponent(mComponent, mCompName, mDisableTest); ASSERT_EQ(mDisableTest, false); } class Codec2AudioEncEncodeTest - : public Codec2AudioEncHidlTest, - public ::testing::WithParamInterface> { + : public Codec2AudioEncHidlTestBase, + public ::testing::WithParamInterface< + std::tuple> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } }; TEST_P(Codec2AudioEncEncodeTest, EncodeTest) { ALOGV("EncodeTest"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; char mURL[512]; - strcpy(mURL, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL); - bool signalEOS = GetParam().first; + bool signalEOS = !std::get<2>(GetParam()).compare("true"); // Ratio w.r.t to mInputMaxBufSize - int32_t inputMaxBufRatio = GetParam().second; + int32_t inputMaxBufRatio = std::stoi(std::get<3>(GetParam())); + ; // Setting default sampleRate int32_t nChannels = 2; @@ -414,10 +396,9 @@ TEST_P(Codec2AudioEncEncodeTest, EncodeTest) { default: ASSERT_TRUE(false); } - int32_t samplesPerFrame = - ((mInputMaxBufSize / inputMaxBufRatio) / (nChannels * 2)); - ALOGV("signalEOS %d mInputMaxBufSize %d samplesPerFrame %d", signalEOS, - mInputMaxBufSize, samplesPerFrame); + int32_t samplesPerFrame = ((mInputMaxBufSize / inputMaxBufRatio) / (nChannels * 2)); + ALOGV("signalEOS %d mInputMaxBufSize %d samplesPerFrame %d", signalEOS, mInputMaxBufSize, + samplesPerFrame); if (!setupConfigParam(mComponent, nChannels, nSampleRate)) { std::cout << "[ WARN ] Test Skipped \n"; @@ -429,26 +410,21 @@ TEST_P(Codec2AudioEncEncodeTest, EncodeTest) { eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); ALOGV("mURL : %s", mURL); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, numFrames, - samplesPerFrame, nChannels, nSampleRate, false, - signalEOS)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames( + mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, mLinearPool, + eleStream, numFrames, samplesPerFrame, nChannels, nSampleRate, false, signalEOS)); // If EOS is not sent, sending empty input with EOS flag if (!signalEOS) { - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); - ASSERT_NO_FATAL_FAILURE( - testInputBuffer(mComponent, mQueueLock, mWorkQueue, - C2FrameData::FLAG_END_OF_STREAM, false)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); + ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue, + C2FrameData::FLAG_END_OF_STREAM, false)); numFrames += 1; } // blocking call to ensures application to Wait till all the inputs are // consumed - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); eleStream.close(); if (mFramesReceived != numFrames) { ALOGE("Input buffer count and Output buffer count mismatch"); @@ -465,18 +441,9 @@ TEST_P(Codec2AudioEncEncodeTest, EncodeTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -// EncodeTest with EOS / No EOS and inputMaxBufRatio -// inputMaxBufRatio is ratio w.r.t. to mInputMaxBufSize -INSTANTIATE_TEST_CASE_P(EncodeTest, Codec2AudioEncEncodeTest, - ::testing::Values(std::make_pair(false, 1), - std::make_pair(false, 2), - std::make_pair(true, 1), - std::make_pair(true, 2))); - - -TEST_F(Codec2AudioEncHidlTest, EOSTest) { +TEST_P(Codec2AudioEncHidlTest, EOSTest) { description("Test empty input buffer with EOS flag"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ASSERT_EQ(mComponent->start(), C2_OK); typedef std::unique_lock ULock; @@ -514,13 +481,13 @@ TEST_F(Codec2AudioEncHidlTest, EOSTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2AudioEncHidlTest, FlushTest) { +TEST_P(Codec2AudioEncHidlTest, FlushTest) { description("Test Request for flush"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; typedef std::unique_lock ULock; char mURL[512]; - strcpy(mURL, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL); // Setting default configuration @@ -570,29 +537,24 @@ TEST_F(Codec2AudioEncHidlTest, FlushTest) { eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); ALOGV("mURL : %s", mURL); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, numFramesFlushed, - samplesPerFrame, nChannels, nSampleRate)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, numFramesFlushed, + samplesPerFrame, nChannels, nSampleRate)); std::list> flushedWork; - c2_status_t err = - mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); + c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); uint64_t frameIndex; { - //Update mFlushedIndices based on the index received from flush() + // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); frameIndex = work->input.ordinal.frameIndex.peeku(); std::list::iterator frameIndexIt = - std::find(mFlushedIndices.begin(), mFlushedIndices.end(), - frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -601,29 +563,24 @@ TEST_F(Codec2AudioEncHidlTest, FlushTest) { } } mFlushedIndices.clear(); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, - numFrames - numFramesFlushed, samplesPerFrame, - nChannels, nSampleRate, true)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, + numFrames - numFramesFlushed, samplesPerFrame, nChannels, + nSampleRate, true)); eleStream.close(); - err = - mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); + err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); { - //Update mFlushedIndices based on the index received from flush() + // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); frameIndex = work->input.ordinal.frameIndex.peeku(); std::list::iterator frameIndexIt = - std::find(mFlushedIndices.begin(), mFlushedIndices.end(), - frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -635,17 +592,39 @@ TEST_F(Codec2AudioEncHidlTest, FlushTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } +INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioEncHidlTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + +// EncodeTest with EOS / No EOS and inputMaxBufRatio +// inputMaxBufRatio is ratio w.r.t. to mInputMaxBufSize +INSTANTIATE_TEST_SUITE_P(EncodeTest, Codec2AudioEncEncodeTest, + testing::ValuesIn(kEncodeTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + } // anonymous namespace int main(int argc, char** argv) { - gEnv = new ComponentTestEnvironment(); - ::testing::AddGlobalTestEnvironment(gEnv); - ::testing::InitGoogleTest(&argc, argv); - gEnv->init(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - int status = RUN_ALL_TESTS(); - LOG(INFO) << "C2 Test result = " << status; + kTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_ENCODER); + for (auto params : kTestParameters) { + kEncodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "false", "1")); + kEncodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "false", "2")); + kEncodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "true", "1")); + kEncodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "true", "2")); + } + + // Set the resource directory based on command line args. + // Test will fail to set up if the argument is not set. + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-P") == 0 && i < argc - 1) { + sResourceDir = argv[i + 1]; + break; + } } - return status; + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.xml b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.xml new file mode 100644 index 0000000000..2e37111ad7 --- /dev/null +++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h deleted file mode 100644 index 4d773ceaf5..0000000000 --- a/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2018 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_C2_AUDIO_HIDL_TEST_COMMON_H -#define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H - - -#endif // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H diff --git a/media/codec2/hidl/1.0/vts/functional/common/Android.bp b/media/codec2/hidl/1.0/vts/functional/common/Android.bp index 3b4e2324b5..f9ec5aecc1 100644 --- a/media/codec2/hidl/1.0/vts/functional/common/Android.bp +++ b/media/codec2/hidl/1.0/vts/functional/common/Android.bp @@ -1,7 +1,7 @@ cc_library_static { name: "VtsHalMediaC2V1_0CommonUtil", defaults: [ - "Vts10HalTargetTestDefaults", + "VtsHalTargetTestDefaults", "libcodec2-hidl-client-defaults", ], @@ -19,15 +19,19 @@ cc_library_static { cc_defaults { name: "VtsHalMediaC2V1_0Defaults", defaults: [ - "Vts10HalTargetTestDefaults", + "VtsHalTargetTestDefaults", "libcodec2-hidl-client-defaults", ], static_libs: [ + "libgtest", "VtsHalMediaC2V1_0CommonUtil", ], shared_libs: [ "libcodec2_client", ], + test_suites: [ + "vts", + ], } diff --git a/media/codec2/hidl/1.0/vts/functional/common/README.md b/media/codec2/hidl/1.0/vts/functional/common/README.md index f2f579c98d..ac510c56bc 100644 --- a/media/codec2/hidl/1.0/vts/functional/common/README.md +++ b/media/codec2/hidl/1.0/vts/functional/common/README.md @@ -3,34 +3,22 @@ ## master : Functionality of master is to enumerate all the Codec2 components available in C2 media service. -usage: `VtsHalMediaC2V1_0TargetMasterTest -I default` +usage: `atest VtsHalMediaC2V1_0TargetMasterTest` ## component : Functionality of component test is to validate common functionality across all the Codec2 components available in C2 media service. For a standard C2 component, these tests are expected to pass. -usage: `VtsHalMediaC2V1_0TargetComponentTest -I software -C ` - -example: `VtsHalMediaC2V1_0TargetComponentTest -I software -C c2.android.vorbis.decoder` +usage: `atest VtsHalMediaC2V1_0TargetComponentTest` ## audio : Functionality of audio test is to validate audio specific functionality of Codec2 components. The resource files for this test are taken from `frameworks/av/media/codec2/hidl/1.0/vts/functional/res`. The path to these files on the device can be specified with `-P`. (If the device path is omitted, `/data/local/tmp/media/` is the default value.) -usage: `VtsHalMediaC2V1_0TargetAudioDecTest -I default -C -P ` - -usage: `VtsHalMediaC2V1_0TargetAudioEncTest -I software -C -P ` +usage: `atest VtsHalMediaC2V1_0TargetAudioDecTest` -example: `VtsHalMediaC2V1_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /data/local/tmp/media/` - -example: `VtsHalMediaC2V1_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /data/local/tmp/media/` +usage: `atest VtsHalMediaC2V1_0TargetAudioEncTest` ## video : Functionality of video test is to validate video specific functionality of Codec2 components. The resource files for this test are taken from `frameworks/av/media/codec2/hidl/1.0/vts/functional/res`. The path to these files on the device can be specified with `-P`. (If the device path is omitted, `/data/local/tmp/media/` is the default value.) -usage: `VtsHalMediaC2V1_0TargetVideoDecTest -I default -C -P ` - -usage: `VtsHalMediaC2V1_0TargetVideoEncTest -I software -C -P ` - -example: `VtsHalMediaC2V1_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /data/local/tmp/media/` - -example: `VtsHalMediaC2V1_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /data/local/tmp/media/` - +usage: `atest VtsHalMediaC2V1_0TargetVideoDecTest` +usage: `atest VtsHalMediaC2V1_0TargetVideoEncTest` diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp index 2f029133d6..5d4b00105c 100644 --- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp +++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp @@ -22,16 +22,10 @@ #include -void ComponentTestEnvironment::registerTestServices() { - registerTestService<::android::hardware::media::c2::V1_0:: - IComponentStore>(); -} - // Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set -void testInputBuffer( - const std::shared_ptr& component, - std::mutex& queueLock, std::list>& workQueue, - uint32_t flags, bool isNullBuffer) { +void testInputBuffer(const std::shared_ptr& component, + std::mutex& queueLock, std::list>& workQueue, + uint32_t flags, bool isNullBuffer) { std::unique_ptr work; { typedef std::unique_lock ULock; @@ -61,10 +55,8 @@ void testInputBuffer( } // Wait for all the inputs to be consumed by the plugin. -void waitOnInputConsumption(std::mutex& queueLock, - std::condition_variable& queueCondition, - std::list>& workQueue, - size_t bufferCount) { +void waitOnInputConsumption(std::mutex& queueLock, std::condition_variable& queueCondition, + std::list>& workQueue, size_t bufferCount) { typedef std::unique_lock ULock; uint32_t queueSize; uint32_t maxRetry = 0; @@ -85,29 +77,25 @@ void waitOnInputConsumption(std::mutex& queueLock, } // process onWorkDone received by Listener -void workDone( - const std::shared_ptr& component, - std::unique_ptr& work, std::list& flushedIndices, - std::mutex& queueLock, std::condition_variable& queueCondition, - std::list>& workQueue, bool& eos, bool& csd, - uint32_t& framesReceived) { +void workDone(const std::shared_ptr& component, + std::unique_ptr& work, std::list& flushedIndices, + std::mutex& queueLock, std::condition_variable& queueCondition, + std::list>& workQueue, bool& eos, bool& csd, + uint32_t& framesReceived) { // handle configuration changes in work done if (work->worklets.front()->output.configUpdate.size() != 0) { ALOGV("Config Update"); std::vector> updates = - std::move(work->worklets.front()->output.configUpdate); + std::move(work->worklets.front()->output.configUpdate); std::vector configParam; std::vector> failures; for (size_t i = 0; i < updates.size(); ++i) { C2Param* param = updates[i].get(); if (param->index() == C2StreamInitDataInfo::output::PARAM_TYPE) { csd = true; - } else if ((param->index() == - C2StreamSampleRateInfo::output::PARAM_TYPE) || - (param->index() == - C2StreamChannelCountInfo::output::PARAM_TYPE) || - (param->index() == - C2StreamPictureSizeInfo::output::PARAM_TYPE)) { + } else if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) || + (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE) || + (param->index() == C2StreamPictureSizeInfo::output::PARAM_TYPE)) { configParam.push_back(param); } } @@ -116,8 +104,7 @@ void workDone( } if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) { framesReceived++; - eos = (work->worklets.front()->output.flags & - C2FrameData::FLAG_END_OF_STREAM) != 0; + eos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) != 0; auto frameIndexIt = std::find(flushedIndices.begin(), flushedIndices.end(), work->input.ordinal.frameIndex.peeku()); ALOGV("WorkDone: frameID received %d", @@ -143,3 +130,33 @@ int64_t getNowUs() { return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll; } + +// Return all test parameters, a list of tuple of +const std::vector>& getTestParameters() { + return getTestParameters(C2Component::DOMAIN_OTHER, C2Component::KIND_OTHER); +} + +// Return all test parameters, a list of tuple of with matching domain and +// kind. +const std::vector>& getTestParameters( + C2Component::domain_t domain, C2Component::kind_t kind) { + static std::vector> parameters; + + auto instances = android::Codec2Client::GetServiceNames(); + for (std::string instance : instances) { + std::shared_ptr client = + android::Codec2Client::CreateFromService(instance.c_str()); + std::vector components = client->listComponents(); + for (C2Component::Traits traits : components) { + if (instance.compare(traits.owner)) continue; + if (domain != C2Component::DOMAIN_OTHER && + (traits.domain != domain || traits.kind != kind)) { + continue; + } + + parameters.push_back(std::make_tuple(instance, traits.name)); + } + } + + return parameters; +} \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h index 23e332a6a3..4b5e0a6698 100644 --- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h +++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h @@ -22,31 +22,34 @@ #include #include +#include #include -#include +#include #define MAX_RETRY 20 #define TIME_OUT 400ms #define MAX_INPUT_BUFFERS 8 -using ::android::hardware::Void; -using ::android::hardware::Return; -using ::android::hardware::hidl_vec; using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; + +using namespace ::std::chrono; + +static std::vector> kTestParameters; /* * Handle Callback functions onWorkDone(), onTripped(), * onError(), onDeath(), onFramesRendered() */ struct CodecListener : public android::Codec2Client::Listener { - public: + public: CodecListener( - const std::function>& workItems)> fn = - nullptr) + const std::function>& workItems)> fn = nullptr) : callBack(fn) {} - virtual void onWorkDone( - const std::weak_ptr& comp, - std::list>& workItems) override { + virtual void onWorkDone(const std::weak_ptr& comp, + std::list>& workItems) override { /* TODO */ ALOGD("onWorkDone called"); (void)comp; @@ -54,40 +57,34 @@ struct CodecListener : public android::Codec2Client::Listener { } virtual void onTripped( - const std::weak_ptr& comp, - const std::vector>& settingResults) - override { + const std::weak_ptr& comp, + const std::vector>& settingResults) override { /* TODO */ (void)comp; (void)settingResults; } - virtual void onError( - const std::weak_ptr& comp, - uint32_t errorCode) override { + virtual void onError(const std::weak_ptr& comp, + uint32_t errorCode) override { /* TODO */ (void)comp; ALOGD("onError called"); if (errorCode != 0) ALOGE("Error : %u", errorCode); } - virtual void onDeath( - const std::weak_ptr& comp) override { + virtual void onDeath(const std::weak_ptr& comp) override { /* TODO */ (void)comp; } - virtual void onInputBufferDone( - uint64_t frameIndex, size_t arrayIndex) override { + virtual void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex) override { /* TODO */ (void)frameIndex; (void)arrayIndex; } - virtual void onFrameRendered( - uint64_t bufferQueueId, - int32_t slotId, - int64_t timestampNs) override { + virtual void onFrameRendered(uint64_t bufferQueueId, int32_t slotId, + int64_t timestampNs) override { /* TODO */ (void)bufferQueueId; (void)slotId; @@ -99,96 +96,30 @@ struct CodecListener : public android::Codec2Client::Listener { std::function>& workItems)> callBack; }; -// A class for test environment setup -class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { - private: - typedef ::testing::VtsHalHidlTargetTestEnvBase Super; - - public: - virtual void registerTestServices() override; - - ComponentTestEnvironment() : res("/data/local/tmp/media/") {} - - void setComponent(const char* _component) { component = _component; } - - void setInstance(const char* _instance) { instance = _instance; } - - void setRes(const char* _res) { res = _res; } - - const hidl_string getInstance() const { return instance; } - - const hidl_string getComponent() const { return component; } - - const hidl_string getRes() const { return res; } - - int initFromOptions(int argc, char** argv) { - static struct option options[] = { - {"instance", required_argument, 0, 'I'}, - {"component", required_argument, 0, 'C'}, - {"res", required_argument, 0, 'P'}, - {0, 0, 0, 0}}; - - while (true) { - int index = 0; - int c = getopt_long(argc, argv, "I:C:P:", options, &index); - if (c == -1) { - break; - } - - switch (c) { - case 'I': - setInstance(optarg); - break; - case 'C': - setComponent(optarg); - break; - case 'P': - setRes(optarg); - break; - case '?': - break; - } - } - - if (optind < argc) { - fprintf(stderr, - "unrecognized option: %s\n\n" - "usage: %s \n\n" - "test options are:\n\n" - "-I, --instance: software for C2 components, else default\n" - "-C, --component: C2 component to test\n" - "-P, --res: Resource files directory location\n", - argv[optind ?: 1], argv[0]); - return 2; - } - return 0; - } +// Return all test parameters, a list of tuple of . +const std::vector>& getTestParameters(); - private: - hidl_string instance; - hidl_string component; - hidl_string res; -}; +// Return all test parameters, a list of tuple of with matching domain and +// kind. +const std::vector>& getTestParameters( + C2Component::domain_t domain, C2Component::kind_t kind); /* * common functions declarations */ -void testInputBuffer( - const std::shared_ptr& component, - std::mutex& queueLock, std::list>& workQueue, - uint32_t flags, bool isNullBuffer); +void testInputBuffer(const std::shared_ptr& component, + std::mutex& queueLock, std::list>& workQueue, + uint32_t flags, bool isNullBuffer); -void waitOnInputConsumption(std::mutex& queueLock, - std::condition_variable& queueCondition, +void waitOnInputConsumption(std::mutex& queueLock, std::condition_variable& queueCondition, std::list>& workQueue, size_t bufferCount = MAX_INPUT_BUFFERS); -void workDone( - const std::shared_ptr& component, - std::unique_ptr& work, std::list& flushedIndices, - std::mutex& queueLock, std::condition_variable& queueCondition, - std::list>& workQueue, bool& eos, bool& csd, - uint32_t& framesReceived); +void workDone(const std::shared_ptr& component, + std::unique_ptr& work, std::list& flushedIndices, + std::mutex& queueLock, std::condition_variable& queueCondition, + std::list>& workQueue, bool& eos, bool& csd, + uint32_t& framesReceived); int64_t getNowUs(); diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp index 9dc541c5de..119ce14448 100644 --- a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp +++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp @@ -19,11 +19,11 @@ #include #include +#include #include #include -#include #include "media_c2_hidl_test_common.h" /* Time_Out for start(), stop(), reset(), release(), flush(), queue() are @@ -31,50 +31,45 @@ * extra in case of timeout is 500ms, 1ms extra in case timeout is 1ms/5ms. All * timeout is calculated in us. */ -#define START_TIME_OUT 550000 -#define STOP_TIME_OUT 550000 -#define RESET_TIME_OUT 550000 -#define RELEASE_TIME_OUT 550000 -#define FLUSH_TIME_OUT 6000 -#define QUEUE_TIME_OUT 2000 +#define START_TIME_OUT 550000 +#define STOP_TIME_OUT 550000 +#define RESET_TIME_OUT 550000 +#define RELEASE_TIME_OUT 550000 +#define FLUSH_TIME_OUT 6000 +#define QUEUE_TIME_OUT 2000 // Time_Out for config(), query(), querySupportedParams() are defined in // hardware/interfaces/media/c2/1.0/IConfigurable.hal. -#define CONFIG_TIME_OUT 6000 -#define QUERY_TIME_OUT 6000 -#define QUERYSUPPORTEDPARAMS_TIME_OUT 2000 - -#define CHECK_TIMEOUT(timeConsumed, TIME_OUT, FuncName) \ - if (timeConsumed > TIME_OUT) { \ - ALOGW( \ - "TIMED_OUT %s timeConsumed=%" PRId64 " us is " \ - "greater than threshold %d us", \ - FuncName, timeConsumed, TIME_OUT); \ +#define CONFIG_TIME_OUT 6000 +#define QUERY_TIME_OUT 6000 +#define QUERYSUPPORTEDPARAMS_TIME_OUT 2000 + +#define CHECK_TIMEOUT(timeConsumed, TIME_OUT, FuncName) \ + if (timeConsumed > TIME_OUT) { \ + ALOGW("TIMED_OUT %s timeConsumed=%" PRId64 \ + " us is " \ + "greater than threshold %d us", \ + FuncName, timeConsumed, TIME_OUT); \ } -static ComponentTestEnvironment* gEnv = nullptr; - namespace { -// google.codec2 Component test setup -class Codec2ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase { - private: - typedef ::testing::VtsHalHidlTargetTestBase Super; +static std::vector> + kInputTestParameters; - public: +// google.codec2 Component test setup +class Codec2ComponentHidlTestBase : public ::testing::Test { + public: virtual void SetUp() override { - Super::SetUp(); + getParams(); mEos = false; - mClient = android::Codec2Client::CreateFromService( - gEnv->getInstance().c_str()); + mClient = android::Codec2Client::CreateFromService(mInstanceName.c_str()); ASSERT_NE(mClient, nullptr); - mListener.reset(new CodecListener( - [this](std::list>& workItems) { - handleWorkDone(workItems); - })); + mListener.reset(new CodecListener([this](std::list>& workItems) { + handleWorkDone(workItems); + })); ASSERT_NE(mListener, nullptr); - mClient->createComponent(gEnv->getComponent().c_str(), mListener, - &mComponent); + mClient->createComponent(mComponentName.c_str(), mListener, &mComponent); ASSERT_NE(mComponent, nullptr); for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) { mWorkQueue.emplace_back(new C2Work); @@ -90,8 +85,11 @@ class Codec2ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase { mComponent->release(); mComponent = nullptr; } - Super::TearDown(); } + + // Get the test parameters from GetParam call. + virtual void getParams() {} + // callback function to process onWorkDone received by Listener void handleWorkDone(std::list>& workItems) { for (std::unique_ptr& work : workItems) { @@ -99,12 +97,14 @@ class Codec2ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase { bool mCsd = false; uint32_t mFramesReceived = 0; std::list mFlushedIndices; - workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, - mWorkQueue, mEos, mCsd, mFramesReceived); + workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue, + mEos, mCsd, mFramesReceived); } } } + std::string mInstanceName; + std::string mComponentName; bool mEos; std::mutex mQueueLock; std::condition_variable mQueueCondition; @@ -114,14 +114,23 @@ class Codec2ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase { std::shared_ptr mListener; std::shared_ptr mComponent; - protected: + protected: static void description(const std::string& description) { RecordProperty("description", description); } }; +class Codec2ComponentHidlTest + : public Codec2ComponentHidlTestBase, + public ::testing::WithParamInterface> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } +}; + // Test Empty Flush -TEST_F(Codec2ComponentHidlTest, EmptyFlush) { +TEST_P(Codec2ComponentHidlTest, EmptyFlush) { ALOGV("Empty Flush Test"); c2_status_t err = mComponent->start(); ASSERT_EQ(err, C2_OK); @@ -137,7 +146,7 @@ TEST_F(Codec2ComponentHidlTest, EmptyFlush) { } // Test Queue Empty Work -TEST_F(Codec2ComponentHidlTest, QueueEmptyWork) { +TEST_P(Codec2ComponentHidlTest, QueueEmptyWork) { ALOGV("Queue Empty Work Test"); c2_status_t err = mComponent->start(); ASSERT_EQ(err, C2_OK); @@ -151,7 +160,7 @@ TEST_F(Codec2ComponentHidlTest, QueueEmptyWork) { } // Test Component Configuration -TEST_F(Codec2ComponentHidlTest, Config) { +TEST_P(Codec2ComponentHidlTest, Config) { ALOGV("Configuration Test"); C2String name = mComponent->getName(); @@ -180,7 +189,7 @@ TEST_F(Codec2ComponentHidlTest, Config) { } // Test Multiple Start Stop Reset Test -TEST_F(Codec2ComponentHidlTest, MultipleStartStopReset) { +TEST_P(Codec2ComponentHidlTest, MultipleStartStopReset) { ALOGV("Multiple Start Stop and Reset Test"); for (size_t i = 0; i < MAX_RETRY; i++) { @@ -202,21 +211,21 @@ TEST_F(Codec2ComponentHidlTest, MultipleStartStopReset) { } // Test Component Release API -TEST_F(Codec2ComponentHidlTest, MultipleRelease) { +TEST_P(Codec2ComponentHidlTest, MultipleRelease) { ALOGV("Multiple Release Test"); c2_status_t err = mComponent->start(); ASSERT_EQ(err, C2_OK); // Query Component Domain Type std::vector> queried; - err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, - C2_DONT_BLOCK, &queried); + err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, C2_DONT_BLOCK, + &queried); EXPECT_NE(queried.size(), 0u); // Configure Component Domain std::vector> failures; C2PortMediaTypeSetting::input* portMediaType = - C2PortMediaTypeSetting::input::From(queried[0].get()); + C2PortMediaTypeSetting::input::From(queried[0].get()); err = mComponent->config({portMediaType}, C2_DONT_BLOCK, &failures); ASSERT_EQ(err, C2_OK); ASSERT_EQ(failures.size(), 0u); @@ -226,40 +235,8 @@ TEST_F(Codec2ComponentHidlTest, MultipleRelease) { } } -class Codec2ComponentInputTests : public Codec2ComponentHidlTest, - public ::testing::WithParamInterface > { -}; - -TEST_P(Codec2ComponentInputTests, InputBufferTest) { - description("Tests for different inputs"); - - uint32_t flags = GetParam().first; - bool isNullBuffer = GetParam().second; - if (isNullBuffer) ALOGD("Testing for null input buffer with flag : %u", flags); - else ALOGD("Testing for empty input buffer with flag : %u", flags); - mEos = false; - ASSERT_EQ(mComponent->start(), C2_OK); - ASSERT_NO_FATAL_FAILURE(testInputBuffer( - mComponent, mQueueLock, mWorkQueue, flags, isNullBuffer)); - - ALOGD("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); - - if (flags == C2FrameData::FLAG_END_OF_STREAM) ASSERT_EQ(mEos, true); - ASSERT_EQ(mComponent->stop(), C2_OK); - ASSERT_EQ(mComponent->reset(), C2_OK); -} - -INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests, ::testing::Values( - std::make_pair(0, true), - std::make_pair(C2FrameData::FLAG_END_OF_STREAM, true), - std::make_pair(0, false), - std::make_pair(C2FrameData::FLAG_CODEC_CONFIG, false), - std::make_pair(C2FrameData::FLAG_END_OF_STREAM, false))); - // Test API's Timeout -TEST_F(Codec2ComponentHidlTest, Timeout) { +TEST_P(Codec2ComponentHidlTest, Timeout) { ALOGV("Timeout Test"); c2_status_t err = C2_OK; @@ -285,10 +262,8 @@ TEST_F(Codec2ComponentHidlTest, Timeout) { startTime = getNowUs(); err = mComponent->querySupportedParams(¶ms); timeConsumed = getNowUs() - startTime; - CHECK_TIMEOUT(timeConsumed, QUERYSUPPORTEDPARAMS_TIME_OUT, - "querySupportedParams()"); - ALOGV("mComponent->querySupportedParams() timeConsumed=%" PRId64 " us", - timeConsumed); + CHECK_TIMEOUT(timeConsumed, QUERYSUPPORTEDPARAMS_TIME_OUT, "querySupportedParams()"); + ALOGV("mComponent->querySupportedParams() timeConsumed=%" PRId64 " us", timeConsumed); ASSERT_EQ(err, C2_OK); std::vector> queried; @@ -301,8 +276,8 @@ TEST_F(Codec2ComponentHidlTest, Timeout) { CHECK_TIMEOUT(timeConsumed, QUERY_TIME_OUT, "query()"); EXPECT_NE(queried.size(), 0u); EXPECT_EQ(err, C2_OK); - ALOGV("mComponent->query() for %s timeConsumed=%" PRId64 " us", - p->name().c_str(), timeConsumed); + ALOGV("mComponent->query() for %s timeConsumed=%" PRId64 " us", p->name().c_str(), + timeConsumed); startTime = getNowUs(); err = mComponent->config({queried[0].get()}, C2_DONT_BLOCK, &failures); @@ -310,8 +285,8 @@ TEST_F(Codec2ComponentHidlTest, Timeout) { CHECK_TIMEOUT(timeConsumed, CONFIG_TIME_OUT, "config()"); ASSERT_EQ(err, C2_OK); ASSERT_EQ(failures.size(), 0u); - ALOGV("mComponent->config() for %s timeConsumed=%" PRId64 " us", - p->name().c_str(), timeConsumed); + ALOGV("mComponent->config() for %s timeConsumed=%" PRId64 " us", p->name().c_str(), + timeConsumed); } std::list> workList; @@ -340,22 +315,68 @@ TEST_F(Codec2ComponentHidlTest, Timeout) { ALOGV("mComponent->release() timeConsumed=%" PRId64 " us", timeConsumed); CHECK_TIMEOUT(timeConsumed, RELEASE_TIME_OUT, "release()"); ASSERT_EQ(err, C2_OK); +} + +class Codec2ComponentInputTests + : public Codec2ComponentHidlTestBase, + public ::testing::WithParamInterface< + std::tuple> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } +}; + +TEST_P(Codec2ComponentInputTests, InputBufferTest) { + description("Tests for different inputs"); + + uint32_t flags = std::stol(std::get<2>(GetParam())); + bool isNullBuffer = !std::get<3>(GetParam()).compare("true"); + if (isNullBuffer) + ALOGD("Testing for null input buffer with flag : %u", flags); + else + ALOGD("Testing for empty input buffer with flag : %u", flags); + mEos = false; + ASSERT_EQ(mComponent->start(), C2_OK); + ASSERT_NO_FATAL_FAILURE( + testInputBuffer(mComponent, mQueueLock, mWorkQueue, flags, isNullBuffer)); + + ALOGD("Waiting for input consumption"); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + if (flags == C2FrameData::FLAG_END_OF_STREAM) ASSERT_EQ(mEos, true); + ASSERT_EQ(mComponent->stop(), C2_OK); + ASSERT_EQ(mComponent->reset(), C2_OK); } +INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2ComponentHidlTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + +INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests, + testing::ValuesIn(kInputTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); } // anonymous namespace // TODO: Add test for Invalid work, // TODO: Add test for Invalid states int main(int argc, char** argv) { - gEnv = new ComponentTestEnvironment(); - ::testing::AddGlobalTestEnvironment(gEnv); - ::testing::InitGoogleTest(&argc, argv); - gEnv->init(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - status = RUN_ALL_TESTS(); - LOG(INFO) << "C2 Test result = " << status; + kTestParameters = getTestParameters(); + for (auto params : kTestParameters) { + kInputTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "true")); + kInputTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), + std::to_string(C2FrameData::FLAG_END_OF_STREAM), "true")); + kInputTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "false")); + kInputTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), + std::to_string(C2FrameData::FLAG_CODEC_CONFIG), "false")); + kInputTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), + std::to_string(C2FrameData::FLAG_END_OF_STREAM), "false")); } - return status; + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp index e88fbc7d8d..fb1c291a4a 100644 --- a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp +++ b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp @@ -19,30 +19,25 @@ #include #include +#include +#include #include #include #include "media_c2_hidl_test_common.h" -static ComponentTestEnvironment* gEnv = nullptr; - namespace { // google.codec2 Master test setup -class Codec2MasterHalTest : public ::testing::VtsHalHidlTargetTestBase { - private: - typedef ::testing::VtsHalHidlTargetTestBase Super; - - public: +class Codec2MasterHalTest : public ::testing::TestWithParam { + public: virtual void SetUp() override { - Super::SetUp(); - mClient = android::Codec2Client::CreateFromService( - gEnv->getInstance().c_str()); + mClient = android::Codec2Client::CreateFromService(GetParam().c_str()); ASSERT_NE(mClient, nullptr); } - protected: + protected: static void description(const std::string& description) { RecordProperty("description", description); } @@ -58,15 +53,14 @@ void displayComponentInfo(const std::vector& compList) { } // List Components -TEST_F(Codec2MasterHalTest, ListComponents) { +TEST_P(Codec2MasterHalTest, ListComponents) { ALOGV("ListComponents Test"); C2String name = mClient->getName(); EXPECT_NE(name.empty(), true) << "Invalid Codec2Client Name"; // Get List of components from all known services - const std::vector listTraits = - mClient->ListComponents(); + const std::vector listTraits = mClient->ListComponents(); if (listTraits.size() == 0) ALOGE("Warning, ComponentInfo list empty"); @@ -79,24 +73,16 @@ TEST_F(Codec2MasterHalTest, ListComponents) { ASSERT_NE(listener, nullptr); // Create component from all known services - component = mClient->CreateComponentByName( - listTraits[i].name.c_str(), listener, &mClient); - ASSERT_NE(component, nullptr) << "Create component failed for " - << listTraits[i].name.c_str(); + component = + mClient->CreateComponentByName(listTraits[i].name.c_str(), listener, &mClient); + ASSERT_NE(component, nullptr) + << "Create component failed for " << listTraits[i].name.c_str(); } } } } // anonymous namespace -int main(int argc, char** argv) { - gEnv = new ComponentTestEnvironment(); - ::testing::InitGoogleTest(&argc, argv); - gEnv->init(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - status = RUN_ALL_TESTS(); - LOG(INFO) << "C2 Test result = " << status; - } - return status; -} +INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2MasterHalTest, + testing::ValuesIn(android::Codec2Client::GetServiceNames()), + android::hardware::PrintInstanceNameToString); diff --git a/media/codec2/hidl/1.0/vts/functional/video/Android.bp b/media/codec2/hidl/1.0/vts/functional/video/Android.bp index b7373236db..760f4da892 100644 --- a/media/codec2/hidl/1.0/vts/functional/video/Android.bp +++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp @@ -16,6 +16,7 @@ cc_test { name: "VtsHalMediaC2V1_0TargetVideoDecTest", + stem: "vts_media_c2_v1_0_video_dec_test", defaults: ["VtsHalMediaC2V1_0Defaults"], srcs: ["VtsHalMediaC2V1_0TargetVideoDecTest.cpp"], header_libs: [ @@ -26,11 +27,16 @@ cc_test { "libgui", "libutils", ], + data: [":media_c2_v1_video_decode_res"], + test_config: "VtsHalMediaC2V1_0TargetVideoDecTest.xml", } cc_test { name: "VtsHalMediaC2V1_0TargetVideoEncTest", + stem: "vts_media_c2_v1_0_video_enc_test", defaults: ["VtsHalMediaC2V1_0Defaults"], srcs: ["VtsHalMediaC2V1_0TargetVideoEncTest.cpp"], + data: [":media_c2_v1_video_encode_res"], + test_config: "VtsHalMediaC2V1_0TargetVideoEncTest.xml", } diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp index 256603cc4c..ec3fd7b348 100644 --- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp +++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp @@ -19,15 +19,16 @@ #include #include +#include #include #include -#include #include -#include -#include #include #include +#include +#include +#include #include #include #include @@ -35,9 +36,8 @@ using android::C2AllocatorIon; -#include -#include "media_c2_video_hidl_test_common.h" #include "media_c2_hidl_test_common.h" +#include "media_c2_video_hidl_test_common.h" struct FrameInfo { int bytesCount; @@ -45,61 +45,47 @@ struct FrameInfo { int64_t timestamp; }; +static std::vector> + kDecodeTestParameters; + +// Resource directory +static std::string sResourceDir = ""; + class LinearBuffer : public C2Buffer { - public: + public: explicit LinearBuffer(const std::shared_ptr& block) - : C2Buffer( - {block->share(block->offset(), block->size(), ::C2Fence())}) {} + : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {} explicit LinearBuffer(const std::shared_ptr& block, size_t size) - : C2Buffer( - {block->share(block->offset(), size, ::C2Fence())}) {} + : C2Buffer({block->share(block->offset(), size, ::C2Fence())}) {} }; -static ComponentTestEnvironment* gEnv = nullptr; - namespace { -class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { - private: - typedef ::testing::VtsHalHidlTargetTestBase Super; - - public: - ::std::string getTestCaseInfo() const override { - return ::std::string() + - "Component: " + gEnv->getComponent().c_str() + " | " + - "Instance: " + gEnv->getInstance().c_str() + " | " + - "Res: " + gEnv->getRes().c_str(); - } - +class Codec2VideoDecHidlTestBase : public ::testing::Test { + public: // google.codec2 Video test setup virtual void SetUp() override { - Super::SetUp(); + getParams(); mDisableTest = false; ALOGV("Codec2VideoDecHidlTest SetUp"); mClient = android::Codec2Client::CreateFromService( - gEnv->getInstance().c_str(), - !bool(android::Codec2Client::CreateFromService("default", true))); + mInstanceName.c_str(), + !bool(android::Codec2Client::CreateFromService("default", true))); ASSERT_NE(mClient, nullptr); - mListener.reset(new CodecListener( - [this](std::list>& workItems) { - handleWorkDone(workItems); - })); + mListener.reset(new CodecListener([this](std::list>& workItems) { + handleWorkDone(workItems); + })); ASSERT_NE(mListener, nullptr); for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) { mWorkQueue.emplace_back(new C2Work); } - mClient->createComponent(gEnv->getComponent().c_str(), mListener, - &mComponent); + mClient->createComponent(mComponentName, mListener, &mComponent); ASSERT_NE(mComponent, nullptr); - std::shared_ptr store = - android::GetCodec2PlatformAllocatorStore(); - CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, - &mLinearAllocator), - C2_OK); - mLinearPool = std::make_shared(mLinearAllocator, - mBlockPoolId++); + std::shared_ptr store = android::GetCodec2PlatformAllocatorStore(); + CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator), C2_OK); + mLinearPool = std::make_shared(mLinearAllocator, mBlockPoolId++); ASSERT_NE(mLinearPool, nullptr); mCompName = unknown_comp; @@ -109,17 +95,15 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { }; const StringToName kStringToName[] = { - {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4}, - {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1}, + {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4}, + {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1}, }; - const size_t kNumStringToName = - sizeof(kStringToName) / sizeof(kStringToName[0]); + const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]); // Find the component type - std::string comp = std::string(gEnv->getComponent()); for (size_t i = 0; i < kNumStringToName; ++i) { - if (strcasestr(comp.c_str(), kStringToName[i].Name)) { + if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) { mCompName = kStringToName[i].CompName; break; } @@ -131,7 +115,7 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { if (mCompName == unknown_comp) mDisableTest = true; C2SecureModeTuning secureModeTuning{}; - mComponent->query({ &secureModeTuning }, {}, C2_MAY_BLOCK, nullptr); + mComponent->query({&secureModeTuning}, {}, C2_MAY_BLOCK, nullptr); if (secureModeTuning.value == C2Config::SM_READ_PROTECTED) { mDisableTest = true; } @@ -145,9 +129,11 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { mComponent->release(); mComponent = nullptr; } - Super::TearDown(); } + // Get the test parameters from GetParam call. + virtual void getParams() {} + // callback function to process onWorkDone received by Listener void handleWorkDone(std::list>& workItems) { for (std::unique_ptr& work : workItems) { @@ -157,13 +143,10 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { typedef std::unique_lock ULock; bool codecConfig = ((work->worklets.front()->output.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0); - if (!codecConfig && - !work->worklets.front()->output.buffers.empty()) { - EXPECT_GE( - (work->worklets.front()->output.ordinal.timestamp.peeku()), - mTimestampUs); - mTimestampUs = - work->worklets.front()->output.ordinal.timestamp.peeku(); + if (!codecConfig && !work->worklets.front()->output.buffers.empty()) { + EXPECT_GE((work->worklets.front()->output.ordinal.timestamp.peeku()), + mTimestampUs); + mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku(); ULock l(mQueueLock); if (mTimestampDevTest) { @@ -179,8 +162,7 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { } if (tsHit == false) { if (mTimestampUslist.empty() == false) { - EXPECT_EQ(tsHit, true) - << "TimeStamp not recognized"; + EXPECT_EQ(tsHit, true) << "TimeStamp not recognized"; } else { std::cout << "[ INFO ] Received non-zero " "output / TimeStamp not recognized \n"; @@ -189,9 +171,8 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { } } bool mCsd; - workDone(mComponent, work, mFlushedIndices, mQueueLock, - mQueueCondition, mWorkQueue, mEos, mCsd, - mFramesReceived); + workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue, + mEos, mCsd, mFramesReceived); (void)mCsd; } } @@ -209,6 +190,9 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { unknown_comp, }; + std::string mInstanceName; + std::string mComponentName; + bool mEos; bool mDisableTest; bool mTimestampDevTest; @@ -229,15 +213,23 @@ class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase { std::shared_ptr mListener; std::shared_ptr mComponent; - protected: + protected: static void description(const std::string& description) { RecordProperty("description", description); } }; -void validateComponent( - const std::shared_ptr& component, - Codec2VideoDecHidlTest::standardComp compName, bool& disableTest) { +class Codec2VideoDecHidlTest + : public Codec2VideoDecHidlTestBase, + public ::testing::WithParamInterface> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } +}; + +void validateComponent(const std::shared_ptr& component, + Codec2VideoDecHidlTest::standardComp compName, bool& disableTest) { // Validate its a C2 Component if (component->getName().find("c2") == std::string::npos) { ALOGE("Not a c2 component"); @@ -252,14 +244,12 @@ void validateComponent( return; } std::vector> queried; - c2_status_t c2err = - component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, - C2_DONT_BLOCK, &queried); + c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, + C2_DONT_BLOCK, &queried); if (c2err != C2_OK && queried.size() == 0) { ALOGE("Query media type failed => %d", c2err); } else { - std::string inputDomain = - ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; + std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; if (inputDomain.find("video/") == std::string::npos) { ALOGE("Expected Video Component"); disableTest = true; @@ -279,8 +269,8 @@ void validateComponent( // number of elementary streams per component #define STREAM_COUNT 2 // LookUpTable of clips and metadata for component testing -void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, - char* info, size_t streamIndex = 1) { +void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, char* info, + size_t streamIndex = 1) { struct CompToURL { Codec2VideoDecHidlTest::standardComp comp; const char mURL[STREAM_COUNT][512]; @@ -289,42 +279,30 @@ void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, ASSERT_TRUE(streamIndex < STREAM_COUNT); static const CompToURL kCompToURL[] = { - {Codec2VideoDecHidlTest::standardComp::avc, - {"bbb_avc_176x144_300kbps_60fps.h264", - "bbb_avc_640x360_768kbps_30fps.h264"}, - {"bbb_avc_176x144_300kbps_60fps.info", - "bbb_avc_640x360_768kbps_30fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::hevc, - {"bbb_hevc_176x144_176kbps_60fps.hevc", - "bbb_hevc_640x360_1600kbps_30fps.hevc"}, - {"bbb_hevc_176x144_176kbps_60fps.info", - "bbb_hevc_640x360_1600kbps_30fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::mpeg2, - {"bbb_mpeg2_176x144_105kbps_25fps.m2v", - "bbb_mpeg2_352x288_1mbps_60fps.m2v"}, - {"bbb_mpeg2_176x144_105kbps_25fps.info", - "bbb_mpeg2_352x288_1mbps_60fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::h263, - {"", "bbb_h263_352x288_300kbps_12fps.h263"}, - {"", "bbb_h263_352x288_300kbps_12fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::mpeg4, - {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"}, - {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::vp8, - {"bbb_vp8_176x144_240kbps_60fps.vp8", - "bbb_vp8_640x360_2mbps_30fps.vp8"}, - {"bbb_vp8_176x144_240kbps_60fps.info", - "bbb_vp8_640x360_2mbps_30fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::vp9, - {"bbb_vp9_176x144_285kbps_60fps.vp9", - "bbb_vp9_640x360_1600kbps_30fps.vp9"}, - {"bbb_vp9_176x144_285kbps_60fps.info", - "bbb_vp9_640x360_1600kbps_30fps.info"}}, - {Codec2VideoDecHidlTest::standardComp::av1, - {"bbb_av1_640_360.av1", - "bbb_av1_176_144.av1"}, - {"bbb_av1_640_360.info", - "bbb_av1_176_144.info"}}, + {Codec2VideoDecHidlTest::standardComp::avc, + {"bbb_avc_176x144_300kbps_60fps.h264", "bbb_avc_640x360_768kbps_30fps.h264"}, + {"bbb_avc_176x144_300kbps_60fps.info", "bbb_avc_640x360_768kbps_30fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::hevc, + {"bbb_hevc_176x144_176kbps_60fps.hevc", "bbb_hevc_640x360_1600kbps_30fps.hevc"}, + {"bbb_hevc_176x144_176kbps_60fps.info", "bbb_hevc_640x360_1600kbps_30fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::mpeg2, + {"bbb_mpeg2_176x144_105kbps_25fps.m2v", "bbb_mpeg2_352x288_1mbps_60fps.m2v"}, + {"bbb_mpeg2_176x144_105kbps_25fps.info", "bbb_mpeg2_352x288_1mbps_60fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::h263, + {"", "bbb_h263_352x288_300kbps_12fps.h263"}, + {"", "bbb_h263_352x288_300kbps_12fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::mpeg4, + {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"}, + {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::vp8, + {"bbb_vp8_176x144_240kbps_60fps.vp8", "bbb_vp8_640x360_2mbps_30fps.vp8"}, + {"bbb_vp8_176x144_240kbps_60fps.info", "bbb_vp8_640x360_2mbps_30fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::vp9, + {"bbb_vp9_176x144_285kbps_60fps.vp9", "bbb_vp9_640x360_1600kbps_30fps.vp9"}, + {"bbb_vp9_176x144_285kbps_60fps.info", "bbb_vp9_640x360_1600kbps_30fps.info"}}, + {Codec2VideoDecHidlTest::standardComp::av1, + {"bbb_av1_640_360.av1", "bbb_av1_176_144.av1"}, + {"bbb_av1_640_360.info", "bbb_av1_176_144.info"}}, }; for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) { @@ -337,13 +315,11 @@ void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, } void decodeNFrames(const std::shared_ptr& component, - std::mutex &queueLock, std::condition_variable& queueCondition, + std::mutex& queueLock, std::condition_variable& queueCondition, std::list>& workQueue, - std::list& flushedIndices, - std::shared_ptr& linearPool, - std::ifstream& eleStream, - android::Vector* Info, - int offset, int range, bool signalEOS = true) { + std::list& flushedIndices, std::shared_ptr& linearPool, + std::ifstream& eleStream, android::Vector* Info, int offset, + int range, bool signalEOS = true) { typedef std::unique_lock ULock; int frameID = offset; int maxRetry = 0; @@ -367,8 +343,7 @@ void decodeNFrames(const std::shared_ptr& comp } int64_t timestamp = (*Info)[frameID].timestamp; if ((*Info)[frameID].flags) flags = (1 << ((*Info)[frameID].flags - 1)); - if (signalEOS && ((frameID == (int)Info->size() - 1) || - (frameID == (offset + range - 1)))) + if (signalEOS && ((frameID == (int)Info->size() - 1) || (frameID == (offset + range - 1)))) flags |= C2FrameData::FLAG_END_OF_STREAM; work->input.flags = (C2FrameData::flags_t)flags; @@ -390,10 +365,9 @@ void decodeNFrames(const std::shared_ptr& comp auto alignedSize = ALIGN(size, PAGE_SIZE); if (size) { std::shared_ptr block; - ASSERT_EQ(C2_OK, - linearPool->fetchLinearBlock( - alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, - &block)); + ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock( + alignedSize, + {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block)); ASSERT_TRUE(block); // Write View @@ -424,16 +398,16 @@ void decodeNFrames(const std::shared_ptr& comp } } -TEST_F(Codec2VideoDecHidlTest, validateCompName) { - if (mDisableTest) return; +TEST_P(Codec2VideoDecHidlTest, validateCompName) { + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ALOGV("Checks if the given component is a valid video component"); validateComponent(mComponent, mCompName, mDisableTest); ASSERT_EQ(mDisableTest, false); } -TEST_F(Codec2VideoDecHidlTest, configureTunnel) { +TEST_P(Codec2VideoDecHidlTest, configureTunnel) { description("Attempts to configure tunneling"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ALOGV("Checks if the component can be configured for tunneling"); native_handle_t* sidebandStream{}; c2_status_t err = mComponent->configureVideoTunnel(0, &sidebandStream); @@ -449,7 +423,7 @@ TEST_F(Codec2VideoDecHidlTest, configureTunnel) { BufferQueue::createBufferQueue(&producer, &consumer); class DummyConsumerListener : public BnConsumerListener { - public: + public: DummyConsumerListener() : BnConsumerListener() {} void onFrameAvailable(const BufferItem&) override {} void onBuffersReleased() override {} @@ -458,37 +432,39 @@ TEST_F(Codec2VideoDecHidlTest, configureTunnel) { consumer->consumerConnect(new DummyConsumerListener(), false); class DummyProducerListener : public BnProducerListener { - public: + public: DummyProducerListener() : BnProducerListener() {} virtual void onBufferReleased() override {} virtual bool needsReleaseNotify() override { return false; } virtual void onBuffersDiscarded(const std::vector&) override {} }; IGraphicBufferProducer::QueueBufferOutput qbo{}; - producer->connect(new DummyProducerListener(), - NATIVE_WINDOW_API_MEDIA, - false, - &qbo); + producer->connect(new DummyProducerListener(), NATIVE_WINDOW_API_MEDIA, false, &qbo); ASSERT_EQ(producer->setSidebandStream(nativeHandle), NO_ERROR); } class Codec2VideoDecDecodeTest - : public Codec2VideoDecHidlTest, - public ::testing::WithParamInterface> { + : public Codec2VideoDecHidlTestBase, + public ::testing::WithParamInterface< + std::tuple> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } }; // Bitstream Test TEST_P(Codec2VideoDecDecodeTest, DecodeTest) { description("Decodes input file"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; - uint32_t streamIndex = GetParam().first; - bool signalEOS = GetParam().second; + uint32_t streamIndex = std::stoi(std::get<2>(GetParam())); + bool signalEOS = !std::get<2>(GetParam()).compare("true"); char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info, streamIndex); eleInfo.open(info); @@ -504,10 +480,8 @@ TEST_P(Codec2VideoDecDecodeTest, DecodeTest) { if (!(eleInfo >> bytesCount)) break; eleInfo >> flags; eleInfo >> timestamp; - bool codecConfig = flags ? - ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; - if (mTimestampDevTest && !codecConfig) - mTimestampUslist.push_back(timestamp); + bool codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; + if (mTimestampDevTest && !codecConfig) mTimestampUslist.push_back(timestamp); Info.push_back({bytesCount, flags, timestamp}); } eleInfo.close(); @@ -519,52 +493,42 @@ TEST_P(Codec2VideoDecDecodeTest, DecodeTest) { ALOGV("mURL : %s", mURL); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, (int)Info.size(), signalEOS)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + (int)Info.size(), signalEOS)); // If EOS is not sent, sending empty input with EOS flag size_t infoSize = Info.size(); if (!signalEOS) { - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); - ASSERT_NO_FATAL_FAILURE( - testInputBuffer(mComponent, mQueueLock, mWorkQueue, - C2FrameData::FLAG_END_OF_STREAM, false)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); + ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue, + C2FrameData::FLAG_END_OF_STREAM, false)); infoSize += 1; } // blocking call to ensures application to Wait till all the inputs are // consumed if (!mEos) { ALOGV("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); } eleStream.close(); if (mFramesReceived != infoSize) { ALOGE("Input buffer count and Output buffer count mismatch"); - ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, - infoSize); + ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, infoSize); ASSERT_TRUE(false); } if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true); ASSERT_EQ(mComponent->stop(), C2_OK); } -// DecodeTest with StreamIndex and EOS / No EOS -INSTANTIATE_TEST_CASE_P(StreamIndexAndEOS, Codec2VideoDecDecodeTest, - ::testing::Values(std::make_pair(0, false), - std::make_pair(0, true), - std::make_pair(1, false), - std::make_pair(1, true))); // Adaptive Test -TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { +TEST_P(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { description("Adaptive Decode Test"); - if (mDisableTest) return; - if (!(mCompName == avc || mCompName == hevc || mCompName == vp8 || - mCompName == vp9 || mCompName == mpeg2)) + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; + if (!(mCompName == avc || mCompName == hevc || mCompName == vp8 || mCompName == vp9 || + mCompName == mpeg2)) return; typedef std::unique_lock ULock; @@ -578,8 +542,8 @@ TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info, i % STREAM_COUNT); eleInfo.open(info); @@ -594,13 +558,12 @@ TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { eleInfo >> timestamp; timestamp += timestampOffset; Info.push_back({bytesCount, flags, timestamp}); - bool codecConfig = flags ? - ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; + bool codecConfig = + flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; { ULock l(mQueueLock); - if (mTimestampDevTest && !codecConfig) - mTimestampUslist.push_back(timestamp); + if (mTimestampDevTest && !codecConfig) mTimestampUslist.push_back(timestamp); } if (timestampMax < timestamp) timestampMax = timestamp; } @@ -612,10 +575,9 @@ TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { ALOGV("mURL : %s", mURL); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE( - decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, &Info, - offset, (int)(Info.size() - offset), false)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, + offset, (int)(Info.size() - offset), false)); eleStream.close(); offset = (int)Info.size(); @@ -650,13 +612,11 @@ TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { // blocking call to ensures application to Wait till all the inputs are // consumed ALOGV("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); if (mFramesReceived != ((Info.size()) + 1)) { ALOGE("Input buffer count and Output buffer count mismatch"); - ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, - Info.size() + 1); + ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, Info.size() + 1); ASSERT_TRUE(false); } @@ -664,15 +624,15 @@ TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) { } // thumbnail test -TEST_F(Codec2VideoDecHidlTest, ThumbnailTest) { +TEST_P(Codec2VideoDecHidlTest, ThumbnailTest) { description("Test Request for thumbnail"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info); eleInfo.open(info); @@ -703,11 +663,10 @@ TEST_F(Codec2VideoDecHidlTest, ThumbnailTest) { } while (!(flags & SYNC_FRAME)); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, &Info, 0, j + 1)); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + j + 1)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); eleStream.close(); EXPECT_GE(mFramesReceived, 1U); ASSERT_EQ(mEos, true); @@ -716,9 +675,9 @@ TEST_F(Codec2VideoDecHidlTest, ThumbnailTest) { ASSERT_EQ(mComponent->release(), C2_OK); } -TEST_F(Codec2VideoDecHidlTest, EOSTest) { +TEST_P(Codec2VideoDecHidlTest, EOSTest) { description("Test empty input buffer with EOS flag"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; typedef std::unique_lock ULock; ASSERT_EQ(mComponent->start(), C2_OK); std::unique_ptr work; @@ -756,16 +715,16 @@ TEST_F(Codec2VideoDecHidlTest, EOSTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2VideoDecHidlTest, FlushTest) { +TEST_P(Codec2VideoDecHidlTest, FlushTest) { description("Tests Flush calls"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; typedef std::unique_lock ULock; ASSERT_EQ(mComponent->start(), C2_OK); char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info); eleInfo.open(info); @@ -790,28 +749,24 @@ TEST_F(Codec2VideoDecHidlTest, FlushTest) { // frame after this so that the below section can be covered for all // components uint32_t numFramesFlushed = 128; - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, numFramesFlushed, false)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + numFramesFlushed, false)); // flush std::list> flushedWork; - c2_status_t err = - mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); + c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); { // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); - auto frameIndexIt = - std::find(mFlushedIndices.begin(), mFlushedIndices.end(), - work->input.ordinal.frameIndex.peeku()); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + auto frameIndexIt = std::find(mFlushedIndices.begin(), mFlushedIndices.end(), + work->input.ordinal.frameIndex.peeku()); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -835,27 +790,24 @@ TEST_F(Codec2VideoDecHidlTest, FlushTest) { index++; } if (keyFrame) { - ASSERT_NO_FATAL_FAILURE( - decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mLinearPool, eleStream, &Info, index, - (int)Info.size() - index)); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, index, + (int)Info.size() - index)); } eleStream.close(); err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); { // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); uint64_t frameIndex = work->input.ordinal.frameIndex.peeku(); - std::list::iterator frameIndexIt = std::find( - mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::list::iterator frameIndexIt = + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -867,15 +819,15 @@ TEST_F(Codec2VideoDecHidlTest, FlushTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) { +TEST_P(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) { description("Decode with multiple empty input frames"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; char mURL[512], info[512]; std::ifstream eleStream, eleInfo; - strcpy(mURL, gEnv->getRes().c_str()); - strcpy(info, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); + strcpy(info, sResourceDir.c_str()); GetURLForComponent(mCompName, mURL, info); eleInfo.open(info); @@ -890,15 +842,16 @@ TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) { // and empty input frames at an interval of 5 frames. while (1) { if (!(frameId % 5)) { - if (!(frameId % 20)) flags = 32; - else flags = 0; + if (!(frameId % 20)) + flags = 32; + else + flags = 0; bytesCount = 0; } else { if (!(eleInfo >> bytesCount)) break; eleInfo >> flags; eleInfo >> timestamp; - codecConfig = flags ? - ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; + codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0; } Info.push_back({bytesCount, flags, timestamp}); frameId++; @@ -909,39 +862,58 @@ TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) { ALOGV("mURL : %s", mURL); eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); - ASSERT_NO_FATAL_FAILURE(decodeNFrames( - mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, - mLinearPool, eleStream, &Info, 0, (int)Info.size())); + ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mLinearPool, eleStream, &Info, 0, + (int)Info.size())); // blocking call to ensures application to Wait till all the inputs are // consumed if (!mEos) { ALOGV("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); } eleStream.close(); if (mFramesReceived != Info.size()) { ALOGE("Input buffer count and Output buffer count mismatch"); - ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, - Info.size()); + ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, Info.size()); ASSERT_TRUE(false); } } +INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoDecHidlTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + +// DecodeTest with StreamIndex and EOS / No EOS +INSTANTIATE_TEST_SUITE_P(StreamIndexAndEOS, Codec2VideoDecDecodeTest, + testing::ValuesIn(kDecodeTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + } // anonymous namespace // TODO : Video specific configuration Test int main(int argc, char** argv) { - gEnv = new ComponentTestEnvironment(); - ::testing::AddGlobalTestEnvironment(gEnv); - ::testing::InitGoogleTest(&argc, argv); - gEnv->init(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - int status = RUN_ALL_TESTS(); - LOG(INFO) << "C2 Test result = " << status; + kTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_DECODER); + for (auto params : kTestParameters) { + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "false")); + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "true")); + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "false")); + kDecodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "true")); + } + + // Set the resource directory based on command line args. + // Test will fail to set up if the argument is not set. + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-P") == 0 && i < argc - 1) { + sResourceDir = argv[i + 1]; + break; + } } - return status; -} + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml new file mode 100644 index 0000000000..87617977ef --- /dev/null +++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp index 15f6acdd92..be97383e32 100644 --- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp +++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp @@ -19,73 +19,62 @@ #include #include +#include #include #include -#include #include -#include -#include #include #include +#include +#include +#include using android::C2AllocatorIon; -#include -#include "media_c2_video_hidl_test_common.h" #include "media_c2_hidl_test_common.h" +#include "media_c2_video_hidl_test_common.h" class GraphicBuffer : public C2Buffer { -public: - explicit GraphicBuffer(const std::shared_ptr &block) - : C2Buffer({block->share(C2Rect(block->width(), block->height()), - ::C2Fence())}) {} + public: + explicit GraphicBuffer(const std::shared_ptr& block) + : C2Buffer({block->share(C2Rect(block->width(), block->height()), ::C2Fence())}) {} }; -static ComponentTestEnvironment* gEnv = nullptr; +static std::vector> kEncodeTestParameters; +static std::vector> + kEncodeResolutionTestParameters; -namespace { - -class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { - private: - typedef ::testing::VtsHalHidlTargetTestBase Super; +// Resource directory +static std::string sResourceDir = ""; - public: - ::std::string getTestCaseInfo() const override { - return ::std::string() + - "Component: " + gEnv->getComponent().c_str() + " | " + - "Instance: " + gEnv->getInstance().c_str() + " | " + - "Res: " + gEnv->getRes().c_str(); - } +namespace { +class Codec2VideoEncHidlTestBase : public ::testing::Test { + public: // google.codec2 Video test setup virtual void SetUp() override { - Super::SetUp(); + getParams(); mDisableTest = false; ALOGV("Codec2VideoEncHidlTest SetUp"); mClient = android::Codec2Client::CreateFromService( - gEnv->getInstance().c_str(), - !bool(android::Codec2Client::CreateFromService("default", true))); + mInstanceName.c_str(), + !bool(android::Codec2Client::CreateFromService("default", true))); ASSERT_NE(mClient, nullptr); - mListener.reset(new CodecListener( - [this](std::list>& workItems) { - handleWorkDone(workItems); - })); + mListener.reset(new CodecListener([this](std::list>& workItems) { + handleWorkDone(workItems); + })); ASSERT_NE(mListener, nullptr); for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) { mWorkQueue.emplace_back(new C2Work); } - mClient->createComponent(gEnv->getComponent().c_str(), mListener, - &mComponent); + mClient->createComponent(mComponentName, mListener, &mComponent); ASSERT_NE(mComponent, nullptr); - std::shared_ptr store = - android::GetCodec2PlatformAllocatorStore(); - CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, - &mGraphicAllocator), + std::shared_ptr store = android::GetCodec2PlatformAllocatorStore(); + CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mGraphicAllocator), C2_OK); - mGraphicPool = std::make_shared(mGraphicAllocator, - mBlockPoolId++); + mGraphicPool = std::make_shared(mGraphicAllocator, mBlockPoolId++); ASSERT_NE(mGraphicPool, nullptr); mCompName = unknown_comp; @@ -95,17 +84,15 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { }; const StringToName kStringToName[] = { - {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4}, - {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, + {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4}, + {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, }; - const size_t kNumStringToName = - sizeof(kStringToName) / sizeof(kStringToName[0]); + const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]); // Find the component type - std::string comp = std::string(gEnv->getComponent()); for (size_t i = 0; i < kNumStringToName; ++i) { - if (strcasestr(comp.c_str(), kStringToName[i].Name)) { + if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) { mCompName = kStringToName[i].CompName; break; } @@ -126,9 +113,11 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { mComponent->release(); mComponent = nullptr; } - Super::TearDown(); } + // Get the test parameters from GetParam call. + virtual void getParams() {} + bool setupConfigParam(int32_t nWidth, int32_t nHeight); // callback function to process onWorkDone received by Listener @@ -139,11 +128,9 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { // previous timestamp typedef std::unique_lock ULock; if (!mTimestampUslist.empty()) { - EXPECT_GE((work->worklets.front() - ->output.ordinal.timestamp.peeku()), + EXPECT_GE((work->worklets.front()->output.ordinal.timestamp.peeku()), mTimestampUs); - mTimestampUs = work->worklets.front() - ->output.ordinal.timestamp.peeku(); + mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku(); // Currently this lock is redundant as no mTimestampUslist is only initialized // before queuing any work to component. Once AdaptiveTest is added similar to // the one in video decoders, this is needed. @@ -151,8 +138,7 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { if (mTimestampDevTest) { bool tsHit = false; - std::list::iterator it = - mTimestampUslist.begin(); + std::list::iterator it = mTimestampUslist.begin(); while (it != mTimestampUslist.end()) { if (*it == mTimestampUs) { mTimestampUslist.erase(it); @@ -163,21 +149,18 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { } if (tsHit == false) { if (mTimestampUslist.empty() == false) { - EXPECT_EQ(tsHit, true) - << "TimeStamp not recognized"; + EXPECT_EQ(tsHit, true) << "TimeStamp not recognized"; } else { - std::cout - << "[ INFO ] Received non-zero " - "output / TimeStamp not recognized \n"; + std::cout << "[ INFO ] Received non-zero " + "output / TimeStamp not recognized \n"; } } } } if (work->result != C2_OK) mFailedWorkReceived++; - workDone(mComponent, work, mFlushedIndices, mQueueLock, - mQueueCondition, mWorkQueue, mEos, mCsd, - mFramesReceived); + workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue, + mEos, mCsd, mFramesReceived); } } } @@ -192,6 +175,8 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { unknown_comp, }; + std::string mInstanceName; + std::string mComponentName; bool mEos; bool mCsd; bool mDisableTest; @@ -217,15 +202,23 @@ class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase { std::shared_ptr mListener; std::shared_ptr mComponent; - protected: + protected: static void description(const std::string& description) { RecordProperty("description", description); } }; -void validateComponent( - const std::shared_ptr& component, - Codec2VideoEncHidlTest::standardComp compName, bool& disableTest) { +class Codec2VideoEncHidlTest + : public Codec2VideoEncHidlTestBase, + public ::testing::WithParamInterface> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } +}; + +void validateComponent(const std::shared_ptr& component, + Codec2VideoEncHidlTest::standardComp compName, bool& disableTest) { // Validate its a C2 Component if (component->getName().find("c2") == std::string::npos) { ALOGE("Not a c2 component"); @@ -240,14 +233,12 @@ void validateComponent( return; } std::vector> queried; - c2_status_t c2err = - component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, - C2_DONT_BLOCK, &queried); + c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, + C2_DONT_BLOCK, &queried); if (c2err != C2_OK && queried.size() == 0) { ALOGE("Query media type failed => %d", c2err); } else { - std::string inputDomain = - ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; + std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value; if (inputDomain.find("video/") == std::string::npos) { ALOGE("Expected Video Component"); disableTest = true; @@ -265,12 +256,11 @@ void validateComponent( } // Set Default config param. -bool Codec2VideoEncHidlTest::setupConfigParam(int32_t nWidth, int32_t nHeight) { +bool Codec2VideoEncHidlTestBase::setupConfigParam(int32_t nWidth, int32_t nHeight) { std::vector> failures; C2StreamPictureSizeInfo::input inputSize(0u, nWidth, nHeight); std::vector configParam{&inputSize}; - c2_status_t status = - mComponent->config(configParam, C2_DONT_BLOCK, &failures); + c2_status_t status = mComponent->config(configParam, C2_DONT_BLOCK, &failures); if (status == C2_OK && failures.size() == 0u) return true; return false; } @@ -281,13 +271,11 @@ void GetURLForComponent(char* URL) { } void encodeNFrames(const std::shared_ptr& component, - std::mutex &queueLock, std::condition_variable& queueCondition, + std::mutex& queueLock, std::condition_variable& queueCondition, std::list>& workQueue, - std::list& flushedIndices, - std::shared_ptr& graphicPool, - std::ifstream& eleStream, bool& disableTest, - uint32_t frameID, uint32_t nFrames, uint32_t nWidth, - int32_t nHeight, bool flushed = false, bool signalEOS = true) { + std::list& flushedIndices, std::shared_ptr& graphicPool, + std::ifstream& eleStream, bool& disableTest, uint32_t frameID, uint32_t nFrames, + uint32_t nWidth, int32_t nHeight, bool flushed = false, bool signalEOS = true) { typedef std::unique_lock ULock; uint32_t maxRetry = 0; @@ -313,8 +301,7 @@ void encodeNFrames(const std::shared_ptr& comp if (!work && (maxRetry >= MAX_RETRY)) { ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout"; } - if (signalEOS && (nFrames == 1)) - flags |= C2FrameData::FLAG_END_OF_STREAM; + if (signalEOS && (nFrames == 1)) flags |= C2FrameData::FLAG_END_OF_STREAM; if (flushed) { flags |= SYNC_FRAME; flushed = false; @@ -335,9 +322,9 @@ void encodeNFrames(const std::shared_ptr& comp ASSERT_EQ(eleStream.gcount(), bytesCount); } std::shared_ptr block; - err = graphicPool->fetchGraphicBlock( - nWidth, nHeight, HAL_PIXEL_FORMAT_YV12, - {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block); + err = graphicPool->fetchGraphicBlock(nWidth, nHeight, HAL_PIXEL_FORMAT_YV12, + {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, + &block); if (err != C2_OK) { fprintf(stderr, "fetchGraphicBlock failed : %d\n", err); disableTest = true; @@ -380,27 +367,32 @@ void encodeNFrames(const std::shared_ptr& comp } } -TEST_F(Codec2VideoEncHidlTest, validateCompName) { - if (mDisableTest) return; +TEST_P(Codec2VideoEncHidlTest, validateCompName) { + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ALOGV("Checks if the given component is a valid video component"); validateComponent(mComponent, mCompName, mDisableTest); ASSERT_EQ(mDisableTest, false); } -class Codec2VideoEncEncodeTest : public Codec2VideoEncHidlTest, - public ::testing::WithParamInterface { +class Codec2VideoEncEncodeTest + : public Codec2VideoEncHidlTestBase, + public ::testing::WithParamInterface> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } }; TEST_P(Codec2VideoEncEncodeTest, EncodeTest) { description("Encodes input file"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; char mURL[512]; int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH; int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT; - bool signalEOS = GetParam(); + bool signalEOS = !std::get<2>(GetParam()).compare("true"); - strcpy(mURL, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); GetURLForComponent(mURL); std::ifstream eleStream; @@ -425,10 +417,9 @@ TEST_P(Codec2VideoEncEncodeTest, EncodeTest) { return; } ASSERT_EQ(mComponent->start(), C2_OK); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - 0, ENC_NUM_FRAMES, nWidth, nHeight, false, signalEOS)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0, + ENC_NUM_FRAMES, nWidth, nHeight, false, signalEOS)); // mDisableTest will be set if buffer was not fetched properly. // This may happen when resolution is not proper but config suceeded // In this cases, we skip encoding the input stream @@ -441,25 +432,21 @@ TEST_P(Codec2VideoEncEncodeTest, EncodeTest) { // If EOS is not sent, sending empty input with EOS flag inputFrames = ENC_NUM_FRAMES; if (!signalEOS) { - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); - ASSERT_NO_FATAL_FAILURE( - testInputBuffer(mComponent, mQueueLock, mWorkQueue, - C2FrameData::FLAG_END_OF_STREAM, false)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1)); + ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue, + C2FrameData::FLAG_END_OF_STREAM, false)); inputFrames += 1; } // blocking call to ensures application to Wait till all the inputs are // consumed ALOGD("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); eleStream.close(); if (mFramesReceived != inputFrames) { ALOGE("Input buffer count and Output buffer count mismatch"); - ALOGE("framesReceived : %d inputFrames : %d", mFramesReceived, - inputFrames); + ALOGE("framesReceived : %d inputFrames : %d", mFramesReceived, inputFrames); ASSERT_TRUE(false); } @@ -475,13 +462,9 @@ TEST_P(Codec2VideoEncEncodeTest, EncodeTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -// EncodeTest with EOS / No EOS -INSTANTIATE_TEST_CASE_P(EncodeTestwithEOS, Codec2VideoEncEncodeTest, - ::testing::Values(true, false)); - -TEST_F(Codec2VideoEncHidlTest, EOSTest) { +TEST_P(Codec2VideoEncHidlTest, EOSTest) { description("Test empty input buffer with EOS flag"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; ASSERT_EQ(mComponent->start(), C2_OK); typedef std::unique_lock ULock; @@ -519,15 +502,15 @@ TEST_F(Codec2VideoEncHidlTest, EOSTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2VideoEncHidlTest, FlushTest) { +TEST_P(Codec2VideoEncHidlTest, FlushTest) { description("Test Request for flush"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; typedef std::unique_lock ULock; char mURL[512]; int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH; int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT; - strcpy(mURL, gEnv->getRes().c_str()); + strcpy(mURL, sResourceDir.c_str()); GetURLForComponent(mURL); if (!setupConfigParam(nWidth, nHeight)) { @@ -544,10 +527,9 @@ TEST_F(Codec2VideoEncHidlTest, FlushTest) { eleStream.open(mURL, std::ifstream::binary); ASSERT_EQ(eleStream.is_open(), true); ALOGV("mURL : %s", mURL); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - 0, numFramesFlushed, nWidth, nHeight)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0, + numFramesFlushed, nWidth, nHeight)); // mDisableTest will be set if buffer was not fetched properly. // This may happen when resolution is not proper but config suceeded // In this cases, we skip encoding the input stream @@ -558,23 +540,20 @@ TEST_F(Codec2VideoEncHidlTest, FlushTest) { } std::list> flushedWork; - c2_status_t err = - mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); + c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); uint64_t frameIndex; { - //Update mFlushedIndices based on the index received from flush() + // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); frameIndex = work->input.ordinal.frameIndex.peeku(); - std::list::iterator frameIndexIt = std::find( - mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::list::iterator frameIndexIt = + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -583,11 +562,10 @@ TEST_F(Codec2VideoEncHidlTest, FlushTest) { } } mFlushedIndices.clear(); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - numFramesFlushed, numFrames - numFramesFlushed, - nWidth, nHeight, true)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, + numFramesFlushed, numFrames - numFramesFlushed, nWidth, + nHeight, true)); eleStream.close(); // mDisableTest will be set if buffer was not fetched properly. // This may happen when resolution is not proper but config suceeded @@ -600,19 +578,17 @@ TEST_F(Codec2VideoEncHidlTest, FlushTest) { err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork); ASSERT_EQ(err, C2_OK); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, - (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, + (size_t)MAX_INPUT_BUFFERS - flushedWork.size())); { - //Update mFlushedIndices based on the index received from flush() + // Update mFlushedIndices based on the index received from flush() ULock l(mQueueLock); for (std::unique_ptr& work : flushedWork) { ASSERT_NE(work, nullptr); frameIndex = work->input.ordinal.frameIndex.peeku(); - std::list::iterator frameIndexIt = std::find( - mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); - if (!mFlushedIndices.empty() && - (frameIndexIt != mFlushedIndices.end())) { + std::list::iterator frameIndexIt = + std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex); + if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) { mFlushedIndices.erase(frameIndexIt); work->input.buffers.clear(); work->worklets.clear(); @@ -624,9 +600,9 @@ TEST_F(Codec2VideoEncHidlTest, FlushTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -TEST_F(Codec2VideoEncHidlTest, InvalidBufferTest) { +TEST_P(Codec2VideoEncHidlTest, InvalidBufferTest) { description("Tests feeding larger/smaller input buffer"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; std::ifstream eleStream; int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH / 2; @@ -638,28 +614,24 @@ TEST_F(Codec2VideoEncHidlTest, InvalidBufferTest) { } ASSERT_EQ(mComponent->start(), C2_OK); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - 0, 1, nWidth, nHeight, false, false)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0, + 1, nWidth, nHeight, false, false)); // Feed larger input buffer. - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - 1, 1, nWidth*2, nHeight*2, false, false)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 1, + 1, nWidth * 2, nHeight * 2, false, false)); // Feed smaller input buffer. - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - 2, 1, nWidth/2, nHeight/2, false, true)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 2, + 1, nWidth / 2, nHeight / 2, false, true)); // blocking call to ensures application to Wait till all the inputs are // consumed ALOGD("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); if (mFramesReceived != 3) { std::cout << "[ WARN ] Component didn't receive all buffers back \n"; @@ -674,17 +646,23 @@ TEST_F(Codec2VideoEncHidlTest, InvalidBufferTest) { ASSERT_EQ(mComponent->stop(), C2_OK); } -class Codec2VideoEncResolutionTest : public Codec2VideoEncHidlTest, - public ::testing::WithParamInterface > { +class Codec2VideoEncResolutionTest + : public Codec2VideoEncHidlTestBase, + public ::testing::WithParamInterface< + std::tuple> { + void getParams() { + mInstanceName = std::get<0>(GetParam()); + mComponentName = std::get<1>(GetParam()); + } }; TEST_P(Codec2VideoEncResolutionTest, ResolutionTest) { description("Tests encoding at different resolutions"); - if (mDisableTest) return; + if (mDisableTest) GTEST_SKIP() << "Test is disabled"; std::ifstream eleStream; - int32_t nWidth = GetParam().first; - int32_t nHeight = GetParam().second; + int32_t nWidth = std::stoi(std::get<2>(GetParam())); + int32_t nHeight = std::stoi(std::get<3>(GetParam())); ALOGD("Trying encode for width %d height %d", nWidth, nHeight); mEos = false; @@ -694,10 +672,9 @@ TEST_P(Codec2VideoEncResolutionTest, ResolutionTest) { } ASSERT_EQ(mComponent->start(), C2_OK); - ASSERT_NO_FATAL_FAILURE( - encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, - mFlushedIndices, mGraphicPool, eleStream, mDisableTest, - 0, MAX_INPUT_BUFFERS, nWidth, nHeight, false, true)); + ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue, + mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0, + MAX_INPUT_BUFFERS, nWidth, nHeight, false, true)); // mDisableTest will be set if buffer was not fetched properly. // This may happen when resolution is not proper but config suceeded @@ -709,31 +686,52 @@ TEST_P(Codec2VideoEncResolutionTest, ResolutionTest) { } ALOGD("Waiting for input consumption"); - ASSERT_NO_FATAL_FAILURE( - waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); + ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue)); ASSERT_EQ(mEos, true); ASSERT_EQ(mComponent->stop(), C2_OK); ASSERT_EQ(mComponent->reset(), C2_OK); } -INSTANTIATE_TEST_CASE_P(NonStdSizes, Codec2VideoEncResolutionTest, ::testing::Values( - std::make_pair(52, 18), - std::make_pair(365, 365), - std::make_pair(484, 362), - std::make_pair(244, 488))); +INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoEncHidlTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + +INSTANTIATE_TEST_SUITE_P(NonStdSizes, Codec2VideoEncResolutionTest, + ::testing::ValuesIn(kEncodeResolutionTestParameters)); + +// EncodeTest with EOS / No EOS +INSTANTIATE_TEST_SUITE_P(EncodeTestwithEOS, Codec2VideoEncEncodeTest, + ::testing::ValuesIn(kEncodeTestParameters)); } // anonymous namespace int main(int argc, char** argv) { - gEnv = new ComponentTestEnvironment(); - ::testing::AddGlobalTestEnvironment(gEnv); - ::testing::InitGoogleTest(&argc, argv); - gEnv->init(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - int status = RUN_ALL_TESTS(); - LOG(INFO) << "C2 Test result = " << status; + kTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_ENCODER); + for (auto params : kTestParameters) { + kEncodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "true")); + kEncodeTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "false")); + + kEncodeResolutionTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "52", "18")); + kEncodeResolutionTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "365", "365")); + kEncodeResolutionTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "484", "362")); + kEncodeResolutionTestParameters.push_back( + std::make_tuple(std::get<0>(params), std::get<1>(params), "244", "488")); } - return status; -} + + // Set the resource directory based on command line args. + // Test will fail to set up if the argument is not set. + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-P") == 0 && i < argc - 1) { + sResourceDir = argv[i + 1]; + break; + } + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.xml b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.xml new file mode 100644 index 0000000000..260a61661f --- /dev/null +++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h index e37ca38411..d3a693bff0 100644 --- a/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h +++ b/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h @@ -29,5 +29,4 @@ * Common video utils */ - #endif // MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H