Merge "C2SoftAomEnc: Fix encoding issues with 10bit av1 clips" into udc-dev
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index 6fff568..4affaed 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -108,7 +108,7 @@
aaudio_result_t outputError = AAUDIO_OK;
GlitchAnalyzer sineAnalyzer;
- PulseLatencyAnalyzer echoAnalyzer;
+ WhiteNoiseLatencyAnalyzer echoAnalyzer;
AudioRecording audioRecording;
LoopbackProcessor *loopbackProcessor;
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index c8461cc..f305e46 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -206,7 +206,7 @@
return validateChannelMask();
}
-bool AAudioStreamParameters::validateChannelMask() const {
+aaudio_result_t AAudioStreamParameters::validateChannelMask() const {
if (mChannelMask == AAUDIO_UNSPECIFIED) {
return AAUDIO_OK;
}
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index 565d54c..7c78f03 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -213,7 +213,7 @@
void dump() const;
private:
- bool validateChannelMask() const;
+ aaudio_result_t validateChannelMask() const;
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
diff --git a/media/libaudioclient/AudioProductStrategy.cpp b/media/libaudioclient/AudioProductStrategy.cpp
index 381faf6..d9fd58c 100644
--- a/media/libaudioclient/AudioProductStrategy.cpp
+++ b/media/libaudioclient/AudioProductStrategy.cpp
@@ -60,25 +60,50 @@
}
// Keep in sync with android/media/audiopolicy/AudioProductStrategy#attributeMatches
-bool AudioProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
- const audio_attributes_t clientAttritubes)
+int AudioProductStrategy::attributesMatchesScore(const audio_attributes_t refAttributes,
+ const audio_attributes_t clientAttritubes)
{
+ if (refAttributes == clientAttritubes) {
+ return MATCH_EQUALS;
+ }
if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
// The default product strategy is the strategy that holds default attributes by convention.
// All attributes that fail to match will follow the default strategy for routing.
- // Choosing the default must be done as a fallback, the attributes match shall not
- // select the default.
- return false;
+ // Choosing the default must be done as a fallback,so return a default (zero) score to
+ // allow identify the fallback.
+ return MATCH_ON_DEFAULT_SCORE;
}
- return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
- (clientAttritubes.usage == refAttributes.usage)) &&
- ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
- (clientAttritubes.content_type == refAttributes.content_type)) &&
- ((refAttributes.flags == AUDIO_FLAG_NONE) ||
- (clientAttritubes.flags != AUDIO_FLAG_NONE &&
- (clientAttritubes.flags & refAttributes.flags) == refAttributes.flags)) &&
- ((strlen(refAttributes.tags) == 0) ||
- (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
+ int score = MATCH_ON_DEFAULT_SCORE;
+ if (refAttributes.usage == AUDIO_USAGE_UNKNOWN) {
+ score |= MATCH_ON_DEFAULT_SCORE;
+ } else if (clientAttritubes.usage == refAttributes.usage) {
+ score |= MATCH_ON_USAGE_SCORE;
+ } else {
+ return NO_MATCH;
+ }
+ if (refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) {
+ score |= MATCH_ON_DEFAULT_SCORE;
+ } else if (clientAttritubes.content_type == refAttributes.content_type) {
+ score |= MATCH_ON_CONTENT_TYPE_SCORE;
+ } else {
+ return NO_MATCH;
+ }
+ if (strlen(refAttributes.tags) == 0) {
+ score |= MATCH_ON_DEFAULT_SCORE;
+ } else if (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0) {
+ score |= MATCH_ON_TAGS_SCORE;
+ } else {
+ return NO_MATCH;
+ }
+ if (refAttributes.flags == AUDIO_FLAG_NONE) {
+ score |= MATCH_ON_DEFAULT_SCORE;
+ } else if ((clientAttritubes.flags != AUDIO_FLAG_NONE)
+ && ((clientAttritubes.flags & refAttributes.flags) == refAttributes.flags)) {
+ score |= MATCH_ON_FLAGS_SCORE;
+ } else {
+ return NO_MATCH;
+ }
+ return score;
}
} // namespace android
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 706f51f..28d76d7 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -2136,8 +2136,7 @@
if (strategy.getId() == psId) {
auto attrVect = strategy.getVolumeGroupAttributes();
auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto& refAttr) {
- return AudioProductStrategy::attributesMatches(
- refAttr.getAttributes(), attr);
+ return refAttr.matchesScore(attr) > 0;
});
if (iter != end(attrVect)) {
return iter->getStreamType();
diff --git a/media/libaudioclient/VolumeGroupAttributes.cpp b/media/libaudioclient/VolumeGroupAttributes.cpp
index 2de4667..530e73f 100644
--- a/media/libaudioclient/VolumeGroupAttributes.cpp
+++ b/media/libaudioclient/VolumeGroupAttributes.cpp
@@ -21,11 +21,16 @@
#include <binder/Parcel.h>
#include <media/AidlConversion.h>
+#include <media/AudioProductStrategy.h>
#include <media/VolumeGroupAttributes.h>
#include <media/PolicyAidlConversion.h>
namespace android {
+int VolumeGroupAttributes::matchesScore(const audio_attributes_t &attributes) const {
+ return AudioProductStrategy::attributesMatchesScore(mAttributes, attributes);
+}
+
status_t VolumeGroupAttributes::readFromParcel(const Parcel* parcel) {
media::AudioAttributesEx aidl;
RETURN_STATUS_IF_ERROR(aidl.readFromParcel(parcel));
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 3fd438e..ec35e93 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -66,7 +66,7 @@
#define MIX_ROUTE_FLAG_ALL (MIX_ROUTE_FLAG_RENDER | MIX_ROUTE_FLAG_LOOP_BACK | \
MIX_ROUTE_FLAG_DISALLOWS_PREFERRED_DEVICE)
-#define MAX_MIXES_PER_POLICY 10
+#define MAX_MIXES_PER_POLICY 50
#define MAX_CRITERIA_PER_MIX 20
class AudioMixMatchCriterion {
diff --git a/media/libaudioclient/include/media/AudioProductStrategy.h b/media/libaudioclient/include/media/AudioProductStrategy.h
index 7bcb5aa..fcbb019 100644
--- a/media/libaudioclient/include/media/AudioProductStrategy.h
+++ b/media/libaudioclient/include/media/AudioProductStrategy.h
@@ -46,19 +46,35 @@
status_t writeToParcel(Parcel *parcel) const override;
/**
- * @brief attributesMatches: checks if client attributes matches with a reference attributes
- * "matching" means the usage shall match if reference attributes has a defined usage, AND
- * content type shall match if reference attributes has a defined content type AND
+ * @brief attributesMatchesScore: checks if client attributes matches with a reference
+ * attributes "matching" means the usage shall match if reference attributes has a defined
+ * usage, AND content type shall match if reference attributes has a defined content type AND
* flags shall match if reference attributes has defined flags AND
* tags shall match if reference attributes has defined tags.
- * Reference attributes "default" shall not be considered as a "true" case. This convention
+ * Reference attributes "default" shall be considered as a weak match case. This convention
* is used to identify the default strategy.
* @param refAttributes to be considered
* @param clientAttritubes to be considered
- * @return true if matching, false otherwise
+ * @return {@code INVALID_SCORE} if not matching, {@code MATCH_ON_DEFAULT_SCORE} if matching
+ * to default strategy, non zero positive score if matching a strategy.
*/
+ static int attributesMatchesScore(const audio_attributes_t refAttributes,
+ const audio_attributes_t clientAttritubes);
+
static bool attributesMatches(const audio_attributes_t refAttributes,
- const audio_attributes_t clientAttritubes);
+ const audio_attributes_t clientAttritubes) {
+ return attributesMatchesScore(refAttributes, clientAttritubes) > 0;
+ }
+
+ static const int MATCH_ON_TAGS_SCORE = 1 << 3;
+ static const int MATCH_ON_FLAGS_SCORE = 1 << 2;
+ static const int MATCH_ON_USAGE_SCORE = 1 << 1;
+ static const int MATCH_ON_CONTENT_TYPE_SCORE = 1 << 0;
+ static const int MATCH_ON_DEFAULT_SCORE = 0;
+ static const int MATCH_EQUALS = MATCH_ON_TAGS_SCORE | MATCH_ON_FLAGS_SCORE
+ | MATCH_ON_USAGE_SCORE | MATCH_ON_CONTENT_TYPE_SCORE;
+ static const int NO_MATCH = -1;
+
private:
std::string mName;
std::vector<VolumeGroupAttributes> mVolumeGroupAttributes;
diff --git a/media/libaudioclient/include/media/VolumeGroupAttributes.h b/media/libaudioclient/include/media/VolumeGroupAttributes.h
index 0859995..46b3612 100644
--- a/media/libaudioclient/include/media/VolumeGroupAttributes.h
+++ b/media/libaudioclient/include/media/VolumeGroupAttributes.h
@@ -41,6 +41,8 @@
mAttributes.source = AUDIO_SOURCE_INVALID;
}
+ int matchesScore(const audio_attributes_t &attributes) const;
+
audio_attributes_t getAttributes() const { return mAttributes; }
status_t readFromParcel(const Parcel *parcel) override;
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
index 91c3dea..9ec593f 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
@@ -82,7 +82,7 @@
Parameter aidlParam;
switch (type) {
case BASSBOOST_PARAM_STRENGTH: {
- uint32_t value;
+ uint16_t value;
Parameter::Id id =
MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, BassBoost::strengthPm);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
@@ -92,7 +92,7 @@
}
case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
// an invalid range indicates not setting support for this parameter
- uint16_t value =
+ uint32_t value =
::aidl::android::hardware::audio::effect::isRangeValid<Range::Tag::bassBoost>(
BassBoost::strengthPm, mDesc.capability);
return param.writeToValue(&value);
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
index 960273b..0544e3f 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
@@ -43,157 +43,208 @@
using utils::EffectParamReader;
using utils::EffectParamWriter;
-#define MAKE_AIDL_PARAMETER(aidlParam, param, value, tag) \
- { \
- if (OK != param.readFromValue(&value)) { \
- ALOGE("%s invalid parameter %s %d", __func__, #tag, value); \
- return BAD_VALUE; \
- } \
- aidlParam = MAKE_SPECIFIC_PARAMETER( \
- EnvironmentalReverb, environmentalReverb, tag, \
- VALUE_OR_RETURN_STATUS(aidl::android::convertIntegral<int>(value))); \
+/**
+ * Macro to get a parameter from effect_param_t wrapper and set it to AIDL effect.
+ *
+ * Return if there is any error, otherwise continue execution.
+ *
+ * @param param EffectParamReader, a reader wrapper of effect_param_t.
+ * @param aidlType Type of the AIDL parameter field, used to construct AIDL Parameter union.
+ * @param valueType Type of the value get from effect_param_t.
+ * @param tag The AIDL parameter union field tag.
+ */
+#define SET_AIDL_PARAMETER(param, aidlType, valueType, tag) \
+ { \
+ Parameter aidlParam; \
+ valueType value; \
+ if (status_t status = param.readFromValue(&value); status != OK) { \
+ ALOGE("%s %s read from parameter failed, ret %d", __func__, #tag, status); \
+ return status; \
+ } \
+ aidlParam = MAKE_SPECIFIC_PARAMETER( \
+ EnvironmentalReverb, environmentalReverb, tag, \
+ VALUE_OR_RETURN_STATUS(aidl::android::convertIntegral<aidlType>(value))); \
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam))); \
}
-#define GET_AIDL_PARAMETER(tag, value, param) \
+/**
+ * Macro to get a parameter from AIDL effect and write the value to effect_param_t with wrapper.
+ *
+ * Return if there is any error, otherwise continue execution.
+ *
+ * @param param EffectParamWriter, a writer wrapper of effect_param_t.
+ * @param aidlType Type of the AIDL parameter field, used to construct AIDL Parameter union.
+ * @param valueType Type of the value get from effect_param_t.
+ * @param tag The AIDL parameter union field tag.
+ */
+#define GET_AIDL_PARAMETER(param, aidltype, valueType, tag) \
{ \
+ aidltype value; \
Parameter aidlParam; \
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(EnvironmentalReverb, environmentalReverbTag, \
EnvironmentalReverb::tag); \
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam))); \
- value = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD( \
- aidlParam, EnvironmentalReverb, environmentalReverb, EnvironmentalReverb::tag, \
- std::decay_t<decltype(value)>)); \
- return param.writeToValue(&value); \
+ value = VALUE_OR_RETURN_STATUS( \
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, EnvironmentalReverb, environmentalReverb, \
+ EnvironmentalReverb::tag, std::decay_t<aidltype>)); \
+ if (status_t status = param.writeToValue((valueType*)&value); status != OK) { \
+ param.setStatus(status); \
+ ALOGE("%s %s write to parameter failed %d, ret %d", __func__, #tag, value, status); \
+ return status; \
+ } \
}
status_t AidlConversionEnvReverb::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ if (status_t status = param.readFromParameter(&type); status != OK) {
+ ALOGE("%s failed to read type from %s, ret %d", __func__, param.toString().c_str(), status);
return BAD_VALUE;
}
- Parameter aidlParam;
- uint16_t value16;
- uint32_t value32;
+
switch (type) {
case REVERB_PARAM_ROOM_LEVEL: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, roomLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
break;
}
case REVERB_PARAM_ROOM_HF_LEVEL: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, roomHfLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
break;
}
case REVERB_PARAM_DECAY_TIME: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value32, decayTimeMs);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
break;
}
case REVERB_PARAM_DECAY_HF_RATIO: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, decayHfRatioPm);
- break;
- }
- case REVERB_PARAM_REVERB_LEVEL: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, levelMb);
- break;
- }
- case REVERB_PARAM_REVERB_DELAY: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value32, delayMs);
- break;
- }
- case REVERB_PARAM_DIFFUSION: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, diffusionPm);
- break;
- }
- case REVERB_PARAM_DENSITY: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, densityPm);
- break;
- }
- case REVERB_PARAM_BYPASS: {
- if (OK != param.readFromValue(&value32)) {
- ALOGE("%s invalid bypass parameter %d", __func__, value32);
- return BAD_VALUE;
- }
- bool isByPass = VALUE_OR_RETURN_STATUS(aidl::android::convertIntegral<bool>(value32));
- aidlParam = MAKE_SPECIFIC_PARAMETER(EnvironmentalReverb, environmentalReverb, bypass,
- isByPass);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
break;
}
case REVERB_PARAM_REFLECTIONS_LEVEL: {
- // TODO
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
break;
}
case REVERB_PARAM_REFLECTIONS_DELAY: {
- // TODO
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ break;
+ }
+ case REVERB_PARAM_REVERB_LEVEL: {
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ break;
+ }
+ case REVERB_PARAM_REVERB_DELAY: {
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ break;
+ }
+ case REVERB_PARAM_DIFFUSION: {
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ break;
+ }
+ case REVERB_PARAM_DENSITY: {
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
+ break;
+ }
+ case REVERB_PARAM_BYPASS: {
+ SET_AIDL_PARAMETER(param, bool, int32_t, bypass);
break;
}
case REVERB_PARAM_PROPERTIES: {
- // TODO
+ if (sizeof(t_reverb_settings) > param.getValueSize()) {
+ ALOGE("%s vsize %zu less than t_reverb_settings size %zu", __func__,
+ param.getValueSize(), sizeof(t_reverb_settings));
+ return BAD_VALUE;
+ }
+ // this sequency needs to be aligned with t_reverb_settings
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
break;
}
default: {
// TODO: handle with vendor extension
}
}
- return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+ return OK;
}
status_t AidlConversionEnvReverb::getParameter(EffectParamWriter& param) {
uint32_t type = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- param.setStatus(BAD_VALUE);
- return BAD_VALUE;
+ if (status_t status = param.readFromParameter(&type); status != OK) {
+ ALOGE("%s failed to read type from %s", __func__, param.toString().c_str());
+ param.setStatus(status);
+ return status;
}
- uint16_t value16;
- uint32_t value32;
+
switch (type) {
case REVERB_PARAM_ROOM_LEVEL: {
- GET_AIDL_PARAMETER(roomLevelMb, value16, param);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
+ break;
}
case REVERB_PARAM_ROOM_HF_LEVEL: {
- GET_AIDL_PARAMETER(roomHfLevelMb, value16, param);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
+ break;
}
case REVERB_PARAM_DECAY_TIME: {
- GET_AIDL_PARAMETER(decayTimeMs, value32, param);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
+ break;
}
case REVERB_PARAM_DECAY_HF_RATIO: {
- GET_AIDL_PARAMETER(decayHfRatioPm, value16, param);
- }
- case REVERB_PARAM_REVERB_LEVEL: {
- GET_AIDL_PARAMETER(levelMb, value16, param);
- }
- case REVERB_PARAM_REVERB_DELAY: {
- GET_AIDL_PARAMETER(delayMs, value32, param);
- }
- case REVERB_PARAM_DIFFUSION: {
- GET_AIDL_PARAMETER(diffusionPm, value16, param);
- }
- case REVERB_PARAM_DENSITY: {
- GET_AIDL_PARAMETER(densityPm, value16, param);
- }
- case REVERB_PARAM_BYPASS: {
- bool isByPass;
- GET_AIDL_PARAMETER(bypass, isByPass, param);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
+ break;
}
case REVERB_PARAM_REFLECTIONS_LEVEL: {
- // TODO
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
break;
}
case REVERB_PARAM_REFLECTIONS_DELAY: {
- // TODO
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ break;
+ }
+ case REVERB_PARAM_REVERB_LEVEL: {
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ break;
+ }
+ case REVERB_PARAM_REVERB_DELAY: {
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ break;
+ }
+ case REVERB_PARAM_DIFFUSION: {
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ break;
+ }
+ case REVERB_PARAM_DENSITY: {
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
+ break;
+ }
+ case REVERB_PARAM_BYPASS: {
+ GET_AIDL_PARAMETER(param, bool, int32_t, bypass);
break;
}
case REVERB_PARAM_PROPERTIES: {
- // TODO
+ // this sequency needs to be aligned with t_reverb_settings
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
break;
}
default: {
// TODO: handle with vendor extension
+ return BAD_VALUE;
}
}
- return BAD_VALUE;
+ return OK;
}
} // namespace effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
index 018f3bc..e9bdf94 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -184,6 +184,20 @@
EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
return ndk::ScopedAStatus::ok();
}
+ case EnvironmentalReverb::reflectionsLevelMb: {
+ RETURN_IF(mContext->setReflectionsLevel(
+ erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::reflectionsDelayMs: {
+ RETURN_IF(mContext->setReflectionsDelay(
+ erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
+ return ndk::ScopedAStatus::ok();
+ }
case EnvironmentalReverb::levelMb: {
RETURN_IF(mContext->setEnvironmentalReverbLevel(
erParam.get<EnvironmentalReverb::levelMb>()) != RetCode::SUCCESS,
@@ -292,6 +306,14 @@
mContext->getEnvironmentalReverbDecayHfRatio());
break;
}
+ case EnvironmentalReverb::reflectionsLevelMb: {
+ erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getReflectionsLevel());
+ break;
+ }
+ case EnvironmentalReverb::reflectionsDelayMs: {
+ erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getReflectionsDelay());
+ break;
+ }
case EnvironmentalReverb::levelMb: {
erParam.set<EnvironmentalReverb::levelMb>(mContext->getEnvironmentalReverbLevel());
break;
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
index af49a25..9bb0b1a 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
@@ -83,6 +83,18 @@
RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override;
Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
+ RetCode setReflectionsDelay(int delay) {
+ mReflectionsDelayMs = delay;
+ return RetCode::SUCCESS;
+ }
+ bool getReflectionsDelay() const { return mReflectionsDelayMs; }
+
+ RetCode setReflectionsLevel(int level) {
+ mReflectionsLevelMb = level;
+ return RetCode::SUCCESS;
+ }
+ bool getReflectionsLevel() const { return mReflectionsLevelMb; }
+
IEffect::Status lvmProcess(float* in, float* out, int samples);
private:
@@ -146,15 +158,17 @@
bool mEnabled = false;
LVREV_Handle_t mInstance GUARDED_BY(mMutex);
- int mRoomLevel;
- int mRoomHfLevel;
- int mDecayTime;
- int mDecayHfRatio;
- int mLevel;
- int mDelay;
- int mDiffusion;
- int mDensity;
- bool mBypass;
+ int mRoomLevel = 0;
+ int mRoomHfLevel = 0;
+ int mDecayTime = 0;
+ int mDecayHfRatio = 0;
+ int mLevel = 0;
+ int mDelay = 0;
+ int mDiffusion = 0;
+ int mDensity = 0;
+ bool mBypass = 0;
+ int mReflectionsLevelMb = 0;
+ int mReflectionsDelayMs = 0;
PresetReverb::Presets mPreset;
PresetReverb::Presets mNextPreset;
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 85768bd..5aa9adc 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -898,10 +898,9 @@
}
}
- for (size_t cameraId = 0; cameraId < mCameraIds.size(); ++cameraId) {
+ for (size_t refIndex = 0; refIndex < mCameraIds.size(); ++refIndex) {
+ const int cameraId = mCameraIds[refIndex];
for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
- int refIndex = getRequiredProfileRefIndex(cameraId);
- CHECK(refIndex != -1);
RequiredProfileRefInfo *info =
&mRequiredProfileRefs[refIndex].mRefs[j];
@@ -931,14 +930,14 @@
int index = getCamcorderProfileIndex(cameraId, profile->mQuality);
if (index != -1) {
- ALOGV("Profile quality %d for camera %zu already exists",
+ ALOGV("Profile quality %d for camera %d already exists",
profile->mQuality, cameraId);
CHECK(index == refIndex);
continue;
}
// Insert the new profile
- ALOGV("Add a profile: quality %d=>%d for camera %zu",
+ ALOGV("Add a profile: quality %d=>%d for camera %d",
mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
profile->mQuality, cameraId);
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index 4b4f65f..5e7a4c4 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -458,6 +458,9 @@
[[fallthrough]];
case ColorUtils::kColorStandardUnspecified:
+ if (isFullRange) {
+ return is10Bit ? &BT2020_FULL : &BT601_FULL;
+ }
return is10Bit ? &BT2020_LTD_10BIT : &BT601_LIMITED;
}
diff --git a/media/module/extractors/ogg/OggExtractor.cpp b/media/module/extractors/ogg/OggExtractor.cpp
index 1c6f516..23ad1b1 100644
--- a/media/module/extractors/ogg/OggExtractor.cpp
+++ b/media/module/extractors/ogg/OggExtractor.cpp
@@ -34,6 +34,9 @@
#include <system/audio.h>
#include <utils/String8.h>
+#include <inttypes.h>
+#include <stdint.h>
+
extern "C" {
#include <Tremolo/codec_internal.h>
@@ -346,66 +349,118 @@
off64_t startOffset, off64_t *pageOffset) {
*pageOffset = startOffset;
- for (;;) {
- char signature[4];
- ssize_t n = mSource->readAt(*pageOffset, &signature, 4);
+ // balance between larger reads and reducing how much we over-read.
+ const int FIND_BUF_SIZE = 2048;
+ const int lenOggS = strlen("OggS");
+ while(1) {
- if (n < 4) {
+ // work with big buffers to amortize readAt() costs
+ char signatureBuffer[FIND_BUF_SIZE];
+ ssize_t n = mSource->readAt(*pageOffset, &signatureBuffer, sizeof(signatureBuffer));
+
+ if (n < lenOggS) {
*pageOffset = 0;
-
return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM;
}
- if (!memcmp(signature, "OggS", 4)) {
- if (*pageOffset > startOffset) {
- ALOGV("skipped %lld bytes of junk to reach next frame",
- (long long)(*pageOffset - startOffset));
- }
-
- return OK;
- }
-
- // see how far ahead to skip; avoid some fruitless comparisons
- unsigned int i;
- for (i = 1; i < 4 ; i++) {
- if (signature[i] == 'O')
+ for(int i = 0; i < n - (lenOggS - 1) ; i++) {
+ // fast scan for 1st character in a signature
+ char *p = (char *)memchr(&signatureBuffer[i], 'O', n - (lenOggS - 1) - i);
+ if (p == NULL) {
+ // no signature start in the rest of this buffer.
break;
+ }
+ int jump = (p-&signatureBuffer[i]);
+ i += jump;
+ if (memcmp("OggS", &signatureBuffer[i], lenOggS) == 0) {
+ *pageOffset += i;
+ if (*pageOffset > startOffset) {
+ ALOGD("skipped %" PRIu64 " bytes of junk to reach next frame",
+ (*pageOffset - startOffset));
+ }
+ return OK;
+ }
}
- *pageOffset += i;
+
+ // on to next block. buffer didn't end with "OggS", but could end with "Ogg".
+ // overlap enough to detect this. n >= lenOggS, so this always advances.
+ *pageOffset += n - (lenOggS - 1);
}
+ return (status_t)ERROR_END_OF_STREAM;
}
// Given the offset of the "current" page, find the page immediately preceding
// it (if any) and return its granule position.
// To do this we back up from the "current" page's offset until we find any
// page preceding it and then scan forward to just before the current page.
+//
status_t MyOggExtractor::findPrevGranulePosition(
off64_t pageOffset, uint64_t *granulePos) {
*granulePos = 0;
- off64_t prevPageOffset = 0;
- off64_t prevGuess = pageOffset;
- for (;;) {
- if (prevGuess >= 5000) {
- prevGuess -= 5000;
+ const int FIND_BUF_SIZE = 2048;
+ const int lenOggS = strlen("OggS");
+
+ if (pageOffset == 0) {
+ ALOGV("no page before the first page");
+ return UNKNOWN_ERROR;
+ }
+
+ off64_t prevPageOffset = pageOffset;
+
+ // we start our search on the byte immediately in front of pageOffset
+ // which could mean "O" immediately before and "ggS" starting at pageOffset
+ //
+ // if there was an "OggS" at pageOffset, we'll have scanned a few extra bytes
+ // but if pageOffset was chosen by a seek operation, we don't know that it
+ // reflects the beginning of a page. By choosing to scan 3 possibly unneeded
+ // bytes at the start we cover both cases.
+ //
+ off64_t firstAfter = pageOffset + lenOggS - 1; // NOT within our buffer
+ off64_t nextOffset = pageOffset;
+
+ while(prevPageOffset == pageOffset) {
+ // work with big buffers to amortize readAt() costs
+ char signatureBuffer[FIND_BUF_SIZE];
+
+ ssize_t desired = sizeof(signatureBuffer);
+ if (firstAfter >= desired) {
+ nextOffset = firstAfter - desired;
} else {
- prevGuess = 0;
+ nextOffset = 0;
+ desired = firstAfter;
}
+ ssize_t n = mSource->readAt(nextOffset, &signatureBuffer, desired);
- ALOGV("backing up %lld bytes", (long long)(pageOffset - prevGuess));
-
- status_t err = findNextPage(prevGuess, &prevPageOffset);
- if (err == ERROR_END_OF_STREAM) {
- // We are at the last page and didn't back off enough;
- // back off 5000 bytes more and try again.
- continue;
- } else if (err != OK) {
- return err;
- }
-
- if (prevPageOffset < pageOffset || prevGuess == 0) {
+ if (n < lenOggS) {
+ ALOGD("short read, get out");
break;
}
+
+ // work backwards
+ // loop control ok for n >= 0
+ for(int i = n - lenOggS; i >= 0 ; i--) {
+ // fast scan for 1st character in the signature
+ char *p = (char *)memrchr(&signatureBuffer[0], 'O', i);
+ if (p == NULL) {
+ // no signature start in the rest of this buffer.
+ break;
+ }
+ i = (p-&signatureBuffer[0]);
+ // loop start chosen to ensure we will always have lenOggS bytes
+ if (memcmp("OggS", &signatureBuffer[i], lenOggS) == 0) {
+ prevPageOffset = nextOffset + i;
+ break;
+ }
+ }
+
+ // back up for next read; make sure we catch overlaps
+ if (nextOffset == 0) {
+ // can't back up any further
+ break;
+ }
+ // current buffer might start with "ggS", include those bytes in the next iteration
+ firstAfter = nextOffset + lenOggS - 1;
}
if (prevPageOffset == pageOffset) {
@@ -413,8 +468,8 @@
return UNKNOWN_ERROR;
}
- ALOGV("prevPageOffset at %lld, pageOffset at %lld",
- (long long)prevPageOffset, (long long)pageOffset);
+ ALOGV("prevPageOffset at %" PRIu64 ", pageOffset at %" PRIu64,
+ prevPageOffset, pageOffset);
uint8_t flag = 0;
for (;;) {
Page prevPage;
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index e8251e3..1593be0 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -56,6 +56,7 @@
AttributesVector getAudioAttributes() const;
product_strategy_t getId() const { return mId; }
StreamTypeVector getSupportedStreams() const;
+ VolumeGroupAttributesVector getVolumeGroupAttributes() const { return mAttributesVector; }
/**
* @brief matches checks if the given audio attributes shall follow the strategy.
@@ -63,9 +64,9 @@
* If only the usage is available, the check is performed on the usages of the given
* attributes, otherwise all fields must match.
* @param attributes to consider
- * @return true if attributes matches with the strategy, false otherwise.
+ * @return matching score, negative value if no match.
*/
- bool matches(const audio_attributes_t attributes) const;
+ int matchesScore(const audio_attributes_t attributes) const;
bool supportStreamType(const audio_stream_type_t &streamType) const;
@@ -84,9 +85,6 @@
DeviceTypeSet getDeviceTypes() const { return mApplicableDevices; }
audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
- audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
-
- volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const;
volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;
@@ -161,6 +159,9 @@
void dump(String8 *dst, int spaces = 0) const;
private:
+ VolumeGroupAttributes getVolumeGroupAttributesForAttributes(
+ const audio_attributes_t &attr, bool fallbackOnDefault = true) const;
+
product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE;
};
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index c104c97..1d3ad1c 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -62,29 +62,17 @@
return { AUDIO_ATTRIBUTES_INITIALIZER };
}
-bool ProductStrategy::matches(const audio_attributes_t attr) const
+int ProductStrategy::matchesScore(const audio_attributes_t attr) const
{
- return std::find_if(begin(mAttributesVector), end(mAttributesVector),
- [&attr](const auto &supportedAttr) {
- return AudioProductStrategy::attributesMatches(supportedAttr.getAttributes(), attr);
- }) != end(mAttributesVector);
-}
-
-audio_stream_type_t ProductStrategy::getStreamTypeForAttributes(
- const audio_attributes_t &attr) const
-{
- const auto &iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
- [&attr](const auto &supportedAttr) {
- return AudioProductStrategy::attributesMatches(supportedAttr.getAttributes(), attr); });
- if (iter == end(mAttributesVector)) {
- return AUDIO_STREAM_DEFAULT;
+ int strategyScore = AudioProductStrategy::NO_MATCH;
+ for (const auto &attrGroup : mAttributesVector) {
+ int score = AudioProductStrategy::attributesMatchesScore(attrGroup.getAttributes(), attr);
+ if (score == AudioProductStrategy::MATCH_EQUALS) {
+ return score;
+ }
+ strategyScore = std::max(score, strategyScore);
}
- audio_stream_type_t streamType = iter->getStreamType();
- ALOGW_IF(streamType == AUDIO_STREAM_DEFAULT,
- "%s: Strategy %s supporting attributes %s has not stream type associated"
- "fallback on MUSIC. Do not use stream volume API", __func__, mName.c_str(),
- toString(attr).c_str());
- return streamType != AUDIO_STREAM_DEFAULT ? streamType : AUDIO_STREAM_MUSIC;
+ return strategyScore;
}
audio_attributes_t ProductStrategy::getAttributesForStreamType(audio_stream_type_t streamType) const
@@ -120,16 +108,6 @@
return supportedAttr.getStreamType() == streamType; }) != end(mAttributesVector);
}
-volume_group_t ProductStrategy::getVolumeGroupForAttributes(const audio_attributes_t &attr) const
-{
- for (const auto &supportedAttr : mAttributesVector) {
- if (AudioProductStrategy::attributesMatches(supportedAttr.getAttributes(), attr)) {
- return supportedAttr.getGroupId();
- }
- }
- return VOLUME_GROUP_NONE;
-}
-
volume_group_t ProductStrategy::getVolumeGroupForStreamType(audio_stream_type_t stream) const
{
for (const auto &supportedAttr : mAttributesVector) {
@@ -167,16 +145,22 @@
}
product_strategy_t ProductStrategyMap::getProductStrategyForAttributes(
- const audio_attributes_t &attr, bool fallbackOnDefault) const
+ const audio_attributes_t &attributes, bool fallbackOnDefault) const
{
+ product_strategy_t bestStrategyOrdefault = PRODUCT_STRATEGY_NONE;
+ int matchScore = AudioProductStrategy::NO_MATCH;
for (const auto &iter : *this) {
- if (iter.second->matches(attr)) {
+ int score = iter.second->matchesScore(attributes);
+ if (score == AudioProductStrategy::MATCH_EQUALS) {
return iter.second->getId();
}
+ if (score > matchScore) {
+ bestStrategyOrdefault = iter.second->getId();;
+ matchScore = score;
+ }
}
- ALOGV("%s: No matching product strategy for attributes %s, return default", __FUNCTION__,
- toString(attr).c_str());
- return fallbackOnDefault? getDefault() : PRODUCT_STRATEGY_NONE;
+ return (matchScore != AudioProductStrategy::MATCH_ON_DEFAULT_SCORE || fallbackOnDefault) ?
+ bestStrategyOrdefault : PRODUCT_STRATEGY_NONE;
}
audio_attributes_t ProductStrategyMap::getAttributesForStreamType(audio_stream_type_t stream) const
@@ -192,20 +176,6 @@
return {};
}
-audio_stream_type_t ProductStrategyMap::getStreamTypeForAttributes(
- const audio_attributes_t &attr) const
-{
- for (const auto &iter : *this) {
- audio_stream_type_t stream = iter.second->getStreamTypeForAttributes(attr);
- if (stream != AUDIO_STREAM_DEFAULT) {
- return stream;
- }
- }
- ALOGV("%s: No product strategy for attributes %s, using default (aka MUSIC)", __FUNCTION__,
- toString(attr).c_str());
- return AUDIO_STREAM_MUSIC;
-}
-
product_strategy_t ProductStrategyMap::getDefault() const
{
if (mDefaultStrategy != PRODUCT_STRATEGY_NONE) {
@@ -270,16 +240,39 @@
return at(psId)->getDeviceAddress();
}
+VolumeGroupAttributes ProductStrategyMap::getVolumeGroupAttributesForAttributes(
+ const audio_attributes_t &attr, bool fallbackOnDefault) const
+{
+ int matchScore = AudioProductStrategy::NO_MATCH;
+ VolumeGroupAttributes bestVolumeGroupAttributes = {};
+ for (const auto &iter : *this) {
+ for (const auto &volGroupAttr : iter.second->getVolumeGroupAttributes()) {
+ int score = volGroupAttr.matchesScore(attr);
+ if (score == AudioProductStrategy::MATCH_EQUALS) {
+ return volGroupAttr;
+ }
+ if (score > matchScore) {
+ matchScore = score;
+ bestVolumeGroupAttributes = volGroupAttr;
+ }
+ }
+ }
+ return (matchScore != AudioProductStrategy::MATCH_ON_DEFAULT_SCORE || fallbackOnDefault) ?
+ bestVolumeGroupAttributes : VolumeGroupAttributes();
+}
+
+audio_stream_type_t ProductStrategyMap::getStreamTypeForAttributes(
+ const audio_attributes_t &attr) const
+{
+ audio_stream_type_t streamType = getVolumeGroupAttributesForAttributes(
+ attr, /* fallbackOnDefault= */ true).getStreamType();
+ return streamType != AUDIO_STREAM_DEFAULT ? streamType : AUDIO_STREAM_MUSIC;
+}
+
volume_group_t ProductStrategyMap::getVolumeGroupForAttributes(
const audio_attributes_t &attr, bool fallbackOnDefault) const
{
- for (const auto &iter : *this) {
- volume_group_t group = iter.second->getVolumeGroupForAttributes(attr);
- if (group != VOLUME_GROUP_NONE) {
- return group;
- }
- }
- return fallbackOnDefault ? getDefaultVolumeGroup() : VOLUME_GROUP_NONE;
+ return getVolumeGroupAttributesForAttributes(attr, fallbackOnDefault).getGroupId();
}
volume_group_t ProductStrategyMap::getVolumeGroupForStreamType(
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 948cee1..59d1ae4 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -241,6 +241,7 @@
"format_hardware",
"channel_count_hardware",
"sample_rate_hardware",
+ "uid",
};
static constexpr const char * HeadTrackerDeviceEnabledFields[] {
@@ -1376,6 +1377,8 @@
mAudioAnalytics.mAnalyticsState->timeMachine().get(
key, AMEDIAMETRICS_PROP_SAMPLERATEHARDWARE, &sampleRateHardware);
+ const auto uid = item->getUid();
+
LOG(LOG_LEVEL) << "key:" << key
<< " path:" << path
<< " direction:" << direction << "(" << directionStr << ")"
@@ -1398,7 +1401,8 @@
<< "(" << sharingModeRequestedStr << ")"
<< " format_hardware:" << formatHardware << "(" << formatHardwareStr << ")"
<< " channel_count_hardware:" << channelCountHardware
- << " sample_rate_hardware: " << sampleRateHardware;
+ << " sample_rate_hardware: " << sampleRateHardware
+ << " uid: " << uid;
if (mAudioAnalytics.mDeliverStatistics) {
const stats::media_metrics::BytesField bf_serialized(
@@ -1426,6 +1430,7 @@
, formatHardware
, channelCountHardware
, sampleRateHardware
+ , uid
);
std::stringstream ss;
ss << "result:" << result;
@@ -1452,6 +1457,7 @@
, formatHardware
, channelCountHardware
, sampleRateHardware
+ , uid
);
ss << " " << fieldsStr;
std::string str = ss.str();