#define POLL_ERROR_TRY_COUNT_MAX 10
#define POLL_ERROR_TRY_SLEEP_US 10000
+#define CODEC_IS_DECODER(handle) ((handle)->type == HAL_CODEC_TYPE_DECODER)
+#define BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control) ((buffer_control)->type == CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT)
+#define BUFFER_CONTROL_TYPE_STRING(buffer_control) (((buffer_control)->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 { \
static void __codec_v4l2_add_idle_buffer(codec_hal_buffer_control_s *buffer_control, hal_codec_buffer_s *buffer);
static int __codec_v4l2_get_format(guint32 fourcc, hal_codec_format_e *format);
-static int __codec_get_fourcc_plane_num(hal_codec_format_e format, uint32_t *fourcc, uint32_t *plane_num);
+static int __codec_v4l2_get_fourcc_plane_num(hal_codec_format_e format, uint32_t *fourcc, uint32_t *plane_num);
+static const char *__codec_v4l2_get_format_string(hal_codec_format_e format);
}
if (format_index == format_list->count) {
- LOGW("in_format[%d] not found in device[%d][%s]",
- in_format, device_index, codec_device->node_path);
+ LOGW("in_format[%s] not found in device[%d][%s]",
+ __codec_v4l2_get_format_string(in_format), device_index, codec_device->node_path);
continue;
}
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);
+ LOGI("found node path[%s], buf_type[in:%d, out:%d] for format[in:%s, out:%s]",
+ *path, *in_buf_type, *out_buf_type,
+ __codec_v4l2_get_format_string(in_format),
+ __codec_v4l2_get_format_string(out_format));
return HAL_CODEC_ERROR_NONE;
}
codec_config = &buffer_control->config;
- 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);
+ LOGI("type[%d] v4l2[buf type:%d, memory:%d], format[%s], resolution[%dx%d][max:%dx%d]",
+ buffer_control->type, buf_type, memory,
+ __codec_v4l2_get_format_string(format),
+ width, height, max_width, max_height);
codec_config->buf_type = buf_type;
codec_config->memory = memory;
codec_config = &buffer_control->config;
- if (__codec_get_fourcc_plane_num(codec_config->format, &fourcc, &num_planes) != HAL_CODEC_ERROR_NONE) {
+ if (__codec_v4l2_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(buffer_control), codec_config->format);
return HAL_CODEC_ERROR_INVALID_PARAMETER;
if (codec_config->memory == V4L2_MEMORY_DMABUF) {
if (codec_memory->num_fd == 0 ||
codec_memory->num_fd > HAL_CODEC_BUFFER_PLANE_MAX) {
- LOGE("[%s] QBUF invalid num_fd[%u]",
+ LOGE("[%s] QBUF[DMABUF] invalid num_fd[%u]",
BUFFER_CONTROL_TYPE_STRING(buffer_control),
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("[%s] QBUF plane[%d] fd %d",
+ LOGD("[%s] QBUF[DMABUF] plane[%d] fd[%d], length[%u], bytesused[%u]",
BUFFER_CONTROL_TYPE_STRING(buffer_control),
- i, codec_memory->fd[i]);
+ i, codec_memory->fd[i],
+ codec_buffer->planes.plane[i].size,
+ codec_buffer->planes.plane[i].bytesused);
+
v4l2_buf.m.planes[i].m.fd = codec_memory->fd[i];
+ v4l2_buf.m.planes[i].bytesused = codec_buffer->planes.plane[i].bytesused;
+ v4l2_buf.m.planes[i].length = codec_buffer->planes.plane[i].size;
+ }
+
+ if (codec_memory->num_fd == 1 &&
+ codec_buffer->planes.num_planes != codec_memory->num_fd) {
+ LOGD(" update planes[0].bytesused,length [%u,%u] -> [%u,%u]",
+ v4l2_buf.m.planes[0].bytesused, v4l2_buf.m.planes[0].length,
+ codec_buffer->size, codec_buffer->size);
+
+ v4l2_buf.m.planes[0].bytesused = codec_buffer->size;
+ v4l2_buf.m.planes[0].length = codec_buffer->size;
}
+
+ v4l2_buf.length = codec_memory->num_fd;
} else {
- if (codec_memory->num_fd != 1)
- LOGW("[%s] QBUF invalid num_fd[%u]",
+ if (codec_memory->num_fd != 1) {
+ LOGW("[%s] QBUF[DMABUF] invalid num_fd[%u]",
BUFFER_CONTROL_TYPE_STRING(buffer_control),
codec_memory->num_fd);
+ }
v4l2_buf.m.fd = codec_memory->fd[0];
+ v4l2_buf.bytesused = codec_buffer->size;
+ v4l2_buf.length = codec_buffer->size;
}
-
- v4l2_buf.length = codec_memory->num_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]",
+ LOGD("[%s] QBUF[MMAP] multiplanar: bytesused[%u]",
BUFFER_CONTROL_TYPE_STRING(buffer_control),
- v4l2_buf.m.planes[0].bytesused);
- } else {
- v4l2_buf.bytesused = codec_buffer->planes.plane[0].bytesused;
+ codec_buffer->planes.plane[0].bytesused);
- LOGD("[%s] QBUF singleplanar: bytesused[%u]",
+ v4l2_buf.m.planes[0].bytesused = codec_buffer->planes.plane[0].bytesused;
+ v4l2_buf.m.planes[0].length = codec_buffer->planes.plane[0].size;
+ v4l2_buf.length = 1;
+ } else {
+ LOGD("[%s] QBUF[MMAP] singleplanar: bytesused[%u]",
BUFFER_CONTROL_TYPE_STRING(buffer_control),
- v4l2_buf.bytesused);
+ codec_buffer->planes.plane[0].bytesused);
+
+ v4l2_buf.bytesused = codec_buffer->planes.plane[0].bytesused;
+ v4l2_buf.length = codec_buffer->planes.plane[0].size;
}
}
buffer_control->buffers.queued_count);
}
+ *out_buffer = &buffer_control->buffers.buffer[v4l2_buf.index];
+
+ (*out_buffer)->meta.flags = HAL_CODEC_BUFFER_FLAG_NONE;
+
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),
v4l2_buf.m.planes[0].bytesused,
v4l2_buf.m.planes[1].bytesused,
buffer_control->buffers.queued_count);
+
+ if (codec_config->format & HAL_CODEC_FORMAT_TYPE_ENCODED)
+ (*out_buffer)->planes.plane[0].bytesused = v4l2_buf.m.planes[0].bytesused;
} else {
LOGD("[%s] DQBUF done: index[%d], bytesused[%u], length[%u], queued_count[%d]",
BUFFER_CONTROL_TYPE_STRING(buffer_control),
v4l2_buf.index, v4l2_buf.bytesused, v4l2_buf.length,
buffer_control->buffers.queued_count);
- }
-
- *out_buffer = &buffer_control->buffers.buffer[v4l2_buf.index];
- (*out_buffer)->meta.flags = HAL_CODEC_BUFFER_FLAG_NONE;
+ if (codec_config->format & HAL_CODEC_FORMAT_TYPE_ENCODED)
+ (*out_buffer)->planes.plane[0].bytesused = v4l2_buf.bytesused;
+ }
if (!BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
TIMEVAL_TO_TIMESTAMP(v4l2_buf.timestamp, (*out_buffer)->meta.timestamp);
return HAL_CODEC_ERROR_INTERNAL;
}
- LOGI("fourcc ["FOURCC_FORMAT"] -> format [0x%x]",
- FOURCC_CONVERT(fourcc), *format);
+ LOGI("fourcc ["FOURCC_FORMAT"] -> format [%s][0x%x]",
+ FOURCC_CONVERT(fourcc), __codec_v4l2_get_format_string(*format), *format);
return HAL_CODEC_ERROR_NONE;
}
-static int __codec_get_fourcc_plane_num(hal_codec_format_e format, uint32_t *fourcc, uint32_t *plane_num)
+static const char *__codec_v4l2_get_format_string(hal_codec_format_e format)
+{
+ switch (format) {
+ case HAL_CODEC_FORMAT_NV12:
+ return "NV12";
+ case HAL_CODEC_FORMAT_NV12T:
+ return "NV12T";
+ case HAL_CODEC_FORMAT_NV21:
+ return "NV21";
+ case HAL_CODEC_FORMAT_I420:
+ return "I420";
+ case HAL_CODEC_FORMAT_YV12:
+ return "YV12";
+ case HAL_CODEC_FORMAT_YUYV:
+ return "YUYV";
+ case HAL_CODEC_FORMAT_UYVY:
+ return "UYVY";
+ case HAL_CODEC_FORMAT_H264:
+ return "H264";
+ case HAL_CODEC_FORMAT_H265:
+ return "H265";
+ case HAL_CODEC_FORMAT_H266:
+ return "H266";
+ case HAL_CODEC_FORMAT_VP8:
+ return "VP8";
+ case HAL_CODEC_FORMAT_VP9:
+ return "VP9";
+ case HAL_CODEC_FORMAT_AV1:
+ return "AV1";
+ case HAL_CODEC_FORMAT_BGRA8888:
+ return "BGRA8888";
+ case HAL_CODEC_FORMAT_ARGB8888:
+ return "ARGB8888";
+ default:
+ LOGE("unhandled format [%d]", format);
+ return "UNKONWN";
+ }
+}
+
+
+static int __codec_v4l2_get_fourcc_plane_num(hal_codec_format_e format, uint32_t *fourcc, uint32_t *plane_num)
{
if (!fourcc || !plane_num) {
LOGE("NULL parameter %p %p", fourcc, plane_num);
return HAL_CODEC_ERROR_INTERNAL;
}
- LOGD("format [0x%x] -> fourcc ["FOURCC_FORMAT"]",
- format, FOURCC_CONVERT(*fourcc));
+ LOGD("format [%s][0x%x] -> fourcc ["FOURCC_FORMAT"]",
+ __codec_v4l2_get_format_string(format), format, FOURCC_CONVERT(*fourcc));
return HAL_CODEC_ERROR_NONE;
}
return ret;
}
- if (config->memory == V4L2_MEMORY_DMABUF) {
+ if (!BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
+ /* DECODER+ENCODER: wait for output buffer */
g_mutex_lock(&buffer_control->lock);
while (buffer_control->buffers.queued_count < buffer_control->buffers.count) {
g_mutex_unlock(&buffer_control->lock);
- 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("[%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("[%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;
+ if (config->memory == V4L2_MEMORY_DMABUF) {
+ /* DECODER: release allocated bo and fd */
+ 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("[%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("[%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;
+ }
}
}
}
- } else {
+ }
+
+ if (config->memory == V4L2_MEMORY_MMAP) {
+ /* DECODER+ENCODER: release mapped memory */
for (i = 0 ; i < buffers->count ; i++) {
codec_buffer = &buffers->buffer[i];
codec_buffer->planes.plane[0].data = NULL;
codec_buffer->size = 0;
}
+ }
+ if (BUFFER_CONTROL_TYPE_IS_INPUT(buffer_control)) {
+ /* DECODER+ENCODER: clear queue for input buffers */
+ g_mutex_lock(&buffer_control->lock);
g_queue_clear(buffers->idle_buffers);
+ g_mutex_unlock(&buffer_control->lock);
}
ret = __codec_v4l2_reqbufs(handle->device_fd, config->buf_type, config->memory, 0, NULL);
}
} else {
/* V4L2_MEMORY_DMABUF */
- new_bo = tbm_bo_alloc(handle->bufmgr, (int)codec_buffer->size, TBM_BO_DEFAULT);
- if (!new_bo) {
- LOGE("type[%d] buffer[i:%d] bo alloc failed, size[%u]", type, i, codec_buffer->size);
- goto _START_STREAM_FAILED;
- }
+ if (CODEC_IS_DECODER(handle)) {
+ new_bo = tbm_bo_alloc(handle->bufmgr, (int)codec_buffer->size, TBM_BO_DEFAULT);
+ if (!new_bo) {
+ LOGE("type[%d] buffer[i:%d] bo alloc failed, size[%u]", type, i, codec_buffer->size);
+ goto _START_STREAM_FAILED;
+ }
- bo_handle = tbm_bo_get_handle(new_bo, TBM_DEVICE_CPU);
- if (!bo_handle.ptr) {
- LOGE("type[%d] buffer[i:%d] bo get handle failed for bo[%p]", type, i, new_bo);
- tbm_bo_unref(new_bo);
- goto _START_STREAM_FAILED;
- }
+ bo_handle = tbm_bo_get_handle(new_bo, TBM_DEVICE_CPU);
+ if (!bo_handle.ptr) {
+ LOGE("type[%d] buffer[i:%d] bo get handle failed for bo[%p]", type, i, new_bo);
+ tbm_bo_unref(new_bo);
+ goto _START_STREAM_FAILED;
+ }
- codec_memory->fd[0] = tbm_bo_export_fd(new_bo);
- if (codec_memory->fd[0] < 0) {
- LOGE("type[%d] buffer[i:%d] get fd handle failed for bo[%p]", type, i, new_bo);
- tbm_bo_unref(new_bo);
- goto _START_STREAM_FAILED;
+ codec_memory->fd[0] = tbm_bo_export_fd(new_bo);
+ if (codec_memory->fd[0] < 0) {
+ LOGE("type[%d] buffer[i:%d] get fd handle failed for bo[%p]", type, i, new_bo);
+ tbm_bo_unref(new_bo);
+ goto _START_STREAM_FAILED;
+ }
+
+ buffers->bo[i][0] = new_bo;
+ codec_memory->num_fd = 1;
}
- buffers->bo[i][0] = new_bo;
- codec_memory->num_fd = 1;
+ if (bo_handle.ptr) {
+ codec_buffer->planes.plane[0].data = bo_handle.ptr;
+ codec_buffer->planes.plane[1].data = bo_handle.ptr + handle->ts_info.planes[0].size;
+ }
- codec_buffer->planes.plane[0].data = bo_handle.ptr;
codec_buffer->planes.plane[0].stride = handle->ts_info.planes[0].stride;
codec_buffer->planes.plane[0].size = handle->ts_info.planes[0].size;
codec_buffer->planes.plane[0].bytesused = handle->ts_info.planes[0].stride * codec_config->resolution.height;
-
- codec_buffer->planes.plane[1].data = bo_handle.ptr + handle->ts_info.planes[0].size;
codec_buffer->planes.plane[1].stride = handle->ts_info.planes[1].stride;
codec_buffer->planes.plane[1].size = handle->ts_info.planes[1].size;
codec_buffer->planes.plane[1].bytesused = handle->ts_info.planes[1].stride * (codec_config->resolution.height >> 1);
- LOGI("type[%d] buffer[i:%d] new bo[%p], vaddr[%p]", type, i, new_bo, bo_handle.ptr);
+ LOGI("type[%d] buffer[%d], size[%u], new bo[%p], vaddr[%p]",
+ type, i, codec_buffer->size, new_bo, bo_handle.ptr);
LOGI(" plane[0] data[%p], stride[%u], size[%u], bytesused[%u]",
codec_buffer->planes.plane[0].data,
codec_buffer->planes.plane[0].stride,
}
+static int __codec_v4l2_get_type(hal_codec_format_e format, hal_codec_format_type_e *type)
+{
+ if (!type) {
+ LOGE("NULL type");
+ return HAL_CODEC_ERROR_INVALID_PARAMETER;
+ }
+
+ if (format & HAL_CODEC_FORMAT_TYPE_ENCODED) {
+ *type = HAL_CODEC_FORMAT_TYPE_ENCODED;
+ LOGI("format[%s] - ENCODED", __codec_v4l2_get_format_string(format));
+ return HAL_CODEC_ERROR_NONE;
+ }
+
+ if (format & HAL_CODEC_FORMAT_TYPE_RAW) {
+ *type = HAL_CODEC_FORMAT_TYPE_RAW;
+ LOGI("format[%s] - RAW", __codec_v4l2_get_format_string(format));
+ return HAL_CODEC_ERROR_NONE;
+ }
+
+ LOGE("invalid format[%s]", __codec_v4l2_get_format_string(format));
+
+ return HAL_CODEC_ERROR_INVALID_PARAMETER;
+}
+
+
int codec_v4l2_configure(void *codec_handle, int width, int height,
hal_codec_format_e in_format, hal_codec_format_e out_format, bool is_secure)
{
int ret = 0;
int device_fd = CODEC_HAL_INITIAL_FD;
uint32_t input_id = 0;
+ hal_codec_format_e hal_format = HAL_CODEC_FORMAT_NV12;
+ hal_codec_format_type_e in_format_type = HAL_CODEC_FORMAT_TYPE_ENCODED;
+ hal_codec_format_type_e out_format_type = HAL_CODEC_FORMAT_TYPE_ENCODED;
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;
+ codec_hal_buffer_control_s *buffer_control = NULL;
enum v4l2_buf_type in_buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
enum v4l2_buf_type out_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ enum v4l2_memory in_memory = V4L2_MEMORY_MMAP;
+ enum v4l2_memory out_memory = V4L2_MEMORY_MMAP;
tbm_surface_h surface = NULL;
return HAL_CODEC_ERROR_INVALID_STATE;
}
- if (((in_format & HAL_CODEC_FORMAT_TYPE_ENCODED) && (out_format & HAL_CODEC_FORMAT_TYPE_ENCODED)) ||
- ((in_format & HAL_CODEC_FORMAT_TYPE_RAW) && (out_format & HAL_CODEC_FORMAT_TYPE_RAW))) {
- LOGE("invalid format : in[%d], out[%d]", in_format, out_format);
+ ret = __codec_v4l2_get_type(in_format, &in_format_type);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ LOGE("invalid in_format[0x%x]", in_format);
+ return ret;
+ }
+
+ ret = __codec_v4l2_get_type(out_format, &out_format_type);
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ LOGE("invalid out_format[0x%x]", out_format);
+ return ret;
+ }
+
+ if (in_format_type == out_format_type) {
+ LOGE("invalid format : in[0x%x], out[0x%x], type[%d]", in_format, out_format, in_format_type);
return HAL_CODEC_ERROR_INVALID_PARAMETER;
}
if (ret != HAL_CODEC_ERROR_NONE)
return ret;
- surface = tbm_surface_create(width, height, __codec_v4l2_get_tbm_format(out_format));
+ hal_format = CODEC_IS_DECODER(handle) ? out_format : in_format;
+
+ surface = tbm_surface_create(width, height, __codec_v4l2_get_tbm_format(hal_format));
if (!surface) {
- LOGE("create surface failed [%dx%d][format:%d]", width, height, out_format);
+ LOGE("create surface failed [%dx%d][format:%d]", width, height, hal_format);
return HAL_CODEC_ERROR_INTERNAL;
}
}
/* subscribe SOURCE_CHANGE event */
- if (ioctl(device_fd, VIDIOC_G_INPUT, &input_id) < 0)
- LOGW("G_INPUT failed, use default input id[%d]", input_id);
+ if (CODEC_IS_DECODER(handle)) {
+ if (ioctl(device_fd, VIDIOC_G_INPUT, &input_id) < 0)
+ LOGW("G_INPUT failed, use default input id[%d]", input_id);
- if (__codec_v4l2_subscribe_event(device_fd, V4L2_EVENT_SOURCE_CHANGE, input_id) != HAL_CODEC_ERROR_NONE) {
- LOGW("subscribe event[SOURCE_CHANGE] failed");
- return HAL_CODEC_ERROR_DEVICE_READ;
+ if (__codec_v4l2_subscribe_event(device_fd, V4L2_EVENT_SOURCE_CHANGE, input_id) != HAL_CODEC_ERROR_NONE) {
+ LOGW("subscribe event[SOURCE_CHANGE] failed");
+ return HAL_CODEC_ERROR_DEVICE_READ;
+ }
+
+ in_memory = V4L2_MEMORY_MMAP;
+ out_memory = V4L2_MEMORY_DMABUF;
+ } else {
+ in_memory = V4L2_MEMORY_DMABUF;
+ out_memory = V4L2_MEMORY_MMAP;
}
/* 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_max_resolution.width, in_max_resolution.height);
+ buffer_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT];
+
+ ret = __codec_v4l2_set_config(buffer_control,
+ in_buf_type, in_memory, in_format, width, height,
+ in_max_resolution.width, in_max_resolution.height);
if (ret != HAL_CODEC_ERROR_NONE)
return ret;
- ret = __codec_v4l2_s_fmt(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT], device_fd);
+ ret = __codec_v4l2_s_fmt(buffer_control, device_fd);
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("set format[%d] for input failed - [0x%x]", in_format, ret);
close(device_fd);
}
/* 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, 0, 0);
+ buffer_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT];
+
+ ret = __codec_v4l2_set_config(buffer_control,
+ out_buf_type, out_memory, out_format, width, height,
+ out_max_resolution.width, out_max_resolution.height);
if (ret != HAL_CODEC_ERROR_NONE)
return ret;
- ret = __codec_v4l2_s_fmt(&handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT], device_fd);
+ ret = __codec_v4l2_s_fmt(buffer_control, device_fd);
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("set format[%d] for output failed - [0x%x]", out_format, ret);
close(device_fd);
config->resolution.width = new_width;
config->resolution.height = new_height;
- ret = __codec_v4l2_start_stream(handle, buffer_control, BUFFER_NUM_OUTPUT);
+ ret = __codec_v4l2_start_stream(handle, buffer_control, BUFFER_NUM_DECODER_OUTPUT);
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("[output] __codec_start_stream failed[0x%x]", ret);
return;
output_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT];
while (run_loop) {
- /* exit thread with some conditions */
- //////////////////////////////////////
-
poll_errno = 0;
ret = __codec_v4l2_poll(handle, (POLLIN | POLLOUT | POLLPRI), OUTPUT_POLL_TIMEOUT_MS, &revents, &poll_errno);
return HAL_CODEC_ERROR_INVALID_STATE;
}
- ret = __codec_v4l2_start_stream(handle, &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT], BUFFER_NUM_INPUT);
+ ret = __codec_v4l2_start_stream(handle, &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT],
+ CODEC_IS_DECODER(handle) ? BUFFER_NUM_DECODER_INPUT : BUFFER_NUM_ENCODER_INPUT);
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("[input] __codec_start_stream failed[0x%x]", ret);
return ret;
}
- ret = __codec_v4l2_start_stream(handle, &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT], BUFFER_NUM_OUTPUT);
+ ret = __codec_v4l2_start_stream(handle, &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_OUTPUT],
+ CODEC_IS_DECODER(handle) ? BUFFER_NUM_DECODER_OUTPUT : BUFFER_NUM_ENCODER_OUTPUT);
if (ret != HAL_CODEC_ERROR_NONE) {
LOGE("[output] __codec_start_stream failed[0x%x]", ret);
return ret;
if (buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_EOS) {
struct v4l2_decoder_cmd dcmd = { 0, };
- LOGW("EOS - VIDIOC_DECODER_CMD: V4L2_DEC_CMD_STOP");
+ LOGW("EOS: V4L2_DEC_CMD_STOP");
dcmd.cmd = V4L2_DEC_CMD_STOP;
}
+int codec_v4l2_encode(void *codec_handle, hal_codec_buffer_s *buffer)
+{
+ uint32_t i = 0;
+ int ret = HAL_CODEC_ERROR_NONE;
+ hal_codec_buffer_s *idle_buffer = NULL;
+ codec_hal_buffer_control_s *buffer_control;
+ codec_hal_handle_s *handle = (codec_hal_handle_s *)codec_handle;
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ if (!handle) {
+ LOGE("NULL handle");
+ return HAL_CODEC_ERROR_INVALID_PARAMETER;
+ }
+
+ locker = g_mutex_locker_new(&handle->lock);
+
+ if (handle->state < HAL_CODEC_STATE_STARTED) {
+ LOGE("invalid state[%d]", handle->state);
+ return HAL_CODEC_ERROR_INVALID_STATE;
+ }
+
+ buffer_control = &handle->buffer_control[CODEC_HAL_BUFFER_CONTROL_TYPE_INPUT];
+
+ if (buffer->meta.flags & HAL_CODEC_BUFFER_FLAG_EOS) {
+ struct v4l2_encoder_cmd ecmd = { 0, };
+
+ LOGW("EOS: V4L2_ENC_CMD_STOP");
+
+ ecmd.cmd = V4L2_ENC_CMD_STOP;
+
+ if (ioctl(handle->device_fd, VIDIOC_ENCODER_CMD, &ecmd) < 0)
+ LOGE("V4L2_ENC_CMD_STOP failed %d", errno);
+
+ __codec_v4l2_message_send(handle, HAL_CODEC_MESSAGE_TYPE_INPUT_BUFFER_USED, buffer);
+
+ LOGW("done");
+
+ return HAL_CODEC_ERROR_NONE;
+ }
+
+ idle_buffer = __codec_v4l2_get_idle_buffer(buffer_control, 0);
+ 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]);
+ idle_buffer->memory.fd[i] = buffer->memory.fd[i];
+ }
+
+ memcpy(&idle_buffer->meta, &buffer->meta, sizeof(hal_codec_meta_s));
+
+ ret = __codec_v4l2_qbuf(handle->device_fd,
+ buffer_control, idle_buffer);
+
+ if (ret != HAL_CODEC_ERROR_NONE) {
+ LOGE("QBUF[%p] failed[i:%d], 0x%x",
+ buffer, idle_buffer->index, ret);
+ return ret;
+ }
+
+ LOGD("QBUF[%p] done", buffer);
+
+ return HAL_CODEC_ERROR_NONE;
+}
+
+
int codec_v4l2_release_output_buffer(void *codec_handle, int buffer_index)
{
int ret = HAL_CODEC_ERROR_NONE;
funcs->stop = codec_v4l2_stop;
funcs->flush = codec_v4l2_flush;
funcs->decode = codec_v4l2_decode;
+ funcs->encode = codec_v4l2_encode;
funcs->release_output_buffer = codec_v4l2_release_output_buffer;
funcs->get_state = codec_v4l2_get_state;
funcs->set_command = codec_v4l2_set_command;