Merge "FrameDecoder:Return error if dimension is missing" into sc-qpr1-dev
diff --git a/OWNERS b/OWNERS
index 7f523a2..0be1196 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,10 +1,8 @@
-chz@google.com
+# Bug component: 1344
elaurent@google.com
etalvala@google.com
hkuang@google.com
lajos@google.com
-marcone@google.com
-# LON
-olly@google.com
-andrewlewis@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/OWNERS b/media/OWNERS
index 3e194f0..4cf4870 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,24 +1,20 @@
-andrewlewis@google.com
-chz@google.com
-dwkang@google.com
+# Bug component: 1344
elaurent@google.com
essick@google.com
-gkasten@google.com
hkuang@google.com
hunga@google.com
jiabin@google.com
jmtrivi@google.com
lajos@google.com
-marcone@google.com
mnaganov@google.com
nchalko@google.com
-pawin@google.com
philburk@google.com
pmclean@google.com
quxiangfang@google.com
-rachad@google.com
rago@google.com
robertshih@google.com
taklee@google.com
-wjia@google.com
wonsik@google.com
+
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 342d771..57cdcd0 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -287,6 +287,7 @@
mOutputDelayRingBufferWritePos = 0;
mOutputDelayRingBufferReadPos = 0;
mOutputDelayRingBufferFilled = 0;
+ mOutputDelayRingBuffer.reset();
mBuffersInfo.clear();
status_t status = UNKNOWN_ERROR;
@@ -308,10 +309,7 @@
aacDecoder_Close(mAACDecoder);
mAACDecoder = nullptr;
}
- if (mOutputDelayRingBuffer) {
- delete[] mOutputDelayRingBuffer;
- mOutputDelayRingBuffer = nullptr;
- }
+ mOutputDelayRingBuffer.reset();
}
status_t C2SoftAacDec::initDecoder() {
@@ -327,7 +325,7 @@
mOutputDelayCompensated = 0;
mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
- mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
+ mOutputDelayRingBuffer.reset(new short[mOutputDelayRingBufferSize]);
mOutputDelayRingBufferWritePos = 0;
mOutputDelayRingBufferReadPos = 0;
mOutputDelayRingBufferFilled = 0;
diff --git a/media/codec2/components/aac/C2SoftAacDec.h b/media/codec2/components/aac/C2SoftAacDec.h
index 986187c..a03fc70 100644
--- a/media/codec2/components/aac/C2SoftAacDec.h
+++ b/media/codec2/components/aac/C2SoftAacDec.h
@@ -93,7 +93,7 @@
bool mEndOfOutput;
int32_t mOutputDelayCompensated;
int32_t mOutputDelayRingBufferSize;
- short *mOutputDelayRingBuffer;
+ std::unique_ptr<short[]> mOutputDelayRingBuffer;
int32_t mOutputDelayRingBufferWritePos;
int32_t mOutputDelayRingBufferReadPos;
int32_t mOutputDelayRingBufferFilled;
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 74b099c..9e3a823 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
@@ -100,8 +100,10 @@
ASSERT_NE(mLinearPool, nullptr);
std::vector<std::unique_ptr<C2Param>> queried;
- mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, C2_DONT_BLOCK, &queried);
- ASSERT_GT(queried.size(), 0);
+ c2_status_t c2err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+ C2_DONT_BLOCK, &queried);
+ ASSERT_EQ(c2err, C2_OK) << "Query media type failed";
+ ASSERT_EQ(queried.size(), 1) << "Size of the vector returned is invalid";
mMime = ((C2PortMediaTypeSetting::input*)queried[0].get())->m.value;
@@ -277,24 +279,20 @@
};
std::vector<std::unique_ptr<C2Param>> 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);
- } else {
- size_t offset = sizeof(C2Param);
- for (size_t i = 0; i < inParams.size(); ++i) {
- C2Param* param = inParams[i].get();
- bitStreamInfo[i] = *(int32_t*)((uint8_t*)param + offset);
- }
- if (mime.find("3gpp") != std::string::npos) {
- ASSERT_EQ(bitStreamInfo[0], 8000);
- ASSERT_EQ(bitStreamInfo[1], 1);
- } else if (mime.find("amr-wb") != std::string::npos) {
- ASSERT_EQ(bitStreamInfo[0], 16000);
- ASSERT_EQ(bitStreamInfo[1], 1);
- } else if (mime.find("gsm") != std::string::npos) {
- ASSERT_EQ(bitStreamInfo[0], 8000);
- }
+ ASSERT_EQ(status, C2_OK) << "Query sample rate and channel count info failed";
+ ASSERT_EQ(inParams.size(), indices.size()) << "Size of the vector returned is invalid";
+
+ bitStreamInfo[0] = C2StreamSampleRateInfo::output::From(inParams[0].get())->value;
+ bitStreamInfo[1] = C2StreamChannelCountInfo::output::From(inParams[1].get())->value;
+ if (mime.find("3gpp") != std::string::npos) {
+ ASSERT_EQ(bitStreamInfo[0], 8000);
+ ASSERT_EQ(bitStreamInfo[1], 1);
+ } else if (mime.find("amr-wb") != std::string::npos) {
+ ASSERT_EQ(bitStreamInfo[0], 16000);
+ ASSERT_EQ(bitStreamInfo[1], 1);
+ } else if (mime.find("gsm") != std::string::npos) {
+ ASSERT_EQ(bitStreamInfo[0], 8000);
+ ASSERT_EQ(bitStreamInfo[1], 1);
}
}
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 d77b943..bd7ec0d 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
@@ -73,26 +73,22 @@
ASSERT_NE(mLinearPool, nullptr);
std::vector<std::unique_ptr<C2Param>> queried;
- mComponent->query({}, {C2PortMediaTypeSetting::output::PARAM_TYPE}, C2_DONT_BLOCK,
- &queried);
- ASSERT_GT(queried.size(), 0);
+ c2_status_t c2err = mComponent->query({}, {C2PortMediaTypeSetting::output::PARAM_TYPE},
+ C2_DONT_BLOCK, &queried);
+ ASSERT_EQ(c2err, C2_OK) << "Query media type failed";
+ ASSERT_EQ(queried.size(), 1) << "Size of the vector returned is invalid";
mMime = ((C2PortMediaTypeSetting::output*)queried[0].get())->m.value;
mEos = false;
mCsd = false;
mFramesReceived = 0;
+ mEncoderFrameSize = 0;
mWorkResult = C2_OK;
mOutputSize = 0u;
- getInputMaxBufSize();
-
- c2_status_t status = getChannelCount(&mNumChannels);
- ASSERT_EQ(status, C2_OK) << "Unable to get supported channel count";
-
- status = getSampleRate(&mSampleRate);
- ASSERT_EQ(status, C2_OK) << "Unable to get supported sample rate";
-
- status = getSamplesPerFrame(mNumChannels, &mSamplesPerFrame);
- ASSERT_EQ(status, C2_OK) << "Unable to get supported number of samples per frame";
+ ASSERT_NO_FATAL_FAILURE(getInputMaxBufSize());
+ ASSERT_NO_FATAL_FAILURE(getChannelCount(&mNumChannels));
+ ASSERT_NO_FATAL_FAILURE(getSampleRate(&mSampleRate));
+ ASSERT_NO_FATAL_FAILURE(getSamplesPerFrame(mNumChannels, &mSamplesPerFrame));
getFile(mNumChannels, mSampleRate);
}
@@ -108,9 +104,9 @@
// Get the test parameters from GetParam call.
virtual void getParams() {}
- c2_status_t getChannelCount(int32_t* nChannels);
- c2_status_t getSampleRate(int32_t* nSampleRate);
- c2_status_t getSamplesPerFrame(int32_t nChannels, int32_t* samplesPerFrame);
+ void getChannelCount(int32_t* nChannels);
+ void getSampleRate(int32_t* nSampleRate);
+ void getSamplesPerFrame(int32_t nChannels, int32_t* samplesPerFrame);
void getFile(int32_t channelCount, int32_t sampleRate);
@@ -146,6 +142,7 @@
uint32_t mFramesReceived;
int32_t mInputMaxBufSize;
uint64_t mOutputSize;
+ uint32_t mEncoderFrameSize;
std::list<uint64_t> mFlushedIndices;
C2BlockPool::local_id_t mBlockPoolId;
@@ -173,21 +170,13 @@
// In encoder components, fetch the size of input buffer allocated
void getInputMaxBufSize() {
- int32_t bitStreamInfo[1] = {0};
std::vector<std::unique_ptr<C2Param>> 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);
- } else {
- size_t offset = sizeof(C2Param);
- for (size_t i = 0; i < inParams.size(); ++i) {
- C2Param* param = inParams[i].get();
- bitStreamInfo[i] = *(int32_t*)((uint8_t*)param + offset);
- }
- }
- mInputMaxBufSize = bitStreamInfo[0];
+ ASSERT_EQ(status, C2_OK) << "Query max buffer size info failed";
+ ASSERT_EQ(inParams.size(), 1) << "Size of the vector returned is invalid";
+
+ mInputMaxBufSize = C2StreamMaxBufferSizeInfo::input::From(inParams[0].get())->value;
}
};
@@ -243,17 +232,15 @@
return false;
}
-c2_status_t Codec2AudioEncHidlTestBase::getChannelCount(int32_t* nChannels) {
+void Codec2AudioEncHidlTestBase::getChannelCount(int32_t* nChannels) {
std::unique_ptr<C2StreamChannelCountInfo::input> channelCount =
std::make_unique<C2StreamChannelCountInfo::input>();
std::vector<C2FieldSupportedValuesQuery> validValueInfos = {
C2FieldSupportedValuesQuery::Current(
C2ParamField(channelCount.get(), &C2StreamChannelCountInfo::value))};
c2_status_t c2err = mComponent->querySupportedValues(validValueInfos, C2_DONT_BLOCK);
- if (c2err != C2_OK || validValueInfos.size() != 1u) {
- ALOGE("querySupportedValues_vb failed for channelCount");
- return c2err;
- }
+ ASSERT_EQ(c2err, C2_OK) << "Query channel count info failed";
+ ASSERT_EQ(validValueInfos.size(), 1) << "Size of the vector returned is invalid";
// setting default value of channelCount
*nChannels = 1;
@@ -280,37 +267,45 @@
break;
}
default:
+ ASSERT_TRUE(false) << "Unsupported type: " << c2FSV.type;
break;
}
- return C2_OK;
+ return;
}
-c2_status_t Codec2AudioEncHidlTestBase::getSampleRate(int32_t* nSampleRate) {
+void Codec2AudioEncHidlTestBase::getSampleRate(int32_t* nSampleRate) {
// Use the default sample rate for mComponents
std::vector<std::unique_ptr<C2Param>> queried;
c2_status_t c2err = mComponent->query({}, {C2StreamSampleRateInfo::input::PARAM_TYPE},
C2_DONT_BLOCK, &queried);
- if (c2err != C2_OK || queried.size() == 0) return c2err;
+ ASSERT_EQ(c2err, C2_OK) << "Query sample rate info failed";
+ ASSERT_EQ(queried.size(), 1) << "Size of the vector returned is invalid";
- size_t offset = sizeof(C2Param);
- C2Param* param = queried[0].get();
- *nSampleRate = *(int32_t*)((uint8_t*)param + offset);
-
- return C2_OK;
+ *nSampleRate = C2StreamSampleRateInfo::input::From(queried[0].get())->value;
+ return;
}
-c2_status_t Codec2AudioEncHidlTestBase::getSamplesPerFrame(int32_t nChannels,
- int32_t* samplesPerFrame) {
+void Codec2AudioEncHidlTestBase::getSamplesPerFrame(int32_t nChannels, int32_t* samplesPerFrame) {
std::vector<std::unique_ptr<C2Param>> queried;
- c2_status_t c2err = mComponent->query({}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE},
+ c2_status_t c2err = mComponent->query({}, {C2StreamAudioFrameSizeInfo::input::PARAM_TYPE},
C2_DONT_BLOCK, &queried);
- if (c2err != C2_OK || queried.size() == 0) return c2err;
- size_t offset = sizeof(C2Param);
- C2Param* param = queried[0].get();
- uint32_t maxInputSize = *(uint32_t*)((uint8_t*)param + offset);
+ if (c2err == C2_OK && queried.size() == 1) {
+ mEncoderFrameSize = C2StreamAudioFrameSizeInfo::input::From(queried[0].get())->value;
+ if (mEncoderFrameSize) {
+ *samplesPerFrame = mEncoderFrameSize;
+ return;
+ }
+ }
+
+ c2err = mComponent->query({}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE}, C2_DONT_BLOCK,
+ &queried);
+ ASSERT_EQ(c2err, C2_OK) << "Query max buffer size info failed";
+ ASSERT_EQ(queried.size(), 1) << "Size of the vector returned is invalid";
+
+ uint32_t maxInputSize = C2StreamMaxBufferSizeInfo::input::From(queried[0].get())->value;
*samplesPerFrame = std::min((maxInputSize / (nChannels * 2)), kMaxSamplesPerFrame);
- return C2_OK;
+ return;
}
// LookUpTable of clips and metadata for component testing
@@ -440,10 +435,13 @@
ALOGV("EncodeTest");
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
bool signalEOS = std::get<2>(GetParam());
- // Ratio w.r.t to mInputMaxBufSize
- int32_t inputMaxBufRatio = std::get<3>(GetParam());
- mSamplesPerFrame = ((mInputMaxBufSize / inputMaxBufRatio) / (mNumChannels * 2));
-
+ // Set samples per frame based on inputMaxBufRatio if component does not
+ // advertise supported frame size
+ if (!mEncoderFrameSize) {
+ // Ratio w.r.t to mInputMaxBufSize
+ int32_t inputMaxBufRatio = std::get<3>(GetParam());
+ mSamplesPerFrame = ((mInputMaxBufSize / inputMaxBufRatio) / (mNumChannels * 2));
+ }
ALOGV("signalEOS %d mInputMaxBufSize %d mSamplesPerFrame %d", signalEOS, mInputMaxBufSize,
mSamplesPerFrame);
@@ -603,12 +601,11 @@
std::vector<std::unique_ptr<C2Param>> inParams;
c2_status_t c2_status = mComponent->query({}, {C2StreamChannelCountInfo::input::PARAM_TYPE},
C2_DONT_BLOCK, &inParams);
- ASSERT_TRUE(!c2_status && inParams.size())
- << "Query configured channelCount failed => %d" << c2_status;
+ ASSERT_EQ(c2_status, C2_OK) << "Query channel count info failed";
+ ASSERT_EQ(inParams.size(), 1) << "Size of the vector returned is invalid";
- size_t offset = sizeof(C2Param);
- C2Param* param = inParams[0].get();
- int32_t channelCount = *(int32_t*)((uint8_t*)param + offset);
+ int32_t channelCount = C2StreamChannelCountInfo::input::From(inParams[0].get())->value;
+
if (channelCount != nChannels) {
std::cout << "[ WARN ] Test Skipped for ChannelCount " << nChannels << "\n";
continue;
@@ -692,13 +689,11 @@
std::vector<std::unique_ptr<C2Param>> inParams;
c2_status_t c2_status = mComponent->query({}, {C2StreamSampleRateInfo::input::PARAM_TYPE},
C2_DONT_BLOCK, &inParams);
+ ASSERT_EQ(c2_status, C2_OK) << "Query sample rate info failed";
+ ASSERT_EQ(inParams.size(), 1) << "Size of the vector returned is invalid";
- ASSERT_TRUE(!c2_status && inParams.size())
- << "Query configured SampleRate failed => %d" << c2_status;
- size_t offset = sizeof(C2Param);
- C2Param* param = inParams[0].get();
- int32_t configuredSampleRate = *(int32_t*)((uint8_t*)param + offset);
-
+ int32_t configuredSampleRate =
+ C2StreamSampleRateInfo::input::From(inParams[0].get())->value;
if (configuredSampleRate != nSampleRate) {
std::cout << "[ WARN ] Test Skipped for SampleRate " << nSampleRate << "\n";
continue;
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 95a4674..67873fa 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
@@ -123,8 +123,10 @@
ASSERT_NE(mLinearPool, nullptr);
std::vector<std::unique_ptr<C2Param>> queried;
- mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, C2_DONT_BLOCK, &queried);
- ASSERT_GT(queried.size(), 0);
+ c2_status_t c2err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+ C2_DONT_BLOCK, &queried);
+ ASSERT_EQ(c2err, C2_OK) << "Query media type failed";
+ ASSERT_EQ(queried.size(), 1) << "Size of the vector returned is invalid";
mMime = ((C2PortMediaTypeSetting::input*)queried[0].get())->m.value;
mEos = false;
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 a6507e7..366025f 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
@@ -74,9 +74,10 @@
ASSERT_NE(mGraphicPool, nullptr);
std::vector<std::unique_ptr<C2Param>> queried;
- mComponent->query({}, {C2PortMediaTypeSetting::output::PARAM_TYPE}, C2_DONT_BLOCK,
- &queried);
- ASSERT_GT(queried.size(), 0);
+ c2_status_t c2err = mComponent->query({}, {C2PortMediaTypeSetting::output::PARAM_TYPE},
+ C2_DONT_BLOCK, &queried);
+ ASSERT_EQ(c2err, C2_OK) << "Query media type failed";
+ ASSERT_EQ(queried.size(), 1) << "Size of the vector returned is invalid";
mMime = ((C2PortMediaTypeSetting::output*)queried[0].get())->m.value;
std::cout << "mime : " << mMime << "\n";
@@ -531,9 +532,17 @@
<< " resetting num BFrames to 0\n";
mConfigBPictures = false;
} else {
- size_t offset = sizeof(C2Param);
- C2Param* param = inParams[0].get();
- int32_t numBFrames = *(int32_t*)((uint8_t*)param + offset);
+ int32_t numBFrames = 0;
+ C2StreamGopTuning::output* gop = C2StreamGopTuning::output::From(inParams[0].get());
+ if (gop && gop->flexCount() >= 1) {
+ for (size_t i = 0; i < gop->flexCount(); ++i) {
+ const C2GopLayerStruct& layer = gop->m.values[i];
+ if (layer.type_ == C2Config::picture_type_t(P_FRAME | B_FRAME)) {
+ numBFrames = layer.count;
+ break;
+ }
+ }
+ }
if (!numBFrames) {
std::cout << "[ WARN ] Bframe not supported for " << mComponentName
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 29cc564..333a2ca 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -96,7 +96,10 @@
if (img->mNumPlanes > 0 && img->mType != img->MEDIA_IMAGE_TYPE_UNKNOWN) {
int32_t stride = img->mPlane[0].mRowInc;
mFormatWithImageData->setInt32(KEY_STRIDE, stride);
- ALOGD("[%s] updating stride = %d", mName, stride);
+ mFormatWithImageData->setInt32(KEY_WIDTH, img->mWidth);
+ mFormatWithImageData->setInt32(KEY_HEIGHT, img->mHeight);
+ ALOGD("[%s] updating stride = %d, width: %d, height: %d",
+ mName, stride, img->mWidth, img->mHeight);
if (img->mNumPlanes > 1 && stride > 0) {
int64_t offsetDelta =
(int64_t)img->mPlane[1].mOffset - (int64_t)img->mPlane[0].mOffset;
diff --git a/media/codec2/vndk/C2PlatformStorePluginLoader.cpp b/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
index bee028a..2a888a8 100644
--- a/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
+++ b/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
@@ -59,13 +59,14 @@
c2_status_t C2PlatformStorePluginLoader::createBlockPool(
::C2Allocator::id_t allocatorId, ::C2BlockPool::local_id_t blockPoolId,
- std::shared_ptr<C2BlockPool>* pool) {
+ std::shared_ptr<C2BlockPool>* pool,
+ std::function<void(C2BlockPool *)> deleter) {
if (mCreateBlockPool == nullptr) {
ALOGD("Handle or CreateBlockPool symbol is null");
return C2_NOT_FOUND;
}
- std::shared_ptr<::C2BlockPool> ptr(mCreateBlockPool(allocatorId, blockPoolId));
+ std::shared_ptr<::C2BlockPool> ptr(mCreateBlockPool(allocatorId, blockPoolId), deleter);
if (ptr) {
*pool = ptr;
return C2_OK;
@@ -75,14 +76,16 @@
}
c2_status_t C2PlatformStorePluginLoader::createAllocator(
- ::C2Allocator::id_t allocatorId, std::shared_ptr<C2Allocator>* const allocator) {
+ ::C2Allocator::id_t allocatorId,
+ std::shared_ptr<C2Allocator>* const allocator,
+ std::function<void(C2Allocator *)> deleter) {
if (mCreateAllocator == nullptr) {
ALOGD("Handle or CreateAllocator symbol is null");
return C2_NOT_FOUND;
}
c2_status_t res = C2_CORRUPTED;
- allocator->reset(mCreateAllocator(allocatorId, &res));
+ allocator->reset(mCreateAllocator(allocatorId, &res), deleter);
if (res != C2_OK) {
ALOGD("Failed to CreateAllocator by id: %u, res: %d", allocatorId, res);
allocator->reset();
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index c07c09e..1660c38 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -443,6 +443,7 @@
public:
_C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
+private:
c2_status_t _createBlockPool(
C2PlatformAllocatorStore::id_t allocatorId,
std::vector<std::shared_ptr<const C2Component>> components,
@@ -456,14 +457,19 @@
if (allocatorId == C2AllocatorStore::DEFAULT_LINEAR) {
allocatorId = GetPreferredLinearAllocatorId(GetCodec2PoolMask());
}
+ auto deleter = [this, poolId](C2BlockPool *pool) {
+ std::unique_lock lock(mMutex);
+ mBlockPools.erase(poolId);
+ mComponents.erase(poolId);
+ delete pool;
+ };
switch(allocatorId) {
case C2PlatformAllocatorStore::ION: /* also ::DMABUFHEAP */
res = allocatorStore->fetchAllocator(
C2PlatformAllocatorStore::ION, &allocator);
if (res == C2_OK) {
- std::shared_ptr<C2BlockPool> ptr =
- std::make_shared<C2PooledBlockPool>(
- allocator, poolId);
+ std::shared_ptr<C2BlockPool> ptr(
+ new C2PooledBlockPool(allocator, poolId), deleter);
*pool = ptr;
mBlockPools[poolId] = ptr;
mComponents[poolId].insert(
@@ -475,9 +481,8 @@
res = allocatorStore->fetchAllocator(
C2PlatformAllocatorStore::BLOB, &allocator);
if (res == C2_OK) {
- std::shared_ptr<C2BlockPool> ptr =
- std::make_shared<C2PooledBlockPool>(
- allocator, poolId);
+ std::shared_ptr<C2BlockPool> ptr(
+ new C2PooledBlockPool(allocator, poolId), deleter);
*pool = ptr;
mBlockPools[poolId] = ptr;
mComponents[poolId].insert(
@@ -490,8 +495,8 @@
res = allocatorStore->fetchAllocator(
C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
if (res == C2_OK) {
- std::shared_ptr<C2BlockPool> ptr =
- std::make_shared<C2PooledBlockPool>(allocator, poolId);
+ std::shared_ptr<C2BlockPool> ptr(
+ new C2PooledBlockPool(allocator, poolId), deleter);
*pool = ptr;
mBlockPools[poolId] = ptr;
mComponents[poolId].insert(
@@ -503,9 +508,8 @@
res = allocatorStore->fetchAllocator(
C2PlatformAllocatorStore::BUFFERQUEUE, &allocator);
if (res == C2_OK) {
- std::shared_ptr<C2BlockPool> ptr =
- std::make_shared<C2BufferQueueBlockPool>(
- allocator, poolId);
+ std::shared_ptr<C2BlockPool> ptr(
+ new C2BufferQueueBlockPool(allocator, poolId), deleter);
*pool = ptr;
mBlockPools[poolId] = ptr;
mComponents[poolId].insert(
@@ -517,7 +521,7 @@
// Try to create block pool from platform store plugins.
std::shared_ptr<C2BlockPool> ptr;
res = C2PlatformStorePluginLoader::GetInstance()->createBlockPool(
- allocatorId, poolId, &ptr);
+ allocatorId, poolId, &ptr, deleter);
if (res == C2_OK) {
*pool = ptr;
mBlockPools[poolId] = ptr;
@@ -530,17 +534,20 @@
return res;
}
+public:
c2_status_t createBlockPool(
C2PlatformAllocatorStore::id_t allocatorId,
std::vector<std::shared_ptr<const C2Component>> components,
std::shared_ptr<C2BlockPool> *pool) {
+ std::unique_lock lock(mMutex);
return _createBlockPool(allocatorId, components, mBlockPoolSeqId++, pool);
}
- bool getBlockPool(
+ c2_status_t getBlockPool(
C2BlockPool::local_id_t blockPoolId,
std::shared_ptr<const C2Component> component,
std::shared_ptr<C2BlockPool> *pool) {
+ std::unique_lock lock(mMutex);
// TODO: use one iterator for multiple blockpool type scalability.
std::shared_ptr<C2BlockPool> ptr;
auto it = mBlockPools.find(blockPoolId);
@@ -558,14 +565,22 @@
});
if (found != mComponents[blockPoolId].end()) {
*pool = ptr;
- return true;
+ return C2_OK;
}
}
}
- return false;
+ // TODO: remove this. this is temporary
+ if (blockPoolId == C2BlockPool::PLATFORM_START) {
+ return _createBlockPool(
+ C2PlatformAllocatorStore::BUFFERQUEUE, {component}, blockPoolId, pool);
+ }
+ return C2_NOT_FOUND;
}
private:
+ // Deleter needs to hold this mutex, and there is a small chance that deleter
+ // is invoked while the mutex is held.
+ std::recursive_mutex mMutex;
C2BlockPool::local_id_t mBlockPoolSeqId;
std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BlockPool>> mBlockPools;
@@ -574,7 +589,6 @@
static std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
std::make_unique<_C2BlockPoolCache>();
-static std::mutex sBlockPoolCacheMutex;
} // anynymous namespace
@@ -582,15 +596,12 @@
C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
std::shared_ptr<C2Allocator> allocator;
c2_status_t res = C2_NOT_FOUND;
if (id >= C2BlockPool::PLATFORM_START) {
- if (sBlockPoolCache->getBlockPool(id, component, pool)) {
- return C2_OK;
- }
+ return sBlockPoolCache->getBlockPool(id, component, pool);
}
switch (id) {
@@ -606,11 +617,6 @@
*pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
}
break;
- // TODO: remove this. this is temporary
- case C2BlockPool::PLATFORM_START:
- res = sBlockPoolCache->_createBlockPool(
- C2PlatformAllocatorStore::BUFFERQUEUE, {component}, id, pool);
- break;
default:
break;
}
@@ -623,7 +629,6 @@
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
return sBlockPoolCache->createBlockPool(allocatorId, components, pool);
}
@@ -633,7 +638,6 @@
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
return sBlockPoolCache->createBlockPool(allocatorId, {component}, pool);
}
diff --git a/media/codec2/vndk/include/C2PlatformStorePluginLoader.h b/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
index 4c10643..73d1b5e 100644
--- a/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
+++ b/media/codec2/vndk/include/C2PlatformStorePluginLoader.h
@@ -61,9 +61,11 @@
* \retval C2_NOT_FOUND the extension symbol was not found.
* \retval C2_BAD_INDEX the input allocatorId is not defined in platform store extension.
*/
- c2_status_t createBlockPool(::C2Allocator::id_t allocatorId,
- ::C2BlockPool::local_id_t blockPoolId,
- std::shared_ptr<C2BlockPool>* pool);
+ c2_status_t createBlockPool(
+ ::C2Allocator::id_t allocatorId,
+ ::C2BlockPool::local_id_t blockPoolId,
+ std::shared_ptr<C2BlockPool>* pool,
+ std::function<void(C2BlockPool *)> deleter = std::default_delete<C2BlockPool>());
/**
* Creates allocator from platform store extension.
@@ -81,8 +83,10 @@
* \retval C2_BAD_INDEX the input allocatorId is not defined in platform store extension.
* \retval C2_NO_MEMORY not enough memory to create the allocator
*/
- c2_status_t createAllocator(::C2Allocator::id_t allocatorId,
- std::shared_ptr<C2Allocator>* const allocator);
+ c2_status_t createAllocator(
+ ::C2Allocator::id_t allocatorId,
+ std::shared_ptr<C2Allocator>* const allocator,
+ std::function<void(C2Allocator *)> deleter = std::default_delete<C2Allocator>());
private:
explicit C2PlatformStorePluginLoader(const char *libPath);
diff --git a/media/janitors/media_solutions_OWNERS b/media/janitors/media_solutions_OWNERS
new file mode 100644
index 0000000..8dc1c7b
--- /dev/null
+++ b/media/janitors/media_solutions_OWNERS
@@ -0,0 +1,10 @@
+# Bug component: 1344
+# go/android-fwk-media-solutions for info on areas of ownership.
+
+# Main owners:
+aquilescanta@google.com
+krocard@google.com
+
+# In case of emergency:
+andrewlewis@google.com #{LAST_RESORT_SUGGESTION}
+olly@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
index 7e5caed..1eadd27 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
@@ -313,9 +313,9 @@
*/
pInstance->eqBiquad.resize(pParams->NBands,
android::audio_utils::BiquadFilter<LVM_FLOAT>(pParams->NrChannels));
- LVEQNB_ClearFilterHistory(pInstance);
if (bChange || modeChange) {
+ LVEQNB_ClearFilterHistory(pInstance);
/*
* If the sample rate has changed clear the history
*/
diff --git a/media/libeffects/lvm/tests/EffectBundleTest.cpp b/media/libeffects/lvm/tests/EffectBundleTest.cpp
index 881ffb1..018cb7c 100644
--- a/media/libeffects/lvm/tests/EffectBundleTest.cpp
+++ b/media/libeffects/lvm/tests/EffectBundleTest.cpp
@@ -14,29 +14,39 @@
* limitations under the License.
*/
+#include <system/audio_effects/effect_bassboost.h>
+#include <system/audio_effects/effect_equalizer.h>
+#include <system/audio_effects/effect_virtualizer.h>
#include "EffectTestHelper.h"
-using namespace android;
-// Update isBassBoost, if the order of effects is updated
-constexpr effect_uuid_t kEffectUuids[] = {
+using namespace android;
+typedef enum {
+ EFFECT_BASS_BOOST,
+ EFFECT_EQUALIZER,
+ EFFECT_VIRTUALIZER,
+ EFFECT_VOLUME
+} effect_type_t;
+
+const std::map<effect_type_t, effect_uuid_t> kEffectUuids = {
// NXP SW BassBoost
- {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
- // NXP SW Virtualizer
- {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ {EFFECT_BASS_BOOST,
+ {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}},
// NXP SW Equalizer
- {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ {EFFECT_EQUALIZER,
+ {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}},
+ // NXP SW Virtualizer
+ {EFFECT_VIRTUALIZER,
+ {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}},
// NXP SW Volume
- {0x119341a0, 0x8469, 0x11df, 0x81f9, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ {EFFECT_VOLUME, {0x119341a0, 0x8469, 0x11df, 0x81f9, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}},
};
-static bool isBassBoost(const effect_uuid_t* uuid) {
- // Update this, if the order of effects in kEffectUuids is updated
- return uuid == &kEffectUuids[0];
-}
+const size_t kNumEffectUuids = std::size(kEffectUuids);
-constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
+constexpr float kMinAmplitude = -1.0f;
+constexpr float kMaxAmplitude = 1.0f;
-typedef std::tuple<int, int, int, int, int> SingleEffectTestParam;
+using SingleEffectTestParam = std::tuple<int, int, int, int, int>;
class SingleEffectTest : public ::testing::TestWithParam<SingleEffectTestParam> {
public:
SingleEffectTest()
@@ -46,7 +56,8 @@
mFrameCount(EffectTestHelper::kFrameCounts[std::get<2>(GetParam())]),
mLoopCount(EffectTestHelper::kLoopCounts[std::get<3>(GetParam())]),
mTotalFrameCount(mFrameCount * mLoopCount),
- mUuid(&kEffectUuids[std::get<4>(GetParam())]) {}
+ mEffectType((effect_type_t)std::get<4>(GetParam())),
+ mUuid(kEffectUuids.at(mEffectType)) {}
const size_t mChMask;
const size_t mChannelCount;
@@ -54,7 +65,8 @@
const size_t mFrameCount;
const size_t mLoopCount;
const size_t mTotalFrameCount;
- const effect_uuid_t* mUuid;
+ const effect_type_t mEffectType;
+ const effect_uuid_t mUuid;
};
// Tests applying a single effect
@@ -63,7 +75,7 @@
<< "chMask: " << mChMask << " sampleRate: " << mSampleRate
<< " frameCount: " << mFrameCount << " loopCount: " << mLoopCount);
- EffectTestHelper effect(mUuid, mChMask, mChMask, mSampleRate, mFrameCount, mLoopCount);
+ EffectTestHelper effect(&mUuid, mChMask, mChMask, mSampleRate, mFrameCount, mLoopCount);
ASSERT_NO_FATAL_FAILURE(effect.createEffect());
ASSERT_NO_FATAL_FAILURE(effect.setConfig());
@@ -72,7 +84,7 @@
std::vector<float> input(mTotalFrameCount * mChannelCount);
std::vector<float> output(mTotalFrameCount * mChannelCount);
std::minstd_rand gen(mChMask);
- std::uniform_real_distribution<> dis(-1.0f, 1.0f);
+ std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
for (auto& in : input) {
in = dis(gen);
}
@@ -88,7 +100,7 @@
::testing::Range(0, (int)EffectTestHelper::kNumLoopCounts),
::testing::Range(0, (int)kNumEffectUuids)));
-typedef std::tuple<int, int, int, int> SingleEffectComparisonTestParam;
+using SingleEffectComparisonTestParam = std::tuple<int, int, int, int>;
class SingleEffectComparisonTest
: public ::testing::TestWithParam<SingleEffectComparisonTestParam> {
public:
@@ -97,13 +109,15 @@
mFrameCount(EffectTestHelper::kFrameCounts[std::get<1>(GetParam())]),
mLoopCount(EffectTestHelper::kLoopCounts[std::get<2>(GetParam())]),
mTotalFrameCount(mFrameCount * mLoopCount),
- mUuid(&kEffectUuids[std::get<3>(GetParam())]) {}
+ mEffectType((effect_type_t)std::get<3>(GetParam())),
+ mUuid(kEffectUuids.at(mEffectType)) {}
const size_t mSampleRate;
const size_t mFrameCount;
const size_t mLoopCount;
const size_t mTotalFrameCount;
- const effect_uuid_t* mUuid;
+ const effect_type_t mEffectType;
+ const effect_uuid_t mUuid;
};
// Compares first two channels in multi-channel output to stereo output when same effect is applied
@@ -115,7 +129,7 @@
std::vector<float> monoInput(mTotalFrameCount);
std::minstd_rand gen(mSampleRate);
- std::uniform_real_distribution<> dis(-1.0f, 1.0f);
+ std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
for (auto& in : monoInput) {
in = dis(gen);
}
@@ -126,7 +140,7 @@
mTotalFrameCount * sizeof(float) * FCC_1);
// Apply effect on stereo channels
- EffectTestHelper stereoEffect(mUuid, AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_STEREO,
+ EffectTestHelper stereoEffect(&mUuid, AUDIO_CHANNEL_OUT_STEREO, AUDIO_CHANNEL_OUT_STEREO,
mSampleRate, mFrameCount, mLoopCount);
ASSERT_NO_FATAL_FAILURE(stereoEffect.createEffect());
@@ -142,7 +156,7 @@
for (size_t chMask : EffectTestHelper::kChMasks) {
size_t channelCount = audio_channel_count_from_out_mask(chMask);
- EffectTestHelper testEffect(mUuid, chMask, chMask, mSampleRate, mFrameCount, mLoopCount);
+ EffectTestHelper testEffect(&mUuid, chMask, chMask, mSampleRate, mFrameCount, mLoopCount);
ASSERT_NO_FATAL_FAILURE(testEffect.createEffect());
ASSERT_NO_FATAL_FAILURE(testEffect.setConfig());
@@ -170,7 +184,7 @@
memcpy_to_i16_from_float(stereoTestI16.data(), stereoTestOutput.data(),
mTotalFrameCount * FCC_2);
- if (isBassBoost(mUuid)) {
+ if (EFFECT_BASS_BOOST == mEffectType) {
// SNR must be above the threshold
float snr = computeSnr<int16_t>(stereoRefI16.data(), stereoTestI16.data(),
mTotalFrameCount * FCC_2);
@@ -191,6 +205,135 @@
::testing::Range(0, (int)EffectTestHelper::kNumLoopCounts),
::testing::Range(0, (int)kNumEffectUuids)));
+using SingleEffectDefaultSetParamTestParam = std::tuple<int, int, int>;
+class SingleEffectDefaultSetParamTest
+ : public ::testing::TestWithParam<SingleEffectDefaultSetParamTestParam> {
+ public:
+ SingleEffectDefaultSetParamTest()
+ : mChMask(EffectTestHelper::kChMasks[std::get<0>(GetParam())]),
+ mChannelCount(audio_channel_count_from_out_mask(mChMask)),
+ mSampleRate(16000),
+ mFrameCount(EffectTestHelper::kFrameCounts[std::get<1>(GetParam())]),
+ mLoopCount(1),
+ mTotalFrameCount(mFrameCount * mLoopCount),
+ mEffectType((effect_type_t)std::get<2>(GetParam())),
+ mUuid(kEffectUuids.at(mEffectType)) {}
+
+ const size_t mChMask;
+ const size_t mChannelCount;
+ const size_t mSampleRate;
+ const size_t mFrameCount;
+ const size_t mLoopCount;
+ const size_t mTotalFrameCount;
+ const effect_type_t mEffectType;
+ const effect_uuid_t mUuid;
+};
+
+// Tests verifying that redundant setParam calls do not alter output
+TEST_P(SingleEffectDefaultSetParamTest, SimpleProcess) {
+ SCOPED_TRACE(testing::Message()
+ << "chMask: " << mChMask << " sampleRate: " << mSampleRate
+ << " frameCount: " << mFrameCount << " loopCount: " << mLoopCount);
+ // effect.process() handles mTotalFrameCount * mChannelCount samples in each call.
+ // This test calls process() twice per effect, hence total samples when allocating
+ // input and output vectors is twice the number of samples processed in one call.
+ size_t totalNumSamples = 2 * mTotalFrameCount * mChannelCount;
+ // Initialize input buffer with deterministic pseudo-random values
+ std::vector<float> input(totalNumSamples);
+ std::minstd_rand gen(mChMask);
+ std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
+ for (auto& in : input) {
+ in = dis(gen);
+ }
+
+ uint32_t key;
+ int32_t value1, value2;
+ switch (mEffectType) {
+ case EFFECT_BASS_BOOST:
+ key = BASSBOOST_PARAM_STRENGTH;
+ value1 = 1;
+ value2 = 14;
+ break;
+ case EFFECT_VIRTUALIZER:
+ key = VIRTUALIZER_PARAM_STRENGTH;
+ value1 = 0;
+ value2 = 100;
+ break;
+ case EFFECT_EQUALIZER:
+ key = EQ_PARAM_CUR_PRESET;
+ value1 = 0;
+ value2 = 1;
+ break;
+ case EFFECT_VOLUME:
+ key = 0 /* VOLUME_PARAM_LEVEL */;
+ value1 = 0;
+ value2 = -100;
+ break;
+ default:
+ FAIL() << "Unsupported effect type : " << mEffectType;
+ }
+
+ EffectTestHelper refEffect(&mUuid, mChMask, mChMask, mSampleRate, mFrameCount, mLoopCount);
+
+ ASSERT_NO_FATAL_FAILURE(refEffect.createEffect());
+ ASSERT_NO_FATAL_FAILURE(refEffect.setConfig());
+
+ if (EFFECT_BASS_BOOST == mEffectType) {
+ ASSERT_NO_FATAL_FAILURE(refEffect.setParam<int16_t>(key, value1));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(refEffect.setParam<int32_t>(key, value1));
+ }
+ std::vector<float> refOutput(totalNumSamples);
+ float* pInput = input.data();
+ float* pOutput = refOutput.data();
+ ASSERT_NO_FATAL_FAILURE(refEffect.process(pInput, pOutput));
+
+ pInput += totalNumSamples / 2;
+ pOutput += totalNumSamples / 2;
+ ASSERT_NO_FATAL_FAILURE(refEffect.process(pInput, pOutput));
+ ASSERT_NO_FATAL_FAILURE(refEffect.releaseEffect());
+
+ EffectTestHelper testEffect(&mUuid, mChMask, mChMask, mSampleRate, mFrameCount, mLoopCount);
+
+ ASSERT_NO_FATAL_FAILURE(testEffect.createEffect());
+ ASSERT_NO_FATAL_FAILURE(testEffect.setConfig());
+
+ if (EFFECT_BASS_BOOST == mEffectType) {
+ ASSERT_NO_FATAL_FAILURE(testEffect.setParam<int16_t>(key, value1));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(testEffect.setParam<int32_t>(key, value1));
+ }
+
+ std::vector<float> testOutput(totalNumSamples);
+ pInput = input.data();
+ pOutput = testOutput.data();
+ ASSERT_NO_FATAL_FAILURE(testEffect.process(pInput, pOutput));
+
+ // Call setParam once to change the parameters, and then call setParam again
+ // to restore the parameters to the initial state, making the first setParam
+ // call redundant
+ if (EFFECT_BASS_BOOST == mEffectType) {
+ ASSERT_NO_FATAL_FAILURE(testEffect.setParam<int16_t>(key, value2));
+ ASSERT_NO_FATAL_FAILURE(testEffect.setParam<int16_t>(key, value1));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(testEffect.setParam<int32_t>(key, value2));
+ ASSERT_NO_FATAL_FAILURE(testEffect.setParam<int32_t>(key, value1));
+ }
+
+ pInput += totalNumSamples / 2;
+ pOutput += totalNumSamples / 2;
+ ASSERT_NO_FATAL_FAILURE(testEffect.process(pInput, pOutput));
+ ASSERT_NO_FATAL_FAILURE(testEffect.releaseEffect());
+ ASSERT_TRUE(areNearlySame(refOutput.data(), testOutput.data(), totalNumSamples))
+ << "Outputs do not match with default setParam calls";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ EffectBundleTestAll, SingleEffectDefaultSetParamTest,
+ ::testing::Combine(::testing::Range(0, (int)EffectTestHelper::kNumChMasks),
+ ::testing::Range(0, (int)EffectTestHelper::kNumFrameCounts),
+ ::testing::Range(0, (int)kNumEffectUuids)));
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int status = RUN_ALL_TESTS();
diff --git a/media/libeffects/lvm/tests/EffectTestHelper.cpp b/media/libeffects/lvm/tests/EffectTestHelper.cpp
index 625c15a..ec727c7 100644
--- a/media/libeffects/lvm/tests/EffectTestHelper.cpp
+++ b/media/libeffects/lvm/tests/EffectTestHelper.cpp
@@ -50,23 +50,6 @@
ASSERT_EQ(reply, 0) << "cmd_enable reply non zero " << reply;
}
-void EffectTestHelper::setParam(uint32_t type, uint32_t value) {
- int reply = 0;
- uint32_t replySize = sizeof(reply);
- uint32_t paramData[2] = {type, value};
- auto effectParam = new effect_param_t[sizeof(effect_param_t) + sizeof(paramData)];
- memcpy(&effectParam->data[0], ¶mData[0], sizeof(paramData));
- effectParam->psize = sizeof(paramData[0]);
- effectParam->vsize = sizeof(paramData[1]);
- int status = (*mEffectHandle)
- ->command(mEffectHandle, EFFECT_CMD_SET_PARAM,
- sizeof(effect_param_t) + sizeof(paramData), effectParam,
- &replySize, &reply);
- delete[] effectParam;
- ASSERT_EQ(status, 0) << "set_param returned an error " << status;
- ASSERT_EQ(reply, 0) << "set_param reply non zero " << reply;
-}
-
void EffectTestHelper::process(float* input, float* output) {
audio_buffer_t inBuffer = {.frameCount = mFrameCount, .f32 = input};
audio_buffer_t outBuffer = {.frameCount = mFrameCount, .f32 = output};
diff --git a/media/libeffects/lvm/tests/EffectTestHelper.h b/media/libeffects/lvm/tests/EffectTestHelper.h
index 3854d46..bcee84e 100644
--- a/media/libeffects/lvm/tests/EffectTestHelper.h
+++ b/media/libeffects/lvm/tests/EffectTestHelper.h
@@ -50,6 +50,23 @@
return snr;
}
+template <typename T>
+static float areNearlySame(const T* ref, const T* tst, size_t count) {
+ T delta;
+ if constexpr (std::is_floating_point_v<T>) {
+ delta = std::numeric_limits<T>::epsilon();
+ } else {
+ delta = 1;
+ }
+ for (size_t i = 0; i < count; ++i) {
+ const double diff(tst[i] - ref[i]);
+ if (abs(diff) > delta) {
+ return false;
+ }
+ }
+ return true;
+}
+
class EffectTestHelper {
public:
EffectTestHelper(const effect_uuid_t* uuid, size_t inChMask, size_t outChMask,
@@ -65,7 +82,25 @@
void createEffect();
void releaseEffect();
void setConfig();
- void setParam(uint32_t type, uint32_t val);
+ template <typename VALUE_DTYPE>
+ void setParam(uint32_t type, VALUE_DTYPE const value) {
+ int reply = 0;
+ uint32_t replySize = sizeof(reply);
+
+ uint8_t paramData[sizeof(effect_param_t) + sizeof(type) + sizeof(value)];
+ auto effectParam = (effect_param_t*)paramData;
+
+ memcpy(&effectParam->data[0], &type, sizeof(type));
+ memcpy(&effectParam->data[sizeof(type)], &value, sizeof(value));
+ effectParam->psize = sizeof(type);
+ effectParam->vsize = sizeof(value);
+ int status = (*mEffectHandle)
+ ->command(mEffectHandle, EFFECT_CMD_SET_PARAM,
+ sizeof(effect_param_t) + sizeof(type) + sizeof(value),
+ effectParam, &replySize, &reply);
+ ASSERT_EQ(status, 0) << "set_param returned an error " << status;
+ ASSERT_EQ(reply, 0) << "set_param reply non zero " << reply;
+ };
void process(float* input, float* output);
// Corresponds to SNR for 1 bit difference between two int16_t signals
diff --git a/media/libstagefright/MediaAppender.cpp b/media/libstagefright/MediaAppender.cpp
index 5d80b30..21dcfa1 100644
--- a/media/libstagefright/MediaAppender.cpp
+++ b/media/libstagefright/MediaAppender.cpp
@@ -75,10 +75,21 @@
return status;
}
- if (strcmp("MPEG4Extractor", mExtractor->getName()) == 0) {
+ sp<AMessage> fileFormat;
+ status = mExtractor->getFileFormat(&fileFormat);
+ if (status != OK) {
+ ALOGE("extractor_getFileFormat failed, status :%d", status);
+ return status;
+ }
+
+ AString fileMime;
+ fileFormat->findString("mime", &fileMime);
+ // only compare the end of the file MIME type to allow for vendor customized mime type
+ if (fileMime.endsWith("mp4")){
mFormat = MediaMuxer::OUTPUT_FORMAT_MPEG_4;
} else {
- ALOGE("Unsupported format, extractor name:%s", mExtractor->getName());
+ ALOGE("Unsupported file format, extractor name:%s, fileformat %s",
+ mExtractor->getName(), fileMime.c_str());
return ERROR_UNSUPPORTED;
}
diff --git a/media/libstagefright/OWNERS b/media/libstagefright/OWNERS
index 0cc2294..e67496e 100644
--- a/media/libstagefright/OWNERS
+++ b/media/libstagefright/OWNERS
@@ -1,11 +1,9 @@
+# Bug component: 1344
set noparent
-chz@google.com
essick@google.com
lajos@google.com
-marcone@google.com
taklee@google.com
wonsik@google.com
-# LON
-olly@google.com
-andrewlewis@google.com
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index e2f8d011..1b2ceda 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -205,7 +205,7 @@
static const int MAX_INITIAL_PREVIEW_WIDTH = 1920;
static const int MAX_INITIAL_PREVIEW_HEIGHT = 1080;
// Aspect ratio tolerance
- static const CONSTEXPR float ASPECT_RATIO_TOLERANCE = 0.001;
+ static const CONSTEXPR float ASPECT_RATIO_TOLERANCE = 0.01;
// Threshold for slow jpeg mode
static const int64_t kSlowJpegModeThreshold = 33400000LL; // 33.4 ms
// Margin for checking FPS
diff --git a/services/camera/libcameraservice/device3/BufferUtils.h b/services/camera/libcameraservice/device3/BufferUtils.h
index 1e1cd60..03112ec 100644
--- a/services/camera/libcameraservice/device3/BufferUtils.h
+++ b/services/camera/libcameraservice/device3/BufferUtils.h
@@ -104,7 +104,7 @@
// Return the removed buffer ID if input cache is found.
// Otherwise return BUFFER_ID_NO_BUFFER
- uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle);
+ uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle) override;
// Clear all caches for input stream, but do not remove the stream
// Removed buffers' ID are returned
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index fd645c7..a195fb1 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -4132,6 +4132,11 @@
return mBufferRecords.getBufferId(buf, streamId);
}
+uint64_t Camera3Device::HalInterface::removeOneBufferCache(int streamId,
+ const native_handle_t* handle) {
+ return mBufferRecords.removeOneBufferCache(streamId, handle);
+}
+
void Camera3Device::HalInterface::onBufferFreed(
int streamId, const native_handle_t* handle) {
uint32_t bufferId = mBufferRecords.removeOneBufferCache(streamId, handle);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 39714f0..543de64 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -412,6 +412,8 @@
std::pair<bool, uint64_t> getBufferId(
const buffer_handle_t& buf, int streamId) override;
+ uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle) override;
+
status_t popInflightBuffer(int32_t frameNumber, int32_t streamId,
/*out*/ buffer_handle_t **buffer) override;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputInterface.h b/services/camera/libcameraservice/device3/Camera3OutputInterface.h
index 8817833..40eef1d 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputInterface.h
@@ -50,6 +50,10 @@
// return pair of (newlySeenBuffer?, bufferId)
virtual std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId) = 0;
+ // Return the removed buffer ID if input cache is found.
+ // Otherwise return BUFFER_ID_NO_BUFFER
+ virtual uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle) = 0;
+
// Find a buffer_handle_t based on frame number and stream ID
virtual status_t popInflightBuffer(int32_t frameNumber, int32_t streamId,
/*out*/ buffer_handle_t **buffer) = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 9f225d0..5a97f4b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -1305,6 +1305,7 @@
hardware::hidl_vec<StreamBuffer> tmpRetBuffers(numBuffersRequested);
bool currentReqSucceeds = true;
std::vector<camera_stream_buffer_t> streamBuffers(numBuffersRequested);
+ std::vector<buffer_handle_t> newBuffers;
size_t numAllocatedBuffers = 0;
size_t numPushedInflightBuffers = 0;
for (size_t b = 0; b < numBuffersRequested; b++) {
@@ -1344,6 +1345,9 @@
hBuf.buffer = (isNewBuffer) ? *buffer : nullptr;
hBuf.status = BufferStatus::OK;
hBuf.releaseFence = nullptr;
+ if (isNewBuffer) {
+ newBuffers.push_back(*buffer);
+ }
native_handle_t *acquireFence = nullptr;
if (sb.acquire_fence != -1) {
@@ -1386,6 +1390,9 @@
returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
streamBuffers.data(), numAllocatedBuffers, 0, /*requested*/false,
/*requestTimeNs*/0, states.sessionStatsBuilder);
+ for (auto buf : newBuffers) {
+ states.bufferRecordsIntf.removeOneBufferCache(streamId, buf);
+ }
}
}