Merge "m4v_h263: Fix integer-overflow in idct_vca.cpp"
diff --git a/apex/Android.bp b/apex/Android.bp
index ef296d6..80e751c 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -64,10 +64,9 @@
],
}
-prebuilt_etc {
+linker_config {
name: "media-linker-config",
- src: "linker.config.txt",
- filename: "linker.config.txt",
+ src: "linker.config.json",
installable: false,
}
diff --git a/apex/linker.config.json b/apex/linker.config.json
new file mode 100644
index 0000000..67c076e
--- /dev/null
+++ b/apex/linker.config.json
@@ -0,0 +1,3 @@
+{
+ "visible": true
+}
diff --git a/apex/linker.config.txt b/apex/linker.config.txt
deleted file mode 100644
index d1c815b..0000000
--- a/apex/linker.config.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Extra linker configurations for media APEX
-# See https://android.googlesource.com/platform/system/linkerconfig/+/master/README.md#apex_etc_linker_config_txt
-
-[properties]
-
-# Set media APEX as force visible so media APEX namespace is accessible via android_get_exported_namespace
-visible = true
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
index a04ab3f..d86094e 100644
--- a/apex/testing/Android.bp
+++ b/apex/testing/Android.bp
@@ -17,7 +17,10 @@
manifest: "test_manifest.json",
file_contexts: ":com.android.media-file_contexts",
defaults: ["com.android.media-defaults"],
- prebuilts: ["sdkinfo_45"],
+ prebuilts: [
+ "sdkinfo_45",
+ "media-linker-config",
+ ],
installable: false,
}
diff --git a/media/OWNERS b/media/OWNERS
index bd83ad9..3e194f0 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -11,9 +11,11 @@
lajos@google.com
marcone@google.com
mnaganov@google.com
+nchalko@google.com
pawin@google.com
philburk@google.com
pmclean@google.com
+quxiangfang@google.com
rachad@google.com
rago@google.com
robertshih@google.com
diff --git a/media/codec2/core/include/C2Buffer.h b/media/codec2/core/include/C2Buffer.h
index 3d3587c..fe37b05 100644
--- a/media/codec2/core/include/C2Buffer.h
+++ b/media/codec2/core/include/C2Buffer.h
@@ -734,6 +734,22 @@
}
virtual ~C2Allocator() = default;
+
+ /**
+ * Returns a true if the handle looks valid for this allocator.
+ *
+ * It does not actually validate that the handle represents a valid allocation (by this
+ * allocator), only that the handle could have been returned by this allocator. As such,
+ * multiple allocators may return true for looksValid for the same handle.
+ *
+ * This method MUST be "non-blocking", MUST not access kernel and/or device drivers, and
+ * return within 1us.
+ *
+ * \param handle the handle for an existing allocation (possibly from another
+ * allocator)
+ */
+ virtual bool checkHandle(const C2Handle *const handle) const = 0;
+
protected:
C2Allocator() = default;
};
@@ -2156,9 +2172,12 @@
};
/**
- * An extension of C2Info objects that can contain arbitrary buffer data.
+ * A const metadata object that can contain arbitrary buffer data.
*
- * \note This object is not describable and contains opaque data.
+ * This object is not an actual C2Info and is not attached to buffers (C2Buffer), but rather to
+ * frames (C2FrameData). It is not describable via C2ParamDescriptor.
+ *
+ * C2InfoBuffer is a const object that can be allocated on stack and is copiable.
*/
class C2InfoBuffer {
public:
@@ -2167,14 +2186,65 @@
*
* \return the parameter index.
*/
- const C2Param::Index index() const;
+ const C2Param::Index index() const { return mIndex; }
/**
* Gets the buffer's data.
*
* \return the buffer's data.
*/
- const C2BufferData data() const;
+ const C2BufferData data() const { return mData; }
+
+ /// Returns a clone of this as a global info buffer.
+ C2InfoBuffer asGlobal() const {
+ C2Param::Index index = mIndex;
+ index.convertToGlobal();
+ return C2InfoBuffer(index, mData);
+ }
+
+ /// Returns a clone of this as a port info buffer.
+ C2InfoBuffer asPort(bool output) const {
+ C2Param::Index index = mIndex;
+ index.convertToPort(output);
+ return C2InfoBuffer(index, mData);
+ }
+
+ /// Returns a clone of this as a stream info buffer.
+ C2InfoBuffer asStream(bool output, unsigned stream) const {
+ C2Param::Index index = mIndex;
+ index.convertToStream(output, stream);
+ return C2InfoBuffer(index, mData);
+ }
+
+ /**
+ * Creates a global info buffer containing a single linear block.
+ *
+ * \param index the core parameter index of this info buffer.
+ * \param block the content of the info buffer.
+ *
+ * \return shared pointer to the created info buffer.
+ */
+ static C2InfoBuffer CreateLinearBuffer(C2Param::CoreIndex index, const C2ConstLinearBlock &block);
+
+ /**
+ * Creates a global info buffer containing a single graphic block.
+ *
+ * \param index the core parameter index of this info buffer.
+ * \param block the content of the info buffer.
+ *
+ * \return shared pointer to the created info buffer.
+ */
+ static C2InfoBuffer CreateGraphicBuffer(C2Param::CoreIndex index, const C2ConstGraphicBlock &block);
+
+protected:
+ // no public constructor
+ explicit C2InfoBuffer(C2Param::Index index, const std::vector<C2ConstLinearBlock> &blocks);
+ explicit C2InfoBuffer(C2Param::Index index, const std::vector<C2ConstGraphicBlock> &blocks);
+
+private:
+ C2Param::Index mIndex;
+ C2BufferData mData;
+ explicit C2InfoBuffer(C2Param::Index index, const C2BufferData &data);
};
/// @}
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 29bccd5..ebe7b40 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -249,6 +249,11 @@
// low latency mode
kParamIndexLowLatencyMode, // bool
+
+ // tunneled codec
+ kParamIndexTunneledMode, // struct
+ kParamIndexTunnelHandle, // int32[]
+ kParamIndexTunnelSystemTime, // int64
};
}
@@ -2182,6 +2187,79 @@
typedef C2PortParam<C2Tuning, C2TimestampGapAdjustmentStruct> C2PortTimestampGapTuning;
constexpr char C2_PARAMKEY_INPUT_SURFACE_TIMESTAMP_ADJUSTMENT[] = "input-surface.timestamp-adjustment";
+/* ===================================== TUNNELED CODEC ==================================== */
+
+/**
+ * Tunneled codec control.
+ */
+struct C2TunneledModeStruct {
+ /// mode
+ enum mode_t : uint32_t;
+ /// sync type
+ enum sync_type_t : uint32_t;
+
+ inline C2TunneledModeStruct() = default;
+
+ inline C2TunneledModeStruct(
+ size_t flexCount, mode_t mode_, sync_type_t type, std::vector<int32_t> id)
+ : mode(mode_), syncType(type) {
+ memcpy(&syncId, &id[0], c2_min(id.size(), flexCount) * FLEX_SIZE);
+ }
+
+ inline C2TunneledModeStruct(size_t flexCount, mode_t mode_, sync_type_t type, int32_t id)
+ : mode(mode_), syncType(type) {
+ if (flexCount >= 1) {
+ syncId[0] = id;
+ }
+ }
+
+ mode_t mode; ///< tunneled mode
+ sync_type_t syncType; ///< type of sync used for tunneled mode
+ int32_t syncId[]; ///< sync id
+
+ DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TunneledMode, syncId)
+ C2FIELD(mode, "mode")
+ C2FIELD(syncType, "sync-type")
+ C2FIELD(syncId, "sync-id")
+
+};
+
+C2ENUM(C2TunneledModeStruct::mode_t, uint32_t,
+ NONE,
+ SIDEBAND,
+);
+
+
+C2ENUM(C2TunneledModeStruct::sync_type_t, uint32_t,
+ REALTIME,
+ AUDIO_HW_SYNC,
+ HW_AV_SYNC,
+);
+
+/**
+ * Configure tunneled mode
+ */
+typedef C2PortParam<C2Tuning, C2TunneledModeStruct, kParamIndexTunneledMode>
+ C2PortTunneledModeTuning;
+constexpr char C2_PARAMKEY_TUNNELED_RENDER[] = "output.tunneled-render";
+
+/**
+ * Tunneled mode handle. The meaning of this is depends on the
+ * tunneled mode. If the tunneled mode is SIDEBAND, this is the
+ * sideband handle.
+ */
+typedef C2PortParam<C2Tuning, C2Int32Array, kParamIndexTunnelHandle> C2PortTunnelHandleTuning;
+constexpr char C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE[] = "output.tunnel-handle";
+
+/**
+ * The system time using CLOCK_MONOTONIC in nanoseconds at the tunnel endpoint.
+ * For decoders this is the render time for the output frame and
+ * this corresponds to the media timestamp of the output frame.
+ */
+typedef C2PortParam<C2Info, C2SimpleValueStruct<int64_t>, kParamIndexTunnelSystemTime>
+ C2PortTunnelSystemTime;
+constexpr char C2_PARAMKEY_OUTPUT_RENDER_TIME[] = "output.render-time";
+
/// @}
#endif // C2CONFIG_H_
diff --git a/media/codec2/core/include/C2Param.h b/media/codec2/core/include/C2Param.h
index 436269a..e938f96 100644
--- a/media/codec2/core/include/C2Param.h
+++ b/media/codec2/core/include/C2Param.h
@@ -317,7 +317,8 @@
DEFINE_FIELD_BASED_COMPARISON_OPERATORS(Index, mIndex)
private:
- friend struct C2Param; // for setStream, MakeStreamId, isValid
+ friend class C2InfoBuffer; // for convertTo*
+ friend struct C2Param; // for setStream, MakeStreamId, isValid, convertTo*
friend struct _C2ParamInspector; // for testing
/**
diff --git a/media/codec2/core/include/C2Work.h b/media/codec2/core/include/C2Work.h
index 6923f3e..67084cc 100644
--- a/media/codec2/core/include/C2Work.h
+++ b/media/codec2/core/include/C2Work.h
@@ -161,7 +161,7 @@
//< for initial work item, these may also come from the parser - if provided
//< for output buffers, these are the responses to requestedInfos
std::vector<std::unique_ptr<C2Param>> configUpdate;
- std::vector<std::shared_ptr<C2InfoBuffer>> infoBuffers;
+ std::vector<C2InfoBuffer> infoBuffers;
};
struct C2Worklet {
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index c73cb52..1f0c856 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -943,14 +943,9 @@
d->infoBuffers.resize(s.infoBuffers.size());
i = 0;
- for (const std::shared_ptr<C2InfoBuffer>& sInfoBuffer : s.infoBuffers) {
+ for (const C2InfoBuffer& sInfoBuffer : s.infoBuffers) {
InfoBuffer& dInfoBuffer = d->infoBuffers[i++];
- if (!sInfoBuffer) {
- LOG(ERROR) << "Null C2FrameData::infoBuffers["
- << i - 1 << "].";
- return false;
- }
- if (!objcpy(&dInfoBuffer, *sInfoBuffer,
+ if (!objcpy(&dInfoBuffer, sInfoBuffer,
bufferPoolSender, baseBlocks, baseBlockIndices)) {
LOG(ERROR) << "Invalid C2FrameData::infoBuffers["
<< i - 1 << "].";
diff --git a/media/codec2/hidl/1.1/utils/Android.bp b/media/codec2/hidl/1.1/utils/Android.bp
index 386f6e2..ab8635b 100644
--- a/media/codec2/hidl/1.1/utils/Android.bp
+++ b/media/codec2/hidl/1.1/utils/Android.bp
@@ -44,6 +44,12 @@
"libstagefright_bufferpool@2.0.1",
"libui",
],
+
+ // Device does not boot when global ThinLTO is enabled for this library.
+ // http://b/170595429
+ lto: {
+ never: true,
+ },
}
diff --git a/media/codec2/tests/C2Param_test.cpp b/media/codec2/tests/C2Param_test.cpp
index c39605a..bb8130c 100644
--- a/media/codec2/tests/C2Param_test.cpp
+++ b/media/codec2/tests/C2Param_test.cpp
@@ -96,7 +96,7 @@
const static std::vector<C2FieldDescriptor> _FIELD_LIST;
static const std::vector<C2FieldDescriptor> FieldList(); // <= needed for C2FieldDescriptor
const static FD::type_t TYPE = (FD::type_t)(CORE_INDEX | FD::STRUCT_FLAG);
-};
+} C2_PACK;
DEFINE_NO_NAMED_VALUES_FOR(C2SizeStruct)
@@ -111,11 +111,13 @@
struct C2TestStruct_A {
int32_t signed32;
+ // 4-byte padding
int64_t signed64[2];
uint32_t unsigned32[1];
+ // 4-byte padding
uint64_t unsigned64;
float fp32;
- C2SizeStruct sz[3];
+ C2SizeStruct sz[3]; // 8-byte structure, but 4-byte aligned
uint8_t blob[100];
char string[100];
bool yesNo[100];
@@ -124,21 +126,21 @@
static const std::vector<C2FieldDescriptor> FieldList();
// enum : uint32_t { CORE_INDEX = kParamIndexTest };
// typedef C2TestStruct_A _type;
-} __attribute__((packed));
+} __attribute__((aligned(4)));
const std::vector<C2FieldDescriptor> C2TestStruct_A::FieldList() {
return _FIELD_LIST;
}
const std::vector<C2FieldDescriptor> C2TestStruct_A::_FIELD_LIST =
{ { FD::INT32, 1, "s32", 0, 4 },
- { FD::INT64, 2, "s64", 4, 8 },
- { FD::UINT32, 1, "u32", 20, 4 },
- { FD::UINT64, 1, "u64", 24, 8 },
- { FD::FLOAT, 1, "fp", 32, 4 },
- { C2SizeStruct::TYPE, 3, "size", 36, 8 },
- { FD::BLOB, 100, "blob", 60, 1 },
- { FD::STRING, 100, "str", 160, 1 },
- { FD::BLOB, 100, "y-n", 260, 1 } };
+ { FD::INT64, 2, "s64", 8, 8 },
+ { FD::UINT32, 1, "u32", 24, 4 },
+ { FD::UINT64, 1, "u64", 32, 8 },
+ { FD::FLOAT, 1, "fp", 40, 4 },
+ { C2SizeStruct::TYPE, 3, "size", 44, 8 },
+ { FD::BLOB, 100, "blob", 68, 1 },
+ { FD::STRING, 100, "str", 168, 1 },
+ { FD::BLOB, 100, "y-n", 268, 1 } };
TEST_P(C2ParamTest_ParamFieldList, VerifyStruct) {
std::vector<C2FieldDescriptor> fields = GetParam(), expected = C2TestStruct_A::_FIELD_LIST;
@@ -198,11 +200,13 @@
struct C2TestAStruct {
int32_t signed32;
+ // 4-byte padding
int64_t signed64[2];
uint32_t unsigned32[1];
+ // 4-byte padding
uint64_t unsigned64;
float fp32;
- C2SizeStruct sz[3];
+ C2SizeStruct sz[3]; // 8-byte structure, but 4-byte aligned
uint8_t blob[100];
char string[100];
bool yesNo[100];
@@ -229,11 +233,13 @@
struct C2TestBStruct {
int32_t signed32;
+ // 4-byte padding
int64_t signed64[2];
uint32_t unsigned32[1];
+ // 4-byte padding
uint64_t unsigned64;
float fp32;
- C2SizeStruct sz[3];
+ C2SizeStruct sz[3]; // 8-byte structure, but 4-byte aligned
uint8_t blob[100];
char string[100];
bool yesNo[100];
@@ -286,7 +292,7 @@
if (fields.size() > 1) {
EXPECT_EQ(2u, fields.size());
EXPECT_EQ(C2FieldDescriptor(FD::INT32, 1, "s32", 0, 4), fields[0]);
- EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", 4, this->FLEX_SIZE),
+ EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", alignof(TypeParam) /* offset */, this->FLEX_SIZE),
fields[1]);
} else {
EXPECT_EQ(1u, fields.size());
@@ -392,6 +398,7 @@
struct C2TestStruct_FlexEndS64 {
int32_t signed32;
+ // 4-byte padding
int64_t mSigned64Flex[];
const static std::vector<C2FieldDescriptor> _FIELD_LIST;
@@ -406,7 +413,7 @@
}
const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS64::_FIELD_LIST = {
{ FD::INT32, 1, "s32", 0, 4 },
- { FD::INT64, 0, "flex", 4, 8 },
+ { FD::INT64, 0, "flex", 8, 8 },
};
struct C2TestFlexS64Struct {
@@ -419,6 +426,7 @@
struct C2TestFlexEndS64Struct {
int32_t signed32;
+ // 4-byte padding
int64_t mFlexSigned64[];
C2TestFlexEndS64Struct() {}
@@ -468,7 +476,7 @@
// enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndSize, FLEX_SIZE = 8 };
// typedef C2TestStruct_FlexEndSize _type;
// typedef C2SizeStruct FlexType;
-};
+} __attribute__((aligned(4)));
const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndSize::FieldList() {
return _FIELD_LIST;
@@ -539,14 +547,14 @@
TEST_F(C2ParamTest, FieldId) {
// pointer constructor
EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestStruct_A*)0)->signed32));
- EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestStruct_A*)0)->signed64));
- EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId(&((C2TestStruct_A*)0)->unsigned32));
- EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId(&((C2TestStruct_A*)0)->unsigned64));
- EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&((C2TestStruct_A*)0)->fp32));
- EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId(&((C2TestStruct_A*)0)->sz));
- EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId(&((C2TestStruct_A*)0)->blob));
- EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId(&((C2TestStruct_A*)0)->string));
- EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId(&((C2TestStruct_A*)0)->yesNo));
+ EXPECT_EQ(_C2FieldId(8, 8), _C2FieldId(&((C2TestStruct_A*)0)->signed64));
+ EXPECT_EQ(_C2FieldId(24, 4), _C2FieldId(&((C2TestStruct_A*)0)->unsigned32));
+ EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&((C2TestStruct_A*)0)->unsigned64));
+ EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&((C2TestStruct_A*)0)->fp32));
+ EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&((C2TestStruct_A*)0)->sz));
+ EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&((C2TestStruct_A*)0)->blob));
+ EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&((C2TestStruct_A*)0)->string));
+ EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&((C2TestStruct_A*)0)->yesNo));
EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->signed32));
EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->mFlexSize));
@@ -556,14 +564,14 @@
// member pointer constructor
EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed32));
- EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed64));
- EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32));
- EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64));
- EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::fp32));
- EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::sz));
- EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::blob));
- EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::string));
- EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::yesNo));
+ EXPECT_EQ(_C2FieldId(8, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed64));
+ EXPECT_EQ(_C2FieldId(24, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32));
+ EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64));
+ EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::fp32));
+ EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::sz));
+ EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::blob));
+ EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::string));
+ EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::yesNo));
EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::signed32));
EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::mFlexSize));
@@ -573,14 +581,14 @@
// member pointer sans type pointer
EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestStruct_A::signed32));
- EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestStruct_A::signed64));
- EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId(&C2TestStruct_A::unsigned32));
- EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId(&C2TestStruct_A::unsigned64));
- EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&C2TestStruct_A::fp32));
- EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId(&C2TestStruct_A::sz));
- EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId(&C2TestStruct_A::blob));
- EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId(&C2TestStruct_A::string));
- EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId(&C2TestStruct_A::yesNo));
+ EXPECT_EQ(_C2FieldId(8, 8), _C2FieldId(&C2TestStruct_A::signed64));
+ EXPECT_EQ(_C2FieldId(24, 4), _C2FieldId(&C2TestStruct_A::unsigned32));
+ EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&C2TestStruct_A::unsigned64));
+ EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&C2TestStruct_A::fp32));
+ EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&C2TestStruct_A::sz));
+ EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&C2TestStruct_A::blob));
+ EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&C2TestStruct_A::string));
+ EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&C2TestStruct_A::yesNo));
EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestFlexEndSizeStruct::signed32));
EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestFlexEndSizeStruct::mFlexSize));
@@ -594,14 +602,14 @@
// pointer constructor in C2Param
EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestAInfo*)0)->signed32));
- EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestAInfo*)0)->signed64));
- EXPECT_EQ(_C2FieldId(28, 4), _C2FieldId(&((C2TestAInfo*)0)->unsigned32));
- EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&((C2TestAInfo*)0)->unsigned64));
- EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&((C2TestAInfo*)0)->fp32));
- EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&((C2TestAInfo*)0)->sz));
- EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&((C2TestAInfo*)0)->blob));
- EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&((C2TestAInfo*)0)->string));
- EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&((C2TestAInfo*)0)->yesNo));
+ EXPECT_EQ(_C2FieldId(16, 8), _C2FieldId(&((C2TestAInfo*)0)->signed64));
+ EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&((C2TestAInfo*)0)->unsigned32));
+ EXPECT_EQ(_C2FieldId(40, 8), _C2FieldId(&((C2TestAInfo*)0)->unsigned64));
+ EXPECT_EQ(_C2FieldId(48, 4), _C2FieldId(&((C2TestAInfo*)0)->fp32));
+ EXPECT_EQ(_C2FieldId(52, 8), _C2FieldId(&((C2TestAInfo*)0)->sz));
+ EXPECT_EQ(_C2FieldId(76, 1), _C2FieldId(&((C2TestAInfo*)0)->blob));
+ EXPECT_EQ(_C2FieldId(176, 1), _C2FieldId(&((C2TestAInfo*)0)->string));
+ EXPECT_EQ(_C2FieldId(276, 1), _C2FieldId(&((C2TestAInfo*)0)->yesNo));
EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.signed32));
EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.mFlexSize));
@@ -611,14 +619,14 @@
// member pointer in C2Param
EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed32));
- EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed64));
- EXPECT_EQ(_C2FieldId(28, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned32));
- EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned64));
- EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::fp32));
- EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::sz));
- EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::blob));
- EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::string));
- EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::yesNo));
+ EXPECT_EQ(_C2FieldId(16, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed64));
+ EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned32));
+ EXPECT_EQ(_C2FieldId(40, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned64));
+ EXPECT_EQ(_C2FieldId(48, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::fp32));
+ EXPECT_EQ(_C2FieldId(52, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::sz));
+ EXPECT_EQ(_C2FieldId(76, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::blob));
+ EXPECT_EQ(_C2FieldId(176, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::string));
+ EXPECT_EQ(_C2FieldId(276, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::yesNo));
// NOTE: cannot use a member pointer for flex params due to introduction of 'm'
// EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfo::m.signed32));
diff --git a/media/codec2/tests/vndk/C2BufferTest.cpp b/media/codec2/tests/vndk/C2BufferTest.cpp
index 780994a..a9f8e17 100644
--- a/media/codec2/tests/vndk/C2BufferTest.cpp
+++ b/media/codec2/tests/vndk/C2BufferTest.cpp
@@ -765,4 +765,54 @@
}
}
+TEST_F(C2BufferTest, InfoBufferTest) {
+ constexpr size_t kCapacity = 524288u;
+
+ // allocate a linear block
+ std::shared_ptr<C2BlockPool> linearPool(makeLinearBlockPool());
+ std::shared_ptr<C2LinearBlock> linearBlock;
+ ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock(
+ kCapacity,
+ { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
+ &linearBlock));
+
+ C2InfoBuffer info = C2InfoBuffer::CreateLinearBuffer(
+ kParamIndexNumber1, linearBlock->share(1024, kCapacity / 2, C2Fence()));
+ std::shared_ptr<C2InfoBuffer> spInfo(new C2InfoBuffer(info));
+ ASSERT_EQ(kParamIndexNumber1, spInfo->index().coreIndex());
+ ASSERT_TRUE(spInfo->index().isGlobal());
+ ASSERT_EQ(C2Param::INFO, spInfo->index().kind());
+ ASSERT_EQ(C2BufferData::LINEAR, spInfo->data().type());
+ ASSERT_EQ(1024, spInfo->data().linearBlocks()[0].offset());
+ ASSERT_EQ(kCapacity / 2, spInfo->data().linearBlocks()[0].size());
+ // handles must actually be identical after sharing into an info buffer
+ ASSERT_EQ(linearBlock->handle(), spInfo->data().linearBlocks()[0].handle());
+ ASSERT_EQ(linearPool->getAllocatorId(), spInfo->data().linearBlocks()[0].getAllocatorId());
+
+ C2InfoBuffer streamInfo = info.asStream(false /* output */, 1u);
+ ASSERT_EQ(kParamIndexNumber1, streamInfo.index().coreIndex());
+ ASSERT_TRUE(streamInfo.index().forStream());
+ ASSERT_TRUE(streamInfo.index().forInput());
+ ASSERT_EQ(1u, streamInfo.index().stream());
+ ASSERT_EQ(C2Param::INFO, streamInfo.index().kind());
+ ASSERT_EQ(C2BufferData::LINEAR, streamInfo.data().type());
+ ASSERT_EQ(1024, streamInfo.data().linearBlocks()[0].offset());
+ ASSERT_EQ(kCapacity / 2, streamInfo.data().linearBlocks()[0].size());
+ // handles must actually be identical after sharing into an info buffer
+ ASSERT_EQ(linearBlock->handle(), streamInfo.data().linearBlocks()[0].handle());
+ ASSERT_EQ(linearPool->getAllocatorId(), streamInfo.data().linearBlocks()[0].getAllocatorId());
+
+ C2InfoBuffer portInfo = streamInfo.asPort(true /* output */);
+ ASSERT_EQ(kParamIndexNumber1, portInfo.index().coreIndex());
+ ASSERT_TRUE(portInfo.index().forPort());
+ ASSERT_TRUE(portInfo.index().forOutput());
+ ASSERT_EQ(C2Param::INFO, portInfo.index().kind());
+ ASSERT_EQ(C2BufferData::LINEAR, portInfo.data().type());
+ ASSERT_EQ(1024, portInfo.data().linearBlocks()[0].offset());
+ ASSERT_EQ(kCapacity / 2, portInfo.data().linearBlocks()[0].size());
+ // handles must actually be identical after sharing into an info buffer
+ ASSERT_EQ(linearBlock->handle(), portInfo.data().linearBlocks()[0].handle());
+ ASSERT_EQ(linearPool->getAllocatorId(), portInfo.data().linearBlocks()[0].getAllocatorId());
+}
+
} // namespace android
diff --git a/media/codec2/vndk/C2AllocatorBlob.cpp b/media/codec2/vndk/C2AllocatorBlob.cpp
index 50c9e59..565137c 100644
--- a/media/codec2/vndk/C2AllocatorBlob.cpp
+++ b/media/codec2/vndk/C2AllocatorBlob.cpp
@@ -175,12 +175,12 @@
}
// static
-bool C2AllocatorBlob::isValid(const C2Handle* const o) {
+bool C2AllocatorBlob::CheckHandle(const C2Handle* const o) {
size_t capacity;
// Distinguish C2Handle purely allocated by C2AllocatorGralloc, or one allocated through
// C2AllocatorBlob, by checking the handle's height is 1, and its format is
// PixelFormat::BLOB by GetCapacityFromHandle().
- return C2AllocatorGralloc::isValid(o) && GetCapacityFromHandle(o, &capacity) == C2_OK;
+ return C2AllocatorGralloc::CheckHandle(o) && GetCapacityFromHandle(o, &capacity) == C2_OK;
}
} // namespace android
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index e1e1377..4d7e619 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -103,7 +103,7 @@
const static uint32_t MAGIC = '\xc2gr\x00';
static
- const ExtraData* getExtraData(const C2Handle *const handle) {
+ const ExtraData* GetExtraData(const C2Handle *const handle) {
if (handle == nullptr
|| native_handle_is_invalid(handle)
|| handle->numInts < NUM_INTS) {
@@ -114,23 +114,23 @@
}
static
- ExtraData *getExtraData(C2Handle *const handle) {
- return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
+ ExtraData *GetExtraData(C2Handle *const handle) {
+ return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
}
public:
void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
- const ExtraData *ed = getExtraData(this);
+ const ExtraData *ed = GetExtraData(this);
*generation = ed->generation;
*igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
*igbp_slot = ed->igbp_slot;
}
- static bool isValid(const C2Handle *const o) {
+ static bool IsValid(const C2Handle *const o) {
if (o == nullptr) { // null handle is always valid
return true;
}
- const ExtraData *xd = getExtraData(o);
+ const ExtraData *xd = GetExtraData(o);
// we cannot validate width/height/format/usage without accessing gralloc driver
return xd != nullptr && xd->magic == MAGIC;
}
@@ -152,7 +152,7 @@
native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
if (res != nullptr) {
memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
- *getExtraData(res) = xd;
+ *GetExtraData(res) = xd;
}
return reinterpret_cast<C2HandleGralloc *>(res);
}
@@ -180,10 +180,10 @@
static bool MigrateNativeHandle(
native_handle_t *handle,
uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
- if (handle == nullptr || !isValid(handle)) {
+ if (handle == nullptr || !IsValid(handle)) {
return false;
}
- ExtraData *ed = getExtraData(handle);
+ ExtraData *ed = GetExtraData(handle);
if (!ed) return false;
ed->generation = generation;
ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
@@ -195,7 +195,7 @@
static native_handle_t* UnwrapNativeHandle(
const C2Handle *const handle) {
- const ExtraData *xd = getExtraData(handle);
+ const ExtraData *xd = GetExtraData(handle);
if (xd == nullptr || xd->magic != MAGIC) {
return nullptr;
}
@@ -211,7 +211,7 @@
uint32_t *width, uint32_t *height, uint32_t *format,
uint64_t *usage, uint32_t *stride,
uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
- const ExtraData *xd = getExtraData(handle);
+ const ExtraData *xd = GetExtraData(handle);
if (xd == nullptr) {
return nullptr;
}
@@ -784,8 +784,9 @@
return mImpl->status();
}
-bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
- return C2HandleGralloc::isValid(o);
+// static
+bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
+ return C2HandleGralloc::IsValid(o);
}
} // namespace android
diff --git a/media/codec2/vndk/C2AllocatorIon.cpp b/media/codec2/vndk/C2AllocatorIon.cpp
index 6d27a02..85623b8 100644
--- a/media/codec2/vndk/C2AllocatorIon.cpp
+++ b/media/codec2/vndk/C2AllocatorIon.cpp
@@ -73,7 +73,7 @@
};
// static
-bool C2HandleIon::isValid(const C2Handle * const o) {
+bool C2HandleIon::IsValid(const C2Handle * const o) {
if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
return false;
}
@@ -579,7 +579,7 @@
return mInit;
}
- if (!C2HandleIon::isValid(handle)) {
+ if (!C2HandleIon::IsValid(handle)) {
return C2_BAD_VALUE;
}
@@ -596,9 +596,8 @@
return ret;
}
-bool C2AllocatorIon::isValid(const C2Handle* const o) {
- return C2HandleIon::isValid(o);
+bool C2AllocatorIon::CheckHandle(const C2Handle* const o) {
+ return C2HandleIon::IsValid(o);
}
} // namespace android
-
diff --git a/media/codec2/vndk/C2Buffer.cpp b/media/codec2/vndk/C2Buffer.cpp
index 0b08f31..143355f 100644
--- a/media/codec2/vndk/C2Buffer.cpp
+++ b/media/codec2/vndk/C2Buffer.cpp
@@ -106,6 +106,7 @@
class BufferDataBuddy : public C2BufferData {
using C2BufferData::C2BufferData;
friend class ::C2Buffer;
+ friend class ::C2InfoBuffer;
};
} // namespace
@@ -396,26 +397,18 @@
std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
const C2Handle *handle) {
// TODO: get proper allocator? and mutex?
- static std::unique_ptr<C2Allocator> sAllocator = []{
- std::unique_ptr<C2Allocator> allocator;
- if (android::GetPreferredLinearAllocatorId(android::GetCodec2PoolMask()) ==
- android::C2PlatformAllocatorStore::BLOB) {
- allocator = std::make_unique<C2AllocatorBlob>(android::C2PlatformAllocatorStore::BLOB);
- } else {
- allocator = std::make_unique<C2AllocatorIon>(android::C2PlatformAllocatorStore::ION);
- }
+ static std::shared_ptr<C2Allocator> sAllocator = []{
+ std::shared_ptr<C2Allocator> allocator;
+ std::shared_ptr<C2AllocatorStore> allocatorStore = android::GetCodec2PlatformAllocatorStore();
+ allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+
return allocator;
}();
if (sAllocator == nullptr)
return nullptr;
- bool isValidHandle = false;
- if (sAllocator->getId() == android::C2PlatformAllocatorStore::BLOB) {
- isValidHandle = C2AllocatorBlob::isValid(handle);
- } else {
- isValidHandle = C2AllocatorIon::isValid(handle);
- }
+ bool isValidHandle = sAllocator->checkHandle(handle);
std::shared_ptr<C2LinearAllocation> alloc;
if (isValidHandle) {
@@ -431,26 +424,18 @@
std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
const C2Handle *cHandle, const std::shared_ptr<BufferPoolData> &data) {
// TODO: get proper allocator? and mutex?
- static std::unique_ptr<C2Allocator> sAllocator = []{
- std::unique_ptr<C2Allocator> allocator;
- if (android::GetPreferredLinearAllocatorId(android::GetCodec2PoolMask()) ==
- android::C2PlatformAllocatorStore::BLOB) {
- allocator = std::make_unique<C2AllocatorBlob>(android::C2PlatformAllocatorStore::BLOB);
- } else {
- allocator = std::make_unique<C2AllocatorIon>(android::C2PlatformAllocatorStore::ION);
- }
+ static std::shared_ptr<C2Allocator> sAllocator = []{
+ std::shared_ptr<C2Allocator> allocator;
+ std::shared_ptr<C2AllocatorStore> allocatorStore = android::GetCodec2PlatformAllocatorStore();
+ allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+
return allocator;
}();
if (sAllocator == nullptr)
return nullptr;
- bool isValidHandle = false;
- if (sAllocator->getId() == android::C2PlatformAllocatorStore::BLOB) {
- isValidHandle = C2AllocatorBlob::isValid(cHandle);
- } else {
- isValidHandle = C2AllocatorIon::isValid(cHandle);
- }
+ bool isValidHandle = sAllocator->checkHandle(cHandle);
std::shared_ptr<C2LinearAllocation> alloc;
if (isValidHandle) {
@@ -1148,7 +1133,7 @@
static std::unique_ptr<C2AllocatorGralloc> sAllocator = std::make_unique<C2AllocatorGralloc>(0);
std::shared_ptr<C2GraphicAllocation> alloc;
- if (C2AllocatorGralloc::isValid(cHandle)) {
+ if (sAllocator->isValid(cHandle)) {
c2_status_t err = sAllocator->priorGraphicAllocation(cHandle, &alloc);
const std::shared_ptr<C2PooledBlockPoolData> poolData =
std::make_shared<C2PooledBlockPoolData>(data);
@@ -1185,6 +1170,7 @@
type_t mType;
std::vector<C2ConstLinearBlock> mLinearBlocks;
std::vector<C2ConstGraphicBlock> mGraphicBlocks;
+ friend class C2InfoBuffer;
};
C2BufferData::C2BufferData(const std::vector<C2ConstLinearBlock> &blocks) : mImpl(new Impl(blocks)) {}
@@ -1200,6 +1186,35 @@
return mImpl->graphicBlocks();
}
+C2InfoBuffer::C2InfoBuffer(
+ C2Param::Index index, const std::vector<C2ConstLinearBlock> &blocks)
+ : mIndex(index), mData(BufferDataBuddy(blocks)) {
+}
+
+C2InfoBuffer::C2InfoBuffer(
+ C2Param::Index index, const std::vector<C2ConstGraphicBlock> &blocks)
+ : mIndex(index), mData(BufferDataBuddy(blocks)) {
+}
+
+C2InfoBuffer::C2InfoBuffer(
+ C2Param::Index index, const C2BufferData &data)
+ : mIndex(index), mData(data) {
+}
+
+// static
+C2InfoBuffer C2InfoBuffer::CreateLinearBuffer(
+ C2Param::CoreIndex index, const C2ConstLinearBlock &block) {
+ return C2InfoBuffer(index.coreIndex() | C2Param::Index::KIND_INFO | C2Param::Index::DIR_GLOBAL,
+ { block });
+}
+
+// static
+C2InfoBuffer C2InfoBuffer::CreateGraphicBuffer(
+ C2Param::CoreIndex index, const C2ConstGraphicBlock &block) {
+ return C2InfoBuffer(index.coreIndex() | C2Param::Index::KIND_INFO | C2Param::Index::DIR_GLOBAL,
+ { block });
+}
+
class C2Buffer::Impl {
public:
Impl(C2Buffer *thiz, const std::vector<C2ConstLinearBlock> &blocks)
@@ -1330,4 +1345,3 @@
std::shared_ptr<C2Buffer> C2Buffer::CreateGraphicBuffer(const C2ConstGraphicBlock &block) {
return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
}
-
diff --git a/media/codec2/vndk/C2PlatformStorePluginLoader.cpp b/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
index 4c330e5..bee028a 100644
--- a/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
+++ b/media/codec2/vndk/C2PlatformStorePluginLoader.cpp
@@ -33,7 +33,8 @@
} // unnamed
C2PlatformStorePluginLoader::C2PlatformStorePluginLoader(const char *libPath)
- : mCreateBlockPool(nullptr) {
+ : mCreateBlockPool(nullptr),
+ mCreateAllocator(nullptr) {
mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE);
if (mLibHandle == nullptr) {
ALOGD("Failed to load library: %s (%s)", libPath, dlerror());
diff --git a/media/codec2/vndk/include/C2AllocatorBlob.h b/media/codec2/vndk/include/C2AllocatorBlob.h
index 89ce949..fc67af7 100644
--- a/media/codec2/vndk/include/C2AllocatorBlob.h
+++ b/media/codec2/vndk/include/C2AllocatorBlob.h
@@ -44,7 +44,12 @@
virtual ~C2AllocatorBlob() override;
- static bool isValid(const C2Handle* const o);
+ virtual bool checkHandle(const C2Handle* const o) const override { return CheckHandle(o); }
+
+ static bool CheckHandle(const C2Handle* const o);
+
+ // deprecated
+ static bool isValid(const C2Handle* const o) { return CheckHandle(o); }
private:
std::shared_ptr<const Traits> mTraits;
diff --git a/media/codec2/vndk/include/C2AllocatorGralloc.h b/media/codec2/vndk/include/C2AllocatorGralloc.h
index ee7524e..578cf76 100644
--- a/media/codec2/vndk/include/C2AllocatorGralloc.h
+++ b/media/codec2/vndk/include/C2AllocatorGralloc.h
@@ -84,7 +84,12 @@
virtual ~C2AllocatorGralloc() override;
- static bool isValid(const C2Handle* const o);
+ virtual bool checkHandle(const C2Handle* const o) const override { return CheckHandle(o); }
+
+ static bool CheckHandle(const C2Handle* const o);
+
+ // deprecated
+ static bool isValid(const C2Handle* const o) { return CheckHandle(o); }
private:
class Impl;
diff --git a/media/codec2/vndk/include/C2AllocatorIon.h b/media/codec2/vndk/include/C2AllocatorIon.h
index 1b2051f..6a49b7d 100644
--- a/media/codec2/vndk/include/C2AllocatorIon.h
+++ b/media/codec2/vndk/include/C2AllocatorIon.h
@@ -57,7 +57,12 @@
virtual ~C2AllocatorIon() override;
- static bool isValid(const C2Handle* const o);
+ virtual bool checkHandle(const C2Handle* const o) const override { return CheckHandle(o); }
+
+ static bool CheckHandle(const C2Handle* const o);
+
+ // deprecated
+ static bool isValid(const C2Handle* const o) { return CheckHandle(o); }
/**
* Updates the usage mapper for subsequent new allocations, as well as the supported
diff --git a/media/codec2/vndk/internal/C2HandleIonInternal.h b/media/codec2/vndk/internal/C2HandleIonInternal.h
index c0e1d83..c67698c 100644
--- a/media/codec2/vndk/internal/C2HandleIonInternal.h
+++ b/media/codec2/vndk/internal/C2HandleIonInternal.h
@@ -28,7 +28,10 @@
mFds{ bufferFd },
mInts{ int(size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } { }
- static bool isValid(const C2Handle * const o);
+ static bool IsValid(const C2Handle * const o);
+
+ // deprecated
+ static bool isValid(const C2Handle * const o) { return IsValid(o); }
int bufferFd() const { return mFds.mBuffer; }
size_t size() const {
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 62936f6..fff12c4 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -223,7 +223,7 @@
static std::unique_ptr<C2AllocatorGralloc> sAllocator = std::make_unique<C2AllocatorGralloc>(0);
std::shared_ptr<C2GraphicAllocation> alloc;
- if (C2AllocatorGralloc::isValid(handle)) {
+ if (C2AllocatorGralloc::CheckHandle(handle)) {
uint32_t width;
uint32_t height;
uint32_t format;
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 3dbe37d..e9b589d 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -22,6 +22,9 @@
#include <media/DeviceDescriptorBase.h>
#include <media/TypeConverter.h>
+#include <arpa/inet.h>
+#include <regex>
+
namespace android {
DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type) :
@@ -34,6 +37,31 @@
{
}
+namespace {
+
+static const std::string SUPPRESSED = "SUPPRESSED";
+static const std::regex MAC_ADDRESS_REGEX("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
+
+bool isAddressSensitive(const std::string &address) {
+ if (std::regex_match(address, MAC_ADDRESS_REGEX)) {
+ return true;
+ }
+
+ sockaddr_storage ss4;
+ if (inet_pton(AF_INET, address.c_str(), &ss4) > 0) {
+ return true;
+ }
+
+ sockaddr_storage ss6;
+ if (inet_pton(AF_INET6, address.c_str(), &ss6) > 0) {
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
DeviceDescriptorBase::DeviceDescriptorBase(const AudioDeviceTypeAddr &deviceTypeAddr) :
AudioPort("", AUDIO_PORT_TYPE_DEVICE,
audio_is_output_device(deviceTypeAddr.mType) ? AUDIO_PORT_ROLE_SINK :
@@ -43,6 +71,12 @@
if (mDeviceTypeAddr.mAddress.empty() && audio_is_remote_submix_device(mDeviceTypeAddr.mType)) {
mDeviceTypeAddr.mAddress = "0";
}
+ mIsAddressSensitive = isAddressSensitive(mDeviceTypeAddr.mAddress);
+}
+
+void DeviceDescriptorBase::setAddress(const std::string &address) {
+ mDeviceTypeAddr.mAddress = address;
+ mIsAddressSensitive = isAddressSensitive(address);
}
void DeviceDescriptorBase::toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -130,10 +164,15 @@
AudioPort::dump(dst, spaces, verbose);
}
-std::string DeviceDescriptorBase::toString() const
+std::string DeviceDescriptorBase::toString(bool includeSensitiveInfo) const
{
std::stringstream sstream;
- sstream << "type:0x" << std::hex << type() << ",@:" << mDeviceTypeAddr.mAddress;
+ sstream << "type:0x" << std::hex << type();
+ // IP and MAC address are sensitive information. The sensitive information will be suppressed
+ // is `includeSensitiveInfo` is false.
+ sstream << ",@:"
+ << (!includeSensitiveInfo && mIsAddressSensitive ? SUPPRESSED
+ : mDeviceTypeAddr.mAddress);
return sstream.str();
}
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index af04721..c143c7e 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -42,7 +42,7 @@
audio_devices_t type() const { return mDeviceTypeAddr.mType; }
std::string address() const { return mDeviceTypeAddr.mAddress; }
- void setAddress(const std::string &address) { mDeviceTypeAddr.mAddress = address; }
+ void setAddress(const std::string &address);
const AudioDeviceTypeAddr& getDeviceTypeAddr() const { return mDeviceTypeAddr; }
// AudioPortConfig
@@ -61,7 +61,14 @@
void dump(std::string *dst, int spaces, int index,
const char* extraInfo = nullptr, bool verbose = true) const;
void log() const;
- std::string toString() const;
+
+ /**
+ * Return a string to describe the DeviceDescriptor.
+ *
+ * @param includeSensitiveInfo sensitive information will be added when it is true.
+ * @return a string that can be used to describe the DeviceDescriptor.
+ */
+ std::string toString(bool includeSensitiveInfo = false) const;
bool equals(const sp<DeviceDescriptorBase>& other) const;
@@ -70,6 +77,7 @@
protected:
AudioDeviceTypeAddr mDeviceTypeAddr;
+ bool mIsAddressSensitive;
uint32_t mEncapsulationModes = 0;
uint32_t mEncapsulationMetadataTypes = 0;
};
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
index a1520af..5c5f646 100644
--- a/media/libeffects/lvm/tests/lvmtest.cpp
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -94,21 +94,21 @@
AUDIO_CHANNEL_OUT_QUAD_BACK,
AUDIO_CHANNEL_OUT_QUAD_SIDE,
AUDIO_CHANNEL_OUT_SURROUND,
- (1 << 4) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_4,
AUDIO_CHANNEL_OUT_2POINT1POINT2,
AUDIO_CHANNEL_OUT_3POINT0POINT2,
AUDIO_CHANNEL_OUT_PENTA,
- (1 << 5) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_5,
AUDIO_CHANNEL_OUT_3POINT1POINT2,
AUDIO_CHANNEL_OUT_5POINT1,
AUDIO_CHANNEL_OUT_5POINT1_BACK,
AUDIO_CHANNEL_OUT_5POINT1_SIDE,
- (1 << 6) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_6,
AUDIO_CHANNEL_OUT_6POINT1,
- (1 << 7) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_7,
AUDIO_CHANNEL_OUT_5POINT1POINT2,
AUDIO_CHANNEL_OUT_7POINT1,
- (1 << 8) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_8,
};
void printUsage() {
diff --git a/media/libeffects/lvm/tests/reverb_test.cpp b/media/libeffects/lvm/tests/reverb_test.cpp
index 768f655..7cbca9b 100644
--- a/media/libeffects/lvm/tests/reverb_test.cpp
+++ b/media/libeffects/lvm/tests/reverb_test.cpp
@@ -79,21 +79,21 @@
AUDIO_CHANNEL_OUT_QUAD_BACK,
AUDIO_CHANNEL_OUT_QUAD_SIDE,
AUDIO_CHANNEL_OUT_SURROUND,
- (1 << 4) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_4,
AUDIO_CHANNEL_OUT_2POINT1POINT2,
AUDIO_CHANNEL_OUT_3POINT0POINT2,
AUDIO_CHANNEL_OUT_PENTA,
- (1 << 5) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_5,
AUDIO_CHANNEL_OUT_3POINT1POINT2,
AUDIO_CHANNEL_OUT_5POINT1,
AUDIO_CHANNEL_OUT_5POINT1_BACK,
AUDIO_CHANNEL_OUT_5POINT1_SIDE,
- (1 << 6) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_6,
AUDIO_CHANNEL_OUT_6POINT1,
- (1 << 7) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_7,
AUDIO_CHANNEL_OUT_5POINT1POINT2,
AUDIO_CHANNEL_OUT_7POINT1,
- (1 << 8) - 1,
+ AUDIO_CHANNEL_INDEX_MASK_8,
};
constexpr int kReverbConfigChMaskCount = std::size(kReverbConfigChMask);
diff --git a/media/libmedia/xsd/vts/Android.mk b/media/libmedia/xsd/vts/Android.mk
deleted file mode 100644
index 52c3779..0000000
--- a/media/libmedia/xsd/vts/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := VtsValidateMediaProfiles
-include test/vts/tools/build/Android.host_config.mk
diff --git a/media/libmedia/xsd/vts/AndroidTest.xml b/media/libmedia/xsd/vts/AndroidTest.xml
deleted file mode 100644
index e68721b..0000000
--- a/media/libmedia/xsd/vts/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Config for VTS VtsValidateMediaProfiles.">
- <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
- <option name="abort-on-push-failure" value="false"/>
- <option name="push-group" value="HostDrivenTest.push"/>
- <option name="push" value="DATA/etc/media_profiles.xsd->/data/local/tmp/media_profiles.xsd"/>
- </target_preparer>
- <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
- <option name="test-module-name" value="VtsValidateMediaProfiles"/>
- <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_mediaProfiles_validate_test/vts_mediaProfiles_validate_test" />
- <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_mediaProfiles_validate_test/vts_mediaProfiles_validate_test" />
- <option name="binary-test-type" value="gtest"/>
- <option name="test-timeout" value="30s"/>
- </test>
-</configuration>
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 6e2d22f..d677744 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -8268,17 +8268,38 @@
FALLTHROUGH_INTENDED;
}
case kWhatResume:
- case kWhatSetParameters:
{
- if (msg->what() == kWhatResume) {
- ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
- }
+ ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
mCodec->deferMessage(msg);
handled = true;
break;
}
+ case kWhatSetParameters:
+ {
+ sp<AMessage> params;
+ CHECK(msg->findMessage("params", ¶ms));
+
+ sp<ABuffer> hdr10PlusInfo;
+ if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
+ if (hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
+ (void)mCodec->setHdr10PlusInfo(hdr10PlusInfo);
+ }
+ params->removeEntryAt(params->findEntryByName("hdr10-plus-info"));
+
+ if (params->countEntries() == 0) {
+ msg->removeEntryAt(msg->findEntryByName("params"));
+ }
+ }
+
+ if (msg->countEntries() > 0) {
+ mCodec->deferMessage(msg);
+ }
+ handled = true;
+ break;
+ }
+
case kWhatForceStateTransition:
{
int32_t generation = 0;
@@ -8389,6 +8410,15 @@
return false;
}
+ case OMX_EventConfigUpdate:
+ {
+ CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
+
+ mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);
+
+ return true;
+ }
+
default:
return BaseState::onOMXEvent(event, data1, data2);
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7a6112f..c38de64 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2131,6 +2131,8 @@
}
bool sendErrorResponse = true;
+ std::string origin{"kWhatError:"};
+ origin += stateString(mState);
switch (mState) {
case INITIALIZING:
@@ -2182,14 +2184,14 @@
// be a shutdown complete notification after
// all.
- // note that we're directly going from
+ // note that we may be directly going from
// STOPPING->UNINITIALIZED, instead of the
// usual STOPPING->INITIALIZED state.
setState(UNINITIALIZED);
if (mState == RELEASING) {
mComponentName.clear();
}
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages(origin + ":dead");
sendErrorResponse = false;
}
break;
@@ -2280,7 +2282,7 @@
// released by ResourceManager.
finalErr = DEAD_OBJECT;
}
- postPendingRepliesAndDeferredMessages(finalErr);
+ postPendingRepliesAndDeferredMessages(origin, finalErr);
}
break;
}
@@ -2328,7 +2330,7 @@
MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
}
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages("kWhatComponentAllocated");
break;
}
@@ -2367,7 +2369,7 @@
mFlags |= kFlagUsesSoftwareRenderer;
}
setState(CONFIGURED);
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages("kWhatComponentConfigured");
// augment our media metrics info, now that we know more things
// such as what the codec extracted from any CSD passed in.
@@ -2436,7 +2438,7 @@
} else {
response->setInt32("err", err);
}
- postPendingRepliesAndDeferredMessages(response);
+ postPendingRepliesAndDeferredMessages("kWhatInputSurfaceCreated", response);
break;
}
@@ -2458,7 +2460,7 @@
} else {
response->setInt32("err", err);
}
- postPendingRepliesAndDeferredMessages(response);
+ postPendingRepliesAndDeferredMessages("kWhatInputSurfaceAccepted", response);
break;
}
@@ -2476,7 +2478,7 @@
if (msg->findInt32("err", &err)) {
response->setInt32("err", err);
}
- postPendingRepliesAndDeferredMessages(response);
+ postPendingRepliesAndDeferredMessages("kWhatSignaledInputEOS", response);
break;
}
@@ -2495,7 +2497,7 @@
MediaResource::GraphicMemoryResource(getGraphicBufferSize()));
}
setState(STARTED);
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages("kWhatStartCompleted");
break;
}
@@ -2725,7 +2727,13 @@
break;
}
setState(INITIALIZED);
- postPendingRepliesAndDeferredMessages();
+ if (mReplyID) {
+ postPendingRepliesAndDeferredMessages("kWhatStopCompleted");
+ } else {
+ ALOGW("kWhatStopCompleted: presumably an error occurred earlier, "
+ "but the operation completed anyway. (last reply origin=%s)",
+ mLastReplyOrigin.c_str());
+ }
break;
}
@@ -2749,7 +2757,7 @@
mReleaseSurface.reset();
if (mReplyID != nullptr) {
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages("kWhatReleaseCompleted");
}
if (mAsyncReleaseCompleteNotification != nullptr) {
flushMediametrics();
@@ -2774,7 +2782,7 @@
mCodec->signalResume();
}
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages("kWhatFlushCompleted");
break;
}
@@ -3163,7 +3171,8 @@
if (mState == FLUSHING || mState == STOPPING
|| mState == CONFIGURING || mState == STARTING) {
// mReply is always set if in these states.
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages(
+ std::string("kWhatRelease:") + stateString(mState));
}
if (mFlags & kFlagSawMediaServerDie) {
@@ -3212,7 +3221,7 @@
// State transition replies are handled above, so this reply
// would not be related to state transition. As we are
// shutting down the component, just fail the operation.
- postPendingRepliesAndDeferredMessages(UNKNOWN_ERROR);
+ postPendingRepliesAndDeferredMessages("kWhatRelease:reply", UNKNOWN_ERROR);
}
mReplyID = replyID;
setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
@@ -3228,7 +3237,7 @@
if (asyncNotify != nullptr) {
mResourceManagerProxy->markClientForPendingRemoval();
- postPendingRepliesAndDeferredMessages();
+ postPendingRepliesAndDeferredMessages("kWhatRelease:async");
asyncNotifyPost.clear();
mAsyncReleaseCompleteNotification = asyncNotify;
}
@@ -4303,16 +4312,23 @@
return OK;
}
-void MediaCodec::postPendingRepliesAndDeferredMessages(status_t err /* = OK */) {
+void MediaCodec::postPendingRepliesAndDeferredMessages(
+ std::string origin, status_t err /* = OK */) {
sp<AMessage> response{new AMessage};
if (err != OK) {
response->setInt32("err", err);
}
- postPendingRepliesAndDeferredMessages(response);
+ postPendingRepliesAndDeferredMessages(origin, response);
}
-void MediaCodec::postPendingRepliesAndDeferredMessages(const sp<AMessage> &response) {
- CHECK(mReplyID);
+void MediaCodec::postPendingRepliesAndDeferredMessages(
+ std::string origin, const sp<AMessage> &response) {
+ LOG_ALWAYS_FATAL_IF(
+ !mReplyID,
+ "postPendingRepliesAndDeferredMessages: mReplyID == null, from %s following %s",
+ origin.c_str(),
+ mLastReplyOrigin.c_str());
+ mLastReplyOrigin = origin;
response->postReply(mReplyID);
mReplyID.clear();
ALOGV_IF(!mDeferredMessages.empty(),
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.bp b/media/libstagefright/codecs/amrnb/enc/Android.bp
index 73a1d4b..ff9a720 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/Android.bp
@@ -81,6 +81,13 @@
//},
shared_libs: ["libstagefright_amrnb_common"],
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
//###############################################################################
diff --git a/media/libstagefright/codecs/amrwb/src/wb_syn_filt.cpp b/media/libstagefright/codecs/amrwb/src/wb_syn_filt.cpp
index e1af6d4..d960322 100644
--- a/media/libstagefright/codecs/amrwb/src/wb_syn_filt.cpp
+++ b/media/libstagefright/codecs/amrwb/src/wb_syn_filt.cpp
@@ -273,9 +273,10 @@
L_tmp1 >>= 11; /* -4 : sig_lo[i] << 4 */
- L_tmp1 += (int32)exc[(i<<1)] << a0;
+ int64 sig_tmp;
+ sig_tmp = (int64)L_tmp1 + (int32)(exc[(i<<1)] << a0);
+ L_tmp1 = (int32)(sig_tmp - (L_tmp2 << 1));
- L_tmp1 -= (L_tmp2 << 1);
/* sig_hi = bit16 to bit31 of synthesis */
L_tmp1 = shl_int32(L_tmp1, 3); /* ai in Q12 */
@@ -290,9 +291,8 @@
L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)], a[1], L_tmp3);
L_tmp3 = -L_tmp3 >> 11;
- L_tmp3 += (int32)exc[(i<<1)+1] << a0;
-
- L_tmp3 -= (L_tmp4 << 1);
+ sig_tmp = (int64)L_tmp3 + (int32)(exc[(i<<1)+1] << a0);
+ L_tmp3 = (int32)(sig_tmp - (L_tmp4 << 1));
/* sig_hi = bit16 to bit31 of synthesis */
L_tmp3 = shl_int32(L_tmp3, 3); /* ai in Q12 */
sig_hi[(i<<1)+1] = (int16)(L_tmp3 >> 16);
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 64f302c..70c672d 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -138,6 +138,12 @@
cfi: true,
},
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
//###############################################################################
diff --git a/media/libstagefright/codecs/amrwbenc/src/preemph.c b/media/libstagefright/codecs/amrwbenc/src/preemph.c
index 70c8650..a43841a 100644
--- a/media/libstagefright/codecs/amrwbenc/src/preemph.c
+++ b/media/libstagefright/codecs/amrwbenc/src/preemph.c
@@ -24,6 +24,7 @@
#include "typedef.h"
#include "basic_op.h"
+#include <stdint.h>
void Preemph(
Word16 x[], /* (i/o) : input signal overwritten by the output */
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
index fe0bdda..657b6fe 100644
--- a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
+++ b/media/libstagefright/codecs/amrwbenc/src/q_pulse.c
@@ -27,6 +27,7 @@
#include "q_pulse.h"
#define NB_POS 16 /* pos in track, mask for sign bit */
+#define UNUSED_VAR __attribute__((unused))
Word32 quant_1p_N1( /* (o) return N+1 bits */
Word16 pos, /* (i) position of the pulse */
@@ -188,7 +189,7 @@
Word16 pos[], /* (i) position of the pulse 1..4 */
Word16 N) /* (i) number of bits for position */
{
- Word16 nb_pos, mask __unused, n_1, tmp;
+ Word16 nb_pos, mask UNUSED_VAR, n_1, tmp;
Word16 posA[4], posB[4];
Word32 i, j, k, index;
diff --git a/media/libstagefright/codecs/common/Android.bp b/media/libstagefright/codecs/common/Android.bp
index 260a60a..2290722 100644
--- a/media/libstagefright/codecs/common/Android.bp
+++ b/media/libstagefright/codecs/common/Android.bp
@@ -14,4 +14,11 @@
export_include_dirs: ["include"],
cflags: ["-Werror"],
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml b/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
index 233f9bb..29952eb 100644
--- a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
+++ b/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
@@ -19,7 +19,7 @@
<option name="cleanup" value="true" />
<option name="push" value="Mp3DecoderTest->/data/local/tmp/Mp3DecoderTest" />
<option name="push-file"
- key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest-1.1.zip?unzip=true"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/mp3dec/test/Mp3DecoderTest-1.2.zip?unzip=true"
value="/data/local/tmp/Mp3DecoderTestRes/" />
</target_preparer>
diff --git a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp b/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
index 0784c0c..91326a8 100644
--- a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
+++ b/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
@@ -186,6 +186,7 @@
::testing::Values(("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3"),
("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3"),
("bug_136053885.mp3"),
+ ("bbb_2ch_44kHz_lame_crc.mp3"),
("bbb_mp3_stereo_192kbps_48000hz.mp3")));
int main(int argc, char **argv) {
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index e97f6eb..5509512 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -813,10 +813,6 @@
baseSize = U32_AT(&mParent.mData[mOffset + 4]);
}
- if (baseSize == 0) {
- return;
- }
-
// Prevent integer overflow when adding
if (SIZE_MAX - 10 <= baseSize) {
return;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index c9109f5..a4836cd 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -366,6 +366,7 @@
AString mOwnerName;
sp<MediaCodecInfo> mCodecInfo;
sp<AReplyToken> mReplyID;
+ std::string mLastReplyOrigin;
std::vector<sp<AMessage>> mDeferredMessages;
uint32_t mFlags;
status_t mStickyError;
@@ -489,8 +490,8 @@
bool hasPendingBuffer(int portIndex);
bool hasPendingBuffer();
- void postPendingRepliesAndDeferredMessages(status_t err = OK);
- void postPendingRepliesAndDeferredMessages(const sp<AMessage> &response);
+ void postPendingRepliesAndDeferredMessages(std::string origin, status_t err = OK);
+ void postPendingRepliesAndDeferredMessages(std::string origin, const sp<AMessage> &response);
/* called to get the last codec error when the sticky flag is set.
* if no such codec error is found, returns UNKNOWN_ERROR.
diff --git a/media/libstagefright/tests/mediacodec/Android.bp b/media/libstagefright/tests/mediacodec/Android.bp
index 006864e..0bd0639 100644
--- a/media/libstagefright/tests/mediacodec/Android.bp
+++ b/media/libstagefright/tests/mediacodec/Android.bp
@@ -23,7 +23,12 @@
"MediaTestHelper.cpp",
],
+ header_libs: [
+ "libmediadrm_headers",
+ ],
+
shared_libs: [
+ "libgui",
"libmedia",
"libmedia_codeclist",
"libmediametrics",
diff --git a/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp b/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp
index baa86c1..d00a50f 100644
--- a/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp
+++ b/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp
@@ -20,6 +20,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <gui/Surface.h>
+#include <mediadrm/ICrypto.h>
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecListWriter.h>
@@ -152,6 +154,37 @@
using namespace android;
using ::testing::_;
+static sp<MediaCodec> SetupMediaCodec(
+ const AString &owner,
+ const AString &codecName,
+ const AString &mediaType,
+ const sp<ALooper> &looper,
+ std::function<sp<CodecBase>(const AString &name, const char *owner)> getCodecBase) {
+ std::shared_ptr<MediaCodecListWriter> listWriter =
+ MediaTestHelper::CreateCodecListWriter();
+ std::unique_ptr<MediaCodecInfoWriter> infoWriter = listWriter->addMediaCodecInfo();
+ infoWriter->setName(codecName.c_str());
+ infoWriter->setOwner(owner.c_str());
+ infoWriter->addMediaType(mediaType.c_str());
+ std::vector<sp<MediaCodecInfo>> codecInfos;
+ MediaTestHelper::WriteCodecInfos(listWriter, &codecInfos);
+ std::function<status_t(const AString &, sp<MediaCodecInfo> *)> getCodecInfo =
+ [codecInfos](const AString &name, sp<MediaCodecInfo> *info) -> status_t {
+ auto it = std::find_if(
+ codecInfos.begin(), codecInfos.end(),
+ [&name](const sp<MediaCodecInfo> &info) {
+ return name.equalsIgnoreCase(info->getCodecName());
+ });
+
+ *info = (it == codecInfos.end()) ? nullptr : *it;
+ return (*info) ? OK : NAME_NOT_FOUND;
+ };
+
+ looper->start();
+ return MediaTestHelper::CreateCodec(
+ codecName, looper, getCodecBase, getCodecInfo);
+}
+
TEST(MediaCodecTest, ReclaimReleaseRace) {
// Test scenario:
//
@@ -202,30 +235,9 @@
return mockCodec;
};
- std::shared_ptr<MediaCodecListWriter> listWriter =
- MediaTestHelper::CreateCodecListWriter();
- std::unique_ptr<MediaCodecInfoWriter> infoWriter = listWriter->addMediaCodecInfo();
- infoWriter->setName(kCodecName.c_str());
- infoWriter->setOwner(kCodecOwner.c_str());
- infoWriter->addMediaType(kMediaType.c_str());
- std::vector<sp<MediaCodecInfo>> codecInfos;
- MediaTestHelper::WriteCodecInfos(listWriter, &codecInfos);
- std::function<status_t(const AString &, sp<MediaCodecInfo> *)> getCodecInfo =
- [codecInfos](const AString &name, sp<MediaCodecInfo> *info) -> status_t {
- auto it = std::find_if(
- codecInfos.begin(), codecInfos.end(),
- [&name](const sp<MediaCodecInfo> &info) {
- return name.equalsIgnoreCase(info->getCodecName());
- });
-
- *info = (it == codecInfos.end()) ? nullptr : *it;
- return (*info) ? OK : NAME_NOT_FOUND;
- };
-
sp<ALooper> looper{new ALooper};
- looper->start();
- sp<MediaCodec> codec = MediaTestHelper::CreateCodec(
- kCodecName, looper, getCodecBase, getCodecInfo);
+ sp<MediaCodec> codec = SetupMediaCodec(
+ kCodecOwner, kCodecName, kMediaType, looper, getCodecBase);
ASSERT_NE(nullptr, codec) << "Codec must not be null";
ASSERT_NE(nullptr, mockCodec) << "MockCodec must not be null";
std::promise<void> reclaimCompleted;
@@ -266,3 +278,73 @@
<< "release timed out";
looper->stop();
}
+
+TEST(MediaCodecTest, ErrorWhileStopping) {
+ // Test scenario:
+ //
+ // 1) Client thread calls stop(); MediaCodec looper thread calls
+ // initiateShutdown(); shutdown is being handled at the component thread.
+ // 2) Error occurred, but the shutdown operation is still being done.
+ // 3) MediaCodec looper thread handles the error.
+ // 4) Component thread completes shutdown and posts onStopCompleted()
+
+ static const AString kCodecName{"test.codec"};
+ static const AString kCodecOwner{"nobody"};
+ static const AString kMediaType{"video/x-test"};
+
+ std::promise<void> errorOccurred;
+ sp<MockCodec> mockCodec;
+ std::function<sp<CodecBase>(const AString &name, const char *owner)> getCodecBase =
+ [&mockCodec, &errorOccurred](const AString &, const char *) {
+ mockCodec = new MockCodec([](const std::shared_ptr<MockBufferChannel> &) {
+ // No mock setup, as we don't expect any buffer operations
+ // in this scenario.
+ });
+ ON_CALL(*mockCodec, initiateAllocateComponent(_))
+ .WillByDefault([mockCodec](const sp<AMessage> &) {
+ mockCodec->callback()->onComponentAllocated(kCodecName.c_str());
+ });
+ ON_CALL(*mockCodec, initiateConfigureComponent(_))
+ .WillByDefault([mockCodec](const sp<AMessage> &msg) {
+ mockCodec->callback()->onComponentConfigured(
+ msg->dup(), msg->dup());
+ });
+ ON_CALL(*mockCodec, initiateStart())
+ .WillByDefault([mockCodec]() {
+ mockCodec->callback()->onStartCompleted();
+ });
+ ON_CALL(*mockCodec, initiateShutdown(true))
+ .WillByDefault([mockCodec, &errorOccurred](bool) {
+ mockCodec->callback()->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+ // Mark that 1) and 2) are complete.
+ errorOccurred.set_value();
+ });
+ ON_CALL(*mockCodec, initiateShutdown(false))
+ .WillByDefault([mockCodec](bool) {
+ mockCodec->callback()->onReleaseCompleted();
+ });
+ return mockCodec;
+ };
+
+ sp<ALooper> looper{new ALooper};
+ sp<MediaCodec> codec = SetupMediaCodec(
+ kCodecOwner, kCodecName, kMediaType, looper, getCodecBase);
+ ASSERT_NE(nullptr, codec) << "Codec must not be null";
+ ASSERT_NE(nullptr, mockCodec) << "MockCodec must not be null";
+
+ std::thread([mockCodec, &errorOccurred]{
+ // Simulate component thread that handles stop()
+ errorOccurred.get_future().wait();
+ // Error occurred but shutdown request still got processed.
+ mockCodec->callback()->onStopCompleted();
+ }).detach();
+
+ codec->configure(new AMessage, nullptr, nullptr, 0);
+ codec->start();
+ codec->stop();
+ // Sleep here to give time for the MediaCodec looper thread
+ // to process the messages.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ codec->release();
+ looper->stop();
+}
diff --git a/media/libstagefright/xmlparser/vts/Android.mk b/media/libstagefright/xmlparser/vts/Android.mk
deleted file mode 100644
index d5290ba..0000000
--- a/media/libstagefright/xmlparser/vts/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := VtsValidateMediaCodecs
-include test/vts/tools/build/Android.host_config.mk
diff --git a/media/libstagefright/xmlparser/vts/AndroidTest.xml b/media/libstagefright/xmlparser/vts/AndroidTest.xml
deleted file mode 100644
index 97ee107..0000000
--- a/media/libstagefright/xmlparser/vts/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Config for VTS VtsValidateMediaCodecs.">
- <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
- <option name="abort-on-push-failure" value="false"/>
- <option name="push-group" value="HostDrivenTest.push"/>
- <option name="push" value="DATA/etc/media_codecs.xsd->/data/local/tmp/media_codecs.xsd"/>
- </target_preparer>
- <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
- <option name="test-module-name" value="VtsValidateMediaCodecs"/>
- <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_mediaCodecs_validate_test/vts_mediaCodecs_validate_test" />
- <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_mediaCodecs_validate_test/vts_mediaCodecs_validate_test" />
- <option name="binary-test-type" value="gtest"/>
- <option name="test-timeout" value="30s"/>
- </test>
-</configuration>
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 316732b..58e2d2a 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -18,7 +18,6 @@
#define LOG_TAG "mediaserver"
//#define LOG_NDEBUG 0
-#include <aicu/AIcu.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
@@ -39,7 +38,6 @@
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
- AIcu_initializeIcuOrDie();
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
diff --git a/services/OWNERS b/services/OWNERS
index 66a4bcb..f0b5e2f 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -5,3 +5,5 @@
gkasten@google.com
hunga@google.com
marcone@google.com
+nchalko@google.com
+quxiangfang@google.com
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index dd1499c..0f9bcc1 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -248,7 +248,9 @@
return String8("");
}
- std::string toString() const;
+ // Return a string to describe the DeviceVector. The sensitive information will only be
+ // added to the string if `includeSensitiveInfo` is true.
+ std::string toString(bool includeSensitiveInfo = false) const;
void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index b963121..4922ebe 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -516,7 +516,7 @@
dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
dst->appendFormat(" Format: %d\n", mFormat);
dst->appendFormat(" Channels: %08x\n", mChannelMask);
- dst->appendFormat(" Devices %s\n", mDevice->toString().c_str());
+ dst->appendFormat(" Devices %s\n", mDevice->toString(true /*includeSensitiveInfo*/).c_str());
mEnabledEffects.dump(dst, 1 /*spaces*/, false /*verbose*/);
dst->append(" AudioRecord Clients:\n");
ClientMapHandler<RecordClientDescriptor>::dump(dst);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index d6d472b..a2e2eec 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -245,7 +245,7 @@
dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
dst->appendFormat(" Format: %08x\n", mFormat);
dst->appendFormat(" Channels: %08x\n", mChannelMask);
- dst->appendFormat(" Devices: %s\n", devices().toString().c_str());
+ dst->appendFormat(" Devices: %s\n", devices().toString(true /*includeSensitiveInfo*/).c_str());
dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
for (const auto &iter : mRoutingActivities) {
dst->appendFormat(" Product Strategy id: %d", iter.first);
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index a29e60e..68a32a2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -408,7 +408,7 @@
}
}
-std::string DeviceVector::toString() const
+std::string DeviceVector::toString(bool includeSensitiveInfo) const
{
if (isEmpty()) {
return {"AUDIO_DEVICE_NONE"};
@@ -418,7 +418,7 @@
if (device != *begin()) {
result += ";";
}
- result += device->toString();
+ result += device->toString(includeSensitiveInfo);
}
return result + "}";
}
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
index 981582e..1821140 100644
--- a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -136,7 +136,7 @@
{"rerouting",
{
{"", AUDIO_STREAM_REROUTING, "AUDIO_STREAM_REROUTING",
- {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VIRTUAL_SOURCE, AUDIO_SOURCE_DEFAULT, 0, ""}}
}
},
},
diff --git a/services/mediametrics/AudioPowerUsage.cpp b/services/mediametrics/AudioPowerUsage.cpp
index cca6b41..33dfa8fa 100644
--- a/services/mediametrics/AudioPowerUsage.cpp
+++ b/services/mediametrics/AudioPowerUsage.cpp
@@ -200,6 +200,34 @@
return true;
}
+bool AudioPowerUsage::saveAsItems_l(
+ int32_t device, int64_t duration_ns, int32_t type, double average_vol)
+{
+ ALOGV("%s: (%#x, %d, %lld, %f)", __func__, device, type,
+ (long long)duration_ns, average_vol );
+ if (duration_ns == 0) {
+ return true; // skip duration 0 usage
+ }
+ if (device == 0) {
+ return true; //ignore unknown device
+ }
+
+ bool ret = false;
+ const int32_t input_bit = device & INPUT_DEVICE_BIT;
+ int32_t device_bits = device ^ input_bit;
+
+ while (device_bits != 0) {
+ int32_t tmp_device = device_bits & -device_bits; // get lowest bit
+ device_bits ^= tmp_device; // clear lowest bit
+ tmp_device |= input_bit; // restore input bit
+ ret = saveAsItem_l(tmp_device, duration_ns, type, average_vol);
+
+ ALOGV("%s: device %#x recorded, remaining device_bits = %#x", __func__,
+ tmp_device, device_bits);
+ }
+ return ret;
+}
+
void AudioPowerUsage::checkTrackRecord(
const std::shared_ptr<const mediametrics::Item>& item, bool isTrack)
{
@@ -245,7 +273,7 @@
ALOGV("device = %s => %d", device_strings.c_str(), device);
}
std::lock_guard l(mLock);
- saveAsItem_l(device, deviceTimeNs, type, deviceVolume);
+ saveAsItems_l(device, deviceTimeNs, type, deviceVolume);
}
void AudioPowerUsage::checkMode(const std::shared_ptr<const mediametrics::Item>& item)
@@ -262,7 +290,7 @@
if (durationNs > 0) {
mDeviceVolume = (mDeviceVolume * double(mVolumeTimeNs - mDeviceTimeNs) +
mVoiceVolume * double(endCallNs - mVolumeTimeNs)) / durationNs;
- saveAsItem_l(mPrimaryDevice, durationNs, VOICE_CALL_TYPE, mDeviceVolume);
+ saveAsItems_l(mPrimaryDevice, durationNs, VOICE_CALL_TYPE, mDeviceVolume);
}
} else if (mode == "AUDIO_MODE_IN_CALL") { // entering call mode
mStartCallNs = item->getTimestamp(); // advisory only
@@ -321,7 +349,7 @@
if (durationNs > 0) {
mDeviceVolume = (mDeviceVolume * double(mVolumeTimeNs - mDeviceTimeNs) +
mVoiceVolume * double(endDeviceNs - mVolumeTimeNs)) / durationNs;
- saveAsItem_l(mPrimaryDevice, durationNs, VOICE_CALL_TYPE, mDeviceVolume);
+ saveAsItems_l(mPrimaryDevice, durationNs, VOICE_CALL_TYPE, mDeviceVolume);
}
// reset statistics
mDeviceVolume = 0;
diff --git a/services/mediametrics/AudioPowerUsage.h b/services/mediametrics/AudioPowerUsage.h
index 446ff4f..b705a6a 100644
--- a/services/mediametrics/AudioPowerUsage.h
+++ b/services/mediametrics/AudioPowerUsage.h
@@ -85,6 +85,8 @@
REQUIRES(mLock);
static void sendItem(const std::shared_ptr<const mediametrics::Item>& item);
void collect();
+ bool saveAsItems_l(int32_t device, int64_t duration, int32_t type, double average_vol)
+ REQUIRES(mLock);
AudioAnalytics * const mAudioAnalytics;
const bool mDisabled;