Support fd for decode 84/325084/6 accepted/tizen_unified accepted/tizen_unified_x tizen accepted/tizen/unified/20250613.040652 accepted/tizen/unified/x/20250613.044716
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 2 Jun 2025 12:27:29 +0000 (21:27 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 12 Jun 2025 05:52:10 +0000 (14:52 +0900)
- Update TIDL file for decoding using fd
- Support new interface
- Update Test for new interface
- Extract common function to process fd on backend service

[Version] 1.6.1
[Issue Type] New feature

Change-Id: Ic254801eb3c49193d262e3759b362b51f9784d75
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
include/hal_codec_ipc_1.tidl
packaging/hal-api-codec.spec
src/hal-api-codec-ipc.c
src/service_plugin/hal-backend-service-codec.c
tests/codec_hal_test.cpp

index 54060f17c4f04303723486a8e91898c6754a0698..dcb8bcc8dc96de923fb8bb6ce1d66d32ef2cacbf 100644 (file)
@@ -25,6 +25,7 @@ interface codec {
   int flush();
 
   int decode(bundle buffer);
+  int decode_fd(bundle buffer, array<file_desc> fd);
   int encode(bundle buffer, array<file_desc> fd);
   int release_output_buffer(int buffer_index);
 
index 0361f54d2fdaf1020f10b7ca9302d11fe30b4745..ef19cb9d340f6af04b7c3b089d049bc167dfe566 100644 (file)
@@ -6,7 +6,7 @@
 ### main package #########
 Name:       %{name}
 Summary:    %{name} interface
-Version:    1.6.0
+Version:    1.6.1
 Release:    0
 Group:      Development/Libraries
 License:    Apache-2.0
index 33b11d0457dd2beb5f3e9091c4a04132c5a00919..527cd484ce3acac3881d2bc45cc50569a17ee2d3 100644 (file)
@@ -217,6 +217,9 @@ static int __hal_codec_ipc_hal_buffer_set_decoder_output(hal_codec_buffer_s *hal
        for (i = 0 ; i < fd_size ; i++) {
                hal_buffer->memory.fd[i] = fd[i];
 
+               if (hal_buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_SECURE)
+                       continue;
+
                if (fd_size == 1)
                        mmap_length = hal_buffer->size;
                else
@@ -244,13 +247,14 @@ static int __hal_codec_ipc_hal_buffer_set_decoder_output(hal_codec_buffer_s *hal
                }
        }
 
-       if (fd_size != (int)hal_buffer->planes.num_planes) {
+       if (!(hal_buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_SECURE) &&
+               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("[DECODER][OUTPUT] buffer[%d] fd[%d:%d] data[%p:%p] size[%u:%u]",
-               hal_buffer->index, fd[0], fd_size > 1 ? fd[1] : 0,
+       SLOGD("[DECODER][OUTPUT] buffer[%d][flag:0x%x] fd[%d:%d] data[%p:%p] size[%u:%u]",
+               hal_buffer->index, hal_buffer->meta.flags, fd[0], fd_size > 1 ? fd[1] : 0,
                hal_buffer->planes.plane[0].data, hal_buffer->planes.plane[1].data,
                hal_buffer->planes.plane[0].size, hal_buffer->planes.plane[1].size);
 
@@ -281,6 +285,9 @@ static void __hal_codec_ipc_hal_buffer_release_decoder_output(hal_codec_buffer_s
                        SLOGW("  invalid fd[%u] %d", i, hal_buffer->memory.fd[i]);
                }
 
+               if (hal_buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_SECURE)
+                       continue;
+
                if (hal_buffer->memory.num_fd == 1)
                        unmap_size = hal_buffer->size;
                else
@@ -1090,6 +1097,33 @@ int hal_codec_ipc_flush(void *codec_handle)
 }
 
 
+static rpc_port_proxy_array_file_desc_h __hal_codec_ipc_fd_handle_new(uint32_t num_fd, int *fd)
+{
+       int ipc_ret = 0;
+       rpc_port_proxy_array_file_desc_h fd_handle = NULL;
+
+       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);
+               return NULL;
+       }
+
+       SLOGD("num_fd[%u]: fd[0] %d, fd[1] %d", num_fd, fd[0], fd[1]);
+
+       if (num_fd == 0)
+               return fd_handle;
+
+       ipc_ret = rpc_port_proxy_array_file_desc_set(fd_handle, fd, num_fd);
+       if (ipc_ret != RPC_PORT_ERROR_NONE) {
+               SLOGE("fd set failed[0x%x]", ipc_ret);
+               rpc_port_proxy_array_file_desc_destroy(fd_handle);
+               return NULL;
+       }
+
+       return fd_handle;
+}
+
+
 int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer)
 {
        int ret = HAL_CODEC_ERROR_NONE;
@@ -1104,6 +1138,7 @@ int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer)
        hal_codec_message_s hal_message = {0, };
 
        rpc_port_proxy_codec_async_return_type_e type = RPC_PORT_PROXY_ASYNC_RETURN_TYPE_CODEC_DECODE;
+       rpc_port_proxy_array_file_desc_h fd_handle = NULL;
        bundle *b_buffer = NULL;
 
        HAL_CODEC_RETURN_VAL_IF_FAILED(handle, HAL_CODEC_ERROR_INVALID_PARAMETER);
@@ -1128,21 +1163,30 @@ int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer)
                (const char *)buffer, sizeof(hal_codec_buffer_s));
        if (ipc_ret != BUNDLE_ERROR_NONE) {
                SLOGE("add byte failed for buffer");
-               bundle_free(b_buffer);
-               return HAL_CODEC_ERROR_OUT_OF_MEMORY;
+               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);
-               bundle_free(b_buffer);
-               return HAL_CODEC_ERROR_OUT_OF_MEMORY;
+       if (buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_SECURE) {
+               fd_handle = __hal_codec_ipc_fd_handle_new(buffer->memory.num_fd, buffer->memory.fd);
+               if (!fd_handle) {
+                       SLOGE("fd handle create failed[0x%x]", ipc_ret);
+                       ret = HAL_CODEC_ERROR_OUT_OF_MEMORY;
+                       goto _IPC_DECODE_DONE;
+               }
+       } else {
+               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;
+               }
        }
 
        if (__hal_codec_ipc_input_buffer_push(ipc_buffer, buffer) != HAL_CODEC_ERROR_NONE) {
-               bundle_free(b_buffer);
-               return HAL_CODEC_ERROR_INTERNAL;
+               ret = HAL_CODEC_ERROR_INTERNAL;
+               goto _IPC_DECODE_DONE;
        }
 
        g_mutex_lock(&ipc_async_return->lock[type]);
@@ -1163,11 +1207,15 @@ int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer)
 
                g_mutex_unlock(&ipc_message->lock);
                g_mutex_unlock(&ipc_async_return->lock[type]);
-               bundle_free(b_buffer);
-               return HAL_CODEC_ERROR_NONE;
+               ret = HAL_CODEC_ERROR_NONE;
+               goto _IPC_DECODE_DONE;
        }
 
-       ret = rpc_port_proxy_codec_invoke_decode(handle->rpc_handle, b_buffer);
+       if (fd_handle)
+               ret = rpc_port_proxy_codec_invoke_decode_fd(handle->rpc_handle, b_buffer, fd_handle);
+       else
+               ret = rpc_port_proxy_codec_invoke_decode(handle->rpc_handle, b_buffer);
+
        if (ret == HAL_CODEC_ERROR_NONE) {
                ipc_async_return->wait_result[type] = true;
                end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
@@ -1194,6 +1242,9 @@ int hal_codec_ipc_decode(void *codec_handle, hal_codec_buffer_s *buffer)
                __hal_codec_ipc_input_buffer_pop(ipc_buffer, buffer->index);
        }
 
+_IPC_DECODE_DONE:
+       if (fd_handle)
+               rpc_port_proxy_array_file_desc_destroy(fd_handle);
        bundle_free(b_buffer);
 
        return ret;
@@ -1235,25 +1286,13 @@ int hal_codec_ipc_encode(void *codec_handle, hal_codec_buffer_s *buffer)
                goto _IPC_ENCODE_DONE;
        }
 
-       ipc_ret = rpc_port_proxy_array_file_desc_create(&fd_handle);
-       if (ipc_ret != RPC_PORT_ERROR_NONE) {
+       fd_handle = __hal_codec_ipc_fd_handle_new(buffer->memory.num_fd, buffer->memory.fd);
+       if (!fd_handle) {
                SLOGE("fd handle create failed[0x%x]", ipc_ret);
                ret = HAL_CODEC_ERROR_OUT_OF_MEMORY;
                goto _IPC_ENCODE_DONE;
        }
 
-       if (buffer->memory.num_fd > 0) {
-               SLOGD("num_fd[%u] fd[%d/%d/%d/%d]", buffer->memory.num_fd,
-                       buffer->memory.fd[0], buffer->memory.fd[1], buffer->memory.fd[2], buffer->memory.fd[3]);
-
-               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;
-               }
-       }
-
        if (__hal_codec_ipc_input_buffer_push(ipc_buffer, buffer) != HAL_CODEC_ERROR_NONE) {
                ret = HAL_CODEC_ERROR_INTERNAL;
                goto _IPC_ENCODE_DONE;
index 786937e2fc25da8671756bab5a513e048dfc5b33..3e041710c2e713d07cdc00e89f4f7c64719c57fd 100644 (file)
@@ -182,17 +182,32 @@ static int __hal_codec_service_message_cb(hal_codec_message_s *message, void *us
                bundle_add_byte(b_msg, HAL_CODEC_IPC_PARAM_KEY_BUFFER, (const void *)buffer, sizeof(hal_codec_buffer_s));
 
                if (service_handle->type == HAL_CODEC_TYPE_DECODER) {
-                       for (i = 0 ; i < buffer->planes.num_planes ; i++) {
-                               if (!buffer->planes.plane[i].data) {
-                                       HAL_CODEC_SERVICE_LOGW("invalid ptr: buffer[%d][plane:%d] %p",
-                                       buffer->index, i, buffer->planes.plane[i].data);
-                                       continue;
-                               }
-
-                               HAL_CODEC_SERVICE_LOGD("[DECODER] free INPUT_BUFFER: buffer[%d][plane:%d] %p",
-                                       buffer->index, i, buffer->planes.plane[i].data);
+                       if (buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_SECURE) {
+                               for (i = 0 ; i < buffer->memory.num_fd ; i++) {
+                                       if (buffer->memory.fd[i] < 0) {
+                                               HAL_CODEC_SERVICE_LOGW("invalid fd: buffer[%d] fd[%u] %d",
+                                                       buffer->index, i, buffer->memory.fd[i]);
+                                               continue;
+                                       }
+
+                                       HAL_CODEC_SERVICE_LOGD("[DECODER] close INPUT_BUFFER: buffer[%d] fd[%u] %d",
+                                               buffer->index, i, buffer->memory.fd[i]);
 
-                               g_free(buffer->planes.plane[i].data);
+                                       close(buffer->memory.fd[i]);
+                               }
+                       } else {
+                               for (i = 0 ; i < buffer->planes.num_planes ; i++) {
+                                       if (!buffer->planes.plane[i].data) {
+                                               HAL_CODEC_SERVICE_LOGW("invalid ptr: buffer[%d][plane:%d] %p",
+                                               buffer->index, i, buffer->planes.plane[i].data);
+                                               continue;
+                                       }
+
+                                       HAL_CODEC_SERVICE_LOGD("[DECODER] free INPUT_BUFFER: buffer[%d][plane:%d] %p",
+                                               buffer->index, i, buffer->planes.plane[i].data);
+
+                                       g_free(buffer->planes.plane[i].data);
+                               }
                        }
                } else {
                        for (i = 0 ; i < buffer->memory.num_fd ; i++) {
@@ -792,8 +807,8 @@ static int _hal_codec_service_backend_decode(rpc_port_stub_codec_context_h conte
 }
 
 
-static int _hal_codec_service_backend_encode(rpc_port_stub_codec_context_h context,
-       bundle *b_buffer, rpc_port_stub_array_file_desc_h fd_handle, void *user_data)
+static int __hal_codec_service_process_fd(hal_codec_service_s *service_handle,
+       bundle *b_buffer, rpc_port_stub_array_file_desc_h fd_handle, hal_codec_service_task_cmd_e command)
 {
        int i = 0;
        int ipc_ret = 0;
@@ -802,15 +817,14 @@ static int _hal_codec_service_backend_encode(rpc_port_stub_codec_context_h conte
        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_SERVICE_RETURN_VAL_IF_FAILED_CONTEXT(service_handle, HAL_CODEC_ERROR_INTERNAL);
-       HAL_CODEC_SERVICE_RETURN_VAL_IF_FAILED_CONTEXT(fd_handle, HAL_CODEC_ERROR_INTERNAL);
+       HAL_CODEC_SERVICE_RETURN_VAL_IF_FAILED(service_handle, HAL_CODEC_ERROR_INTERNAL);
+       HAL_CODEC_SERVICE_RETURN_VAL_IF_FAILED(fd_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_CONTEXT("get data to encode failed[0x%x,%p,%zu/%zu]",
-                       ipc_ret, b_data, b_size, sizeof(hal_codec_buffer_s));
+               HAL_CODEC_SERVICE_LOGE("command[%d] get data failed[0x%x,%p,%zu/%zu]",
+                       command, ipc_ret, b_data, b_size, sizeof(hal_codec_buffer_s));
                return HAL_CODEC_ERROR_INTERNAL;
        }
 
@@ -818,24 +832,43 @@ static int _hal_codec_service_backend_encode(rpc_port_stub_codec_context_h conte
 
        ipc_ret = rpc_port_stub_array_file_desc_get(fd_handle, &fd, &fd_size);
        if (ipc_ret != RPC_PORT_ERROR_NONE || !fd || buffer->memory.num_fd != (uint32_t)fd_size) {
-               HAL_CODEC_SERVICE_LOGE_CONTEXT("get fd failed[0x%x,%p], num_fd[%u] vs fd_size[%d]",
-                       ipc_ret, fd, buffer->memory.num_fd, fd_size);
+               HAL_CODEC_SERVICE_LOGE("command[%d] get fd failed[0x%x,%p], num_fd[%u] vs fd_size[%d]",
+                       command, ipc_ret, fd, buffer->memory.num_fd, fd_size);
                g_free(buffer);
                return HAL_CODEC_ERROR_INTERNAL;
        }
 
        for (i = 0 ; i < fd_size ; i++) {
-               HAL_CODEC_SERVICE_LOGD_CONTEXT("fd[%d] %d", i, fd[i]);
+               HAL_CODEC_SERVICE_LOGD("command[%d] fd[%d] %d", command, i, fd[i]);
                buffer->memory.fd[i] = fd[i];
                /* NOTE: no need to set virtual address, fd will be used only. */
        }
 
-       HAL_CODEC_SERVICE_TASK_PUSH_JOB(service_handle->task, HAL_CODEC_SERVICE_TASK_CMD_ENCODE, buffer, -1, SLOGD);
+       HAL_CODEC_SERVICE_LOGD("command[%d] buffer[%d] size[%u] bytesused[%u]",
+               command, buffer->index, buffer->planes.plane[0].size, buffer->planes.plane[0].bytesused);
+
+       HAL_CODEC_SERVICE_TASK_PUSH_JOB(service_handle->task, command, buffer, -1, SLOGD);
 
        return HAL_CODEC_ERROR_NONE;
 }
 
 
+static int _hal_codec_service_backend_decode_fd(rpc_port_stub_codec_context_h context,
+       bundle *b_buffer, rpc_port_stub_array_file_desc_h fd_handle, void *user_data)
+{
+       return __hal_codec_service_process_fd(__hal_codec_service_get_handle(context),
+               b_buffer, fd_handle, HAL_CODEC_SERVICE_TASK_CMD_DECODE);
+}
+
+
+static int _hal_codec_service_backend_encode(rpc_port_stub_codec_context_h context,
+       bundle *b_buffer, rpc_port_stub_array_file_desc_h fd_handle, void *user_data)
+{
+       return __hal_codec_service_process_fd(__hal_codec_service_get_handle(context),
+               b_buffer, fd_handle, HAL_CODEC_SERVICE_TASK_CMD_ENCODE);
+}
+
+
 static int _hal_codec_service_backend_release_output_buffer(rpc_port_stub_codec_context_h context, int buffer_index, void *user_data)
 {
        hal_codec_service_s *service_handle = __hal_codec_service_get_handle(context);
@@ -889,6 +922,7 @@ static int hal_codec_service_init(void *data)
                .stop       = _hal_codec_service_backend_stop,
                .flush      = _hal_codec_service_backend_flush,
                .decode     = _hal_codec_service_backend_decode,
+               .decode_fd  = _hal_codec_service_backend_decode_fd,
                .encode     = _hal_codec_service_backend_encode,
                .release_output_buffer = _hal_codec_service_backend_release_output_buffer,
                .get_state  = _hal_codec_service_backend_get_state
index 69b22b743b45d764f39e0b43499a2d53488598f1..32d0bfd33d9fbf24d65ec83f847981b57a6f2192 100644 (file)
@@ -37,6 +37,7 @@ using namespace std;
 
 #define DECODE_FRAME_WIDTH          1920
 #define DECODE_FRAME_HEIGHT         1080
+#define DECODE_FRAME_BO_ALLOC_SIZE  (1024 * 1024)
 #define ENCODE_FRAME_WIDTH          1920
 #define ENCODE_FRAME_HEIGHT         1080
 #define ENCODE_FRAME_TEST_NUM       60
@@ -232,11 +233,39 @@ class CodecHalTestDecoder : public testing::Test, public CodecHalTest
                        }
 
                        ReleaseContents();
+               }
 
-                       return;
+               void AllocMemoryForFd()
+               {
+                       bufmgr = tbm_bufmgr_init(-1);
+
+                       cout << "Alloc bo for decode_fd test - buffer size: " << DECODE_FRAME_BO_ALLOC_SIZE << endl;
+
+                       for (int i = 0 ; i < CONTENTS_H264_FRAME_NUM ; i++) {
+                               bo[i] = tbm_bo_alloc(bufmgr, DECODE_FRAME_BO_ALLOC_SIZE, TBM_BO_DEFAULT);
+                               fd[i] = tbm_bo_export_fd(bo[i]);
+                               cout << "[" << i << "] bo " << bo[i] << ", fd " << fd[i] << endl;
+                       }
                }
 
-               int FeedDataDecode(void)
+               void ReleaseMemoryForFd()
+               {
+                       cout << "Release bo for decode_fd test - buffer size: " << DECODE_FRAME_BO_ALLOC_SIZE << endl;
+
+                       for (int i = 0 ; i < CONTENTS_H264_FRAME_NUM ; i++) {
+                               cout << "[" << i << "] bo " << bo[i] << ", fd " << fd[i] << endl;
+
+                               if (fd[i] > 0)
+                                       close(fd[i]);
+
+                               if (bo[i])
+                                       tbm_bo_unref(bo[i]);
+                       }
+
+                       tbm_bufmgr_deinit(bufmgr);
+               }
+
+               int FeedDataDecode()
                {
                        memset(&buffer_[gFeedCount], 0x0, sizeof(hal_codec_buffer_s));
 
@@ -249,6 +278,17 @@ class CodecHalTestDecoder : public testing::Test, public CodecHalTest
                                buffer_[gFeedCount].planes.plane[0].data = (unsigned char *)(mappedFileContents_ + mappedFileOffset_);
                                buffer_[gFeedCount].planes.plane[0].size = buffer_[gFeedCount].size;
                                buffer_[gFeedCount].planes.plane[0].bytesused = buffer_[gFeedCount].size;
+                               if (useFd) {
+                                       tbm_bo_handle bo_handle = {nullptr, };
+
+                                       buffer_[gFeedCount].memory.num_fd = 1;
+                                       buffer_[gFeedCount].memory.fd[0] = fd[gFeedCount];
+
+                                       bo_handle = tbm_bo_get_handle(bo[gFeedCount], TBM_DEVICE_CPU);
+                                       memcpy(bo_handle.ptr, buffer_[gFeedCount].planes.plane[0].data, buffer_[gFeedCount].size);
+
+                                       buffer_[gFeedCount].meta.flags |= HAL_CODEC_BUFFER_FLAG_SECURE;
+                               }
 
                                cout << "[FeedDataDecode] buffer[" << gFeedCount << "] " << &buffer_[gFeedCount];
                                cout << " size[" << buffer_[gFeedCount].planes.plane[0].bytesused << "]" << endl;
@@ -273,7 +313,67 @@ class CodecHalTestDecoder : public testing::Test, public CodecHalTest
                        return G_SOURCE_CONTINUE;
                }
 
+               void DecodeTestCommon()
+               {
+                       DECODER_SUPPORT_CHECK;
+
+                       ASSERT_NE(gHalHandleDec, nullptr);
+                       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
+                       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_INITIALIZED));
+
+                       ret = hal_codec_configure(gHalHandleDec, DECODE_FRAME_WIDTH, DECODE_FRAME_HEIGHT,
+                               HAL_CODEC_FORMAT_H264, HAL_CODEC_FORMAT_NV12, false);
+                       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
+                       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_CONFIGURED));
+
+                       ret = hal_codec_start(gHalHandleDec, CodecHalTestDecoder::MessageCb, gHalHandleDec);
+                       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
+                       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_STARTED));
+
+                       ret = GetContents(CONTENTS_H264_PATH);
+                       ASSERT_EQ(ret, 0);
+
+                       gMainLoop = g_main_loop_new(nullptr, TRUE);
+
+                       gFeedCount = 0;
+                       gOutputCount = 0;
+
+                       g_timeout_add(50, [](gpointer user_data) -> gboolean {
+                               CodecHalTestDecoder *self = (CodecHalTestDecoder *)user_data;
+                               return self->FeedDataDecode();
+                       }, this);
+
+                       gTimeoutSourceID = g_timeout_add(3000, [](gpointer user_data) -> gboolean {
+                               cout << "[DECODE] timeout(3000ms) decoded count: " << gOutputCount << endl;
+                               g_main_loop_quit(gMainLoop);
+                               return G_SOURCE_REMOVE;
+                       }, nullptr);
+
+                       cout << "[DECODE] timeout source id " << gTimeoutSourceID << endl;
+
+                       g_main_loop_run(gMainLoop);
+
+                       g_main_loop_unref(gMainLoop);
+                       gMainLoop = nullptr;
+
+                       ASSERT_NE(gOutputCount, 0);
+
+                       ReleaseContents();
+
+                       ret = hal_codec_stop(gHalHandleDec);
+                       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
+                       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_CONFIGURED));
+
+                       ret = hal_codec_release(gHalHandleDec);
+                       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
+                       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_INITIALIZED));
+               }
+
                hal_codec_buffer_s buffer_[CONTENTS_H264_FRAME_NUM + 1] {};
+               tbm_bufmgr bufmgr {};
+               tbm_bo bo[CONTENTS_H264_FRAME_NUM] {};
+               int fd[CONTENTS_H264_FRAME_NUM] {};
+               bool useFd;
 };
 
 
@@ -554,58 +654,29 @@ TEST_F(CodecHalTestDecoder, DecoderStartStopP)
  */
 TEST_F(CodecHalTestDecoder, DecoderDecodeP)
 {
-       DECODER_SUPPORT_CHECK;
-
-       ASSERT_NE(gHalHandleDec, nullptr);
-       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
-       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_INITIALIZED));
-
-       ret = hal_codec_configure(gHalHandleDec, DECODE_FRAME_WIDTH, DECODE_FRAME_HEIGHT,
-               HAL_CODEC_FORMAT_H264, HAL_CODEC_FORMAT_NV12, false);
-       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
-       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_CONFIGURED));
-
-       ret = hal_codec_start(gHalHandleDec, CodecHalTestDecoder::MessageCb, gHalHandleDec);
-       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
-       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_STARTED));
-
-       ret = GetContents(CONTENTS_H264_PATH);
-       ASSERT_EQ(ret, 0);
-
-       gMainLoop = g_main_loop_new(nullptr, TRUE);
-
-       gFeedCount = 0;
-       gOutputCount = 0;
-
-       g_timeout_add(50, [](gpointer user_data) -> gboolean {
-               CodecHalTestDecoder *self = (CodecHalTestDecoder *)user_data;
-               return self->FeedDataDecode();
-       }, this);
-
-       gTimeoutSourceID = g_timeout_add(3000, [](gpointer user_data) -> gboolean {
-               cout << "[DECODE] timeout(3000ms) decoded count: " << gOutputCount << endl;
-               g_main_loop_quit(gMainLoop);
-               return G_SOURCE_REMOVE;
-       }, nullptr);
-
-       cout << "[DECODE] timeout source id " << gTimeoutSourceID << endl;
-
-       g_main_loop_run(gMainLoop);
-
-       g_main_loop_unref(gMainLoop);
-       gMainLoop = nullptr;
-
-       ASSERT_NE(gOutputCount, 0);
-
-       ReleaseContents();
-
-       ret = hal_codec_stop(gHalHandleDec);
-       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
-       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_CONFIGURED));
+       useFd = false;
+       DecodeTestCommon();
+}
 
-       ret = hal_codec_release(gHalHandleDec);
-       ASSERT_EQ(ret, HAL_CODEC_ERROR_NONE);
-       ASSERT_TRUE(CheckCurrentState(gHalHandleDec, HAL_CODEC_STATE_INITIALIZED));
+/**
+ * @testcase           DecoderDecodeFdP
+ * @since_tizen                10.0
+ * @author                     SR(jm80.yang)
+ * @reviewer           SR(heechul.jeon)
+ * @type                       auto
+ * @description                Positive, Decode buffer
+ * @apicovered         hal_codec_decode
+ * @passcase           when hal_codec_decode returns HAL_CODEC_ERROR_NONE and get decoded buffers
+ * @failcase           when hal_codec_decode does not return HAL_CODEC_ERROR_NONE or decoded buffer is not come
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(CodecHalTestDecoder, DecoderDecodeFdP)
+{
+       useFd = true;
+       AllocMemoryForFd();
+       DecodeTestCommon();
+       ReleaseMemoryForFd();
 }
 
 /**