return ret;
}
+static int __vision_source_set_stream(vision_source_v4l2_s *handle,
+ vision_source_pixel_format_e pixel_format,
+ vision_source_resolution_s *resolution,
+ uint32_t fps,
+ uint32_t request_buffer_count)
+{
+ struct v4l2_format v4l2_fmt;
+ struct v4l2_streamparm v4l2_parm;
+
+ guint32 fourcc = 0;
+ guint32 plane_num = 0;
+
+ if (!handle || !resolution) {
+ LOGE("NULL param %p %p", handle, resolution);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ /* S_FMT */
+ int ret = __vision_source_get_fourcc_plane_num(pixel_format, &fourcc,
+ &plane_num);
+ if (ret != VISION_SOURCE_ERROR_NONE) {
+ LOGE("get fourcc failed [format %d]", pixel_format);
+ return ret;
+ }
+
+ memset(&v4l2_fmt, 0x0, sizeof(struct v4l2_format));
+
+ v4l2_fmt.type = handle->buffer_type;
+ if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) {
+ v4l2_fmt.fmt.pix_mp.width = resolution->width;
+ v4l2_fmt.fmt.pix_mp.height = resolution->height;
+ v4l2_fmt.fmt.pix_mp.pixelformat = fourcc;
+ v4l2_fmt.fmt.pix_mp.num_planes = plane_num;
+ } else {
+ v4l2_fmt.fmt.pix.width = resolution->width;
+ v4l2_fmt.fmt.pix.height = resolution->height;
+ v4l2_fmt.fmt.pix.pixelformat = fourcc;
+ v4l2_fmt.fmt.pix.bytesperline = resolution->width;
+ }
+
+ if (v4l2_ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
+ LOGE("S_FMT failed. errno %d", errno);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) {
+ for (int i = 0; i < v4l2_fmt.fmt.pix_mp.num_planes; i++) {
+ 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 {
+ LOGD("stride %d, sizeimage %d", v4l2_fmt.fmt.pix.bytesperline,
+ v4l2_fmt.fmt.pix.sizeimage);
+ }
+
+ /* G_PARM */
+ memset(&v4l2_parm, 0x0, sizeof(struct v4l2_streamparm));
+
+ v4l2_parm.type = handle->buffer_type;
+
+ if (v4l2_ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
+ LOGE("G_PARM failed. errno %d", errno);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ /* S_PARM to set fps */
+ v4l2_parm.parm.capture.timeperframe.numerator = 1;
+ v4l2_parm.parm.capture.timeperframe.denominator = fps;
+
+ if (v4l2_ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
+ LOGE("S_PARM failed. errno %d", errno);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+ return VISION_SOURCE_ERROR_NONE;
+}
+
int vision_source_v4l2_init(vision_source_h *handle)
{
LOGD("enter");
return VISION_SOURCE_ERROR_NONE;
}
+int vision_source_v4l2_set_stream_format(vision_source_h handle,
+ vision_source_format_s *format)
+{
+ VISION_SOURCE_NULL_ARG_CHECK(handle);
+ VISION_SOURCE_NULL_ARG_CHECK(format);
+ vision_source_v4l2_s *v4l2_handle = (vision_source_v4l2_s *) handle;
+ int i = 0;
+ int j = 0;
+ int ret = VISION_SOURCE_ERROR_NONE;
+ gboolean capability_check = FALSE;
+ vision_source_device_info_s *device_info = NULL;
+
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&v4l2_handle->lock);
+
+ if (!v4l2_handle->device_info_list) {
+ LOGE("no device info list");
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ /* check capability */
+ device_info = &v4l2_handle->device_info_list
+ ->device_info[v4l2_handle->device_index];
+
+ /* format */
+ for (i = 0; i < device_info->pixel_list.count; i++) {
+ if (format->pixel_format ==
+ device_info->pixel_list.pixels[i].pixel_format) {
+ LOGD("format matched %d, check resolution.", format->pixel_format);
+
+ vision_source_resolution_match_fps_list_s *res_match =
+ &device_info->pixel_list.pixels[i].resolution_list;
+
+ /* resolution */
+ for (j = 0; j < res_match->count; j++) {
+ if (format->resolution.width ==
+ res_match->resolutions[j].resolution.width &&
+ format->resolution.height ==
+ res_match->resolutions[j].resolution.height) {
+ LOGD("resolution matched %dx%d", format->resolution.width,
+ format->resolution.height);
+ capability_check = TRUE;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (!capability_check) {
+ LOGE("capability failed - %d, %dx%d", format->pixel_format,
+ format->resolution.width, format->resolution.height);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ /* compare with current settings */
+ if (v4l2_handle->stream_format.pixel_format == format->pixel_format &&
+ v4l2_handle->stream_format.resolution.width ==
+ format->resolution.width &&
+ v4l2_handle->stream_format.resolution.height ==
+ format->resolution.height &&
+ v4l2_handle->stream_format.fps == format->fps) {
+ LOGD("no need to restart preview stream");
+ return VISION_SOURCE_ERROR_NONE;
+ }
+
+ LOGD("Preview setting is changed. Restart preview now.");
+
+ /* stop preview stream to change it */
+ ret = __vision_source_stop_stream(v4l2_handle, v4l2_handle->buffer_count);
+ if (ret != VISION_SOURCE_ERROR_NONE) {
+ LOGE("failed to stop stream");
+ return ret;
+ }
+
+ ret = __vision_source_set_stream(v4l2_handle, format->pixel_format,
+ &format->resolution, format->fps,
+ BUFFER_MAX);
+ if (ret != VISION_SOURCE_ERROR_NONE) {
+ LOGE("failed to set stream");
+ return ret;
+ }
+
+ memcpy(&v4l2_handle->stream_format, format, sizeof(vision_source_format_s));
+
+ return VISION_SOURCE_ERROR_NONE;
+}
+
void attach_backend(vision_source_func_s *funcp)
{
funcp->init = vision_source_v4l2_init;
funcp->enumerate_devices = vision_source_v4l2_enumerate_devices;
funcp->open_device = vision_source_v4l2_open_device;
funcp->close_device = vision_source_v4l2_close_device;
+ funcp->set_stream_format = vision_source_v4l2_set_stream_format;
}
\ No newline at end of file
ASSERT_EQ(vision_source_open_device(ms_handle, 0),
VISION_SOURCE_ERROR_NONE);
EXPECT_EQ(vision_source_close_device(ms_handle), VISION_SOURCE_ERROR_NONE);
+}
+
+TEST_F(VisionV4L2, SetStream)
+{
+ vision_source_device_info_list_s dev_list;
+ ASSERT_EQ(vision_source_enumerate_devices(ms_handle, &dev_list),
+ VISION_SOURCE_ERROR_NONE);
+ ASSERT_GT(dev_list.count, 0);
+
+ ASSERT_GT(dev_list.device_info[0].pixel_list.count, 0);
+ vision_source_format_s format;
+ format.pixel_format =
+ dev_list.device_info[0].pixel_list.pixels[0].pixel_format;
+ ASSERT_GT(
+ dev_list.device_info[0].pixel_list.pixels[0].resolution_list.count,
+ 0);
+
+ format.resolution.width = dev_list.device_info[0]
+ .pixel_list.pixels[0]
+ .resolution_list.resolutions[0]
+ .resolution.width;
+ format.resolution.height = dev_list.device_info[0]
+ .pixel_list.pixels[0]
+ .resolution_list.resolutions[0]
+ .resolution.height;
+ ASSERT_GT(dev_list.device_info[0]
+ .pixel_list.pixels[0]
+ .resolution_list.resolutions[0]
+ .fps_list.count,
+ 0);
+ format.fps = dev_list.device_info[0]
+ .pixel_list.pixels[0]
+ .resolution_list.resolutions[0]
+ .fps_list.fps[0];
+
+ ASSERT_EQ(vision_source_open_device(ms_handle, 0),
+ VISION_SOURCE_ERROR_NONE);
+ EXPECT_EQ(vision_source_set_stream_format(ms_handle, &format),
+ VISION_SOURCE_ERROR_NONE);
+ EXPECT_EQ(vision_source_close_device(ms_handle), VISION_SOURCE_ERROR_NONE);
}
\ No newline at end of file