static int __codec_v4l2_set_command(codec_hal_handle_s *handle, int64_t command, void *value);
-static hal_codec_buffer_s *__codec_v4l2_get_idle_buffer(codec_hal_buffer_control_s *buffer_control, gint64 timeout_ms);
-static void __codec_v4l2_add_idle_buffer(codec_hal_buffer_control_s *buffer_control, hal_codec_buffer_s *buffer);
+static hal_codec_buffer_s *__codec_v4l2_get_idle_buffer(codec_hal_buffer_control_s *buffer_control, gint64 timeout_ms, hal_codec_buffer_s *user_buffer);
+static void __codec_v4l2_add_idle_buffer(codec_hal_buffer_control_s *buffer_control, hal_codec_buffer_s *buffer, hal_codec_buffer_s **user_buffer);
static int __codec_v4l2_get_format(guint32 fourcc, hal_codec_format_e *format);
static int __codec_v4l2_get_fourcc_plane_num(hal_codec_format_e format, uint32_t *fourcc, uint32_t *plane_num);
static void __codec_v4l2_release_device_list(void)
{
uint32_t device_index = 0;
- uint32_t device_count = 0;
codec_v4l2_device_s *codec_device = NULL;
if (!g_codec_device_list) {
LOGI("release device list [%p]", g_codec_device_list);
- for (device_index = 0 ; device_index < device_count ; device_index++) {
+ for (device_index = 0 ; device_index < g_codec_device_list->count ; device_index++) {
codec_device = g_codec_device_list->devices[device_index];
if (!codec_device) {
LOGW("NULL codec_device for index[%u]", device_index);
message = g_new0(hal_codec_message_s, 1);
message->type = type;
- locker = g_mutex_locker_new(&handle->msg_cb_lock);
-
switch (type) {
case HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED:
message->buffer = (hal_codec_buffer_s *)value;
- LOGD("InputBufferUsed[message:%p]: buffer[i:%d,HAL:%p]",
- message, message->buffer->index, message->buffer);
+ if (!message->buffer) {
+ LOGE("[INPUT_BUFFER_USED] NULL buffer");
+ g_free(message);
+ return;
+ }
+ LOGD("[INPUT_BUFFER_USED] buffer[%d] %p", message->buffer->index, message->buffer);
break;
case HAL_CODEC_MESSAGE_TYPE_OUTPUT_BUFFER:
message->buffer = (hal_codec_buffer_s *)value;
- LOGD("OutputBuffer[message:%p]: buffer[i:%d,HAL:%p]",
- message, message->buffer->index, message->buffer);
+ if (!message->buffer) {
+ LOGE("[OUTPUT_BUFFER] NULL buffer");
+ g_free(message);
+ return;
+ }
+ LOGD("[OUTPUT_BUFFER] buffer[%d] %p", message->buffer->index, message->buffer);
break;
case HAL_CODEC_MESSAGE_TYPE_RESOLUTION_CHANGED:
message->resolution.width = ((hal_codec_resolution_s *)value)->width;
message->resolution.height = ((hal_codec_resolution_s *)value)->height;
- LOGI("ResolutionChanged[%dx%d]", message->resolution.width, message->resolution.height);
+ LOGI("[RESOLUTION_CHANGED] %dx%d", message->resolution.width, message->resolution.height);
break;
case HAL_CODEC_MESSAGE_TYPE_ERROR:
message->error_code = GPOINTER_TO_INT(value);
- LOGE("error code[%d]", message->error_code);
+ LOGE("[ERROR] code[%d]", message->error_code);
break;
default:
- LOGW("unhandled type[%d]", type);
+ LOGE("unhandled type[%d]", type);
g_free(message);
return;
}
- g_queue_push_tail(handle->msg_list, message);
-
- LOGD("message length[%u]", g_queue_get_length(handle->msg_list));
+ locker = g_mutex_locker_new(&handle->msg_cb_lock);
+ g_queue_push_tail(handle->msg_list, message);
g_cond_broadcast(&handle->msg_cb_cond);
}
(*out_buffer)->planes.plane[0].bytesused = v4l2_buf.bytesused;
}
+ if (codec_config->format & HAL_CODEC_FORMAT_TYPE_ENCODED &&
+ v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
+ LOGI("[ENCODER] SYNC FRAME");
+ (*out_buffer)->meta.flags |= HAL_CODEC_BUFFER_FLAG_SYNCFRAME;
+ }
+
if (!BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
TIMEVAL_TO_TIMESTAMP(v4l2_buf.timestamp, (*out_buffer)->meta.timestamp);
g_mutex_lock(&handle->msg_cb_lock);
while (handle->msg_cb_run) {
- if (g_queue_is_empty(handle->msg_list)) {
- LOGD("wait for message");
+ if (g_queue_is_empty(handle->msg_list))
g_cond_wait(&handle->msg_cb_cond, &handle->msg_cb_lock);
- LOGD("message[length:%u] signal received", g_queue_get_length(handle->msg_list));
- }
if (!handle->msg_cb_run) {
LOGW("break message thread");
continue;
}
+#ifdef ENABLE_MESSAGE_THREAD_LOG
switch (message->type) {
case HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED:
- LOGD("INPUT_BUFFER_USED[message:%p]: buffer[index:%d,HAL:%p]",
- message, message->buffer->index, message->buffer);
+ LOGD("[INPUT_BUFFER_USED] buffer[%d] %p", message->buffer->index, message->buffer);
break;
case HAL_CODEC_MESSAGE_TYPE_OUTPUT_BUFFER:
- LOGD("OUTPUT_BUFFER[message:%p]: buffer[index:%d,HAL:%p]",
- message, message->buffer->index, message->buffer);
+ LOGD("[OUTPUT_BUFFER] buffer[%d] %p", message->buffer->index, message->buffer);
break;
case HAL_CODEC_MESSAGE_TYPE_RESOLUTION_CHANGED:
- LOGD("[message:%p] RESOLUTION_CHANGED [%dx%d]",
- message, message->resolution.width, message->resolution.height);
+ LOGD("[RESOLUTION_CHANGED] %dx%d", message, message->resolution.width, message->resolution.height);
break;
default:
break;
}
+#endif
g_mutex_unlock(&handle->msg_cb_lock);
return TBM_FORMAT_NV12;
case HAL_CODEC_FORMAT_I420:
return TBM_FORMAT_YUV420;
+ case HAL_CODEC_FORMAT_YUYV:
+ return TBM_FORMAT_YUYV;
default:
break;
}
static void __codec_v4l2_restart_output_stream(codec_hal_handle_s *handle)
{
+ int i = 0;
int ret = 0;
- int new_width = 0;
- int new_height = 0;
struct v4l2_format v4l2_fmt;
codec_hal_config_s *config = NULL;
codec_hal_buffer_control_s *buffer_control = NULL;
+ tbm_surface_h surface = NULL;
+
if (!handle) {
LOGE("NULL handle");
return;
}
if (V4L2_TYPE_IS_MULTIPLANAR(config->buf_type)) {
- new_width = v4l2_fmt.fmt.pix_mp.width;
- new_height = v4l2_fmt.fmt.pix_mp.height;
+ config->resolution.width = v4l2_fmt.fmt.pix_mp.width;
+ config->resolution.height = v4l2_fmt.fmt.pix_mp.height;
+ 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(buffer_control),
+ i, v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ config->buffer_size += v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage;
+ }
} else {
- new_width = v4l2_fmt.fmt.pix.width;
- new_height = v4l2_fmt.fmt.pix.height;
+ config->resolution.width = v4l2_fmt.fmt.pix.width;
+ config->resolution.height = v4l2_fmt.fmt.pix.height;
+ config->buffer_size = v4l2_fmt.fmt.pix.sizeimage;
}
- LOGI("new resolution[%dx%d]", new_width, new_height);
+ LOGI("new resolution[%dx%d], buffer size[%u]",
+ config->resolution.width, config->resolution.height,
+ config->buffer_size);
- config->resolution.width = new_width;
- config->resolution.height = new_height;
+ surface = tbm_surface_create(config->resolution.width, config->resolution.height,
+ __codec_v4l2_get_tbm_format(config->format));
+ if (!surface) {
+ LOGE("create surface failed [%dx%d][format:%d]",
+ config->resolution.width, config->resolution.height, config->format);
+ return;
+ }
ret = __codec_v4l2_start_stream(handle, buffer_control, BUFFER_NUM_DECODER_OUTPUT);
if (ret != HAL_CODEC_ERROR_NONE) {
codec_hal_handle_s *handle = (codec_hal_handle_s *)data;
hal_codec_buffer_s *input_buffer = NULL;
hal_codec_buffer_s *output_buffer = NULL;
+ hal_codec_buffer_s *user_buffer = NULL;
codec_hal_buffer_control_s *input_control = NULL;
codec_hal_buffer_control_s *output_control = NULL;
LOGD("[INPUT] DQBUF index[%d]", input_buffer->index);
- __codec_v4l2_add_idle_buffer(input_control, input_buffer);
+ __codec_v4l2_add_idle_buffer(input_control, input_buffer, &user_buffer);
+
+ if (!user_buffer)
+ continue;
+
+ if (handle->type == HAL_CODEC_TYPE_DECODER) {
+ LOGW("[DECODER] but, got user_buffer, check it.");
+ continue;
+ }
+
+ __codec_v4l2_message_send(handle, HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED, user_buffer);
}
}
}
-static hal_codec_buffer_s *__codec_v4l2_get_idle_buffer(codec_hal_buffer_control_s *buffer_control, gint64 timeout_ms)
+static hal_codec_buffer_s *__codec_v4l2_get_idle_buffer(codec_hal_buffer_control_s *buffer_control,
+ gint64 timeout_ms, hal_codec_buffer_s *user_buffer)
{
int index = IDLE_BUFFER_INDEX_INIT;
gint64 end_time = 0;
index = GPOINTER_TO_INT(g_queue_pop_head(buffer_control->buffers.idle_buffers));
- LOGD("type[%d] popped buffer[%d]", buffer_control->type, index);
+ buffer_control->buffers.user_buffer[index] = user_buffer;
+
+ LOGD("type[%d] buffer[%d]: user_buffer[%p]",
+ buffer_control->type, index, user_buffer);
return &buffer_control->buffers.buffer[index];
}
-static void __codec_v4l2_add_idle_buffer(codec_hal_buffer_control_s *buffer_control, hal_codec_buffer_s *buffer)
+static void __codec_v4l2_add_idle_buffer(codec_hal_buffer_control_s *buffer_control,
+ hal_codec_buffer_s *buffer, hal_codec_buffer_s **user_buffer)
{
g_autoptr(GMutexLocker) locker = NULL;
LOGD("add idle buffer[%d]", buffer->index);
+ if (user_buffer)
+ *user_buffer = buffer_control->buffers.user_buffer[buffer->index];
+
+ buffer_control->buffers.user_buffer[buffer->index] = NULL;
+
g_queue_push_tail(buffer_control->buffers.idle_buffers, GINT_TO_POINTER(buffer->index));
g_cond_broadcast(&buffer_control->cond);
return HAL_CODEC_ERROR_NONE;
}
- idle_buffer = __codec_v4l2_get_idle_buffer(buffer_control, 0);
+ idle_buffer = __codec_v4l2_get_idle_buffer(buffer_control, 0, NULL);
if (!idle_buffer) {
LOGE("no idle buffer");
return HAL_CODEC_ERROR_DEVICE_BUSY;
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("QBUF[%p] failed[i:%d], 0x%x",
buffer, idle_buffer->index, ret);
+ __codec_v4l2_add_idle_buffer(buffer_control, idle_buffer, NULL);
return ret;
}
return HAL_CODEC_ERROR_NONE;
}
- idle_buffer = __codec_v4l2_get_idle_buffer(buffer_control, 0);
+ idle_buffer = __codec_v4l2_get_idle_buffer(buffer_control, 0, buffer);
if (!idle_buffer) {
LOGE("no idle buffer");
return HAL_CODEC_ERROR_DEVICE_BUSY;
idle_buffer->memory.num_fd = buffer->memory.num_fd;
for (i = 0 ; i < buffer->memory.num_fd ; i++) {
- LOGD("[INPUT] buffer[%d]: memory[%u] fd %d", buffer->index, i, buffer->memory.fd[i]);
+ LOGD("[INPUT] user_buffer[%d] %p: memory[%u] fd %d, idle_buffer[%d] %p",
+ buffer->index, buffer, i, buffer->memory.fd[i], idle_buffer->index, idle_buffer);
idle_buffer->memory.fd[i] = buffer->memory.fd[i];
}
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("QBUF[%p] failed[i:%d], 0x%x",
buffer, idle_buffer->index, ret);
+ __codec_v4l2_add_idle_buffer(buffer_control, idle_buffer, NULL);
return ret;
}