SET(EXEC_PREFIX "${CMAKE_INSTALL_PREFIX}/bin")
SET(INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include")
SET(LIBDIR ${CMAKE_LIBDIR_PREFIX})
-SET(VERSION_MAJOR 1)
-SET(VERSION "${VERSION_MAJOR}.0.0")
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/generated)
SET(PKG_MODULES
dlog
glib-2.0
+ rpc-port
+ bundle
+ capi-appfw-app-common
+ capi-appfw-app-manager
+ capi-appfw-package-manager
hal-api-common
)
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIC -Wall -Wextra -Wno-array-bounds -Wno-empty-body -Wno-ignored-qualifiers -Wno-unused-parameter -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-but-set-parameter -Wno-unused-but-set-variable")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -Wno-discarded-qualifiers")
-SET(SRCS src/hal-api-codec.c)
+SET(SRCS
+ src/generated/hal_codec_proxy_1.c
+ src/hal-api-codec.c
+ src/hal-api-codec-passthrough.c
+ src/hal-api-codec-ipc.c
+)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -Wl,--as-needed -Wl,--rpath=${LIBDIR}/hal)
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME}
+ PROPERTIES
+ VERSION ${FULLVER}
+ SOVERSION ${MAJORVER}
+)
CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig)
+ADD_SUBDIRECTORY(src/service_plugin)
+
IF(ENABLE_TESTS)
ADD_SUBDIRECTORY(tests)
ENDIF(ENABLE_TESTS)
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics 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 __HAL_CODEC_IPC__
+#define __HAL_CODEC_IPC__
+
+#include "hal-codec-interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define HAL_BACKEND_SERVICE_APPID "d::HalBackendService"
+
+#define HAL_CODEC_IPC_PARAM_KEY_BUFFER "HAL_CODEC_BUFFER_S"
+#define HAL_CODEC_IPC_PARAM_KEY_PLANE0_DATA "HAL_CODEC_PLANE0"
+#define HAL_CODEC_IPC_PARAM_KEY_PLANE1_DATA "HAL_CODEC_PLANE1"
+#define HAL_CODEC_IPC_PARAM_KEY_PLANE2_DATA "HAL_CODEC_PLANE2"
+#define HAL_CODEC_IPC_PARAM_KEY_PLANE3_DATA "HAL_CODEC_PLANE3"
+#define HAL_CODEC_IPC_PARAM_KEY_MESSAGE "HAL_CODEC_MESSAGE_S"
+
+#define HAL_CODEC_BUFFER_MAX 32
+
+
+int hal_codec_ipc_init(hal_codec_type_e type, void **codec_handle);
+int hal_codec_ipc_deinit(void *codec_handle);
+int hal_codec_ipc_configure(void *codec_handle, int width, int height, hal_codec_format_e in_format, hal_codec_format_e out_format, bool is_secure);
+int hal_codec_ipc_release(void *codec_handle);
+int hal_codec_ipc_start(void *codec_handle, hal_codec_message_cb callback, void *user_data);
+int hal_codec_ipc_stop(void *codec_handle);
+int hal_codec_ipc_flush(void *codec_handle);
+int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer);
+int hal_codec_ipc_encode(void *codec_handle, hal_codec_buffer_s *buffer);
+int hal_codec_ipc_release_output_buffer(void *codec_handle, int buffer_index);
+int hal_codec_ipc_get_state(void *codec_handle, hal_codec_state_e *state);
+int hal_codec_ipc_set_command(void *codec_handle, hal_codec_command_e command, void *value);
+int hal_codec_ipc_get_command(void *codec_handle, hal_codec_command_e command, void **value);
+int hal_codec_ipc_set_batch_command(void *codec_handle, hal_codec_batch_command_control_s *batch_command, hal_codec_command_e *error_command);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HAL_CODEC_IPC__ */
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics 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 __HAL_CODEC_PASSTHROUGH__
+#define __HAL_CODEC_PASSTHROUGH__
+
+#include "hal-codec-interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int hal_codec_passthrough_init(hal_codec_type_e type, void **codec_handle);
+int hal_codec_passthrough_deinit(void *codec_handle);
+int hal_codec_passthrough_configure(void *codec_handle, int width, int height, hal_codec_format_e in_format, hal_codec_format_e out_format, bool is_secure);
+int hal_codec_passthrough_release(void *codec_handle);
+int hal_codec_passthrough_start(void *codec_handle, hal_codec_message_cb callback, void *user_data);
+int hal_codec_passthrough_stop(void *codec_handle);
+int hal_codec_passthrough_flush(void *codec_handle);
+int hal_codec_passthrough_decode(void *codec_handle, hal_codec_buffer_s *buffer);
+int hal_codec_passthrough_encode(void *codec_handle, hal_codec_buffer_s *buffer);
+int hal_codec_passthrough_release_output_buffer(void *codec_handle, int buffer_index);
+int hal_codec_passthrough_get_state(void *codec_handle, hal_codec_state_e *state);
+int hal_codec_passthrough_set_command(void *codec_handle, hal_codec_command_e command, void *value);
+int hal_codec_passthrough_get_command(void *codec_handle, hal_codec_command_e command, void **value);
+int hal_codec_passthrough_set_batch_command(void *codec_handle, hal_codec_batch_command_control_s *batch_command, hal_codec_command_e *error_command);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HAL_CODEC_PASSTHROUGH__ */
--- /dev/null
+protocol 2
+
+interface codec {
+ void message(bundle msg, array<file_desc> fd) delegate;
+
+ int init(int type);
+ int deinit();
+
+ int configure(int width, int height, int in_format, int out_format, bool is_secure);
+ int release();
+
+ int start(message callback);
+ int stop();
+ int flush();
+
+ int decode(bundle buffer);
+ int encode(bundle buffer, array<file_desc> fd);
+ int release_output_buffer(int buffer_index);
+
+ int get_state(out int state);
+
+ int set_command(long command, bundle value);
+ int get_command(long command, out bundle value);
+ int set_batch_command(bundle command, out long error_command);
+}
+
<manifest platform-version="10.0">
<hal-module>
<name>HAL_MODULE_CODEC</name>
- <version>1.0</version>
+ <version transport="passthrough">1.0</version>
</hal-module>
</manifest>
</hal-api>
### main package #########
Name: %{name}
Summary: %{name} interface
-Version: 1.0.0
+Version: 1.1.0
Release: 0
Group: Development/Libraries
License: Apache-2.0
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(hal-api-common)
+BuildRequires: tidl
+BuildRequires: pkgconfig(rpc-port)
+BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(capi-appfw-app-common)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(capi-appfw-package-manager)
%if "%{enable_test}" == "1"
BuildRequires: pkgconfig(gmock)
%endif
### build and install #########
%prep
%setup -q
+
+mkdir -p ./src/generated
+pushd src/generated
+tidlc -p -l C -i ../../include/hal_codec_ipc_1.tidl -o hal_codec_proxy_1
+popd
+
+mkdir -p ./src/service_plugin/generated
+pushd src/service_plugin/generated
+tidlc -s -l C -i ../../../include/hal_codec_ipc_1.tidl -o hal_codec_stub_1
+popd
+
%if "%{enable_test}" == "1"
export CXXFLAGS+=" -D_LARGEFILE64_SOURCE -DSYSCONFDIR=\\\"%{_hal_sysconfdir}\\\" -DTEST_FILES_PATH=\\\"%{_datadir}%{res_path}\\\""
%endif
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
%cmake . \
%if "%{enable_test}" == "1"
-DENABLE_TESTS=YES\
-DTESTCASE_RES_DIR=%{_datadir}%{res_path}\
%endif
+ -DFULLVER=%{version}\
+ -DMAJORVER=${MAJORVER}\
-DCMAKE_INSTALL_PREFIX=%{_prefix}\
-DCMAKE_LIBDIR_PREFIX=%{_libdir}
%license LICENSE
%defattr(-,root,root,-)
%{_libdir}/hal/*.so.*
+%{_libdir}/hal/libhal-backend-service-codec.so
%{_sysconfdir}/hal/%{name}-manifest.xml
%files devel
%defattr(-,root,root,-)
%{_includedir}/hal/*.h
-%{_libdir}/hal/*.so
+%{_libdir}/hal/libhal-api-*.so
%{_libdir}/pkgconfig/*.pc
%if "%{enable_test}" == "1"
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics 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 <sys/mman.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <glib.h>
+
+#include <bundle.h>
+#include <hal/hal-common.h>
+
+#include "hal-codec-ipc.h"
+#include "hal_codec_proxy_1.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "HALAPI_CODEC_IPC"
+
+#define HAL_CODEC_IPC_CONNECT_COUNT_MAX 10
+
+
+#define HAL_CODEC_RETURN_IF_FAILED(arg) \
+ do {\
+ if (!(arg)) {\
+ SLOGE("[%s]failed", #arg);\
+ return;\
+ }\
+ } while (0)
+
+#define HAL_CODEC_RETURN_VAL_IF_FAILED(arg, ret) \
+ do {\
+ if (!(arg)) {\
+ SLOGE("[%s]failed, return[%s]", #arg, #ret);\
+ return (ret);\
+ }\
+ } while (0)
+
+typedef struct _hal_codec_ipc_s {
+ rpc_port_proxy_codec_h rpc_handle;
+ rpc_port_proxy_codec_message_h rpc_msg_handle;
+
+ hal_codec_message_cb msg_cb;
+ void *msg_cb_data;
+
+ GMutex buffer_lock;
+ GMutex msg_lock;
+
+ hal_codec_buffer_s *input_buffers[HAL_CODEC_BUFFER_MAX];
+ hal_codec_buffer_s *output_buffers[HAL_CODEC_BUFFER_MAX];
+} hal_codec_ipc_s;
+
+
+static void __hal_codec_ipc_connected(rpc_port_proxy_codec_h h, void *user_data)
+{
+ SLOGI("connected: handle[%p]", h);
+}
+
+
+static void __hal_codec_ipc_disconnected(rpc_port_proxy_codec_h h, void *user_data)
+{
+ SLOGI("disonnected: handle[%p]", h);
+}
+
+
+static void __hal_codec_ipc_rejected(rpc_port_proxy_codec_h h, void *user_data)
+{
+ SLOGE("connection rejected: handle[%p]", h);
+}
+
+
+static void __hal_codec_ipc_hal_buffer_release(hal_codec_buffer_s *hal_buffer)
+{
+ uint32_t i = 0;
+ size_t unmap_size = 0;
+
+ if (!hal_buffer) {
+ SLOGD("NULL buffer");
+ return;
+ }
+
+ SLOGD("release hal buffer[%d] %p", hal_buffer->index, hal_buffer);
+
+ for (i = 0 ; i < hal_buffer->memory.num_fd ; i++) {
+ if (hal_buffer->memory.fd[i] > 0) {
+ SLOGD(" close fd[%u] %d", i, hal_buffer->memory.fd[i]);
+ close(hal_buffer->memory.fd[i]);
+ hal_buffer->memory.fd[i] = 0;
+ } else {
+ SLOGW(" invalid fd[%u] %d", i, hal_buffer->memory.fd[i]);
+ }
+
+ if (hal_buffer->memory.num_fd == 1)
+ unmap_size = hal_buffer->size;
+ else
+ unmap_size = hal_buffer->planes.plane[i].size;
+
+ if (hal_buffer->planes.plane[i].data) {
+ SLOGD(" munmap data[%u] %p, size[%zu]", i, hal_buffer->planes.plane[i].data, unmap_size);
+ if (munmap(hal_buffer->planes.plane[i].data, unmap_size) != 0)
+ SLOGE(" munmap failed for data[%u] %p, size[%zu]", i, hal_buffer->planes.plane[i].data, unmap_size);
+ }
+ }
+
+ g_free(hal_buffer);
+}
+
+
+static void __hal_codec_ipc_message_cb(void *user_data, bundle *b_msg, rpc_port_proxy_array_file_desc_h fd_handle)
+{
+ int i = 0;
+ int ipc_ret = 0;
+ int *fd = NULL;
+ int fd_size = 0;
+ void *b_data = NULL;
+ size_t mmap_length = 0;
+ size_t hal_message_size = 0;
+ size_t hal_buffer_size = 0;
+ hal_codec_message_s *hal_message = NULL;
+ hal_codec_buffer_s *hal_buffer = NULL;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)user_data;
+
+ HAL_CODEC_RETURN_IF_FAILED(handle);
+ HAL_CODEC_RETURN_IF_FAILED(b_msg);
+ HAL_CODEC_RETURN_IF_FAILED(fd_handle);
+
+ /* message */
+ ipc_ret = bundle_get_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_MESSAGE, (void **)&hal_message, &hal_message_size);
+ if (ipc_ret != BUNDLE_ERROR_NONE ||
+ hal_message_size != sizeof(hal_codec_message_s)) {
+ SLOGE("get message from bundle failed[0x%x], size[%zu:%zu]",
+ ipc_ret, hal_message_size, sizeof(hal_codec_message_s));
+ return;
+ }
+
+ SLOGD("message: type[%d]", hal_message->type);
+
+ switch (hal_message->type) {
+ case HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED:
+ ipc_ret = bundle_get_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_BUFFER, (void **)&hal_buffer, &hal_buffer_size);
+ if (ipc_ret != BUNDLE_ERROR_NONE ||
+ hal_buffer_size != sizeof(hal_codec_buffer_s)) {
+ SLOGE("get message from bundle failed[0x%x], size[%zu:%zu]",
+ ipc_ret, hal_message_size, sizeof(hal_codec_message_s));
+ goto _CODEC_IPC_MESSAGE_CB_DONE;
+ }
+
+ if (hal_buffer->index >= HAL_CODEC_BUFFER_MAX) {
+ SLOGE("[INPUT_USED] invalid buffer index[%d]", hal_buffer->index);
+ goto _CODEC_IPC_MESSAGE_CB_DONE;
+ }
+
+ g_mutex_lock(&handle->buffer_lock);
+
+ if (!handle->input_buffers[hal_buffer->index]) {
+ SLOGE("[INPUT_USED] NULL buffer for index[%d]", hal_buffer->index);
+ g_mutex_unlock(&handle->buffer_lock);
+ goto _CODEC_IPC_MESSAGE_CB_DONE;
+ }
+
+ hal_message->buffer = handle->input_buffers[hal_buffer->index];
+ handle->input_buffers[hal_buffer->index] = NULL;
+
+ SLOGD("check index [%d] vs [%d]", hal_message->buffer->index, hal_buffer->index);
+
+ g_mutex_unlock(&handle->buffer_lock);
+
+ break;
+
+ case HAL_CODEC_MESSAGE_TYPE_OUTPUT_BUFFER:
+ ipc_ret = bundle_get_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_BUFFER, (void **)&b_data, &hal_buffer_size);
+ if (ipc_ret != BUNDLE_ERROR_NONE ||
+ hal_buffer_size != sizeof(hal_codec_buffer_s)) {
+ SLOGE("get message from bundle failed[0x%x], size[%zu:%zu]",
+ ipc_ret, hal_message_size, sizeof(hal_codec_message_s));
+ goto _CODEC_IPC_MESSAGE_CB_DONE;
+ }
+
+ hal_buffer = g_memdup2(b_data, hal_buffer_size);
+
+ ipc_ret = rpc_port_proxy_array_file_desc_get(fd_handle, &fd, &fd_size);
+ if (ipc_ret != RPC_PORT_ERROR_NONE ||
+ hal_buffer->memory.num_fd != (uint32_t)fd_size) {
+ SLOGE("get fd failed[0x%x], num_fd[%u] vs fd_size[%d]",
+ ipc_ret, hal_buffer->memory.num_fd, fd_size);
+ goto _CODEC_IPC_MESSAGE_CB_DONE;
+ }
+
+ for (i = 0 ; i < fd_size ; i++) {
+ SLOGD("[OUTPUT] fd[%d] %d", i, fd[i]);
+ hal_buffer->memory.fd[i] = fd[i];
+
+ if (fd_size == 1)
+ mmap_length = hal_buffer->size;
+ else
+ mmap_length = hal_buffer->planes.plane[i].size;
+
+ hal_buffer->planes.plane[i].data = mmap(NULL,
+ mmap_length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd[i], 0);
+ if (hal_buffer->planes.plane[i].data == MAP_FAILED) {
+ hal_buffer->planes.plane[i].data = NULL;
+ SLOGE(" mmap failed for fd[%d] %d", i, fd[i]);
+ } else {
+ SLOGD("plane[%d] data %p", i, hal_buffer->planes.plane[i].data);
+ }
+ }
+
+ if (fd_size != (int)hal_buffer->planes.num_planes) {
+ for (i = 1 ; i < (int)hal_buffer->planes.num_planes ; i++) {
+ hal_buffer->planes.plane[i].data = hal_buffer->planes.plane[i-1].data + hal_buffer->planes.plane[i-1].size;
+ SLOGD("plane[%d] data %p", i, hal_buffer->planes.plane[i].data);
+ }
+ }
+
+ g_mutex_lock(&handle->buffer_lock);
+
+ if (handle->output_buffers[hal_buffer->index]) {
+ SLOGE("duplicated buffer index[%d]", hal_buffer->index);
+ g_free(hal_buffer);
+ g_mutex_unlock(&handle->buffer_lock);
+ goto _CODEC_IPC_MESSAGE_CB_DONE;
+ }
+
+ hal_message->buffer = hal_buffer;
+ handle->output_buffers[hal_buffer->index] = hal_buffer;
+
+ g_mutex_unlock(&handle->buffer_lock);
+
+ /* The fd will be closed in release_output_buffer via hal_buffer. */
+ fd = NULL;
+ fd_size = 0;
+ break;
+
+ case HAL_CODEC_MESSAGE_TYPE_RESOLUTION_CHANGED:
+ break;
+
+ default:
+ break;
+ }
+
+ g_mutex_lock(&handle->msg_lock);
+
+ if (handle->msg_cb) {
+ SLOGD(">>>>> msg cb: type[%d]", hal_message->type);
+ ((hal_codec_message_cb)handle->msg_cb)(hal_message, handle->msg_cb_data);
+ SLOGD("<<<<< msg cb: type[%d]", hal_message->type);
+ } else {
+ SLOGW("no msg cb for handle[%p]", handle);
+
+ if (hal_message->type == HAL_CODEC_MESSAGE_TYPE_OUTPUT_BUFFER) {
+ SLOGW("release output buffer[%d]", hal_message->buffer->index);
+ hal_codec_ipc_release_output_buffer(handle, hal_message->buffer->index);
+ }
+ }
+
+ g_mutex_unlock(&handle->msg_lock);
+
+_CODEC_IPC_MESSAGE_CB_DONE:
+ for (i = 0 ; i < fd_size && fd ; i++) {
+ /* error case */
+ SLOGW("message type[%d]: close fd[%d] %d", hal_message->type, i, fd[i]);
+ close(fd[i]);
+ }
+}
+
+
+int hal_codec_ipc_init(hal_codec_type_e type, void **codec_handle)
+{
+ int ret = 0;
+ int connect_count = 0;
+ hal_codec_ipc_s *new_handle = NULL;
+ rpc_port_proxy_codec_callback_s rpc_callbacks = {
+ .connected = __hal_codec_ipc_connected,
+ .disconnected = __hal_codec_ipc_disconnected,
+ .rejected = __hal_codec_ipc_rejected
+ };
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(codec_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ SLOGI("start");
+
+ new_handle = g_new0(hal_codec_ipc_s, 1);
+
+ ret = rpc_port_proxy_codec_create(HAL_BACKEND_SERVICE_APPID,
+ &rpc_callbacks, NULL, &new_handle->rpc_handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("RPC handle failed[0x%x]", ret);
+ g_free(new_handle);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ while (connect_count++ < HAL_CODEC_IPC_CONNECT_COUNT_MAX) {
+ ret = rpc_port_proxy_codec_connect_sync(new_handle->rpc_handle);
+ if (ret == RPC_PORT_ERROR_NONE)
+ break;
+
+ SLOGW("RPC connect failed: ret[0x%x], retry(%d)...", ret, connect_count);
+
+ g_usleep(100000);
+ }
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ rpc_port_proxy_codec_destroy(new_handle->rpc_handle);
+ g_free(new_handle);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ ret = rpc_port_proxy_codec_invoke_init(new_handle->rpc_handle, type);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("invoke init failed[0x%x]", ret);
+ rpc_port_proxy_codec_destroy(new_handle->rpc_handle);
+ g_free(new_handle);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ g_mutex_init(&new_handle->buffer_lock);
+ g_mutex_init(&new_handle->msg_lock);
+
+ *codec_handle = (void *)new_handle;
+
+ SLOGI("new handle[%p:,rpc:%p]", new_handle, new_handle->rpc_handle);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+int hal_codec_ipc_deinit(void *codec_handle)
+{
+ int ret = 0;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ SLOGI("start");
+
+ ret = rpc_port_proxy_codec_invoke_deinit(handle->rpc_handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("invoke deinit failed[0x%x]", ret);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ if (handle->rpc_msg_handle) {
+ ret = rpc_port_proxy_codec_message_dispose(handle->rpc_handle, handle->rpc_msg_handle);
+ if (ret != RPC_PORT_ERROR_NONE)
+ rpc_port_proxy_codec_message_destroy(handle->rpc_msg_handle);
+ handle->rpc_msg_handle = NULL;
+ }
+
+ ret = rpc_port_proxy_codec_disconnect(handle->rpc_handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("disconnect failed: handle[%p], ret[%d]", handle->rpc_handle, ret);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ ret = rpc_port_proxy_codec_destroy(handle->rpc_handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("destroy failed: handle[%p], ret[%d]", handle->rpc_handle, ret);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ g_mutex_clear(&handle->buffer_lock);
+ g_mutex_clear(&handle->msg_lock);
+
+ SLOGI("release handle[%p]", handle);
+
+ g_free(handle);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+int hal_codec_ipc_configure(void *codec_handle, int width, int height, hal_codec_format_e in_format, hal_codec_format_e out_format, bool is_secure)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ return rpc_port_proxy_codec_invoke_configure(handle->rpc_handle, width, height, in_format, out_format, is_secure);
+}
+
+
+int hal_codec_ipc_release(void *codec_handle)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ return rpc_port_proxy_codec_invoke_release(handle->rpc_handle);
+}
+
+
+int hal_codec_ipc_start(void *codec_handle, hal_codec_message_cb callback, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int ipc_ret = 0;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+ rpc_port_proxy_codec_message_h msg_handle = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ ipc_ret = rpc_port_proxy_codec_message_create(&msg_handle);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("msg handle create failed[0x%x]", ipc_ret);
+ return HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ }
+
+ ipc_ret = rpc_port_proxy_codec_message_set_callback(msg_handle,
+ __hal_codec_ipc_message_cb, handle);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("set callback failed[0x%x]", ipc_ret);
+ rpc_port_proxy_codec_message_destroy(msg_handle);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ rpc_port_proxy_codec_message_set_once(msg_handle, false);
+
+ g_mutex_lock(&handle->msg_lock);
+
+ ret = rpc_port_proxy_codec_invoke_start(handle->rpc_handle, msg_handle);
+ if (ret == HAL_CODEC_ERROR_NONE) {
+ handle->msg_cb = callback;
+ handle->msg_cb_data = user_data;
+ handle->rpc_msg_handle = msg_handle;
+ } else {
+ SLOGE("start failed[0x%x]", ret);
+ rpc_port_proxy_codec_message_destroy(msg_handle);
+ }
+
+ g_mutex_unlock(&handle->msg_lock);
+
+ return ret;
+}
+
+
+int hal_codec_ipc_stop(void *codec_handle)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int ipc_ret = 0;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ ret = rpc_port_proxy_codec_invoke_stop(handle->rpc_handle);
+
+ g_mutex_lock(&handle->msg_lock);
+
+ if (ret == HAL_CODEC_ERROR_NONE) {
+ handle->msg_cb = NULL;
+ handle->msg_cb_data = NULL;
+
+ SLOGI("dispose msg handle[%p]", handle->rpc_msg_handle);
+
+ if (handle->rpc_msg_handle) {
+ ipc_ret = rpc_port_proxy_codec_message_dispose(handle->rpc_handle, handle->rpc_msg_handle);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ SLOGW("msg handle dispose failed[0x%x]", ipc_ret);
+ rpc_port_proxy_codec_message_destroy(handle->rpc_msg_handle);
+ }
+
+ handle->rpc_msg_handle = NULL;
+ }
+ }
+
+ g_mutex_unlock(&handle->msg_lock);
+
+ return ret;
+}
+
+
+int hal_codec_ipc_flush(void *codec_handle)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ return rpc_port_proxy_codec_invoke_flush(handle->rpc_handle);
+}
+
+
+int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int ipc_ret = 0;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+ bundle *b_buffer = NULL;
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(buffer, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ if (buffer->index >= HAL_CODEC_BUFFER_MAX) {
+ SLOGE("invalid buffer index[%d]", buffer->index);
+ return HAL_CODEC_ERROR_INVALID_PARAMETER;
+ }
+
+ locker = g_mutex_locker_new(&handle->buffer_lock);
+
+ if (handle->input_buffers[buffer->index]) {
+ SLOGE("already existed input buffer[%d] %p",
+ buffer->index, handle->input_buffers[buffer->index]);
+ return HAL_CODEC_ERROR_INVALID_PARAMETER;
+ }
+
+ b_buffer = bundle_create();
+ if (!b_buffer) {
+ SLOGE("bundle failed");
+ return HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ }
+
+ ipc_ret = bundle_add_byte(b_buffer, HAL_CODEC_IPC_PARAM_KEY_BUFFER,
+ (const char *)buffer, sizeof(hal_codec_buffer_s));
+ if (ipc_ret != BUNDLE_ERROR_NONE) {
+ SLOGE("add byte failed for buffer");
+ ret = HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ goto _IPC_DECODE_DONE;
+ }
+
+ ipc_ret = bundle_add_byte(b_buffer, HAL_CODEC_IPC_PARAM_KEY_PLANE0_DATA,
+ (const char *)buffer->planes.plane[0].data, buffer->planes.plane[0].size);
+ if (ipc_ret != BUNDLE_ERROR_NONE) {
+ SLOGE("add byte failed for buffer[%d] size[%u]", buffer->index, buffer->planes.plane[0].size);
+ ret = HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ goto _IPC_DECODE_DONE;
+ }
+
+ SLOGD("buffer[%d] size[%u]", buffer->index, buffer->size);
+
+ ret = rpc_port_proxy_codec_invoke_decode(handle->rpc_handle, b_buffer);
+
+ if (ret == HAL_CODEC_ERROR_NONE) {
+ SLOGD("set input buffer[%d] %p", buffer->index, buffer);
+ handle->input_buffers[buffer->index] = buffer;
+ }
+
+_IPC_DECODE_DONE:
+ bundle_free(b_buffer);
+
+ return ret;
+}
+
+
+int hal_codec_ipc_encode(void *codec_handle, hal_codec_buffer_s *buffer)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int ipc_ret = 0;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+ bundle *b_buffer = NULL;
+ rpc_port_proxy_array_file_desc_h fd_handle = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ b_buffer = bundle_create();
+ if (!b_buffer) {
+ SLOGE("bundle failed");
+ return HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ }
+
+ ipc_ret = bundle_add_byte(b_buffer, HAL_CODEC_IPC_PARAM_KEY_BUFFER,
+ (const char *)buffer, sizeof(hal_codec_buffer_s));
+ if (ipc_ret != BUNDLE_ERROR_NONE) {
+ SLOGE("add byte failed for buffer");
+ ret = HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ goto _IPC_ENCODE_DONE;
+ }
+
+ ipc_ret = rpc_port_proxy_array_file_desc_create(&fd_handle);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("fd handle create failed[0x%x]", ipc_ret);
+ ret = HAL_CODEC_ERROR_OUT_OF_MEMORY;
+ goto _IPC_ENCODE_DONE;
+ }
+
+ ipc_ret = rpc_port_proxy_array_file_desc_set(fd_handle, buffer->memory.fd, buffer->memory.num_fd);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ SLOGE("fd set failed[0x%x]", ipc_ret);
+ ret = HAL_CODEC_ERROR_INTERNAL;
+ goto _IPC_ENCODE_DONE;
+ }
+
+ ipc_ret = rpc_port_proxy_codec_invoke_encode(handle->rpc_handle, b_buffer, fd_handle);
+
+_IPC_ENCODE_DONE:
+ if (fd_handle)
+ rpc_port_proxy_array_file_desc_destroy(fd_handle);
+
+ bundle_free(b_buffer);
+
+ return ret;
+}
+
+
+int hal_codec_ipc_release_output_buffer(void *codec_handle, int buffer_index)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ ret = rpc_port_proxy_codec_invoke_release_output_buffer(handle->rpc_handle, buffer_index);
+
+ g_mutex_lock(&handle->buffer_lock);
+
+ if (ret == HAL_CODEC_ERROR_NONE) {
+ if (handle->output_buffers[buffer_index]) {
+ __hal_codec_ipc_hal_buffer_release(handle->output_buffers[buffer_index]);
+ handle->output_buffers[buffer_index] = NULL;
+ } else {
+ SLOGW("[OUTPUT] no buffer for index[%d]", buffer_index);
+ }
+ }
+
+ g_mutex_unlock(&handle->buffer_lock);
+
+ return ret;
+}
+
+
+int hal_codec_ipc_get_state(void *codec_handle, hal_codec_state_e *state)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(state, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ return rpc_port_proxy_codec_invoke_get_state(handle->rpc_handle, (int *)state);
+}
+
+
+int hal_codec_ipc_set_command(void *codec_handle, hal_codec_command_e command, void *value)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(value, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ /* TODO: It's not used yet, but it will be updated later. */
+
+ return HAL_CODEC_ERROR_NOT_IMPLEMENTED;
+}
+
+
+int hal_codec_ipc_get_command(void *codec_handle, hal_codec_command_e command, void **value)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(value, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ /* TODO: It's not used yet, but it will be updated later. */
+
+ return HAL_CODEC_ERROR_NOT_IMPLEMENTED;
+}
+
+
+int hal_codec_ipc_set_batch_command(void *codec_handle, hal_codec_batch_command_control_s *batch_command, hal_codec_command_e *error_command)
+{
+ hal_codec_ipc_s *handle = (hal_codec_ipc_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(batch_command, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->rpc_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ /* TODO: It's not used yet, but it will be updated later. */
+
+ return HAL_CODEC_ERROR_NOT_IMPLEMENTED;
+}
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics 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 <stdio.h>
+#include <stdint.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <glib.h>
+
+#include <hal/hal-common.h>
+
+#include "hal-codec-passthrough.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "HALAPI_CODEC_PT"
+
+#define HAL_CODEC_RETURN_VAL_IF_FAILED(arg, ret) \
+ do {\
+ if (!(arg)) {\
+ SLOGE("[%s]failed, return[%s]", #arg, #ret);\
+ return (ret);\
+ }\
+ } while (0)
+
+
+typedef struct _hal_codec_s {
+ void *backend;
+ hal_backend_codec_funcs *funcs;
+} hal_codec_s;
+
+
+static int __hal_codec_passthrough_init_backend(void **data, void *user_data)
+{
+ if (!data) {
+ SLOGE("NULL data");
+ return -EINVAL;
+ }
+
+ *data = g_new0(hal_backend_codec_funcs, 1);
+
+ SLOGI("new - codec HAL funcs[%p], size[%zu]",
+ *data, sizeof(hal_backend_codec_funcs));
+
+ return 0;
+}
+
+
+static int __hal_codec_passthrough_exit_backend(void *data, void *user_data)
+{
+ if (!data) {
+ SLOGE("NULL data");
+ return -EINVAL;
+ }
+
+ SLOGI("release - codec HAL funcs[%p], size[%zu]",
+ data, sizeof(hal_backend_codec_funcs));
+
+ g_free(data);
+
+ return 0;
+}
+
+
+int hal_codec_passthrough_init(hal_codec_type_e type, void **codec_handle)
+{
+ int ret = 0;
+ hal_codec_s *new_handle = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(codec_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ SLOGI("start");
+
+ new_handle = g_new0(hal_codec_s, 1);
+
+ ret = hal_common_get_backend_v2(HAL_MODULE_CODEC,
+ (void **)&new_handle->funcs,
+ NULL,
+ __hal_codec_passthrough_init_backend);
+ if (ret != 0) {
+ SLOGE("Failed to get backend");
+ goto __HAL_INIT_FAILED;
+ }
+
+ if (!new_handle->funcs || !new_handle->funcs->init) {
+ SLOGE("invalid ptr[%p]", new_handle->funcs);
+ goto __HAL_INIT_FAILED;
+ }
+
+ ret = new_handle->funcs->init(type, &new_handle->backend);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ SLOGE("backend init failed[0x%x]", ret);
+ goto __HAL_INIT_FAILED;
+ }
+
+ *codec_handle = (void *)new_handle;
+
+ SLOGI("done");
+
+ return HAL_CODEC_ERROR_NONE;
+
+__HAL_INIT_FAILED:
+ if (new_handle->funcs) {
+ hal_common_put_backend_v2(HAL_MODULE_CODEC,
+ (void *)new_handle->funcs,
+ NULL,
+ __hal_codec_passthrough_exit_backend);
+ }
+
+ g_free(new_handle);
+
+ return HAL_CODEC_ERROR_INTERNAL;
+}
+
+
+int hal_codec_passthrough_deinit(void *codec_handle)
+{
+ int ret = 0;
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->deinit, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ SLOGI("start");
+
+ ret = handle->funcs->deinit(handle->backend);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ SLOGE("deinit failed[0x%x]", ret);
+ return ret;
+ }
+
+ hal_common_put_backend_v2(HAL_MODULE_CODEC,
+ (void *)handle->funcs,
+ NULL,
+ __hal_codec_passthrough_exit_backend);
+
+ g_free(handle);
+
+ SLOGI("done");
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+int hal_codec_passthrough_configure(void *codec_handle, int width, int height, hal_codec_format_e in_format, hal_codec_format_e out_format, bool is_secure)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->configure, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->configure(handle->backend, width, height, in_format, out_format, is_secure);
+}
+
+
+int hal_codec_passthrough_release(void *codec_handle)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->release, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->release(handle->backend);
+}
+
+
+int hal_codec_passthrough_start(void *codec_handle, hal_codec_message_cb callback, void *user_data)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->start, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->start(handle->backend, callback, user_data);
+}
+
+
+int hal_codec_passthrough_stop(void *codec_handle)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->stop, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->stop(handle->backend);
+}
+
+
+int hal_codec_passthrough_flush(void *codec_handle)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->flush, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->flush(handle->backend);
+}
+
+
+int hal_codec_passthrough_decode(void *codec_handle, hal_codec_buffer_s *buffer)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->decode, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->decode(handle->backend, buffer);
+}
+
+
+int hal_codec_passthrough_encode(void *codec_handle, hal_codec_buffer_s *buffer)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->encode, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->encode(handle->backend, buffer);
+}
+
+
+int hal_codec_passthrough_release_output_buffer(void *codec_handle, int buffer_index)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->release_output_buffer, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->release_output_buffer(handle->backend, buffer_index);
+}
+
+
+int hal_codec_passthrough_get_state(void *codec_handle, hal_codec_state_e *state)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->get_state, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->get_state(handle->backend, state);
+}
+
+
+int hal_codec_passthrough_set_command(void *codec_handle, hal_codec_command_e command, void *value)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->set_command, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->set_command(handle->backend, command, value);
+}
+
+
+int hal_codec_passthrough_get_command(void *codec_handle, hal_codec_command_e command, void **value)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->get_command, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->get_command(handle->backend, command, value);
+}
+
+
+int hal_codec_passthrough_set_batch_command(void *codec_handle, hal_codec_batch_command_control_s *batch_command, hal_codec_command_e *error_command)
+{
+ hal_codec_s *handle = (hal_codec_s *)codec_handle;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_RETURN_VAL_IF_FAILED(handle->funcs->set_batch_command, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+
+ return handle->funcs->set_batch_command(handle->backend, batch_command, error_command);
+}
#include <hal/hal-common.h>
#include "hal-codec.h"
+#include "hal-codec-passthrough.h"
+#include "hal-codec-ipc.h"
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "HALAPI_CODEC"
-#define HAL_CODEC_RETURN_IF_FAILED(arg, ret) \
- do {\
- if (!(arg)) {\
- SLOGE("[%s]failed, return[%s]", #arg, #ret);\
- return (ret);\
- }\
- } while (0)
+#define HAL_CODEC_IS_TRANSPORT_IPC (g_hal_codec_transport == HAL_COMMON_TRANSPORT_IPC)
-#define HAL_CODEC_DO_RETURN_IF_FAILED(arg, do_something, ret) \
- do {\
- if (!(arg)) {\
- SLOGE("[%s]failed, return[%s]", #arg, #ret);\
- do_something;\
- return (ret);\
- }\
- } while (0);
+static enum hal_common_transport g_hal_codec_transport;
+static void __hal_codec_constructor(void) __attribute__((constructor));
-typedef struct _hal_codec_s {
- void *backend;
- hal_backend_codec_funcs *funcs;
-} hal_codec_s;
-
-static int hal_codec_init_backend(void **data, void *user_data)
+static void __hal_codec_constructor(void)
{
- if (!data) {
- SLOGE("NULL data");
- return -EINVAL;
- }
-
- *data = g_new0(hal_backend_codec_funcs, 1);
-
- SLOGI("new - codec HAL funcs[%p], size[%zu]",
- *data, sizeof(hal_backend_codec_funcs));
-
- return 0;
-}
-
+ int ret = 0;
-static int hal_codec_exit_backend(void *data, void *user_data)
-{
- if (!data) {
- SLOGE("NULL data");
- return -EINVAL;
+ ret = hal_common_get_transport(HAL_MODULE_CODEC, &g_hal_codec_transport);
+ if (ret < 0) {
+ SLOGW("failed to get transport for Codec HAL, set default(PASSTHROUGH)");
+ g_hal_codec_transport = HAL_COMMON_TRANSPORT_PASSTHROUGH;
}
- SLOGI("release - codec HAL funcs[%p], size[%zu]",
- data, sizeof(hal_backend_codec_funcs));
-
- g_free(data);
-
- return 0;
+ SLOGI("transport[%d]", g_hal_codec_transport);
}
int hal_codec_init(hal_codec_type_e type, void **codec_handle)
{
- int ret = 0;
- hal_codec_s *new_handle = NULL;
-
- HAL_CODEC_RETURN_IF_FAILED(codec_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
-
- SLOGI("start");
-
- new_handle = g_new0(hal_codec_s, 1);
-
- ret = hal_common_get_backend_v2(HAL_MODULE_CODEC,
- (void **)&new_handle->funcs,
- NULL,
- hal_codec_init_backend);
- if (ret != 0) {
- SLOGE("Failed to get backend");
- goto __HAL_INIT_FAILED;
- }
-
- if (!new_handle->funcs || !new_handle->funcs->init) {
- SLOGE("invalid ptr[%p]", new_handle->funcs);
- goto __HAL_INIT_FAILED;
- }
-
- ret = new_handle->funcs->init(type, &new_handle->backend);
- if (ret != HAL_CODEC_ERROR_NONE) {
- SLOGE("backend init failed[0x%x]", ret);
- goto __HAL_INIT_FAILED;
- }
-
- *codec_handle = (void *)new_handle;
-
- SLOGI("done");
-
- return HAL_CODEC_ERROR_NONE;
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_init(type, codec_handle);
-__HAL_INIT_FAILED:
- if (new_handle->funcs) {
- hal_common_put_backend_v2(HAL_MODULE_CODEC,
- (void *)new_handle->funcs,
- NULL,
- hal_codec_exit_backend);
- }
-
- g_free(new_handle);
-
- return HAL_CODEC_ERROR_INTERNAL;
+ return hal_codec_passthrough_init(type, codec_handle);
}
int hal_codec_deinit(void *codec_handle)
{
- int ret = 0;
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->deinit, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
-
- SLOGI("start");
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_deinit(codec_handle);
- ret = handle->funcs->deinit(handle->backend);
- if (ret != HAL_CODEC_ERROR_NONE) {
- SLOGE("deinit failed[0x%x]", ret);
- return ret;
- }
-
- hal_common_put_backend_v2(HAL_MODULE_CODEC,
- (void *)handle->funcs,
- NULL,
- hal_codec_exit_backend);
-
- g_free(handle);
-
- SLOGI("done");
-
- return HAL_CODEC_ERROR_NONE;
+ return hal_codec_passthrough_deinit(codec_handle);
}
int hal_codec_configure(void *codec_handle, int width, int height, hal_codec_format_e in_format, hal_codec_format_e out_format, bool is_secure)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->configure, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_configure(codec_handle, width, height, in_format, out_format, is_secure);
- return handle->funcs->configure(handle->backend, width, height, in_format, out_format, is_secure);
+ return hal_codec_passthrough_configure(codec_handle, width, height, in_format, out_format, is_secure);
}
int hal_codec_release(void *codec_handle)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_release(codec_handle);
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->release, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
-
- return handle->funcs->release(handle->backend);
+ return hal_codec_passthrough_release(codec_handle);
}
int hal_codec_start(void *codec_handle, hal_codec_message_cb callback, void *user_data)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->start, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_start(codec_handle, callback, user_data);
- return handle->funcs->start(handle->backend, callback, user_data);
+ return hal_codec_passthrough_start(codec_handle, callback, user_data);
}
int hal_codec_stop(void *codec_handle)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->stop, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_stop(codec_handle);
- return handle->funcs->stop(handle->backend);
+ return hal_codec_passthrough_stop(codec_handle);
}
int hal_codec_flush(void *codec_handle)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_flush(codec_handle);
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->flush, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
-
- return handle->funcs->flush(handle->backend);
+ return hal_codec_passthrough_flush(codec_handle);
}
int hal_codec_decode(void *codec_handle, hal_codec_buffer_s *buffer)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->decode, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_decode(codec_handle, buffer);
- return handle->funcs->decode(handle->backend, buffer);
+ return hal_codec_passthrough_decode(codec_handle, buffer);
}
int hal_codec_encode(void *codec_handle, hal_codec_buffer_s *buffer)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->encode, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_encode(codec_handle, buffer);
- return handle->funcs->encode(handle->backend, buffer);
+ return hal_codec_passthrough_encode(codec_handle, buffer);
}
int hal_codec_release_output_buffer(void *codec_handle, int buffer_index)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_release_output_buffer(codec_handle, buffer_index);
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->release_output_buffer, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
-
- return handle->funcs->release_output_buffer(handle->backend, buffer_index);
+ return hal_codec_passthrough_release_output_buffer(codec_handle, buffer_index);
}
int hal_codec_get_state(void *codec_handle, hal_codec_state_e *state)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->get_state, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_get_state(codec_handle, state);
- return handle->funcs->get_state(handle->backend, state);
+ return hal_codec_passthrough_get_state(codec_handle, state);
}
int hal_codec_set_command(void *codec_handle, hal_codec_command_e command, void *value)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->set_command, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_set_command(codec_handle, command, value);
- return handle->funcs->set_command(handle->backend, command, value);
+ return hal_codec_passthrough_set_command(codec_handle, command, value);
}
int hal_codec_get_command(void *codec_handle, hal_codec_command_e command, void **value)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_get_command(codec_handle, command, value);
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->get_command, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
-
- return handle->funcs->get_command(handle->backend, command, value);
+ return hal_codec_passthrough_get_command(codec_handle, command, value);
}
int hal_codec_set_batch_command(void *codec_handle, hal_codec_batch_command_control_s *batch_command, hal_codec_command_e *error_command)
{
- hal_codec_s *handle = (hal_codec_s *)codec_handle;
-
- HAL_CODEC_RETURN_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs, HAL_CODEC_ERROR_INVALID_PARAMETER);
- HAL_CODEC_RETURN_IF_FAILED(handle->funcs->set_batch_command, HAL_CODEC_ERROR_NOT_IMPLEMENTED);
+ if (HAL_CODEC_IS_TRANSPORT_IPC)
+ return hal_codec_ipc_set_batch_command(codec_handle, batch_command, error_command);
- return handle->funcs->set_batch_command(handle->backend, batch_command, error_command);
+ return hal_codec_passthrough_set_batch_command(codec_handle, batch_command, error_command);
}
--- /dev/null
+PROJECT(hal-backend-service-codec)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include")
+SET(LIBDIR ${CMAKE_LIBDIR_PREFIX})
+SET(VERSION_MAJOR 1)
+SET(VERSION "${VERSION_MAJOR}.0.0")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/generated)
+
+SET(PKG_MODULES
+ dlog
+ glib-2.0
+ rpc-port
+ bundle
+ capi-appfw-app-common
+ capi-appfw-app-manager
+ capi-appfw-package-manager
+ hal-api-common
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${PKG_MODULES})
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(SRCS
+ ${CMAKE_SOURCE_DIR}/src/hal-api-codec-passthrough.c
+ generated/hal_codec_stub_1.c
+ hal-backend-service-codec.c
+)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR}/hal)
+
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics 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 <stdint.h>
+#include <dlog.h>
+#include <glib.h>
+#include <hal/hal-common.h>
+
+#include "hal_codec_stub_1.h"
+#include "hal-codec.h"
+#include "hal-codec-ipc.h"
+#include "hal-codec-passthrough.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "HAL_BACKEND_SERVICE_CODEC"
+
+#define HAL_CODEC_SERVICE_MSG_LOGE(format, ...) SLOGE(format, ##__VA_ARGS__)
+#define HAL_CODEC_SERVICE_MSG_LOGW(format, ...) SLOGW(format, ##__VA_ARGS__)
+#define HAL_CODEC_SERVICE_MSG_LOGI(format, ...) SLOGI(format, ##__VA_ARGS__)
+#define HAL_CODEC_SERVICE_MSG_LOGD(format, ...) SLOGD(format, ##__VA_ARGS__)
+
+#define HAL_CODEC_MSG_RETURN_VAL_IF_FAILED(arg, ret) \
+ do {\
+ if (!(arg)) {\
+ HAL_CODEC_SERVICE_MSG_LOGE("[%s]failed, return[%s]", #arg, #ret);\
+ return (ret);\
+ }\
+ } while (0)
+
+#define HAL_CODEC_SERVICE_LOGE(format, ...) SLOGE("context[%p] "format, context, ##__VA_ARGS__)
+#define HAL_CODEC_SERVICE_LOGW(format, ...) SLOGW("context[%p] "format, context, ##__VA_ARGS__)
+#define HAL_CODEC_SERVICE_LOGI(format, ...) SLOGI("context[%p] "format, context, ##__VA_ARGS__)
+#define HAL_CODEC_SERVICE_LOGD(format, ...) SLOGD("context[%p] "format, context, ##__VA_ARGS__)
+
+#define HAL_CODEC_RETURN_IF_FAILED(arg) \
+ do {\
+ if (!(arg)) {\
+ HAL_CODEC_SERVICE_LOGE("[%s]failed", #arg);\
+ return;\
+ }\
+ } while (0)
+
+#define HAL_CODEC_RETURN_VAL_IF_FAILED(arg, ret) \
+ do {\
+ if (!(arg)) {\
+ HAL_CODEC_SERVICE_LOGE("[%s]failed, return[%s]", #arg, #ret);\
+ return (ret);\
+ }\
+ } while (0)
+
+
+typedef struct _hal_codec_service_s {
+ void *codec_handle;
+ rpc_port_stub_codec_message_h cb_handle;
+ GMutex cb_lock;
+} hal_codec_service_s;
+
+
+
+static hal_codec_service_s *__hal_codec_service_get_handle(rpc_port_stub_codec_context_h context)
+{
+ int ipc_ret = 0;
+ hal_codec_service_s *service_handle = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(context, NULL);
+
+ ipc_ret = rpc_port_stub_codec_context_get_tag(context, (void **)&service_handle);
+ if (ipc_ret != RPC_PORT_ERROR_NONE || service_handle == NULL) {
+ HAL_CODEC_SERVICE_LOGE("get handle[%p] from context[%p] failed[0x%x]",
+ service_handle, context, ipc_ret);
+ return NULL;
+ }
+
+ HAL_CODEC_SERVICE_LOGI("handle[%p, %p]", service_handle, service_handle->codec_handle);
+
+ return service_handle;
+}
+
+
+static int __hal_codec_service_message_cb(hal_codec_message_s *message, void *user_data)
+{
+ int ipc_ret = 0;
+ hal_codec_buffer_s *buffer = NULL;
+ bundle *b_msg = NULL;
+ rpc_port_stub_array_file_desc_h fd_handle = NULL;
+ hal_codec_service_s *service_handle = (hal_codec_service_s *)user_data;
+
+ HAL_CODEC_MSG_RETURN_VAL_IF_FAILED(message, HAL_CODEC_ERROR_INVALID_PARAMETER);
+ HAL_CODEC_MSG_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
+
+ HAL_CODEC_SERVICE_MSG_LOGD("message[%p] type[%d] handle[service:%p,cb_handle:%p]",
+ message, message->type, service_handle, service_handle->cb_handle);
+
+ b_msg = bundle_create();
+ ipc_ret = bundle_add_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_MESSAGE, (const void *)message, sizeof(hal_codec_message_s));
+ if (ipc_ret != BUNDLE_ERROR_NONE) {
+ HAL_CODEC_SERVICE_MSG_LOGE("add byte for message[type:%d] failed[0x%x]", message->type, ipc_ret);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ switch (message->type) {
+ case HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED:
+ buffer = message->buffer;
+ if (!buffer) {
+ HAL_CODEC_SERVICE_MSG_LOGE("NULL buffer for INPUT_BUFFER_USED, message[%p]", message);
+ goto _SERVICE_MESSAGE_CB_DONE;
+ }
+
+ bundle_add_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_BUFFER, (const void *)buffer, sizeof(hal_codec_buffer_s));
+
+ HAL_CODEC_SERVICE_MSG_LOGD("[INPUT_BUFFER_USED] buffer[%p, index:%d, num_fd:%d] fd[%d:%d:%d:%d]",
+ buffer, buffer->index, buffer->memory.num_fd,
+ buffer->memory.fd[0],
+ buffer->memory.fd[1],
+ buffer->memory.fd[2],
+ buffer->memory.fd[3]);
+
+ rpc_port_stub_array_file_desc_create(&fd_handle);
+ rpc_port_stub_array_file_desc_set(fd_handle, (int *)buffer->memory.fd, buffer->memory.num_fd);
+
+ for (uint32_t i = 0; i < buffer->planes.num_planes; i++) {
+ HAL_CODEC_SERVICE_MSG_LOGD("free INPUT_BUFFER[%d] %p", i, buffer->planes.plane[i].data);
+ g_free(buffer->planes.plane[i].data);
+ }
+
+ g_free(buffer);
+ break;
+
+ case HAL_CODEC_MESSAGE_TYPE_OUTPUT_BUFFER:
+ buffer = message->buffer;
+ if (!buffer) {
+ HAL_CODEC_SERVICE_MSG_LOGE("NULL buffer for OUTPUT_BUFFER, message[%p]", message);
+ goto _SERVICE_MESSAGE_CB_DONE;
+ }
+
+ HAL_CODEC_SERVICE_MSG_LOGD("[OUTPUT_BUFFER] buffer[%p, index:%d, num_planes:%d] fd[%d:%d:%d:%d]",
+ buffer, buffer->index, buffer->planes.num_planes,
+ buffer->memory.fd[0],
+ buffer->memory.fd[1],
+ buffer->memory.fd[2],
+ buffer->memory.fd[3]);
+
+ bundle_add_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_BUFFER, (const void *)buffer, sizeof(hal_codec_buffer_s));
+
+ rpc_port_stub_array_file_desc_create(&fd_handle);
+ rpc_port_stub_array_file_desc_set(fd_handle, (int *)buffer->memory.fd, buffer->memory.num_fd);
+ break;
+
+ default:
+ break;
+ }
+
+ g_mutex_lock(&service_handle->cb_lock);
+
+ if (service_handle->cb_handle == NULL) {
+ HAL_CODEC_SERVICE_MSG_LOGW("NULL cb_handle");
+ g_mutex_unlock(&service_handle->cb_lock);
+ goto _SERVICE_MESSAGE_CB_DONE;
+ }
+
+ ipc_ret = rpc_port_stub_codec_message_invoke(service_handle->cb_handle, b_msg, fd_handle);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ HAL_CODEC_SERVICE_MSG_LOGE("Failed to invoke message_cb");
+ g_mutex_unlock(&service_handle->cb_lock);
+ goto _SERVICE_MESSAGE_CB_DONE;
+ }
+
+ g_mutex_unlock(&service_handle->cb_lock);
+
+ HAL_CODEC_SERVICE_MSG_LOGD("invoke message: type[%d]", message->type);
+
+_SERVICE_MESSAGE_CB_DONE:
+ bundle_free(b_msg);
+ rpc_port_stub_array_file_desc_destroy(fd_handle);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+static void _hal_codec_service_rpc_create(rpc_port_stub_codec_context_h context, void *user_data)
+{
+ HAL_CODEC_SERVICE_LOGI("create");
+}
+
+
+static void _hal_codec_service_rpc_terminate(rpc_port_stub_codec_context_h context, void *user_data)
+{
+ HAL_CODEC_SERVICE_LOGI("terminate");
+}
+
+
+static int _hal_codec_service_backend_init(rpc_port_stub_codec_context_h context, int type, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int rpc_ret = RPC_PORT_ERROR_NONE;
+ hal_codec_service_s *service_handle = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(context, HAL_CODEC_ERROR_INTERNAL);
+
+ HAL_CODEC_SERVICE_LOGI("type[%d]", type);
+
+ service_handle = g_new0(hal_codec_service_s, 1);
+
+ ret = hal_codec_passthrough_init(type, &service_handle->codec_handle);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("backend init failed[0x%x]", ret);
+ g_free(service_handle);
+ return ret;
+ }
+
+ rpc_ret = rpc_port_stub_codec_context_set_tag(context, (char *)service_handle);
+ if (rpc_ret != RPC_PORT_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("set handle to context failed[0x%x]", rpc_ret);
+ hal_codec_passthrough_deinit(service_handle->codec_handle);
+ g_free(service_handle);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ g_mutex_init(&service_handle->cb_lock);
+
+ HAL_CODEC_SERVICE_LOGI("new handle: service[%p], codec[%p]",
+ service_handle, service_handle->codec_handle);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+static int _hal_codec_service_backend_deinit(rpc_port_stub_codec_context_h context, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ ret = hal_codec_passthrough_deinit(service_handle->codec_handle);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("deinit failed[0x%x]", ret);
+ return ret;
+ }
+
+ service_handle->codec_handle = NULL;
+
+ if (service_handle->cb_handle) {
+ HAL_CODEC_SERVICE_LOGW("remove remained cb_handle[%p]", service_handle->cb_handle);
+ rpc_port_stub_codec_message_destroy(service_handle->cb_handle);
+ service_handle->cb_handle = NULL;
+ }
+
+ HAL_CODEC_SERVICE_LOGI("reset tag[service_handle:%p] in context", service_handle);
+
+ rpc_port_stub_codec_context_set_tag(context, NULL);
+
+ g_mutex_clear(&service_handle->cb_lock);
+
+ g_free(service_handle);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+static int _hal_codec_service_backend_configure(rpc_port_stub_codec_context_h context,
+ int width, int height, int in_format, int out_format, bool is_secure, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ HAL_CODEC_SERVICE_LOGI("[%dx%d], format[in:%d,out:%d], secure[%d]",
+ width, height, in_format, out_format, is_secure);
+
+ ret = hal_codec_passthrough_configure(service_handle->codec_handle,
+ width, height, in_format, out_format, is_secure);
+
+ if (ret != HAL_CODEC_ERROR_NONE)
+ HAL_CODEC_SERVICE_LOGE("configure failed[0x%x]", ret);
+
+ return ret;
+}
+
+
+static int _hal_codec_service_backend_release(rpc_port_stub_codec_context_h context, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ ret = hal_codec_passthrough_release(service_handle->codec_handle);
+
+ if (ret != HAL_CODEC_ERROR_NONE)
+ HAL_CODEC_SERVICE_LOGE("release failed[0x%x]", ret);
+
+ return ret;
+}
+
+
+static int _hal_codec_service_backend_start(rpc_port_stub_codec_context_h context, rpc_port_stub_codec_message_h cb_handle, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int ipc_ret = 0;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+ rpc_port_stub_codec_message_h cb_handle_new = NULL;
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ ipc_ret = rpc_port_stub_codec_message_clone(cb_handle, &cb_handle_new);
+ if (ipc_ret != RPC_PORT_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("msg cb handle clone failed[0x%x]", ipc_ret);
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ g_mutex_lock(&service_handle->cb_lock);
+ service_handle->cb_handle = cb_handle_new;
+ g_mutex_unlock(&service_handle->cb_lock);
+
+ ret = hal_codec_passthrough_start(service_handle->codec_handle,
+ __hal_codec_service_message_cb, service_handle);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("start failed[0x%x]", ret);
+ rpc_port_stub_codec_message_destroy(cb_handle_new);
+ service_handle->cb_handle = NULL;
+ }
+
+ return ret;
+}
+
+
+static int _hal_codec_service_backend_stop(rpc_port_stub_codec_context_h context, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ ret = hal_codec_passthrough_stop(service_handle->codec_handle);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("stop failed[0x%x]", ret);
+ return ret;
+ }
+
+ HAL_CODEC_SERVICE_LOGD("release cb_handle[%p]", service_handle->cb_handle);
+ rpc_port_stub_codec_message_destroy(service_handle->cb_handle);
+
+ g_mutex_lock(&service_handle->cb_lock);
+ service_handle->cb_handle = NULL;
+ g_mutex_unlock(&service_handle->cb_lock);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
+static int _hal_codec_service_backend_flush(rpc_port_stub_codec_context_h context, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ ret = hal_codec_passthrough_flush(service_handle->codec_handle);
+
+ if (ret != HAL_CODEC_ERROR_NONE)
+ HAL_CODEC_SERVICE_LOGE("flush failed[0x%x]", ret);
+
+ return ret;
+}
+
+
+static int _hal_codec_service_backend_decode(rpc_port_stub_codec_context_h context, bundle *b_buffer, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ int ipc_ret = 0;
+ void *b_data = NULL;
+ size_t b_size = 0;
+ hal_codec_buffer_s *buffer = NULL;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ ipc_ret = bundle_get_byte(b_buffer, HAL_CODEC_IPC_PARAM_KEY_BUFFER, &b_data, &b_size);
+ if (ipc_ret != BUNDLE_ERROR_NONE || b_data == NULL || b_size != sizeof(hal_codec_buffer_s)) {
+ HAL_CODEC_SERVICE_LOGE("get data to decode failed[0x%x,%p,%zu/%zu",
+ ipc_ret, b_data, b_size, sizeof(hal_codec_buffer_s));
+ return HAL_CODEC_ERROR_INTERNAL;
+ }
+
+ buffer = (hal_codec_buffer_s *)g_memdup2(b_data, b_size);
+
+ b_data = NULL;
+ b_size = 0;
+
+ ipc_ret = bundle_get_byte(b_buffer, HAL_CODEC_IPC_PARAM_KEY_PLANE0_DATA, &b_data, &b_size);
+ if (ipc_ret != BUNDLE_ERROR_NONE || b_data == NULL || b_size != buffer->planes.plane[0].size) {
+ HAL_CODEC_SERVICE_LOGE("get data to decode failed[0x%x,%p,%zu/%u]",
+ ipc_ret, b_data, b_size, buffer->planes.plane[0].size);
+ ret = HAL_CODEC_ERROR_INTERNAL;
+ goto _SERVICE_DECODE_DONE;
+ }
+
+ buffer->planes.plane[0].data = (unsigned char *)g_memdup2(b_data, b_size);
+
+ HAL_CODEC_SERVICE_LOGD("buffer[%d] size[%zu]", buffer->index, b_size);
+
+ ret = hal_codec_passthrough_decode(service_handle->codec_handle, buffer);
+
+_SERVICE_DECODE_DONE:
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ HAL_CODEC_SERVICE_LOGE("decode failed[0x%x]", ret);
+
+ if (buffer->planes.plane[0].data)
+ g_free(buffer->planes.plane[0].data);
+
+ g_free(buffer);
+ }
+
+ return ret;
+}
+
+
+static int _hal_codec_service_backend_release_output_buffer(rpc_port_stub_codec_context_h context, int buffer_index, void *user_data)
+{
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
+
+ HAL_CODEC_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+
+ HAL_CODEC_SERVICE_LOGD("buffer index[%d]", buffer_index);
+
+ ret = hal_codec_passthrough_release_output_buffer(service_handle->codec_handle, buffer_index);
+
+ if (ret != HAL_CODEC_ERROR_NONE)
+ HAL_CODEC_SERVICE_LOGE("release_output_buffer failed[0x%x]", ret);
+
+ return ret;
+}
+
+
+static int hal_codec_service_init(void *data)
+{
+ int rpc_ret = 0;
+
+ rpc_port_stub_codec_callback_s callbacks = {
+ .create = _hal_codec_service_rpc_create,
+ .terminate = _hal_codec_service_rpc_terminate,
+ .init = _hal_codec_service_backend_init,
+ .deinit = _hal_codec_service_backend_deinit,
+ .configure = _hal_codec_service_backend_configure,
+ .release = _hal_codec_service_backend_release,
+ .start = _hal_codec_service_backend_start,
+ .stop = _hal_codec_service_backend_stop,
+ .flush = _hal_codec_service_backend_flush,
+ .decode = _hal_codec_service_backend_decode,
+ .release_output_buffer = _hal_codec_service_backend_release_output_buffer
+ };
+
+ rpc_ret = rpc_port_stub_codec_register(&callbacks, NULL);
+
+ SLOGW("register HAL codec service[0x%x]", rpc_ret);
+
+ return 0;
+}
+
+
+static int hal_codec_service_exit(void *data)
+{
+ SLOGI("exit");
+ return 0;
+}
+
+
+hal_backend_service hal_backend_service_codec_data = {
+ .module = HAL_MODULE_CODEC,
+ .name = "hal-backend-service-codec",
+ .early_init = NULL,
+ .init = hal_codec_service_init,
+ .exit = hal_codec_service_exit,
+ .late_exit = NULL,
+};
using namespace std;
-
#define CONTENTS_H264_PATH RES_DIR"/decode_test.h264"
#define CONTENTS_H264_FRAME_NUM 10
}\
} while (0)
-#define DUMP_OUTPUT_BUFFER
+static bool g_codec_hal_test_dump_decoder_output;
static int decode_test_frame_size[CONTENTS_H264_FRAME_NUM] = {151919, 84650, 8389, 20692, 18090, 18737, 17585, 18476, 11879, 10796};
return;
}
-#ifdef DUMP_OUTPUT_BUFFER
static void DumpBuffer(hal_codec_buffer_s *buffer, const char *dumpPath)
{
static int dumpCount = 0;
fout.close();
}
-#endif
static int MessageCb(hal_codec_message_s *message, void *user_data)
{
- int *decoded_count = (int *)user_data;
+ int *decodedCount = (int *)user_data;
if (!message) {
cout << "Codec HAL : NULL message" << endl;
return 0;
}
- cout << "Codec HAL : message type[" << message->type << "]" << endl;
-
switch (message->type) {
case HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED:
- cout << "Codec HAL : INPUT BUFFER USED p:" << message->buffer << endl;
+ cout << "[INPUT_BUFFER_USED] buffer[" << message->buffer->index << "] "<< message->buffer;
+ cout << " size[" << message->buffer->planes.plane[0].bytesused << "]" << endl;
break;
case HAL_CODEC_MESSAGE_TYPE_OUTPUT_BUFFER:
- if (decoded_count)
- (*decoded_count)++;
+ if (decodedCount)
+ (*decodedCount)++;
+
+ cout << "[OUTPUT_BUFFER] index: " << message->buffer->index << endl;
+
+ if (g_codec_hal_test_dump_decoder_output)
+ DumpBuffer(message->buffer, "/home/owner/media/dump.yuv");
- cout << "Codec HAL : OUTPUT BUFFER index: " << message->buffer->index << endl;
-#ifdef DUMP_OUTPUT_BUFFER
- DumpBuffer(message->buffer, "/home/owner/media/dump.yuv");
-#endif
hal_codec_release_output_buffer(gHalHandle, message->buffer->index);
- cout << "Codec HAL : OUTPUT BUFFER Released" << endl;
break;
default:
+ cout << "[UNHANDLED MSG] type: " << message->type << endl;
break;
}
mappedFileContents_ = nullptr;
}
+ int FeedData(void)
+ {
+ memset(&buffer_[feedCount_], 0x0, sizeof(hal_codec_buffer_s));
+
+ buffer_[feedCount_].index = (int)feedCount_;
+ buffer_[feedCount_].size = decode_test_frame_size[feedCount_];
+ buffer_[feedCount_].planes.num_planes = 1;
+ buffer_[feedCount_].planes.plane[0].data = (unsigned char *)(mappedFileContents_ + mappedFileOffset_);
+ buffer_[feedCount_].planes.plane[0].size = buffer_[feedCount_].size;
+ buffer_[feedCount_].planes.plane[0].bytesused = buffer_[feedCount_].size;
+ buffer_[feedCount_].meta.timestamp = feedCount_ * 1000000000; /* ns */
+
+ cout << "[FeedData] buffer[" << feedCount_ << "] " << &buffer_[feedCount_];
+ cout << " size[" << buffer_[feedCount_].planes.plane[0].bytesused << "]" << endl;
+
+ ret = hal_codec_decode(gHalHandle, &buffer_[feedCount_]);
+ if (ret != HAL_CODEC_ERROR_NONE)
+ cout << "[FeedData] failed " << ret << endl;
+
+ mappedFileOffset_ += decode_test_frame_size[feedCount_];
+ feedCount_++;
+
+ if (feedCount_ >= 10)
+ return G_SOURCE_REMOVE;
+ else
+ return G_SOURCE_CONTINUE;
+ }
+
GMappedFile *mappedFile_ {};
gsize mappedFileLength_ {};
gchar *mappedFileContents_ {};
gsize mappedFileOffset_ {};
+ hal_codec_buffer_s buffer_[CONTENTS_H264_FRAME_NUM] {};
+ guint feedCount_ {};
+ guint decodedCount_ {};
+ GMainLoop *mainLoop_ {};
};
/**
*/
TEST_F(CodecHalTest, DecodeP)
{
- int offset = 0;
- int decoded_count = 0;
- hal_codec_buffer_s buffer[CONTENTS_H264_FRAME_NUM];
CODEC_SUPPORT_CHECK;
ASSERT_NE(gHalHandle, nullptr);
ret = hal_codec_configure(gHalHandle, 1920, 1080, HAL_CODEC_FORMAT_H264, HAL_CODEC_FORMAT_NV12, false);
ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
- ret = hal_codec_start(gHalHandle, CodecHalTest::MessageCb, (void *)&decoded_count);
+ ret = hal_codec_start(gHalHandle, CodecHalTest::MessageCb, &decodedCount_);
ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
ret = GetContents(CONTENTS_H264_PATH);
ASSERT_EQ(ret, 0);
- for (uint64_t i = 0 ; i < CONTENTS_H264_FRAME_NUM ; i++) {
- memset(&buffer[i], 0x0, sizeof(hal_codec_buffer_s));
+ mainLoop_ = g_main_loop_new(NULL, TRUE);
- buffer[i].size = decode_test_frame_size[i];
- buffer[i].planes.plane[0].data = (unsigned char *)(mappedFileContents_ + offset);
- buffer[i].planes.plane[0].size = buffer[i].size;
- buffer[i].planes.plane[0].bytesused = buffer[i].size;
- buffer[i].meta.timestamp = i * 1000000000; /* ns */
+ feedCount_ = 0;
+ decodedCount_ = 0;
- cout << " Codec HAL : [" << i << "] decode buffer: size[" << buffer[i].planes.plane[0].bytesused << "]" << endl;
+ g_timeout_add(50, [](gpointer user_data) -> gboolean {
+ CodecHalTest *self = (CodecHalTest *)user_data;
+ return self->FeedData();
+ }, this);
- ret = hal_codec_decode(gHalHandle, &buffer[i]);
- ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
+ g_timeout_add(1000, [](gpointer user_data) -> gboolean {
+ CodecHalTest *self = (CodecHalTest *)user_data;
+ cout << "decoded count: " << self->decodedCount_ << endl;
+ g_main_loop_quit(self->mainLoop_);
+ return G_SOURCE_REMOVE;
+ }, this);
- offset += decode_test_frame_size[i];
- }
+ g_main_loop_run(mainLoop_);
+ g_main_loop_unref(mainLoop_);
- usleep(1000000);
-
- ASSERT_NE(decoded_count, 0);
+ ASSERT_NE(decodedCount_, 0);
ReleaseContents();
{
testing::InitGoogleTest(&argc, argv);
+ if (argc > 1 && g_strcmp0(argv[1], "dump_output") == 0)
+ g_codec_hal_test_dump_decoder_output = true;
+
return RUN_ALL_TESTS();
}