Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: media/gpu/v4l2_device.cc

Issue 2398883002: Add support for multiple V4L2 video devices of the same type. (Closed)
Patch Set: Fixes for image processor. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <libdrm/drm_fourcc.h> 5 #include <libdrm/drm_fourcc.h>
6 #include <linux/videodev2.h> 6 #include <linux/videodev2.h>
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/numerics/safe_conversions.h" 9 #include "base/numerics/safe_conversions.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
11 #include "media/gpu/generic_v4l2_device.h" 11 #include "media/gpu/generic_v4l2_device.h"
12 #if defined(ARCH_CPU_ARMEL) 12 #if defined(ARCH_CPU_ARMEL)
13 #include "media/gpu/tegra_v4l2_device.h" 13 #include "media/gpu/tegra_v4l2_device.h"
14 #endif 14 #endif
15 15
16 namespace media { 16 namespace media {
17 17
18 V4L2Device::V4L2Device(Type type) : type_(type) {} 18 V4L2Device::V4L2Device(Type type) : type_(type) {}
19 19
20 V4L2Device::~V4L2Device() {} 20 V4L2Device::~V4L2Device() {}
21 21
22 // static 22 // static
23 scoped_refptr<V4L2Device> V4L2Device::Create(Type type) { 23 scoped_refptr<V4L2Device> V4L2Device::Create(Type type) {
24 DVLOG(3) << __PRETTY_FUNCTION__; 24 DVLOG(3) << __PRETTY_FUNCTION__;
25 25
26 scoped_refptr<GenericV4L2Device> generic_device(new GenericV4L2Device(type));
27 if (generic_device->Initialize())
28 return generic_device;
29
30 #if defined(ARCH_CPU_ARMEL) 26 #if defined(ARCH_CPU_ARMEL)
31 scoped_refptr<TegraV4L2Device> tegra_device(new TegraV4L2Device(type)); 27 scoped_refptr<TegraV4L2Device> tegra_device(new TegraV4L2Device(type));
32 if (tegra_device->Initialize()) 28 if (tegra_device->Initialize())
33 return tegra_device; 29 return tegra_device;
34 #endif 30 #endif
35 31
32 scoped_refptr<GenericV4L2Device> generic_device(new GenericV4L2Device(type));
33 if (generic_device->Initialize())
34 return generic_device;
35
36 DVLOG(1) << "Failed to create V4L2Device"; 36 DVLOG(1) << "Failed to create V4L2Device";
37 return scoped_refptr<V4L2Device>(); 37 return scoped_refptr<V4L2Device>();
38 } 38 }
39 39
40 // static 40 // static
41 VideoPixelFormat V4L2Device::V4L2PixFmtToVideoPixelFormat(uint32_t pix_fmt) { 41 VideoPixelFormat V4L2Device::V4L2PixFmtToVideoPixelFormat(uint32_t pix_fmt) {
42 switch (pix_fmt) { 42 switch (pix_fmt) {
43 case V4L2_PIX_FMT_NV12: 43 case V4L2_PIX_FMT_NV12:
44 case V4L2_PIX_FMT_NV12M: 44 case V4L2_PIX_FMT_NV12M:
45 return PIXEL_FORMAT_NV12; 45 return PIXEL_FORMAT_NV12;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 return V4L2_PIX_FMT_VP9_FRAME; 102 return V4L2_PIX_FMT_VP9_FRAME;
103 else 103 else
104 return V4L2_PIX_FMT_VP9; 104 return V4L2_PIX_FMT_VP9;
105 } else { 105 } else {
106 LOG(FATAL) << "Add more cases as needed"; 106 LOG(FATAL) << "Add more cases as needed";
107 return 0; 107 return 0;
108 } 108 }
109 } 109 }
110 110
111 // static 111 // static
112 std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
113 uint32_t pix_fmt,
114 bool is_encoder) {
115 VideoCodecProfile min_profile, max_profile;
116 std::vector<VideoCodecProfile> profiles;
117
118 switch (pix_fmt) {
119 case V4L2_PIX_FMT_H264:
120 case V4L2_PIX_FMT_H264_SLICE:
121 if (is_encoder) {
122 // TODO(posciak): need to query the device for supported H.264 profiles,
123 // for now choose Main as a sensible default.
124 min_profile = H264PROFILE_MAIN;
125 max_profile = H264PROFILE_MAIN;
126 } else {
127 min_profile = H264PROFILE_MIN;
128 max_profile = H264PROFILE_MAX;
129 }
130 break;
131
132 case V4L2_PIX_FMT_VP8:
133 case V4L2_PIX_FMT_VP8_FRAME:
134 min_profile = VP8PROFILE_MIN;
135 max_profile = VP8PROFILE_MAX;
136 break;
137
138 case V4L2_PIX_FMT_VP9:
139 case V4L2_PIX_FMT_VP9_FRAME:
140 min_profile = VP9PROFILE_MIN;
141 max_profile = VP9PROFILE_MAX;
142 break;
143
144 default:
145 NOTREACHED() << "Unhandled pixelformat " << std::hex << pix_fmt;
kcwu 2016/10/06 10:40:00 add "0x" string
Pawel Osciak 2016/10/07 08:30:23 Done.
146 return profiles;
147 }
148
149 for (int profile = min_profile; profile <= max_profile; ++profile)
150 profiles.push_back(static_cast<VideoCodecProfile>(profile));
151
152 return profiles;
153 }
154
155 // static
112 uint32_t V4L2Device::V4L2PixFmtToDrmFormat(uint32_t format) { 156 uint32_t V4L2Device::V4L2PixFmtToDrmFormat(uint32_t format) {
113 switch (format) { 157 switch (format) {
114 case V4L2_PIX_FMT_NV12: 158 case V4L2_PIX_FMT_NV12:
115 case V4L2_PIX_FMT_NV12M: 159 case V4L2_PIX_FMT_NV12M:
116 return DRM_FORMAT_NV12; 160 return DRM_FORMAT_NV12;
117 161
118 case V4L2_PIX_FMT_YUV420: 162 case V4L2_PIX_FMT_YUV420:
119 case V4L2_PIX_FMT_YUV420M: 163 case V4L2_PIX_FMT_YUV420M:
120 return DRM_FORMAT_YUV420; 164 return DRM_FORMAT_YUV420;
121 165
122 case V4L2_PIX_FMT_YVU420: 166 case V4L2_PIX_FMT_YVU420:
123 return DRM_FORMAT_YVU420; 167 return DRM_FORMAT_YVU420;
124 168
125 case V4L2_PIX_FMT_RGB32: 169 case V4L2_PIX_FMT_RGB32:
126 return DRM_FORMAT_ARGB8888; 170 return DRM_FORMAT_ARGB8888;
127 171
172 case V4L2_PIX_FMT_MT21:
173 return DRM_FORMAT_MT21;
174
128 default: 175 default:
129 DVLOG(1) << "Add more cases as needed"; 176 DVLOG(1) << "Unrecognized format " << std::hex << format;
kcwu 2016/10/06 10:39:59 "0x"
Pawel Osciak 2016/10/07 08:30:23 Done.
130 return 0; 177 return 0;
131 } 178 }
132 } 179 }
133 180
134 // static 181 // static
135 gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) { 182 gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) {
136 gfx::Size coded_size; 183 gfx::Size coded_size;
137 gfx::Size visible_size; 184 gfx::Size visible_size;
138 VideoPixelFormat frame_format = PIXEL_FORMAT_UNKNOWN; 185 VideoPixelFormat frame_format = PIXEL_FORMAT_UNKNOWN;
139 size_t bytesperline = 0; 186 size_t bytesperline = 0;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 << ", fall back to " << max_resolution->ToString(); 299 << ", fall back to " << max_resolution->ToString();
253 } 300 }
254 if (min_resolution->IsEmpty()) { 301 if (min_resolution->IsEmpty()) {
255 min_resolution->SetSize(16, 16); 302 min_resolution->SetSize(16, 16);
256 LOG(ERROR) << "GetSupportedResolution failed to get minimum resolution for " 303 LOG(ERROR) << "GetSupportedResolution failed to get minimum resolution for "
257 << "fourcc " << std::hex << pixelformat 304 << "fourcc " << std::hex << pixelformat
258 << ", fall back to " << min_resolution->ToString(); 305 << ", fall back to " << min_resolution->ToString();
259 } 306 }
260 } 307 }
261 308
262 VideoDecodeAccelerator::SupportedProfiles 309 std::vector<uint32_t> V4L2Device::EnumerateSupportedPixelformats(
263 V4L2Device::GetSupportedDecodeProfiles(const size_t num_formats, 310 v4l2_buf_type buf_type) {
264 const uint32_t pixelformats[]) { 311 std::vector<uint32_t> pixelformats;
265 DCHECK_EQ(type_, kDecoder); 312
266 VideoDecodeAccelerator::SupportedProfiles profiles;
267 VideoDecodeAccelerator::SupportedProfile profile;
268 v4l2_fmtdesc fmtdesc; 313 v4l2_fmtdesc fmtdesc;
269 memset(&fmtdesc, 0, sizeof(fmtdesc)); 314 memset(&fmtdesc, 0, sizeof(fmtdesc));
270 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 315 fmtdesc.type = buf_type;
271 316
272 for (; Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { 317 for (; Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) {
273 if (std::find(pixelformats, pixelformats + num_formats, 318 DVLOG(1) << "Found " << std::hex << fmtdesc.pixelformat << " "
274 fmtdesc.pixelformat) == pixelformats + num_formats) 319 << fmtdesc.description;
320 pixelformats.push_back(fmtdesc.pixelformat);
321 }
322
323 return pixelformats;
324 }
325
326 VideoDecodeAccelerator::SupportedProfiles
327 V4L2Device::EnumerateSupportedDecodeProfiles(const size_t num_formats,
328 const uint32_t pixelformats[]) {
329 DCHECK_EQ(type_, Type::kDecoder);
330 VideoDecodeAccelerator::SupportedProfiles profiles;
331
332 const auto& supported_pixelformats =
333 EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
334
335 for (uint32_t pixelformat : supported_pixelformats) {
336 if (std::find(pixelformats, pixelformats + num_formats, pixelformat) ==
337 pixelformats + num_formats)
275 continue; 338 continue;
276 int min_profile, max_profile; 339
277 switch (fmtdesc.pixelformat) { 340 VideoDecodeAccelerator::SupportedProfile profile;
278 case V4L2_PIX_FMT_H264: 341 GetSupportedResolution(pixelformat, &profile.min_resolution,
279 case V4L2_PIX_FMT_H264_SLICE:
280 min_profile = H264PROFILE_MIN;
281 max_profile = H264PROFILE_MAX;
282 break;
283 case V4L2_PIX_FMT_VP8:
284 case V4L2_PIX_FMT_VP8_FRAME:
285 min_profile = VP8PROFILE_MIN;
286 max_profile = VP8PROFILE_MAX;
287 break;
288 case V4L2_PIX_FMT_VP9:
289 case V4L2_PIX_FMT_VP9_FRAME:
290 min_profile = VP9PROFILE_MIN;
291 max_profile = VP9PROFILE_MAX;
292 break;
293 default:
294 NOTREACHED() << "Unhandled pixelformat " << std::hex
295 << fmtdesc.pixelformat;
296 return profiles;
297 }
298 GetSupportedResolution(fmtdesc.pixelformat, &profile.min_resolution,
299 &profile.max_resolution); 342 &profile.max_resolution);
300 for (int media_profile = min_profile; media_profile <= max_profile; 343
301 ++media_profile) { 344 const auto video_codec_profiles =
302 profile.profile = static_cast<VideoCodecProfile>(media_profile); 345 V4L2PixFmtToVideoCodecProfiles(pixelformat, false);
346
347 for (const auto& video_codec_profile : video_codec_profiles) {
348 profile.profile = video_codec_profile;
303 profiles.push_back(profile); 349 profiles.push_back(profile);
350
351 DVLOG(1) << "Found decoder profile " << GetProfileName(profile.profile)
352 << ", resolutions: " << profile.min_resolution.ToString() << " "
353 << profile.max_resolution.ToString();
304 } 354 }
305 } 355 }
356
306 return profiles; 357 return profiles;
307 } 358 }
308 359
309 bool V4L2Device::SupportsDecodeProfileForV4L2PixelFormats( 360 VideoEncodeAccelerator::SupportedProfiles
310 VideoCodecProfile profile, 361 V4L2Device::EnumerateSupportedEncodeProfiles() {
kcwu 2016/10/06 10:39:59 DCHECK_EQ(type_, Type::kEncode);
Pawel Osciak 2016/10/07 08:30:24 Done.
311 const size_t num_formats, 362 VideoEncodeAccelerator::SupportedProfiles profiles;
312 const uint32_t pixelformats[]) {
313 // Get all supported profiles by this device, taking into account only fourccs
314 // in pixelformats.
315 const auto supported_profiles =
316 GetSupportedDecodeProfiles(num_formats, pixelformats);
317 363
318 // Try to find requested profile among the returned supported_profiles. 364 const auto& supported_pixelformats =
319 const auto iter = std::find_if( 365 EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
320 supported_profiles.begin(), supported_profiles.end(),
321 [profile](const VideoDecodeAccelerator::SupportedProfile& p) {
322 return profile == p.profile;
323 });
324 366
325 return iter != supported_profiles.end(); 367 for (const auto& pixelformat : supported_pixelformats) {
368 VideoEncodeAccelerator::SupportedProfile profile;
369 profile.max_framerate_numerator = 30;
370 profile.max_framerate_denominator = 1;
371 gfx::Size min_resolution;
372 GetSupportedResolution(pixelformat, &min_resolution,
373 &profile.max_resolution);
374
375 const auto video_codec_profiles =
376 V4L2PixFmtToVideoCodecProfiles(pixelformat, true);
377
378 for (const auto& video_codec_profile : video_codec_profiles) {
379 profile.profile = video_codec_profile;
380 profiles.push_back(profile);
381
382 DVLOG(1) << "Found encoder profile " << GetProfileName(profile.profile)
383 << ", max resolution: " << profile.max_resolution.ToString();
384 }
385 }
386
387 return profiles;
326 } 388 }
327 389
328 } // namespace media 390 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698