From 0efa67cee4e4287c82920a26424b6624fb56e83f Mon Sep 17 00:00:00 2001
From: Tao Wu <lepton@google.com>
Date: Fri, 10 Mar 2023 18:29:47 -0800
Subject: [PATCH] V4L2EncodeComponent: Better error handling when syncing
 buffer

Thanks Yiwei pointed out the buggy code which doesn't do error handling
and also we should only sync CPU writable buffer.

Bug: 268317650
Test: atest com.google.android.media.gts.RtcVideoCodecTest#testDynamicBitrateChangeVp8
Change-Id: I3c1019fb0d56180ef8460625843cf8e98301ddce
---
 components/V4L2EncodeComponent.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/components/V4L2EncodeComponent.cpp b/components/V4L2EncodeComponent.cpp
index da61217..b266a6e 100644
--- a/components/V4L2EncodeComponent.cpp
+++ b/components/V4L2EncodeComponent.cpp
@@ -531,13 +531,18 @@ void V4L2EncodeComponent::queueTask(std::unique_ptr<C2Work> work) {
             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();
+            do {
+                if (!(usage & GRALLOC_USAGE_SW_WRITE_MASK)) break;
+                native_handle_t* gralloc_handle = UnwrapNativeCodec2GrallocHandle(handle);
+                if (nullptr == gralloc_handle) break;
+                sp<GraphicBuffer> buffer =
+                        new GraphicBuffer(gralloc_handle, GraphicBuffer::CLONE_HANDLE, width,
+                                          height, format, 1, usage, stride);
+                native_handle_delete(gralloc_handle);
+                void* pixels;
+                if (buffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &pixels)) break;
+                buffer->unlock();
+            } while (0);
         }
         if (!encode(inputBlock, index, timestamp)) {
             return;
-- 
GitLab