diff mbox series

[FFmpeg-devel,v08.01,1/3] KMSGrab: getfb2 format_modifier if user doesnt specify

Message ID 20200712172102.72406-2-hanishkvc@gmail.com
State New
Headers show
Series kmsgrab, fbtile+hwcontext_drm, VFs | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

hanishkvc July 12, 2020, 5:21 p.m. UTC
If user doesnt specify a format_modifier explicitly, then use GetFB2
to identify the format_modifier of the framebuffer being grabbed.

This is supported on newer linux builds, where xf86drmMode.h has
added support for GetFB2.
---
 Changelog             |  1 +
 configure             |  5 +++++
 libavdevice/kmsgrab.c | 31 ++++++++++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/Changelog b/Changelog
index 1bb9931c0d..20ba03ae8b 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,7 @@  version <next>:
 - AudioToolbox output device
 - MacCaption demuxer
 - PGX decoder
+- kmsgrab GetFB2 format_modifier, if user doesnt specify
 
 
 version 4.3:
diff --git a/configure b/configure
index bdfd731602..3bbc51053c 100755
--- a/configure
+++ b/configure
@@ -2325,6 +2325,7 @@  HAVE_LIST="
     $TYPES_LIST
     makeinfo
     makeinfo_html
+    drm_getfb2
     opencl_d3d11
     opencl_drm_arm
     opencl_drm_beignet
@@ -6653,6 +6654,10 @@  if enabled vaapi; then
     check_type "va/va.h va/va_enc_vp9.h"  "VAEncPictureParameterBufferVP9"
 fi
 
+if enabled libdrm; then
+    check_pkg_config drm_getfb2 libdrm "xf86drm.h xf86drmMode.h" drmModeGetFB2
+fi
+
 if enabled_all opencl libdrm ; then
     check_type "CL/cl_intel.h" "clCreateImageFromFdINTEL_fn" &&
         enable opencl_drm_beignet
diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c
index d0de774871..c7fa2343e3 100644
--- a/libavdevice/kmsgrab.c
+++ b/libavdevice/kmsgrab.c
@@ -239,6 +239,9 @@  static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
     drmModePlaneRes *plane_res = NULL;
     drmModePlane *plane = NULL;
     drmModeFB *fb = NULL;
+#if HAVE_DRM_GETFB2
+    drmModeFB2 *fb2 = NULL;
+#endif
     AVStream *stream;
     int err, i;
 
@@ -364,6 +367,28 @@  static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
         goto fail;
     }
 
+#if HAVE_DRM_GETFB2
+    fb2 = drmModeGetFB2(ctx->hwctx->fd, plane->fb_id);
+    if (!fb2) {
+        err = errno;
+        av_log(avctx, AV_LOG_ERROR, "Failed to get "
+               "framebuffer2 %"PRIu32": %s.\n",
+               plane->fb_id, strerror(err));
+        err = AVERROR(err);
+        goto fail;
+    }
+
+    av_log(avctx, AV_LOG_INFO, "Template framebuffer2 is %"PRIu32": "
+           "%"PRIu32"x%"PRIu32", pixel_format: 0x%"PRIx32", format_modifier: 0x%"PRIx64".\n",
+           fb2->fb_id, fb2->width, fb2->height, fb2->pixel_format, fb2->modifier);
+
+    if (ctx->drm_format_modifier == DRM_FORMAT_MOD_INVALID)
+        ctx->drm_format_modifier  = fb2->modifier;
+#else
+    if (ctx->drm_format_modifier == DRM_FORMAT_MOD_INVALID)
+        ctx->drm_format_modifier  = DRM_FORMAT_MOD_NONE;
+#endif
+
     stream = avformat_new_stream(avctx, NULL);
     if (!stream) {
         err = AVERROR(ENOMEM);
@@ -408,6 +433,10 @@  fail:
         drmModeFreePlane(plane);
     if (fb)
         drmModeFreeFB(fb);
+#if HAVE_DRM_GETFB2
+    if (fb2)
+        drmModeFreeFB2(fb2);
+#endif
 
     return err;
 }
@@ -433,7 +462,7 @@  static const AVOption options[] = {
       { .i64 = AV_PIX_FMT_BGR0 }, 0, UINT32_MAX, FLAGS },
     { "format_modifier", "DRM format modifier for framebuffer",
       OFFSET(drm_format_modifier), AV_OPT_TYPE_INT64,
-      { .i64 = DRM_FORMAT_MOD_NONE }, 0, INT64_MAX, FLAGS },
+      { .i64 = DRM_FORMAT_MOD_INVALID}, 0, INT64_MAX, FLAGS },
     { "crtc_id", "CRTC ID to define capture source",
       OFFSET(source_crtc), AV_OPT_TYPE_INT64,
       { .i64 = 0 }, 0, UINT32_MAX, FLAGS },