MediaCodec: handle consumer side buffer attach to Surface
Currently MediaCodec handles buffer being released from Surface. Handle
buffer being attached to Surface also.
Bug: 353202582
Flag: EXEMPT bugfix
Merged-In: I5300086f7ae36d3b5e358e62e596001ecd32f572
Change-Id: I5300086f7ae36d3b5e358e62e596001ecd32f572
diff --git a/media/codec2/hal/client/client.cpp b/media/codec2/hal/client/client.cpp
index 1d2794e..a137dbb 100644
--- a/media/codec2/hal/client/client.cpp
+++ b/media/codec2/hal/client/client.cpp
@@ -2556,6 +2556,19 @@
mOutputBufferQueue->onBufferReleased(generation);
}
+void Codec2Client::Component::onBufferAttachedToOutputSurface(
+ uint32_t generation) {
+ if (mAidlBase) {
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (gba) {
+ gba->onBufferAttached(generation);
+ }
+ return;
+ }
+ mOutputBufferQueue->onBufferAttached(generation);
+}
+
void Codec2Client::Component::holdIgbaBlocks(
const std::list<std::unique_ptr<C2Work>>& workList) {
if (!mAidlBase) {
diff --git a/media/codec2/hal/client/include/codec2/hidl/client.h b/media/codec2/hal/client/include/codec2/hidl/client.h
index 5c75a47..413e92e 100644
--- a/media/codec2/hal/client/include/codec2/hidl/client.h
+++ b/media/codec2/hal/client/include/codec2/hidl/client.h
@@ -481,6 +481,10 @@
void onBufferReleasedFromOutputSurface(
uint32_t generation);
+ // Notify a buffer is attached to output surface.
+ void onBufferAttachedToOutputSurface(
+ uint32_t generation);
+
// When the client received \p workList and the blocks inside
// \p workList are IGBA based graphic blocks, specify the owner
// as the current IGBA for the future operations.
diff --git a/media/codec2/hal/client/include/codec2/hidl/output.h b/media/codec2/hal/client/include/codec2/hidl/output.h
index fda34a8..ddb9855 100644
--- a/media/codec2/hal/client/include/codec2/hidl/output.h
+++ b/media/codec2/hal/client/include/codec2/hidl/output.h
@@ -69,6 +69,9 @@
// update the number of dequeueable/allocatable buffers.
void onBufferReleased(uint32_t generation);
+ // Nofify a buffer is attached to the output surface.
+ void onBufferAttached(uint32_t generation);
+
// Retrieve frame event history from the output surface.
void pollForRenderedFrames(FrameEventHistoryDelta* delta);
diff --git a/media/codec2/hal/client/output.cpp b/media/codec2/hal/client/output.cpp
index 36322f5..54d78a0 100644
--- a/media/codec2/hal/client/output.cpp
+++ b/media/codec2/hal/client/output.cpp
@@ -542,6 +542,11 @@
}
}
+void OutputBufferQueue::onBufferAttached(uint32_t generation) {
+ // TODO
+ (void) generation;
+}
+
void OutputBufferQueue::pollForRenderedFrames(FrameEventHistoryDelta* delta) {
if (mIgbp) {
mIgbp->getFrameTimestamps(delta);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index f0a4180..1348ef0 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1469,6 +1469,17 @@
}
}
+void CCodecBufferChannel::onBufferAttachedToOutputSurface(uint32_t generation) {
+ // Note: Since this is called asynchronously from IProducerListener not
+ // knowing the internal state of CCodec/CCodecBufferChannel,
+ // prevent mComponent from being destroyed by holding the shared reference
+ // during this interface being executed.
+ std::shared_ptr<Codec2Client::Component> comp = mComponent;
+ if (comp) {
+ comp->onBufferAttachedToOutputSurface(generation);
+ }
+}
+
status_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
ALOGV("[%s] discardBuffer: %p", mName, buffer.get());
bool released = false;
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 94a5998..e62742b 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -102,6 +102,7 @@
const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) override;
void pollForRenderedBuffers() override;
void onBufferReleasedFromOutputSurface(uint32_t generation) override;
+ void onBufferAttachedToOutputSurface(uint32_t generation) override;
status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) override;
void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 0401e82..04364a8 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -852,6 +852,13 @@
}
}
+ void notifyBufferAttached() {
+ auto p = mBufferChannel.lock();
+ if (p) {
+ p->onBufferAttachedToOutputSurface(mGeneration);
+ }
+ }
+
public:
explicit OnBufferReleasedListener(
uint32_t generation,
@@ -869,6 +876,14 @@
}
bool needsReleaseNotify() override { return true; }
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ void onBufferAttached() override {
+ notifyBufferAttached();
+ }
+
+ bool needsAttachNotify() override { return true; }
+#endif
};
class BufferCallback : public CodecBase::BufferCallback {
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index bffb294..c6087b0 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -517,6 +517,15 @@
};
/**
+ * Notify a buffer is attached to output surface.
+ *
+ * @param generation MediaCodec's surface specifier
+ */
+ virtual void onBufferAttachedToOutputSurface(uint32_t /*generation*/) {
+ // default: no-op
+ };
+
+ /**
* Discard a buffer to the underlying CodecBase object.
*
* TODO: remove once this operation can be handled by just clearing the