diff --git a/codec/BUILD.gn b/codec/BUILD.gn index 7d842d3e8501eaba3449edb734e321a2b990045b..0db678a1227e31bc6f72aca34484cb0af8145a2f 100644 --- a/codec/BUILD.gn +++ b/codec/BUILD.gn @@ -18,5 +18,6 @@ group("hdf_media_codec") { deps = [ "hal:codec_hdi_omx", "hal/config:codec_capability_config", + "hal/v1.0/buffer_manager:codec_buffer_manager", ] } diff --git a/codec/bundle.json b/codec/bundle.json index 86bd6635f6f7751ade8b1a203c5c2a644ff2abfc..efe7d1a2286e1b9d5efc7aee03ac0fa8f7d92608 100755 --- a/codec/bundle.json +++ b/codec/bundle.json @@ -24,6 +24,9 @@ "//drivers/peripheral/codec/hdi_service:codec_client", "//drivers/peripheral/codec/hdi_service:codec_service", "//drivers/peripheral/codec:hdf_media_codec" + ], + "test": [ + "//drivers/peripheral/codec/test:hdf_test_media_codec" ] } } diff --git a/codec/hal/BUILD.gn b/codec/hal/BUILD.gn index 78169225935497204dc04258b6914b6817ceabec..d0c09122b1521cf954ba85d8d12730b3991f8f7f 100644 --- a/codec/hal/BUILD.gn +++ b/codec/hal/BUILD.gn @@ -16,7 +16,6 @@ import("//drivers/adapter/uhdf2/uhdf.gni") ohos_shared_library("libcodec_hdi_omx_server") { include_dirs = [ - "//drivers/adapter/uhdf2/include/hdi", "//drivers/peripheral/codec/interfaces/include", "//drivers/peripheral/codec/hal/include", "//third_party/openmax/api/1.1.2", diff --git a/codec/hal/config/BUILD.gn b/codec/hal/config/BUILD.gn index c543fb03b361c1d04cf4f0f459a11ca24ef40c35..c38c685fe1e14e130de1022baef426d7d16e83c2 100644 --- a/codec/hal/config/BUILD.gn +++ b/codec/hal/config/BUILD.gn @@ -38,8 +38,9 @@ ohos_shared_library("libcodec_capability_config") { external_deps = [ "hilog:libhilog" ] } + install_images = [ chipset_base_dir ] subsystem_name = "hdf" - part_name = "hdf" + part_name = "codec_device_driver" } group("codec_capability_config") { diff --git a/codec/hal/config/capability_config/src/codec_capability_config.c b/codec/hal/config/capability_config/src/codec_capability_config.c index 883afc1b6c98870796c7b5d43a96f4d708f368a3..c7ca4f35f649af5a5c60a59662b1b6de039bebc7 100644 --- a/codec/hal/config/capability_config/src/codec_capability_config.c +++ b/codec/hal/config/capability_config/src/codec_capability_config.c @@ -299,6 +299,12 @@ static int32_t CodecCapabilityBind(struct HdfDeviceObject *deviceObject) static struct IDeviceIoService deviceIoService = { .Dispatch = CodecCapabilityDispatch, }; + + int ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, "ohos.hdi.codec_service"); + if (ret != HDF_SUCCESS) { + HDF_LOGE("failed to set interface desc"); + return ret; + } deviceObject->service = &deviceIoService; return HDF_SUCCESS; diff --git a/codec/hal/v1.0/buffer_manager/BUILD.gn b/codec/hal/v1.0/buffer_manager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..fc6e3b1b547227b5161fa78f4c5cc7de024dd9f2 --- /dev/null +++ b/codec/hal/v1.0/buffer_manager/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 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. + +import("//build/ohos.gni") +import("//drivers/adapter/uhdf2/uhdf.gni") + +ohos_shared_library("libcodec_buffer_manager") { + include_dirs = [ + "//drivers/peripheral/codec/interfaces/include", + "//drivers/peripheral/codec/hal/v1.0/buffer_manager/include", + ] + sources = [ + "src/buffer_manager.cpp", + "src/buffer_manager_wrapper.cpp", + ] + + if (is_standard_system) { + external_deps = [ + "device_driver_framework:libhdf_host", + "device_driver_framework:libhdf_ipc_adapter", + "device_driver_framework:libhdf_utils", + "device_driver_framework:libhdi", + "hiviewdfx_hilog_native:libhilog", + "utils_base:utils", + ] + } else { + external_deps = [ "hilog:libhilog" ] + } + + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "codec_device_driver" +} + +group("codec_buffer_manager") { + deps = [ ":libcodec_buffer_manager" ] +} diff --git a/codec/hal/v1.0/buffer_manager/include/buffer_manager.h b/codec/hal/v1.0/buffer_manager/include/buffer_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..415aa7d99c3f6104637ce02fc94bbc2f78d397ae --- /dev/null +++ b/codec/hal/v1.0/buffer_manager/include/buffer_manager.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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 BUFFER_MANAGER_H +#define BUFFER_MANAGER_H + +#include +#include +#include +#include "codec_type.h" +#include "osal_mutex.h" + +#define CODEC_STATUS_RUN 0 +#define CODEC_STATUS_STOPPED 1 + +#define HDF_NANO_UNITS 1000000000 + +template +class BufferManager { +public: + BufferManager(); + ~BufferManager(); + void Stop(); + T* GetBuffer(uint32_t timeoutMs, bool isChecking); + T* GetUsedBuffer(uint32_t timeoutMs, bool isChecking); + void PutBuffer(T *info); + void PutUsedBuffer(T *info); + +private: + void ConstructTimespec(struct timespec *time, uint32_t timeoutMs); + T* PollBufferQueue(bool isChecking); + T* PollUsedBufferQueue(bool isChecking); + + int32_t status; + OsalMutex bufferQueueLock; + OsalMutex usedBufferQueueLock; + pthread_cond_t inputCond = PTHREAD_COND_INITIALIZER; + pthread_cond_t outputCond = PTHREAD_COND_INITIALIZER; + std::queue bufferQueue; + std::queue usedBufferQueue; +}; + +#endif // BUFFER_MANAGER_H diff --git a/codec/hal/v1.0/buffer_manager/include/buffer_manager_iface.h b/codec/hal/v1.0/buffer_manager/include/buffer_manager_iface.h new file mode 100644 index 0000000000000000000000000000000000000000..d402364ef900a4739e00906089e5f38f8699cd12 --- /dev/null +++ b/codec/hal/v1.0/buffer_manager/include/buffer_manager_iface.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 BUFFER_MANAGER_IF_H +#define BUFFER_MANAGER_IF_H + +#include "hdf_base.h" +#include "buffer_manager_wrapper.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef struct BufferManagerWrapper* (*GetBufferManagerType)(void); +typedef void (*DeleteBufferManagerType)(struct BufferManagerWrapper **ppBufferManager); + +struct BufferManagerIf { + GetBufferManagerType GetBufferManager; + DeleteBufferManagerType DeleteBufferManager; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif // BUFFER_MANAGER_IF_H \ No newline at end of file diff --git a/codec/hal/v1.0/buffer_manager/include/buffer_manager_wrapper.h b/codec/hal/v1.0/buffer_manager/include/buffer_manager_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..4c46f7ffd4faf87bf94fe2744165364680a6d429 --- /dev/null +++ b/codec/hal/v1.0/buffer_manager/include/buffer_manager_wrapper.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 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 BUFFER_MANAGER_WRAPPER_H +#define BUFFER_MANAGER_WRAPPER_H + +#include "codec_type.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct BufferManagerWrapper { + void *inputBufferManager; + void *outputBufferManager; + + bool (*IsInputDataBufferReady)(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs); + InputInfo* (*GetInputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs); + InputInfo* (*GetUsedInputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs); + void (*PutInputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, InputInfo *info); + void (*PutUsedInputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, InputInfo *info); + + bool (*IsUsedOutputDataBufferReady)(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs); + OutputInfo* (*GetOutputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs); + OutputInfo* (*GetUsedOutputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs); + void (*PutOutputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, OutputInfo *info); + void (*PutUsedOutputDataBuffer)(struct BufferManagerWrapper *bufferManagerWrapper, OutputInfo *info); +}; + +struct BufferManagerWrapper* GetBufferManager(void); +void DeleteBufferManager(struct BufferManagerWrapper **ppBufferManager); + +#ifdef __cplusplus +} +#endif +#endif // BUFFER_MANAGER_WRAPPER_H diff --git a/codec/hal/v1.0/buffer_manager/src/buffer_manager.cpp b/codec/hal/v1.0/buffer_manager/src/buffer_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5a7d471cbfe26dab8ba9efc723c96abfa06b384 --- /dev/null +++ b/codec/hal/v1.0/buffer_manager/src/buffer_manager.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 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 "buffer_manager.h" +#include + +template +BufferManager::BufferManager() +{ + OsalMutexInit(&bufferQueueLock); + OsalMutexInit(&usedBufferQueueLock); +} + +template +BufferManager::~BufferManager() +{ + OsalMutexDestroy(&bufferQueueLock); + OsalMutexDestroy(&usedBufferQueueLock); +} + +template +void BufferManager::Stop() +{ + status = CODEC_STATUS_STOPPED; +} + +template +T* BufferManager::GetBuffer(uint32_t timeoutMs, bool isChecking) +{ + OsalMutexLock(&bufferQueueLock); + T *inputData = nullptr; + inputData = PollBufferQueue(isChecking); + if (inputData == nullptr) { + if (timeoutMs == HDF_WAIT_FOREVER) { + // release lock and wait here, and check again later when notified + pthread_cond_wait(&inputCond, (pthread_mutex_t *)bufferQueueLock.realMutex); + inputData = PollBufferQueue(isChecking); + } else if (timeoutMs > 0) { + struct timespec time = {0}; + ConstructTimespec(&time, timeoutMs); + // release lock and wait here, and check again later when notified or timeout + pthread_cond_timedwait(&inputCond, (pthread_mutex_t *)bufferQueueLock.realMutex, &time); + inputData = PollBufferQueue(isChecking); + } + } + OsalMutexUnlock(&bufferQueueLock); + + return inputData; +} + +template +T* BufferManager::GetUsedBuffer(uint32_t timeoutMs, bool isChecking) +{ + OsalMutexLock(&usedBufferQueueLock); + T *outputData = nullptr; + outputData = PollUsedBufferQueue(isChecking); + if (outputData == nullptr) { + if (timeoutMs == HDF_WAIT_FOREVER) { + // release lock and wait here, and check again later when notified + pthread_cond_wait(&outputCond, (pthread_mutex_t *)usedBufferQueueLock.realMutex); + outputData = PollUsedBufferQueue(isChecking); + } else if (timeoutMs > 0) { + struct timespec time = {0}; + ConstructTimespec(&time, timeoutMs); + // release lock and wait here, and check again later when notified or timeout + pthread_cond_timedwait(&outputCond, (pthread_mutex_t *)usedBufferQueueLock.realMutex, &time); + outputData = PollUsedBufferQueue(isChecking); + } + } + OsalMutexUnlock(&usedBufferQueueLock); + + return outputData; +} + +template +void BufferManager::ConstructTimespec(struct timespec *time, uint32_t timeoutMs) +{ + memset_s(time, sizeof(timespec), 0, sizeof(timespec)); + clock_gettime(CLOCK_REALTIME, time); + time->tv_sec += timeoutMs / HDF_KILO_UNIT; + time->tv_nsec += (timeoutMs % HDF_KILO_UNIT) * HDF_KILO_UNIT * HDF_KILO_UNIT; + if (time->tv_nsec >= HDF_NANO_UNITS) { + time->tv_nsec -= HDF_NANO_UNITS; + time->tv_sec += 1; + } +} + +template +T* BufferManager::PollBufferQueue(bool isChecking) +{ + T *info = nullptr; + if (bufferQueue.size() == 0) { + return nullptr; + } + info = bufferQueue.front(); + if (!isChecking) { + bufferQueue.pop(); + } + return info; +} + +template +T* BufferManager::PollUsedBufferQueue(bool isChecking) +{ + T *info = nullptr; + if (usedBufferQueue.size() == 0) { + return nullptr; + } + info = usedBufferQueue.front(); + if (!isChecking) { + usedBufferQueue.pop(); + } + return info; +} + +template +void BufferManager::PutBuffer(T *info) +{ + OsalMutexLock(&bufferQueueLock); + bufferQueue.push(info); + pthread_cond_signal(&inputCond); + OsalMutexUnlock(&bufferQueueLock); +} + +template +void BufferManager::PutUsedBuffer(T *info) +{ + OsalMutexLock(&usedBufferQueueLock); + usedBufferQueue.push(info); + pthread_cond_signal(&outputCond); + OsalMutexUnlock(&usedBufferQueueLock); +} + +template class BufferManager; +template class BufferManager; diff --git a/codec/hal/v1.0/buffer_manager/src/buffer_manager_wrapper.cpp b/codec/hal/v1.0/buffer_manager/src/buffer_manager_wrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c85d6622b4bdcac64d1dfbf34d628970f0bf72fa --- /dev/null +++ b/codec/hal/v1.0/buffer_manager/src/buffer_manager_wrapper.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 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 "buffer_manager_wrapper.h" +#include "buffer_manager.h" +#include "hdf_log.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +static bool IsInputDataBufferReadyImpl(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs) +{ + if (bufferManagerWrapper == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return false; + } + + InputInfo *buffer = + ((BufferManager*)(bufferManagerWrapper->inputBufferManager))->GetBuffer(timeoutMs, true); + return (buffer != nullptr); +} + +static InputInfo* GetInputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs) +{ + if (bufferManagerWrapper == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return nullptr; + } + + InputInfo *buffer = + ((BufferManager*)(bufferManagerWrapper->inputBufferManager))->GetBuffer(timeoutMs, false); + return buffer; +} + +static InputInfo* GetUsedInputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs) +{ + if (bufferManagerWrapper == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return nullptr; + } + + InputInfo *buffer = + ((BufferManager*)(bufferManagerWrapper->inputBufferManager))->GetUsedBuffer(timeoutMs, false); + return buffer; +} + +static void PutInputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, InputInfo *info) +{ + if (bufferManagerWrapper == nullptr || info == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return; + } + + ((BufferManager*)(bufferManagerWrapper->inputBufferManager))->PutBuffer(info); +} + +static void PutUsedInputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, InputInfo *info) +{ + if (bufferManagerWrapper == nullptr || info == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return; + } + ((BufferManager*)(bufferManagerWrapper->inputBufferManager))->PutUsedBuffer(info); +} + +static bool IsUsedOutputDataBufferReadyImpl(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs) +{ + if (bufferManagerWrapper == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return false; + } + + OutputInfo *buffer = + ((BufferManager*)(bufferManagerWrapper->outputBufferManager))->GetUsedBuffer(timeoutMs, true); + return (buffer != nullptr); +} + +static OutputInfo* GetOutputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs) +{ + if (bufferManagerWrapper == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return nullptr; + } + + OutputInfo *buffer = + ((BufferManager*)(bufferManagerWrapper->outputBufferManager))->GetBuffer(timeoutMs, false); + return buffer; +} + +static OutputInfo* GetUsedOutputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, uint32_t timeoutMs) +{ + if (bufferManagerWrapper == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return nullptr; + } + + OutputInfo *buffer = + ((BufferManager*)(bufferManagerWrapper->outputBufferManager))->GetUsedBuffer(timeoutMs, false); + return buffer; +} + +static void PutOutputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, OutputInfo *info) +{ + if (bufferManagerWrapper == nullptr || info == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return; + } + + ((BufferManager*)(bufferManagerWrapper->outputBufferManager))->PutBuffer(info); +} + +static void PutUsedOutputDataBufferImpl(struct BufferManagerWrapper *bufferManagerWrapper, OutputInfo *info) +{ + if (bufferManagerWrapper == nullptr || info == nullptr) { + HDF_LOGE("%{public}s: invalid params!", __func__); + return; + } + ((BufferManager*)(bufferManagerWrapper->outputBufferManager))->PutUsedBuffer(info); +} + +static void ConstructBufferManager(struct BufferManagerWrapper *bufferManager) +{ + bufferManager->IsInputDataBufferReady = IsInputDataBufferReadyImpl; + bufferManager->GetInputDataBuffer = GetInputDataBufferImpl; + bufferManager->GetUsedInputDataBuffer = GetUsedInputDataBufferImpl; + bufferManager->PutInputDataBuffer = PutInputDataBufferImpl; + bufferManager->PutUsedInputDataBuffer = PutUsedInputDataBufferImpl; + bufferManager->IsUsedOutputDataBufferReady = IsUsedOutputDataBufferReadyImpl; + bufferManager->GetOutputDataBuffer = GetOutputDataBufferImpl; + bufferManager->GetUsedOutputDataBuffer = GetUsedOutputDataBufferImpl; + bufferManager->PutOutputDataBuffer = PutOutputDataBufferImpl; + bufferManager->PutUsedOutputDataBuffer = PutUsedOutputDataBufferImpl; +} + +struct BufferManagerWrapper* GetBufferManager(void) +{ + struct BufferManagerWrapper *bufferManager = new struct BufferManagerWrapper; + bufferManager->inputBufferManager = new BufferManager(); + bufferManager->outputBufferManager = new BufferManager(); + ConstructBufferManager(bufferManager); + return bufferManager; +} + +void DeleteBufferManager(struct BufferManagerWrapper **ppBufferManager) +{ + delete (BufferManager*)((*ppBufferManager)->inputBufferManager); + delete (BufferManager*)((*ppBufferManager)->outputBufferManager); + delete *ppBufferManager; +} + +#ifdef __cplusplus +} +#endif diff --git a/codec/hal/v1.0/codec_instance/include/codec_instance.h b/codec/hal/v1.0/codec_instance/include/codec_instance.h new file mode 100644 index 0000000000000000000000000000000000000000..37d5ca59374bb69da0b22ad38c2d88f2170dbcce --- /dev/null +++ b/codec/hal/v1.0/codec_instance/include/codec_instance.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 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_INSTANCE_H +#define CODEC_INSTANCE_H + +#include +#include +#include "buffer_manager_iface.h" +#include "buffer_manager_wrapper.h" +#include "codec_oem_if.h" +#include "share_mem.h" + +#define MAX_BUFFER_NUM 64 +#define QUEUE_TIME_OUT 10 + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef enum { + CODEC_STATUS_IDLE, + CODEC_STATUS_STARTED, + CODEC_STATUS_STOPED, +} CodecStatus; + +struct CodecInstance { + pthread_t task; + ShareMemory inputBuffers[MAX_BUFFER_NUM]; + ShareMemory outputBuffers[MAX_BUFFER_NUM]; + int32_t inputBuffersCount; + int32_t outputBuffersCount; + InputInfo *inputInfos[MAX_BUFFER_NUM]; + OutputInfo *outputInfos[MAX_BUFFER_NUM]; + int32_t inputInfoCount; + int32_t outputInfoCount; + + void *oemLibHandle; + struct CodecOemIf *codecOemIface; + + void *bufferManagerLibHandle; + struct BufferManagerIf *bufferManagerIface; + struct BufferManagerWrapper *bufferManagerWrapper; + + CODEC_HANDLETYPE handle; + CodecType codecType; + volatile CodecStatus codecStatus; + CodecCallback defaultCb; + bool hasCallback; +}; + +struct CodecInstance* GetCodecInstance(void); +void InitCodecInstance(struct CodecInstance *instance); +void AddInputShm(struct CodecInstance *instance, CodecBufferInfo *bufferInfo); +void AddOutputShm(struct CodecInstance *instance, CodecBufferInfo *bufferInfo); +ShareMemory* GetInputShm(struct CodecInstance *instance, int32_t id); +ShareMemory* GetOutputShm(struct CodecInstance *instance, int32_t id); +int32_t GetFdById(struct CodecInstance *instance, int32_t id); +void ReleaseInputShm(struct CodecInstance *instance); +void ReleaseOutputShm(struct CodecInstance *instance); +void AddInputInfo(struct CodecInstance *instance, InputInfo *info); +void AddOutputInfo(struct CodecInstance *instance, OutputInfo *info); +InputInfo* GetInputInfo(struct CodecInstance *instance, int32_t id); +OutputInfo* GetOutputInfo(struct CodecInstance *instance, int32_t id); +void ReleaseInputInfo(struct CodecInstance *instance); +void ReleaseOutputInfo(struct CodecInstance *instance); +void ResetBuffers(struct CodecInstance *instance); +void RunCodecInstance(struct CodecInstance *instance); +void StopCodecInstance(struct CodecInstance *instance); +void DestroyCodecInstance(struct CodecInstance *instance); + +#ifdef __cplusplus +} +#endif +#endif // CODEC_INSTANCE_H diff --git a/codec/hal/v1.0/codec_instance/src/codec_instance.c b/codec/hal/v1.0/codec_instance/src/codec_instance.c new file mode 100644 index 0000000000000000000000000000000000000000..014fe3c0eeb7908f8c791e87800abfaec7accfcd --- /dev/null +++ b/codec/hal/v1.0/codec_instance/src/codec_instance.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 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_instance.h" +#include +#include +#include "hdf_log.h" +#include "osal_mem.h" + +#define HDF_LOG_TAG codec_hdi_instance + +#define CODEC_OEM_INTERFACE_LIB_NAME "libcodec_oem_interface.z.so" +#define CODEC_BUFFER_MANAGER_LIB_NAME "libcodec_buffer_manager.z.so" + +static void InitCodecOemIf(struct CodecInstance *instance) +{ + if (instance == NULL || instance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + + void *libHandle = dlopen(CODEC_OEM_INTERFACE_LIB_NAME, RTLD_NOW); + if (libHandle == NULL) { + HDF_LOGE("%{public}s: lib %{public}s dlopen failed, error code[%{public}s]", + __func__, CODEC_OEM_INTERFACE_LIB_NAME, dlerror()); + return; + } + + struct CodecOemIf *iface = instance->codecOemIface; + iface->CodecInit = (CodecInitType)dlsym(libHandle, "CodecInit"); + iface->CodecDeinit = (CodecDeinitType)dlsym(libHandle, "CodecDeinit"); + iface->CodecCreate = (CodecCreateType)dlsym(libHandle, "CodecCreate"); + iface->CodecDestroy = (CodecDestroyType)dlsym(libHandle, "CodecDestroy"); + iface->CodecSetParameter = (CodecSetParameterType)dlsym(libHandle, "CodecSetParameter"); + iface->CodecGetParameter = (CodecGetParameterType)dlsym(libHandle, "CodecGetParameter"); + iface->CodecStart = (CodecStartType)dlsym(libHandle, "CodecStart"); + iface->CodecStop = (CodecStopType)dlsym(libHandle, "CodecStop"); + iface->CodecFlush = (CodecFlushType)dlsym(libHandle, "CodecFlush"); + iface->CodecSetCallback = (CodecSetCallbackType)dlsym(libHandle, "CodecSetCallback"); + iface->CodecDecode = (CodecDecodeType)dlsym(libHandle, "CodecDecode"); + iface->CodecEncode = (CodecEncodeType)dlsym(libHandle, "CodecEncode"); + iface->CodecEncodeHeader = (CodecEncodeHeaderType)dlsym(libHandle, "CodecEncodeHeader"); + + instance->oemLibHandle = libHandle; +} + +static void InitBufferManagerIf(struct CodecInstance *instance) +{ + if (instance == NULL || instance->bufferManagerIface == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + + void *libHandle = dlopen(CODEC_BUFFER_MANAGER_LIB_NAME, RTLD_NOW); + if (libHandle == NULL) { + HDF_LOGE("%{public}s: lib %{public}s dlopen failed, error code[%{public}s]", + __func__, CODEC_BUFFER_MANAGER_LIB_NAME, dlerror()); + return; + } + + struct BufferManagerIf *iface = instance->bufferManagerIface; + iface->GetBufferManager = (GetBufferManagerType)dlsym(libHandle, "GetBufferManager"); + iface->DeleteBufferManager = (DeleteBufferManagerType)dlsym(libHandle, "DeleteBufferManager"); + if (iface->GetBufferManager != NULL) { + HDF_LOGI("%{public}s: dlsym ok", __func__); + instance->bufferManagerWrapper = iface->GetBufferManager(); + } else { + HDF_LOGE("%{public}s: lib %{public}s dlsym failed, error code[%{public}s]", + __func__, CODEC_BUFFER_MANAGER_LIB_NAME, dlerror()); + } + + instance->bufferManagerLibHandle = libHandle; +} + +static int32_t WaitForBufferData(struct CodecInstance *instance, CodecBufferInfo *outputDataBuffer, + OutputInfo *outputData) +{ + struct BufferManagerWrapper *bmWrapper = instance->bufferManagerWrapper; + OutputInfo *output = NULL; + while (instance->codecStatus == CODEC_STATUS_STARTED) { + if (bmWrapper->IsInputDataBufferReady(bmWrapper, QUEUE_TIME_OUT) + && bmWrapper->IsUsedOutputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)) { + output = bmWrapper->GetUsedOutputDataBuffer(bmWrapper, QUEUE_TIME_OUT); + if (output != NULL) { + memset_s(outputDataBuffer, sizeof(CodecBufferInfo), 0, sizeof(CodecBufferInfo)); + outputDataBuffer->type = BUFFER_TYPE_VIRTUAL; + outputDataBuffer->addr = GetOutputShm(instance, output->buffers->offset)->virAddr; + outputDataBuffer->size = output->buffers->size; + outputDataBuffer->offset = output->buffers->offset; + memset_s(outputData, sizeof(OutputInfo), 0, sizeof(OutputInfo)); + outputData->buffers = outputDataBuffer; + outputData->bufferCnt = 1; + break; + } + } + } + return HDF_SUCCESS; +} + +static void *CodecTaskThread(void *arg) +{ + if (arg == NULL) { + HDF_LOGE("%{public}s: Invalid arg, exit CodecTaskThread!", __func__); + return NULL; + } + struct CodecInstance *instance = (struct CodecInstance *)arg; + struct BufferManagerWrapper *bmWrapper = instance->bufferManagerWrapper; + if (bmWrapper == NULL) { + HDF_LOGE("%{public}s: BufferManager not ready!", __func__); + return NULL; + } + HDF_LOGI("%{public}s: CodecTaskThread start!", __func__); + + CodecBufferInfo inputDataBuffer; + InputInfo inputData; + CodecBufferInfo outputDataBuffer; + OutputInfo outputData; + InputInfo *input = NULL; + int32_t ret; + + if (WaitForBufferData(instance, &outputDataBuffer, &outputData) != HDF_SUCCESS) { + return NULL; + } + + while (instance->codecStatus == CODEC_STATUS_STARTED) { + if (!bmWrapper->IsInputDataBufferReady(bmWrapper, QUEUE_TIME_OUT)) { + continue; + } + + input = bmWrapper->GetInputDataBuffer(bmWrapper, QUEUE_TIME_OUT); + if (input == NULL) { + continue; + } + + memset_s(&inputDataBuffer, sizeof(CodecBufferInfo), 0, sizeof(CodecBufferInfo)); + inputDataBuffer.type = BUFFER_TYPE_VIRTUAL; + inputDataBuffer.addr = GetInputShm(instance, input->buffers->offset)->virAddr; + inputDataBuffer.size = input->buffers->size; + inputDataBuffer.offset = input->buffers->offset; + memset_s(&inputData, sizeof(InputInfo), 0, sizeof(InputInfo)); + inputData.buffers = &inputDataBuffer; + inputData.bufferCnt = 1; + inputData.flag = input->flag; + + if (instance->codecType == VIDEO_DECODER) { + ret = instance->codecOemIface->CodecDecode(instance->handle, inputData, outputData, QUEUE_TIME_OUT); + } else if (instance->codecType == VIDEO_ENCODER) { + ret = instance->codecOemIface->CodecEncode(instance->handle, inputData, outputData, QUEUE_TIME_OUT); + } + if (ret == HDF_SUCCESS || (outputData.flag & STREAM_FLAG_EOS)) { + HDF_LOGI("%{public}s: output reach STREAM_FLAG_EOS!", __func__); + instance->codecStatus = CODEC_STATUS_STOPED; + } + } + + HDF_LOGI("%{public}s: codec task thread finished!", __func__); + return NULL; +} + +struct CodecInstance* GetCodecInstance(void) +{ + struct CodecInstance *instance = (struct CodecInstance *)OsalMemCalloc(sizeof(struct CodecInstance)); + if (instance == NULL) { + HDF_LOGE("%{public}s: instance mem alloc failed", __func__); + return NULL; + } + + instance->codecStatus = CODEC_STATUS_IDLE; + instance->hasCallback = false; + return instance; +} + +void InitCodecInstance(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + + instance->codecOemIface = (struct CodecOemIf *)OsalMemCalloc(sizeof(struct CodecOemIf)); + if (instance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: codecOemIface mem alloc failed", __func__); + return; + } + InitCodecOemIf(instance); + instance->bufferManagerIface = (struct BufferManagerIf *)OsalMemAlloc(sizeof(struct BufferManagerIf)); + if (instance->bufferManagerIface == NULL) { + HDF_LOGE("%{public}s: bufferManagerIface mem alloc failed", __func__); + return; + } + InitBufferManagerIf(instance); +} + +void AddInputShm(struct CodecInstance *instance, CodecBufferInfo *bufferInfo) +{ + if (instance == NULL || bufferInfo == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + int32_t count = instance->inputBuffersCount; + instance->inputBuffers[count].id = bufferInfo->offset; + instance->inputBuffers[count].fd = bufferInfo->fd; + instance->inputBuffers[count].size = bufferInfo->size; + OpenShareMemory(&instance->inputBuffers[count]); + instance->inputBuffersCount++; +} + +void AddOutputShm(struct CodecInstance *instance, CodecBufferInfo *bufferInfo) +{ + if (instance == NULL || bufferInfo == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + int32_t count = instance->outputBuffersCount; + instance->outputBuffers[count].id = bufferInfo->offset; + instance->outputBuffers[count].fd = bufferInfo->fd; + instance->outputBuffers[count].size = bufferInfo->size; + OpenShareMemory(&instance->outputBuffers[count]); + instance->outputBuffersCount++; +} + +ShareMemory* GetInputShm(struct CodecInstance *instance, int32_t id) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return NULL; + } + for (int32_t i = 0; i < instance->inputBuffersCount; i++) { + if (instance->inputBuffers[i].id == id) { + return &(instance->inputBuffers[i]); + } + } + return NULL; +} + +ShareMemory* GetOutputShm(struct CodecInstance *instance, int32_t id) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return NULL; + } + for (int32_t i = 0; i < instance->outputBuffersCount; i++) { + if (instance->outputBuffers[i].id == id) { + return &(instance->outputBuffers[i]); + } + } + return NULL; +} + +int32_t GetFdById(struct CodecInstance *instance, int32_t id) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return HDF_FAILURE; + } + int32_t i; + for (i = 0; i < instance->inputBuffersCount; i++) { + if (instance->inputBuffers[i].id == id) { + return instance->inputBuffers[i].fd; + } + } + for (i = 0; i < instance->outputBuffersCount; i++) { + if (instance->outputBuffers[i].id == id) { + return instance->outputBuffers[i].fd; + } + } + return HDF_FAILURE; +} + +void ReleaseInputShm(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + for (int32_t i = 0; i < instance->inputBuffersCount; i++) { + ReleaseShareMemory(&instance->inputBuffers[i]); + } +} +void ReleaseOutputShm(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + for (int32_t i = 0; i < instance->outputBuffersCount; i++) { + ReleaseShareMemory(&instance->outputBuffers[i]); + } +} + +void AddInputInfo(struct CodecInstance *instance, InputInfo *info) +{ + if (instance == NULL || info == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + instance->inputInfos[instance->inputInfoCount] = info; + instance->inputInfoCount++; +} + +void AddOutputInfo(struct CodecInstance *instance, OutputInfo *info) +{ + if (instance == NULL || info == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + instance->outputInfos[instance->outputInfoCount] = info; + instance->outputInfoCount++; +} + +InputInfo* GetInputInfo(struct CodecInstance *instance, int32_t id) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return NULL; + } + for (int32_t i = 0; i < instance->inputInfoCount; i++) { + if (instance->inputInfos[i]->buffers[0].offset == (uint32_t)id) { + return instance->inputInfos[i]; + } + } + return NULL; +} + +OutputInfo* GetOutputInfo(struct CodecInstance *instance, int32_t id) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return NULL; + } + for (int32_t i = 0; i < instance->outputInfoCount; i++) { + if (instance->outputInfos[i]->buffers[0].offset == (uint32_t)id) { + return instance->outputInfos[i]; + } + } + return NULL; +} + +void ReleaseInputInfo(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + InputInfo *info; + for (int32_t i = 0; i < instance->inputInfoCount; i++) { + info = instance->inputInfos[i]; + OsalMemFree(info->buffers); + OsalMemFree(info); + } +} + +void ReleaseOutputInfo(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + OutputInfo *info; + for (int32_t i = 0; i < instance->outputInfoCount; i++) { + info = instance->outputInfos[i]; + OsalMemFree(info->buffers); + OsalMemFree(info); + } +} + +void ResetBuffers(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + int32_t i; + for (i = 0; i< instance->inputBuffersCount; i++) { + ReleaseShareMemory(&instance->inputBuffers[i]); + } + for (i = 0; i< instance->outputBuffersCount; i++) { + ReleaseShareMemory(&instance->outputBuffers[i]); + } + for (i = 0; i< instance->inputInfoCount; i++) { + OsalMemFree(instance->inputInfos[i]); + } + for (i = 0; i< instance->outputInfoCount; i++) { + OsalMemFree(instance->outputInfos[i]); + } + + instance->inputBuffersCount = 0; + instance->outputBuffersCount = 0; + instance->inputInfoCount = 0; + instance->outputInfoCount = 0; +} + +void RunCodecInstance(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + instance->codecStatus = CODEC_STATUS_STARTED; + int32_t ret = pthread_create(&instance->task, NULL, CodecTaskThread, instance); + if (ret != 0) { + HDF_LOGE("%{public}s: run codec task thread failed!", __func__); + } +} + +void StopCodecInstance(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + instance->codecStatus = CODEC_STATUS_STOPED; +} + +void DestroyCodecInstance(struct CodecInstance *instance) +{ + if (instance == NULL) { + HDF_LOGE("%{public}s: Invalid param!", __func__); + return; + } + + instance->codecStatus = CODEC_STATUS_STOPED; + pthread_join(instance->task, NULL); + + ReleaseInputShm(instance); + ReleaseOutputShm(instance); + ReleaseInputInfo(instance); + ReleaseOutputInfo(instance); + + dlclose(instance->oemLibHandle); + if (instance->codecOemIface != NULL) { + OsalMemFree(instance->codecOemIface); + } + instance->bufferManagerIface->DeleteBufferManager(&(instance->bufferManagerWrapper)); + dlclose(instance->bufferManagerLibHandle); + if (instance->bufferManagerIface != NULL) { + OsalMemFree(instance->bufferManagerIface); + } +} diff --git a/codec/hal/v1.0/oem_interface/include/codec_oem_if.h b/codec/hal/v1.0/oem_interface/include/codec_oem_if.h new file mode 100644 index 0000000000000000000000000000000000000000..2db4f1585dd9e27ad12321278b11e197571801c6 --- /dev/null +++ b/codec/hal/v1.0/oem_interface/include/codec_oem_if.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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_OEM_IF_H +#define CODEC_OEM_IF_H + +#include "hdf_base.h" +#include "codec_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef int32_t (*CodecInitType)(void); +typedef int32_t (*CodecDeinitType)(void); +typedef int32_t (*CodecCreateType)(const char* name, const Param *attr, int32_t len, CODEC_HANDLETYPE *handle); +typedef int32_t (*CodecDestroyType)(CODEC_HANDLETYPE handle); +typedef int32_t (*CodecSetPortModeType)(CODEC_HANDLETYPE handle, DirectionType type, BufferMode mode); +typedef int32_t (*CodecSetParameterType)(CODEC_HANDLETYPE handle, const Param *params, int32_t paramCnt); +typedef int32_t (*CodecGetParameterType)(CODEC_HANDLETYPE handle, Param *params, int32_t paramCnt); +typedef int32_t (*CodecStartType)(CODEC_HANDLETYPE handle); +typedef int32_t (*CodecStopType)(CODEC_HANDLETYPE handle); +typedef int32_t (*CodecFlushType)(CODEC_HANDLETYPE handle, DirectionType directType); +typedef int32_t (*CodecSetCallbackType)(CODEC_HANDLETYPE handle, const CodecCallback *cb, UINTPTR instance); +typedef int32_t (*CodecDecodeType)(CODEC_HANDLETYPE handle, InputInfo inputData, OutputInfo outInfo, + uint32_t timeoutMs); +typedef int32_t (*CodecEncodeType)(CODEC_HANDLETYPE handle, InputInfo inputData, OutputInfo outInfo, + uint32_t timeoutMs); +typedef int32_t (*CodecEncodeHeaderType)(CODEC_HANDLETYPE handle, OutputInfo outInfo, uint32_t timeoutMs); + +struct CodecOemIf { + CodecInitType CodecInit; + CodecDeinitType CodecDeinit; + CodecCreateType CodecCreate; + CodecDestroyType CodecDestroy; + CodecSetPortModeType CodecSetPortMode; + CodecSetParameterType CodecSetParameter; + CodecGetParameterType CodecGetParameter; + CodecStartType CodecStart; + CodecStopType CodecStop; + CodecFlushType CodecFlush; + CodecSetCallbackType CodecSetCallback; + CodecDecodeType CodecDecode; + CodecEncodeType CodecEncode; + CodecEncodeHeaderType CodecEncodeHeader; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif // CODEC_OEM_IF_H \ No newline at end of file diff --git a/codec/hal/v1.0/share_mem/include/ashmem_wrapper.h b/codec/hal/v1.0/share_mem/include/ashmem_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..049db0c750a807ade6f0d9f3281be8d3d6a9ffcb --- /dev/null +++ b/codec/hal/v1.0/share_mem/include/ashmem_wrapper.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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 ASHMEM_WRAPPER_H +#define ASHMEM_WRAPPER_H + +#include "hdf_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int32_t AshmemCreateFd(const char *name, int32_t size); +uint8_t* MapAshmemFd(int32_t fd, int32_t size); +void UnmapAshmemFd(uint8_t *addr, int32_t size); +int32_t CloseAshmemFd(int32_t fd); + +#ifdef __cplusplus +} +#endif + +#endif // ASHMEM_WRAPPER_H diff --git a/codec/hal/v1.0/share_mem/include/share_mem.h b/codec/hal/v1.0/share_mem/include/share_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..f2f5efcf4f34b4ed2a0e4fd03a7987e5ddd66b5b --- /dev/null +++ b/codec/hal/v1.0/share_mem/include/share_mem.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 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 SHARE_MEM_H +#define SHARE_MEM_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define STREAM_PACKET_BUFFER_NUM 4 +#define MEDIA_FRAME_BUFFER_NUM 10 + +#define MEM_NAME_LEN 128 + +typedef struct { + char memName[MEM_NAME_LEN]; + int32_t id; + int32_t fd; /**< Transmit fd through ipc for sharing memory */ + int32_t size; + uint8_t *virAddr; /**< Virtual address */ +} ShareMemory; + +int32_t CreateShareMemory(ShareMemory *shareMemory); +int32_t OpenShareMemory(ShareMemory *shareMemory); +int32_t ReleaseShareMemory(ShareMemory *shareMemory); + +#ifdef __cplusplus +} +#endif +#endif // SHARE_MEM_H diff --git a/codec/hal/v1.0/share_mem/src/ashmem_wrapper.cpp b/codec/hal/v1.0/share_mem/src/ashmem_wrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6c298b951fb6af0e5e155e445f4dee3913f23d1 --- /dev/null +++ b/codec/hal/v1.0/share_mem/src/ashmem_wrapper.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 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 "ashmem_wrapper.h" +#include +#include +#include "ashmem.h" +#include "hdf_base.h" +#include "hdf_log.h" + +#define HDF_LOG_TAG codec_hdi_share_mem + +using namespace OHOS; + +#ifdef __cplusplus +extern "C" +{ +#endif + +int32_t AshmemCreateFd(const char *name, int32_t size) +{ + if (size <= 0) { + HDF_LOGE("%{public}s: Failed to create invalid size: %{public}d", __func__, size); + return HDF_FAILURE; + } + int32_t fd = AshmemCreate(name, size); + if (fd < 0) { + HDF_LOGE("%{public}s: Failed to create fd = %{public}d", __func__, fd); + } + return fd; +} + +uint8_t* MapAshmemFd(int32_t fd, int32_t size) +{ + if (fd < 0) { + HDF_LOGE("%{public}s: Failed to map invalid fd: %{public}d", __func__, fd); + return nullptr; + } + if (size <= 0) { + HDF_LOGE("%{public}s: Failed to map invalid size: %{public}d", __func__, size); + return nullptr; + } + uint8_t *addr = (uint8_t *)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + return addr; +} + +void UnmapAshmemFd(uint8_t *addr, int32_t size) +{ + if (addr == nullptr) { + HDF_LOGE("%{public}s: invalid nullptr addr!", __func__); + return; + } + munmap((void *)addr, size); +} + +int32_t CloseAshmemFd(int32_t fd) +{ + return close(fd); +} + +#ifdef __cplusplus +} +#endif diff --git a/codec/hal/v1.0/share_mem/src/share_mem.c b/codec/hal/v1.0/share_mem/src/share_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..2ea5125a28daa142af343b4b1c914911b4cd1287 --- /dev/null +++ b/codec/hal/v1.0/share_mem/src/share_mem.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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 "share_mem.h" +#include +#include "ashmem_wrapper.h" +#include "hdf_log.h" + +#define HDF_LOG_TAG codec_hdi_share_mem + +int32_t CreateShareMemory(ShareMemory *shareMemory) +{ + if (shareMemory == NULL || shareMemory->size <= 0) { + HDF_LOGE("%{public}s invalid param", __func__); + return HDF_FAILURE; + } + int32_t fd = AshmemCreateFd(shareMemory->memName, shareMemory->size); + if (fd < 0) { + HDF_LOGE("%{public}s invalid fd", __func__); + return HDF_FAILURE; + } + shareMemory->fd = fd; + shareMemory->virAddr = MapAshmemFd(fd, shareMemory->size); + if ((void*)shareMemory->virAddr == MAP_FAILED) { + HDF_LOGE("%{public}s: Failed to map fd!", __func__); + shareMemory->virAddr = NULL; + } + + return HDF_SUCCESS; +} + +int32_t OpenShareMemory(ShareMemory *shareMemory) +{ + if (shareMemory == NULL || shareMemory->fd < 0) { + HDF_LOGE("%{public}s invalid param", __func__); + return HDF_FAILURE; + } + shareMemory->virAddr = MapAshmemFd(shareMemory->fd, shareMemory->size); + if ((void*)shareMemory->virAddr == MAP_FAILED) { + HDF_LOGE("%{public}s: Failed to map fd!", __func__); + shareMemory->virAddr = NULL; + } + + return HDF_SUCCESS; +} + +int32_t ReleaseShareMemory(ShareMemory *shareMemory) +{ + if (shareMemory == NULL || shareMemory->virAddr == NULL) { + HDF_LOGE("%{public}s invalid param", __func__); + return HDF_FAILURE; + } + UnmapAshmemFd(shareMemory->virAddr, shareMemory->size); + CloseAshmemFd(shareMemory->fd); + return HDF_SUCCESS; +} diff --git a/codec/hdi_service/BUILD.gn b/codec/hdi_service/BUILD.gn index e45de72dbfb3f29cde33cb6226d2d027c92904c0..b9e213c418afefd29807843429d4ba1def41bacc 100644 --- a/codec/hdi_service/BUILD.gn +++ b/codec/hdi_service/BUILD.gn @@ -49,21 +49,36 @@ ohos_shared_library("libcodec_server") { include_dirs = [ "//drivers/peripheral/codec/interfaces/include/", "//drivers/peripheral/codec/hdi_service/codec_proxy/", + "//drivers/peripheral/codec/hal/v1.0/codec_instance/include", + "//drivers/peripheral/codec/hal/v1.0/share_mem/include", + "//drivers/peripheral/codec/hal/v1.0/oem_interface/include", + "//drivers/peripheral/codec/hal/v1.0/buffer_manager/include", ] sources = [ + "//drivers/peripheral/codec/hal/v1.0/codec_instance/src/codec_instance.c", + "//drivers/peripheral/codec/hal/v1.0/share_mem/src/ashmem_wrapper.cpp", + "//drivers/peripheral/codec/hal/v1.0/share_mem/src/share_mem.c", "codec_service_stub/codec_callback_service.c", "codec_service_stub/codec_callback_stub.c", "codec_service_stub/codec_host.c", + "codec_service_stub/codec_service.c", "codec_service_stub/codec_stub.c", "codec_service_stub/stub_msgproc.c", ] - CODEC_LIB_PATH = "//device/soc/hisilicon/common/hal/media/codec/hi3516dv300/linux_standard/libs" - CODEC_LIB_REAL_PATH = rebase_path("$CODEC_LIB_PATH") - ldflags = [ "-L$CODEC_LIB_REAL_PATH" ] - ldflags += [ "-lcodec" ] + + if (product_name == "Hi3516DV300") { + CODEC_LIB_PATH = "//device/soc/hisilicon/common/hal/media/codec/hi3516dv300/linux_standard/libs" + CODEC_LIB_REAL_PATH = rebase_path("$CODEC_LIB_PATH") + ldflags = [ "-L$CODEC_LIB_REAL_PATH" ] + ldflags += [ "-lcodec" ] + } deps = [ "//drivers/peripheral/codec/hdi_service:codec_client" ] + if (product_name == "rk3568") { + deps += [ "//device/soc/rockchip/hardware/codec:codec_oem_interface" ] + } + if (is_standard_system) { external_deps = [ "device_driver_framework:libhdf_host", @@ -71,6 +86,7 @@ ohos_shared_library("libcodec_server") { "device_driver_framework:libhdf_utils", "device_driver_framework:libhdi", "hiviewdfx_hilog_native:libhilog", + "utils_base:utils", ] } else { external_deps = [ "hilog:libhilog" ] @@ -82,7 +98,8 @@ ohos_shared_library("libcodec_server") { } group("codec_service") { - if (target_cpu == "arm" && device_company == "hisilicon") { + if ((target_cpu == "arm" && product_name == "Hi3516DV300") || + product_name == "rk3568") { deps = [ ":libcodec_server" ] } } diff --git a/codec/hdi_service/codec_proxy/codec_proxy.c b/codec/hdi_service/codec_proxy/codec_proxy.c index 97a80cd8ba2b94a7f512f8c9688378541aaab101..c47b4cd17f4407b808332ec680debc80a1ee2de2 100644 --- a/codec/hdi_service/codec_proxy/codec_proxy.c +++ b/codec/hdi_service/codec_proxy/codec_proxy.c @@ -23,6 +23,8 @@ extern "C" { #endif /* __cplusplus */ +#define HDF_LOG_TAG codec_hdi_proxy + static int32_t CodecProxyCall(struct ICodec *self, int32_t id, struct HdfSBuf *data, struct HdfSBuf *reply) { @@ -228,7 +230,7 @@ int32_t CodecProxyCreate(struct ICodec *self, const char* name, const Param *att CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)handle)) { CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } @@ -238,7 +240,7 @@ int32_t CodecProxyCreate(struct ICodec *self, const char* name, const Param *att CodecProxySBufRecycle(data, reply); return ret; } - if (!HdfSbufReadUint32(reply, (uint32_t *)handle)) { + if (!HdfSbufReadUint64(reply, (uint64_t *)handle)) { ret = HDF_ERR_INVALID_PARAM; } CodecProxySBufRecycle(data, reply); @@ -263,7 +265,7 @@ int32_t CodecProxyDestroy(struct ICodec *self, CODEC_HANDLETYPE handle) CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: Write handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -293,7 +295,7 @@ int32_t CodecProxySetPortMode(struct ICodec *self, CODEC_HANDLETYPE handle, Dire CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: Read size failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -334,7 +336,7 @@ int32_t CodecProxySetParameter(struct ICodec *self, CODEC_HANDLETYPE handle, con CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write size failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -374,7 +376,7 @@ int32_t CodecProxyGetParameter(struct ICodec *self, CODEC_HANDLETYPE handle, Par return HDF_FAILURE; } if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data) || - !HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + !HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write interface token or size failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -425,7 +427,7 @@ int32_t CodecProxyStart(struct ICodec *self, CODEC_HANDLETYPE handle) CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -455,7 +457,7 @@ int32_t CodecProxyStop(struct ICodec *self, CODEC_HANDLETYPE handle) CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -485,7 +487,7 @@ int32_t CodecProxyFlush(struct ICodec *self, CODEC_HANDLETYPE handle, DirectionT CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -521,7 +523,7 @@ int32_t CodecPorxyQueueInput(struct ICodec *self, CODEC_HANDLETYPE handle, CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -561,7 +563,7 @@ int32_t CodecProxyDequeInput(struct ICodec *self, CODEC_HANDLETYPE handle, uint3 CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -578,7 +580,9 @@ int32_t CodecProxyDequeInput(struct ICodec *self, CODEC_HANDLETYPE handle, uint3 } ret = CodecProxyCall(self, CMD_CODEC_DEQUEQUE_INPUT, data, reply); if (ret != HDF_SUCCESS) { - HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret); + if (ret != HDF_ERR_TIMEOUT) { + HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret); + } CodecProxySBufRecycle(data, reply); return ret; } @@ -609,7 +613,7 @@ int32_t CodecProxyQueueOutput(struct ICodec *self, CODEC_HANDLETYPE handle, Outp CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -651,7 +655,7 @@ int32_t CodecProxyDequeueOutput(struct ICodec *self, CODEC_HANDLETYPE handle, ui return HDF_FAILURE; } if (!HdfRemoteServiceWriteInterfaceToken(self->remote, data) || - !HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + !HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write interface token or input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -668,7 +672,9 @@ int32_t CodecProxyDequeueOutput(struct ICodec *self, CODEC_HANDLETYPE handle, ui } ret = CodecProxyCall(self, CMD_CODEC_DEQUEQUE_OUTPUT, data, reply); if (ret != HDF_SUCCESS) { - HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret); + if (ret != HDF_ERR_TIMEOUT) { + HDF_LOGE("%{public}s: call failed! error code is %{public}d", __func__, ret); + } CodecProxySBufRecycle(data, reply); return ret; } @@ -704,7 +710,7 @@ int32_t CodecProxySetCallback(struct ICodec *self, CODEC_HANDLETYPE handle, stru CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)(uintptr_t)handle)) { + if (!HdfSbufWriteUint64(data, (uint64_t)(uintptr_t)handle)) { HDF_LOGE("%{public}s: write input handle failed!", __func__); CodecProxySBufRecycle(data, reply); return HDF_ERR_INVALID_PARAM; @@ -794,4 +800,4 @@ void HdiCodecRelease(struct ICodec *instance) #ifdef __cplusplus } -#endif /* __cplusplus */ \ No newline at end of file +#endif /* __cplusplus */ diff --git a/codec/hdi_service/codec_proxy/proxy_msgproc.c b/codec/hdi_service/codec_proxy/proxy_msgproc.c index e8dee00ef1c563467f8a362e2e146aee9821f179..b6efe643d91adff7b1b96a990138fa22b598760c 100644 --- a/codec/hdi_service/codec_proxy/proxy_msgproc.c +++ b/codec/hdi_service/codec_proxy/proxy_msgproc.c @@ -14,10 +14,14 @@ */ #include "proxy_msgproc.h" #include +#include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ + +#define HDF_LOG_TAG codec_hdi_proxy + int32_t CodecProxyParseAlignment(struct HdfSBuf *reply, Alignment *alignment) { if (reply == NULL || alignment == NULL) { @@ -129,41 +133,61 @@ int32_t CodecProxyPackParam(struct HdfSBuf *data, const Param *param) HDF_LOGE("%{public}s: params NULL!", __func__); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(data, (uint32_t)param->key)) { - HDF_LOGE("%{public}s: Write key failed!", __func__); - return HDF_FAILURE; - } - if (!HdfSbufWriteUint32(data, (uint32_t)¶m->val)) { - HDF_LOGE("%{public}s: Write val failed!", __func__); - return HDF_FAILURE; + + if (!HdfSbufWriteInt32(data, (int32_t)param->key)) { + HDF_LOGE("%{public}s: write param->key failed!", __func__); + return false; } + if (!HdfSbufWriteInt32(data, param->size)) { - HDF_LOGE("%{public}s: Write size failed!", __func__); - return HDF_FAILURE; + HDF_LOGE("%{public}s: write param->size failed!", __func__); + return false; + } + for (int32_t i = 0; i < param->size; i++) { + if (!HdfSbufWriteInt8(data, ((int8_t*)(param->val))[i])) { + HDF_LOGE("%{public}s: write (param->val)[i] failed!", __func__); + return false; + } } + return HDF_SUCCESS; } int32_t CodecProxyParseParam(struct HdfSBuf *reply, Param *param) { - uint32_t tempKey = 0; if (reply == NULL || param == NULL) { HDF_LOGE("%{public}s: params NULL!", __func__); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufReadUint32(reply, &tempKey)) { - HDF_LOGE("%{public}s: read tempKey failed!", __func__); - return HDF_FAILURE; - } - param->key = (ParamKey)tempKey; - if (!HdfSbufReadUint32(reply, (uint32_t *)¶m->val)) { - HDF_LOGE("%{public}s: Read val failed!", __func__); + + if (!HdfSbufReadInt32(reply, (int32_t*)¶m->key)) { + HDF_LOGE("%{public}s: read param->key failed!", __func__); return HDF_FAILURE; } - if (!HdfSbufReadInt32(reply, (int32_t*)¶m->size)) { + + int8_t* valCp = NULL; + int32_t valCpLen = 0; + if (!HdfSbufReadInt32(reply, &valCpLen)) { HDF_LOGE("%{public}s: read size failed!", __func__); return HDF_FAILURE; } + if (valCpLen > 0) { + valCp = (int8_t*)OsalMemCalloc(sizeof(int8_t) * valCpLen); + if (valCp == NULL) { + HDF_LOGE("%{public}s: alloc mem failed!", __func__); + return HDF_FAILURE; + } + for (int32_t i = 0; i < valCpLen; i++) { + if (!HdfSbufReadInt8(reply, &valCp[i])) { + HDF_LOGE("%{public}s: read valCp[i] failed!", __func__); + OsalMemFree(valCp); + return HDF_FAILURE; + } + } + } + param->val = (void*)valCp; + param->size = valCpLen; + return HDF_SUCCESS; } diff --git a/codec/hdi_service/codec_service_stub/codec_service.c b/codec/hdi_service/codec_service_stub/codec_service.c new file mode 100644 index 0000000000000000000000000000000000000000..1f62e168526de0089a84753a1ed619c97e5e59b0 --- /dev/null +++ b/codec/hdi_service/codec_service_stub/codec_service.c @@ -0,0 +1,403 @@ +/* + * Copyright (c) 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_service.h" +#include +#include +#include +#include +#include +#include +#include "ashmem_wrapper.h" +#include "hdf_log.h" +#include "osal_mem.h" + +#define HDF_LOG_TAG codec_hdi_service + +struct CodecInstance *g_codecInstance = NULL; + +static void CopyInputInfo(InputInfo *dst, const InputInfo *src) +{ + if (dst == NULL || src == NULL) { + HDF_LOGE("%{public}s: Nullpoint, dst: %{public}p, src: %{public}p", __func__, dst, src); + return; + } + dst->bufferCnt = src->bufferCnt; + dst->pts = src->pts; + dst->flag = src->flag; + if (dst->bufferCnt > 0) { + int32_t size = sizeof(CodecBufferInfo) * dst->bufferCnt; + memcpy_s(dst->buffers, size, src->buffers, size); + } +} + +static InputInfo* DupInputInfo(const InputInfo *src) +{ + if (src == NULL) { + HDF_LOGE("%{public}s: inputinfo src Nullpoint", __func__); + return NULL; + } + InputInfo *dst = (InputInfo *)OsalMemAlloc(sizeof(InputInfo)); + if (dst == NULL) { + HDF_LOGE("%{public}s: dst Nullpoint", __func__); + return NULL; + } + dst->bufferCnt = src->bufferCnt; + dst->pts = src->pts; + dst->flag = src->flag; + if (dst->bufferCnt > 0) { + int32_t size = sizeof(CodecBufferInfo) * dst->bufferCnt; + dst->buffers = (CodecBufferInfo *)OsalMemAlloc(size); + if (dst->buffers != NULL) { + memcpy_s(dst->buffers, size, src->buffers, size); + } + } + return dst; +} + +static void CopyOutputInfo(OutputInfo *dst, OutputInfo *src) +{ + if (dst == NULL || src == NULL) { + HDF_LOGE("%{public}s: Nullpoint, dst: %{public}p, src: %{public}p", __func__, dst, src); + return; + } + dst->bufferCnt = src->bufferCnt; + dst->timeStamp = src->timeStamp; + dst->sequence = src->sequence; + dst->flag = src->flag; + dst->type = src->type; + dst->vendorPrivate = src->vendorPrivate; + if (dst->bufferCnt > 0) { + int32_t size = sizeof(CodecBufferInfo) * dst->bufferCnt; + memcpy_s(dst->buffers, size, src->buffers, size); + } +} + +static OutputInfo* DupOutputInfo(OutputInfo *src) +{ + if (src == NULL) { + HDF_LOGE("%{public}s: src Nullpoint", __func__); + return NULL; + } + OutputInfo *dst = (OutputInfo *)OsalMemAlloc(sizeof(OutputInfo)); + if (dst == NULL) { + HDF_LOGE("%{public}s: dst Nullpoint", __func__); + return NULL; + } + dst->bufferCnt = src->bufferCnt; + dst->timeStamp = src->timeStamp; + dst->sequence = src->sequence; + dst->flag = src->flag; + dst->type = src->type; + dst->vendorPrivate = src->vendorPrivate; + if (dst->bufferCnt > 0) { + int32_t size = sizeof(CodecBufferInfo) * dst->bufferCnt; + dst->buffers = (CodecBufferInfo *)OsalMemAlloc(size); + if (dst->buffers != NULL) { + memcpy_s(dst->buffers, size, src->buffers, size); + } + } + return dst; +} + +static int32_t DefaultCbOnEvent(UINTPTR comp, UINTPTR appData, EventType event, + uint32_t data1, uint32_t data2, UINTPTR eventData) +{ + return HDF_SUCCESS; +} + +static int32_t DefaultCbInputBufferAvailable(UINTPTR comp, UINTPTR appData, InputInfo *inBuf) +{ + if (inBuf == NULL || inBuf->buffers == NULL) { + HDF_LOGE("%{public}s: inBuf Nullpoint", __func__); + return HDF_FAILURE; + } + InputInfo *inputInfo = GetInputInfo(g_codecInstance, inBuf->buffers->offset); + if (inputInfo == NULL || inputInfo->buffers == NULL) { + HDF_LOGE("%{public}s: inputInfo Nullpoint", __func__); + return HDF_FAILURE; + } + inputInfo->buffers->fd = GetFdById(g_codecInstance, inBuf->buffers->offset); + inputInfo->buffers->type = BUFFER_TYPE_FD; + g_codecInstance->bufferManagerWrapper->PutUsedInputDataBuffer(g_codecInstance->bufferManagerWrapper, inputInfo); + return HDF_SUCCESS; +} + +static int32_t DefaultCbOutputBufferAvailable(UINTPTR comp, UINTPTR appData, OutputInfo *outBuf) +{ + if (outBuf == NULL || outBuf->buffers == NULL) { + HDF_LOGE("%{public}s: outBuf Nullpoint", __func__); + return HDF_FAILURE; + } + struct BufferManagerWrapper *bmWrapper = g_codecInstance->bufferManagerWrapper; + OutputInfo *outputInfo = GetOutputInfo(g_codecInstance, outBuf->buffers->offset); + if (outputInfo == NULL || outputInfo->buffers == NULL) { + HDF_LOGE("%{public}s: outputInfo Nullpoint", __func__); + return HDF_FAILURE; + } + CopyOutputInfo(outputInfo, outBuf); + outputInfo->buffers->fd = GetFdById(g_codecInstance, outBuf->buffers->offset); + outputInfo->buffers->type = BUFFER_TYPE_FD; + bmWrapper->PutOutputDataBuffer(bmWrapper, outputInfo); + + // get a new OutputBuffer + OutputInfo *output = NULL; + while (output == NULL && g_codecInstance->codecStatus == CODEC_STATUS_STARTED) { + output = bmWrapper->GetUsedOutputDataBuffer(bmWrapper, QUEUE_TIME_OUT); + } + outBuf->buffers->type = BUFFER_TYPE_VIRTUAL; + outBuf->buffers->offset = output->buffers->offset; + outBuf->buffers->addr = GetOutputShm(g_codecInstance, output->buffers->offset)->virAddr; + + return HDF_SUCCESS; +} + +int32_t CodecInit() +{ + g_codecInstance = GetCodecInstance(); + InitCodecInstance(g_codecInstance); + + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecInit(); + return HDF_SUCCESS; +} + +int32_t CodecDeinit() +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecDeinit(); + DestroyCodecInstance(g_codecInstance); + g_codecInstance = NULL; + return HDF_SUCCESS; +} + +int32_t CodecEnumerateCapbility(uint32_t index, CodecCapbility *cap) +{ + return HDF_SUCCESS; +} + +int32_t CodecGetCapbility(AvCodecMime mime, CodecType type, uint32_t flags, CodecCapbility *cap) +{ + return HDF_SUCCESS; +} + +int32_t CodecCreate(const char* name, const Param *attr, int32_t len, CODEC_HANDLETYPE *handle) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecCreate(name, attr, len, handle); + g_codecInstance->handle = *handle; + HDF_LOGI("%{public}s codec created", __func__); + return HDF_SUCCESS; +} + +int32_t CodecDestroy(CODEC_HANDLETYPE handle) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecDestroy(handle); + return HDF_SUCCESS; +} + +int32_t CodecSetPortMode(CODEC_HANDLETYPE handle, DirectionType type, BufferMode mode) +{ + return HDF_SUCCESS; +} + +int32_t CodecSetParameter(CODEC_HANDLETYPE handle, const Param *params, int32_t paramCnt) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + for (int32_t i = 0; i < paramCnt; i++) { + if (params[i].key == KEY_CODEC_TYPE) { + int32_t codecType = 0; + memcpy_s(&codecType, sizeof(codecType), params[i].val, params[i].size); + g_codecInstance->codecType = codecType; + } + } + g_codecInstance->codecOemIface->CodecSetParameter(handle, params, paramCnt); + return HDF_SUCCESS; +} + +int32_t CodecGetParameter(CODEC_HANDLETYPE handle, Param *params, int32_t paramCnt) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecGetParameter(handle, params, paramCnt); + return HDF_SUCCESS; +} + +int32_t CodecStart(CODEC_HANDLETYPE handle) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + if (!g_codecInstance->hasCallback) { + g_codecInstance->defaultCb.OnEvent = DefaultCbOnEvent; + g_codecInstance->defaultCb.InputBufferAvailable = DefaultCbInputBufferAvailable; + g_codecInstance->defaultCb.OutputBufferAvailable = DefaultCbOutputBufferAvailable; + g_codecInstance->codecOemIface->CodecSetCallback(handle, &(g_codecInstance->defaultCb), 0); + } + RunCodecInstance(g_codecInstance); + return HDF_SUCCESS; +} + +int32_t CodecStop(CODEC_HANDLETYPE handle) +{ + if (g_codecInstance == NULL) { + HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__); + return HDF_FAILURE; + } + StopCodecInstance(g_codecInstance); + return HDF_SUCCESS; +} + +int32_t CodecFlush(CODEC_HANDLETYPE handle, DirectionType directType) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecFlush(handle, directType); + return HDF_SUCCESS; +} + +int32_t CodecQueueInput(CODEC_HANDLETYPE handle, const InputInfo *inputInfo, uint32_t timeoutMs) +{ + if (g_codecInstance == NULL) { + HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__); + return HDF_FAILURE; + } + + if (g_codecInstance->codecStatus == CODEC_STATUS_IDLE) { + uint32_t i; + if (g_codecInstance->codecType == VIDEO_DECODER || g_codecInstance->codecType == AUDIO_DECODER || + g_codecInstance->codecType == VIDEO_ENCODER || g_codecInstance->codecType == AUDIO_ENCODER) { + for (i = 0; i < inputInfo->bufferCnt; i++) { + AddInputShm(g_codecInstance, &inputInfo->buffers[i]); + } + } else { + HDF_LOGE("%{public}s: codecType invalid, queue input buffer failed!", __func__); + return HDF_FAILURE; + } + InputInfo *dup = DupInputInfo(inputInfo); + AddInputInfo(g_codecInstance, dup); + g_codecInstance->bufferManagerWrapper->PutUsedInputDataBuffer(g_codecInstance->bufferManagerWrapper, dup); + return HDF_SUCCESS; + } else if (g_codecInstance->codecStatus == CODEC_STATUS_STARTED) { + InputInfo *info = GetInputInfo(g_codecInstance, inputInfo->buffers[0].offset); + CopyInputInfo(info, inputInfo); + g_codecInstance->bufferManagerWrapper->PutInputDataBuffer(g_codecInstance->bufferManagerWrapper, info); + return HDF_SUCCESS; + } + return HDF_SUCCESS; +} + +int32_t CodecDequeInput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, InputInfo *inputData) +{ + if (g_codecInstance == NULL) { + HDF_LOGE("%{public}s: g_codecInstance is NULL!", __func__); + return HDF_FAILURE; + } + + InputInfo *info = g_codecInstance->bufferManagerWrapper->GetUsedInputDataBuffer( + g_codecInstance->bufferManagerWrapper, QUEUE_TIME_OUT); + if (info != NULL) { + CopyInputInfo(inputData, info); + } else { + return HDF_ERR_TIMEOUT; + } + + return HDF_SUCCESS; +} + +int32_t CodecQueueOutput(CODEC_HANDLETYPE handle, OutputInfo *outInfo, uint32_t timeoutMs, int32_t releaseFenceFd) +{ + if (g_codecInstance == NULL || g_codecInstance->bufferManagerWrapper == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or buffermanager is NULL!", __func__); + return HDF_FAILURE; + } + + if (g_codecInstance->codecStatus == CODEC_STATUS_IDLE) { + uint32_t i; + if (g_codecInstance->codecType == VIDEO_DECODER || g_codecInstance->codecType == AUDIO_DECODER || + g_codecInstance->codecType == VIDEO_ENCODER || g_codecInstance->codecType == AUDIO_ENCODER) { + for (i = 0; i < outInfo->bufferCnt; i++) { + AddOutputShm(g_codecInstance, &outInfo->buffers[i]); + } + } else { + HDF_LOGE("%{public}s: codecType invalid, queue output buffer failed!", __func__); + return HDF_FAILURE; + } + OutputInfo *dup = DupOutputInfo(outInfo); + AddOutputInfo(g_codecInstance, dup); + g_codecInstance->bufferManagerWrapper->PutUsedOutputDataBuffer(g_codecInstance->bufferManagerWrapper, dup); + return HDF_SUCCESS; + } else if (g_codecInstance->codecStatus == CODEC_STATUS_STARTED) { + OutputInfo *info = GetOutputInfo(g_codecInstance, outInfo->buffers->offset); + CopyOutputInfo(info, outInfo); + g_codecInstance->bufferManagerWrapper->PutUsedOutputDataBuffer(g_codecInstance->bufferManagerWrapper, info); + return HDF_SUCCESS; + } else if (g_codecInstance->codecStatus == CODEC_STATUS_STOPED) { + OutputInfo *dup = DupOutputInfo(outInfo); + g_codecInstance->bufferManagerWrapper->PutOutputDataBuffer(g_codecInstance->bufferManagerWrapper, dup); + } + return HDF_SUCCESS; +} + +int32_t CodecDequeueOutput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, int32_t *acquireFd, OutputInfo *outInfo) +{ + if (g_codecInstance == NULL || g_codecInstance->bufferManagerWrapper == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or buffermanager is NULL!", __func__); + return HDF_FAILURE; + } + + OutputInfo *info = g_codecInstance->bufferManagerWrapper->GetOutputDataBuffer( + g_codecInstance->bufferManagerWrapper, QUEUE_TIME_OUT); + if (info != NULL) { + *acquireFd = 1; + CopyOutputInfo(outInfo, info); + } else { + return HDF_ERR_TIMEOUT; + } + + return HDF_SUCCESS; +} + +int32_t CodecSetCallback(CODEC_HANDLETYPE handle, const CodecCallback *cb, UINTPTR instance) +{ + if (g_codecInstance == NULL || g_codecInstance->codecOemIface == NULL) { + HDF_LOGE("%{public}s: g_codecInstance or oemIface is NULL!", __func__); + return HDF_FAILURE; + } + g_codecInstance->codecOemIface->CodecSetCallback(handle, cb, instance); + g_codecInstance->hasCallback = true; + return HDF_SUCCESS; +} diff --git a/codec/hdi_service/codec_service_stub/codec_service.h b/codec/hdi_service/codec_service_stub/codec_service.h new file mode 100644 index 0000000000000000000000000000000000000000..7f4fa6407855553a6b9b18ff86fab76a4b6385d5 --- /dev/null +++ b/codec/hdi_service/codec_service_stub/codec_service.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 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_SERVICE_H +#define CODEC_SERVICE_H + +#include "hdf_base.h" +#include "codec_type.h" +#include "codec_instance.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int32_t CodecInit(); +int32_t CodecDeinit(); +int32_t CodecEnumerateCapbility(uint32_t index, CodecCapbility *cap); +int32_t CodecGetCapbility(AvCodecMime mime, CodecType type, uint32_t flags, CodecCapbility *cap); +int32_t CodecCreate(const char* name, const Param *attr, int len, CODEC_HANDLETYPE *handle); +int32_t CodecDestroy(CODEC_HANDLETYPE handle); +int32_t CodecSetPortMode(CODEC_HANDLETYPE handle, DirectionType type, BufferMode mode); +int32_t CodecSetParameter(CODEC_HANDLETYPE handle, const Param *params, int paramCnt); +int32_t CodecGetParameter(CODEC_HANDLETYPE handle, Param *params, int paramCnt); +int32_t CodecStart(CODEC_HANDLETYPE handle); +int32_t CodecStop(CODEC_HANDLETYPE handle); +int32_t CodecFlush(CODEC_HANDLETYPE handle, DirectionType directType); +int32_t CodecQueueInput(CODEC_HANDLETYPE handle, const InputInfo *inputData, uint32_t timeoutMs); +int32_t CodecDequeInput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, InputInfo *inputData); +int32_t CodecQueueOutput(CODEC_HANDLETYPE handle, OutputInfo *outInfo, uint32_t timeoutMs, int releaseFenceFd); +int32_t CodecDequeueOutput(CODEC_HANDLETYPE handle, uint32_t timeoutMs, int *acquireFd, OutputInfo *outInfo); +int32_t CodecSetCallback(CODEC_HANDLETYPE handle, const CodecCallback *cb, UINTPTR instance); + +#ifdef __cplusplus +} +#endif +#endif // CODEC_SERVICE_H diff --git a/codec/hdi_service/codec_service_stub/codec_stub.c b/codec/hdi_service/codec_service_stub/codec_stub.c index 930a0634eef6271f720abb927e0420a6fd18efad..d1e3bc2258ed5bf56f3103d3e298f16d844be90c 100644 --- a/codec/hdi_service/codec_service_stub/codec_stub.c +++ b/codec/hdi_service/codec_service_stub/codec_stub.c @@ -20,7 +20,9 @@ #include "codec_interface.h" #include "icodec.h" #include "stub_msgproc.h" +#include "codec_service.h" +#define HDF_LOG_TAG codec_hdi_stub #define HDF_CODEC_NAME_LEN 50 static int32_t SerCodecInit(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) @@ -108,7 +110,7 @@ static int32_t SerCodecCreate(struct HdfDeviceIoClient *client, struct HdfSBuf * { int32_t len = 0; int32_t errNum; - uint32_t handle = 0; + uint64_t handle = 0; uint32_t dateSize = 0; const char *name = NULL; Param attr; @@ -134,7 +136,7 @@ static int32_t SerCodecCreate(struct HdfDeviceIoClient *client, struct HdfSBuf * HDF_LOGE("%{public}s: Read name failed!", __func__); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: Read handle failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -143,7 +145,7 @@ static int32_t SerCodecCreate(struct HdfDeviceIoClient *client, struct HdfSBuf * HDF_LOGE("%{public}s: call CodecCreate fuc failed!", __func__); return errNum; } - if (!HdfSbufWriteUint32(reply, handle)) { + if (!HdfSbufWriteUint64(reply, handle)) { HDF_LOGE("%{public}s: write handle failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -152,12 +154,12 @@ static int32_t SerCodecCreate(struct HdfDeviceIoClient *client, struct HdfSBuf * static int32_t SerCodecDestroy(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t errNum; - uint32_t handle = 0; - if (!HdfSbufReadUint32(data, &handle)) { + uint64_t handle = 0; + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: Read size failed!", __func__); return HDF_ERR_INVALID_PARAM; } - errNum = CodecDestroy((CODEC_HANDLETYPE)&handle); + errNum = CodecDestroy((CODEC_HANDLETYPE)(uintptr_t)handle); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecDestroy fuc failed!", __func__); return errNum; @@ -168,11 +170,11 @@ static int32_t SerCodecDestroy(struct HdfDeviceIoClient *client, struct HdfSBuf static int32_t SerCodecSetPortMode(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t errNum; - uint32_t handle = 0; + uint64_t handle = 0; DirectionType type; BufferMode mode; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: Read size failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -184,7 +186,7 @@ static int32_t SerCodecSetPortMode(struct HdfDeviceIoClient *client, struct HdfS HDF_LOGE("%{public}s: Read size failed!", __func__); return HDF_ERR_INVALID_PARAM; } - errNum = CodecSetPortMode((CODEC_HANDLETYPE)&handle, type, mode); + errNum = CodecSetPortMode((CODEC_HANDLETYPE)(uintptr_t)handle, type, mode); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecSetPortMode fuc failed!", __func__); return errNum; @@ -192,14 +194,29 @@ static int32_t SerCodecSetPortMode(struct HdfDeviceIoClient *client, struct HdfS return errNum; } +static void FreeParams(Param *params, int32_t paramCnt) +{ + if (params == NULL || paramCnt <= 0) { + HDF_LOGE("%{public}s: params is null or invalid count!", __func__); + return; + } + for (int32_t j = 0; j < paramCnt; j++) { + if (params[j].val != NULL && params[j].size > 0) { + OsalMemFree(params[j].val); + params[j].val = NULL; + } + } + OsalMemFree(params); +} + static int32_t SerCodecSetParameter(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t errNum; int32_t paramCnt = 0; - uint32_t handle = 0; + uint64_t handle = 0; Param *params = NULL; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: Read handle failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -219,25 +236,26 @@ static int32_t SerCodecSetParameter(struct HdfDeviceIoClient *client, struct Hdf for (int32_t i = 0; i < paramCnt; i++) { if (CodecSerParseParam(data, ¶ms[i]) != HDF_SUCCESS) { HDF_LOGE("%{public}s: Read params failed!", __func__); - OsalMemFree(params); + FreeParams(params, paramCnt); return HDF_FAILURE; } } - errNum = CodecSetParameter((CODEC_HANDLETYPE)&handle, params, paramCnt); + errNum = CodecSetParameter((CODEC_HANDLETYPE)(uintptr_t)handle, params, paramCnt); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecSetParameter fuc failed!", __func__); } - OsalMemFree(params); + + FreeParams(params, paramCnt); return errNum; } static int32_t SerCodecGetParameter(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t errNum; int32_t paramCnt = 0; - uint32_t handle = 0; + uint64_t handle = 0; Param *params = NULL; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: Read handle failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -257,36 +275,37 @@ static int32_t SerCodecGetParameter(struct HdfDeviceIoClient *client, struct Hdf for (int32_t i = 0; i < paramCnt; i++) { if (CodecSerParseParam(data, ¶ms[i]) != HDF_SUCCESS) { HDF_LOGE("%{public}s: Read params failed!", __func__); - OsalMemFree(params); + FreeParams(params, paramCnt); return HDF_FAILURE; } } - errNum = CodecGetParameter((CODEC_HANDLETYPE)&handle, params, paramCnt); + errNum = CodecGetParameter((CODEC_HANDLETYPE)(uintptr_t)handle, params, paramCnt); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecGetParameter fuc failed!", __func__); - OsalMemFree(params); + FreeParams(params, paramCnt); return errNum; } for (int32_t i = 0; i < paramCnt; i++) { if (CodecSerPackParam(reply, ¶ms[i]) != HDF_SUCCESS) { HDF_LOGE("%{public}s: CodecSerPackParam err!", __func__); - OsalMemFree(params); + FreeParams(params, paramCnt); return HDF_FAILURE; } } - OsalMemFree(params); + + FreeParams(params, paramCnt); return errNum; } static int32_t SerCodecStart(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t errNum; - uint32_t handle = 0; + uint64_t handle = 0; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: Read handle failed!", __func__); return HDF_ERR_INVALID_PARAM; } - errNum = CodecStart((CODEC_HANDLETYPE)&handle); + errNum = CodecStart((CODEC_HANDLETYPE)(uintptr_t)handle); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call SerCodecStart fuc failed!", __func__); return errNum; @@ -296,12 +315,12 @@ static int32_t SerCodecStart(struct HdfDeviceIoClient *client, struct HdfSBuf *d static int32_t SerCodecStop(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { - uint32_t handle = 0; - if (!HdfSbufReadUint32(data, &handle)) { + uint64_t handle = 0; + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } - int32_t errNum = CodecStop((CODEC_HANDLETYPE)&handle); + int32_t errNum = CodecStop((CODEC_HANDLETYPE)(uintptr_t)handle); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecStop fuc failed!", __func__); return errNum; @@ -310,9 +329,9 @@ static int32_t SerCodecStop(struct HdfDeviceIoClient *client, struct HdfSBuf *da } static int32_t SerCodecFlush(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { - uint32_t handle = 0; + uint64_t handle = 0; uint32_t directType = 0; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -320,7 +339,7 @@ static int32_t SerCodecFlush(struct HdfDeviceIoClient *client, struct HdfSBuf *d HDF_LOGE("%{public}s: read directType data failed!", __func__); return HDF_ERR_INVALID_PARAM; } - int32_t errNum = CodecFlush((CODEC_HANDLETYPE)&handle, (DirectionType)directType); + int32_t errNum = CodecFlush((CODEC_HANDLETYPE)(uintptr_t)handle, (DirectionType)directType); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecFlush fuc failed!", __func__); return errNum; @@ -330,10 +349,10 @@ static int32_t SerCodecFlush(struct HdfDeviceIoClient *client, struct HdfSBuf *d int32_t SerCodecQueueInput(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { uint32_t timeoutMs = 0; - uint32_t handle = 0; + uint64_t handle = 0; uint32_t bufCnt; InputInfo inputData = {0}; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -361,7 +380,7 @@ int32_t SerCodecQueueInput(struct HdfDeviceIoClient *client, struct HdfSBuf *dat OsalMemFree(inputData.buffers); return HDF_ERR_INVALID_PARAM; } - int32_t errNum = CodecQueueInput((CODEC_HANDLETYPE)&handle, &inputData, timeoutMs); + int32_t errNum = CodecQueueInput((CODEC_HANDLETYPE)(uintptr_t)handle, &inputData, timeoutMs); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecQueueInput fuc failed!", __func__); OsalMemFree(inputData.buffers); @@ -373,9 +392,9 @@ int32_t SerCodecQueueInput(struct HdfDeviceIoClient *client, struct HdfSBuf *dat static int32_t SerCodecDequeInput(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { uint32_t timeoutMs = 0; - uint32_t handle = 0; + uint64_t handle = 0; InputInfo inputData = {0}; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -396,9 +415,11 @@ static int32_t SerCodecDequeInput(struct HdfDeviceIoClient *client, struct HdfSB HDF_LOGE("%{public}s: OsalMemAlloc failed!", __func__); return HDF_ERR_INVALID_PARAM; } - int32_t errNum = CodecDequeInput((CODEC_HANDLETYPE)&handle, timeoutMs, &inputData); + int32_t errNum = CodecDequeInput((CODEC_HANDLETYPE)(uintptr_t)handle, timeoutMs, &inputData); if (errNum != HDF_SUCCESS) { - HDF_LOGE("%{public}s: call CodecDequeInput fuc failed!", __func__); + if (errNum != HDF_ERR_TIMEOUT) { + HDF_LOGE("%{public}s: call CodecDequeInput fuc failed!", __func__); + } OsalMemFree(inputData.buffers); return errNum; } @@ -413,11 +434,11 @@ static int32_t SerCodecDequeInput(struct HdfDeviceIoClient *client, struct HdfSB static int32_t SerCodecQueueOutput(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { uint32_t timeoutMs = 0; - int releaseFenceFd; - uint32_t handle = 0; + int releaseFenceFd = 1; + uint64_t handle = 0; uint32_t bufCnt; OutputInfo outInfo = {0}; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -445,13 +466,7 @@ static int32_t SerCodecQueueOutput(struct HdfDeviceIoClient *client, struct HdfS OsalMemFree(outInfo.buffers); return HDF_ERR_INVALID_PARAM; } - releaseFenceFd = HdfSbufReadFileDescriptor(data); - if (releaseFenceFd < 0) { - HDF_LOGE("%{public}s: read timeoutMs data failed!", __func__); - OsalMemFree(outInfo.buffers); - return HDF_ERR_INVALID_PARAM; - } - int32_t errNum = CodecQueueOutput((CODEC_HANDLETYPE)&handle, &outInfo, timeoutMs, releaseFenceFd); + int32_t errNum = CodecQueueOutput((CODEC_HANDLETYPE)(uintptr_t)handle, &outInfo, timeoutMs, releaseFenceFd); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecQueueOutput fuc failed!", __func__); OsalMemFree(outInfo.buffers); @@ -464,9 +479,9 @@ static int32_t SerCodecDequeueOutput(struct HdfDeviceIoClient *client, struct Hd { uint32_t timeoutMs = 0; int acquireFd = 0; - uint32_t handle = 0; + uint64_t handle = 0; OutputInfo outInfo = {0}; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -483,9 +498,11 @@ static int32_t SerCodecDequeueOutput(struct HdfDeviceIoClient *client, struct Hd HDF_LOGE("%{public}s: OsalMemAlloc failed!", __func__); return HDF_ERR_INVALID_PARAM; } - int32_t errNum = CodecDequeueOutput((CODEC_HANDLETYPE)&handle, timeoutMs, &acquireFd, &outInfo); + int32_t errNum = CodecDequeueOutput((CODEC_HANDLETYPE)(uintptr_t)handle, timeoutMs, &acquireFd, &outInfo); if (errNum != HDF_SUCCESS) { - HDF_LOGE("%{public}s: call CodecDequeueOutput fuc failed!", __func__); + if (errNum != HDF_ERR_TIMEOUT) { + HDF_LOGE("%{public}s: call CodecDequeueOutput fuc failed!", __func__); + } OsalMemFree(outInfo.buffers); return errNum; } @@ -505,10 +522,10 @@ static int32_t SerCodecDequeueOutput(struct HdfDeviceIoClient *client, struct Hd static int32_t SerCodecSetCallback(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { - uint32_t handle = 0; + uint64_t handle = 0; UINTPTR instance; struct ICodecCallback *cb = NULL; - if (!HdfSbufReadUint32(data, &handle)) { + if (!HdfSbufReadUint64(data, &handle)) { HDF_LOGE("%{public}s: read handle data failed!", __func__); return HDF_ERR_INVALID_PARAM; } @@ -522,7 +539,7 @@ static int32_t SerCodecSetCallback(struct HdfDeviceIoClient *client, struct HdfS HDF_LOGE("%{public}s: read instance data failed!", __func__); return HDF_ERR_INVALID_PARAM; } - int32_t errNum = CodecSetCallback((CODEC_HANDLETYPE)&handle, &cb->callback, instance); + int32_t errNum = CodecSetCallback((CODEC_HANDLETYPE)(uintptr_t)handle, &cb->callback, instance); if (errNum != HDF_SUCCESS) { HDF_LOGE("%{public}s: call CodecSetCallback fuc failed!", __func__); return errNum; diff --git a/codec/hdi_service/codec_service_stub/stub_msgproc.c b/codec/hdi_service/codec_service_stub/stub_msgproc.c index fd91441de3e1384ae968f9ef28b63c2289f3db79..e056775d9f40a14316a6e713eafc01fe335a1ef5 100644 --- a/codec/hdi_service/codec_service_stub/stub_msgproc.c +++ b/codec/hdi_service/codec_service_stub/stub_msgproc.c @@ -14,6 +14,9 @@ */ #include "stub_msgproc.h" #include +#include + +#define HDF_LOG_TAG codec_hdi_stub int32_t CodecSerPackAlignment(struct HdfSBuf *reply, Alignment *alignment) { @@ -126,18 +129,33 @@ int32_t CodecSerParseParam(struct HdfSBuf *data, Param *param) HDF_LOGE("%{public}s: params null!", __func__); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufReadUint32(data, (uint32_t *)¶m->key)) { - HDF_LOGE("%{public}s: Read key failed!", __func__); + if (!HdfSbufReadInt32(data, (int32_t *)¶m->key)) { + HDF_LOGE("%{public}s: read param->key failed!", __func__); return HDF_FAILURE; } - if (!HdfSbufReadUint32(data, (uint32_t *)¶m->val)) { - HDF_LOGE("%{public}s: Read val failed!", __func__); + + int8_t *valCp = NULL; + int32_t valCpLen = 0; + if (!HdfSbufReadInt32(data, &valCpLen)) { + HDF_LOGE("%{public}s: read size failed!", __func__); return HDF_FAILURE; } - if (!HdfSbufReadInt32(data, (int32_t*)¶m->size)) { - HDF_LOGE("%{public}s: Read size failed!", __func__); - return HDF_FAILURE; + if (valCpLen > 0) { + valCp = (int8_t *)OsalMemCalloc(sizeof(int8_t) * valCpLen); + if (valCp == NULL) { + return HDF_FAILURE; + } + for (int32_t i = 0; i < valCpLen; i++) { + if (!HdfSbufReadInt8(data, &valCp[i])) { + HDF_LOGE("%{public}s: read valCp[i] failed!", __func__); + OsalMemFree(valCp); + return HDF_FAILURE; + } + } } + param->val = (void *)valCp; + param->size = valCpLen; + return HDF_SUCCESS; } @@ -147,18 +165,23 @@ int32_t CodecSerPackParam(struct HdfSBuf *reply, Param *param) HDF_LOGE("%{public}s: params null!", __func__); return HDF_ERR_INVALID_PARAM; } - if (!HdfSbufWriteUint32(reply, (uint32_t)param->key)) { - HDF_LOGE("%{public}s: write key failed!", __func__); - return HDF_FAILURE; - } - if (!HdfSbufWriteUint32(reply, (uint32_t)¶m->val)) { - HDF_LOGE("%{public}s: Write val failed!", __func__); - return HDF_FAILURE; + + if (!HdfSbufWriteInt32(reply, (int32_t)param->key)) { + HDF_LOGE("%{public}s: write param->key failed!", __func__); + return false; } + if (!HdfSbufWriteInt32(reply, param->size)) { - HDF_LOGE("%{public}s: write size failed!", __func__); - return HDF_FAILURE; + HDF_LOGE("%{public}s: write param->size failed!", __func__); + return false; } + for (int32_t i = 0; i < param->size; i++) { + if (!HdfSbufWriteInt8(reply, ((int8_t *)(param->val))[i])) { + HDF_LOGE("%{public}s: write (param->val)[i] failed!", __func__); + return false; + } + } + return HDF_SUCCESS; } @@ -400,4 +423,4 @@ int32_t CodecSerPackOutputInfo(struct HdfSBuf *reply, OutputInfo *outInfo) return HDF_FAILURE; } return HDF_SUCCESS; -} \ No newline at end of file +} diff --git a/codec/interfaces/include/codec_type.h b/codec/interfaces/include/codec_type.h index 5d6c557dcdccf9f25993e6690655f789ba76f2d8..ff2f9cd38a94b4a6a1d751a367b1c03f585eb428 100644 --- a/codec/interfaces/include/codec_type.h +++ b/codec/interfaces/include/codec_type.h @@ -94,6 +94,8 @@ typedef enum { KEY_SOUND_MODE, /**< Audio channel mode. For the value type, see {@link AudioSoundMode}. */ KEY_POINT_NUM_PER_FRAME, /**< Number of sampling points per frame. The value type is uint32_t. */ KEY_DEVICE_ID, /**< Device ID. The value type is uint32_t. */ + KEY_EXT_START = 0xF000, /**< Manufacture extended features. The keys should be defined in oem adapter files. */ + KEY_EXT_END = 0xFFFF, } ParamKey; /**