Merge "Modifies the large frame config checks based on non-zero config" into main
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index d1b08bd..c770d0c 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -35,14 +35,14 @@
#define FILEREAD_MAX_LAYERS 2
-#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
#define DRC_DEFAULT_MOBILE_DRC_ALBUM 0 /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
#define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS (0.25) /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
-#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
// names of properties that can be used to override the default DRC settings
#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
@@ -145,9 +145,13 @@
.withSetter(ProfileLevelSetter)
.build());
+ C2Config::drc_compression_mode_t defaultCompressionMode =
+ property_get_int32(PROP_DRC_OVERRIDE_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY) == 1
+ ? C2Config::DRC_COMPRESSION_HEAVY
+ : C2Config::DRC_COMPRESSION_LIGHT;
addParameter(
DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
- .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
+ .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, defaultCompressionMode))
.withFields({
C2F(mDrcCompressMode, value).oneOf({
C2Config::DRC_COMPRESSION_ODM_DEFAULT,
@@ -158,37 +162,48 @@
.withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
.build());
+
+ float defaultRefLevel = -0.25 * property_get_int32(PROP_DRC_OVERRIDE_REF_LEVEL,
+ DRC_DEFAULT_MOBILE_REF_LEVEL);
addParameter(
DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
- .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
+ .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, defaultRefLevel))
.withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
.withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
.build());
+ float defaultEncLevel = -0.25 * property_get_int32(PROP_DRC_OVERRIDE_ENC_LEVEL,
+ DRC_DEFAULT_MOBILE_ENC_LEVEL);
addParameter(
DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
- .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
+ .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, defaultEncLevel))
.withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
.withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
.build());
+ float defaultDrcBoost =
+ property_get_int32(PROP_DRC_OVERRIDE_BOOST, DRC_DEFAULT_MOBILE_DRC_BOOST) / 127.;
addParameter(
DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
- .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
+ .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, defaultDrcBoost))
.withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
.withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
.build());
+ float defaultDrcCut =
+ property_get_int32(PROP_DRC_OVERRIDE_CUT, DRC_DEFAULT_MOBILE_DRC_CUT) / 127.;
addParameter(
DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
- .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
+ .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, defaultDrcCut))
.withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
.withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
.build());
+ C2Config::drc_effect_type_t defaultDrcEffectType = (C2Config::drc_effect_type_t)
+ property_get_int32(PROP_DRC_OVERRIDE_EFFECT, DRC_DEFAULT_MOBILE_DRC_EFFECT);
addParameter(
DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
- .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
+ .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, defaultDrcEffectType))
.withFields({
C2F(mDrcEffectType, value).oneOf({
C2Config::DRC_EFFECT_ODM_DEFAULT,
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 96a4c4a..3385b95 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -416,6 +416,7 @@
ivdext_create_op_t s_create_op = {};
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+ s_create_ip.u4_keep_threads_active = 1;
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index e424860..80a5e67 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -152,6 +152,17 @@
.build());
addParameter(
+ DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
+ .withDefault(new C2StreamBitrateModeTuning::output(0u, C2Config::BITRATE_VARIABLE))
+ .withFields({C2F(mBitrateMode, value).oneOf({
+ C2Config::BITRATE_CONST,
+ C2Config::BITRATE_VARIABLE,
+ C2Config::BITRATE_IGNORE})
+ })
+ .withSetter(Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
.withDefault(new C2StreamBitrateInfo::output(0u, 64000))
.withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
@@ -536,6 +547,9 @@
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
+ std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const {
+ return mBitrateMode;
+ }
std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
std::shared_ptr<C2StreamGopTuning::output> getGop_l() const { return mGop; }
@@ -552,6 +566,7 @@
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+ std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
std::shared_ptr<C2StreamGopTuning::output> mGop;
@@ -1154,6 +1169,7 @@
{
IntfImpl::Lock lock = mIntf->lock();
mSize = mIntf->getSize_l();
+ mBitrateMode = mIntf->getBitrateMode_l();
mBitrate = mIntf->getBitrate_l();
mFrameRate = mIntf->getFrameRate_l();
mIntraRefresh = mIntf->getIntraRefresh_l();
@@ -1326,8 +1342,23 @@
} else {
ps_init_ip->u4_enable_recon = 0;
}
+
+ switch (mBitrateMode->value) {
+ case C2Config::BITRATE_IGNORE:
+ ps_init_ip->e_rc_mode = IVE_RC_NONE;
+ break;
+ case C2Config::BITRATE_CONST:
+ ps_init_ip->e_rc_mode = IVE_RC_CBR_NON_LOW_DELAY;
+ break;
+ case C2Config::BITRATE_VARIABLE:
+ ps_init_ip->e_rc_mode = IVE_RC_STORAGE;
+ break;
+ default:
+ ps_init_ip->e_rc_mode = DEFAULT_RC_MODE;
+ break;
+ break;
+ }
ps_init_ip->e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
- ps_init_ip->e_rc_mode = DEFAULT_RC_MODE;
ps_init_ip->u4_max_framerate = DEFAULT_MAX_FRAMERATE;
ps_init_ip->u4_max_bitrate = DEFAULT_MAX_BITRATE;
ps_init_ip->u4_num_bframes = mBframes;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index cde6604..33d166f 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -191,6 +191,7 @@
std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+ std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 15d6dcd..81db2a1 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -407,6 +407,7 @@
ivdext_create_op_t s_create_op = {};
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+ s_create_ip.u4_keep_threads_active = 1;
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 439323c..491098d 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -433,6 +433,7 @@
s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(ivdext_fill_mem_rec_ip_t);
s_fill_mem_ip.u4_share_disp_buf = 0;
+ s_fill_mem_ip.u4_keep_threads_active = 1;
s_fill_mem_ip.e_output_format = mIvColorformat;
s_fill_mem_ip.u4_deinterlace = 1;
s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
@@ -474,6 +475,7 @@
s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = mHeight;
s_init_ip.u4_share_disp_buf = 0;
s_init_ip.u4_deinterlace = 1;
+ s_init_ip.u4_keep_threads_active = 1;
s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords;
s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorformat;
s_init_op.s_ivd_init_op_t.u4_size = sizeof(ivdext_init_op_t);
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index e903069..2a33048 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -29,6 +29,12 @@
#define INT32_MAX 2147483647
#endif
+/* Quantization param values defined by the spec */
+#define VPX_QP_MIN 0
+#define VPX_QP_MAX 63
+#define VPX_QP_DEFAULT_MIN VPX_QP_MIN
+#define VPX_QP_DEFAULT_MAX VPX_QP_MAX
+
namespace android {
C2SoftVpxEnc::IntfImpl::IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
@@ -197,6 +203,20 @@
})
.withSetter(CodedColorAspectsSetter, mColorAspects)
.build());
+
+ addParameter(
+ DefineParam(mPictureQuantization, C2_PARAMKEY_PICTURE_QUANTIZATION)
+ .withDefault(C2StreamPictureQuantizationTuning::output::AllocShared(
+ 0 /* flexCount */, 0u /* stream */))
+ .withFields({C2F(mPictureQuantization, m.values[0].type_).oneOf(
+ {C2Config::I_FRAME, C2Config::P_FRAME}),
+ C2F(mPictureQuantization, m.values[0].min).inRange(
+ VPX_QP_DEFAULT_MIN, VPX_QP_DEFAULT_MAX),
+ C2F(mPictureQuantization, m.values[0].max).inRange(
+ VPX_QP_DEFAULT_MIN, VPX_QP_DEFAULT_MAX)})
+ .withSetter(PictureQuantizationSetter)
+ .build());
+
}
C2R C2SoftVpxEnc::IntfImpl::BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
@@ -330,6 +350,58 @@
double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
}
+
+C2R C2SoftVpxEnc::IntfImpl::PictureQuantizationSetter(bool mayBlock,
+ C2P<C2StreamPictureQuantizationTuning::output>
+ &me) {
+ (void)mayBlock;
+ // these are the ones we're going to set, so want them to default
+ // to the DEFAULT values for the codec
+ int32_t iMin = VPX_QP_DEFAULT_MIN, pMin = VPX_QP_DEFAULT_MIN;
+ int32_t iMax = VPX_QP_DEFAULT_MAX, pMax = VPX_QP_DEFAULT_MAX;
+ for (size_t i = 0; i < me.v.flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = me.v.m.values[i];
+ // layerMin is clamped to [VPX_QP_MIN, layerMax] to avoid error
+ // cases where layer.min > layer.max
+ int32_t layerMax = std::clamp(layer.max, VPX_QP_MIN, VPX_QP_MAX);
+ int32_t layerMin = std::clamp(layer.min, VPX_QP_MIN, layerMax);
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
+ iMax = layerMax;
+ iMin = layerMin;
+ ALOGV("iMin %d iMax %d", iMin, iMax);
+ } else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) {
+ pMax = layerMax;
+ pMin = layerMin;
+ ALOGV("pMin %d pMax %d", pMin, pMax);
+ }
+ }
+ ALOGV("PictureQuantizationSetter(entry): i %d-%d p %d-%d",
+ iMin, iMax, pMin, pMax);
+
+ // vpx library takes same range for I/P picture type
+ int32_t maxFrameQP = std::min({iMax, pMax});
+ int32_t minFrameQP = std::max({iMin, pMin});
+ if (minFrameQP > maxFrameQP) {
+ minFrameQP = maxFrameQP;
+ }
+ // put them back into the structure
+ for (size_t i = 0; i < me.v.flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = me.v.m.values[i];
+
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
+ me.set().m.values[i].max = maxFrameQP;
+ me.set().m.values[i].min = minFrameQP;
+ }
+ else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) {
+ me.set().m.values[i].max = maxFrameQP;
+ me.set().m.values[i].min = minFrameQP;
+ }
+ }
+ ALOGV("PictureQuantizationSetter(exit): minFrameQP = %d maxFrameQP = %d",
+ minFrameQP, maxFrameQP);
+ return C2R::Ok();
+}
+
C2R C2SoftVpxEnc::IntfImpl::ColorAspectsSetter(bool mayBlock,
C2P<C2StreamColorAspectsInfo::input>& me) {
(void)mayBlock;
@@ -453,6 +525,7 @@
mRequestSync = mIntf->getRequestSync_l();
mLayering = mIntf->getTemporalLayers_l();
mTemporalLayers = mLayering->m.layerCount;
+ mQpBounds = mIntf->getPictureQuantization_l();
}
switch (mBitrateMode->value) {
@@ -466,6 +539,18 @@
break;
}
+ if (mQpBounds->flexCount() > 0) {
+ // read min max qp for sequence
+ for (size_t i = 0; i < mQpBounds->flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = mQpBounds->m.values[i];
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
+ mMaxQuantizer = layer.max;
+ mMinQuantizer = layer.min;
+ break;
+ }
+ }
+ }
+
setCodecSpecificInterface();
if (!mCodecInterface) goto CleanUp;
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index bfb4444..980de04 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -219,6 +219,7 @@
std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
std::shared_ptr<C2StreamTemporalLayeringTuning::output> mLayering;
+ std::shared_ptr<C2StreamPictureQuantizationTuning::output> mQpBounds;
C2_DO_NOT_COPY(C2SoftVpxEnc);
};
@@ -250,6 +251,9 @@
static C2R LayeringSetter(bool mayBlock, C2P<C2StreamTemporalLayeringTuning::output>& me);
+ static C2R PictureQuantizationSetter(bool mayBlock,
+ C2P<C2StreamPictureQuantizationTuning::output> &me);
+
// unsafe getters
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const {
@@ -269,6 +273,9 @@
std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() const {
return mCodedColorAspects;
}
+ std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const {
+ return mPictureQuantization;
+ }
uint32_t getSyncFramePeriod() const;
static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me);
static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
@@ -287,6 +294,7 @@
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
+ std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization;
};
} // namespace android
diff --git a/media/codec2/hal/aidl/ComponentStore.cpp b/media/codec2/hal/aidl/ComponentStore.cpp
index 3f687b5..ef49308 100644
--- a/media/codec2/hal/aidl/ComponentStore.cpp
+++ b/media/codec2/hal/aidl/ComponentStore.cpp
@@ -206,12 +206,19 @@
const std::shared_ptr<IClientManager>& pool,
std::shared_ptr<IComponent> *component) {
+ if (!listener) {
+ ALOGE("createComponent(): listener is null");
+ return ScopedAStatus::fromServiceSpecificError(Status::BAD_VALUE);
+ }
+ if (!pool) {
+ ALOGE("createComponent(): pool is null");
+ return ScopedAStatus::fromServiceSpecificError(Status::BAD_VALUE);
+ }
+
std::shared_ptr<C2Component> c2component;
c2_status_t status =
mStore->createComponent(name, &c2component);
- ALOGD("createComponent(): listener(%d)", bool(listener));
-
if (status == C2_OK) {
#ifndef __ANDROID_APEX__
c2component = GetFilterWrapper()->maybeWrapComponent(c2component);
diff --git a/media/codec2/hal/common/MultiAccessUnitHelper.cpp b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
index 2473e59..117ce91 100644
--- a/media/codec2/hal/common/MultiAccessUnitHelper.cpp
+++ b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
@@ -277,9 +277,11 @@
std::static_pointer_cast<const C2AccessUnitInfos::input>(
w->input.buffers.front()->getInfo(C2AccessUnitInfos::input::PARAM_TYPE));
uint32_t offset = 0; uint32_t multiAUSize = multiAU.front().size();
+ bool sendEos = false;
for (int idx = 0; idx < auInfo->flexCount(); ++idx) {
std::vector<C2ConstLinearBlock> au;
const C2AccessUnitInfosStruct &info = auInfo->m.values[idx];
+ sendEos |= (info.flags & C2FrameData::FLAG_END_OF_STREAM);
std::unique_ptr<C2Work> newWork = cloneInputWork(w, info.flags);
frameSet.insert(newFrameIdx);
newFrameIdx = mFrameIndex++;
@@ -302,6 +304,17 @@
processedWork->push_back(std::move(sliceWork));
offset += info.size;
}
+ if (!sendEos && (w->input.flags & C2FrameData::FLAG_END_OF_STREAM)) {
+ if (!processedWork->empty()) {
+ std::list<std::unique_ptr<C2Work>> &sliceWork = processedWork->back();
+ if (!sliceWork.empty()) {
+ std::unique_ptr<C2Work> &work = sliceWork.back();
+ if (work) {
+ work->input.flags = C2FrameData::FLAG_END_OF_STREAM;
+ }
+ }
+ }
+ }
}
if (!processedWork->empty()) {
{
diff --git a/media/codec2/vndk/platform/C2IgbaBuffer.cpp b/media/codec2/vndk/platform/C2IgbaBuffer.cpp
index eafdb22..3622d5e 100644
--- a/media/codec2/vndk/platform/C2IgbaBuffer.cpp
+++ b/media/codec2/vndk/platform/C2IgbaBuffer.cpp
@@ -192,28 +192,25 @@
c2_status_t res = _fetchGraphicBlock(
width, height, format, usage, kBlockingFetchTimeoutNs, &origId, block, &fence);
- if (res == C2_BLOCKING) {
+ if (res == C2_TIMED_OUT) {
+ // SyncFence waiting timeout.
+ // Usually HAL treats C2_TIMED_OUT as an irrecoverable error.
+ // We want HAL to re-try.
return C2_BLOCKING;
}
- if (res != C2_OK) {
- return res;
- }
- // TODO: bundle the fence to the block. Are API changes required?
- res = fence.wait(kSyncFenceWaitNs);
- if (res != C2_OK) {
- bool aidlRet = true;
- ::ndk::ScopedAStatus status = mIgba->deallocate(origId, &aidlRet);
- ALOGE("Waiting a sync fence failed %d aidl(%d: %d)",
- res, status.isOk(), aidlRet);
- }
- return C2_OK;
+ return res;
}
c2_status_t C2IgbaBlockPool::fetchGraphicBlock(
uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
std::shared_ptr<C2GraphicBlock> *block, C2Fence *fence) {
uint64_t origId;
- return _fetchGraphicBlock(width, height, format, usage, 0LL, &origId, block, fence);
+ c2_status_t res = _fetchGraphicBlock(width, height, format, usage, 0LL, &origId, block, fence);
+ if (res == C2_TIMED_OUT) {
+ *fence = C2Fence();
+ return C2_BLOCKING;
+ }
+ return res;
}
c2_status_t C2IgbaBlockPool::_fetchGraphicBlock(
@@ -263,10 +260,27 @@
}
}
- *fence = _C2FenceFactory::CreateSyncFence(allocation.fence.release());
+ C2Fence syncFence = _C2FenceFactory::CreateSyncFence(allocation.fence.release());
AHardwareBuffer *ahwb = allocation.buffer.release(); // This is acquired.
CHECK(AHardwareBuffer_getId(ahwb, origId) == ::android::OK);
- c2_status_t res = CreateGraphicBlockFromAhwb(ahwb, mAllocator, mIgba, block);
+
+ // We are waiting for SyncFence here for backward compatibility.
+ // H/W based Sync Fence could be returned to improve pipeline latency.
+ //
+ // TODO: Add a component configuration for returning sync fence
+ // from fetchGraphicBlock() as the C2Fence output param(b/322283520).
+ // In the case C2_OK along with GraphicBlock must be returned together.
+ c2_status_t res = syncFence.wait(kSyncFenceWaitNs);
+ if (res != C2_OK) {
+ AHardwareBuffer_release(ahwb);
+ bool aidlRet = true;
+ ::ndk::ScopedAStatus status = mIgba->deallocate(*origId, &aidlRet);
+ ALOGE("Waiting a sync fence failed %d aidl(%d: %d)",
+ res, status.isOk(), aidlRet);
+ return C2_TIMED_OUT;
+ }
+
+ res = CreateGraphicBlockFromAhwb(ahwb, mAllocator, mIgba, block);
AHardwareBuffer_release(ahwb);
if (res != C2_OK) {
bool aidlRet = true;
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index 234e858..68dba34 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -43,10 +43,9 @@
}
],
"postsubmit": [
- // TODO(b/302036943): Enable once we make it pass with AIDL HAL on CF.
- // {
- // "name": "audioeffect_analysis"
- // },
+ {
+ "name": "audioeffect_analysis"
+ },
{
"name": "CtsVirtualDevicesTestCases",
"options" : [
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 39999a5..e1a82f8 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -187,13 +187,7 @@
IEffect::OpenEffectReturn openReturn;
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));
- updateMqs(openReturn);
-
- if (status_t status = updateEventFlags(); status != OK) {
- ALOGV("%s closing at status %d", __func__, status);
- mEffect->close();
- return status;
- }
+ updateMqsAndEventFlags(openReturn);
} else if (mCommon != common) {
ALOGI("%s at state %s, setParameter", __func__, android::internal::ToString(state).c_str());
Parameter aidlParam = UNION_MAKE(Parameter, common, common);
@@ -204,13 +198,21 @@
return *static_cast<int32_t*>(pReplyData) = OK;
}
-void EffectConversionHelperAidl::updateMqs(const IEffect::OpenEffectReturn& ret) {
+void EffectConversionHelperAidl::updateMqsAndEventFlags(const IEffect::OpenEffectReturn& ret) {
if (mIsProxyEffect) {
mStatusQ = std::static_pointer_cast<EffectProxy>(mEffect)->getStatusMQ();
+ } else {
+ mStatusQ = std::make_shared<StatusMQ>(ret.statusMQ);
+ }
+ updateEventFlags();
+ updateDataMqs(ret);
+}
+
+void EffectConversionHelperAidl::updateDataMqs(const IEffect::OpenEffectReturn& ret) {
+ if (mIsProxyEffect) {
mInputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getInputMQ();
mOutputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getOutputMQ();
} else {
- mStatusQ = std::make_shared<StatusMQ>(ret.statusMQ);
mInputQ = std::make_shared<DataMQ>(ret.inputDataMQ);
mOutputQ = std::make_shared<DataMQ>(ret.outputDataMQ);
}
@@ -407,10 +409,8 @@
}
// update FMQs if the effect instance already open
if (State state; effectProxy->getState(&state).isOk() && state != State::INIT) {
- mStatusQ = effectProxy->getStatusMQ();
- mInputQ = effectProxy->getInputMQ();
- mOutputQ = effectProxy->getOutputMQ();
- updateEventFlags();
+ IEffect::OpenEffectReturn openReturn;
+ updateMqsAndEventFlags(openReturn);
}
}
return *static_cast<int32_t*>(pReplyData) = OK;
@@ -512,7 +512,8 @@
IEffect::OpenEffectReturn openReturn;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->reopen(&openReturn)));
- updateMqs(openReturn);
+ // status MQ won't be changed after open
+ updateDataMqs(openReturn);
return OK;
}
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 8b9efb3..c4841c5 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -98,7 +98,6 @@
std::shared_ptr<StatusMQ> mStatusQ = nullptr;
std::shared_ptr<DataMQ> mInputQ = nullptr, mOutputQ = nullptr;
-
struct EventFlagDeleter {
void operator()(::android::hardware::EventFlag* flag) const {
if (flag) {
@@ -108,8 +107,10 @@
};
std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr;
status_t updateEventFlags();
-
- void updateMqs(const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn& ret);
+ void updateDataMqs(
+ const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn& ret);
+ void updateMqsAndEventFlags(
+ const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn& ret);
status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 5f525d7..2a8ebc6 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -788,7 +788,7 @@
if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
parameters, String8(AudioParameter::keyOffloadCodecAverageBitRate),
[&](int value) {
- return value > 0 ?
+ return value >= 0 ?
mOffloadMetadata.averageBitRatePerSecond = value, OK : BAD_VALUE;
}))) {
updateMetadata = true;
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index bb7e4c6..b7a42cd 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -854,21 +854,34 @@
LOG(DEBUG) << "Effect_process() processing last frame";
}
mNumberEffectsCalled = 0;
- float* outTmp = (accumulate ? getWorkBuffer() : out);
- /* Process the samples */
- LVM_ReturnStatus_en lvmStatus;
- {
- std::lock_guard lg(mMutex);
-
- lvmStatus = LVM_Process(mInstance, in, outTmp, inputFrameCount, 0);
- if (lvmStatus != LVM_SUCCESS) {
- LOG(ERROR) << __func__ << lvmStatus;
- return {EX_UNSUPPORTED_OPERATION, 0, 0};
- }
- if (accumulate) {
- for (int i = 0; i < samples; i++) {
- out[i] += outTmp[i];
+ int frames = samples * sizeof(float) / frameSize;
+ int bufferIndex = 0;
+ // LVM library supports max of int16_t frames at a time and should be multiple of
+ // kBlockSizeMultiple.
+ constexpr int kBlockSizeMultiple = 4;
+ constexpr int kMaxBlockFrames =
+ (std::numeric_limits<int16_t>::max() / kBlockSizeMultiple) * kBlockSizeMultiple;
+ while (frames > 0) {
+ float* outTmp = (accumulate ? getWorkBuffer() : out);
+ /* Process the samples */
+ LVM_ReturnStatus_en lvmStatus;
+ {
+ std::lock_guard lg(mMutex);
+ int processFrames = std::min(frames, kMaxBlockFrames);
+ lvmStatus = LVM_Process(mInstance, in + bufferIndex, outTmp + bufferIndex,
+ processFrames, 0);
+ if (lvmStatus != LVM_SUCCESS) {
+ LOG(ERROR) << "LVM lib failed with error: " << lvmStatus;
+ return {EX_UNSUPPORTED_OPERATION, 0, 0};
}
+ if (accumulate) {
+ for (int i = 0; i < samples; i++) {
+ out[i] += outTmp[i];
+ }
+ }
+ frames -= processFrames;
+ int processedSize = processFrames * frameSize / sizeof(float);
+ bufferIndex += processedSize;
}
}
} else {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index bc1a97c..d50c06b 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2454,6 +2454,11 @@
return true;
}
+ // Make sure abs(timeUs) does not overflow
+ if (timeUs == INT64_MIN) {
+ return false;
+ }
+
// Ensure that the timeUs value does not have extremely low or high values
// that would cause an underflow or overflow, like in the calculation -
// mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index 22885c9..5dd8423 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -1,8 +1,5 @@
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
// writerTest fails about 5 out of 66
// { "name": "writerTest" },
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 24020d1..dc7d787 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -330,6 +330,7 @@
<!-- Video Quality control -->
<!-- supports QP bounding with standard keys -->
<Feature name="qp-bounds" />
+ <Feature name="bitrate-modes" value="VBR,CBR" />
<Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vp8.encoder" type="video/x-vnd.on2.vp8" variant="slow-cpu,!slow-cpu">
diff --git a/media/libstagefright/timedtext/TEST_MAPPING b/media/libstagefright/timedtext/TEST_MAPPING
index 35a5b11..f011d04 100644
--- a/media/libstagefright/timedtext/TEST_MAPPING
+++ b/media/libstagefright/timedtext/TEST_MAPPING
@@ -1,9 +1,5 @@
-// mappings for frameworks/av/media/libstagefright/timedtext
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
{ "name": "TimedTextUnitTest" }
]
}
diff --git a/media/module/codecs/amrnb/TEST_MAPPING b/media/module/codecs/amrnb/TEST_MAPPING
index 343d08a..306921f 100644
--- a/media/module/codecs/amrnb/TEST_MAPPING
+++ b/media/module/codecs/amrnb/TEST_MAPPING
@@ -1,9 +1,5 @@
-// mappings for frameworks/av/media/libstagefright/codecs/amrnb
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
{ "name": "AmrnbDecoderTest"},
{ "name": "AmrnbEncoderTest"}
]
diff --git a/media/module/codecs/amrwb/TEST_MAPPING b/media/module/codecs/amrwb/TEST_MAPPING
new file mode 100644
index 0000000..3f05c90
--- /dev/null
+++ b/media/module/codecs/amrwb/TEST_MAPPING
@@ -0,0 +1,6 @@
+{
+ "postsubmit": [
+ { "name": "AmrwbDecoderTest"},
+ { "name": "AmrwbEncoderTest"}
+ ]
+}
diff --git a/media/module/codecs/amrwb/dec/TEST_MAPPING b/media/module/codecs/amrwb/dec/TEST_MAPPING
deleted file mode 100644
index 0278d26..0000000
--- a/media/module/codecs/amrwb/dec/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-// mappings for frameworks/av/media/libstagefright/codecs/amrwb
-{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
- { "name": "AmrwbDecoderTest"}
-
- ]
-}
diff --git a/media/module/codecs/amrwb/enc/TEST_MAPPING b/media/module/codecs/amrwb/enc/TEST_MAPPING
deleted file mode 100644
index 045e8b3..0000000
--- a/media/module/codecs/amrwb/enc/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-// mappings for frameworks/av/media/libstagefright/codecs/amrwbenc
-{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
- { "name": "AmrwbEncoderTest"}
-
- ]
-}
diff --git a/media/module/codecs/flac/TEST_MAPPING b/media/module/codecs/flac/TEST_MAPPING
new file mode 100644
index 0000000..725ea90
--- /dev/null
+++ b/media/module/codecs/flac/TEST_MAPPING
@@ -0,0 +1,5 @@
+{
+ "postsubmit": [
+ { "name": "FlacDecoderTest"}
+ ]
+}
diff --git a/media/module/codecs/flac/dec/test/Android.bp b/media/module/codecs/flac/dec/test/Android.bp
index a4c2735..8004c4a 100644
--- a/media/module/codecs/flac/dec/test/Android.bp
+++ b/media/module/codecs/flac/dec/test/Android.bp
@@ -28,6 +28,7 @@
cc_test {
name: "FlacDecoderTest",
gtest: true,
+ test_suites: ["device-tests"],
srcs: [
"FlacDecoderTest.cpp",
diff --git a/media/module/codecs/m4v_h263/TEST_MAPPING b/media/module/codecs/m4v_h263/TEST_MAPPING
index ba3ff1c..8599fa5 100644
--- a/media/module/codecs/m4v_h263/TEST_MAPPING
+++ b/media/module/codecs/m4v_h263/TEST_MAPPING
@@ -1,18 +1,6 @@
-// mappings for frameworks/av/media/libstagefright/codecs/m4v_h263
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
-
- // the decoder reports something bad about an unexpected newline in the *config file
- // and the config file looks like the AndroidTest.xml file that we put in there.
- // I don't get this from the Encoder -- and I don't see any substantive difference
- // between decode and encode AndroidTest.xml files -- except that encode does NOT
- // finish with a newline.
- // strange.
+ "postsubmit": [
{ "name": "Mpeg4H263DecoderTest"},
{ "name": "Mpeg4H263EncoderTest"}
-
]
}
diff --git a/media/module/codecs/mp3dec/TEST_MAPPING b/media/module/codecs/mp3dec/TEST_MAPPING
index 4ef4317..5faece6 100644
--- a/media/module/codecs/mp3dec/TEST_MAPPING
+++ b/media/module/codecs/mp3dec/TEST_MAPPING
@@ -1,9 +1,5 @@
-// mappings for frameworks/av/media/libstagefright/codecs/mp3dec
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
{ "name": "Mp3DecoderTest"}
]
}
diff --git a/media/module/esds/TEST_MAPPING b/media/module/esds/TEST_MAPPING
index 9368b6d..0337743 100644
--- a/media/module/esds/TEST_MAPPING
+++ b/media/module/esds/TEST_MAPPING
@@ -1,9 +1,5 @@
-// mappings for frameworks/av/media/module/esds
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
{ "name": "ESDSTest" }
]
}
diff --git a/media/module/esds/tests/Android.bp b/media/module/esds/tests/Android.bp
index aea611e..427b275 100644
--- a/media/module/esds/tests/Android.bp
+++ b/media/module/esds/tests/Android.bp
@@ -25,6 +25,7 @@
cc_test {
name: "ESDSTest",
gtest: true,
+ test_suites: ["device-tests"],
srcs: [
"ESDSTest.cpp",
diff --git a/media/module/foundation/TEST_MAPPING b/media/module/foundation/TEST_MAPPING
index a70c352..ea4e4fd 100644
--- a/media/module/foundation/TEST_MAPPING
+++ b/media/module/foundation/TEST_MAPPING
@@ -1,9 +1,6 @@
-// mappings for frameworks/av/media/libstagefright/foundation
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
+ { "name": "AVCUtilsUnitTest" },
{ "name": "OpusHeaderTest" }
],
diff --git a/media/module/foundation/tests/AVCUtils/Android.bp b/media/module/foundation/tests/AVCUtils/Android.bp
index ee7db21..c306c73 100644
--- a/media/module/foundation/tests/AVCUtils/Android.bp
+++ b/media/module/foundation/tests/AVCUtils/Android.bp
@@ -28,6 +28,7 @@
cc_test {
name: "AVCUtilsUnitTest",
gtest: true,
+ test_suites: ["device-tests"],
srcs: [
"AVCUtilsUnitTest.cpp",
diff --git a/media/module/foundation/tests/AVCUtils/AndroidTest.xml b/media/module/foundation/tests/AVCUtils/AndroidTest.xml
index e30bfbf..315373f 100644
--- a/media/module/foundation/tests/AVCUtils/AndroidTest.xml
+++ b/media/module/foundation/tests/AVCUtils/AndroidTest.xml
@@ -16,7 +16,7 @@
<configuration description="Test module config for AVC Utils unit tests">
<option name="test-suite-tag" value="AVCUtilsUnitTest" />
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="false" />
+ <option name="cleanup" value="true" />
<option name="push" value="AVCUtilsUnitTest->/data/local/tmp/AVCUtilsUnitTest" />
</target_preparer>
diff --git a/media/module/id3/TEST_MAPPING b/media/module/id3/TEST_MAPPING
index 6106908..497d984 100644
--- a/media/module/id3/TEST_MAPPING
+++ b/media/module/id3/TEST_MAPPING
@@ -1,9 +1,5 @@
-// frameworks/av/media/libstagefright/id3
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
{ "name": "ID3Test" }
],
diff --git a/media/module/mpeg2ts/TEST_MAPPING b/media/module/mpeg2ts/TEST_MAPPING
index 9f4bbdf..536450f 100644
--- a/media/module/mpeg2ts/TEST_MAPPING
+++ b/media/module/mpeg2ts/TEST_MAPPING
@@ -1,9 +1,5 @@
-// frameworks/av/media/libstagefright/mpeg2ts
{
- // tests which require dynamic content
- // invoke with: atest -- --enable-module-dynamic-download=true
- // TODO(b/148094059): unit tests not allowed to download content
- "dynamic-presubmit": [
+ "postsubmit": [
{ "name": "Mpeg2tsUnitTest" }
]
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2fd908f..0057c9b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3265,6 +3265,7 @@
// requested device or one of the devices selected by the engine for this stream
// - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
// no specific device volume value exists for currently selected device.
+ // - Only apply the volume if the requested device is the desired device for volume control.
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
DeviceTypeSet curDevices = desc->devices().types();
@@ -3284,7 +3285,8 @@
if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
curSrcDevices.insert(device);
applyVolume = (curSrcDevices.find(
- Volume::getDeviceForVolume(curDevices)) != curSrcDevices.end());
+ Volume::getDeviceForVolume(curDevices)) != curSrcDevices.end())
+ && Volume::getDeviceForVolume(curSrcDevices) == device;
} else {
applyVolume = !curves.hasVolumeIndexForDevice(curSrcDevice);
}
diff --git a/services/mediaresourcemanager/DefaultResourceModel.cpp b/services/mediaresourcemanager/DefaultResourceModel.cpp
index 7bad715..990df82 100644
--- a/services/mediaresourcemanager/DefaultResourceModel.cpp
+++ b/services/mediaresourcemanager/DefaultResourceModel.cpp
@@ -44,7 +44,9 @@
clients.clear();
MediaResourceParcel mediaResource{.type = reclimRequestInfo.mResources[0].type,
.subType = reclimRequestInfo.mResources[0].subType};
- ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid,
+ reclimRequestInfo.mClientId,
+ &mediaResource};
// Resolve the secure-unsecure codec conflicts if there is any.
switch (reclimRequestInfo.mResources[0].type) {
@@ -116,7 +118,9 @@
const ReclaimRequestInfo& reclimRequestInfo,
std::vector<ClientInfo>& clients) {
MediaResourceParcel mediaResource;
- ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid,
+ reclimRequestInfo.mClientId,
+ &mediaResource};
// 1. Look to find the client(s) with the other resources, for the given
// primary type.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 3a02443..305f6fe 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -474,6 +474,7 @@
const std::vector<MediaResourceParcel>& resources,
std::vector<ClientInfo>& targetClients) {
int32_t callingPid = clientInfo.pid;
+ int64_t clientId = clientInfo.id;
std::scoped_lock lock{mLock};
if (!mProcessInfo->isPidTrusted(callingPid)) {
pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
@@ -508,7 +509,7 @@
if (secureCodec != NULL) {
MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
.subType = secureCodec->subType};
- ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &mediaResource};
if (!mSupportsMultipleSecureCodecs) {
if (!getAllClients_l(resourceRequestInfo, targetClients)) {
return false;
@@ -525,7 +526,7 @@
if (!mSupportsSecureWithNonSecureCodec) {
MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
.subType = nonSecureCodec->subType};
- ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &mediaResource};
if (!getAllClients_l(resourceRequestInfo, targetClients)) {
return false;
}
@@ -533,7 +534,7 @@
}
if (drmSession != NULL) {
- ResourceRequestInfo resourceRequestInfo{callingPid, drmSession};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, drmSession};
getClientForResource_l(resourceRequestInfo, targetClients);
if (targetClients.size() == 0) {
return false;
@@ -542,18 +543,18 @@
if (targetClients.size() == 0 && graphicMemory != nullptr) {
// if no secure/non-secure codec conflict, run second pass to handle other resources.
- ResourceRequestInfo resourceRequestInfo{callingPid, graphicMemory};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, graphicMemory};
getClientForResource_l(resourceRequestInfo, targetClients);
}
if (targetClients.size() == 0) {
// if we are here, run the third pass to free one codec with the same type.
if (secureCodec != nullptr) {
- ResourceRequestInfo resourceRequestInfo{callingPid, secureCodec};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, secureCodec};
getClientForResource_l(resourceRequestInfo, targetClients);
}
if (nonSecureCodec != nullptr) {
- ResourceRequestInfo resourceRequestInfo{callingPid, nonSecureCodec};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, nonSecureCodec};
getClientForResource_l(resourceRequestInfo, targetClients);
}
}
@@ -562,12 +563,12 @@
// if we are here, run the fourth pass to free one codec with the different type.
if (secureCodec != nullptr) {
MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
- ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &temp};
getClientForResource_l(resourceRequestInfo, targetClients);
}
if (nonSecureCodec != nullptr) {
MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
- ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &temp};
getClientForResource_l(resourceRequestInfo, targetClients);
}
}
@@ -914,6 +915,11 @@
for (auto& [pid, infos] : mMap) {
for (const auto& [id, info] : infos) {
+ if (pid == resourceRequestInfo.mCallingPid && id == resourceRequestInfo.mClientId) {
+ ALOGI("%s: Skip the client[%jd] for which the resource request is made",
+ __func__, id);
+ continue;
+ }
if (hasResourceType(type, subType, info.resources)) {
if (!isCallingPriorityHigher_l(resourceRequestInfo.mCallingPid, pid)) {
// some higher/equal priority process owns the resource,
diff --git a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
index af093ca..0a0a8f4 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
@@ -248,7 +248,7 @@
// Use the Resource Model to get a list of all the clients that hold the
// needed/requested resources.
uint32_t callingImportance = std::max(0, clientInfo.importance);
- ReclaimRequestInfo reclaimRequestInfo{callingPid, callingImportance, resources};
+ ReclaimRequestInfo reclaimRequestInfo{callingPid, clientInfo.id, callingImportance, resources};
std::vector<ClientInfo> clients;
if (!mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients)) {
if (clients.empty()) {
@@ -300,7 +300,10 @@
// Use the DefaultResourceModel to get all the clients with the resources requested.
std::vector<MediaResourceParcel> resources{*resourceRequestInfo.mResource};
- ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid, 0, resources};
+ ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid,
+ resourceRequestInfo.mClientId,
+ 0, // default importance
+ resources};
std::vector<ClientInfo> clients;
mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients);
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.h b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
index 32cb219..e8f1515 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -166,11 +166,13 @@
/*
* Resource Reclaim request info that encapsulates
* - the calling/requesting process pid.
+ * - id of the client that made reclaim request.
* - the calling/requesting client's importance.
* - the list of resources requesting (to be reclaimed from others)
*/
struct ReclaimRequestInfo {
int mCallingPid = -1;
+ int64_t mClientId = 0;
uint32_t mCallingClientImportance = 0;
const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
};
@@ -178,11 +180,14 @@
/*
* Resource request info that encapsulates
* - the calling/requesting process pid.
+ * - the calling/requesting client's id.
* - the resource requesting (to be reclaimed from others)
*/
struct ResourceRequestInfo {
// pid of the calling/requesting process.
int mCallingPid = -1;
+ // id of the calling/requesting client.
+ int64_t mClientId = 0;
// resources requested.
const ::aidl::android::media::MediaResourceParcel* mResource;
};
diff --git a/services/mediaresourcemanager/ResourceTracker.cpp b/services/mediaresourcemanager/ResourceTracker.cpp
index 22381c3..3ee20cd 100644
--- a/services/mediaresourcemanager/ResourceTracker.cpp
+++ b/services/mediaresourcemanager/ResourceTracker.cpp
@@ -715,6 +715,11 @@
MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
for (const auto& [id, /* ResourceInfo */ info] : infos) {
+ if (pid == resourceRequestInfo.mCallingPid && id == resourceRequestInfo.mClientId) {
+ ALOGI("%s: Skip the client[%jd] for which the resource request is made",
+ __func__, id);
+ continue;
+ }
if (hasResourceType(type, subType, info.resources)) {
if (!isCallingPriorityHigher(resourceRequestInfo.mCallingPid, pid)) {
// some higher/equal priority process owns the resource,
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 7e8a4a0..2c8659d 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -165,6 +165,7 @@
DISALLOW_EVIL_CONSTRUCTORS(TestClient);
};
+// [pid, uid] used by the test.
static const int kTestPid1 = 30;
static const int kTestUid1 = 1010;
@@ -175,6 +176,12 @@
static const int kMidPriorityPid = 25;
static const int kHighPriorityPid = 10;
+// Client Ids used by the test.
+static const int kLowPriorityClientId = 1111;
+static const int kMidPriorityClientId = 2222;
+static const int kHighPriorityClientId = 3333;
+
+// Client importance used by the test.
static const int32_t kHighestCodecImportance = 0;
static const int32_t kLowestCodecImportance = 100;
static const int32_t kMidCodecImportance = 50;
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index b3a0932..027987e 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -337,7 +337,7 @@
// priority too low to reclaim resource
ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kLowPriorityPid),
.uid = static_cast<int32_t>(kTestUid1),
- .id = 0,
+ .id = kLowPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(clientInfo, resources, &result));
@@ -475,9 +475,9 @@
MediaResource resource(MediaResource::Type::kSecureCodec,
MediaResource::SubType::kUnspecifiedSubType,
1);
- ResourceRequestInfo requestInfoHigh { kHighPriorityPid, &resource};
- ResourceRequestInfo requestInfoMid { kMidPriorityPid, &resource};
- ResourceRequestInfo requestInfoLow { kLowPriorityPid, &resource};
+ ResourceRequestInfo requestInfoHigh { kHighPriorityPid, kHighPriorityClientId, &resource};
+ ResourceRequestInfo requestInfoMid { kMidPriorityPid, kMidPriorityClientId, &resource};
+ ResourceRequestInfo requestInfoLow { kLowPriorityPid, kLowPriorityClientId, &resource};
EXPECT_FALSE(mService->getAllClients_l(requestInfoLow, targetClients));
// some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
@@ -491,6 +491,81 @@
EXPECT_EQ(getId(mTestClient1), targetClients[1].mClientId);
}
+ // test set up
+ // ---------------------------------------------------------------------------
+ // pid/priority client/clientId type number
+ // ---------------------------------------------------------------------------
+ // kTestPid1(30) mTestClient1 secure codec 1
+ // graphic memory 200
+ // graphic memory 200
+ // ---------------------------------------------------------------------------
+ // kTestPid2(20) mTestClient2 non-secure codec 1
+ // graphic memory 300
+ // ---------------------------------------------------
+ // mTestClient3 secure codec 1
+ // graphic memory 100
+ // ---------------------------------------------------------------------------
+ // kHighPriorityPid(10) kHighPriorityClient secure codec 1
+ // ---------------------------------------------------------------------------
+ // The kHighPriorityClient tries to reclaim request (after adding self)
+ // This should pass (and shouldn't be considered as a new client trying to
+ // reclaim from an existing client from same/higher priority process).
+ void testSelfReclaimResourceSecure() {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+ resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
+
+ ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = kLowPriorityClientId,
+ .name = "none"};
+ ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = kMidPriorityClientId,
+ .name = "none"};
+ // HighPriority process with client id kHighPriorityClientId.
+ ClientInfoParcel highPriorityClient1{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = kHighPriorityClientId,
+ .name = "none"};
+ // HighPriority process with client id 0xABCD.
+ ClientInfoParcel highPriorityClient2{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0xABCD,
+ .name = "none"};
+
+ addResource();
+
+ // Add a secure codec resource for the highPriorityClient1.
+ std::shared_ptr<IResourceManagerClient> testClient4 =
+ createTestClient(kHighPriorityPid, kTestUid2);
+ std::vector<MediaResourceParcel> resources1;
+ resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+ mService->addResource(highPriorityClient1, testClient4, resources1);
+
+ // secure codecs can't coexist and secure codec can't coexist with non-secure codec.
+ updateConfig(false, false);
+
+ // priority too low
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result));
+
+ // highPriorityClient2 tries to reclaim SecureCodec with Graphic memory.
+ // This should fail as this process already has an instance of secure
+ // codec through testClient4.
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient2, resources, &result));
+
+ // highPriorityClient1 tries to reclaim SecureCodec with Graphic memory.
+ // This should reclaim all secure and non-secure codecs.
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient1, resources, &result));
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
+
+ // Make sure there is nothing left.
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient1, resources, &result));
+ }
+
void testReclaimResourceSecure() {
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
@@ -498,15 +573,15 @@
ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kLowPriorityClientId,
.name = "none"};
ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kMidPriorityClientId,
.name = "none"};
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
// ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
@@ -553,7 +628,6 @@
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
-
// ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
{
addResource();
@@ -650,15 +724,15 @@
ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kLowPriorityClientId,
.name = "none"};
ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kMidPriorityClientId,
.name = "none"};
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
// ### secure codec can't coexist with non-secure codec ###
@@ -751,8 +825,8 @@
MediaResource resource(MediaResource::Type::kGraphicMemory,
MediaResource::SubType::kUnspecifiedSubType,
1);
- ResourceRequestInfo requestInfoHigh { kHighPriorityPid, &resource};
- ResourceRequestInfo requestInfoLow { kLowPriorityPid, &resource};
+ ResourceRequestInfo requestInfoHigh { kHighPriorityPid, kHighPriorityClientId, &resource};
+ ResourceRequestInfo requestInfoLow { kLowPriorityPid, kLowPriorityClientId, &resource};
EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(requestInfoHigh, clientInfo));
addResource();
@@ -910,7 +984,7 @@
reclaimResources.push_back(createNonSecureVideoCodecResource());
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -951,7 +1025,7 @@
reclaimResources.push_back(createNonSecureAudioCodecResource());
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -992,7 +1066,7 @@
reclaimResources.push_back(createNonSecureImageCodecResource());
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -1034,7 +1108,7 @@
reclaimResources.push_back(createGraphicMemoryResource(100));
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -1786,6 +1860,10 @@
testRemoveClient();
}
+TEST_F(ResourceManagerServiceTest, selfReclaimResource) {
+ testSelfReclaimResourceSecure();
+}
+
TEST_F(ResourceManagerServiceTest, reclaimResource) {
testReclaimResourceSecure();
testReclaimResourceNonSecure();
@@ -1873,6 +1951,10 @@
testRemoveClient();
}
+TEST_F(ResourceManagerServiceNewTest, selfReclaimResource) {
+ testSelfReclaimResourceSecure();
+}
+
TEST_F(ResourceManagerServiceNewTest, reclaimResource) {
testReclaimResourceSecure();
testReclaimResourceNonSecure();