Upstream changes from Codec2 MTS
This includes changes up to commit
b3c2c12135ad6e96ca3cfa258bba24eb7b7b92ca.
Test: Builds
Bug: 112362730
Bug: 119853704
Change-Id: I97adbe52258d72d18446f12a9698462174e89b19
diff --git a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
index 6fd9200..1e87f38 100644
--- a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
@@ -156,63 +156,31 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
- (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE)) {
- configParam.push_back(param);
+ if (!work->worklets.empty()) {
+ // For decoder components current timestamp always exceeds
+ // previous timestamp
+ 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();
+ 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);
}
}
- mComponent->config(configParam, C2_DONT_BLOCK, &failures);
- ASSERT_EQ(failures.size(), 0u);
- }
- mFramesReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
- ALOGV("WorkDone: frameID received %d",
- (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
-
- // For decoder components current timestamp always exceeds
- // previous timestamp
- 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();
- 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);
- }
- }
-
- work->input.buffers.clear();
- work->worklets.clear();
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ bool mCsd = false;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
+ (void)mCsd;
}
}
}
@@ -418,11 +386,11 @@
}
}
-void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &linearPool,
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& linearPool,
std::ifstream& eleStream,
android::Vector<FrameInfo>* Info,
int offset, int range, bool signalEOS = true) {
@@ -462,34 +430,37 @@
}
int size = (*Info)[frameID].bytesCount;
char* data = (char*)malloc(size);
+ ASSERT_NE(data, nullptr);
eleStream.read(data, size);
ASSERT_EQ(eleStream.gcount(), size);
- std::shared_ptr<C2LinearBlock> block;
- ASSERT_EQ(C2_OK,
- linearPool->fetchLinearBlock(
- size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
- &block));
- ASSERT_TRUE(block);
-
- // Write View
- C2WriteView view = block->map().get();
- if (view.error() != C2_OK) {
- fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
- break;
- }
- ASSERT_EQ((size_t)size, view.capacity());
- ASSERT_EQ(0u, view.offset());
- ASSERT_EQ((size_t)size, view.size());
-
- memcpy(view.base(), data, size);
-
work->input.buffers.clear();
- work->input.buffers.emplace_back(new LinearBuffer(block));
+ if (size) {
+ std::shared_ptr<C2LinearBlock> block;
+ ASSERT_EQ(C2_OK,
+ linearPool->fetchLinearBlock(
+ size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+ &block));
+ ASSERT_TRUE(block);
+
+ // Write View
+ C2WriteView view = block->map().get();
+ if (view.error() != C2_OK) {
+ fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+ break;
+ }
+ ASSERT_EQ((size_t)size, view.capacity());
+ ASSERT_EQ(0u, view.offset());
+ ASSERT_EQ((size_t)size, view.size());
+
+ memcpy(view.base(), data, size);
+
+ work->input.buffers.emplace_back(new LinearBuffer(block));
+ free(data);
+ }
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
@@ -502,29 +473,6 @@
}
}
-void waitOnInputConsumption(std::mutex& queueLock,
- std::condition_variable& queueCondition,
- std::list<std::unique_ptr<C2Work>>& workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- uint32_t maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
TEST_F(Codec2AudioDecHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid audio component");
@@ -718,7 +666,6 @@
ASSERT_EQ(mComponent->queue(&items), C2_OK);
{
- typedef std::unique_lock<std::mutex> ULock;
ULock l(mQueueLock);
if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
mQueueCondition.wait_for(l, TIME_OUT);
@@ -729,46 +676,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2AudioDecHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- typedef std::unique_lock<std::mutex> ULock;
- ASSERT_EQ(mComponent->start(), C2_OK);
- std::unique_ptr<C2Work> work;
- // Prepare C2Work
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
- }
- }
- ASSERT_NE(work, nullptr);
-
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
-
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2AudioDecHidlTest, FlushTest) {
description("Tests Flush calls");
if (mDisableTest) return;
@@ -891,6 +798,72 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
+TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
+ description("Decode with multiple empty input frames");
+ if (mDisableTest) return;
+
+ 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());
+ GetURLForComponent(mCompName, mURL, info);
+
+ eleInfo.open(info);
+ ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+ android::Vector<FrameInfo> Info;
+ int bytesCount = 0;
+ uint32_t frameId = 0;
+ uint32_t flags = 0;
+ uint32_t timestamp = 0;
+ bool codecConfig = false;
+ // This test introduces empty CSD after every 20th frame
+ // and empty input frames at an interval of 5 frames.
+ while (1) {
+ if (!(frameId % 5)) {
+ 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;
+ }
+ Info.push_back({bytesCount, flags, timestamp});
+ frameId++;
+ }
+ eleInfo.close();
+
+ 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()));
+
+ // 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));
+ }
+
+ eleStream.close();
+ if (mFramesReceived != Info.size()) {
+ ALOGE("Input buffer count and Output buffer count mismatch");
+ ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+ Info.size());
+ ASSERT_TRUE(false);
+ }
+
+ ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
} // anonymous namespace
int main(int argc, char** argv) {
diff --git a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
index 4f86aad..5d66ee5 100644
--- a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
@@ -96,6 +96,7 @@
const StringToName kStringToName[] = {
{"aac", aac},
{"flac", flac},
+ {"opus", opus},
{"amrnb", amrnb},
{"amrwb", amrwb},
};
@@ -135,45 +136,17 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
- mCsd = true;
- }
- }
- }
- mFramesReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
- ALOGV("WorkDone: frameID received %d",
- (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
- work->input.buffers.clear();
- work->worklets.clear();
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ if (!work->worklets.empty()) {
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
}
}
}
enum standardComp {
aac,
flac,
+ opus,
amrnb,
amrwb,
unknown_comp,
@@ -275,6 +248,8 @@
"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) {
@@ -285,11 +260,11 @@
}
}
-void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &linearPool,
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& linearPool,
std::ifstream& eleStream, uint32_t nFrames,
int32_t samplesPerFrame, int32_t nChannels,
int32_t nSampleRate, bool flushed = false,
@@ -334,6 +309,7 @@
flushedIndices.emplace_back(frameID);
}
char* data = (char*)malloc(bytesCount);
+ ASSERT_NE(data, nullptr);
eleStream.read(data, bytesCount);
ASSERT_EQ(eleStream.gcount(), bytesCount);
std::shared_ptr<C2LinearBlock> block;
@@ -372,29 +348,6 @@
}
}
-void waitOnInputConsumption(std::mutex& queueLock,
- std::condition_variable& queueCondition,
- std::list<std::unique_ptr<C2Work>>& workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- uint32_t maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
TEST_F(Codec2AudioEncHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid audio component");
@@ -425,6 +378,11 @@
nSampleRate = 48000;
samplesPerFrame = 1152;
break;
+ case opus:
+ nChannels = 2;
+ nSampleRate = 48000;
+ samplesPerFrame = 960;
+ break;
case amrnb:
nChannels = 1;
nSampleRate = 8000;
@@ -458,7 +416,7 @@
ALOGE("framesReceived : %d inputFrames : %u", mFramesReceived, numFrames);
ASSERT_TRUE(false);
}
- if ((mCompName == flac || mCompName == aac)) {
+ if ((mCompName == flac || mCompName == opus || mCompName == aac)) {
if (!mCsd) {
ALOGE("CSD buffer missing");
ASSERT_TRUE(false);
@@ -508,46 +466,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2AudioEncHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- ASSERT_EQ(mComponent->start(), C2_OK);
-
- typedef std::unique_lock<std::mutex> ULock;
- std::unique_ptr<C2Work> work;
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ALOGE("mWorkQueue Empty is not expected at the start of the test");
- ASSERT_TRUE(false);
- }
- }
- ASSERT_NE(work, nullptr);
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
- uint32_t queueSize;
- {
- ULock l(mQueueLock);
- queueSize = mWorkQueue.size();
- if (queueSize < MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2AudioEncHidlTest, FlushTest) {
description("Test Request for flush");
if (mDisableTest) return;
@@ -574,6 +492,11 @@
nSampleRate = 48000;
samplesPerFrame = 1152;
break;
+ case opus:
+ nChannels = 2;
+ nSampleRate = 48000;
+ samplesPerFrame = 960;
+ break;
case amrnb:
nChannels = 1;
nSampleRate = 8000;
diff --git a/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h b/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
index 89eb69e..4d773ce 100644
--- a/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
@@ -17,8 +17,5 @@
#ifndef MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
#define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
-#define MAX_RETRY 20
-#define TIME_OUT 200ms
-#define MAX_INPUT_BUFFERS 8
#endif // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
index fdccdbb..64a458c 100644
--- a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
@@ -14,39 +14,115 @@
* limitations under the License.
*/
+// #define LOG_NDEBUG 0
#define LOG_TAG "media_c2_hidl_test_common"
#include <stdio.h>
#include "media_c2_hidl_test_common.h"
-using ::android::hardware::media::c2::V1_0::FieldSupportedValues;
-void dumpFSV(const FieldSupportedValues& sv) {
- ALOGD("Dumping FSV data");
- using namespace std;
- if (sv.type == FieldSupportedValues::Type::EMPTY) {
- ALOGD("FSV Value is Empty");
- }
- if (sv.type == FieldSupportedValues::Type::RANGE) {
- ALOGD("Dumping FSV range");
- cout << ".range(" << sv.range.min;
- if (sv.range.step != 0) {
- cout << ":" << sv.range.step;
+// Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set
+void testInputBuffer(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+ uint32_t flags, bool isNullBuffer) {
+ std::unique_ptr<C2Work> work;
+ {
+ typedef std::unique_lock<std::mutex> ULock;
+ ULock l(queueLock);
+ if (!workQueue.empty()) {
+ work.swap(workQueue.front());
+ workQueue.pop_front();
+ } else {
+ ASSERT_TRUE(false) << "workQueue Empty at the start of test";
}
- if (sv.range.num != 1 || sv.range.denom != 1) {
- cout << ":" << sv.range.num << "/" << sv.range.denom;
- }
- cout << " " << sv.range.max << ")";
}
- if (sv.values.size()) {
- ALOGD("Dumping FSV value");
- cout << (sv.type == FieldSupportedValues::Type::FLAGS ? ".flags("
- : ".list(");
- const char* sep = "";
- for (const auto& p : sv.values) {
- cout << sep << p;
- sep = ",";
- }
- cout << ")";
+ ASSERT_NE(work, nullptr);
+
+ work->input.flags = (C2FrameData::flags_t)flags;
+ work->input.ordinal.timestamp = 0;
+ work->input.ordinal.frameIndex = 0;
+ work->input.buffers.clear();
+ if (isNullBuffer) {
+ work->input.buffers.emplace_back(nullptr);
}
- cout << endl;
+ work->worklets.clear();
+ work->worklets.emplace_back(new C2Worklet);
+
+ std::list<std::unique_ptr<C2Work>> items;
+ items.push_back(std::move(work));
+ ASSERT_EQ(component->queue(&items), C2_OK);
}
+
+// Wait for all the inputs to be consumed by the plugin.
+void waitOnInputConsumption(std::mutex& queueLock,
+ std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ size_t bufferCount) {
+ typedef std::unique_lock<std::mutex> ULock;
+ uint32_t queueSize;
+ uint32_t maxRetry = 0;
+ {
+ ULock l(queueLock);
+ queueSize = workQueue.size();
+ }
+ while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
+ ULock l(queueLock);
+ if (queueSize != workQueue.size()) {
+ queueSize = workQueue.size();
+ maxRetry = 0;
+ } else {
+ queueCondition.wait_for(l, TIME_OUT);
+ maxRetry++;
+ }
+ }
+}
+
+// process onWorkDone received by Listener
+void workDone(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& 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<std::unique_ptr<C2Param>> updates =
+ std::move(work->worklets.front()->output.configUpdate);
+ std::vector<C2Param*> configParam;
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ for (size_t i = 0; i < updates.size(); ++i) {
+ C2Param* param = updates[i].get();
+ if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
+ csd = true;
+ } else if ((param->index() ==
+ C2StreamSampleRateInfo::output::PARAM_TYPE) ||
+ (param->index() ==
+ C2StreamChannelCountInfo::output::PARAM_TYPE) ||
+ (param->index() ==
+ C2VideoSizeStreamInfo::output::PARAM_TYPE)) {
+ configParam.push_back(param);
+ }
+ }
+ component->config(configParam, C2_DONT_BLOCK, &failures);
+ ASSERT_EQ(failures.size(), 0u);
+ }
+ framesReceived++;
+ 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",
+ (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
+ work->input.buffers.clear();
+ work->worklets.clear();
+ {
+ typedef std::unique_lock<std::mutex> ULock;
+ ULock l(queueLock);
+ workQueue.push_back(std::move(work));
+ if (!flushedIndices.empty()) {
+ flushedIndices.erase(frameIndexIt);
+ }
+ queueCondition.notify_all();
+ }
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
index f765baa..a688530 100644
--- a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
@@ -22,6 +22,7 @@
#include <android/hardware/media/c2/1.0/types.h>
#include <C2Component.h>
+#include <C2Config.h>
#include <getopt.h>
#include <hidl/HidlSupport.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -38,6 +39,10 @@
#include <VtsHalHidlTargetTestEnvBase.h>
+#define MAX_RETRY 20
+#define TIME_OUT 400ms
+#define MAX_INPUT_BUFFERS 8
+
/*
* Handle Callback functions onWorkDone(), onTripped(),
* onError(), onDeath(), onFramesRendered()
@@ -176,5 +181,21 @@
/*
* common functions declarations
*/
-void dumpFSV(const FieldSupportedValues& sv);
+void testInputBuffer(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+ uint32_t flags, bool isNullBuffer);
+
+void waitOnInputConsumption(std::mutex& queueLock,
+ std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ size_t bufferCount = MAX_INPUT_BUFFERS);
+
+void workDone(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+ uint32_t& framesReceived);
+
#endif // MEDIA_C2_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
index b7fb655..ec803d7 100644
--- a/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
@@ -38,14 +38,21 @@
public:
virtual void SetUp() override {
Super::SetUp();
+ mEos = false;
mClient = android::Codec2Client::CreateFromService(
gEnv->getInstance().c_str());
ASSERT_NE(mClient, nullptr);
- mListener.reset(new CodecListener());
+ mListener.reset(new CodecListener(
+ [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+ handleWorkDone(workItems);
+ }));
ASSERT_NE(mListener, nullptr);
mClient->createComponent(gEnv->getComponent().c_str(), mListener,
&mComponent);
ASSERT_NE(mComponent, nullptr);
+ for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+ mWorkQueue.emplace_back(new C2Work);
+ }
}
virtual void TearDown() override {
@@ -59,6 +66,23 @@
}
Super::TearDown();
}
+ // callback function to process onWorkDone received by Listener
+ void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+ for (std::unique_ptr<C2Work>& work : workItems) {
+ if (!work->worklets.empty()) {
+ bool mCsd = false;
+ uint32_t mFramesReceived = 0;
+ std::list<uint64_t> mFlushedIndices;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition,
+ mWorkQueue, mEos, mCsd, mFramesReceived);
+ }
+ }
+ }
+
+ bool mEos;
+ std::mutex mQueueLock;
+ std::condition_variable mQueueCondition;
+ std::list<std::unique_ptr<C2Work>> mWorkQueue;
std::shared_ptr<android::Codec2Client> mClient;
std::shared_ptr<android::Codec2Client::Listener> mListener;
@@ -135,8 +159,6 @@
ALOGV("Multiple Start Stop and Reset Test");
c2_status_t err = C2_OK;
-#define MAX_RETRY 16
-
for (size_t i = 0; i < MAX_RETRY; i++) {
err = mComponent->start();
ASSERT_EQ(err, C2_OK);
@@ -184,13 +206,44 @@
ASSERT_EQ(err, C2_OK);
ASSERT_EQ(failures.size(), 0u);
-#define MAX_RETRY 16
for (size_t i = 0; i < MAX_RETRY; i++) {
err = mComponent->release();
ASSERT_EQ(err, C2_OK);
}
}
+class Codec2ComponentInputTests : public Codec2ComponentHidlTest,
+ public ::testing::WithParamInterface<std::pair<uint32_t, bool> > {
+};
+
+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)));
+
} // anonymous namespace
// TODO: Add test for Invalid work,
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1 b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1
new file mode 100644
index 0000000..1d67af9
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info
new file mode 100644
index 0000000..cc51168
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info
@@ -0,0 +1,300 @@
+6027 1 0
+6879 0 33000
+5 0 66000
+532 0 100000
+5 0 133000
+2458 0 166000
+5 0 200000
+475 0 233000
+5 0 266000
+1262 0 300000
+5 0 333000
+554 0 366000
+27 0 400000
+6971 0 433000
+5 0 466000
+601 0 500000
+5 0 533000
+3276 0 566000
+5 0 600000
+658 0 633000
+5 0 666000
+1680 0 700000
+5 0 733000
+610 0 766000
+24 0 800000
+6728 0 833000
+5 0 866000
+764 0 900000
+5 0 933000
+2656 0 966000
+5 0 1000000
+462 0 1033000
+5 0 1066000
+1459 0 1100000
+5 0 1133000
+608 0 1166000
+24 0 1200000
+7038 0 1233000
+5 0 1266000
+721 0 1300000
+5 0 1333000
+3102 0 1366000
+5 0 1400000
+752 0 1433000
+5 0 1466000
+1815 0 1500000
+5 0 1533000
+755 0 1566000
+25 0 1600000
+7657 0 1633000
+5 0 1666000
+852 0 1700000
+5 0 1733000
+3537 0 1766000
+5 0 1800000
+673 0 1833000
+5 0 1866000
+1774 0 1900000
+5 0 1933000
+554 0 1966000
+24 0 2000000
+8028 0 2033000
+5 0 2066000
+715 0 2100000
+5 0 2133000
+3395 0 2166000
+5 0 2200000
+736 0 2233000
+5 0 2266000
+1759 0 2300000
+5 0 2333000
+605 0 2366000
+23 0 2400000
+7651 0 2433000
+5 0 2466000
+619 0 2500000
+5 0 2533000
+2788 0 2566000
+5 0 2600000
+556 0 2633000
+5 0 2666000
+1335 0 2700000
+5 0 2733000
+521 0 2766000
+24 0 2800000
+2274 0 2833000
+676 0 2866000
+25 0 2900000
+6224 0 2933000
+5798 0 2966000
+5 0 3000000
+448 0 3033000
+5 0 3066000
+1950 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1218 0 3233000
+5 0 3266000
+1316 0 3300000
+5 0 3333000
+580 0 3366000
+26 0 3400000
+6673 0 3433000
+5 0 3466000
+473 0 3500000
+5 0 3533000
+2467 0 3566000
+5 0 3600000
+429 0 3633000
+5 0 3666000
+1420 0 3700000
+5 0 3733000
+583 0 3766000
+29 0 3800000
+8492 0 3833000
+5 0 3866000
+720 0 3900000
+5 0 3933000
+3635 0 3966000
+5 0 4000000
+621 0 4033000
+5 0 4066000
+1969 0 4100000
+5 0 4133000
+49 0 4166000
+25 0 4200000
+7416 0 4233000
+5 0 4266000
+947 0 4300000
+5 0 4333000
+3713 0 4366000
+5 0 4400000
+714 0 4433000
+5 0 4466000
+2003 0 4500000
+5 0 4533000
+750 0 4566000
+25 0 4600000
+8470 0 4633000
+5 0 4666000
+737 0 4700000
+5 0 4733000
+4094 0 4766000
+5 0 4800000
+1019 0 4833000
+5 0 4866000
+2160 0 4900000
+5 0 4933000
+828 0 4966000
+24 0 5000000
+9282 0 5033000
+5 0 5066000
+655 0 5100000
+5 0 5133000
+3491 0 5166000
+5 0 5200000
+651 0 5233000
+5 0 5266000
+1906 0 5300000
+5 0 5333000
+662 0 5366000
+24 0 5400000
+9724 0 5433000
+5 0 5466000
+617 0 5500000
+5 0 5533000
+3145 0 5566000
+5 0 5600000
+578 0 5633000
+5 0 5666000
+1592 0 5700000
+5 0 5733000
+569 0 5766000
+25 0 5800000
+10015 0 5833000
+5 0 5866000
+609 0 5900000
+5 0 5933000
+3618 0 5966000
+5 0 6000000
+734 0 6033000
+5 0 6066000
+1748 0 6100000
+5 0 6133000
+550 0 6166000
+24 0 6200000
+8806 0 6233000
+5 0 6266000
+498 0 6300000
+5 0 6333000
+2913 0 6366000
+5 0 6400000
+597 0 6433000
+5 0 6466000
+1235 0 6500000
+5 0 6533000
+362 0 6566000
+24 0 6600000
+6592 0 6633000
+5 0 6666000
+468 0 6700000
+5 0 6733000
+1920 0 6766000
+5 0 6800000
+419 0 6833000
+5 0 6866000
+843 0 6900000
+5 0 6933000
+237 0 6966000
+24 0 7000000
+2687 0 7033000
+5 0 7066000
+399 0 7100000
+5 0 7133000
+200 0 7166000
+143 0 7200000
+25 0 7233000
+12603 0 7266000
+1139 0 7300000
+5 0 7333000
+56 0 7366000
+5 0 7400000
+273 0 7433000
+5 0 7466000
+48 0 7500000
+5 0 7533000
+102 0 7566000
+5 0 7600000
+39 0 7633000
+24 0 7666000
+3635 0 7700000
+5 0 7733000
+46 0 7766000
+5 0 7800000
+647 0 7833000
+5 0 7866000
+61 0 7900000
+5 0 7933000
+824 0 7966000
+5 0 8000000
+691 0 8033000
+27 0 8066000
+4573 0 8100000
+5 0 8133000
+473 0 8166000
+5 0 8200000
+1637 0 8233000
+5 0 8266000
+451 0 8300000
+5 0 8333000
+969 0 8366000
+5 0 8400000
+234 0 8433000
+24 0 8466000
+3361 0 8500000
+5 0 8533000
+168 0 8566000
+5 0 8600000
+662 0 8633000
+5 0 8666000
+129 0 8700000
+5 0 8733000
+443 0 8766000
+5 0 8800000
+183 0 8833000
+23 0 8866000
+2769 0 8900000
+5 0 8933000
+182 0 8966000
+5 0 9000000
+890 0 9033000
+5 0 9066000
+171 0 9100000
+5 0 9133000
+599 0 9166000
+5 0 9200000
+236 0 9233000
+23 0 9266000
+2316 0 9300000
+5 0 9333000
+333 0 9366000
+5 0 9400000
+759 0 9433000
+5 0 9466000
+210 0 9500000
+5 0 9533000
+324 0 9566000
+5 0 9600000
+98 0 9633000
+23 0 9666000
+1107 0 9700000
+5 0 9733000
+42 0 9766000
+5 0 9800000
+145 0 9833000
+5 0 9866000
+109 0 9900000
+89 0 9933000
+24 0 9966000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1 b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1
new file mode 100644
index 0000000..529bace
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info
new file mode 100644
index 0000000..fca7833
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info
@@ -0,0 +1,167 @@
+12571 1 0
+9881 0 33000
+5 0 66000
+544 0 100000
+5 0 133000
+2642 0 166000
+5 0 200000
+531 0 233000
+5 0 266000
+1359 0 300000
+5 0 333000
+551 0 366000
+28 0 400000
+10791 0 433000
+5 0 466000
+655 0 500000
+5 0 533000
+3769 0 566000
+5 0 600000
+711 0 633000
+5 0 666000
+2004 0 700000
+5 0 733000
+657 0 766000
+26 0 800000
+8969 0 833000
+5 0 866000
+630 0 900000
+5 0 933000
+2787 0 966000
+5 0 1000000
+404 0 1033000
+5 0 1066000
+1518 0 1100000
+5 0 1133000
+493 0 1166000
+26 0 1200000
+9900 0 1233000
+5 0 1266000
+620 0 1300000
+5 0 1333000
+3072 0 1366000
+5 0 1400000
+668 0 1433000
+5 0 1466000
+1821 0 1500000
+5 0 1533000
+682 0 1566000
+26 0 1600000
+9560 0 1633000
+5 0 1666000
+667 0 1700000
+5 0 1733000
+3249 0 1766000
+5 0 1800000
+589 0 1833000
+5 0 1866000
+1816 0 1900000
+5 0 1933000
+548 0 1966000
+26 0 2000000
+9916 0 2033000
+5 0 2066000
+628 0 2100000
+5 0 2133000
+3034 0 2166000
+5 0 2200000
+590 0 2233000
+5 0 2266000
+1581 0 2300000
+5 0 2333000
+524 0 2366000
+26 0 2400000
+8182 0 2433000
+5 0 2466000
+552 0 2500000
+5 0 2533000
+2412 0 2566000
+5 0 2600000
+489 0 2633000
+5 0 2666000
+1227 0 2700000
+5 0 2733000
+432 0 2766000
+26 0 2800000
+2017 0 2833000
+516 0 2866000
+26 0 2900000
+16619 0 2933000
+6710 0 2966000
+5 0 3000000
+425 0 3033000
+5 0 3066000
+1964 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1129 0 3233000
+5 0 3266000
+1156 0 3300000
+5 0 3333000
+486 0 3366000
+28 0 3400000
+10304 0 3433000
+5 0 3466000
+412 0 3500000
+5 0 3533000
+2608 0 3566000
+5 0 3600000
+397 0 3633000
+5 0 3666000
+1514 0 3700000
+5 0 3733000
+533 0 3766000
+26 0 3800000
+11698 0 3833000
+5 0 3866000
+542 0 3900000
+5 0 3933000
+3334 0 3966000
+5 0 4000000
+547 0 4033000
+5 0 4066000
+1809 0 4100000
+5 0 4133000
+55 0 4166000
+26 0 4200000
+9496 0 4233000
+5 0 4266000
+658 0 4300000
+5 0 4333000
+3232 0 4366000
+5 0 4400000
+600 0 4433000
+5 0 4466000
+1766 0 4500000
+5 0 4533000
+550 0 4566000
+25 0 4600000
+9951 0 4633000
+5 0 4666000
+624 0 4700000
+5 0 4733000
+3617 0 4766000
+5 0 4800000
+644 0 4833000
+5 0 4866000
+1841 0 4900000
+5 0 4933000
+649 0 4966000
+25 0 5000000
+9901 0 5033000
+5 0 5066000
+515 0 5100000
+5 0 5133000
+2814 0 5166000
+5 0 5200000
+511 0 5233000
+5 0 5266000
+1521 0 5300000
+5 0 5333000
+509 0 5366000
+26 0 5400000
+10579 0 5433000
+5 0 5466000
+575 0 5500000
+5 0 5533000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
index 8420cab..9a42d72 100644
--- a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
@@ -101,7 +101,7 @@
const StringToName kStringToName[] = {
{"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
- {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
+ {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1},
};
const size_t kNumStringToName =
@@ -142,79 +142,48 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if (param->index() ==
- C2VideoSizeStreamInfo::output::PARAM_TYPE) {
- ALOGV("Received C2VideoSizeStreamInfo");
- configParam.push_back(param);
- }
- }
- mComponent->config(configParam, C2_DONT_BLOCK, &failures);
- ASSERT_EQ(failures.size(), 0u);
- }
+ if (!work->worklets.empty()) {
+ // For decoder components current timestamp always exceeds
+ // previous timestamp
+ typedef std::unique_lock<std::mutex> 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();
- mFramesReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
-
- // For decoder components current timestamp always exceeds
- // previous timestamp
- typedef std::unique_lock<std::mutex> 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();
-
- ULock l(mQueueLock);
- if (mTimestampDevTest) {
- bool tsHit = false;
- std::list<uint64_t>::iterator it = mTimestampUslist.begin();
- while (it != mTimestampUslist.end()) {
- if (*it == mTimestampUs) {
- mTimestampUslist.erase(it);
- tsHit = true;
- break;
+ ULock l(mQueueLock);
+ if (mTimestampDevTest) {
+ bool tsHit = false;
+ std::list<uint64_t>::iterator it = mTimestampUslist.begin();
+ while (it != mTimestampUslist.end()) {
+ if (*it == mTimestampUs) {
+ mTimestampUslist.erase(it);
+ tsHit = true;
+ break;
+ }
+ it++;
}
- it++;
- }
- if (tsHit == false) {
- if (mTimestampUslist.empty() == false) {
- EXPECT_EQ(tsHit, true)
- << "TimeStamp not recognized";
- } else {
- std::cout << "[ INFO ] Received non-zero "
- "output / TimeStamp not recognized \n";
+ if (tsHit == false) {
+ if (mTimestampUslist.empty() == false) {
+ EXPECT_EQ(tsHit, true)
+ << "TimeStamp not recognized";
+ } else {
+ std::cout << "[ INFO ] Received non-zero "
+ "output / TimeStamp not recognized \n";
+ }
}
}
}
- }
-
- work->input.buffers.clear();
- work->worklets.clear();
- {
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ bool mCsd;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
+ (void)mCsd;
}
}
}
@@ -227,6 +196,7 @@
hevc,
vp8,
vp9,
+ av1,
unknown_comp,
};
@@ -341,6 +311,11 @@
"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) {
@@ -352,11 +327,11 @@
}
}
-void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &linearPool,
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& linearPool,
std::ifstream& eleStream,
android::Vector<FrameInfo>* Info,
int offset, int range, bool signalEOS = true) {
@@ -397,35 +372,37 @@
int size = (*Info)[frameID].bytesCount;
char* data = (char*)malloc(size);
+ ASSERT_NE(data, nullptr);
eleStream.read(data, size);
ASSERT_EQ(eleStream.gcount(), size);
- std::shared_ptr<C2LinearBlock> block;
- ASSERT_EQ(C2_OK,
- linearPool->fetchLinearBlock(
- size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
- &block));
- ASSERT_TRUE(block);
-
- // Write View
- C2WriteView view = block->map().get();
- if (view.error() != C2_OK) {
- fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
- break;
- }
- ASSERT_EQ((size_t)size, view.capacity());
- ASSERT_EQ(0u, view.offset());
- ASSERT_EQ((size_t)size, view.size());
-
- memcpy(view.base(), data, size);
-
work->input.buffers.clear();
- work->input.buffers.emplace_back(new LinearBuffer(block));
+ if (size) {
+ std::shared_ptr<C2LinearBlock> block;
+ ASSERT_EQ(C2_OK,
+ linearPool->fetchLinearBlock(
+ size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+ &block));
+ ASSERT_TRUE(block);
+
+ // Write View
+ C2WriteView view = block->map().get();
+ if (view.error() != C2_OK) {
+ fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+ break;
+ }
+ ASSERT_EQ((size_t)size, view.capacity());
+ ASSERT_EQ(0u, view.offset());
+ ASSERT_EQ((size_t)size, view.size());
+
+ memcpy(view.base(), data, size);
+
+ work->input.buffers.emplace_back(new LinearBuffer(block));
+ free(data);
+ }
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
-
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
@@ -437,29 +414,6 @@
}
}
-void waitOnInputConsumption(std::mutex& queueLock,
- std::condition_variable& queueCondition,
- std::list<std::unique_ptr<C2Work>>& workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- uint32_t maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
TEST_F(Codec2VideoDecHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid video component");
@@ -678,8 +632,8 @@
EXPECT_GE(mFramesReceived, 1U);
ASSERT_EQ(mEos, true);
ASSERT_EQ(mComponent->stop(), C2_OK);
- ASSERT_EQ(mComponent->release(), C2_OK);
}
+ ASSERT_EQ(mComponent->release(), C2_OK);
}
TEST_F(Codec2VideoDecHidlTest, EOSTest) {
@@ -712,7 +666,6 @@
ASSERT_EQ(mComponent->queue(&items), C2_OK);
{
- typedef std::unique_lock<std::mutex> ULock;
ULock l(mQueueLock);
if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
mQueueCondition.wait_for(l, TIME_OUT);
@@ -723,46 +676,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2VideoDecHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- typedef std::unique_lock<std::mutex> ULock;
- ASSERT_EQ(mComponent->start(), C2_OK);
- std::unique_ptr<C2Work> work;
- // Prepare C2Work
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
- }
- }
- ASSERT_NE(work, nullptr);
-
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
-
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2VideoDecHidlTest, FlushTest) {
description("Tests Flush calls");
if (mDisableTest) return;
@@ -874,6 +787,69 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
+TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) {
+ description("Decode with multiple empty input frames");
+ if (mDisableTest) return;
+
+ char mURL[512], info[512];
+ std::ifstream eleStream, eleInfo;
+
+ strcpy(mURL, gEnv->getRes().c_str());
+ strcpy(info, gEnv->getRes().c_str());
+ GetURLForComponent(mCompName, mURL, info);
+
+ eleInfo.open(info);
+ ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+ android::Vector<FrameInfo> Info;
+ int bytesCount = 0;
+ uint32_t frameId = 0;
+ uint32_t flags = 0;
+ uint32_t timestamp = 0;
+ bool codecConfig = false;
+ // This test introduces empty CSD after every 20th frame
+ // and empty input frames at an interval of 5 frames.
+ while (1) {
+ if (!(frameId % 5)) {
+ 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;
+ }
+ Info.push_back({bytesCount, flags, timestamp});
+ frameId++;
+ }
+ eleInfo.close();
+
+ ASSERT_EQ(mComponent->start(), C2_OK);
+ 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()));
+
+ // 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));
+ }
+
+ eleStream.close();
+ if (mFramesReceived != Info.size()) {
+ ALOGE("Input buffer count and Output buffer count mismatch");
+ ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+ Info.size());
+ ASSERT_TRUE(false);
+ }
+}
+
} // anonymous namespace
// TODO : Video specific configuration Test
diff --git a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
index 87b7902..8585c87 100644
--- a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
@@ -139,40 +139,11 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
- mCsd = true;
- }
- }
- }
- mFramesReceived++;
- if (work->result != C2_OK) mFailedWorkReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
- ALOGV("WorkDone: frameID received %d",
- (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
- work->input.buffers.clear();
- work->worklets.clear();
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ if (!work->worklets.empty()) {
+ if (work->result != C2_OK) mFailedWorkReceived++;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
}
}
}
@@ -272,11 +243,11 @@
strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
}
-void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &graphicPool,
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& graphicPool,
std::ifstream& eleStream, uint32_t frameID,
uint32_t nFrames, uint32_t nWidth, int32_t nHeight,
bool flushed = false,bool signalEOS = true) {
@@ -319,6 +290,7 @@
flushedIndices.emplace_back(frameID);
}
char* data = (char*)malloc(bytesCount);
+ ASSERT_NE(data, nullptr);
memset(data, 0, bytesCount);
if (eleStream.is_open()) {
eleStream.read(data, bytesCount);
@@ -365,30 +337,6 @@
}
}
-void waitOnInputConsumption(std::mutex &queueLock,
- std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- int maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
-
TEST_F(Codec2VideoEncHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid video component");
@@ -488,46 +436,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2VideoEncHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- ASSERT_EQ(mComponent->start(), C2_OK);
-
- typedef std::unique_lock<std::mutex> ULock;
- std::unique_ptr<C2Work> work;
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ALOGE("mWorkQueue Empty is not expected at the start of the test");
- ASSERT_TRUE(false);
- }
- }
- ASSERT_NE(work, nullptr);
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
- uint32_t queueSize;
- {
- ULock l(mQueueLock);
- queueSize = mWorkQueue.size();
- if (queueSize < MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2VideoEncHidlTest, FlushTest) {
description("Test Request for flush");
if (mDisableTest) return;
diff --git a/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h b/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
index 1215b13..dd45557 100644
--- a/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
@@ -17,9 +17,6 @@
#ifndef MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
#define MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
-#define MAX_RETRY 20
-#define TIME_OUT 400ms
-#define MAX_INPUT_BUFFERS 8
#define ENCODER_TIMESTAMP_INCREMENT 40000
#define ENC_NUM_FRAMES 32
#define ENC_DEFAULT_FRAME_WIDTH 352