diff mbox series

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

Message ID 20200705154946.401280-3-sw@jkqxz.net
State Accepted
Commit ff14858a6045aa62cd508b4a6c50973a291c91aa
Headers show
Series [FFmpeg-devel,1/4] kmsgrab: Refactor and clean error cases
Related show

Checks

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

Commit Message

Mark Thompson July 5, 2020, 3:49 p.m. UTC
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 mbox series

Patch

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 },