blob: 3fd8c80ff2a7936f566685d8bfa2a95770813bfa [file] [log] [blame]
// Copyright 2014 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.
//
// hw_video_acc_* detectors
// For each detector, check both V4L2 and VAAPI capabilities.
#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_V4L2_CODEC)
static const char* kJpegDevicePattern = "/dev/jpeg*";
static const char* kVideoDevicePattern = "/dev/video*";
/* Helper function for detect_video_acc_h264.
* A V4L2 device supports H.264 decoding, if it's
* a mem-to-mem V4L2 device, i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*,
* V4L2_CAP_VIDEO_OUTPUT_* and V4L2_CAP_STREAMING capabilities and it supports
* V4L2_PIX_FMT_H264 as it's input, i.e. for its
* V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE queue.
*/
static bool is_v4l2_dec_h264_device(int fd) {
return is_hw_video_acc_device(fd) &&
(is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_H264) ||
is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_H264_SLICE));
}
/* Helper function for detect_video_acc_vp8.
* A V4L2 device supports VP8 decoding, if it's a mem-to-mem V4L2 device,
* i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*, V4L2_CAP_VIDEO_OUTPUT_* and
* V4L2_CAP_STREAMING capabilities and it supports V4L2_PIX_FMT_VP8 as it's
* input, i.e. for its V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE queue.
*/
static bool is_v4l2_dec_vp8_device(int fd) {
return is_hw_video_acc_device(fd) &&
(is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP8) ||
is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP8_FRAME));
}
/* Helper function for detect_video_acc_vp9.
* A V4L2 device supports VP9 decoding, if it's a mem-to-mem V4L2 device,
* i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*, V4L2_CAP_VIDEO_OUTPUT_* and
* V4L2_CAP_STREAMING capabilities and it supports V4L2_PIX_FMT_VP9 as it's
* input, i.e. for its V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE queue.
*/
static bool is_v4l2_dec_vp9_device(int fd) {
return is_hw_video_acc_device(fd) &&
(is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP9) ||
is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_VP9_FRAME));
}
/* Helper function for detect_video_acc_enc_h264.
* A V4L2 device supports H.264 encoding, if it's a mem-to-mem V4L2 device,
* i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*, V4L2_CAP_VIDEO_OUTPUT_* and
* V4L2_CAP_STREAMING capabilities and it supports V4L2_PIX_FMT_H264 as it's
* output, i.e. for its V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE queue.
*/
static bool is_v4l2_enc_h264_device(int fd) {
return is_hw_video_acc_device(fd) &&
is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_H264);
}
/* Helper function for detect_video_acc_enc_vp8.
* A V4L2 device supports VP8 encoding, if it's a mem-to-mem V4L2 device,
* i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*, V4L2_CAP_VIDEO_OUTPUT_* and
* V4L2_CAP_STREAMING capabilities and it supports V4L2_PIX_FMT_VP8 as it's
* output, i.e. for its V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE queue.
*/
static bool is_v4l2_enc_vp8_device(int fd) {
return is_hw_video_acc_device(fd) &&
is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_VP8);
}
/* Helper function for detect_jpeg_acc_dec.
* A V4L2 device supports JPEG decoding, if it's a mem-to-mem V4L2 device,
* i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*, V4L2_CAP_VIDEO_OUTPUT_* and
* V4L2_CAP_STREAMING capabilities and it supports V4L2_PIX_FMT_JPEG as it's
* input, i.e. for its V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE queue.
*/
static bool is_v4l2_dec_jpeg_device(int fd) {
return is_hw_jpeg_acc_device(fd) &&
is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
V4L2_PIX_FMT_JPEG);
}
/* Helper function for detect_jpeg_acc_enc.
* A V4L2 device supports JPEG encoding, if it's a mem-to-mem V4L2 device,
* i.e. it provides V4L2_CAP_VIDEO_CAPTURE_*, V4L2_CAP_VIDEO_OUTPUT_* and
* V4L2_CAP_STREAMING capabilities and it supports V4L2_PIX_FMT_JPEG as it's
* output, i.e. for its V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE queue.
*/
static bool is_v4l2_enc_jpeg_device(int fd) {
if (is_hw_jpeg_acc_device(fd)) {
if (is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_JPEG))
return true;
if (is_v4l2_support_format(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
V4L2_PIX_FMT_JPEG_RAW))
return true;
}
return false;
}
#endif // defined(USE_V4L2_CODEC)
#if defined(USE_VAAPI)
static const char* kDRMDevicePattern = "/dev/dri/renderD*";
/* Helper function for detect_video_acc_h264.
* Determine given |fd| is a VAAPI device supports H.264 decoding, i.e.
* it supports one of H.264 profile, has decoding entry point, and output
* YUV420 formats.
*/
static bool is_vaapi_dec_h264_device(int fd) {
VAProfile va_profiles[] = {VAProfileH264Baseline, VAProfileH264Main,
VAProfileH264High,
VAProfileH264ConstrainedBaseline, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointVLD,
VA_RT_FORMAT_YUV420))
return true;
return false;
}
/* Helper function for detect_video_acc_vp8.
* Dtermine given |fd| is a VAAPI device supports VP8 decoding, i.e. it
* supports VP8 profile, has decoding entry point, and output YUV420
* formats.
*/
static bool is_vaapi_dec_vp8_device(int fd) {
#if VA_CHECK_VERSION(0, 35, 0)
VAProfile va_profiles[] = {VAProfileVP8Version0_3, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointVLD,
VA_RT_FORMAT_YUV420))
return true;
#endif
return false;
}
/* Helper function for detect_video_acc_vp9.
* Determine given |fd| is a VAAPI device supports VP9 decoding, i.e. it
* supports VP9 profile 0, has decoding entry point, and can output YUV420
* format.
*/
static bool is_vaapi_dec_vp9_device(int fd) {
#if VA_CHECK_VERSION(0, 37, 1)
VAProfile va_profiles[] = {VAProfileVP9Profile0, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointVLD,
VA_RT_FORMAT_YUV420))
return true;
#endif
return false;
}
/* Helper function for detect_video_acc_vp9_2.
* Determine given |fd| is a VAAPI device supports VP9 decoding Profile 2, i.e.
* it supports VP9 profile 2, has decoding entry point, and can output YUV420
* 10BPP format.
*/
static bool is_vaapi_dec_vp9_2_device(int fd) {
#if VA_CHECK_VERSION(0, 38, 1)
VAProfile va_profiles[] = {VAProfileVP9Profile2, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointVLD,
VA_RT_FORMAT_YUV420_10BPP))
return true;
#endif
return false;
}
/* Helper function for detect_video_acc_enc_h264.
* Determine given |fd| is a VAAPI device supports H.264 encoding, i.e. it
* support one of H.264 profile, has encoding entry point, and input YUV420
* formats.
*/
static bool is_vaapi_enc_h264_device(int fd) {
VAProfile va_profiles[] = {VAProfileH264Baseline, VAProfileH264Main,
VAProfileH264High,
VAProfileH264ConstrainedBaseline, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncSlice,
VA_RT_FORMAT_YUV420) ||
is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncSliceLP,
VA_RT_FORMAT_YUV420)) {
return true;
}
return false;
}
/* Helper function for detect_video_acc_enc_vp8.
* Determine given |fd| is a VAAPI device supports VP8 encoding, i.e. it
* supports one of VP8 profile, has encoding entry point, and input YUV420
* formats.
*/
static bool is_vaapi_enc_vp8_device(int fd) {
#if VA_CHECK_VERSION(0, 35, 0)
VAProfile va_profiles[] = {VAProfileVP8Version0_3, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncSlice,
VA_RT_FORMAT_YUV420) ||
is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncSliceLP,
VA_RT_FORMAT_YUV420)) {
return true;
}
#endif
return false;
}
/* Helper function for detect_video_acc_enc_vp9.
* Determine given |fd| is a VAAPI device supports VP9 encoding, i.e. it
* supports one of VP9 profile, has encoding entry point, and input YUV420
* formats.
*/
static bool is_vaapi_enc_vp9_device(int fd) {
#if VA_CHECK_VERSION(0, 37, 1)
VAProfile va_profiles[] = {VAProfileVP9Profile0, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncSlice,
VA_RT_FORMAT_YUV420) ||
is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncSliceLP,
VA_RT_FORMAT_YUV420)) {
return true;
}
#endif
return false;
}
/* Helper function for detect_jpeg_acc_dec.
* Determine given |fd| is a VAAPI device supports JPEG decoding, i.e. it
* supports JPEG profile, has decoding entry point, and output YUV420
* formats.
*/
static bool is_vaapi_dec_jpeg_device(int fd) {
VAProfile va_profiles[] = {VAProfileJPEGBaseline, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointVLD,
VA_RT_FORMAT_YUV420))
return true;
return false;
}
/* Helper function for detect_jpeg_acc_enc.
* Determine given |fd| is a VAAPI device supports JPEG encoding, i.e. it
* supports JPEG profile, has encoding entry point, and accepts YUV420
* as input.
*/
static bool is_vaapi_enc_jpeg_device(int fd) {
VAProfile va_profiles[] = {VAProfileJPEGBaseline, VAProfileNone};
if (is_vaapi_support_formats(fd, va_profiles, VAEntrypointEncPicture,
VA_RT_FORMAT_YUV420))
return true;
return false;
}
#endif // defined(USE_VAAPI)
/* Determines "hw_video_acc_h264" label. That is, either the VAAPI device
* supports one of H.264 profile, has decoding entry point, and output
* YUV420 formats. Or there is a /dev/video* device supporting H.264
* decoding.
*/
bool detect_video_acc_h264(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_dec_h264_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_dec_h264_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "hw_video_acc_vp8" label. That is, either the VAAPI device
* supports VP8 profile, has decoding entry point, and output YUV420
* formats. Or there is a /dev/video* device supporting VP8 decoding.
*/
bool detect_video_acc_vp8(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_dec_vp8_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_dec_vp8_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "hw_video_acc_vp9" label. That is, either the VAAPI device
* supports VP9 profile, has decoding entry point, and output YUV420
* formats. Or there is a /dev/video* device supporting VP9 decoding.
*/
bool detect_video_acc_vp9(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_dec_vp9_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_dec_vp9_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "hw_video_acc_vp9_2" label. That is, either the VAAPI device
* supports VP9 profile 2, has decoding entry point, and output YUV420 10BPP
* format.
*/
bool detect_video_acc_vp9_2(void) {
#if defined(USE_VAAPI)
return is_any_device(kDRMDevicePattern, is_vaapi_dec_vp9_2_device);
#endif // defined(USE_VAAPI)
return false;
}
/* Determines "hw_video_acc_enc_h264" label. That is, either the VAAPI
* device supports one of H.264 profile, has encoding entry point, and
* input YUV420 formats. Or there is a /dev/video* device supporting H.264
* encoding.
*/
bool detect_video_acc_enc_h264(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_enc_h264_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_enc_h264_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "hw_video_acc_enc_vp8" label. That is, either the VAAPI device
* supports one of VP8 profile, has encoding entry point, and input YUV420
* formats. Or there is a /dev/video* device supporting VP8 encoding.
*/
bool detect_video_acc_enc_vp8(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_enc_vp8_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kVideoDevicePattern, is_v4l2_enc_vp8_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "hw_video_acc_enc_vp9" label. That is, either the VAAPI device
* supports one of VP9 profile, has encoding entry point, and input YUV420
* formats.
*/
bool detect_video_acc_enc_vp9(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_enc_vp9_device))
return true;
#endif // defined(USE_VAAPI)
return false;
}
/* Determines "hw_jpeg_acc_dec" label. That is, either the VAAPI device
* supports jpeg profile, has decoding entry point, and output YUV420
* formats. Or there is a /dev/jpeg* device supporting JPEG decoding.
*/
bool detect_jpeg_acc_dec(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_dec_jpeg_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kJpegDevicePattern, is_v4l2_dec_jpeg_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}
/* Determines "hw_jpeg_acc_enc" label. That is, either the VAAPI device
* supports jpeg profile, has encoding entry point, and output JPEG
* formats. Or there is a /dev/jpeg* device supporting JPEG encoding.
*/
bool detect_jpeg_acc_enc(void) {
#if defined(USE_VAAPI)
if (is_any_device(kDRMDevicePattern, is_vaapi_enc_jpeg_device))
return true;
#endif // defined(USE_VAAPI)
#if defined(USE_V4L2_CODEC)
if (is_any_device(kJpegDevicePattern, is_v4l2_enc_jpeg_device))
return true;
#endif // defined(USE_V4L2_CODEC)
return false;
}