From: Jeongmo Yang Date: Tue, 14 Jan 2025 02:35:14 +0000 (+0900) Subject: Support timestamp and set missed bytesused value X-Git-Tag: accepted/tizen/unified/20250610.081745~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4dcfd35ae3819802016b57dab8e02b845756fe29;p=platform%2Fhal%2Fbackend%2Fcodec-v4l2.git Support timestamp and set missed bytesused value Signed-off-by: Jeongmo Yang --- diff --git a/src/hal_backend_codec_v4l2.c b/src/hal_backend_codec_v4l2.c index c88471f..afe8ca8 100644 --- a/src/hal_backend_codec_v4l2.c +++ b/src/hal_backend_codec_v4l2.c @@ -57,9 +57,8 @@ #define LOGE(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) #endif -#define VIRTUAL_CODEC_FMT_MAX 2 -#define VIRTUAL_CODEC_RES_MAX 3 #define DEVICE_NODE_PATH_PREFIX "/dev/video" + #define FOURCC_FORMAT "%c%c%c%c" #define FOURCC_CONVERT(fourcc) \ fourcc & 0xff,\ @@ -67,6 +66,14 @@ (fourcc >> 16) & 0xff,\ (fourcc >> 24) & 0xff +#define TIMESTAMP_SECOND ((uint64_t)1000000000) +#define TIMESTAMP_FORMAT "03lu:%02lu:%02lu.%03lu" +#define TIMESTAMP_ARGS(time) \ + (((uint64_t)time / (TIMESTAMP_SECOND * 60 * 60))), \ + (((uint64_t)time / (TIMESTAMP_SECOND * 60)) % 60), \ + (((uint64_t)time / TIMESTAMP_SECOND) % 60), \ + ((uint64_t)time % TIMESTAMP_SECOND) + #define DEVICE_TYPE_MAX (HAL_CODEC_TYPE_ENCODER + 1) #define DEVICE_NODE_PATH_LENGTH_MAX 32 #define DEVICE_MAX 8 @@ -80,16 +87,19 @@ #define POLL_ERROR_TRY_SLEEP_US 100000 +#define BUFFER_CONTROL_TYPE_STRING(type) \ + ((type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) ? "INPUT" : "OUTPUT") + #define TIMESTAMP_TO_TIMEVAL(timestamp, timeval) \ do { \ - timeval.tv_sec = (glong)(timestamp / NSEC_PER_SEC); \ - timeval.tv_usec = (glong)((timestamp % NSEC_PER_SEC) / 1000); \ + (timeval).tv_sec = ((uint64_t)(timestamp) / NSEC_PER_SEC); \ + (timeval).tv_usec = (((uint64_t)(timestamp) - ((timeval).tv_sec * NSEC_PER_SEC)) / 1000); \ } while (0) #define TIMEVAL_TO_TIMESTAMP(timeval, timestamp) \ do { \ - timestamp = timeval.tv_sec * NSEC_PER_SEC; \ - timestamp += timeval.tv_usec * 1000; \ + (timestamp) = (uint64_t)(timeval).tv_sec * NSEC_PER_SEC; \ + (timestamp) += (uint64_t)(timeval).tv_usec * 1000; \ } while (0) #define CODEC_THREAD_NAME_HANDLE_BUFFER "handle_buffer" @@ -166,6 +176,17 @@ static void __codec_v4l2_destructor(void) } +static char *__codec_v4l2_get_error_string(int err_number) +{ + static char error_string[ERROR_STRING_LENGTH]; + + error_string[0] = '\0'; + strerror_r(err_number, error_string, ERROR_STRING_LENGTH); + + return error_string; +} + + static void __codec_v4l2_get_supported_format_list(int device_fd, enum v4l2_buf_type buf_type, codec_v4l2_format_list_s *format_list) @@ -255,14 +276,14 @@ static int __codec_v4l2_probe_device(void) device_fd = open(glob_buf.gl_pathv[i], O_RDWR); if (device_fd < 0) { - LOGE("open failed [%s] errno %d", glob_buf.gl_pathv[i], errno); + LOGE("open failed [%s] %s", glob_buf.gl_pathv[i], __codec_v4l2_get_error_string(errno)); continue; } memset(&v4l2_cap, 0x0, sizeof(struct v4l2_capability)); if (ioctl(device_fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) { - LOGE("querycap failed. errno %d", errno); + LOGE("querycap failed[%s]", __codec_v4l2_get_error_string(errno)); close(device_fd); continue; } @@ -579,7 +600,7 @@ static int __codec_v4l2_s_fmt(codec_hal_buffer_control_s *buffer_control, int de } if (ioctl(device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) { - LOGE("type[%d] S_FMT failed. errno %d", type, errno); + LOGE("type[%d] S_FMT failed[%s]", type, __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_INTERNAL; } @@ -609,7 +630,7 @@ static int __codec_v4l2_stream(int device_fd, int type, gboolean onoff) } if (ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type) < 0) { - LOGE("stream %d failed. [t:%d] errno %d", onoff, type, errno); + LOGE("stream %d failed. [t:%d] %s", onoff, type, __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_INTERNAL; } @@ -637,7 +658,7 @@ static int __codec_v4l2_reqbufs(int device_fd, int type, int memory, uint32_t co v4l2_reqbuf.count = count; if (ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) { - LOGE("REQBUFS[count %d] failed. errno %d", count, errno); + LOGE("REQBUFS[count %d] failed[%s]", count, __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_INTERNAL; } @@ -683,18 +704,24 @@ static int __codec_v4l2_qbuf(int device_fd, if (codec_config->memory == V4L2_MEMORY_DMABUF) { if (codec_memory->num_fd == 0 || codec_memory->num_fd > HAL_CODEC_BUFFER_PLANE_MAX) { - LOGE("invalid num_fd[%u]", codec_memory->num_fd); + LOGE("[%s] QBUF invalid num_fd[%u]", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + codec_memory->num_fd); return HAL_CODEC_ERROR_INVALID_PARAMETER; } if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) { for (i = 0 ; i < codec_memory->num_fd ; i++) { - LOGD("plane[%d] fd %d", i, codec_memory->fd[i]); + LOGD("[%s] QBUF plane[%d] fd %d", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + i, codec_memory->fd[i]); v4l2_buf.m.planes[i].m.fd = codec_memory->fd[i]; } } else { if (codec_memory->num_fd != 1) - LOGW("invalid num_fd[%u]", codec_memory->num_fd); + LOGW("[%s] QBUF invalid num_fd[%u]", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + codec_memory->num_fd); v4l2_buf.m.fd = codec_memory->fd[0]; } @@ -703,21 +730,39 @@ static int __codec_v4l2_qbuf(int device_fd, } else { /* V4L2_MEMORY_MMAP */ v4l2_buf.length = 1; + if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) { + 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), + 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), + v4l2_buf.bytesused); + } } - if (codec_buffer->meta.timestamp > 0) { + if (buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT) { TIMESTAMP_TO_TIMEVAL(codec_buffer->meta.timestamp, v4l2_buf.timestamp); - LOGD("timeval sec:%lu, usec:%lu", v4l2_buf.timestamp.tv_sec, v4l2_buf.timestamp.tv_usec); + + LOGD("[INPUT] QBUF timestamp: [%"TIMESTAMP_FORMAT"] -> sec[%lu], usec[%lu]", + TIMESTAMP_ARGS(codec_buffer->meta.timestamp), + v4l2_buf.timestamp.tv_sec, v4l2_buf.timestamp.tv_usec); } if (ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) { - LOGE("QBUF failed. control[%d] buffer[%d], errno[%d]", - buffer_control->type, codec_buffer->index, errno); + LOGE("[%s] QBUF failed: buffer[%d] %s", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + codec_buffer->index, __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_INTERNAL; } - LOGD("QBUF done - control[%d] buffer[%d]", - buffer_control->type, codec_buffer->index); + LOGD("[%s] QBUF done: buffer[%d]", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + codec_buffer->index); return HAL_CODEC_ERROR_NONE; } @@ -752,16 +797,35 @@ static int __codec_v4l2_dqbuf(int device_fd, ret = ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf); if (ret < 0) { - LOGE("control[%d] DQBUF failed. [t: %d, m: %d] errno %d", - buffer_control->type, codec_config->buf_type, codec_config->memory, errno); + LOGE("[%s] DQBUF failed. [t: %d, m: %d] %s", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + codec_config->buf_type, codec_config->memory, + __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_DEVICE_READ; } - LOGD("control[%d] DQBUF[i:%d], bytesused[%u], length[%u]", - buffer_control->type, v4l2_buf.index, v4l2_buf.bytesused, v4l2_buf.length); + if (V4L2_TYPE_IS_MULTIPLANAR(codec_config->buf_type)) { + LOGD("[%s] DQBUF done: index[%d], length[%u], bytesused[%u,%u]", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + v4l2_buf.index, v4l2_buf.length, + v4l2_buf.m.planes[0].bytesused, + v4l2_buf.m.planes[1].bytesused); + } else { + LOGD("[%s] DQBUF done: index[%d], bytesused[%u], length[%u]", + BUFFER_CONTROL_TYPE_STRING(buffer_control->type), + v4l2_buf.index, v4l2_buf.bytesused, v4l2_buf.length); + } *out_buffer = &buffer_control->buffers.buffer[v4l2_buf.index]; + if (buffer_control->type == CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT) { + TIMEVAL_TO_TIMESTAMP(v4l2_buf.timestamp, (*out_buffer)->meta.timestamp); + + LOGD("[OUTPUT] DQBUF timestamp: sec[%lu], usec[%lu] -> [%"TIMESTAMP_FORMAT"]", + v4l2_buf.timestamp.tv_sec, v4l2_buf.timestamp.tv_usec, + TIMESTAMP_ARGS((*out_buffer)->meta.timestamp)); + } + return HAL_CODEC_ERROR_NONE; } @@ -900,13 +964,13 @@ static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle) 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]); + 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 (buffer_control->buffers.bo[i][k]) { - LOGI("[output][%d][%d] unref bo[%p]", i, k, buffer_control->buffers.bo[i][k]); + LOGI("[OUTPUT][%d][%d] unref bo[%p]", i, k, buffer_control->buffers.bo[i][k]); tbm_bo_unref(buffer_control->buffers.bo[i][k]); buffer_control->buffers.bo[i][k] = NULL; } @@ -916,7 +980,7 @@ static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle) 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] REQBUFS 0 failed[0x%x]", ret); return ret; } @@ -927,12 +991,12 @@ static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle) codec_buffer = &buffer_control->buffers.buffer[i]; if (!codec_buffer->planes.plane[0].data || codec_buffer->size == 0) { - LOGW("[input][%d] invalid data[%p], size[%u]", + LOGW("[INPUT][%d] invalid data[%p], size[%u]", i, codec_buffer->planes.plane[0].data, codec_buffer->size); continue; } - LOGI("[input][%d] munmap[%p], size[%u]", + 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); @@ -944,7 +1008,7 @@ static int __codec_v4l2_stop_stream(codec_hal_handle_s *handle) ret = __codec_v4l2_reqbufs(handle->device_fd, buffer_control->config.buf_type, V4L2_MEMORY_MMAP, 0, NULL); if (ret != HAL_CODEC_ERROR_NONE) { - LOGE("[input] REQBUFS 0 failed[0x%x]", ret); + LOGE("[INPUT] REQBUFS 0 failed[0x%x]", ret); return ret; } @@ -1021,7 +1085,8 @@ static int __codec_v4l2_start_stream(codec_hal_handle_s *handle, v4l2_buf.length = num_planes; if (ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) { - LOGE("type[%d] buffer[i:%d] query buf failed (errno %d)", type, i, errno); + LOGE("type[%d] buffer[i:%d] query buf failed[%s]", + type, i, __codec_v4l2_get_error_string(errno)); ret = HAL_CODEC_ERROR_INTERNAL; goto _START_STREAM_FAILED; } @@ -1036,8 +1101,9 @@ static int __codec_v4l2_start_stream(codec_hal_handle_s *handle, (off_t)v4l2_planes[k].m.mem_offset); if (codec_buffer->planes.plane[k].data == MAP_FAILED) { - LOGE("type[%d] buffer[i:%d][plane:%d] mmap failed, size[%d], offset[%u] for mmap (errno %d)", - type, i, k, v4l2_planes[k].length, v4l2_planes[k].m.mem_offset, errno); + LOGE("type[%d] buffer[i:%d][plane:%d] mmap failed, size[%d], offset[%u] for mmap[%s]", + type, i, k, v4l2_planes[k].length, v4l2_planes[k].m.mem_offset, + __codec_v4l2_get_error_string(errno)); ret = HAL_CODEC_ERROR_INTERNAL; goto _START_STREAM_FAILED; } @@ -1104,8 +1170,8 @@ static int __codec_v4l2_start_stream(codec_hal_handle_s *handle, buffer_control, codec_buffer); if (ret != HAL_CODEC_ERROR_NONE) { - LOGE("[output][%d] qbuf failed (fd %d, errno %d)", - i, codec_memory->fd[0], errno); + LOGE("[output][%d] qbuf failed[fd:%d] %s", + i, codec_memory->fd[0], __codec_v4l2_get_error_string(errno)); goto _START_STREAM_FAILED; } } @@ -1509,9 +1575,7 @@ int codec_v4l2_configure(void *codec_handle, int width, int height, /* device open */ device_fd = open(node_path, O_RDWR); if (device_fd < 0) { - char error_string[ERROR_STRING_LENGTH] = {'\0',}; - strerror_r(errno, error_string, ERROR_STRING_LENGTH); - LOGE("[%s] open failed [%s]", node_path, error_string); + LOGE("[%s] open failed [%s]", node_path, __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_DEVICE_OPEN; } @@ -1588,7 +1652,6 @@ static int __codec_v4l2_poll(codec_hal_handle_s *handle, short events, int timeo { int ret = 0; struct pollfd poll_fd; - char error_string[ERROR_STRING_LENGTH] = {'\0',}; if (!handle) { LOGE("NULL handle"); @@ -1603,8 +1666,7 @@ static int __codec_v4l2_poll(codec_hal_handle_s *handle, short events, int timeo ret = poll(&poll_fd, 1, timeout_ms); if (ret < 0) { - strerror_r(errno, error_string, ERROR_STRING_LENGTH); - LOGE("poll[events 0x%x] failed[%s]", events, error_string); + LOGE("poll[events 0x%x] failed[%s]", events, __codec_v4l2_get_error_string(errno)); } else if (ret == 0) { LOGW("poll[events 0x%x] time out for %d ms", events, timeout_ms); } else { @@ -1652,9 +1714,7 @@ static gpointer __codec_v4l2_buffer_handler_func(gpointer data) break; if (revents & POLLERR) { - char error_string[ERROR_STRING_LENGTH] = {'\0',}; - strerror_r(errno, error_string, ERROR_STRING_LENGTH); - LOGW("POLLERR[%s]", error_string); + LOGW("POLLERR[%s]", __codec_v4l2_get_error_string(errno)); if (handle->is_stopping) { LOGW("now stopping... stop buffer handler"); @@ -1899,6 +1959,8 @@ int codec_v4l2_decode(void *codec_handle, hal_codec_buffer_s *buffer) } memcpy(idle_buffer->planes.plane[0].data, buffer->planes.plane[0].data, buffer->planes.plane[0].bytesused); + idle_buffer->planes.plane[0].bytesused = buffer->planes.plane[0].bytesused; + memcpy(&idle_buffer->meta, &buffer->meta, sizeof(hal_codec_meta_s)); ret = __codec_v4l2_qbuf(handle->device_fd, @@ -1944,11 +2006,15 @@ int codec_v4l2_get_state(void *codec_handle, hal_codec_state_e *state) { codec_hal_handle_s *handle = (codec_hal_handle_s *)codec_handle; - if (!handle) { - LOGE("NULL handle"); + if (!handle || !state) { + LOGE("NULL param[%p,%p]", handle, state); return HAL_CODEC_ERROR_INVALID_PARAMETER; } + *state = handle->state; + + LOGD("state[%d]", *state); + return HAL_CODEC_ERROR_NONE; } @@ -1966,7 +2032,7 @@ static int __codec_v4l2_set_command(codec_hal_handle_s *handle, int64_t command, set_value = *(int *)value; - if (handle->state < HAL_CODEC_STATE_OPENED) { + if (handle->state < HAL_CODEC_STATE_CONFIGURED) { LOGE("invalid state %d", handle->state); return HAL_CODEC_ERROR_INVALID_STATE; } @@ -1988,7 +2054,7 @@ static int __codec_v4l2_set_command(codec_hal_handle_s *handle, int64_t command, switch (errno) { case EACCES: case EPERM: - LOGE("Permission denied %d", errno); + LOGE("Permission denied[%s]", __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_PERMISSION_DENIED; case EINVAL: LOGE("Invalid argument"); @@ -2000,7 +2066,7 @@ static int __codec_v4l2_set_command(codec_hal_handle_s *handle, int64_t command, LOGE("Not supported"); return HAL_CODEC_ERROR_NOT_SUPPORTED; default: - LOGE("Unknown errro %d", errno); + LOGE("Unknown errno[%s]", __codec_v4l2_get_error_string(errno)); return HAL_CODEC_ERROR_INTERNAL; } } @@ -2038,14 +2104,14 @@ int codec_v4l2_get_command(void *codec_handle, hal_codec_command_e command, void locker = g_mutex_locker_new(&handle->lock); - LOGI("command[0x%x]", command); + LOGI("command[0x%"PRIx64"]", command); switch (command) { case HAL_CODEC_COMMAND_BITRATE: cid = V4L2_CID_MPEG_VIDEO_BITRATE; break; default: - LOGE("Not supported command[0x%x]", command); + LOGE("Not supported command[0x%"PRIx64"]", command); return HAL_CODEC_ERROR_NOT_SUPPORTED; } @@ -2054,7 +2120,7 @@ int codec_v4l2_get_command(void *codec_handle, hal_codec_command_e command, void switch (errno) { case EACCES: case EPERM: - LOGE("Permission denied %d", errno); + LOGE("Permission denied[%s]", __codec_v4l2_get_error_string(errno)); ret = HAL_CODEC_ERROR_PERMISSION_DENIED; break; case EINVAL: @@ -2070,7 +2136,7 @@ int codec_v4l2_get_command(void *codec_handle, hal_codec_command_e command, void ret = HAL_CODEC_ERROR_NOT_SUPPORTED; break; default: - LOGE("Unknown errro %d", errno); + LOGE("Unknown errro[%s]", __codec_v4l2_get_error_string(errno)); ret = HAL_CODEC_ERROR_INTERNAL; break; } @@ -2128,7 +2194,7 @@ int codec_v4l2_set_batch_command(void *codec_handle, hal_codec_batch_command_con ret = __codec_v4l2_set_command(handle, set_table[i].command, set_table[i].value); if (ret != HAL_CODEC_ERROR_NONE) { - LOGE("failed command 0x%x, ret 0x%x", set_table[i].command, ret); + LOGE("failed command 0x%"PRIx64", ret 0x%x", set_table[i].command, ret); break; } }