X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavdevice%2Fkmsgrab.c;h=6cc305b16f3c54312a82f166bb2422081529b0ff;hb=4217e091fefe540a0aab767e4a0a2454808cb4aa;hp=edfa26490942042eee92535eb43e1cda4c589584;hpb=ff14858a6045aa62cd508b4a6c50973a291c91aa;p=ffmpeg diff --git a/libavdevice/kmsgrab.c b/libavdevice/kmsgrab.c index edfa2649094..6cc305b16f3 100644 --- a/libavdevice/kmsgrab.c +++ b/libavdevice/kmsgrab.c @@ -160,6 +160,7 @@ static int kmsgrab_get_fb2(AVFormatContext *avctx, KMSGrabContext *ctx = avctx->priv_data; drmModeFB2 *fb; int err, i, nb_objects; + uint64_t modifier = ctx->drm_format_modifier; fb = drmModeGetFB2(ctx->hwctx->fd, plane->fb_id); if (!fb) { @@ -175,13 +176,6 @@ static int kmsgrab_get_fb2(AVFormatContext *avctx, err = AVERROR(EIO); goto fail; } - if (fb->modifier != ctx->drm_format_modifier) { - av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer " - "format modifier changed: now %"PRIx64".\n", - ctx->plane_id, fb->modifier); - err = AVERROR(EIO); - goto fail; - } if (fb->width != ctx->width || fb->height != ctx->height) { av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer " "dimensions changed: now %"PRIu32"x%"PRIu32".\n", @@ -195,6 +189,9 @@ static int kmsgrab_get_fb2(AVFormatContext *avctx, goto fail; } + if (fb->flags & DRM_MODE_FB_MODIFIERS) + modifier = fb->modifier; + *desc = (AVDRMFrameDescriptor) { .nb_layers = 1, .layers[0] = { @@ -243,7 +240,7 @@ static int kmsgrab_get_fb2(AVFormatContext *avctx, desc->objects[obj] = (AVDRMObjectDescriptor) { .fd = fd, .size = size, - .format_modifier = fb->modifier, + .format_modifier = modifier, }; desc->layers[0].planes[i] = (AVDRMPlaneDescriptor) { .object_index = obj, @@ -271,7 +268,7 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) int64_t now; int err; - now = av_gettime(); + now = av_gettime_relative(); if (ctx->frame_last) { int64_t delay; while (1) { @@ -279,10 +276,11 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt) if (delay <= 0) break; av_usleep(delay); - now = av_gettime(); + now = av_gettime_relative(); } } ctx->frame_last = now; + now = av_gettime(); plane = drmModeGetPlane(ctx->hwctx->fd, ctx->plane_id); if (!plane) { @@ -367,6 +365,7 @@ static const struct { enum AVPixelFormat pixfmt; uint32_t drm_format; } kmsgrab_formats[] = { + // Monochrome. #ifdef DRM_FORMAT_R8 { AV_PIX_FMT_GRAY8, DRM_FORMAT_R8 }, #endif @@ -374,6 +373,7 @@ static const struct { { AV_PIX_FMT_GRAY16LE, DRM_FORMAT_R16 }, { AV_PIX_FMT_GRAY16BE, DRM_FORMAT_R16 | DRM_FORMAT_BIG_ENDIAN }, #endif + // <8-bit RGB. { AV_PIX_FMT_BGR8, DRM_FORMAT_BGR233 }, { AV_PIX_FMT_RGB555LE, DRM_FORMAT_XRGB1555 }, { AV_PIX_FMT_RGB555BE, DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN }, @@ -383,6 +383,7 @@ static const struct { { AV_PIX_FMT_RGB565BE, DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN }, { AV_PIX_FMT_BGR565LE, DRM_FORMAT_BGR565 }, { AV_PIX_FMT_BGR565BE, DRM_FORMAT_BGR565 | DRM_FORMAT_BIG_ENDIAN }, + // 8-bit RGB. { AV_PIX_FMT_RGB24, DRM_FORMAT_RGB888 }, { AV_PIX_FMT_BGR24, DRM_FORMAT_BGR888 }, { AV_PIX_FMT_0RGB, DRM_FORMAT_BGRX8888 }, @@ -393,6 +394,12 @@ static const struct { { AV_PIX_FMT_ABGR, DRM_FORMAT_RGBA8888 }, { AV_PIX_FMT_RGBA, DRM_FORMAT_ABGR8888 }, { AV_PIX_FMT_BGRA, DRM_FORMAT_ARGB8888 }, + // 10-bit RGB. + { AV_PIX_FMT_X2RGB10LE, DRM_FORMAT_XRGB2101010 }, + { AV_PIX_FMT_X2RGB10BE, DRM_FORMAT_XRGB2101010 | DRM_FORMAT_BIG_ENDIAN }, + // 8-bit YUV 4:2:0. + { AV_PIX_FMT_NV12, DRM_FORMAT_NV12 }, + // 8-bit YUV 4:2:2. { AV_PIX_FMT_YUYV422, DRM_FORMAT_YUYV }, { AV_PIX_FMT_YVYU422, DRM_FORMAT_YVYU }, { AV_PIX_FMT_UYVY422, DRM_FORMAT_UYVY }, @@ -548,15 +555,18 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx) err = AVERROR(EINVAL); goto fail; } - if (ctx->drm_format_modifier != DRM_FORMAT_MOD_INVALID && - ctx->drm_format_modifier != fb2->modifier) { - av_log(avctx, AV_LOG_ERROR, "Framebuffer format modifier " - "%"PRIx64" does not match expected modifier.\n", - fb2->modifier); - err = AVERROR(EINVAL); - goto fail; - } else { - ctx->drm_format_modifier = fb2->modifier; + + if (fb2->flags & DRM_MODE_FB_MODIFIERS) { + if (ctx->drm_format_modifier != DRM_FORMAT_MOD_INVALID && + ctx->drm_format_modifier != fb2->modifier) { + av_log(avctx, AV_LOG_ERROR, "Framebuffer format modifier " + "%"PRIx64" does not match expected modifier.\n", + fb2->modifier); + err = AVERROR(EINVAL); + goto fail; + } else { + ctx->drm_format_modifier = fb2->modifier; + } } av_log(avctx, AV_LOG_VERBOSE, "Format is %s, from " "DRM format %"PRIx32" modifier %"PRIx64".\n",