aboutsummaryrefslogtreecommitdiff
path: root/components/V4L2EncodeComponent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'components/V4L2EncodeComponent.cpp')
-rw-r--r--components/V4L2EncodeComponent.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/components/V4L2EncodeComponent.cpp b/components/V4L2EncodeComponent.cpp
index f9d735d..b266a6e 100644
--- a/components/V4L2EncodeComponent.cpp
+++ b/components/V4L2EncodeComponent.cpp
@@ -517,6 +517,32 @@ 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);
+ 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;