Index: media/gpu/v4l2_device.cc |
diff --git a/media/gpu/v4l2_device.cc b/media/gpu/v4l2_device.cc |
index 9beee049c20a8854828dec42deace08a421cb250..2793164cfcf6c8e97d6c08d976b134cd994fb36c 100644 |
--- a/media/gpu/v4l2_device.cc |
+++ b/media/gpu/v4l2_device.cc |
@@ -23,16 +23,16 @@ V4L2Device::~V4L2Device() {} |
scoped_refptr<V4L2Device> V4L2Device::Create(Type type) { |
DVLOG(3) << __PRETTY_FUNCTION__; |
- scoped_refptr<GenericV4L2Device> generic_device(new GenericV4L2Device(type)); |
- if (generic_device->Initialize()) |
- return generic_device; |
- |
#if defined(ARCH_CPU_ARMEL) |
scoped_refptr<TegraV4L2Device> tegra_device(new TegraV4L2Device(type)); |
if (tegra_device->Initialize()) |
return tegra_device; |
#endif |
+ scoped_refptr<GenericV4L2Device> generic_device(new GenericV4L2Device(type)); |
+ if (generic_device->Initialize()) |
+ return generic_device; |
+ |
DVLOG(1) << "Failed to create V4L2Device"; |
return scoped_refptr<V4L2Device>(); |
} |
@@ -109,6 +109,50 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, |
} |
// static |
+std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( |
+ uint32_t pix_fmt, |
+ bool is_encoder) { |
+ VideoCodecProfile min_profile, max_profile; |
+ std::vector<VideoCodecProfile> profiles; |
+ |
+ switch (pix_fmt) { |
+ case V4L2_PIX_FMT_H264: |
+ case V4L2_PIX_FMT_H264_SLICE: |
+ if (is_encoder) { |
+ // TODO(posciak): need to query the device for supported H.264 profiles, |
+ // for now choose Main as a sensible default. |
+ min_profile = H264PROFILE_MAIN; |
+ max_profile = H264PROFILE_MAIN; |
+ } else { |
+ min_profile = H264PROFILE_MIN; |
+ max_profile = H264PROFILE_MAX; |
+ } |
+ break; |
+ |
+ case V4L2_PIX_FMT_VP8: |
+ case V4L2_PIX_FMT_VP8_FRAME: |
+ min_profile = VP8PROFILE_MIN; |
+ max_profile = VP8PROFILE_MAX; |
+ break; |
+ |
+ case V4L2_PIX_FMT_VP9: |
+ case V4L2_PIX_FMT_VP9_FRAME: |
+ min_profile = VP9PROFILE_MIN; |
+ max_profile = VP9PROFILE_MAX; |
+ break; |
+ |
+ default: |
+ 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.
|
+ return profiles; |
+ } |
+ |
+ for (int profile = min_profile; profile <= max_profile; ++profile) |
+ profiles.push_back(static_cast<VideoCodecProfile>(profile)); |
+ |
+ return profiles; |
+} |
+ |
+// static |
uint32_t V4L2Device::V4L2PixFmtToDrmFormat(uint32_t format) { |
switch (format) { |
case V4L2_PIX_FMT_NV12: |
@@ -125,8 +169,11 @@ uint32_t V4L2Device::V4L2PixFmtToDrmFormat(uint32_t format) { |
case V4L2_PIX_FMT_RGB32: |
return DRM_FORMAT_ARGB8888; |
+ case V4L2_PIX_FMT_MT21: |
+ return DRM_FORMAT_MT21; |
+ |
default: |
- DVLOG(1) << "Add more cases as needed"; |
+ DVLOG(1) << "Unrecognized format " << std::hex << format; |
kcwu
2016/10/06 10:39:59
"0x"
Pawel Osciak
2016/10/07 08:30:23
Done.
|
return 0; |
} |
} |
@@ -259,70 +306,85 @@ void V4L2Device::GetSupportedResolution(uint32_t pixelformat, |
} |
} |
-VideoDecodeAccelerator::SupportedProfiles |
-V4L2Device::GetSupportedDecodeProfiles(const size_t num_formats, |
- const uint32_t pixelformats[]) { |
- DCHECK_EQ(type_, kDecoder); |
- VideoDecodeAccelerator::SupportedProfiles profiles; |
- VideoDecodeAccelerator::SupportedProfile profile; |
+std::vector<uint32_t> V4L2Device::EnumerateSupportedPixelformats( |
+ v4l2_buf_type buf_type) { |
+ std::vector<uint32_t> pixelformats; |
+ |
v4l2_fmtdesc fmtdesc; |
memset(&fmtdesc, 0, sizeof(fmtdesc)); |
- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
+ fmtdesc.type = buf_type; |
for (; Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { |
- if (std::find(pixelformats, pixelformats + num_formats, |
- fmtdesc.pixelformat) == pixelformats + num_formats) |
+ DVLOG(1) << "Found " << std::hex << fmtdesc.pixelformat << " " |
+ << fmtdesc.description; |
+ pixelformats.push_back(fmtdesc.pixelformat); |
+ } |
+ |
+ return pixelformats; |
+} |
+ |
+VideoDecodeAccelerator::SupportedProfiles |
+V4L2Device::EnumerateSupportedDecodeProfiles(const size_t num_formats, |
+ const uint32_t pixelformats[]) { |
+ DCHECK_EQ(type_, Type::kDecoder); |
+ VideoDecodeAccelerator::SupportedProfiles profiles; |
+ |
+ const auto& supported_pixelformats = |
+ EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); |
+ |
+ for (uint32_t pixelformat : supported_pixelformats) { |
+ if (std::find(pixelformats, pixelformats + num_formats, pixelformat) == |
+ pixelformats + num_formats) |
continue; |
- int min_profile, max_profile; |
- switch (fmtdesc.pixelformat) { |
- case V4L2_PIX_FMT_H264: |
- case V4L2_PIX_FMT_H264_SLICE: |
- min_profile = H264PROFILE_MIN; |
- max_profile = H264PROFILE_MAX; |
- break; |
- case V4L2_PIX_FMT_VP8: |
- case V4L2_PIX_FMT_VP8_FRAME: |
- min_profile = VP8PROFILE_MIN; |
- max_profile = VP8PROFILE_MAX; |
- break; |
- case V4L2_PIX_FMT_VP9: |
- case V4L2_PIX_FMT_VP9_FRAME: |
- min_profile = VP9PROFILE_MIN; |
- max_profile = VP9PROFILE_MAX; |
- break; |
- default: |
- NOTREACHED() << "Unhandled pixelformat " << std::hex |
- << fmtdesc.pixelformat; |
- return profiles; |
- } |
- GetSupportedResolution(fmtdesc.pixelformat, &profile.min_resolution, |
+ |
+ VideoDecodeAccelerator::SupportedProfile profile; |
+ GetSupportedResolution(pixelformat, &profile.min_resolution, |
&profile.max_resolution); |
- for (int media_profile = min_profile; media_profile <= max_profile; |
- ++media_profile) { |
- profile.profile = static_cast<VideoCodecProfile>(media_profile); |
+ |
+ const auto video_codec_profiles = |
+ V4L2PixFmtToVideoCodecProfiles(pixelformat, false); |
+ |
+ for (const auto& video_codec_profile : video_codec_profiles) { |
+ profile.profile = video_codec_profile; |
profiles.push_back(profile); |
+ |
+ DVLOG(1) << "Found decoder profile " << GetProfileName(profile.profile) |
+ << ", resolutions: " << profile.min_resolution.ToString() << " " |
+ << profile.max_resolution.ToString(); |
} |
} |
+ |
return profiles; |
} |
-bool V4L2Device::SupportsDecodeProfileForV4L2PixelFormats( |
- VideoCodecProfile profile, |
- const size_t num_formats, |
- const uint32_t pixelformats[]) { |
- // Get all supported profiles by this device, taking into account only fourccs |
- // in pixelformats. |
- const auto supported_profiles = |
- GetSupportedDecodeProfiles(num_formats, pixelformats); |
- |
- // Try to find requested profile among the returned supported_profiles. |
- const auto iter = std::find_if( |
- supported_profiles.begin(), supported_profiles.end(), |
- [profile](const VideoDecodeAccelerator::SupportedProfile& p) { |
- return profile == p.profile; |
- }); |
- |
- return iter != supported_profiles.end(); |
+VideoEncodeAccelerator::SupportedProfiles |
+V4L2Device::EnumerateSupportedEncodeProfiles() { |
kcwu
2016/10/06 10:39:59
DCHECK_EQ(type_, Type::kEncode);
Pawel Osciak
2016/10/07 08:30:24
Done.
|
+ VideoEncodeAccelerator::SupportedProfiles profiles; |
+ |
+ const auto& supported_pixelformats = |
+ EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); |
+ |
+ for (const auto& pixelformat : supported_pixelformats) { |
+ VideoEncodeAccelerator::SupportedProfile profile; |
+ profile.max_framerate_numerator = 30; |
+ profile.max_framerate_denominator = 1; |
+ gfx::Size min_resolution; |
+ GetSupportedResolution(pixelformat, &min_resolution, |
+ &profile.max_resolution); |
+ |
+ const auto video_codec_profiles = |
+ V4L2PixFmtToVideoCodecProfiles(pixelformat, true); |
+ |
+ for (const auto& video_codec_profile : video_codec_profiles) { |
+ profile.profile = video_codec_profile; |
+ profiles.push_back(profile); |
+ |
+ DVLOG(1) << "Found encoder profile " << GetProfileName(profile.profile) |
+ << ", max resolution: " << profile.max_resolution.ToString(); |
+ } |
+ } |
+ |
+ return profiles; |
} |
} // namespace media |