1 /*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "StreamFormat"
19
20 #include "stream_format.h"
21
22 #include <system/graphics.h>
23 #include "arc/image_processor.h"
24 #include "common.h"
25
26 namespace v4l2_camera_hal {
27
28 using arc::SupportedFormat;
29 using arc::SupportedFormats;
30
GetSupportedFourCCs()31 static const std::vector<uint32_t> GetSupportedFourCCs() {
32 // The preference of supported fourccs in the list is from high to low.
33 static const std::vector<uint32_t> kSupportedFourCCs = {V4L2_PIX_FMT_YUYV,
34 V4L2_PIX_FMT_MJPEG};
35 return kSupportedFourCCs;
36 }
37
StreamFormat(int format,uint32_t width,uint32_t height)38 StreamFormat::StreamFormat(int format, uint32_t width, uint32_t height)
39 // TODO(b/30000211): multiplanar support.
40 : type_(V4L2_BUF_TYPE_VIDEO_CAPTURE),
41 v4l2_pixel_format_(StreamFormat::HalToV4L2PixelFormat(format)),
42 width_(width),
43 height_(height),
44 bytes_per_line_(0) {}
45
StreamFormat(const v4l2_format & format)46 StreamFormat::StreamFormat(const v4l2_format& format)
47 : type_(format.type),
48 // TODO(b/30000211): multiplanar support.
49 v4l2_pixel_format_(format.fmt.pix.pixelformat),
50 width_(format.fmt.pix.width),
51 height_(format.fmt.pix.height),
52 bytes_per_line_(format.fmt.pix.bytesperline) {}
53
StreamFormat(const arc::SupportedFormat & format)54 StreamFormat::StreamFormat(const arc::SupportedFormat& format)
55 : type_(V4L2_BUF_TYPE_VIDEO_CAPTURE),
56 v4l2_pixel_format_(format.fourcc),
57 width_(format.width),
58 height_(format.height),
59 bytes_per_line_(0) {}
60
FillFormatRequest(v4l2_format * format) const61 void StreamFormat::FillFormatRequest(v4l2_format* format) const {
62 memset(format, 0, sizeof(*format));
63 format->type = type_;
64 format->fmt.pix.pixelformat = v4l2_pixel_format_;
65 format->fmt.pix.width = width_;
66 format->fmt.pix.height = height_;
67 // Bytes per line and min buffer size are outputs set by the driver,
68 // not part of the request.
69 }
70
Category() const71 FormatCategory StreamFormat::Category() const {
72 switch (v4l2_pixel_format_) {
73 case V4L2_PIX_FMT_JPEG:
74 return kFormatCategoryStalling;
75 case V4L2_PIX_FMT_YUV420: // Fall through.
76 case V4L2_PIX_FMT_BGR32:
77 return kFormatCategoryNonStalling;
78 default:
79 // Note: currently no supported RAW formats.
80 return kFormatCategoryUnknown;
81 }
82 }
83
operator ==(const StreamFormat & other) const84 bool StreamFormat::operator==(const StreamFormat& other) const {
85 // Used to check that a requested format was actually set, so
86 // don't compare bytes per line or min buffer size.
87 return (type_ == other.type_ &&
88 v4l2_pixel_format_ == other.v4l2_pixel_format_ &&
89 width_ == other.width_ && height_ == other.height_);
90 }
91
operator !=(const StreamFormat & other) const92 bool StreamFormat::operator!=(const StreamFormat& other) const {
93 return !(*this == other);
94 }
95
V4L2ToHalPixelFormat(uint32_t v4l2_pixel_format)96 int StreamFormat::V4L2ToHalPixelFormat(uint32_t v4l2_pixel_format) {
97 // Translate V4L2 format to HAL format.
98 switch (v4l2_pixel_format) {
99 case V4L2_PIX_FMT_BGR32:
100 return HAL_PIXEL_FORMAT_RGBA_8888;
101 case V4L2_PIX_FMT_JPEG:
102 return HAL_PIXEL_FORMAT_BLOB;
103 case V4L2_PIX_FMT_NV21:
104 return HAL_PIXEL_FORMAT_YCrCb_420_SP;
105 case V4L2_PIX_FMT_YUV420:
106 return HAL_PIXEL_FORMAT_YCbCr_420_888;
107 case V4L2_PIX_FMT_YUYV:
108 return HAL_PIXEL_FORMAT_YCbCr_422_I;
109 case V4L2_PIX_FMT_YVU420:
110 return HAL_PIXEL_FORMAT_YV12;
111 default:
112 // Unrecognized format.
113 HAL_LOGV("Unrecognized v4l2 pixel format %u", v4l2_pixel_format);
114 break;
115 }
116 return -1;
117 }
118
HalToV4L2PixelFormat(int hal_pixel_format)119 uint32_t StreamFormat::HalToV4L2PixelFormat(int hal_pixel_format) {
120 switch (hal_pixel_format) {
121 case HAL_PIXEL_FORMAT_BLOB:
122 return V4L2_PIX_FMT_JPEG;
123 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: // Fall-through
124 case HAL_PIXEL_FORMAT_RGBA_8888:
125 return V4L2_PIX_FMT_BGR32;
126 case HAL_PIXEL_FORMAT_YCbCr_420_888:
127 // This is a flexible YUV format that depends on platform. Different
128 // platform may have different format. It can be YVU420 or NV12. Now we
129 // return YVU420 first.
130 // TODO(): call drm_drv.get_fourcc() to get correct format.
131 return V4L2_PIX_FMT_YUV420;
132 case HAL_PIXEL_FORMAT_YCbCr_422_I:
133 return V4L2_PIX_FMT_YUYV;
134 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
135 return V4L2_PIX_FMT_NV21;
136 case HAL_PIXEL_FORMAT_YV12:
137 return V4L2_PIX_FMT_YVU420;
138 default:
139 HAL_LOGV("Pixel format 0x%x is unsupported.", hal_pixel_format);
140 break;
141 }
142 return -1;
143 }
144
145 // Copy the qualified format into out_format and return true if there is a
146 // proper and fitting format in the given format lists.
FindBestFitFormat(const SupportedFormats & supported_formats,const SupportedFormats & qualified_formats,uint32_t fourcc,uint32_t width,uint32_t height,SupportedFormat * out_format)147 bool StreamFormat::FindBestFitFormat(const SupportedFormats& supported_formats,
148 const SupportedFormats& qualified_formats,
149 uint32_t fourcc, uint32_t width,
150 uint32_t height,
151 SupportedFormat* out_format) {
152 // Match exact format and resolution if possible.
153 for (const auto& format : supported_formats) {
154 if (format.fourcc == fourcc && format.width == width &&
155 format.height == height) {
156 if (out_format != NULL) {
157 *out_format = format;
158 }
159 return true;
160 }
161 }
162 // All conversions will be done through CachedFrame for now, which will
163 // immediately convert the qualified format into YU12 (YUV420). We check
164 // here that the conversion between YU12 and |fourcc| is supported.
165 if (!arc::ImageProcessor::SupportsConversion(V4L2_PIX_FMT_YUV420, fourcc)) {
166 HAL_LOGE("Conversion between YU12 and 0x%x not supported.", fourcc);
167 return false;
168 }
169
170 // Choose the qualified format with a matching resolution.
171 for (const auto& format : qualified_formats) {
172 if (format.width == width && format.height == height) {
173 if (out_format != NULL) {
174 *out_format = format;
175 }
176 return true;
177 }
178 }
179 return false;
180 }
181
182 // Copy corresponding format into out_format and return true by matching
183 // resolution |width|x|height| in |formats|.
FindFormatByResolution(const SupportedFormats & formats,uint32_t width,uint32_t height,SupportedFormat * out_format)184 bool StreamFormat::FindFormatByResolution(const SupportedFormats& formats,
185 uint32_t width, uint32_t height,
186 SupportedFormat* out_format) {
187 for (const auto& format : formats) {
188 if (format.width == width && format.height == height) {
189 if (out_format != NULL) {
190 *out_format = format;
191 }
192 return true;
193 }
194 }
195 return false;
196 }
197
GetQualifiedFormats(const SupportedFormats & supported_formats)198 SupportedFormats StreamFormat::GetQualifiedFormats(
199 const SupportedFormats& supported_formats) {
200 // The preference of supported fourccs in the list is from high to low.
201 const std::vector<uint32_t> supported_fourccs = GetSupportedFourCCs();
202 SupportedFormats qualified_formats;
203 for (const auto& supported_fourcc : supported_fourccs) {
204 for (const auto& supported_format : supported_formats) {
205 if (supported_format.fourcc != supported_fourcc) {
206 continue;
207 }
208
209 // Skip if |qualified_formats| already has the same resolution with a more
210 // preferred fourcc.
211 if (FindFormatByResolution(qualified_formats, supported_format.width,
212 supported_format.height, NULL)) {
213 continue;
214 }
215 qualified_formats.push_back(supported_format);
216 }
217 }
218 return qualified_formats;
219 }
220
221 } // namespace v4l2_camera_hal
222