[FFmpeg-devel] [PATCH 3/4] kmsgrab: Don't require the user to set framebuffer format

Mark Thompson sw at jkqxz.net
Sun Jul 5 18:49:45 EEST 2020


This is provided by GetFB2, but we still need the option for cases where
that isn't available.
---
 libavdevice/kmsgrab.c | 55 +++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 15 deletions(-)

diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c
index 3e89c3f445..b859f202aa 100644
--- a/libavdevice/kmsgrab.c
+++ b/libavdevice/kmsgrab.c
@@ -405,18 +405,6 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
     AVStream *stream;
     int err, i;
 
-    for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) {
-        if (kmsgrab_formats[i].pixfmt == ctx->format) {
-            ctx->drm_format = kmsgrab_formats[i].drm_format;
-            break;
-        }
-    }
-    if (i >= FF_ARRAY_ELEMS(kmsgrab_formats)) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported format %s.\n",
-               av_get_pix_fmt_name(ctx->format));
-        return AVERROR(EINVAL);
-    }
-
     err = av_hwdevice_ctx_create(&ctx->device_ref, AV_HWDEVICE_TYPE_DRM,
                                  ctx->device_path, NULL, 0);
     if (err < 0) {
@@ -530,9 +518,25 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
             err = AVERROR(EINVAL);
             goto fail;
         }
-        if (ctx->drm_format != fb2->pixel_format) {
+
+        for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) {
+            if (kmsgrab_formats[i].drm_format == fb2->pixel_format) {
+                if (ctx->format != AV_PIX_FMT_NONE &&
+                    ctx->format != kmsgrab_formats[i].pixfmt) {
+                    av_log(avctx, AV_LOG_ERROR, "Framebuffer pixel format "
+                           "%"PRIx32" does not match expected format.\n",
+                           fb2->pixel_format);
+                    err = AVERROR(EINVAL);
+                    goto fail;
+                }
+                ctx->drm_format = fb2->pixel_format;
+                ctx->format     = kmsgrab_formats[i].pixfmt;
+                break;
+            }
+        }
+        if (i == FF_ARRAY_ELEMS(kmsgrab_formats)) {
             av_log(avctx, AV_LOG_ERROR, "Framebuffer pixel format "
-                   "%"PRIx32" does not match expected format.\n",
+                   "%"PRIx32" is not a known supported format.\n",
                    fb2->pixel_format);
             err = AVERROR(EINVAL);
             goto fail;
@@ -547,11 +551,32 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
         } else {
             ctx->drm_format_modifier = fb2->modifier;
         }
+        av_log(avctx, AV_LOG_VERBOSE, "Format is %s, from "
+               "DRM format %"PRIx32" modifier %"PRIx64".\n",
+               av_get_pix_fmt_name(ctx->format),
+               ctx->drm_format, ctx->drm_format_modifier);
+
         ctx->fb2_available = 1;
     }
 #endif
 
     if (!ctx->fb2_available) {
+        if (ctx->format == AV_PIX_FMT_NONE) {
+            // Backward compatibility: assume BGR0 if no format supplied.
+            ctx->format = AV_PIX_FMT_BGR0;
+        }
+        for (i = 0; i < FF_ARRAY_ELEMS(kmsgrab_formats); i++) {
+            if (kmsgrab_formats[i].pixfmt == ctx->format) {
+                ctx->drm_format = kmsgrab_formats[i].drm_format;
+                break;
+            }
+        }
+        if (i >= FF_ARRAY_ELEMS(kmsgrab_formats)) {
+            av_log(avctx, AV_LOG_ERROR, "Unsupported format %s.\n",
+                   av_get_pix_fmt_name(ctx->format));
+            return AVERROR(EINVAL);
+        }
+
         fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id);
         if (!fb) {
             err = errno;
@@ -642,7 +667,7 @@ static const AVOption options[] = {
       { .str = "/dev/dri/card0" }, 0, 0, FLAGS },
     { "format", "Pixel format for framebuffer",
       OFFSET(format), AV_OPT_TYPE_PIXEL_FMT,
-      { .i64 = AV_PIX_FMT_BGR0 }, 0, UINT32_MAX, FLAGS },
+      { .i64 = AV_PIX_FMT_NONE }, -1, INT32_MAX, FLAGS },
     { "format_modifier", "DRM format modifier for framebuffer",
       OFFSET(drm_format_modifier), AV_OPT_TYPE_INT64,
       { .i64 = DRM_FORMAT_MOD_INVALID }, 0, INT64_MAX, FLAGS },
-- 
2.27.0



More information about the ffmpeg-devel mailing list