diff options
author | Jeongmo Yang <jm80.yang@samsung.com> | 2022-06-29 20:03:18 +0900 |
---|---|---|
committer | Jeongmo Yang <jm80.yang@samsung.com> | 2022-06-29 20:03:18 +0900 |
commit | b2bdcfeb070f20731d86f905e141865baf75c31f (patch) | |
tree | eaa333ca0024d1e7ae5a6ffbffcf797065506726 | |
parent | 46bca20ea107e83f9c896bb0f21649c34987facd (diff) | |
download | camera-v4l2-b2bdcfeb070f20731d86f905e141865baf75c31f.tar.gz camera-v4l2-b2bdcfeb070f20731d86f905e141865baf75c31f.tar.bz2 camera-v4l2-b2bdcfeb070f20731d86f905e141865baf75c31f.zip |
Support zero-copy for preview buffersubmit/tizen/20220701.103121accepted/tizen/unified/20220704.213045
- Replace V4L2_MEMORY_MMAP by V4L2_MEMORY_DMABUF for memory type.
- The zero-copy is disabled now.
- If zero-copy is enabled, libv4l2 will be disabled,
then emulated format is also disabled.
[Version] 0.0.2
[Issue Type] New feature
Change-Id: I7f240e6775aa43ca5dc767d61daf23a863ab82c7
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r-- | packaging/hal-backend-camera-v4l2.spec | 11 | ||||
-rw-r--r-- | src/hal_backend_camera_v4l2.c | 243 | ||||
-rw-r--r-- | src/hal_backend_camera_v4l2_private.h | 8 |
3 files changed, 207 insertions, 55 deletions
diff --git a/packaging/hal-backend-camera-v4l2.spec b/packaging/hal-backend-camera-v4l2.spec index 59f2bba..eb038a9 100644 --- a/packaging/hal-backend-camera-v4l2.spec +++ b/packaging/hal-backend-camera-v4l2.spec @@ -1,8 +1,14 @@ +%define enable_zero_copy 0 + +%if 0%{?enable_zero_copy} +%define enable_libv4l2 0 +%else %define enable_libv4l2 1 +%endif Name: hal-backend-camera-v4l2 Summary: Tizen Camera Hal using generic V4L2 interface -Version: 0.0.1 +Version: 0.0.2 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 @@ -27,6 +33,9 @@ Tizen Camera Hal using generic V4L2 interface. %build +%if 0%{?enable_zero_copy} +export CFLAGS+=" -DTIZEN_FEATURE_ZERO_COPY_SUPPORT" +%endif ./autogen.sh %configure \ %if 0%{?enable_libv4l2} diff --git a/src/hal_backend_camera_v4l2.c b/src/hal_backend_camera_v4l2.c index 2d830ec..660b753 100644 --- a/src/hal_backend_camera_v4l2.c +++ b/src/hal_backend_camera_v4l2.c @@ -229,6 +229,8 @@ static int __camera_v4l2_reqbufs(int device_fd, int type, int memory, uint32_t c return CAMERA_ERROR_INVALID_PARAMETER; } + LOGI("type[%d], memory[%d], count[%u]", type, memory, count); + memset(&v4l2_reqbuf, 0x0, sizeof(struct v4l2_requestbuffers)); v4l2_reqbuf.type = type; @@ -249,7 +251,7 @@ static int __camera_v4l2_reqbufs(int device_fd, int type, int memory, uint32_t c } -static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index) +static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index, int dmabuf_fd) { struct v4l2_buffer v4l2_buf; struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX]; @@ -266,8 +268,13 @@ static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index) v4l2_buf.type = type; v4l2_buf.memory = memory; v4l2_buf.m.planes = v4l2_planes; - v4l2_buf.length = 460800; - v4l2_buf.bytesused = 460800; + + if (dmabuf_fd > CAMERA_HAL_INITIAL_FD) { + if (V4L2_TYPE_IS_MULTIPLANAR(type)) + v4l2_buf.m.planes[0].m.fd = dmabuf_fd; + else + v4l2_buf.m.fd = dmabuf_fd; + } if (v4l2_ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) { LOGE("qbuf failed. [i: %d, t: %d, m: %d] errno %d", @@ -275,13 +282,14 @@ static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index) return CAMERA_ERROR_INTERNAL; } - /*LOGD("QBUF done [i: %d, t: %d, m: %d]", index, type, memory);*/ + LOGD("QBUF done [i:%d, t:%d, m:%d, fd:%d]", + index, type, memory, dmabuf_fd); return CAMERA_ERROR_NONE; } -static int __camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index) +static int __camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index, uint32_t *bytesused) { int ret = CAMERA_ERROR_NONE; struct v4l2_buffer v4l2_buf; @@ -311,7 +319,12 @@ static int __camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index) return CAMERA_ERROR_DEVICE_READ; } + LOGD("DQBUF[i:%d], bytesused[%u], length[%u]", + v4l2_buf.index, v4l2_buf.bytesused, v4l2_buf.length); + *index = v4l2_buf.index; + if (bytesused) + *bytesused = v4l2_buf.bytesused; /*LOGD("dqbuf index %d", *index);*/ @@ -595,6 +608,7 @@ static int __camera_get_device_info_list(void) #endif /* HAVE_LIBV4L2 */ glob_t glob_buf; struct v4l2_capability v4l2_cap; + guint32 device_caps; camera_device_info_list_s *device_info_list = NULL; g_mutex_lock(&g_device_info_lock); @@ -665,13 +679,13 @@ static int __camera_get_device_info_list(void) } if (v4l2_cap.capabilities & V4L2_CAP_DEVICE_CAPS) - g_device_caps = v4l2_cap.device_caps; + device_caps = v4l2_cap.device_caps; else - g_device_caps = v4l2_cap.capabilities; + device_caps = v4l2_cap.capabilities; - if (!(g_device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) || - (g_device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) { - LOGW("[%s] is not a capture device 0x%x", glob_buf.gl_pathv[i], g_device_caps); + if (!(device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) || + (device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) { + LOGW("[%s] is not a capture device 0x%x", glob_buf.gl_pathv[i], device_caps); v4l2_close(device_fd); continue; } @@ -681,8 +695,11 @@ static int __camera_get_device_info_list(void) v4l2_close(device_fd); - if (ret == CAMERA_ERROR_NONE) + if (ret == CAMERA_ERROR_NONE) { device_count++; + g_device_caps = device_caps; + LOGI("device caps [0x%08x]", g_device_caps); + } } device_info_list->count = device_count; @@ -706,38 +723,63 @@ static int __camera_stop_stream(hal_camera_handle *handle, uint32_t buffer_count { int i = 0; int ret = CAMERA_ERROR_NONE; + camera_buffer_s *buffer = NULL; +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + camera_tbm_buffer_s *tbm_buffer = NULL; +#endif if (!handle) { LOGE("NULL handle"); return CAMERA_ERROR_INVALID_PARAMETER; } - LOGD("buffer count[%d]", buffer_count); + LOGI("buffer count[%d]", buffer_count); /* stream off */ ret = __camera_v4l2_stream(handle->device_fd, handle->buffer_type, FALSE); - LOGD("stream off : 0x%x", ret); + LOGI("stream off[0x%x]", ret); - /* munmap */ + /* release buffer */ for (i = 0 ; i < buffer_count ; i++) { - if (handle->camera_buffers[i].planes[0].data != NULL) { - LOGW("munmap %p", handle->camera_buffers[i].planes[0].data); + buffer = &handle->camera_buffers[i]; + + LOGI("release buffer[%d]", i); - v4l2_munmap(handle->camera_buffers[i].planes[0].data, handle->camera_buffers[i].planes[0].size); +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + tbm_buffer = &handle->tbm_buffers[i]; - handle->camera_buffers[i].planes[0].data = 0; - handle->camera_buffers[i].planes[0].size = 0; + if (tbm_buffer->dmabuf_fd > CAMERA_HAL_INITIAL_FD) { + LOGI(" close dmabuf fd[%d]", tbm_buffer->dmabuf_fd); + close(tbm_buffer->dmabuf_fd); + tbm_buffer->dmabuf_fd = CAMERA_HAL_INITIAL_FD; + } + + if (tbm_buffer->bo) { + LOGI(" unref tbm bo[%p]", tbm_buffer->bo); + tbm_bo_unref(tbm_buffer->bo); + tbm_buffer->bo = NULL; + } + + tbm_buffer->bo_handle.ptr = NULL; +#endif + + if (buffer->planes[0].data) { +#ifndef TIZEN_FEATURE_ZERO_COPY_SUPPORT + LOGI(" munmap %p", buffer->planes[0].data); + v4l2_munmap(buffer->planes[0].data, buffer->planes[0].size); +#endif + buffer->planes[0].data = NULL; + buffer->planes[0].size = 0; } else { - LOGW("NULL data [index %d]", i); + LOGI(" NULL data [i:%d]", i); } } - /* reqbufs 0 */ ret = __camera_v4l2_reqbufs(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, 0, &buffer_count); + handle->buffer_type, handle->memory_type, 0, &buffer_count); - LOGD("reqbufs 0 : 0x%x", ret); + LOGI("reqbufs 0 [0x%x]", ret); return ret; } @@ -751,8 +793,13 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_ camera_buffer_s *buffer = NULL; struct v4l2_format v4l2_fmt; struct v4l2_streamparm v4l2_parm; +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + uint32_t buffer_size = 0; + camera_tbm_buffer_s *tbm_buffer = NULL; +#else struct v4l2_buffer v4l2_buf; struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];; +#endif guint32 fourcc = 0; guint32 plane_num = 0; @@ -761,6 +808,9 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_ return CAMERA_ERROR_INTERNAL; } + LOGI("[%dx%d], format[%d], fps[%u]", + resolution->width, resolution->height, pixel_format, fps); + /* S_FMT */ ret = __camera_get_fourcc_plane_num(pixel_format, &fourcc, &plane_num); if (ret != CAMERA_ERROR_NONE) { @@ -790,11 +840,18 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_ if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) { for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) { +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + /* TODO: Is it needed to make array for each planes? */ + buffer_size += v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage; +#endif LOGD("plane[%d] stride %u, sizeimage %u", i, v4l2_fmt.fmt.pix_mp.plane_fmt[i].bytesperline, v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage); } } else { +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + buffer_size = v4l2_fmt.fmt.pix.sizeimage; +#endif LOGD("stride %d, sizeimage %d", v4l2_fmt.fmt.pix.bytesperline, v4l2_fmt.fmt.pix.sizeimage); @@ -821,32 +878,78 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_ /* request buffer */ ret = __camera_v4l2_reqbufs(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, request_buffer_count, &handle->buffer_count); + handle->buffer_type, handle->memory_type, + request_buffer_count, &handle->buffer_count); if (ret != CAMERA_ERROR_NONE) { return ret; } - LOGD("buffer count : request %d -> result %d", + LOGI("buffer count : request %d -> result %d", request_buffer_count, handle->buffer_count); - /* query buffer, mmap and qbuf */ + /* alloc and queue buffer */ for (i = 0 ; i < handle->buffer_count ; i++) { + buffer = &handle->camera_buffers[i]; + + buffer->index = i; + buffer->format = pixel_format; + buffer->resolution.width = resolution->width; + buffer->resolution.height = resolution->height; + buffer->num_planes = plane_num; + +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + tbm_buffer = &handle->tbm_buffers[i]; + + tbm_buffer->bo = tbm_bo_alloc(handle->bufmgr, (int)buffer_size, TBM_BO_DEFAULT); + if (!tbm_buffer->bo) { + LOGE("bo alloc failed[size:%u]", buffer_size); + ret = CAMERA_ERROR_OUT_OF_MEMORY; + goto _START_STREAM_FAILED; + } + + tbm_buffer->bo_handle = tbm_bo_get_handle(tbm_buffer->bo, TBM_DEVICE_CPU); + if (!tbm_buffer->bo_handle.ptr) { + LOGE("bo[%p] get handle failed", tbm_buffer->bo); + ret = CAMERA_ERROR_INTERNAL; + goto _START_STREAM_FAILED; + } + + tbm_buffer->dmabuf_fd = tbm_bo_export_fd(tbm_buffer->bo); + if (tbm_buffer->dmabuf_fd < 0) { + LOGE("export fd failed from bo[%p]", tbm_buffer->bo); + ret = CAMERA_ERROR_INTERNAL; + goto _START_STREAM_FAILED; + } + + buffer->total_size = buffer_size; + buffer->planes[0].size = buffer_size; + buffer->planes[0].data = tbm_buffer->bo_handle.ptr; + buffer->num_bos = 1; + buffer->bos[0] = tbm_buffer->bo; + + LOGD("buffer[%d], size[%d], data[%p], bo[%p], fd[%d]", + i, buffer->planes[0].size, buffer->planes[0].data, + tbm_buffer->bo, tbm_buffer->dmabuf_fd); + + ret = __camera_v4l2_qbuf(handle->device_fd, + handle->buffer_type, handle->memory_type, + i, tbm_buffer->dmabuf_fd); +#else /* TIZEN_FEATURE_ZERO_COPY_SUPPORT */ memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer)); memset(v4l2_planes, 0x0, sizeof(v4l2_planes)); v4l2_buf.type = handle->buffer_type; - v4l2_buf.memory = V4L2_MEMORY_MMAP; + v4l2_buf.memory = handle->memory_type; v4l2_buf.index = i; v4l2_buf.m.planes = v4l2_planes; v4l2_buf.length = plane_num; if (v4l2_ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) { LOGE("[%d] query buf failed. errno %d", i, errno); + ret = CAMERA_ERROR_INTERNAL; goto _START_STREAM_FAILED; } - buffer = &handle->camera_buffers[i]; - buffer->index = i; buffer->format = pixel_format; buffer->resolution.width = resolution->width; @@ -866,7 +969,15 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_ goto _START_STREAM_FAILED; } - if (__camera_v4l2_qbuf(handle->device_fd, handle->buffer_type, V4L2_MEMORY_MMAP, i) != CAMERA_ERROR_NONE) { + LOGI("buffer[%d], size[%d], data[%p]", + i, buffer->planes[0].size, buffer->planes[0].data); + + ret = __camera_v4l2_qbuf(handle->device_fd, + handle->buffer_type, handle->memory_type, + i, CAMERA_HAL_INITIAL_FD); +#endif /* TIZEN_FEATURE_ZERO_COPY_SUPPORT */ + + if (ret != CAMERA_ERROR_NONE) { LOGE("[%d] qbuf failed (errno %d)", i, errno); goto _START_STREAM_FAILED; } @@ -879,6 +990,8 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_ goto _START_STREAM_FAILED; } + LOGI("done"); + return CAMERA_ERROR_NONE; _START_STREAM_FAILED: @@ -890,10 +1003,11 @@ _START_STREAM_FAILED: static void __camera_do_capture(hal_camera_handle *handle) { int ret = CAMERA_ERROR_NONE; - int buffer_index = 0; + int index = 0; gint64 current_time = 0; gint64 previous_time = 0; gint64 interval_us = 0; + uint32_t bytesused = 0; if (!handle) { LOGE("NULL handle"); @@ -933,12 +1047,15 @@ static void __camera_do_capture(hal_camera_handle *handle) } ret = __camera_v4l2_dqbuf(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, &buffer_index); + handle->buffer_type, handle->memory_type, + &index, &bytesused); if (ret != CAMERA_ERROR_NONE) { LOGE("dqbuf failed for capture[0x%x]", ret); goto _CAPTURE_DONE; } + handle->camera_buffers[index].planes[0].bytesused = bytesused; + if (handle->captured_count > 0) { g_mutex_lock(&handle->buffer_lock); if (handle->state != CAMERA_STATE_CAPTURING) { @@ -965,10 +1082,10 @@ static void __camera_do_capture(hal_camera_handle *handle) g_mutex_unlock(&handle->buffer_lock); LOGD("capture cb[%p], buffer index[%d],count[%d]", - handle->capture_cb, buffer_index, handle->captured_count); + handle->capture_cb, index, handle->captured_count); if (handle->capture_cb) { - handle->capture_cb(&handle->camera_buffers[buffer_index], + handle->capture_cb(&handle->camera_buffers[index], NULL, NULL, handle->capture_cb_data); } else { LOGW("capture callback is NULL"); @@ -979,7 +1096,8 @@ static void __camera_do_capture(hal_camera_handle *handle) _TRY_NEXT: ret = __camera_v4l2_qbuf(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index); + handle->buffer_type, handle->memory_type, + index, handle->tbm_buffers[index].dmabuf_fd); if (ret != CAMERA_ERROR_NONE) LOGE("qbuf failed for capture[0x%x]", ret); } while (handle->captured_count < handle->capture_count); @@ -1021,6 +1139,7 @@ static void *__camera_buffer_handler_func(gpointer data) int error = CAMERA_ERROR_NONE; int index = 0; hal_camera_handle *handle = (hal_camera_handle *)data; + uint32_t bytesused = 0; if (!handle) { LOGE("NULL handle for buffer handler"); @@ -1048,13 +1167,16 @@ static void *__camera_buffer_handler_func(gpointer data) break; } - error = __camera_v4l2_dqbuf(handle->device_fd, handle->buffer_type, V4L2_MEMORY_MMAP, &index); + error = __camera_v4l2_dqbuf(handle->device_fd, + handle->buffer_type, handle->memory_type, + &index, &bytesused); if (error != CAMERA_ERROR_NONE) { LOGE("dqbuf failed[0x%x]", error); break; } handle->buffer_dequeued_count++; + handle->camera_buffers[index].planes[0].bytesused = bytesused; /*LOGD("dequeued buffer count %d", handle->buffer_dequeued_count);*/ @@ -1212,6 +1334,7 @@ static void __camera_release_handle(hal_camera_handle *handle) int camera_v4l2_init(void **camera_handle) { + int i = 0; int ret = CAMERA_ERROR_NONE; hal_camera_handle *new_handle = NULL; tbm_bufmgr bufmgr = NULL; @@ -1223,6 +1346,12 @@ int camera_v4l2_init(void **camera_handle) return CAMERA_ERROR_INVALID_PARAMETER; } + ret = __camera_get_device_info_list(); + if (ret != CAMERA_ERROR_NONE) { + LOGE("get device info failed[0x%x]", ret); + return ret; + } + bufmgr = tbm_bufmgr_init(-1); if (bufmgr == NULL) { LOGE("get tbm bufmgr failed"); @@ -1260,11 +1389,8 @@ int camera_v4l2_init(void **camera_handle) new_handle->device_fd = CAMERA_HAL_INITIAL_FD; new_handle->state = CAMERA_STATE_INITIALIZED; - ret = __camera_get_device_info_list(); - if (ret != CAMERA_ERROR_NONE) { - LOGE("get device info failed"); - goto _INIT_ERROR; - } + for (i = 0 ; i < BUFFER_MAX ; i++) + new_handle->tbm_buffers[i].dmabuf_fd = CAMERA_HAL_INITIAL_FD; #ifdef HAVE_LIBV4L2 LOGI("libv4l2 ENABLED"); @@ -1393,9 +1519,15 @@ int camera_v4l2_open_device(void *camera_handle, int device_index) } if (g_device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) - handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE_MPLANE; + handle->buffer_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; else - handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE; + handle->buffer_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + +#ifdef TIZEN_FEATURE_ZERO_COPY_SUPPORT + handle->memory_type = V4L2_MEMORY_DMABUF; +#else + handle->memory_type = V4L2_MEMORY_MMAP; +#endif #ifdef HAVE_LIBV4L2 libv4l2_fd = v4l2_fd_open(device_fd, V4L2_ENABLE_ENUM_FMT_EMULATION); @@ -1745,7 +1877,7 @@ int camera_v4l2_start_preview(void *camera_handle, hal_camera_preview_frame_cb c } -int camera_v4l2_release_preview_buffer(void *camera_handle, int buffer_index) +int camera_v4l2_release_preview_buffer(void *camera_handle, int index) { int ret = CAMERA_ERROR_NONE; hal_camera_handle *handle = (hal_camera_handle *)camera_handle; @@ -1755,13 +1887,14 @@ int camera_v4l2_release_preview_buffer(void *camera_handle, int buffer_index) return CAMERA_ERROR_INVALID_PARAMETER; } - if (buffer_index >= handle->buffer_count) { - LOGE("invalid buffer index %d", buffer_index); + if (index >= handle->buffer_count) { + LOGE("invalid buffer index %d", index); return CAMERA_ERROR_INVALID_PARAMETER; } ret = __camera_v4l2_qbuf(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index); + handle->buffer_type, handle->memory_type, + index, handle->tbm_buffers[index].dmabuf_fd); g_mutex_lock(&handle->buffer_lock); @@ -1772,9 +1905,9 @@ int camera_v4l2_release_preview_buffer(void *camera_handle, int buffer_index) LOGW("invalid dequeued buffer count[%u]", handle->buffer_dequeued_count); /*LOGD("qbud done : index %d, dequeued buffer count %d", - buffer_index, handle->buffer_dequeued_count);*/ + index, handle->buffer_dequeued_count);*/ } else { - LOGE("qbuf failed [index %d]", buffer_index); + LOGE("qbuf failed [index %d]", index); } g_cond_signal(&handle->buffer_cond); @@ -1823,12 +1956,14 @@ int camera_v4l2_stop_preview(void *camera_handle) g_mutex_unlock(&handle->buffer_lock); - ret = __camera_stop_stream(handle, handle->buffer_count); - /* wait for preview thread exit */ + LOGD("wait for buffer thread"); + g_thread_join(handle->buffer_thread); handle->buffer_thread = NULL; + ret = __camera_stop_stream(handle, handle->buffer_count); + handle->state = CAMERA_STATE_OPENED; LOGD("stop preview done [0x%x]", ret); @@ -1985,7 +2120,7 @@ int camera_v4l2_start_record(void *camera_handle, hal_camera_video_frame_cb call } -int camera_v4l2_release_video_buffer(void *camera_handle, int buffer_index) +int camera_v4l2_release_video_buffer(void *camera_handle, int index) { if (!camera_handle) { LOGE("NULL handle"); @@ -2057,7 +2192,7 @@ int camera_v4l2_unset_extra_preview_frame_cb(void *camera_handle) } -int camera_v4l2_release_extra_preview_buffer(void *camera_handle, int stream_id, int buffer_index) +int camera_v4l2_release_extra_preview_buffer(void *camera_handle, int stream_id, int index) { hal_camera_handle *handle = (hal_camera_handle *)camera_handle; @@ -2066,7 +2201,7 @@ int camera_v4l2_release_extra_preview_buffer(void *camera_handle, int stream_id, return CAMERA_ERROR_INVALID_PARAMETER; } - LOGI("done - stream_id[%d], index[%d]", stream_id, buffer_index); + LOGI("done - stream_id[%d], index[%d]", stream_id, index); return CAMERA_ERROR_NONE; } diff --git a/src/hal_backend_camera_v4l2_private.h b/src/hal_backend_camera_v4l2_private.h index f5e6e1a..c6f4840 100644 --- a/src/hal_backend_camera_v4l2_private.h +++ b/src/hal_backend_camera_v4l2_private.h @@ -50,6 +50,12 @@ typedef struct _set_batch_table_s { void *value; } set_batch_table_s; +typedef struct _camera_tbm_buffer_s { + tbm_bo bo; + tbm_bo_handle bo_handle; + int dmabuf_fd; +} camera_tbm_buffer_s; + typedef struct _camera_hal_handle { /* tbm */ tbm_bufmgr bufmgr; @@ -64,7 +70,9 @@ typedef struct _camera_hal_handle { gboolean buffer_thread_run; guint32 buffer_count; camera_buffer_s camera_buffers[BUFFER_MAX]; + camera_tbm_buffer_s tbm_buffers[BUFFER_MAX]; enum v4l2_buf_type buffer_type; + enum v4l2_memory memory_type; GMutex buffer_lock; GCond buffer_cond; |