Remove duplicated code in __codec_v4l2_restart_output_stream()
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 13 Feb 2025 09:34:19 +0000 (18:34 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 13 Feb 2025 09:34:19 +0000 (18:34 +0900)
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
src/hal_backend_codec_v4l2.c

index 128518deed9f423273654bce11b23d66790f21a1..34248fed59c2d7a8900440388d55f631cc852721 100644 (file)
 #define POLL_ERROR_TRY_SLEEP_US         10000
 
 
-#define BUFFER_CONTROL_TYPE_STRING(type) \
-       ((type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) ? "INPUT" : "OUTPUT")
+#define BUFFER_CONTROL_TYPE_STRING(buffer_control) \
+       (((buffer_control)->type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) ? "INPUT" : "OUTPUT")
+
+#define BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control) \
+       ((buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) ? TRUE : FALSE)
 
 #define TIMESTAMP_TO_TIMEVAL(timestamp, timeval) \
        do { \
@@ -151,7 +154,7 @@ static void __codec_v4l2_message_release_func(gpointer data);
 static void __codec_v4l2_message_send(codec_hal_handle_s *handle, hal_codec_message_type_e type, gpointer value);
 
 static int __codec_v4l2_start_stream(codec_hal_handle_s *handle, codec_hal_buffer_control_s *buffer_control, uint32_t buffer_count);
-static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle);
+static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle, codec_hal_buffer_control_s *buffer_control);
 
 static int __codec_v4l2_set_command(codec_hal_handle_s *handle, int64_t command, void *value);
 
@@ -613,7 +616,6 @@ static int __codec_v4l2_s_fmt(codec_hal_buffer_control_s *buffer_control, int de
        uint32_t fourcc = 0;
        uint32_t num_planes = 0;
        codec_hal_config_s *codec_config = NULL;
-       codec_hal_buffer_control_type_e type;
        struct v4l2_format v4l2_fmt;
 
        if (!buffer_control) {
@@ -622,11 +624,10 @@ static int __codec_v4l2_s_fmt(codec_hal_buffer_control_s *buffer_control, int de
        }
 
        codec_config = &buffer_control->config;
-       type = buffer_control->type;
 
        if (__codec_get_fourcc_plane_num(codec_config->format, &fourcc, &num_planes) != HAL_CODEC_ERROR_NONE) {
                LOGE("[%s] get fourcc failed for format [0x%x]",
-                       BUFFER_CONTROL_TYPE_STRING(type), codec_config->format);
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control), codec_config->format);
                return HAL_CODEC_ERROR_INVALID_PARAMETER;
        }
 
@@ -665,26 +666,26 @@ static int __codec_v4l2_s_fmt(codec_hal_buffer_control_s *buffer_control, int de
                v4l2_fmt.fmt.pix.bytesperline = codec_config->resolution.width;
        }
 
-       if (type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT &&
+       if (BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control) &&
                codec_config->max_resolution.width > 0 &&
                codec_config->max_resolution.height > 0) {
                v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = (codec_config->max_resolution.width * codec_config->max_resolution.height) >> 1;
 
                LOGI("[%s] set buffer size[%u] with max resolution[%dx%d]",
-                       BUFFER_CONTROL_TYPE_STRING(type),
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                        v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
                        codec_config->max_resolution.width, codec_config->max_resolution.height);
        }
 
        if (ioctl(device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
-               LOGE("[%s] S_FMT failed[%s]", BUFFER_CONTROL_TYPE_STRING(type), __codec_v4l2_get_error_string(errno));
+               LOGE("[%s] S_FMT failed[%s]", BUFFER_CONTROL_TYPE_STRING(buffer_control), __codec_v4l2_get_error_string(errno));
                return HAL_CODEC_ERROR_INTERNAL;
        }
 
        if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) {
                codec_config->buffer_size = 0;
                for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) {
-                       LOGI("[%s] plane[%d] size [%u]", BUFFER_CONTROL_TYPE_STRING(type),
+                       LOGI("[%s] plane[%d] size [%u]", BUFFER_CONTROL_TYPE_STRING(buffer_control),
                                i, v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
                        codec_config->buffer_size += v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage;
                }
@@ -693,7 +694,7 @@ static int __codec_v4l2_s_fmt(codec_hal_buffer_control_s *buffer_control, int de
                codec_config->buffer_size = v4l2_fmt.fmt.pix.sizeimage;
        }
 
-       LOGI("[%s] buffer size[%u], num planes[%u]", BUFFER_CONTROL_TYPE_STRING(type),
+       LOGI("[%s] buffer size[%u], num planes[%u]", BUFFER_CONTROL_TYPE_STRING(buffer_control),
                codec_config->buffer_size, codec_config->num_planes);
 
        return HAL_CODEC_ERROR_NONE;
@@ -787,7 +788,7 @@ static int __codec_v4l2_qbuf(int device_fd,
                if (codec_memory->num_fd == 0 ||
                        codec_memory->num_fd > HAL_CODEC_BUFFER_PLANE_MAX) {
                        LOGE("[%s] QBUF invalid num_fd[%u]",
-                               BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                               BUFFER_CONTROL_TYPE_STRING(buffer_control),
                                codec_memory->num_fd);
                        return HAL_CODEC_ERROR_INVALID_PARAMETER;
                }
@@ -795,14 +796,14 @@ static int __codec_v4l2_qbuf(int device_fd,
                if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) {
                        for (i = 0 ; i < codec_memory->num_fd ; i++) {
                                LOGD("[%s] QBUF plane[%d] fd %d",
-                                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                                        i, codec_memory->fd[i]);
                                v4l2_buf.m.planes[i].m.fd = codec_memory->fd[i];
                        }
                } else {
                        if (codec_memory->num_fd != 1)
                                LOGW("[%s] QBUF invalid num_fd[%u]",
-                                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                                        codec_memory->num_fd);
 
                        v4l2_buf.m.fd = codec_memory->fd[0];
@@ -816,18 +817,18 @@ static int __codec_v4l2_qbuf(int device_fd,
                        v4l2_buf.m.planes[0].bytesused = codec_buffer->planes.plane[0].bytesused;
 
                        LOGD("[%s] QBUF multiplanar: bytesused[%u]",
-                               BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                               BUFFER_CONTROL_TYPE_STRING(buffer_control),
                                v4l2_buf.m.planes[0].bytesused);
                } else {
                        v4l2_buf.bytesused = codec_buffer->planes.plane[0].bytesused;
 
                        LOGD("[%s] QBUF singleplanar: bytesused[%u]",
-                               BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                               BUFFER_CONTROL_TYPE_STRING(buffer_control),
                                v4l2_buf.bytesused);
                }
        }
 
-       if (buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) {
+       if (BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
                TIMESTAMP_TO_TIMEVAL(codec_buffer->meta.timestamp, v4l2_buf.timestamp);
 
                LOGD("[INPUT] QBUF timestamp: [%"TIMESTAMP_FORMAT"] -> sec[%lu], usec[%lu]",
@@ -837,7 +838,7 @@ static int __codec_v4l2_qbuf(int device_fd,
 
        if (ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) {
                LOGE("[%s] QBUF failed: buffer[%d] %s",
-                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                        codec_buffer->index, __codec_v4l2_get_error_string(errno));
                return HAL_CODEC_ERROR_INTERNAL;
        }
@@ -846,10 +847,10 @@ static int __codec_v4l2_qbuf(int device_fd,
        buffer_control->buffers.queued_count++;
 
        LOGD("[%s] QBUF done: buffer[%d], queued_count[%d]",
-               BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+               BUFFER_CONTROL_TYPE_STRING(buffer_control),
                codec_buffer->index, buffer_control->buffers.queued_count);
 
-       if (buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT)
+       if (!BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control))
                g_cond_broadcast(&buffer_control->cond);
 
        return HAL_CODEC_ERROR_NONE;
@@ -890,7 +891,7 @@ static int __codec_v4l2_dqbuf(int device_fd,
        ret = ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf);
        if (ret < 0) {
                LOGE("[%s] DQBUF failed. [t: %d, m: %d] %s",
-                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                        codec_config->buf_type, codec_config->memory,
                        __codec_v4l2_get_error_string(errno));
                return HAL_CODEC_ERROR_DEVICE_READ;
@@ -900,20 +901,20 @@ static int __codec_v4l2_dqbuf(int device_fd,
        buffer_control->buffers.queued_count--;
        if (buffer_control->buffers.queued_count < 0) {
                LOGW("[%s] invalid queued_count[%d], check it.",
-                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                        buffer_control->buffers.queued_count);
        }
 
        if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) {
                LOGD("[%s] DQBUF done: index[%d], length[%u], bytesused[0:%u,1:%u], queued_count[%d]",
-                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                        v4l2_buf.index, v4l2_buf.length,
                        v4l2_buf.m.planes[0].bytesused,
                        v4l2_buf.m.planes[1].bytesused,
                        buffer_control->buffers.queued_count);
        } else {
                LOGD("[%s] DQBUF done: index[%d], bytesused[%u], length[%u], queued_count[%d]",
-                       BUFFER_CONTROL_TYPE_STRING(buffer_control->type),
+                       BUFFER_CONTROL_TYPE_STRING(buffer_control),
                        v4l2_buf.index, v4l2_buf.bytesused, v4l2_buf.length,
                        buffer_control->buffers.queued_count);
        }
@@ -922,7 +923,7 @@ static int __codec_v4l2_dqbuf(int device_fd,
 
        (*out_buffer)->meta.flags = HAL_CODEC_BUFFER_FLAG_NONE;
 
-       if (buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT) {
+       if (!BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
                TIMEVAL_TO_TIMESTAMP(v4l2_buf.timestamp, (*out_buffer)->meta.timestamp);
 
                LOGD("[OUTPUT] DQBUF timestamp: sec[%lu], usec[%lu] -> [%"TIMESTAMP_FORMAT"]",
@@ -932,7 +933,7 @@ static int __codec_v4l2_dqbuf(int device_fd,
 
        if (v4l2_buf.flags & V4L2_BUF_FLAG_LAST &&
                v4l2_buf.m.planes[0].bytesused == 0) {
-               LOGW("[%s] LAST BUFFER - set EOS flag", BUFFER_CONTROL_TYPE_STRING(buffer_control->type));
+               LOGW("[%s] LAST BUFFER - set EOS flag", BUFFER_CONTROL_TYPE_STRING(buffer_control));
                (*out_buffer)->meta.flags |= HAL_CODEC_BUFFER_FLAG_EOS;
        }
 
@@ -1038,121 +1039,100 @@ static int __codec_get_fourcc_plane_num(hal_codec_format_e format, uint32_t *fou
 }
 
 
-static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle)
+static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle, codec_hal_buffer_control_s *buffer_control)
 {
        int i = 0;
        int k = 0;
        int ret = HAL_CODEC_ERROR_NONE;
        gint64 end_time = 0;
-       hal_codec_memory_s *codec_memory = NULL;
-       codec_hal_buffer_control_s *buffer_control = NULL;
+       codec_hal_config_s *config = NULL;
        codec_hal_buffers_s *buffers = NULL;
+       hal_codec_memory_s *codec_memory = NULL;
        hal_codec_buffer_s *codec_buffer = NULL;
 
-       if (!handle) {
-               LOGE("NULL handle");
+       if (!handle || !buffer_control) {
+               LOGE("NULL param[%p,%p]", handle, buffer_control);
                return HAL_CODEC_ERROR_INVALID_PARAMETER;
        }
 
-       LOGI("start");
+       LOGI("start - type[%s]", BUFFER_CONTROL_TYPE_STRING(buffer_control));
 
-       /* output */
-       buffer_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT];
+       buffers = &buffer_control->buffers;
+       config = &buffer_control->config;
 
-       ret = __codec_v4l2_stream(handle->device_fd,
-               buffer_control->config.buf_type, FALSE);
+       ret = __codec_v4l2_stream(handle->device_fd, config->buf_type, FALSE);
        if (ret != HAL_CODEC_ERROR_NONE) {
-               LOGE("[OUTPUT] STREAMOFF failed[0x%x]", ret);
+               LOGE("[%s] STREAMOFF failed[0x%x]", BUFFER_CONTROL_TYPE_STRING(buffer_control), ret);
                return ret;
        }
 
-       g_mutex_lock(&buffer_control->lock);
+       if (config->memory == V4L2_MEMORY_DMABUF) {
+               g_mutex_lock(&buffer_control->lock);
 
-       while (buffer_control->buffers.queued_count < buffer_control->buffers.count) {
-               LOGW("wait for output buffer[queued:%d vs count:%u]",
-                       buffer_control->buffers.queued_count, buffer_control->buffers.count);
+               while (buffer_control->buffers.queued_count < buffer_control->buffers.count) {
+                       LOGW("wait for output buffer[queued:%d vs count:%u]",
+                               buffer_control->buffers.queued_count, buffer_control->buffers.count);
 
-               end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
+                       end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
 
-               if (!g_cond_wait_until(&buffer_control->cond, &buffer_control->lock, end_time)) {
-                       LOGE("timeout: wait for output buffer");
-                       break;
-               }
+                       if (!g_cond_wait_until(&buffer_control->cond, &buffer_control->lock, end_time)) {
+                               LOGE("timeout: wait for output buffer");
+                               break;
+                       }
 
-               LOGW("signal received, check it again[queued:%d,count:%u]",
-                       buffer_control->buffers.queued_count, buffer_control->buffers.count);
-       }
+                       LOGW("signal received, check it again[queued:%d,count:%u]",
+                               buffer_control->buffers.queued_count, buffer_control->buffers.count);
+               }
 
-       g_mutex_unlock(&buffer_control->lock);
+               g_mutex_unlock(&buffer_control->lock);
 
-       /* release output buffer */
-       buffers = &buffer_control->buffers;
+               for (i = 0 ; i < buffers->count ; i++) {
+                       codec_buffer = &buffers->buffer[i];
+                       codec_memory = &codec_buffer->memory;
 
-       for (i = 0 ; i < buffers->count ; i++) {
-               codec_buffer = &buffers->buffer[i];
-               codec_memory = &codec_buffer->memory;
-
-               for (k = 0 ; k < codec_memory->num_fd ; k++) {
-                       if (codec_memory->fd[k] > CODEC_HAL_INITIAL_FD) {
-                               LOGI("[OUTPUT][%d][%d] close fd[%d]", i, k, codec_memory->fd[k]);
-                               close(codec_memory->fd[k]);
-                               codec_memory->fd[k] = CODEC_HAL_INITIAL_FD;
-                       }
+                       for (k = 0 ; k < codec_memory->num_fd ; k++) {
+                               if (codec_memory->fd[k] > CODEC_HAL_INITIAL_FD) {
+                                       LOGI("[%s][%d][%d] close fd[%d]", BUFFER_CONTROL_TYPE_STRING(buffer_control), i, k, codec_memory->fd[k]);
+                                       close(codec_memory->fd[k]);
+                                       codec_memory->fd[k] = CODEC_HAL_INITIAL_FD;
+                               }
 
-                       if (buffers->bo[i][k]) {
-                               LOGI("[OUTPUT][%d][%d] unref bo[%p]", i, k, buffers->bo[i][k]);
-                               tbm_bo_unref(buffers->bo[i][k]);
-                               buffers->bo[i][k] = NULL;
+                               if (buffers->bo[i][k]) {
+                                       LOGI("[%s][%d][%d] unref bo[%p]", BUFFER_CONTROL_TYPE_STRING(buffer_control), i, k, buffers->bo[i][k]);
+                                       tbm_bo_unref(buffers->bo[i][k]);
+                                       buffers->bo[i][k] = NULL;
+                               }
                        }
                }
-       }
-
-       ret = __codec_v4l2_reqbufs(handle->device_fd,
-               buffer_control->config.buf_type, V4L2_MEMORY_MMAP, 0, NULL);
-       if (ret != HAL_CODEC_ERROR_NONE) {
-               LOGE("[OUTPUT] REQBUFS 0 failed[0x%x]", ret);
-               return ret;
-       }
+       } else {
+               for (i = 0 ; i < buffers->count ; i++) {
+                       codec_buffer = &buffers->buffer[i];
 
-       /* input */
-       buffer_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT];
-       buffers = &buffer_control->buffers;
+                       if (!codec_buffer->planes.plane[0].data || codec_buffer->size == 0) {
+                               LOGW("[%s][%d] invalid data[%p], size[%u]",
+                                       BUFFER_CONTROL_TYPE_STRING(buffer_control), i, codec_buffer->planes.plane[0].data, codec_buffer->size);
+                               continue;
+                       }
 
-       ret = __codec_v4l2_stream(handle->device_fd,
-               buffer_control->config.buf_type, FALSE);
-       if (ret != HAL_CODEC_ERROR_NONE) {
-               LOGE("[INPUT] STREAMOFF failed[0x%x]", ret);
-               return ret;
-       }
+                       LOGI("[%s][%d] munmap[%p], size[%u]",
+                               BUFFER_CONTROL_TYPE_STRING(buffer_control), i, codec_buffer->planes.plane[0].data, codec_buffer->size);
 
-       for (i = 0 ; i < buffers->count ; i++) {
-               codec_buffer = &buffers->buffer[i];
+                       munmap(codec_buffer->planes.plane[0].data, codec_buffer->size);
 
-               if (!codec_buffer->planes.plane[0].data || codec_buffer->size == 0) {
-                       LOGW("[INPUT][%d] invalid data[%p], size[%u]",
-                               i, codec_buffer->planes.plane[0].data, codec_buffer->size);
-                       continue;
+                       codec_buffer->planes.plane[0].data = NULL;
+                       codec_buffer->size = 0;
                }
 
-               LOGI("[INPUT][%d] munmap[%p], size[%u]",
-                       i, codec_buffer->planes.plane[0].data, codec_buffer->size);
-
-               munmap(codec_buffer->planes.plane[0].data, codec_buffer->size);
-
-               codec_buffer->planes.plane[0].data = NULL;
-               codec_buffer->size = 0;
+               g_queue_clear(buffers->idle_buffers);
        }
 
-       g_queue_clear(buffers->idle_buffers);
-
-       ret = __codec_v4l2_reqbufs(handle->device_fd,
-               buffer_control->config.buf_type, V4L2_MEMORY_MMAP, 0, NULL);
+       ret = __codec_v4l2_reqbufs(handle->device_fd, config->buf_type, config->memory, 0, NULL);
        if (ret != HAL_CODEC_ERROR_NONE) {
-               LOGE("[INPUT] REQBUFS 0 failed[0x%x]", ret);
+               LOGE("[%s] REQBUFS 0 failed[0x%x]", BUFFER_CONTROL_TYPE_STRING(buffer_control), ret);
                return ret;
        }
 
-       LOGI("done");
+       LOGI("[%s] done", BUFFER_CONTROL_TYPE_STRING(buffer_control));
 
        return HAL_CODEC_ERROR_NONE;
 }
@@ -1304,7 +1284,7 @@ static int __codec_v4l2_start_stream(codec_hal_handle_s *handle,
                                codec_buffer->planes.plane[1].bytesused);
                }
 
-               if (buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) {
+               if (BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
                        g_mutex_lock(&buffer_control->lock);
                        LOGI("[input] push idle buffer[%d]", i);
                        g_queue_push_tail(buffers->idle_buffers, GINT_TO_POINTER(i));
@@ -1333,7 +1313,7 @@ static int __codec_v4l2_start_stream(codec_hal_handle_s *handle,
        return HAL_CODEC_ERROR_NONE;
 
 _START_STREAM_FAILED:
-       __codec_v4l2_stop_stream(handle);
+       __codec_v4l2_stop_stream(handle, buffer_control);
        return ret;
 }
 
@@ -1866,17 +1846,12 @@ static int __codec_v4l2_poll(codec_hal_handle_s *handle, short events, int timeo
 
 static void __codec_v4l2_restart_output_stream(codec_hal_handle_s *handle)
 {
-       int i = 0;
-       int k = 0;
        int ret = 0;
        int new_width = 0;
        int new_height = 0;
-       gint64 end_time = 0;
        struct v4l2_format v4l2_fmt;
-       hal_codec_memory_s *codec_memory = NULL;
-       hal_codec_buffer_s *codec_buffer = NULL;
+       codec_hal_config_s *config = NULL;
        codec_hal_buffer_control_s *buffer_control = NULL;
-       codec_hal_buffers_s *buffers = NULL;
 
        if (!handle) {
                LOGE("NULL handle");
@@ -1886,72 +1861,24 @@ static void __codec_v4l2_restart_output_stream(codec_hal_handle_s *handle)
        LOGI("start");
 
        buffer_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT];
+       config = &buffer_control->config;
 
-       ret = __codec_v4l2_stream(handle->device_fd,
-               buffer_control->config.buf_type, FALSE);
+       ret = __codec_v4l2_stop_stream(handle, buffer_control);
        if (ret != HAL_CODEC_ERROR_NONE) {
-               LOGE("[OUTPUT] STREAMOFF failed[0x%x]", ret);
-               return;
-       }
-
-       g_mutex_lock(&buffer_control->lock);
-
-       while (buffer_control->buffers.queued_count < buffer_control->buffers.count) {
-               LOGW("wait for output buffer[queued:%d vs count:%u]",
-                       buffer_control->buffers.queued_count, buffer_control->buffers.count);
-
-               end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
-
-               if (!g_cond_wait_until(&buffer_control->cond, &buffer_control->lock, end_time)) {
-                       LOGE("timeout: wait for output buffer");
-                       break;
-               }
-
-               LOGW("signal received, check it again[queued:%d,count:%u]",
-                       buffer_control->buffers.queued_count, buffer_control->buffers.count);
-       }
-
-       g_mutex_unlock(&buffer_control->lock);
-
-       /* release output buffer */
-       buffers = &buffer_control->buffers;
-
-       for (i = 0 ; i < buffers->count ; i++) {
-               codec_buffer = &buffers->buffer[i];
-               codec_memory = &codec_buffer->memory;
-
-               for (k = 0 ; k < codec_memory->num_fd ; k++) {
-                       if (codec_memory->fd[k] > CODEC_HAL_INITIAL_FD) {
-                               LOGI("[OUTPUT][%d][%d] close fd[%d]", i, k, codec_memory->fd[k]);
-                               close(codec_memory->fd[k]);
-                               codec_memory->fd[k] = CODEC_HAL_INITIAL_FD;
-                       }
-
-                       if (buffers->bo[i][k]) {
-                               LOGI("[OUTPUT][%d][%d] unref bo[%p]", i, k, buffers->bo[i][k]);
-                               tbm_bo_unref(buffers->bo[i][k]);
-                               buffers->bo[i][k] = NULL;
-                       }
-               }
-       }
-
-       ret = __codec_v4l2_reqbufs(handle->device_fd,
-               buffer_control->config.buf_type, V4L2_MEMORY_MMAP, 0, NULL);
-       if (ret != HAL_CODEC_ERROR_NONE) {
-               LOGE("[OUTPUT] REQBUFS 0 failed[0x%x]", ret);
+               LOGE("[OUTPUT] stop stream failed[0x%x]", ret);
                return;
        }
 
        memset(&v4l2_fmt, 0x0, sizeof(struct v4l2_format));
 
-       v4l2_fmt.type = buffer_control->config.buf_type;
+       v4l2_fmt.type = config->buf_type;
 
        if (ioctl(handle->device_fd, VIDIOC_G_FMT, &v4l2_fmt) < 0) {
                LOGE("G_FMT failed");
                return;
        }
 
-       if (V4L2_TYPE_IS_MULTIPLANAR(buffer_control->config.buf_type)) {
+       if (V4L2_TYPE_IS_MULTIPLANAR(config->buf_type)) {
                new_width = v4l2_fmt.fmt.pix_mp.width;
                new_height = v4l2_fmt.fmt.pix_mp.height;
        } else {
@@ -1961,8 +1888,8 @@ static void __codec_v4l2_restart_output_stream(codec_hal_handle_s *handle)
 
        LOGI("new resolution[%dx%d]", new_width, new_height);
 
-       buffer_control->config.resolution.width = new_width;
-       buffer_control->config.resolution.height = new_height;
+       config->resolution.width = new_width;
+       config->resolution.height = new_height;
 
        ret = __codec_v4l2_start_stream(handle, buffer_control, BUFFER_NUM_OUTPUT);
        if (ret != HAL_CODEC_ERROR_NONE) {
@@ -1970,8 +1897,9 @@ static void __codec_v4l2_restart_output_stream(codec_hal_handle_s *handle)
                return;
        }
 
-       __codec_v4l2_message_send(handle, HAL_CODEC_MESSAGE_TYPE_RESOLUTION_CHANGED,
-               &buffer_control->config.resolution);
+       __codec_v4l2_message_send(handle,
+               HAL_CODEC_MESSAGE_TYPE_RESOLUTION_CHANGED,
+               &config->resolution);
 
        LOGI("done");
 }
@@ -2155,6 +2083,8 @@ int codec_v4l2_stop(void *codec_handle)
 {
        int ret = HAL_CODEC_ERROR_NONE;
        codec_hal_handle_s *handle = (codec_hal_handle_s *)codec_handle;
+       codec_hal_buffer_control_s *input_control = NULL;
+       codec_hal_buffer_control_s *output_control = NULL;
        g_autoptr(GMutexLocker) locker = NULL;
 
        if (!handle) {
@@ -2174,7 +2104,11 @@ int codec_v4l2_stop(void *codec_handle)
 
        handle->is_stopping = TRUE;
 
-       ret = __codec_v4l2_stop_stream(handle);
+       input_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT];
+       output_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT];
+
+       ret = __codec_v4l2_stop_stream(handle, output_control);
+       ret |= __codec_v4l2_stop_stream(handle, input_control);
        if (ret != HAL_CODEC_ERROR_NONE) {
                LOGE("__codec_stop_stream failed[0x%x]", ret);
                goto _STOP_DONE;
@@ -2183,9 +2117,9 @@ int codec_v4l2_stop(void *codec_handle)
        LOGI("join buffer thread[%p]", handle->buffer_handler);
 
        if (handle->buffer_handler) {
-               g_mutex_lock(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT].lock);
-               g_cond_broadcast(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT].cond);
-               g_mutex_unlock(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT].lock);
+               g_mutex_lock(&output_control->lock);
+               g_cond_broadcast(&output_control->cond);
+               g_mutex_unlock(&output_control->lock);
 
                g_thread_join(handle->buffer_handler);
                handle->buffer_handler = NULL;