Log pixel format metric for decoders and non-surface mode encoders.
Test: manual
Bug: 270518245
Merged-In: I0d3fabcca632d974ecd7d86305b3dfef4eee895f
Change-Id: I0d3fabcca632d974ecd7d86305b3dfef4eee895f
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 1153fb6..abfac8b 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -45,6 +45,7 @@
#include <media/stagefright/CCodec.h>
#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaCodecMetricsConstants.h>
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/RenderedFrameInfo.h>
#include <utils/NativeHandle.h>
@@ -1536,6 +1537,9 @@
config->queryConfiguration(comp);
+ mMetrics = new AMessage;
+ mChannel->resetBuffersPixelFormat((config->mDomain & Config::IS_ENCODER) ? true : false);
+
mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat);
}
@@ -2499,6 +2503,19 @@
}
mChannel->onWorkDone(
std::move(work), outputFormat, initData ? initData.get() : nullptr);
+ // log metrics to MediaCodec
+ if (mMetrics->countEntries() == 0) {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ uint32_t pf = PIXEL_FORMAT_UNKNOWN;
+ if (!config->mInputSurface) {
+ pf = mChannel->getBuffersPixelFormat(config->mDomain & Config::IS_ENCODER);
+ }
+ if (pf != PIXEL_FORMAT_UNKNOWN) {
+ mMetrics->setInt64(kCodecPixelFormat, pf);
+ mCallback->onMetricsUpdated(mMetrics);
+ }
+ }
break;
}
case kWhatWatch: {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index fea9cb9..eb6be63 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -2373,6 +2373,46 @@
mDescrambler = descrambler;
}
+uint32_t CCodecBufferChannel::getBuffersPixelFormat(bool isEncoder) {
+ if (isEncoder) {
+ return getInputBuffersPixelFormat();
+ } else {
+ return getOutputBuffersPixelFormat();
+ }
+}
+
+uint32_t CCodecBufferChannel::getInputBuffersPixelFormat() {
+ Mutexed<Input>::Locked input(mInput);
+ if (input->buffers == nullptr) {
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+ return input->buffers->getPixelFormatIfApplicable();
+}
+
+uint32_t CCodecBufferChannel::getOutputBuffersPixelFormat() {
+ Mutexed<Output>::Locked output(mOutput);
+ if (output->buffers == nullptr) {
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+ return output->buffers->getPixelFormatIfApplicable();
+}
+
+void CCodecBufferChannel::resetBuffersPixelFormat(bool isEncoder) {
+ if (isEncoder) {
+ Mutexed<Input>::Locked input(mInput);
+ if (input->buffers == nullptr) {
+ return;
+ }
+ input->buffers->resetPixelFormatIfApplicable();
+ } else {
+ Mutexed<Output>::Locked output(mOutput);
+ if (output->buffers == nullptr) {
+ return;
+ }
+ output->buffers->resetPixelFormatIfApplicable();
+ }
+}
+
status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
// C2_OK is always translated to OK.
if (c2s == C2_OK) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index f60b6fa..9f6b90c 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -207,7 +207,20 @@
void setMetaMode(MetaMode mode);
+ /**
+ * get pixel format from output buffers.
+ *
+ * @return 0 if no valid pixel format found.
+ */
+ uint32_t getBuffersPixelFormat(bool isEncoder);
+
+ void resetBuffersPixelFormat(bool isEncoder);
+
private:
+ uint32_t getInputBuffersPixelFormat();
+
+ uint32_t getOutputBuffersPixelFormat();
+
class QueueGuard;
/**
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 0f4a8d8..670923b 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "CCodecBuffers"
#include <utils/Log.h>
+#include <C2AllocatorGralloc.h>
#include <C2PlatformSupport.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -121,6 +122,10 @@
buffer->setFormat(mFormatWithImageData);
}
+uint32_t CCodecBuffers::getPixelFormatIfApplicable() { return PIXEL_FORMAT_UNKNOWN; }
+
+bool CCodecBuffers::resetPixelFormatIfApplicable() { return false; }
+
// InputBuffers
sp<Codec2Buffer> InputBuffers::cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer) {
@@ -1043,7 +1048,8 @@
const char *componentName, const char *name)
: InputBuffers(componentName, name),
mImpl(mName),
- mLocalBufferPool(LocalBufferPool::Create()) { }
+ mLocalBufferPool(LocalBufferPool::Create()),
+ mPixelFormat(PIXEL_FORMAT_UNKNOWN) { }
bool GraphicInputBuffers::requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) {
sp<Codec2Buffer> newBuffer = createNewBuffer();
@@ -1109,8 +1115,16 @@
sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() {
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+ mPixelFormat = extractPixelFormat(mFormat);
return AllocateInputGraphicBuffer(
- mPool, mFormat, extractPixelFormat(mFormat), usage, mLocalBufferPool);
+ mPool, mFormat, mPixelFormat, usage, mLocalBufferPool);
+}
+
+uint32_t GraphicInputBuffers::getPixelFormatIfApplicable() { return mPixelFormat; }
+
+bool GraphicInputBuffers::resetPixelFormatIfApplicable() {
+ mPixelFormat = PIXEL_FORMAT_UNKNOWN;
+ return true;
}
// OutputBuffersArray
@@ -1269,6 +1283,8 @@
*index = mImpl.assignSlot(newBuffer);
handleImageData(newBuffer);
*clientBuffer = newBuffer;
+
+ extractPixelFormatFromC2Buffer(buffer);
ALOGV("[%s] registered buffer %zu", mName, *index);
return OK;
}
@@ -1309,6 +1325,32 @@
return mImpl.numActiveSlots();
}
+bool FlexOutputBuffers::extractPixelFormatFromC2Buffer(const std::shared_ptr<C2Buffer> &buffer) {
+ if (buffer == nullptr) {
+ return false;
+ }
+ const C2BufferData &data = buffer->data();
+ // only extract the first pixel format in a metric session.
+ if (mPixelFormat != PIXEL_FORMAT_UNKNOWN || data.type() != C2BufferData::GRAPHIC
+ || data.graphicBlocks().empty()) {
+ return false;
+ }
+ const C2Handle *const handle = data.graphicBlocks().front().handle();
+ uint32_t pf = ExtractFormatFromCodec2GrallocHandle(handle);
+ if (pf == PIXEL_FORMAT_UNKNOWN) {
+ return false;
+ }
+ mPixelFormat = pf;
+ return true;
+}
+
+bool FlexOutputBuffers::resetPixelFormatIfApplicable() {
+ mPixelFormat = PIXEL_FORMAT_UNKNOWN;
+ return true;
+}
+
+uint32_t FlexOutputBuffers::getPixelFormatIfApplicable() { return mPixelFormat; }
+
// LinearOutputBuffers
void LinearOutputBuffers::flush(
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index 6335f13..cbef644 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -81,6 +81,16 @@
*/
void handleImageData(const sp<Codec2Buffer> &buffer);
+ /**
+ * Get the first pixel format of a metric session.
+ */
+ virtual uint32_t getPixelFormatIfApplicable();
+
+ /**
+ * Reset the pixel format when a new metric session started.
+ */
+ virtual bool resetPixelFormatIfApplicable();
+
protected:
std::string mComponentName; ///< name of component for debugging
std::string mChannelName; ///< name of channel for debugging
@@ -938,12 +948,17 @@
size_t numActiveSlots() const final;
+ uint32_t getPixelFormatIfApplicable() override;
+
+ bool resetPixelFormatIfApplicable() override;
+
protected:
sp<Codec2Buffer> createNewBuffer() override;
private:
FlexBuffersImpl mImpl;
std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+ uint32_t mPixelFormat;
};
class DummyInputBuffers : public InputBuffers {
@@ -1064,7 +1079,8 @@
public:
FlexOutputBuffers(const char *componentName, const char *name = "Output[]")
: OutputBuffers(componentName, name),
- mImpl(mName) { }
+ mImpl(mName),
+ mPixelFormat(0) { }
status_t registerBuffer(
const std::shared_ptr<C2Buffer> &buffer,
@@ -1107,8 +1123,20 @@
*/
virtual std::function<sp<Codec2Buffer>()> getAlloc() = 0;
+ uint32_t getPixelFormatIfApplicable() override;
+
+ bool resetPixelFormatIfApplicable() override;
private:
FlexBuffersImpl mImpl;
+
+ uint32_t mPixelFormat;
+
+ /**
+ * extract pixel format from C2Buffer when register.
+ *
+ * \param buffer The C2Buffer used to extract pixel format.
+ */
+ bool extractPixelFormatFromC2Buffer(const std::shared_ptr<C2Buffer> &buffer);
};
class LinearOutputBuffers : public FlexOutputBuffers {
diff --git a/media/codec2/sfplugin/include/media/stagefright/CCodec.h b/media/codec2/sfplugin/include/media/stagefright/CCodec.h
index 13713bc..3b23470 100644
--- a/media/codec2/sfplugin/include/media/stagefright/CCodec.h
+++ b/media/codec2/sfplugin/include/media/stagefright/CCodec.h
@@ -205,6 +205,8 @@
Mutexed<std::unique_ptr<CCodecConfig>> mConfig;
Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
+ sp<AMessage> mMetrics;
+
friend class CCodecCallbackImpl;
DISALLOW_EVIL_CONSTRUCTORS(CCodec);
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index f272499..f04674e 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -187,6 +187,14 @@
return res;
}
+ static uint32_t getPixelFormat(const C2Handle *const handle) {
+ if (handle == nullptr) {
+ return 0;
+ }
+ const ExtraData *xd = GetExtraData(handle);
+ return xd->format;
+ }
+
static bool MigrateNativeHandle(
native_handle_t *handle,
uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
@@ -333,6 +341,10 @@
generation, igbp_id, igbp_slot);
}
+uint32_t ExtractFormatFromCodec2GrallocHandle(const C2Handle *const handle) {
+ return C2HandleGralloc::getPixelFormat(handle);
+}
+
bool MigrateNativeCodec2GrallocHandle(
native_handle_t *handle,
uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
diff --git a/media/codec2/vndk/include/C2AllocatorGralloc.h b/media/codec2/vndk/include/C2AllocatorGralloc.h
index 1da3e14..4b4a45d 100644
--- a/media/codec2/vndk/include/C2AllocatorGralloc.h
+++ b/media/codec2/vndk/include/C2AllocatorGralloc.h
@@ -46,6 +46,13 @@
uint32_t generation = 0, uint64_t igbp_id = 0, uint32_t igbp_slot = 0);
/**
+ * Extract pixel format from the extra data of gralloc handle.
+ *
+ * @return 0 when no valid pixel format exists.
+ */
+uint32_t ExtractFormatFromCodec2GrallocHandle(const C2Handle *const handle);
+
+/**
* When the gralloc handle is migrated to another bufferqueue, update
* bufferqueue information.
*