From b2944629fafc722b5f284f9c5f739ee6fe7f0996 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 12 Oct 2018 16:11:06 -0300 Subject: [PATCH 1/3] Add support for dynamic detection of supported codecs H.264 and H.265 support is still not supported upstream, so it makes sense to autodetect each codec and only enable those that are supported. Signed-off-by: Ezequiel Garcia --- configure.ac | 42 ++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 15 +++++++++++++-- src/config.c | 9 +++++++++ src/context.c | 9 +++++++++ src/picture.c | 24 ++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index aeb7dde..3d333fb 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,45 @@ if test "$USE_DRM" = "yes"; then CPPFLAGS="$saved_CPPFLAGS" fi +AC_MSG_CHECKING([for MPEG2 support]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +#ifndef V4L2_PIX_FMT_MPEG2_SLICE +# error macro not defined +#endif +]])], [WITH_MPEG2="yes"], [WITH_MPEG2="no"]) +AC_MSG_RESULT([$WITH_MPEG2]) +AM_CONDITIONAL([WITH_MPEG2], [test "$WITH_MPEG2" = "yes"]) +if test "$WITH_MPEG2" = "yes"; then + AC_DEFINE([WITH_MPEG2], [1], [MPEG2 support detected]) +fi + +AC_MSG_CHECKING([for H.264 support]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +#ifndef V4L2_PIX_FMT_H264_SLICE +# error macro not defined +#endif +]])], [WITH_H264="yes"], [WITH_H264="no"]) +AC_MSG_RESULT([$WITH_H264]) +AM_CONDITIONAL([WITH_H264], [test "$WITH_H264" = "yes"]) +if test "$WITH_H264" = "yes"; then + AC_DEFINE([WITH_H264], [1], [H.264 support detected]) +fi + +AC_MSG_CHECKING([for H.265 support]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +#ifndef V4L2_PIX_FMT_HEVC_SLICE +# error macro not defined +#endif +]])], [WITH_H265="yes"], [WITH_H265="no"]) +AC_MSG_RESULT([$WITH_H265]) +AM_CONDITIONAL([WITH_H265], [test "$WITH_H265" = "yes"]) +if test "$WITH_H265" = "yes"; then + AC_DEFINE([WITH_H265], [1], [H.265 support detected]) +fi + VA_VERSION=`$PKG_CONFIG --modversion libva` VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1` VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2` @@ -109,4 +148,7 @@ echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR echo VA-API drivers path .............. : $LIBVA_DRIVERS_PATH +echo H.264 support .................... : $WITH_H264 +echo H.265 support .................... : $WITH_H265 +echo MPEG2 support .................... : $WITH_MPEG2 echo diff --git a/src/Makefile.am b/src/Makefile.am index 19cafbb..ef7b092 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,8 +5,19 @@ backend_ldflags = -module -avoid-version -no-undefined -Wl,--no-undefined backend_libs = -lpthread -ldl $(DRM_LIBS) $(LIBVA_DEPS_LIBS) backend_c = request.c object_heap.c config.c surface.c context.c buffer.c \ - mpeg2.c picture.c subpicture.c image.c v4l2.c video.c media.c utils.c \ - h264.c h265.c + picture.c subpicture.c image.c v4l2.c video.c media.c utils.c + +if WITH_MPEG2 +backend_c += mpeg2.c +endif + +if WITH_H264 +backend_c += h264.c +endif + +if WITH_H265 +backend_c += h265.c +endif backend_s = tiled_yuv.S diff --git a/src/config.c b/src/config.c index c76240d..6c52fb9 100644 --- a/src/config.c +++ b/src/config.c @@ -36,6 +36,8 @@ #include "utils.h" #include "v4l2.h" +#include "autoconfig.h" + VAStatus RequestCreateConfig(VADriverContextP context, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attributes, int attributes_count, @@ -111,6 +113,7 @@ VAStatus RequestQueryConfigProfiles(VADriverContextP context, unsigned int index = 0; bool found; +#ifdef WITH_MPEG2 found = v4l2_find_format(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_PIX_FMT_MPEG2_SLICE); @@ -118,7 +121,10 @@ VAStatus RequestQueryConfigProfiles(VADriverContextP context, profiles[index++] = VAProfileMPEG2Simple; profiles[index++] = VAProfileMPEG2Main; } +#endif +#ifdef WITH_H264 + found = v4l2_find_format(driver_data->video_fd, found = v4l2_find_format(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_PIX_FMT_H264_SLICE); @@ -129,12 +135,15 @@ VAStatus RequestQueryConfigProfiles(VADriverContextP context, profiles[index++] = VAProfileH264MultiviewHigh; profiles[index++] = VAProfileH264StereoHigh; } +#endif +#ifdef WITH_H265 found = v4l2_find_format(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_PIX_FMT_HEVC_SLICE); if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 1)) profiles[index++] = VAProfileHEVCMain; +#endif *profiles_count = index; diff --git a/src/context.c b/src/context.c index 943887f..70efd82 100644 --- a/src/context.c +++ b/src/context.c @@ -41,6 +41,8 @@ #include "utils.h" #include "v4l2.h" +#include "autoconfig.h" + VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id, int picture_width, int picture_height, int flags, VASurfaceID *surfaces_ids, int surfaces_count, @@ -86,11 +88,15 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id, memset(&context_object->dpb, 0, sizeof(context_object->dpb)); switch (config_object->profile) { + +#ifdef WITH_MPEG2 case VAProfileMPEG2Simple: case VAProfileMPEG2Main: pixelformat = V4L2_PIX_FMT_MPEG2_SLICE; break; +#endif +#ifdef WITH_H264 case VAProfileH264Main: case VAProfileH264High: case VAProfileH264ConstrainedBaseline: @@ -98,10 +104,13 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id, case VAProfileH264StereoHigh: pixelformat = V4L2_PIX_FMT_H264_SLICE; break; +#endif +#ifdef WITH_H265 case VAProfileHEVCMain: pixelformat = V4L2_PIX_FMT_HEVC_SLICE; break; +#endif default: status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; diff --git a/src/picture.c b/src/picture.c index 3490820..9969d84 100644 --- a/src/picture.c +++ b/src/picture.c @@ -47,6 +47,8 @@ #include "utils.h" #include "v4l2.h" +#include "autoconfig.h" + static VAStatus codec_store_buffer(struct request_data *driver_data, VAProfile profile, struct object_surface *surface_object, @@ -71,13 +73,16 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, case VAPictureParameterBufferType: switch (profile) { +#ifdef WITH_MPEG2 case VAProfileMPEG2Simple: case VAProfileMPEG2Main: memcpy(&surface_object->params.mpeg2.picture, buffer_object->data, sizeof(surface_object->params.mpeg2.picture)); break; +#endif +#ifdef WITH_H264 case VAProfileH264Main: case VAProfileH264High: case VAProfileH264ConstrainedBaseline: @@ -87,12 +92,15 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, buffer_object->data, sizeof(surface_object->params.h264.picture)); break; +#endif +#ifdef WITH_H265 case VAProfileHEVCMain: memcpy(&surface_object->params.h265.picture, buffer_object->data, sizeof(surface_object->params.h265.picture)); break; +#endif default: break; @@ -101,6 +109,7 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, case VASliceParameterBufferType: switch (profile) { +#ifdef WITH_H264 case VAProfileH264Main: case VAProfileH264High: case VAProfileH264ConstrainedBaseline: @@ -110,12 +119,15 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, buffer_object->data, sizeof(surface_object->params.h264.slice)); break; +#endif +#ifdef WITH_H265 case VAProfileHEVCMain: memcpy(&surface_object->params.h265.slice, buffer_object->data, sizeof(surface_object->params.h265.slice)); break; +#endif default: break; @@ -124,6 +136,7 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, case VAIQMatrixBufferType: switch (profile) { +#ifdef WITH_MPEG2 case VAProfileMPEG2Simple: case VAProfileMPEG2Main: memcpy(&surface_object->params.mpeg2.iqmatrix, @@ -131,7 +144,9 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, sizeof(surface_object->params.mpeg2.iqmatrix)); surface_object->params.mpeg2.iqmatrix_set = true; break; +#endif +#ifdef WITH_H264 case VAProfileH264Main: case VAProfileH264High: case VAProfileH264ConstrainedBaseline: @@ -141,13 +156,16 @@ static VAStatus codec_store_buffer(struct request_data *driver_data, buffer_object->data, sizeof(surface_object->params.h264.matrix)); break; +#endif +#ifdef WITH_H265 case VAProfileHEVCMain: memcpy(&surface_object->params.h265.iqmatrix, buffer_object->data, sizeof(surface_object->params.h265.iqmatrix)); surface_object->params.h265.iqmatrix_set = true; break; +#endif default: break; @@ -169,13 +187,16 @@ static VAStatus codec_set_controls(struct request_data *driver_data, int rc; switch (profile) { +#ifdef WITH_MPEG2 case VAProfileMPEG2Simple: case VAProfileMPEG2Main: rc = mpeg2_set_controls(driver_data, context, surface_object); if (rc < 0) return VA_STATUS_ERROR_OPERATION_FAILED; break; +#endif +#ifdef WITH_H264 case VAProfileH264Main: case VAProfileH264High: case VAProfileH264ConstrainedBaseline: @@ -185,12 +206,15 @@ static VAStatus codec_set_controls(struct request_data *driver_data, if (rc < 0) return VA_STATUS_ERROR_OPERATION_FAILED; break; +#endif +#ifdef WITH_H265 case VAProfileHEVCMain: rc = h265_set_controls(driver_data, context, surface_object); if (rc < 0) return VA_STATUS_ERROR_OPERATION_FAILED; break; +#endif default: return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; From 2c27ec37949f412752edfa78e6698442e8a1d760 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 12 Oct 2018 16:13:05 -0300 Subject: [PATCH 2/3] Add settable attributes to pixelformats Apparently, pixelformats are expected to be settable although the reason is not exactly clear to me. However, intel vaapi driver sets all its pixelformats as settable, and gstreamer-vaapi expects that as well. Signed-off-by: Ezequiel Garcia --- src/surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/surface.c b/src/surface.c index ab06619..2a5bb23 100644 --- a/src/surface.c +++ b/src/surface.c @@ -342,7 +342,7 @@ VAStatus RequestQuerySurfaceAttributes(VADriverContextP context, memset(attributes_list, 0, attributes_list_size); attributes_list[i].type = VASurfaceAttribPixelFormat; - attributes_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE; + attributes_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE; attributes_list[i].value.type = VAGenericValueTypeInteger; attributes_list[i].value.value.i = VA_FOURCC_NV12; i++; From 59cd32bc42af4eeaa61697615775d1dfc8ad7b4f Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 12 Oct 2018 16:42:02 -0300 Subject: [PATCH 3/3] Fix single planar QBUF ioctl Commit 7ff2543e64e1e ("Add support for the single-planar V4L2 API") missed the VIDIOC_QBUF bytesused parameter. The kernel will warn loudly if bytesused is not properly defined for an OUTPUT buffer. Signed-off-by: Ezequiel Garcia --- src/v4l2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/v4l2.c b/src/v4l2.c index a76dadf..250b054 100644 --- a/src/v4l2.c +++ b/src/v4l2.c @@ -348,7 +348,10 @@ int v4l2_queue_buffer(int video_fd, int request_fd, unsigned int type, buffer.m.planes = planes; for (i = 0; i < buffers_count; i++) - buffer.m.planes[i].bytesused = size; + if (v4l2_type_is_mplane(type)) + buffer.m.planes[i].bytesused = size; + else + buffer.bytesused = size; if (request_fd >= 0) { buffer.flags = V4L2_BUF_FLAG_REQUEST_FD;