From: Jeongmo Yang Date: Wed, 22 Jan 2025 06:00:04 +0000 (+0900) Subject: Set input buffer size with supported max resolution X-Git-Tag: accepted/tizen/unified/20250610.081745~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=04a799128d95f5e9c4261e2beba28a1365113691;p=platform%2Fhal%2Fbackend%2Fcodec-v4l2.git Set input buffer size with supported max resolution - QBUF for input buffer could be failed because of small buffer size. The default buffer size is not enough in case of high bitrate content. Signed-off-by: Jeongmo Yang --- diff --git a/src/hal_backend_codec_v4l2.c b/src/hal_backend_codec_v4l2.c index afe8ca8..9a93890 100644 --- a/src/hal_backend_codec_v4l2.c +++ b/src/hal_backend_codec_v4l2.c @@ -110,6 +110,7 @@ typedef struct _codec_v4l2_format_list_s { enum v4l2_buf_type buf_type; hal_codec_format_type_e format_type; hal_codec_format_e formats[DEVICE_FORMAT_MAX]; + hal_codec_resolution_s max_resolution[DEVICE_FORMAT_MAX]; } codec_v4l2_format_list_s; typedef struct _codec_v4l2_device_s { @@ -195,6 +196,7 @@ static void __codec_v4l2_get_supported_format_list(int device_fd, uint32_t count = 0; hal_codec_format_e format = HAL_CODEC_FORMAT_H264; struct v4l2_fmtdesc fmtdesc; + struct v4l2_frmsizeenum frmsize; if (device_fd < 0 || !format_list) { LOGE("invalid param[%d,%p]", device_fd, format_list); @@ -214,15 +216,29 @@ static void __codec_v4l2_get_supported_format_list(int device_fd, break; } - if (__codec_v4l2_get_format(fmtdesc.pixelformat, &format) == HAL_CODEC_ERROR_NONE) { - format_list->formats[count] = format; - count++; + if (__codec_v4l2_get_format(fmtdesc.pixelformat, &format) != HAL_CODEC_ERROR_NONE) + continue; + + format_list->formats[count] = format; + + if (format & HAL_CODEC_FORMAT_TYPE_ENCODED) + format_list->format_type = HAL_CODEC_FORMAT_TYPE_ENCODED; + else + format_list->format_type = HAL_CODEC_FORMAT_TYPE_RAW; + + memset(&frmsize, 0x0, sizeof(struct v4l2_frmsizeenum)); - if (format & HAL_CODEC_FORMAT_TYPE_ENCODED) - format_list->format_type = HAL_CODEC_FORMAT_TYPE_ENCODED; - else - format_list->format_type = HAL_CODEC_FORMAT_TYPE_RAW; + frmsize.pixel_format = fmtdesc.pixelformat; + + if (ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0) { + LOGI("["FOURCC_FORMAT"] max size [%ux%u]", FOURCC_CONVERT(fmtdesc.pixelformat), + frmsize.stepwise.max_width, frmsize.stepwise.max_height); + + format_list->max_resolution[count].width = frmsize.stepwise.max_width; + format_list->max_resolution[count].height = frmsize.stepwise.max_height; } + + count++; } format_list->count = count; @@ -321,10 +337,7 @@ static int __codec_v4l2_probe_device(void) close(device_fd); if (codec_device->in_format.count > 0 && codec_device->out_format.count > 0 && - ((codec_device->in_format.format_type == HAL_CODEC_FORMAT_TYPE_ENCODED && - codec_device->out_format.format_type == HAL_CODEC_FORMAT_TYPE_RAW) || - (codec_device->in_format.format_type == HAL_CODEC_FORMAT_TYPE_RAW && - codec_device->out_format.format_type == HAL_CODEC_FORMAT_TYPE_ENCODED))) { + codec_device->in_format.format_type != codec_device->out_format.format_type) { strncpy(codec_device->node_path, glob_buf.gl_pathv[i], DEVICE_NODE_PATH_LENGTH_MAX - 1); codec_device->capabilities = device_caps; @@ -390,8 +403,9 @@ static void __codec_v4l2_release_device_list(void) } -static int __codec_v4l2_get_buf_type_and_node_path(hal_codec_format_e in_format, hal_codec_format_e out_format, - enum v4l2_buf_type *in_buf_type, enum v4l2_buf_type *out_buf_type, char **path) +static int __codec_v4l2_get_device_info(hal_codec_format_e in_format, hal_codec_format_e out_format, + enum v4l2_buf_type *in_buf_type, enum v4l2_buf_type *out_buf_type, + hal_codec_resolution_s *in_max_resolution, hal_codec_resolution_s *out_max_resolution, char **path) { uint32_t device_index = 0; uint32_t format_index = 0; @@ -419,6 +433,10 @@ static int __codec_v4l2_get_buf_type_and_node_path(hal_codec_format_e in_format, for (format_index = 0 ; format_index < format_list->count ; format_index++) { if (format_list->formats[format_index] == in_format) { *in_buf_type = format_list->buf_type; + if (in_max_resolution) { + in_max_resolution->width = format_list->max_resolution[format_index].width; + in_max_resolution->height = format_list->max_resolution[format_index].height; + } break; } } @@ -435,6 +453,11 @@ static int __codec_v4l2_get_buf_type_and_node_path(hal_codec_format_e in_format, *out_buf_type = format_list->buf_type; *path = codec_device->node_path; + if (out_max_resolution) { + out_max_resolution->width = format_list->max_resolution[format_index].width; + out_max_resolution->height = format_list->max_resolution[format_index].height; + } + LOGI("found node path[%s], buf_type[in:%d, out:%d] for format[in:0x%x, out:0x%x]", *path, *in_buf_type, *out_buf_type, in_format, out_format); @@ -535,7 +558,7 @@ static int __codec_v4l2_s_ctrl(int device_fd, int cid, int value) static int __codec_v4l2_set_config(codec_hal_buffer_control_s *buffer_control, enum v4l2_buf_type buf_type, enum v4l2_memory memory, - hal_codec_format_e format, int width, int height) + hal_codec_format_e format, int width, int height, int max_width, int max_height) { codec_hal_config_s *codec_config = NULL; @@ -546,14 +569,16 @@ static int __codec_v4l2_set_config(codec_hal_buffer_control_s *buffer_control, codec_config = &buffer_control->config; - LOGI("type[%d] v4l2[buf type:%d, memory:%d], format[0x%x], resolution[%dx%d]", - buffer_control->type, buf_type, memory, format, width, height); + LOGI("type[%d] v4l2[buf type:%d, memory:%d], format[0x%x], resolution[%dx%d][max:%dx%d]", + buffer_control->type, buf_type, memory, format, width, height, max_width, max_height); codec_config->buf_type = buf_type; codec_config->memory = memory; codec_config->format = format; codec_config->resolution.width = width; codec_config->resolution.height = height; + codec_config->max_resolution.width = max_width; + codec_config->max_resolution.height = max_height; return HAL_CODEC_ERROR_NONE; } @@ -577,7 +602,8 @@ static int __codec_v4l2_s_fmt(codec_hal_buffer_control_s *buffer_control, int de type = buffer_control->type; if (__codec_get_fourcc_plane_num(codec_config->format, &fourcc, &num_planes) != HAL_CODEC_ERROR_NONE) { - LOGE("type[%d] get fourcc failed for format [0x%x]", type, codec_config->format); + LOGE("[%s] get fourcc failed for format [0x%x]", + BUFFER_CONTROL_TYPE_STRING(type), codec_config->format); return HAL_CODEC_ERROR_INVALID_PARAMETER; } @@ -599,15 +625,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 && + 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), + 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("type[%d] S_FMT failed[%s]", type, __codec_v4l2_get_error_string(errno)); + LOGE("[%s] S_FMT failed[%s]", BUFFER_CONTROL_TYPE_STRING(type), __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_INTERNAL; } if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) { for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) { - LOGI("type[%d] plane[%d] size [%u]", - type, i, v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage); + LOGI("[%s] plane[%d] size [%u]", BUFFER_CONTROL_TYPE_STRING(type), + i, v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage); codec_config->buffer_size += v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage; } } else { @@ -615,8 +652,8 @@ 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("type[%d] buffer size[%u], num planes[%u]", - type, codec_config->buffer_size, codec_config->num_planes); + LOGI("[%s] buffer size[%u], num planes[%u]", BUFFER_CONTROL_TYPE_STRING(type), + codec_config->buffer_size, codec_config->num_planes); return HAL_CODEC_ERROR_NONE; } @@ -1515,6 +1552,8 @@ int codec_v4l2_configure(void *codec_handle, int width, int height, int i = 0; int ret = 0; int device_fd = CODEC_HAL_INITIAL_FD; + hal_codec_resolution_s in_max_resolution = {0, 0}; + hal_codec_resolution_s out_max_resolution = {0, 0}; char *node_path = NULL; codec_hal_handle_s *handle = (codec_hal_handle_s *)codec_handle; @@ -1544,8 +1583,8 @@ int codec_v4l2_configure(void *codec_handle, int width, int height, return HAL_CODEC_ERROR_INVALID_PARAMETER; } - ret = __codec_v4l2_get_buf_type_and_node_path(in_format, out_format, - &in_buf_type, &out_buf_type, &node_path); + ret = __codec_v4l2_get_device_info(in_format, out_format, + &in_buf_type, &out_buf_type, &in_max_resolution, &out_max_resolution, &node_path); if (ret != HAL_CODEC_ERROR_NONE) return ret; @@ -1581,7 +1620,7 @@ int codec_v4l2_configure(void *codec_handle, int width, int height, /* set format for input */ ret = __codec_v4l2_set_config(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT], - in_buf_type, V4L2_MEMORY_MMAP, in_format, width, height); + in_buf_type, V4L2_MEMORY_MMAP, in_format, width, height, in_max_resolution.width, in_max_resolution.height); if (ret != HAL_CODEC_ERROR_NONE) return ret; @@ -1594,7 +1633,7 @@ int codec_v4l2_configure(void *codec_handle, int width, int height, /* set format for output */ ret = __codec_v4l2_set_config(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT], - out_buf_type, V4L2_MEMORY_DMABUF, out_format, width, height); + out_buf_type, V4L2_MEMORY_DMABUF, out_format, width, height, 0, 0); if (ret != HAL_CODEC_ERROR_NONE) return ret; @@ -1926,7 +1965,7 @@ static void __codec_v4l2_add_idle_buffer(codec_hal_buffer_control_s *buffer_cont g_queue_push_tail(buffer_control->buffers.idle_buffers, GINT_TO_POINTER(buffer->index)); - g_cond_broadcast(&buffer_control->cond); + g_cond_broadcast(&buffer_control->cond); } @@ -1968,12 +2007,14 @@ int codec_v4l2_decode(void *codec_handle, hal_codec_buffer_s *buffer) if (ret != HAL_CODEC_ERROR_NONE) { LOGE("QBUF[%p] failed[i:%d], 0x%x", buffer, idle_buffer->index, ret); - } else { - LOGD("QBUF[%p] done", buffer); - __codec_v4l2_message_send(handle, HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED, buffer); + return ret; } - return ret; + LOGD("QBUF[%p] done", buffer); + + __codec_v4l2_message_send(handle, HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED, buffer); + + return HAL_CODEC_ERROR_NONE; } diff --git a/src/hal_backend_codec_v4l2_private.h b/src/hal_backend_codec_v4l2_private.h index 51acde6..e32eb04 100644 --- a/src/hal_backend_codec_v4l2_private.h +++ b/src/hal_backend_codec_v4l2_private.h @@ -29,7 +29,7 @@ #define CODEC_HAL_INITIAL_INDEX -1 #define CODEC_HAL_INITIAL_FD -1 -#define BUFFER_MIN 4 +#define BUFFER_MIN 6 #define BUFFER_MAX 16 #define V4L2_PLANES_MAX 4 @@ -55,6 +55,7 @@ typedef struct { enum v4l2_memory memory; hal_codec_format_e format; hal_codec_resolution_s resolution; + hal_codec_resolution_s max_resolution; uint32_t num_planes; uint32_t buffer_size; } codec_hal_config_s;