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 {
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);
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;
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;
}
-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;
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;
}
}
*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);
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;
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;
}
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;
}
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 {
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;
}
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;
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;
/* 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;
/* 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;
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);
}
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;
}