From add5343beb09f23bc0265cd717794240ad63304a Mon Sep 17 00:00:00 2001 From: Tao Wu <lepton@google.com> Date: Mon, 27 Feb 2023 19:18:43 -0800 Subject: [PATCH] V4L2EncodeComponent: force sync gpu buffer Android encoder framework reuses the same gpu buffers as inputs and doesn't call lock/unlock explicitly between writes. If there is format conversion, this is fine since we will read back what we've written first and then put it in another buffer. Whenever there is no format conversion, this causes sync issue on ARCVM since host side buffers never get updated. Fix this by explicitly calling lock/unlock before sending buffer to encoder. Bug: 268317650 Test: atest com.google.android.media.gts.RtcVideoCodecTest#testDynamicBitrateChangeVp8 Change-Id: Ia1750aa37c2d879ddff0301814e489974f218f5c --- components/V4L2EncodeComponent.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/components/V4L2EncodeComponent.cpp b/components/V4L2EncodeComponent.cpp index f9d735d..da61217 100644 --- a/components/V4L2EncodeComponent.cpp +++ b/components/V4L2EncodeComponent.cpp @@ -517,6 +517,27 @@ void V4L2EncodeComponent::queueTask(std::unique_ptr<C2Work> work) { reportError(status); return; } + } else { + // Android encoder framework reuses the same gpu buffers as + // inputs and doesn't call lock/unlock explicitly between writes. + // If there is format conversion, this is fine since we will + // read back what we've written first and then put it in another + // buffer. Whenever there is no format conversion, this causes + // sync issue on ARCVM since host side buffers never get updated. + // Fix this by explicitly calling lock/unlock before sending buffer + // to encoder. + const C2Handle* handle = inputBlock.handle(); + uint32_t width, height, format, stride, generation, igbpSlot; + uint64_t usage, igbpId; + _UnwrapNativeCodec2GrallocMetadata(handle, &width, &height, &format, &usage, &stride, + &generation, &igbpId, &igbpSlot); + native_handle_t* gralloc_handle = UnwrapNativeCodec2GrallocHandle(handle); + sp<GraphicBuffer> buffer = + new GraphicBuffer(gralloc_handle, GraphicBuffer::CLONE_HANDLE, width, height, + format, 1, usage, stride); + void* pixels; + buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &pixels); + buffer->unlock(); } if (!encode(inputBlock, index, timestamp)) { return; -- GitLab