blob: 8207dd9af9209efdb824733b13f672fbbf2f63a7 [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// resolution detectors
#if defined(USE_V4L2_CODEC)
#include <linux/videodev2.h>
#endif // defined(USE_V4L2_CODEC)
#if defined(USE_VAAPI)
#include <va/va.h>
#endif // defined(USE_VAAPI)
#include "label_detect.h"
#if defined(USE_VAAPI) || defined(USE_V4L2_CODEC)
static const int32_t width_4k = 3840;
static const int32_t height_4k = 2160;
#endif
#if defined(USE_VAAPI)
#if VA_CHECK_VERSION(0, 35, 0)
static const char kDRMDevicePattern[] = "/dev/dri/renderD*";
static const VAProfile va_profiles_h264[] = {
VAProfileH264Baseline, VAProfileH264Main, VAProfileH264High,
VAProfileH264ConstrainedBaseline, VAProfileNone};
static const VAProfile va_profiles_vp8[] = {VAProfileVP8Version0_3,
VAProfileNone};
static const VAProfile va_profiles_vp9[] = {VAProfileVP9Profile0,
VAProfileNone};
/* Determines if a VAAPI device associated with given |fd| supports
* |va_profiles| for |va_entrypoint|, and its maximum resolution is larger
* than 3840x2160.
*/
static bool is_vaapi_4k_device(int fd,
const VAProfile* va_profiles,
VAEntrypoint va_entrypoint) {
int32_t resolution_width = 0;
int32_t resolution_height = 0;
if (is_vaapi_support_formats(fd, va_profiles, va_entrypoint,
VA_RT_FORMAT_YUV420)) {
if (get_vaapi_max_resolution(fd, va_profiles, va_entrypoint,
&resolution_width, &resolution_height)) {
return resolution_width >= width_4k && resolution_height >= height_4k;
}
}
return false;
}
// Determines if is_vaapi_4k_device() for H264 decoding.
static bool is_vaapi_4k_device_dec_h264(int fd) {
return is_vaapi_4k_device(fd, va_profiles_h264, VAEntrypointVLD);
}
// Determines if is_vaapi_4k_device() for H264 encoding.
static bool is_vaapi_4k_device_enc_h264(int fd) {
return (is_vaapi_4k_device(fd, va_profiles_h264, VAEntrypointEncSlice) ||
is_vaapi_4k_device(fd, va_profiles_h264, VAEntrypointEncSliceLP));
}
// Determines if is_vaapi_4k_device() for VP8 decoding.
static bool is_vaapi_4k_device_dec_vp8(int fd) {
return is_vaapi_4k_device(fd, va_profiles_vp8, VAEntrypointVLD);
}
// Determines if is_vaapi_4k_device() for VP8 encoding.
static bool is_vaapi_4k_device_enc_vp8(int fd) {
return (is_vaapi_4k_device(fd, va_profiles_vp8, VAEntrypointEncSlice) ||
is_vaapi_4k_device(fd, va_profiles_vp8, VAEntrypointEncSliceLP));
}
// Determines if is_vaapi_4k_device() for VP9 decoding.
static bool is_vaapi_4k_device_dec_vp9(int fd) {
return is_vaapi_4k_device(fd, va_profiles_vp9, VAEntrypointVLD);
}
// Determines if is_vaapi_4k_device() for VP9 encoding.
static bool is_vaapi_4k_device_enc_vp9(int fd) {
return (is_vaapi_4k_device(fd, va_profiles_vp9, VAEntrypointEncSlice) ||
is_vaapi_4k_device(fd, va_profiles_vp9, VAEntrypointEncSliceLP));
}
#endif // VA_CHECK_VERSION(0, 38, 1)
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
static const char kVideoDevicePattern[] = "/dev/video*";
/* Determined if a V4L2 device associated with given |fd| supports |pix_fmt|
* for |buf_type|, and its maximum resolution is larger than 3840x2160.
*/
static bool is_v4l2_4k_device(int fd,
enum v4l2_buf_type buf_type,
uint32_t pix_fmt) {
int32_t resolution_width;
int32_t resolution_height;
if (!is_hw_video_acc_device(fd)) {
return false;
}
if (is_v4l2_support_format(fd, buf_type, pix_fmt)) {
if (get_v4l2_max_resolution(fd, pix_fmt, &resolution_width,
&resolution_height)) {
return resolution_width >= width_4k && resolution_height >= height_4k;
}
}
return false;
}
// Determines if is_v4l2_4k_device() for H264 decoding.
static bool is_v4l2_4k_device_dec_h264(int fd) {
return is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_H264) ||
is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_H264_SLICE);
}
// Determines if is_v4l2_4k_device() for H264 encoding.
static bool is_v4l2_4k_device_enc_h264(int fd) {
return is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_H264);
}
// Determines if is_v4l2_4k_device() for VP8 decoding.
static bool is_v4l2_4k_device_dec_vp8(int fd) {
return is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP8) ||
is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP8_FRAME);
}
// Determines if is_v4l2_4k_device() for VP8 encoding.
static bool is_v4l2_4k_device_enc_vp8(int fd) {
return is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_VP8);
}
// Determines if is_v4l2_4k_device() for VP9 decoding.
static bool is_v4l2_4k_device_dec_vp9(int fd) {
return is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP9) ||
is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP9_FRAME);
}
// Determines if is_v4l2_4k_device() for VP9 encoding.
static bool is_v4l2_4k_device_enc_vp9(int fd) {
return is_v4l2_4k_device(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_VP9);
}
#endif // defined(USE_V4L2_CODEC)
/* Determines "4k_video_h264". Return true, if either the VAAPI device
* supports 4k resolution H264 decoding, has decoding entry point,
* and input YUV420 formats. Or there is a
* /dev/video* device supporting 4k resolution H264 decoding.
*/
bool detect_4k_device_h264(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_4k_device_dec_h264))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_4k_device_dec_h264))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "4k_video_vp8". Return true, if either the VAAPI device
* supports 4k resolution VP8 decoding, has decoding entry point,
* and input YUV420 formats. Or there is a
* /dev/video* device supporting 4k resolution VP8 decoding.
*/
bool detect_4k_device_vp8(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_4k_device_dec_vp8))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_4k_device_dec_vp8))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "4k_video_vp9". Return true, if either the VAAPI device
* supports 4k resolution VP9 decoding, has decoding entry point,
* and input YUV420 formats. Or there is a
* /dev/video* device supporting 4k resolution VP9 decoding.
*/
bool detect_4k_device_vp9(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_4k_device_dec_vp9))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_4k_device_dec_vp9))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "4k_video_enc_h264". Return true, if either the VAAPI device
* supports 4k resolution H264 encoding, has encoding entry point,
* and input YUV420 formats. Or there is a
* /dev/video* device supporting 4k resolution H264 encoding.
*/
bool detect_4k_device_enc_h264(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_4k_device_enc_h264))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_4k_device_enc_h264))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "4k_video_enc_vp8". Return true, if either the VAAPI device
* supports 4k resolution VP8 encoding, has encoding entry point,
* and input YUV420 formats. Or there is a
* /dev/video* device supporting 4k resolution VP8 encoding.
*/
bool detect_4k_device_enc_vp8(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_4k_device_enc_vp8))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_4k_device_enc_vp8))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "4k_video_enc_vp9". Return true, if either the VAAPI device
* supports 4k resolution VP9 encoding, has encoding entry point,
* and input YUV420 formats. Or there is a
* /dev/video* device supporting 4k resolution VP9 encoding.
*/
bool detect_4k_device_enc_vp9(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_4k_device_enc_vp9))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_4k_device_enc_vp9))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}