Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 1 | // Copyright 2014 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 4 | #include <linux/videodev2.h> |
Kuang-che Wu | ca2bd58 | 2014-07-22 18:24:45 +0800 | [diff] [blame] | 5 | #include <stdio.h> |
| 6 | #include <string.h> |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 7 | |
| 8 | #include "label_detect.h" |
| 9 | |
| 10 | /* Returns true if device fd supports given format of buffer type. |
| 11 | * Example of buf_type: V4L2_BUF_TYPE_VIDEO_OUTPUT, |
| 12 | * V4L2_BUF_TYPE_VIDEO_CAPTURE. |
| 13 | * */ |
Tom Hughes | 0e81695 | 2020-08-24 18:04:24 -0700 | [diff] [blame] | 14 | bool is_v4l2_support_format(int fd, |
| 15 | enum v4l2_buf_type buf_type, |
| 16 | uint32_t fourcc) { |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 17 | int i; |
| 18 | bool found = false; |
| 19 | char fourcc_str[5]; |
| 20 | |
| 21 | convert_fourcc_to_str(fourcc, fourcc_str); |
| 22 | TRACE("is_v4l2_support_format(%s)\n", fourcc_str); |
Tom Hughes | 0e81695 | 2020-08-24 18:04:24 -0700 | [diff] [blame] | 23 | for (i = 0;; ++i) { |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 24 | struct v4l2_fmtdesc format_desc; |
| 25 | memset(&format_desc, 0, sizeof(format_desc)); |
Tom Hughes | 0e81695 | 2020-08-24 18:04:24 -0700 | [diff] [blame] | 26 | format_desc.type = (enum v4l2_buf_type)buf_type; |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 27 | format_desc.index = i; |
| 28 | if (-1 == do_ioctl(fd, VIDIOC_ENUM_FMT, &format_desc)) { |
| 29 | break; |
| 30 | } |
| 31 | convert_fourcc_to_str(format_desc.pixelformat, fourcc_str); |
| 32 | TRACE("%s supported\n", fourcc_str); |
| 33 | if (format_desc.pixelformat == fourcc) { |
| 34 | found = true; |
| 35 | /* continue the loop in order to output all supported formats */ |
| 36 | } |
| 37 | } |
| 38 | TRACE("is_v4l2_support_format: %s\n", found ? "true" : "false"); |
| 39 | return found; |
| 40 | } |
| 41 | |
henryhsu | 5c4b664 | 2015-08-13 14:15:00 +0800 | [diff] [blame] | 42 | /* Returns true if device fd is V4L2 video encode/decode device. */ |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 43 | bool is_hw_video_acc_device(int fd) { |
| 44 | struct v4l2_capability cap; |
| 45 | int ret = do_ioctl(fd, VIDIOC_QUERYCAP, &cap); |
| 46 | if (ret == 0) { |
Wu-Cheng Li | 853d053 | 2016-05-19 13:19:01 +0800 | [diff] [blame] | 47 | if ((cap.capabilities & V4L2_CAP_STREAMING) && |
| 48 | (cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE)) { |
Kuang-che Wu | db9c20b | 2014-04-17 16:14:18 +0800 | [diff] [blame] | 49 | TRACE("is_hw_video_acc_device: true\n"); |
| 50 | return true; |
| 51 | } |
| 52 | } |
| 53 | TRACE("is_hw_video_acc_device: false\n"); |
| 54 | return false; |
| 55 | } |
henryhsu | 5c4b664 | 2015-08-13 14:15:00 +0800 | [diff] [blame] | 56 | |
| 57 | /* Returns true if device fd is V4L2 jpeg encode/decode device. */ |
| 58 | bool is_hw_jpeg_acc_device(int fd) { |
| 59 | struct v4l2_capability cap; |
| 60 | int ret = do_ioctl(fd, VIDIOC_QUERYCAP, &cap); |
| 61 | if (ret == 0) { |
henryhsu | 5f8cd9d | 2015-08-17 14:15:04 +0800 | [diff] [blame] | 62 | if ((cap.capabilities & V4L2_CAP_STREAMING) && |
Kuang-che Wu | 1307bd4 | 2017-01-03 17:54:42 +0800 | [diff] [blame] | 63 | (cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE)) { |
henryhsu | 5c4b664 | 2015-08-13 14:15:00 +0800 | [diff] [blame] | 64 | TRACE("is_hw_jpeg_acc_device: true\n"); |
| 65 | return true; |
| 66 | } |
| 67 | } |
| 68 | TRACE("is_hw_jpeg_acc_device: false\n"); |
| 69 | return false; |
| 70 | } |
Hirokazu Honda | d92e9ac | 2017-09-20 11:33:59 +0900 | [diff] [blame] | 71 | |
| 72 | /* Returns success or failure of getting resolution. The maximum resolution is |
| 73 | returned through arguments. */ |
Tom Hughes | 0e81695 | 2020-08-24 18:04:24 -0700 | [diff] [blame] | 74 | bool get_v4l2_max_resolution(int fd, |
| 75 | uint32_t fourcc, |
| 76 | int32_t* const resolution_width, |
| 77 | int32_t* const resolution_height) { |
Hirokazu Honda | d92e9ac | 2017-09-20 11:33:59 +0900 | [diff] [blame] | 78 | *resolution_width = 0; |
| 79 | *resolution_height = 0; |
| 80 | |
| 81 | struct v4l2_frmsizeenum frame_size; |
| 82 | memset(&frame_size, 0, sizeof(frame_size)); |
| 83 | frame_size.pixel_format = fourcc; |
| 84 | |
| 85 | for (; do_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size) == 0; |
| 86 | ++frame_size.index) { |
| 87 | if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { |
| 88 | if (frame_size.discrete.width >= *resolution_width && |
| 89 | frame_size.discrete.height >= *resolution_height) { |
| 90 | *resolution_width = frame_size.discrete.width; |
| 91 | *resolution_height = frame_size.discrete.height; |
| 92 | } |
| 93 | } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE || |
| 94 | frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { |
| 95 | *resolution_width = frame_size.stepwise.max_width; |
| 96 | *resolution_height = frame_size.stepwise.max_height; |
| 97 | break; |
| 98 | } |
| 99 | } |
| 100 | return *resolution_width > 0 && *resolution_height > 0; |
| 101 | } |