From 2ce118aee5ccd5d050d13323695fabf29d557173 Mon Sep 17 00:00:00 2001 From: zhangguorong Date: Thu, 12 May 2022 17:40:02 +0800 Subject: [PATCH] feat:HDI2.0 service implment BufferHandle to support Codec without copy buffer Signed-off-by: zhangguorong --- codec/hal/BUILD.gn | 22 + codec/hal/include/codec_types.h | 3 +- codec/hal/src/codec_callback_type_stub.c | 8 +- codec/hal/src/codec_component_type_stub.c | 30 +- codec/hal/src/codec_types.c | 260 ++++++--- .../v2.0/hdi_impl/include/codec_dyna_buffer.h | 47 ++ .../hdi_impl/include/codec_handle_buffer.h | 48 ++ .../hdi_impl/include/codec_share_buffer.h | 51 ++ .../v2.0/hdi_impl/include/component_node.h | 53 +- .../hal/v2.0/hdi_impl/include/icodec_buffer.h | 74 +++ .../v2.0/hdi_impl/src/codec_dyna_buffer.cpp | 142 +++++ .../v2.0/hdi_impl/src/codec_handle_buffer.cpp | 144 +++++ .../v2.0/hdi_impl/src/codec_share_buffer.cpp | 190 +++++++ .../hal/v2.0/hdi_impl/src/component_node.cpp | 503 ++++-------------- codec/hal/v2.0/hdi_impl/src/icodec_buffer.cpp | 119 +++++ 15 files changed, 1163 insertions(+), 531 deletions(-) create mode 100644 codec/hal/v2.0/hdi_impl/include/codec_dyna_buffer.h create mode 100644 codec/hal/v2.0/hdi_impl/include/codec_handle_buffer.h create mode 100644 codec/hal/v2.0/hdi_impl/include/codec_share_buffer.h create mode 100644 codec/hal/v2.0/hdi_impl/include/icodec_buffer.h create mode 100644 codec/hal/v2.0/hdi_impl/src/codec_dyna_buffer.cpp create mode 100644 codec/hal/v2.0/hdi_impl/src/codec_handle_buffer.cpp create mode 100644 codec/hal/v2.0/hdi_impl/src/codec_share_buffer.cpp create mode 100644 codec/hal/v2.0/hdi_impl/src/icodec_buffer.cpp diff --git a/codec/hal/BUILD.gn b/codec/hal/BUILD.gn index 7b652b636f..a6a61980d3 100644 --- a/codec/hal/BUILD.gn +++ b/codec/hal/BUILD.gn @@ -19,6 +19,7 @@ ohos_shared_library("libcodec_hdi_omx_server") { "//drivers/peripheral/codec/interfaces/include", "//drivers/peripheral/codec/hal/include", "//third_party/openmax/api/1.1.2", + "//drivers/peripheral/base", ] sources = [ "src/codec_callback_type_proxy.c", @@ -35,6 +36,7 @@ ohos_shared_library("libcodec_hdi_omx_server") { "device_driver_framework:libhdf_ipc_adapter", "device_driver_framework:libhdf_utils", "device_driver_framework:libhdi", + "graphic_chipsetsdk:buffer_handle", "hiviewdfx_hilog_native:libhilog", "utils_base:utils", ] @@ -53,6 +55,7 @@ ohos_shared_library("libcodec_hdi_omx_client") { "//drivers/peripheral/codec/interfaces/include", "//drivers/peripheral/codec/hal/include", "//third_party/openmax/api/1.1.2", + "//drivers/peripheral/base", ] sources = [ "src/codec_callback_type_stub.c", @@ -62,11 +65,14 @@ ohos_shared_library("libcodec_hdi_omx_client") { ] if (is_standard_system) { + deps = [ "//third_party/libdrm:libdrm" ] + external_deps = [ "device_driver_framework:libhdf_host", "device_driver_framework:libhdf_ipc_adapter", "device_driver_framework:libhdf_utils", "device_driver_framework:libhdi", + "graphic_chipsetsdk:buffer_handle", "hiviewdfx_hilog_native:libhilog", "utils_base:utils", ] @@ -91,9 +97,22 @@ ohos_shared_library("libcodec_hdi_omx_service_impl") { sources = [ "src/codec_adapter.cpp", "src/codec_component_type_service.c", + "v2.0/hdi_impl/src/codec_dyna_buffer.cpp", + "v2.0/hdi_impl/src/codec_handle_buffer.cpp", + "v2.0/hdi_impl/src/codec_share_buffer.cpp", "v2.0/hdi_impl/src/component_mgr.cpp", "v2.0/hdi_impl/src/component_node.cpp", "v2.0/hdi_impl/src/component_node_mgr.cpp", + "v2.0/hdi_impl/src/icodec_buffer.cpp", + ] + + cflags_cc = [ + "-Wall", + "-Wextra", + "-Werror", + "-Wno-#warnings", + "-Wno-missing-braces", + "-Wno-missing-field-initializers", ] if (is_standard_system) { @@ -102,9 +121,12 @@ ohos_shared_library("libcodec_hdi_omx_service_impl") { "device_driver_framework:libhdf_ipc_adapter", "device_driver_framework:libhdf_utils", "device_driver_framework:libhdi", + "graphic_chipsetsdk:buffer_handle", "hiviewdfx_hilog_native:libhilog", "utils_base:utils", ] + + deps = [ "//third_party/libdrm:libdrm" ] } else { external_deps = [ "hilog:libhilog" ] } diff --git a/codec/hal/include/codec_types.h b/codec/hal/include/codec_types.h index 45f6383b72..6ec4f6eec5 100644 --- a/codec/hal/include/codec_types.h +++ b/codec/hal/include/codec_types.h @@ -35,7 +35,8 @@ void OMX_TUNNELSETUPTYPEFree(struct OMX_TUNNELSETUPTYPE *dataBlock, bool freeSel bool OmxCodecBufferBlockMarshalling(struct HdfSBuf *data, const struct OmxCodecBuffer *dataBlock); bool OmxCodecBufferBlockUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer *dataBlock); - +void ReleaseOmxCodecBuffer(struct OmxCodecBuffer *codecBuffer); +void InitOmxCodecBuffer(struct OmxCodecBuffer *codecBuffer); // for config marshall bool RangeValueBlockMarshalling(struct HdfSBuf *data, const RangeValue *dataBlock); diff --git a/codec/hal/src/codec_callback_type_stub.c b/codec/hal/src/codec_callback_type_stub.c index 2dc9311f1c..d9379d4c8b 100644 --- a/codec/hal/src/codec_callback_type_stub.c +++ b/codec/hal/src/codec_callback_type_stub.c @@ -149,6 +149,7 @@ static int32_t SerStubEmptyBufferDone(struct CodecCallbackType *serviceImpl, int8_t *appData = NULL; uint32_t appDataLen = 0; struct OmxCodecBuffer buffer; + InitOmxCodecBuffer(&buffer); if (!HdfSbufReadUint32(data, &appDataLen)) { HDF_LOGE("%{public}s: read appData size failed!", __func__); @@ -173,6 +174,7 @@ static int32_t SerStubEmptyBufferDone(struct CodecCallbackType *serviceImpl, if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) { HDF_LOGE("%{public}s: read buffer failed!", __func__); FreeMem(appData, appDataLen); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } @@ -180,10 +182,12 @@ static int32_t SerStubEmptyBufferDone(struct CodecCallbackType *serviceImpl, if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call EmptyBufferDone function failed!", __func__); FreeMem(appData, appDataLen); + ReleaseOmxCodecBuffer(&buffer); return ret; } FreeMem(appData, appDataLen); + ReleaseOmxCodecBuffer(&buffer); return ret; } @@ -194,7 +198,7 @@ static int32_t SerStubFillBufferDone(struct CodecCallbackType *serviceImpl, int8_t *appData = NULL; uint32_t appDataLen = 0; struct OmxCodecBuffer buffer; - + InitOmxCodecBuffer(&buffer); if (!HdfSbufReadUint32(data, &appDataLen)) { HDF_LOGE("%{public}s: read appData size failed!", __func__); return HDF_ERR_INVALID_PARAM; @@ -225,10 +229,12 @@ static int32_t SerStubFillBufferDone(struct CodecCallbackType *serviceImpl, if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call FillBufferDone function failed!", __func__); FreeMem(appData, appDataLen); + ReleaseOmxCodecBuffer(&buffer); return ret; } FreeMem(appData, appDataLen); + ReleaseOmxCodecBuffer(&buffer); return ret; } diff --git a/codec/hal/src/codec_component_type_stub.c b/codec/hal/src/codec_component_type_stub.c index ed8ac226aa..0e088cbac3 100644 --- a/codec/hal/src/codec_component_type_stub.c +++ b/codec/hal/src/codec_component_type_stub.c @@ -499,6 +499,7 @@ static int32_t SerStubUseBuffer(struct CodecComponentTypeStub *stub, struct HdfS int32_t ret; struct OmxCodecBuffer buffer; uint32_t portIndex = 0; + InitOmxCodecBuffer(&buffer); if (!HdfSbufReadUint32(data, &portIndex)) { HDF_LOGE("%{public}s: read &portIndex failed!", __func__); @@ -507,20 +508,23 @@ static int32_t SerStubUseBuffer(struct CodecComponentTypeStub *stub, struct HdfS if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) { HDF_LOGE("%{public}s: read buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } ret = stub->service.UseBuffer(&stub->service, portIndex, &buffer); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call UseBuffer function failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return ret; } if (!OmxCodecBufferBlockMarshalling(reply, &buffer)) { HDF_LOGE("%{public}s: write buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } - + ReleaseOmxCodecBuffer(&buffer); return ret; } @@ -530,6 +534,7 @@ static int32_t SerStubAllocateBuffer(struct CodecComponentTypeStub *stub, int32_t ret; struct OmxCodecBuffer buffer; uint32_t portIndex = 0; + InitOmxCodecBuffer(&buffer); if (!HdfSbufReadUint32(data, &portIndex)) { HDF_LOGE("%{public}s: read &portIndex failed!", __func__); @@ -538,20 +543,23 @@ static int32_t SerStubAllocateBuffer(struct CodecComponentTypeStub *stub, if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) { HDF_LOGE("%{public}s: read buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } ret = stub->service.AllocateBuffer(&stub->service, portIndex, &buffer); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call AllocateBuffer function failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return ret; } if (!OmxCodecBufferBlockMarshalling(reply, &buffer)) { HDF_LOGE("%{public}s: write buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } - + ReleaseOmxCodecBuffer(&buffer); return ret; } @@ -560,7 +568,7 @@ static int32_t SerStubFreeBuffer(struct CodecComponentTypeStub *stub, struct Hdf int32_t ret; uint32_t portIndex = 0; struct OmxCodecBuffer buffer; - + InitOmxCodecBuffer(&buffer); if (!HdfSbufReadUint32(data, &portIndex)) { HDF_LOGE("%{public}s: read &portIndex failed!", __func__); return HDF_ERR_INVALID_PARAM; @@ -568,15 +576,17 @@ static int32_t SerStubFreeBuffer(struct CodecComponentTypeStub *stub, struct Hdf if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) { HDF_LOGE("%{public}s: read buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } ret = stub->service.FreeBuffer(&stub->service, portIndex, &buffer); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call FreeBuffer function failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return ret; } - + ReleaseOmxCodecBuffer(&buffer); return ret; } @@ -585,18 +595,20 @@ static int32_t SerStubEmptyThisBuffer(struct CodecComponentTypeStub *stub, { int32_t ret; struct OmxCodecBuffer buffer; - + InitOmxCodecBuffer(&buffer); if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) { HDF_LOGE("%{public}s: read buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } ret = stub->service.EmptyThisBuffer(&stub->service, &buffer); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call EmptyThisBuffer function failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return ret; } - + ReleaseOmxCodecBuffer(&buffer); return ret; } @@ -605,18 +617,20 @@ static int32_t SerStubFillThisBuffer(struct CodecComponentTypeStub *stub, { int32_t ret; struct OmxCodecBuffer buffer; - + InitOmxCodecBuffer(&buffer); if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) { HDF_LOGE("%{public}s: read buffer failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return HDF_ERR_INVALID_PARAM; } ret = stub->service.FillThisBuffer(&stub->service, &buffer); if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: call FillThisBuffer function failed!", __func__); + ReleaseOmxCodecBuffer(&buffer); return ret; } - + ReleaseOmxCodecBuffer(&buffer); return ret; } diff --git a/codec/hal/src/codec_types.c b/codec/hal/src/codec_types.c index f0c95abda2..4a6b6e5fec 100644 --- a/codec/hal/src/codec_types.c +++ b/codec/hal/src/codec_types.c @@ -12,11 +12,107 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "codec_types.h" +#include +#include #include #include #include +#include + +bool BufferHandleMarshalling(struct HdfSBuf *data, BufferHandle *handle) +{ + if (handle == NULL) { + HDF_LOGE("%{public}s: handle is NULL!", __func__); + return false; + } + + uint8_t validFd = 0; + if (!HdfSbufWriteUint32(data, handle->reserveFds) || !HdfSbufWriteUint32(data, handle->reserveInts) || + !HdfSbufWriteInt32(data, handle->width) || !HdfSbufWriteInt32(data, handle->stride) || + !HdfSbufWriteInt32(data, handle->height) || !HdfSbufWriteInt32(data, handle->size) || + !HdfSbufWriteInt32(data, handle->format) || !HdfSbufWriteInt64(data, handle->usage) || + !HdfSbufWriteUint64(data, handle->phyAddr) || !HdfSbufWriteInt32(data, handle->key)) { + HDF_LOGE("%{public}s: write handle failed!", __func__); + return false; + } + + validFd = (handle->fd >= 0); + if (!HdfSbufWriteUint8(data, validFd)) { + HDF_LOGE("%{public}s: write uint8_t failed!", __func__); + return false; + } + if (validFd && !HdfSbufWriteFileDescriptor(data, handle->fd)) { + HDF_LOGE("%{public}s: write fd failed!", __func__); + return false; + } + + for (uint32_t i = 0; i < handle->reserveFds; i++) { + if (!HdfSbufWriteFileDescriptor(data, handle->reserve[i])) { + HDF_LOGE("%{public}s: write handle->reserve[%{public}d] failed!", __func__, i); + return false; + } + } + + for (uint32_t i = 0; i < handle->reserveInts; i++) { + if (!HdfSbufWriteInt32(data, handle->reserve[i + handle->reserveFds])) { + HDF_LOGE("%{public}s: write handle->reserve[%{public}d] failed!", __func__, i + handle->reserveFds); + return false; + } + } + + return true; +} + +bool BufferHandleUnmarshalling(struct HdfSBuf *data, BufferHandle **handle) +{ + uint8_t validFd = 0; + uint32_t reserveFds = 0; + uint32_t reserveInts = 0; + if (!HdfSbufReadUint32(data, &reserveFds) || !HdfSbufReadUint32(data, &reserveInts)) { + HDF_LOGE("%{public}s: read reserveFds or reserveInts failed!", __func__); + return false; + } + + BufferHandle *tmpHandle = AllocateBufferHandle(reserveFds, reserveInts); + if (tmpHandle == NULL) { + HDF_LOGE("%{public}s: allocate buffer handle failed!", __func__); + return false; + } + + if (!HdfSbufReadInt32(data, &tmpHandle->width) || !HdfSbufReadInt32(data, &tmpHandle->stride) || + !HdfSbufReadInt32(data, &tmpHandle->height) || !HdfSbufReadInt32(data, &tmpHandle->size) || + !HdfSbufReadInt32(data, &tmpHandle->format) || !HdfSbufReadUint64(data, &tmpHandle->usage) || + !HdfSbufReadUint64(data, &tmpHandle->phyAddr) || !HdfSbufReadInt32(data, &tmpHandle->key)) { + HDF_LOGE("%{public}s: read handle failed!", __func__); + FreeBufferHandle(tmpHandle); + return false; + } + + if (!HdfSbufReadUint8(data, &validFd)) { + HDF_LOGE("%{public}s: read handle bool value failed!", __func__); + FreeBufferHandle(tmpHandle); + return false; + } + + if (validFd != 0) { + tmpHandle->fd = HdfSbufReadFileDescriptor(data); + } + + for (uint32_t i = 0; i < tmpHandle->reserveFds; i++) { + tmpHandle->reserve[i] = HdfSbufReadFileDescriptor(data); + } + + for (uint32_t i = 0; i < tmpHandle->reserveInts; i++) { + if (!HdfSbufReadInt32(data, &tmpHandle->reserve[tmpHandle->reserveFds + i])) { + HDF_LOGE("%{public}s: read reserve bool value failed!", __func__); + FreeBufferHandle(tmpHandle); + return false; + } + } + *handle = tmpHandle; + return true; +} bool OMX_TUNNELSETUPTYPEBlockMarshalling(struct HdfSBuf *data, const struct OMX_TUNNELSETUPTYPE *dataBlock) { @@ -43,7 +139,7 @@ bool OMX_TUNNELSETUPTYPEBlockUnmarshalling(struct HdfSBuf *data, struct OMX_TUNN return false; } - if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->eSupplier)) { + if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->eSupplier)) { HDF_LOGE("%{public}s: read dataBlock->eSupplier failed!", __func__); return false; } @@ -77,12 +173,23 @@ static bool CodecBufferMarshalling(struct HdfSBuf *data, const struct OmxCodecBu return true; } + if (dataBlock->buffer == NULL) { + HDF_LOGE("%{public}s: dataBlock->buffer is null", __func__); + return false; + } + if (dataBlock->bufferType == BUFFER_TYPE_AVSHARE_MEM_FD) { int fd = (int)dataBlock->buffer; if (!HdfSbufWriteFileDescriptor(data, fd)) { HDF_LOGE("%{public}s: write fd failed!", __func__); return false; } + } else if (dataBlock->bufferType == BUFFER_TYPE_HANDLE || dataBlock->bufferType == BUFFER_TYPE_DYNAMIC_HANDLE) { + BufferHandle *handle = (BufferHandle *)dataBlock->buffer; + if (!BufferHandleMarshalling(data, handle)) { + HDF_LOGE("%{public}s: write handle failed!", __func__); + return false; + } } else { for (uint32_t i = 0; i < dataBlock->bufferLen; i++) { if (!HdfSbufWriteUint8(data, (dataBlock->buffer)[i])) { @@ -96,13 +203,14 @@ static bool CodecBufferMarshalling(struct HdfSBuf *data, const struct OmxCodecBu bool OmxCodecBufferBlockMarshalling(struct HdfSBuf *data, const struct OmxCodecBuffer *dataBlock) { - if (!HdfSbufWriteUint32(data, dataBlock->bufferId)) { - HDF_LOGE("%{public}s: write dataBlock->bufferId failed!", __func__); + uint8_t validFd = 0; + if (dataBlock == NULL) { + HDF_LOGE("%{public}s: dataBlock is NULL!", __func__); return false; } - if (!HdfSbufWriteUint32(data, dataBlock->size)) { - HDF_LOGE("%{public}s: write dataBlock->size failed!", __func__); + if (!HdfSbufWriteUint32(data, dataBlock->bufferId) || !HdfSbufWriteUint32(data, dataBlock->size)) { + HDF_LOGE("%{public}s: write dataBlock:bufferId or size failed!", __func__); return false; } @@ -115,47 +223,37 @@ bool OmxCodecBufferBlockMarshalling(struct HdfSBuf *data, const struct OmxCodecB return false; } - if (!HdfSbufWriteUint32(data, dataBlock->allocLen)) { - HDF_LOGE("%{public}s: write dataBlock->allocLen failed!", __func__); - return false; - } - - if (!HdfSbufWriteUint32(data, dataBlock->filledLen)) { - HDF_LOGE("%{public}s: write dataBlock->filledLen failed!", __func__); + if (!HdfSbufWriteUint32(data, dataBlock->allocLen) || !HdfSbufWriteUint32(data, dataBlock->filledLen) || + !HdfSbufWriteUint32(data, dataBlock->offset)) { + HDF_LOGE("%{public}s: write dataBlock:allocLen, filledLen or offset failed!", __func__); return false; } - if (!HdfSbufWriteUint32(data, dataBlock->offset)) { - HDF_LOGE("%{public}s: write dataBlock->offset failed!", __func__); + validFd = dataBlock->fenceFd >= 0; + if (!HdfSbufWriteUint8(data, validFd)) { + HDF_LOGE("%{public}s: write validFd failed!", __func__); return false; } - - if (!HdfSbufWriteInt32(data, dataBlock->fenceFd)) { + if (validFd != 0 && !HdfSbufWriteFileDescriptor(data, dataBlock->fenceFd)) { HDF_LOGE("%{public}s: write dataBlock->fenceFd failed!", __func__); return false; } - if (!HdfSbufWriteInt32(data, (int32_t)dataBlock->type)) { - HDF_LOGE("%{public}s: write dataBlock->type failed!", __func__); - return false; - } - - if (!HdfSbufWriteInt64(data, dataBlock->pts)) { - HDF_LOGE("%{public}s: write dataBlock->pts failed!", __func__); - return false; - } - - if (!HdfSbufWriteUint32(data, dataBlock->flag)) { - HDF_LOGE("%{public}s: write dataBlock->flag failed!", __func__); + if (!HdfSbufWriteInt32(data, (int32_t)dataBlock->type) || !HdfSbufWriteInt64(data, dataBlock->pts) || + !HdfSbufWriteUint32(data, dataBlock->flag)) { + HDF_LOGE("%{public}s: write dataBlock:type, pts or flag failed!", __func__); return false; } - return true; } static bool CodecBufferUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer *dataBlock) { - if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->bufferType)) { + if (dataBlock == NULL) { + HDF_LOGE("%{public}s: dataBlock is NULL!", __func__); + return false; + } + if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->bufferType)) { HDF_LOGE("%{public}s: read dataBlock->bufferType failed!", __func__); return false; } @@ -176,11 +274,18 @@ static bool CodecBufferUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer HDF_LOGE("%{public}s: read fd failed!", __func__); return false; } - dataBlock->buffer = (uint8_t*)(unsigned long)fd; + dataBlock->buffer = (uint8_t *)(unsigned long)fd; + } else if (dataBlock->bufferType == BUFFER_TYPE_HANDLE || dataBlock->bufferType == BUFFER_TYPE_DYNAMIC_HANDLE) { + BufferHandle *handle = NULL; + if (!BufferHandleUnmarshalling(data, &handle)) { + HDF_LOGE("%{public}s: read bufferhandle failed!", __func__); + return false; + } + dataBlock->buffer = (uint8_t *)handle; } else { - uint8_t* bufferCp = NULL; + uint8_t *bufferCp = NULL; if (bufferCpLen > 0) { - bufferCp = (uint8_t*)OsalMemCalloc(sizeof(uint8_t) * bufferCpLen); + bufferCp = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * bufferCpLen); } if (bufferCp == NULL) { return false; @@ -197,21 +302,47 @@ static bool CodecBufferUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer return true; } -bool OmxCodecBufferBlockUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer *dataBlock) +void ReleaseOmxCodecBuffer(struct OmxCodecBuffer *codecBuffer) { - if (dataBlock == NULL) { - return false; + if (codecBuffer == NULL) { + return; } - if (!HdfSbufReadUint32(data, &dataBlock->bufferId)) { - HDF_LOGE("%{public}s: read dataBlock->bufferId failed!", __func__); - return false; + + if (codecBuffer->fenceFd >= 0) { + close(codecBuffer->fenceFd); + codecBuffer->fenceFd = -1; + } + if (codecBuffer->buffer == NULL || codecBuffer->bufferLen == 0) { + return; } - if (!HdfSbufReadUint32(data, &dataBlock->size)) { - HDF_LOGE("%{public}s: read dataBlock->size failed!", __func__); - return false; + if (codecBuffer->bufferType == BUFFER_TYPE_DYNAMIC_HANDLE || codecBuffer->bufferType == BUFFER_TYPE_HANDLE) { + FreeBufferHandle((BufferHandle *)codecBuffer->buffer); + } else if (codecBuffer->bufferType != BUFFER_TYPE_AVSHARE_MEM_FD) { + OsalMemFree(codecBuffer->buffer); } + codecBuffer->buffer = NULL; + codecBuffer->bufferLen = 0; +} +void InitOmxCodecBuffer(struct OmxCodecBuffer *codecBuffer) +{ + if (codecBuffer != NULL) { + (void)memset_s(codecBuffer, sizeof(struct OmxCodecBuffer), 0, sizeof(struct OmxCodecBuffer)); + codecBuffer->fenceFd = -1; + } +} +bool OmxCodecBufferBlockUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffer *dataBlock) +{ + uint8_t validFd = 0; + if (dataBlock == NULL || data == NULL) { + HDF_LOGE("%{public}s: dataBlock or data is NULL!", __func__); + return false; + } + if (!HdfSbufReadUint32(data, &dataBlock->bufferId) || !HdfSbufReadUint32(data, &dataBlock->size)) { + HDF_LOGE("%{public}s: read dataBlock:bufferId or size failed!", __func__); + return false; + } const union OMX_VERSIONTYPE *versionCp = (const union OMX_VERSIONTYPE *)HdfSbufReadUnpadBuffer(data, sizeof(union OMX_VERSIONTYPE)); if (versionCp == NULL) { @@ -219,46 +350,29 @@ bool OmxCodecBufferBlockUnmarshalling(struct HdfSBuf *data, struct OmxCodecBuffe return false; } (void)memcpy_s(&dataBlock->version, sizeof(union OMX_VERSIONTYPE), versionCp, sizeof(union OMX_VERSIONTYPE)); - if (!CodecBufferUnmarshalling(data, dataBlock)) { return false; } - - if (!HdfSbufReadUint32(data, &dataBlock->allocLen)) { - HDF_LOGE("%{public}s: read dataBlock->allocLen failed!", __func__); + if (!HdfSbufReadUint32(data, &dataBlock->allocLen) || !HdfSbufReadUint32(data, &dataBlock->filledLen) || + !HdfSbufReadUint32(data, &dataBlock->offset)) { + HDF_LOGE("%{public}s: read dataBlock:allocLen, filledLen or offset failed!", __func__); return false; } - if (!HdfSbufReadUint32(data, &dataBlock->filledLen)) { - HDF_LOGE("%{public}s: read dataBlock->filledLen failed!", __func__); + if (!HdfSbufReadUint8(data, &validFd)) { + HDF_LOGE("%{public}s: read validFd failed!", __func__); return false; } - if (!HdfSbufReadUint32(data, &dataBlock->offset)) { - HDF_LOGE("%{public}s: read dataBlock->offset failed!", __func__); - return false; + if (validFd != 0) { + dataBlock->fenceFd = HdfSbufReadFileDescriptor(data); } - if (!HdfSbufReadInt32(data, &dataBlock->fenceFd)) { - HDF_LOGE("%{public}s: read dataBlock->fenceFd failed!", __func__); + if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->type) || !HdfSbufReadInt64(data, &dataBlock->pts) || + !HdfSbufReadUint32(data, &dataBlock->flag)) { + HDF_LOGE("%{public}s: read dataBlock:type, pts or flag failed!", __func__); return false; } - - if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->type)) { - HDF_LOGE("%{public}s: read dataBlock->type failed!", __func__); - return false; - } - - if (!HdfSbufReadInt64(data, &dataBlock->pts)) { - HDF_LOGE("%{public}s: read dataBlock->pts failed!", __func__); - return false; - } - - if (!HdfSbufReadUint32(data, &dataBlock->flag)) { - HDF_LOGE("%{public}s: read dataBlock->flag failed!", __func__); - return false; - } - return true; } @@ -604,18 +718,18 @@ bool CodecCompCapabilityBlockUnmarshalling(struct HdfSBuf *data, CodecCompCapabi if (dataBlock == NULL) { return false; } - if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->role)) { + if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->role)) { HDF_LOGE("%{public}s: read dataBlock->role failed!", __func__); return false; } - if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->type)) { + if (!HdfSbufReadInt32(data, (int32_t *)&dataBlock->type)) { HDF_LOGE("%{public}s: read dataBlock->type failed!", __func__); return false; } for (uint32_t i = 0; i < NAME_LENGTH; i++) { - if (!HdfSbufReadUint8(data, (uint8_t*)&(dataBlock->compName)[i])) { + if (!HdfSbufReadUint8(data, (uint8_t *)&(dataBlock->compName)[i])) { HDF_LOGE("%{public}s: read compName[i] failed!", __func__); return false; } diff --git a/codec/hal/v2.0/hdi_impl/include/codec_dyna_buffer.h b/codec/hal/v2.0/hdi_impl/include/codec_dyna_buffer.h new file mode 100644 index 0000000000..ace3225d18 --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/include/codec_dyna_buffer.h @@ -0,0 +1,47 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_DYNA_BUFFER_H +#define CODEC_DYNA_BUFFER_H +#include "icodec_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecDynaBuffer : ICodecBuffer { +public: + CodecDynaBuffer(struct OmxCodecBuffer &codecBuffer); + ~CodecDynaBuffer(); + sptr static Create(struct OmxCodecBuffer &codecBuffer); + int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) override; + int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + uint8_t *GetBuffer() override; + +protected: + bool CheckInvalid(struct OmxCodecBuffer &codecBuffer) override; + +private: + void ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + +private: + std::shared_ptr dynaBuffer_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif // CODEC_DYNA_BUFFER_H \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/include/codec_handle_buffer.h b/codec/hal/v2.0/hdi_impl/include/codec_handle_buffer.h new file mode 100644 index 0000000000..e18f067f08 --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/include/codec_handle_buffer.h @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_HANDLE_BUFFER_H +#define CODEC_HANDLE_BUFFER_H +#include +#include "icodec_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecHandleBuffer : ICodecBuffer { +public: + CodecHandleBuffer(struct OmxCodecBuffer &codecBuffer); + ~CodecHandleBuffer(); + sptr static Create(struct OmxCodecBuffer &codecBuffer); + int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) override; + int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + uint8_t *GetBuffer() override; + +protected: + bool CheckInvalid(struct OmxCodecBuffer &codecBuffer) override; + +private: + void ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + +private: + BufferHandle *bufferHandle_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif // CODEC_HANDLE_BUFFER_H \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/include/codec_share_buffer.h b/codec/hal/v2.0/hdi_impl/include/codec_share_buffer.h new file mode 100644 index 0000000000..50cefc9081 --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/include/codec_share_buffer.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_SHARE_BUFFER_H +#define CODEC_SHARE_BUFFER_H +#include +#include +#include "icodec_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecShareBuffer : ICodecBuffer { +public: + CodecShareBuffer(struct OmxCodecBuffer &codecBuffer); + ~CodecShareBuffer(); + OHOS::sptr static Create(struct OmxCodecBuffer &codecBuffer); + OHOS::sptr static Allocate(struct OmxCodecBuffer &codecBuffer); + int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) override; + int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + void SetAshMem(std::shared_ptr shMem); + uint8_t *GetBuffer() override; + +protected: + bool CheckInvalid(struct OmxCodecBuffer &codecBuffer) override; + +private: + void ReleaseFd(struct OmxCodecBuffer &codecBuffer); + +private: + std::shared_ptr shMem_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/include/component_node.h b/codec/hal/v2.0/hdi_impl/include/component_node.h index 96b661dc3f..5b1ed6a341 100644 --- a/codec/hal/v2.0/hdi_impl/include/component_node.h +++ b/codec/hal/v2.0/hdi_impl/include/component_node.h @@ -17,36 +17,15 @@ #include #include #include -#include #include #include #include #include +#include "icodec_buffer.h" #include "codec_callback_if.h" #include "codec_component_type.h" -struct BufferInfo { - struct OmxCodecBuffer omxCodecBuffer; - std::shared_ptr sharedMem; // sharedMem - - BufferInfo() - { - omxCodecBuffer = {0}; - sharedMem = nullptr; - } - ~BufferInfo() - { - if (sharedMem) { - sharedMem->UnmapAshmem(); - sharedMem->CloseAshmem(); - sharedMem = nullptr; - } - } -}; -using BufferInfo = struct BufferInfo; -using BufferInfoSPtr = std::shared_ptr; -using BufferInfoWPtr = std::weak_ptr; namespace OHOS { namespace Codec { namespace Omx { @@ -116,41 +95,17 @@ private: int32_t OnFillBufferDone(OMX_BUFFERHEADERTYPE *buffer); uint32_t GenerateBufferId(); - - void inline CheckBuffer(struct OmxCodecBuffer &buffer); - - BufferInfoSPtr GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer); - - bool GetBufferById(uint32_t bufferId, BufferInfoSPtr &bufferInfo, OMX_BUFFERHEADERTYPE *&bufferHdrType); - - void ReleaseBufferById(uint32_t bufferId); - - int32_t UseSharedBuffer(struct OmxCodecBuffer &omxCodecBuffer, uint32_t portIndex); - - int32_t UseHandleBuffer(struct OmxCodecBuffer &omxCodecBuffer, uint32_t portIndex); - - int32_t UseDynaHandleBuffer(struct OmxCodecBuffer &omxCodecBuffer, uint32_t portIndex); - - int32_t EmptySharedBuffer(struct OmxCodecBuffer &buffer, BufferInfoSPtr bufferInfo, - OMX_BUFFERHEADERTYPE *bufferHdrType); - - void SaveBufferInfo(struct OmxCodecBuffer &omxCodecBuffer, OMX_BUFFERHEADERTYPE *bufferHdrType, - std::shared_ptr sharedMem); + sptr GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer); + bool GetBufferById(uint32_t bufferId, sptr &codecBuffer, OMX_BUFFERHEADERTYPE *&bufferHdrType); private: OMX_HANDLETYPE comp_; // Compnent handle struct CodecCallbackType *omxCallback_; // Callbacks in HDI int8_t *appData_; // Use data, default is nullptr int32_t appDataSize_; // User data length, default is 0 - std::map bufferInfoMap_; // Key is buffferID + std::map> codecBufferMap_; // Key is buffferID std::map bufferHeaderMap_; // Key is omx buffer header type - uint32_t bufferIdCount_; - -#ifdef NODE_DEBUG - FILE *fp_in; - FILE *fp_out; -#endif }; } // namespace Omx } // namespace Codec diff --git a/codec/hal/v2.0/hdi_impl/include/icodec_buffer.h b/codec/hal/v2.0/hdi_impl/include/icodec_buffer.h new file mode 100644 index 0000000000..33dc09941c --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/include/icodec_buffer.h @@ -0,0 +1,74 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_CODEC_BUFFER_H +#define I_CODEC_BUFFER_H +#include +#include +#include +#include +#include +#include +#include +#include "codec_component_type.h" + +constexpr uint32_t TIME_WAIT_MS = 5; +namespace OHOS { +namespace Codec { +namespace Omx { +struct DynamicBuffer { + int32_t type; + BufferHandle *bufferHandle; + + DynamicBuffer() : type(0), bufferHandle(nullptr) + {} + ~DynamicBuffer() + { + type = 0; + if (bufferHandle != nullptr) { + FreeBufferHandle(bufferHandle); + } + bufferHandle = nullptr; + } +}; +using DynamicBuffer = struct DynamicBuffer; + +class ICodecBuffer : public RefBase { +public: + ICodecBuffer() + {} + ICodecBuffer(struct OmxCodecBuffer &codecBuffer); + virtual ~ICodecBuffer(); + sptr static CreateCodeBuffer(struct OmxCodecBuffer &codecBuffer); + sptr static AllocateCodecBuffer(struct OmxCodecBuffer &codecBuffer); + virtual int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + virtual int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + virtual int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) = 0; + virtual int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer); + virtual int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer); + virtual uint8_t *GetBuffer() = 0; + struct OmxCodecBuffer &GetCodecBuffer(); + void SetBufferId(int32_t bufferId); + +protected: + virtual bool CheckInvalid(struct OmxCodecBuffer &codecBuffer); + +protected: + struct OmxCodecBuffer codecBuffer_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/src/codec_dyna_buffer.cpp b/codec/hal/v2.0/hdi_impl/src/codec_dyna_buffer.cpp new file mode 100644 index 0000000000..99a1a99f8a --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/src/codec_dyna_buffer.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "codec_dyna_buffer.h" +#include +#include +#include +#include +#include + +namespace OHOS { +namespace Codec { +namespace Omx { +CodecDynaBuffer::CodecDynaBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) +{} + +CodecDynaBuffer::~CodecDynaBuffer() +{ + if (dynaBuffer_ != nullptr) { + dynaBuffer_ = nullptr; + } +} + +sptr CodecDynaBuffer::Create(struct OmxCodecBuffer &codecBuffer) +{ + auto bufferHandle = reinterpret_cast(codecBuffer.buffer); + // may be empty for bufferHandle + codecBuffer.buffer = nullptr; + codecBuffer.bufferLen = 0; + + CodecDynaBuffer *buffer = new CodecDynaBuffer(codecBuffer); + buffer->dynaBuffer_ = std::make_shared(); + buffer->dynaBuffer_->bufferHandle = bufferHandle; + return sptr(buffer); +} + +int32_t CodecDynaBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s :dyna buffer handle is not supported in FillThisBuffer ", __func__); + (void)codecBuffer; + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +int32_t CodecDynaBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s : CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + ResetBuffer(codecBuffer, omxBuffer); + + int eFence = codecBuffer.fenceFd; + if (eFence >= 0) { + sync_wait(eFence, TIME_WAIT_MS); + close(codecBuffer.fenceFd); + codecBuffer.fenceFd = -1; + } + + return ICodecBuffer::EmptyOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecDynaBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + + if (codecBuffer.buffer != nullptr) { + auto bufferHandle = reinterpret_cast(codecBuffer.buffer); + // if recv new BufferHandle, save it + if (bufferHandle != nullptr) { + FreeBufferHandle(bufferHandle); + bufferHandle = nullptr; + } + codecBuffer.buffer = 0; + codecBuffer.bufferLen = 0; + } + + if (dynaBuffer_ != nullptr) { + dynaBuffer_ = nullptr; + } + + return HDF_SUCCESS; +} + +int32_t CodecDynaBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + return ICodecBuffer::EmptyOmxBufferDone(omxBuffer); +} + +int32_t CodecDynaBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s :dyna buffer handle is not supported in FillThisBuffer ", __func__); + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +uint8_t *CodecDynaBuffer::GetBuffer() +{ + return reinterpret_cast(dynaBuffer_.get()); +} + +bool CodecDynaBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (!ICodecBuffer::CheckInvalid(codecBuffer) || dynaBuffer_ == nullptr) { + HDF_LOGE("%{public}s :dynaBuffer_ is null or CheckInvalid return false", __func__); + return false; + } + return true; +} + +void CodecDynaBuffer::ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + (void)omxBuffer; + if (codecBuffer.buffer == nullptr) { + return; + } + auto bufferHandle = reinterpret_cast(codecBuffer.buffer); + // if recv new BufferHandle, save it, but do not need to save to omxBuffer + if (dynaBuffer_->bufferHandle != nullptr) { + FreeBufferHandle(dynaBuffer_->bufferHandle); + } + dynaBuffer_->bufferHandle = bufferHandle; + codecBuffer.buffer = 0; + codecBuffer.bufferLen = 0; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/src/codec_handle_buffer.cpp b/codec/hal/v2.0/hdi_impl/src/codec_handle_buffer.cpp new file mode 100644 index 0000000000..bea008456d --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/src/codec_handle_buffer.cpp @@ -0,0 +1,144 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_handle_buffer.h" +#include +#include +#include +#include + +namespace OHOS { +namespace Codec { +namespace Omx { +CodecHandleBuffer::CodecHandleBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) +{} + +CodecHandleBuffer::~CodecHandleBuffer() +{ + if (bufferHandle_ != nullptr) { + FreeBufferHandle(bufferHandle_); + bufferHandle_ = nullptr; + } +} + +sptr CodecHandleBuffer::Create(struct OmxCodecBuffer &codecBuffer) +{ + auto bufferHandle = reinterpret_cast(codecBuffer.buffer); + if (bufferHandle == nullptr) { + HDF_LOGE("%{public}s error, bufferHandle is null", __func__); + return nullptr; + } + codecBuffer.buffer = nullptr; + codecBuffer.bufferLen = 0; + + CodecHandleBuffer *buffer = new CodecHandleBuffer(codecBuffer); + buffer->bufferHandle_ = bufferHandle; + return sptr(buffer); +} + +int32_t CodecHandleBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :CheckInvalid return false or mem has no right to write ", __func__); + return HDF_ERR_INVALID_PARAM; + } + ResetBuffer(codecBuffer, omxBuffer); + + int fenceFd = codecBuffer.fenceFd; + if (fenceFd >= 0) { + sync_wait(fenceFd, TIME_WAIT_MS); + close(codecBuffer.fenceFd); + codecBuffer.fenceFd = -1; + } + return ICodecBuffer::FillOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecHandleBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s : bufferHandle is not support in EmptyThisBuffer", __func__); + (void)codecBuffer; + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +int32_t CodecHandleBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + + if (codecBuffer.buffer != nullptr) { + auto bufferHandle = reinterpret_cast(codecBuffer.buffer); + // if recv new BufferHandle, save it + if (bufferHandle != nullptr) { + FreeBufferHandle(bufferHandle); + bufferHandle = nullptr; + } + codecBuffer.buffer = 0; + codecBuffer.bufferLen = 0; + } + + if (bufferHandle_ != nullptr) { + FreeBufferHandle(bufferHandle_); + bufferHandle_ = nullptr; + } + + return HDF_SUCCESS; +} + +int32_t CodecHandleBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s : bufferHandle is not support in EmptyThisBuffer", __func__); + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +int32_t CodecHandleBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + return ICodecBuffer::FillOmxBufferDone(omxBuffer); +} + +uint8_t *CodecHandleBuffer::GetBuffer() +{ + return reinterpret_cast(bufferHandle_); +} + +bool CodecHandleBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (!ICodecBuffer::CheckInvalid(codecBuffer) || bufferHandle_ == nullptr) { + HDF_LOGE("%{public}s :bufferHandle_ is null or CheckInvalid return false", __func__); + return false; + } + return true; +} + +void CodecHandleBuffer::ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (codecBuffer.buffer != nullptr) { + auto bufferHandle = reinterpret_cast(codecBuffer.buffer); + // if recv new BufferHandle, save it, and save the new bufferhandle to omxbuffer + if (bufferHandle != nullptr) { + FreeBufferHandle(bufferHandle_); + bufferHandle_ = bufferHandle; + } + omxBuffer.pBuffer = reinterpret_cast(bufferHandle_); + codecBuffer.buffer = 0; + codecBuffer.bufferLen = 0; + } +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/src/codec_share_buffer.cpp b/codec/hal/v2.0/hdi_impl/src/codec_share_buffer.cpp new file mode 100644 index 0000000000..84ba014306 --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/src/codec_share_buffer.cpp @@ -0,0 +1,190 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_share_buffer.h" +#include +#include +#include +#include + +namespace OHOS { +namespace Codec { +namespace Omx { +CodecShareBuffer::CodecShareBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) +{} + +CodecShareBuffer::~CodecShareBuffer() +{ + if (shMem_ != nullptr) { + shMem_->UnmapAshmem(); + shMem_->CloseAshmem(); + shMem_ = nullptr; + } +} + +void CodecShareBuffer::SetAshMem(std::shared_ptr shMem) +{ + shMem_ = shMem; +} + +OHOS::sptr CodecShareBuffer::Create(struct OmxCodecBuffer &codecBuffer) +{ + int shardFd = (int)reinterpret_cast(codecBuffer.buffer); + if (shardFd < 0) { + HDF_LOGE("%{public}s error, shardFd < 0", __func__); + return nullptr; + } + int size = OHOS::AshmemGetSize(shardFd); + std::shared_ptr sharedMem = std::make_shared(shardFd, size); + bool mapd = false; + if (codecBuffer.type == READ_WRITE_TYPE) { + mapd = sharedMem->MapReadAndWriteAshmem(); + } else { + mapd = sharedMem->MapReadOnlyAshmem(); + } + if (!mapd) { + HDF_LOGE("%{public}s error, MapReadAndWriteAshmem or MapReadOnlyAshmem return false", __func__); + return nullptr; + } + + codecBuffer.buffer = nullptr; + codecBuffer.bufferLen = 0; + CodecShareBuffer *buffer = new CodecShareBuffer(codecBuffer); + buffer->SetAshMem(sharedMem); + + return OHOS::sptr(buffer); +} + +OHOS::sptr CodecShareBuffer::Allocate(struct OmxCodecBuffer &codecBuffer) +{ + codecBuffer.bufferType = BUFFER_TYPE_AVSHARE_MEM_FD; + // create shared memory + int sharedFD = AshmemCreate(nullptr, codecBuffer.allocLen); + + std::shared_ptr sharedMemory = std::make_shared(sharedFD, codecBuffer.allocLen); + codecBuffer.type = READ_WRITE_TYPE; + bool mapd = false; + if (codecBuffer.type == READ_WRITE_TYPE) { + mapd = sharedMemory->MapReadAndWriteAshmem(); + } else { + mapd = sharedMemory->MapReadOnlyAshmem(); + } + if (!mapd) { + HDF_LOGE("%{public}s error, MapReadAndWriteAshmem or MapReadOnlyAshmem return false", __func__); + return nullptr; + } + codecBuffer.offset = 0; + codecBuffer.filledLen = 0; + + CodecShareBuffer *buffer = new CodecShareBuffer(codecBuffer); + codecBuffer.buffer = (uint8_t *)(uintptr_t)sharedFD; + codecBuffer.bufferLen = sizeof(int); + buffer->SetAshMem(sharedMemory); + return OHOS::sptr(buffer); +} + +int32_t CodecShareBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer) || codecBuffer_.type != READ_WRITE_TYPE) { + HDF_LOGE("%{public}s :CheckInvalid return false or mem has no right to write ", __func__); + return HDF_ERR_INVALID_PARAM; + } + + ReleaseFd(codecBuffer); + + return ICodecBuffer::FillOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecShareBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + + ReleaseFd(codecBuffer); + + void *sharedPtr = const_cast(shMem_->ReadFromAshmem(codecBuffer.filledLen, codecBuffer.offset)); + if (!sharedPtr) { + HDF_LOGE("%{public}s error, omxBuffer.length [%{public}d omxBuffer.offset[%{public}d]", __func__, + codecBuffer.filledLen, codecBuffer.offset); + return HDF_ERR_INVALID_PARAM; + } + auto ret = memcpy_s(omxBuffer.pBuffer + codecBuffer.offset, codecBuffer.allocLen - codecBuffer.offset, sharedPtr, + codecBuffer.filledLen); + if (ret != EOK) { + HDF_LOGE("%{public}s error, memcpy_s ret [%{public}d", __func__, ret); + return HDF_ERR_INVALID_PARAM; + } + return ICodecBuffer::EmptyOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecShareBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + + ReleaseFd(codecBuffer); + + shMem_->UnmapAshmem(); + shMem_->CloseAshmem(); + shMem_ = nullptr; + return HDF_SUCCESS; +} + +uint8_t *CodecShareBuffer::GetBuffer() +{ + return nullptr; +} + +int32_t CodecShareBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + return ICodecBuffer::EmptyOmxBufferDone(omxBuffer); +} + +int32_t CodecShareBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (shMem_ == nullptr || !shMem_->WriteToAshmem(omxBuffer.pBuffer, omxBuffer.nFilledLen, omxBuffer.nOffset)) { + HDF_LOGE("%{public}s write to ashmem[%{public}p] fail", __func__, shMem_.get()); + return HDF_ERR_INVALID_PARAM; + } + + return ICodecBuffer::FillOmxBufferDone(omxBuffer); +} + +bool CodecShareBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (!ICodecBuffer::CheckInvalid(codecBuffer) || shMem_ == nullptr) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return false; + } + return true; +} + +void CodecShareBuffer::ReleaseFd(struct OmxCodecBuffer &codecBuffer) +{ + // close the fd, if fd is sent by codecBuffer + if (codecBuffer.buffer != nullptr) { + int fd = (int)reinterpret_cast(codecBuffer.buffer); + close(fd); + codecBuffer.buffer = 0; + codecBuffer.bufferLen = 0; + } +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/src/component_node.cpp b/codec/hal/v2.0/hdi_impl/src/component_node.cpp index fb627fad98..17c699d5d3 100644 --- a/codec/hal/v2.0/hdi_impl/src/component_node.cpp +++ b/codec/hal/v2.0/hdi_impl/src/component_node.cpp @@ -13,16 +13,16 @@ * limitations under the License. */ +#include "component_node.h" #include -#include #include #include +#include #include #include #include #include - -#include "component_node.h" +#include "icodec_buffer.h" #define HDF_LOG_TAG codec_hdi_server #define FD_SIZE sizeof(int) @@ -76,33 +76,14 @@ ComponentNode::ComponentNode(struct CodecCallbackType *callback, int8_t *appData appDataSize_ = 0; } comp_ = nullptr; - bufferInfoMap_.clear(); + codecBufferMap_.clear(); bufferHeaderMap_.clear(); omxCallback_ = callback; bufferIdCount_ = 0; -#ifdef NODE_DEBUG - char filename[256] = {0}; - (void)snprintf_s(filename, sizeof(filename), sizeof(filename) - 1, "/data/codec_in_%p.h264", this); - fp_in = fopen(filename, "wb+"); - (void)snprintf_s(filename, sizeof(filename), sizeof(filename) - 1, "/data/codec_out_%p.yuv", this); - fp_out = fopen(filename, "wb+"); -#endif } ComponentNode::~ComponentNode() { -#ifdef NODE_DEBUG - if (fp_in != nullptr) { - fclose(fp_in); - fp_in = nullptr; - } - - if (fp_out != nullptr) { - fclose(fp_out); - fp_out = nullptr; - } -#endif - if (appData_ != nullptr) { OsalMemFree(appData_); appData_ = nullptr; @@ -113,8 +94,7 @@ ComponentNode::~ComponentNode() OsalMemFree(omxCallback_); omxCallback_ = nullptr; } - - bufferInfoMap_.clear(); + codecBufferMap_.clear(); bufferHeaderMap_.clear(); bufferIdCount_ = 0; } @@ -213,8 +193,7 @@ int32_t ComponentNode::ComponentTunnelRequest(uint32_t port, int32_t omxHandleTy } OMX_COMPONENTTYPE *comType = static_cast(comp_); unsigned long tunneledComp = (unsigned long)omxHandleTypeTunneledComp; - return comType->ComponentTunnelRequest(comp_, port, (OMX_HANDLETYPE)tunneledComp, tunneledPort, - tunnelSetup); + return comType->ComponentTunnelRequest(comp_, port, (OMX_HANDLETYPE)tunneledComp, tunneledPort, tunnelSetup); } int32_t ComponentNode::SetCallbacks(struct CodecCallbackType *omxCallback, int8_t *appData, uint32_t appDataLen) @@ -289,14 +268,15 @@ int32_t ComponentNode::OnEvent(OMX_EVENTTYPE event, uint32_t data1, uint32_t dat return OMX_ErrorNone; } - struct EventInfo info = {0}; + struct EventInfo info = { + .appData = nullptr, .appDataLen = 0, .data1 = 0, .data2 = 0, .eventData = nullptr, .eventDataLen = 0}; info.appData = appData_; info.appDataLen = appDataSize_; info.data1 = data1; info.data2 = data2; info.eventData = static_cast(eventData); info.eventDataLen = 0; - omxCallback_->EventHandler(omxCallback_, event, &info); + (void)omxCallback_->EventHandler(omxCallback_, event, &info); return OMX_ErrorNone; } @@ -307,39 +287,13 @@ int32_t ComponentNode::OnEmptyBufferDone(OMX_BUFFERHEADERTYPE *buffer) HDF_LOGE("%{public}s error, omxCallback_ or buffer is null", __func__); return OMX_ErrorNone; } - BufferInfoSPtr bufferInfo = GetBufferInfoByHeader(buffer); - if (bufferInfo == nullptr) { - HDF_LOGE("%{public}s get bufferinfo by header[0x%{public}p] error", __func__, buffer); + sptr codecBuffer = GetBufferInfoByHeader(buffer); + if (codecBuffer == nullptr || codecBuffer->EmptyOmxBufferDone(*buffer) != HDF_SUCCESS) { + HDF_LOGE("%{public}s codecBuffer is null or EmptyOmxBufferDone error", __func__); return OMX_ErrorNone; } - - struct OmxCodecBuffer &omxCodecBuffer = bufferInfo->omxCodecBuffer; - switch (omxCodecBuffer.bufferType) { - case BUFFER_TYPE_AVSHARE_MEM_FD: { - omxCodecBuffer.offset = buffer->nOffset; - omxCodecBuffer.filledLen = buffer->nFilledLen; - break; - } - - case BUFFER_TYPE_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle = %{public}d is not implement", __func__, - omxCodecBuffer.bufferType); - break; - } - - case BUFFER_TYPE_DYNAMIC_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle = %{public}d is not implement", __func__, - omxCodecBuffer.bufferType); - break; - } - default: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle = %{public}d is not implement", __func__, - omxCodecBuffer.bufferType); - break; - } - } - - omxCallback_->EmptyBufferDone(omxCallback_, appData_, appDataSize_, &omxCodecBuffer); + struct OmxCodecBuffer &codecOmxBuffer = codecBuffer->GetCodecBuffer(); + (void)omxCallback_->EmptyBufferDone(omxCallback_, appData_, appDataSize_, &codecOmxBuffer); return OMX_ErrorNone; } @@ -350,50 +304,14 @@ int32_t ComponentNode::OnFillBufferDone(OMX_BUFFERHEADERTYPE *buffer) return OMX_ErrorNone; } - BufferInfoSPtr bufferInfo = GetBufferInfoByHeader(buffer); - if (bufferInfo == nullptr) { - HDF_LOGE("%{public}s error, GetBufferInfoByHeader return null", __func__); + sptr codecBuffer = GetBufferInfoByHeader(buffer); + if (codecBuffer == nullptr || codecBuffer->FillOmxBufferDone(*buffer) != HDF_SUCCESS) { + HDF_LOGE("%{public}s codecBuffer is null or EmptyOmxBufferDone error", __func__); return OMX_ErrorNone; } - struct OmxCodecBuffer &omxCodecBuffer = bufferInfo->omxCodecBuffer; - - switch (omxCodecBuffer.bufferType) { - case BUFFER_TYPE_AVSHARE_MEM_FD: { - if (!bufferInfo->sharedMem->WriteToAshmem(buffer->pBuffer, buffer->nFilledLen, buffer->nOffset)) { - HDF_LOGE("%{public}s write to ashmem fail", __func__); - return OMX_ErrorNone; - } -#ifdef NODE_DEBUG - (void)fwrite(buffer->buffer + buffer->nOffset, 1, buffer->nFilledLen, fp_out); - (void)fflush(fp_out); -#endif - omxCodecBuffer.offset = buffer->nOffset; - omxCodecBuffer.filledLen = buffer->nFilledLen; - break; - } - - case BUFFER_TYPE_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle = %{public}d is not implement", __func__, - omxCodecBuffer.bufferType); - break; - } - - case BUFFER_TYPE_DYNAMIC_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle = %{public}d is not implement", __func__, - omxCodecBuffer.bufferType); - break; - } - default: { - break; - } - } - - // save the flags - omxCodecBuffer.flag = buffer->nFlags; - omxCodecBuffer.pts = buffer->nTimeStamp; - omxCallback_->FillBufferDone(omxCallback_, appData_, appDataSize_, &omxCodecBuffer); - + struct OmxCodecBuffer &codecOmxBuffer = codecBuffer->GetCodecBuffer(); + (void)omxCallback_->FillBufferDone(omxCallback_, appData_, appDataSize_, &codecOmxBuffer); return OMX_ErrorNone; } @@ -403,22 +321,36 @@ int32_t ComponentNode::UseBuffer(uint32_t portIndex, struct OmxCodecBuffer &buff HDF_LOGE("%{public}s error, comp_ is null", __func__); return OMX_ErrorInvalidComponent; } + if (buffer.fenceFd >= 0) { + close(buffer.fenceFd); + buffer.fenceFd = -1; + } - int32_t err = OMX_ErrorUndefined; + int32_t err = OMX_ErrorBadParameter; + sptr codecBuffer = ICodecBuffer::CreateCodeBuffer(buffer); + if (codecBuffer == nullptr) { + HDF_LOGE("%{public}s error, comp_ is null", __func__); + return OMX_ErrorInvalidComponent; + } + OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; + if (buffer.bufferType == BUFFER_TYPE_AVSHARE_MEM_FD) { + err = OMX_AllocateBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, buffer.allocLen); + } else { + err = OMX_UseBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, buffer.allocLen, + codecBuffer->GetBuffer()); + } - switch (buffer.bufferType) { - case BUFFER_TYPE_AVSHARE_MEM_FD: - err = UseSharedBuffer(buffer, portIndex); - break; - case BUFFER_TYPE_HANDLE: - err = UseHandleBuffer(buffer, portIndex); - break; - case BUFFER_TYPE_DYNAMIC_HANDLE: - err = UseDynaHandleBuffer(buffer, portIndex); - break; - default: - break; + if (err != OMX_ErrorNone) { + HDF_LOGE("%{public}s : type [%{public}d] OMX_AllocateBuffer or OMX_UseBuffer ret err[%{public}x]", __func__, + buffer.bufferType, err); + codecBuffer = nullptr; + return err; } + uint32_t bufferId = GenerateBufferId(); + buffer.bufferId = bufferId; + codecBuffer->SetBufferId(bufferId); + codecBufferMap_.emplace(std::make_pair(bufferId, codecBuffer)); + bufferHeaderMap_.emplace(std::make_pair(bufferHdrType, bufferId)); return err; } @@ -429,7 +361,6 @@ int32_t ComponentNode::AllocateBuffer(uint32_t portIndex, struct OmxCodecBuffer HDF_LOGE("%{public}s error, comp_ is null", __func__); return OMX_ErrorInvalidComponent; } - OMX_BUFFERHEADERTYPE *bufferHdrType = 0; int32_t err = OMX_AllocateBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, buffer.allocLen); if (err != OMX_ErrorNone) { @@ -437,12 +368,18 @@ int32_t ComponentNode::AllocateBuffer(uint32_t portIndex, struct OmxCodecBuffer return err; } - // create shared memory - int sharedFD = AshmemCreate(nullptr, bufferHdrType->nAllocLen); - std::shared_ptr sharedMemory = std::make_shared(sharedFD, bufferHdrType->nAllocLen); - SaveBufferInfo(buffer, bufferHdrType, sharedMemory); - buffer.buffer = (uint8_t *)(unsigned long)sharedFD; - buffer.bufferLen = FD_SIZE; + buffer.allocLen = bufferHdrType->nAllocLen; + sptr codecBuffer = ICodecBuffer::AllocateCodecBuffer(buffer); + if (codecBuffer == nullptr) { + HDF_LOGE("%{public}s error, comp_ is null", __func__); + (void)OMX_FreeBuffer((OMX_HANDLETYPE)comp_, portIndex, bufferHdrType); + return OMX_ErrorInvalidComponent; + } + + uint32_t bufferId = GenerateBufferId(); + buffer.bufferId = bufferId; + codecBufferMap_.emplace(std::make_pair(bufferId, codecBuffer)); + bufferHeaderMap_.emplace(std::make_pair(bufferHdrType, bufferId)); return OMX_ErrorNone; } @@ -452,41 +389,36 @@ int32_t ComponentNode::FreeBuffer(uint32_t portIndex, struct OmxCodecBuffer &buf HDF_LOGE("%{public}s error, comp_ = %{public}p", __func__, comp_); return OMX_ErrorInvalidComponent; } - CheckBuffer(buffer); - int32_t err = OMX_ErrorUndefined; - BufferInfoSPtr bufferInfo = nullptr; + + int32_t err = OMX_ErrorBadParameter; + sptr codecBufer = nullptr; OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; - if (!GetBufferById(buffer.bufferId, bufferInfo, bufferHdrType)) { + if (!GetBufferById(buffer.bufferId, codecBufer, bufferHdrType)) { HDF_LOGE("%{public}s error, GetBufferById return false", __func__); return err; } - switch (bufferInfo->omxCodecBuffer.bufferType) { - case BUFFER_TYPE_AVSHARE_MEM_FD: { - err = OMX_FreeBuffer((OMX_HANDLETYPE)comp_, portIndex, bufferHdrType); - HDF_LOGI("%{public}s , OMX_FreeBuffer ret [0x%{public}x]", __func__, err); - break; - } - case BUFFER_TYPE_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle is not implement", __func__); - err = OMX_ErrorUndefined; - break; - } + err = OMX_FreeBuffer((OMX_HANDLETYPE)comp_, portIndex, bufferHdrType); + if (err != OMX_ErrorNone) { + HDF_LOGE("%{public}s error, OMX_FreeBuffer err [%{public}x]", __func__, err); + return err; + } - case BUFFER_TYPE_DYNAMIC_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle is not implement", __func__); - err = OMX_ErrorUndefined; - break; - } - default: { - err = OMX_ErrorUndefined; + auto iterOmxBuffer = bufferHeaderMap_.begin(); + while (iterOmxBuffer != bufferHeaderMap_.end()) { + if (iterOmxBuffer->first == bufferHdrType) { + bufferHeaderMap_.erase(iterOmxBuffer); break; } + iterOmxBuffer++; } - if (err == OMX_ErrorNone) { - ReleaseBufferById(buffer.bufferId); - bufferInfo = nullptr; + + auto iter = codecBufferMap_.find(buffer.bufferId); + if (iter != codecBufferMap_.end()) { + codecBufferMap_.erase(iter); } + (void)codecBufer->FreeBuffer(buffer); + return err; } @@ -496,46 +428,20 @@ int32_t ComponentNode::EmptyThisBuffer(struct OmxCodecBuffer &buffer) HDF_LOGE("%{public}s error, comp_ = %{public}p", __func__, comp_); return OMX_ErrorInvalidComponent; } - CheckBuffer(buffer); - int32_t err = OMX_ErrorUndefined; - BufferInfoSPtr bufferInfo = nullptr; + int32_t err = OMX_ErrorBadParameter; OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; - if (!GetBufferById(buffer.bufferId, bufferInfo, bufferHdrType)) { + sptr codecBuffer = nullptr; + if (!GetBufferById(buffer.bufferId, codecBuffer, bufferHdrType)) { HDF_LOGE("%{public}s error, GetBufferById return false", __func__); return err; } - switch (bufferInfo->omxCodecBuffer.bufferType) { - case BUFFER_TYPE_AVSHARE_MEM_FD: { - err = EmptySharedBuffer(buffer, bufferInfo, bufferHdrType); - break; - } - // When empty buffer, this case is disabled - case BUFFER_TYPE_HANDLE: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle is not implement", __func__); - err = OMX_ErrorBadParameter; - break; - } - - case BUFFER_TYPE_DYNAMIC_HANDLE: { - int eFence = buffer.fenceFd; - if (eFence > 0) { - ; // sync_wait(eFence, 5); - } - err = OMX_ErrorNone; - break; - } - default: { - err = OMX_ErrorUndefined; - break; - } + err = codecBuffer->EmptyOmxBuffer(buffer, *bufferHdrType); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s EmptyOmxBuffer err [%{public}d]", __func__, err); + return err; } - if (err == OMX_ErrorNone) { - bufferHdrType->nOffset = buffer.offset; - bufferHdrType->nFilledLen = buffer.filledLen; - bufferHdrType->nFlags = buffer.flag; - err = OMX_EmptyThisBuffer((OMX_HANDLETYPE)comp_, bufferHdrType); - } + err = OMX_EmptyThisBuffer((OMX_HANDLETYPE)comp_, bufferHdrType); return err; } @@ -545,50 +451,21 @@ int32_t ComponentNode::FillThisBuffer(struct OmxCodecBuffer &buffer) HDF_LOGE("%{public}s error, comp_ = %{public}p", __func__, comp_); return OMX_ErrorInvalidComponent; } - - CheckBuffer(buffer); - - int32_t err = OMX_ErrorUndefined; + int32_t err = OMX_ErrorBadParameter; OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; - BufferInfoSPtr bufferInfo = nullptr; - if (!GetBufferById(buffer.bufferId, bufferInfo, bufferHdrType)) { + sptr codecBuffer = nullptr; + if (!GetBufferById(buffer.bufferId, codecBuffer, bufferHdrType)) { HDF_LOGE("%{public}s error, GetBufferById return false", __func__); return err; } - switch (bufferInfo->omxCodecBuffer.bufferType) { - case BUFFER_TYPE_AVSHARE_MEM_FD: { - if ((bufferInfo->sharedMem == nullptr) || (bufferInfo->omxCodecBuffer.type != READ_WRITE_TYPE)) { - HDF_LOGE("%{public}s error, pBufferHdrType [0x%{public}p] omxCodecBuffer.type[%{public}d]", __func__, - bufferHdrType, bufferInfo->omxCodecBuffer.type); - } else { - err = OMX_ErrorNone; - } - - break; - } - case BUFFER_TYPE_HANDLE: { - int eFence = buffer.fenceFd; - if (eFence > 0) { - ; // we may sync_wait here// sync_wait(eFence, 5); - } - err = OMX_ErrorUndefined; - break; - } - default: { - HDF_LOGE("%{public}s error, bufferTypeBufferHandle = %{public}d is not implement", __func__, - bufferInfo->omxCodecBuffer.bufferType); - err = OMX_ErrorBadParameter; - break; - } + err = codecBuffer->FillOmxBuffer(buffer, *bufferHdrType); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s FillOmxBuffer err [%{public}d]", __func__, err); + return err; } - if (err == OMX_ErrorNone) { - // check this - bufferHdrType->nOffset = buffer.offset; - bufferHdrType->nFilledLen = buffer.filledLen; - err = OMX_FillThisBuffer((OMX_HANDLETYPE)comp_, bufferHdrType); - } + err = OMX_FillThisBuffer((OMX_HANDLETYPE)comp_, bufferHdrType); return err; } @@ -600,22 +477,11 @@ uint32_t ComponentNode::GenerateBufferId() ++bufferIdCount_; } bufferId = bufferIdCount_; - } while (bufferInfoMap_.find(bufferId) != bufferInfoMap_.end()); + } while (codecBufferMap_.find(bufferId) != codecBufferMap_.end()); return bufferId; } -void ComponentNode::CheckBuffer(struct OmxCodecBuffer &buffer) -{ - if ((buffer.buffer != nullptr) && (buffer.bufferType == BUFFER_TYPE_AVSHARE_MEM_FD) && - (buffer.bufferLen == FD_SIZE)) { - int fd = (int)reinterpret_cast(buffer.buffer); - close(fd); - buffer.buffer = 0; - buffer.bufferLen = 0; - } -} - -BufferInfoSPtr ComponentNode::GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer) +sptr ComponentNode::GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer) { if (buffer == nullptr) { HDF_LOGE("%{public}s buffer is null", __func__); @@ -629,24 +495,19 @@ BufferInfoSPtr ComponentNode::GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer } uint32_t nBufferID = iterHead->second; - auto iter = bufferInfoMap_.find(nBufferID); - if (iter == bufferInfoMap_.end()) { + auto iter = codecBufferMap_.find(nBufferID); + if (iter == codecBufferMap_.end()) { HDF_LOGE("%{public}s can not find bufferInfo by nBufferID = %{public}d", __func__, nBufferID); return nullptr; } - BufferInfoSPtr bufferInfo = iter->second; - if (bufferInfo == nullptr) { - HDF_LOGE("%{public}s pBufferInfo is null", __func__); - return nullptr; - } - - return bufferInfo; + return iter->second; } -bool ComponentNode::GetBufferById(uint32_t bufferId, BufferInfoSPtr &bufferInfo, OMX_BUFFERHEADERTYPE *&bufferHdrType) +bool ComponentNode::GetBufferById(uint32_t bufferId, sptr &codecBuffer, + OMX_BUFFERHEADERTYPE *&bufferHdrType) { - auto iter = bufferInfoMap_.find(bufferId); - if ((iter == bufferInfoMap_.end()) || (iter->second == nullptr)) { + auto iter = codecBufferMap_.find(bufferId); + if ((iter == codecBufferMap_.end()) || (iter->second == nullptr)) { HDF_LOGE("%{public}s error, can not find bufferIndo by bufferID [%{public}d]", __func__, bufferId); return false; } @@ -663,165 +524,9 @@ bool ComponentNode::GetBufferById(uint32_t bufferId, BufferInfoSPtr &bufferInfo, return false; } bufferHdrType = iterHead->first; - bufferInfo = iter->second; + codecBuffer = iter->second; return true; } - -void ComponentNode::ReleaseBufferById(uint32_t bufferId) -{ - auto iter = bufferInfoMap_.find(bufferId); - if ((iter == bufferInfoMap_.end()) || (iter->second == nullptr)) { - HDF_LOGE("%{public}s error, can not find bufferIndo by bufferID [%{public}d]", __func__, bufferId); - return; - } - - auto iterHead = bufferHeaderMap_.begin(); - for (; iterHead != bufferHeaderMap_.end(); iterHead++) { - if (iterHead->second == bufferId) { - break; - } - } - if ((iterHead == bufferHeaderMap_.end()) || (iterHead->first == nullptr)) { - HDF_LOGE("%{public}s error, can not find bufferHeaderType by bufferID [%{public}d] or iterHead->first is null", - __func__, bufferId); - return; - } - BufferInfoSPtr bufferInfo = iter->second; - bufferInfoMap_.erase(iter); - bufferHeaderMap_.erase(iterHead); - bufferInfo = nullptr; -} - -int32_t ComponentNode::UseSharedBuffer(struct OmxCodecBuffer &omxCodecBuffer, uint32_t portIndex) -{ - OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; - int32_t err = OMX_ErrorUndefined; - if (omxCodecBuffer.bufferLen != FD_SIZE) { - HDF_LOGE("%{public}s error, omxCodecBuffer.bufferLen = %{public}d ", __func__, omxCodecBuffer.bufferLen); - return err; - } - - int shardFd = (int)reinterpret_cast(omxCodecBuffer.buffer); - if (shardFd < 0) { - HDF_LOGE("%{public}s error, shardFd < 0", __func__); - return err; - } - - int size = AshmemGetSize(shardFd); - HDF_LOGI("%{public}s , shardFd = %{public}d, size = %{public}d", __func__, shardFd, size); - std::shared_ptr sharedMem = std::make_shared(shardFd, size); - // check READ/WRITE - bool mapd = false; - if (omxCodecBuffer.type == READ_WRITE_TYPE) { - mapd = sharedMem->MapReadAndWriteAshmem(); - } else { - mapd = sharedMem->MapReadOnlyAshmem(); - } - - if (!mapd) { - HDF_LOGE("%{public}s error, MapReadAndWriteAshmem or MapReadOnlyAshmem return false", __func__); - return err; - } - - err = OMX_AllocateBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, omxCodecBuffer.allocLen); - if (err != OMX_ErrorNone) { - HDF_LOGE("%{public}s error, OMX_AllocateBuffer failed", __func__); - sharedMem->UnmapAshmem(); - sharedMem->CloseAshmem(); - sharedMem = nullptr; - return err; - } - SaveBufferInfo(omxCodecBuffer, bufferHdrType, sharedMem); - - return err; -} -int32_t ComponentNode::UseHandleBuffer(struct OmxCodecBuffer &omxCodecBuffer, uint32_t portIndex) -{ - OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; - int32_t err = OMX_ErrorUndefined; - - if (sizeof(BufferHandle) != omxCodecBuffer.bufferLen) { - HDF_LOGE("%{public}s error, BufferHandle size = %{public}zu, omxBuffer.ptrSize = %{public}d ", __func__, - sizeof(BufferHandle), omxCodecBuffer.bufferLen); - return err; - } - - BufferHandle *bufferHandle = (BufferHandle *)omxCodecBuffer.buffer; - (void)bufferHandle; - // bufferHandle trans to native_handle_t, then use native_handle_t in omx - err = OMX_UseBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, omxCodecBuffer.allocLen, nullptr); - if (err != OMX_ErrorNone) { - HDF_LOGE("%{public}s error, OMX_UseBuffer ret[%{public}d]", __func__, err); - } - HDF_LOGW("%{public}s error, bufferType BufferHandle is not implement", __func__); - // bufferID - SaveBufferInfo(omxCodecBuffer, bufferHdrType, nullptr); - return err; -} - -int32_t ComponentNode::UseDynaHandleBuffer(struct OmxCodecBuffer &omxCodecBuffer, uint32_t portIndex) -{ - OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; - int32_t err = OMX_ErrorUndefined; - // check: buffer need alloc 8 Bytes - // type 4 Bytes,native_handle 4 Bytes - err = OMX_UseBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, omxCodecBuffer.allocLen, nullptr); - if (err != OMX_ErrorNone) { - HDF_LOGE("%{public}s error, OMX_UseBuffer ret [%{public}d]", __func__, err); - } - HDF_LOGW("%{public}s error, bufferTypeBufferHandle is not implement", __func__); - // bufferID - SaveBufferInfo(omxCodecBuffer, bufferHdrType, nullptr); - return err; -} - -int32_t ComponentNode::EmptySharedBuffer(struct OmxCodecBuffer &buffer, BufferInfoSPtr bufferInfo, - OMX_BUFFERHEADERTYPE *bufferHdrType) -{ - void *sharedPtr = const_cast(bufferInfo->sharedMem->ReadFromAshmem(buffer.filledLen, buffer.offset)); - if (!sharedPtr) { - HDF_LOGE("%{public}s error, omxBuffer.length [%{public}d omxBuffer.offset[%{public}d]", __func__, - buffer.filledLen, buffer.offset); - return OMX_ErrorUndefined; - } - auto ret = memcpy_s(bufferHdrType->pBuffer + buffer.offset, buffer.allocLen - buffer.offset, sharedPtr, - buffer.filledLen); - if (ret != EOK) { - HDF_LOGE("%{public}s error, memcpy_s ret [%{public}d", __func__, ret); - return OMX_ErrorUndefined; - } - -#ifdef NODE_DEBUG - (void)fwrite(sharedPtr, 1, buffer->filledLen, fp_in); - (void)fflush(fp_in); -#endif - - return OMX_ErrorNone; -} - -void ComponentNode::SaveBufferInfo(struct OmxCodecBuffer &omxCodecBuffer, OMX_BUFFERHEADERTYPE *bufferHdrType, - std::shared_ptr sharedMem) -{ - BufferInfoSPtr bufferInfo = std::make_shared(); - uint32_t bufferId = GenerateBufferId(); - // set bufferId - omxCodecBuffer.bufferId = bufferId; - omxCodecBuffer.version = bufferHdrType->nVersion; - omxCodecBuffer.allocLen = bufferHdrType->nAllocLen; - omxCodecBuffer.filledLen = bufferHdrType->nFilledLen; - omxCodecBuffer.offset = bufferHdrType->nOffset; - omxCodecBuffer.pts = bufferHdrType->nTimeStamp; - omxCodecBuffer.flag = bufferHdrType->nFlags; - - bufferInfo->omxCodecBuffer = omxCodecBuffer; - bufferInfo->omxCodecBuffer.buffer = 0; - bufferInfo->omxCodecBuffer.bufferLen = 0; - bufferInfo->sharedMem = sharedMem; - uint32_t bufferIdTemp = bufferId; - bufferInfoMap_.insert(std::make_pair(std::move(bufferId), std::move(bufferInfo))); - bufferHeaderMap_.insert( - std::make_pair(std::move(bufferHdrType), std::move(bufferIdTemp))); -} } // namespace Omx } // namespace Codec } // namespace OHOS \ No newline at end of file diff --git a/codec/hal/v2.0/hdi_impl/src/icodec_buffer.cpp b/codec/hal/v2.0/hdi_impl/src/icodec_buffer.cpp new file mode 100644 index 0000000000..55fa30c1d9 --- /dev/null +++ b/codec/hal/v2.0/hdi_impl/src/icodec_buffer.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "icodec_buffer.h" +#include +#include +#include "codec_dyna_buffer.h" +#include "codec_handle_buffer.h" +#include "codec_share_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +ICodecBuffer::ICodecBuffer(struct OmxCodecBuffer &codecBuffer) +{ + codecBuffer_ = codecBuffer; +} +ICodecBuffer::~ICodecBuffer() +{} + +sptr ICodecBuffer::CreateCodeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + sptr buffer = nullptr; + switch (codecBuffer.bufferType) { + case BUFFER_TYPE_AVSHARE_MEM_FD: + buffer = CodecShareBuffer::Create(codecBuffer); + break; + case BUFFER_TYPE_HANDLE: + buffer = CodecHandleBuffer::Create(codecBuffer); + break; + case BUFFER_TYPE_DYNAMIC_HANDLE: + buffer = CodecDynaBuffer::Create(codecBuffer); + break; + default: + HDF_LOGE("%s: bufferType[%{public}d] is unexpected", __func__, codecBuffer.bufferType); + break; + } + return buffer; +} + +sptr ICodecBuffer::AllocateCodecBuffer(struct OmxCodecBuffer &codecBuffer) +{ + sptr buffer = nullptr; + switch (codecBuffer.bufferType) { + case BUFFER_TYPE_AVSHARE_MEM_FD: + buffer = CodecShareBuffer::Allocate(codecBuffer); + break; + default: + HDF_LOGE("%s: bufferType[%{public}d] is unexpected", __func__, codecBuffer.bufferType); + break; + } + return buffer; +} + +struct OmxCodecBuffer &ICodecBuffer::GetCodecBuffer() +{ + return codecBuffer_; +} + +void ICodecBuffer::SetBufferId(int32_t bufferId) +{ + codecBuffer_.bufferId = bufferId; +} + +bool ICodecBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (codecBuffer_.type != codecBuffer.type) { + HDF_LOGE("%{public}s :input buffer type [%{public}d], but expect type [%{public}d]", __func__, + codecBuffer.bufferType, codecBuffer_.bufferType); + return false; + } + return true; +} + +int32_t ICodecBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + omxBuffer.nOffset = codecBuffer.offset; + omxBuffer.nFilledLen = codecBuffer.filledLen; + return HDF_SUCCESS; +} + +int32_t ICodecBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + omxBuffer.nOffset = codecBuffer.offset; + omxBuffer.nFilledLen = codecBuffer.filledLen; + omxBuffer.nFlags = codecBuffer.flag; + omxBuffer.nTimeStamp = codecBuffer.pts; + return HDF_SUCCESS; +} + +int32_t ICodecBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + codecBuffer_.offset = omxBuffer.nOffset; + codecBuffer_.filledLen = omxBuffer.nFilledLen; + return HDF_SUCCESS; +} + +int32_t ICodecBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + codecBuffer_.offset = omxBuffer.nOffset; + codecBuffer_.filledLen = omxBuffer.nFilledLen; + codecBuffer_.flag = omxBuffer.nFlags; + codecBuffer_.pts = omxBuffer.nTimeStamp; + return HDF_SUCCESS; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file -- Gitee