25#include <drm_fourcc.h>
28#include <xf86drmMode.h>
31#ifndef DRM_FORMAT_MOD_INVALID
32#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
81 for (
i = 0;
i <
desc->nb_objects;
i++)
102 fb = drmModeGetFB(
ctx->hwctx->fd, plane->fb_id);
106 "%"PRIu32
": %s.\n", plane->fb_id, strerror(err));
110 if (fb->width !=
ctx->width || fb->height !=
ctx->height) {
112 "dimensions changed: now %"PRIu32
"x%"PRIu32
".\n",
113 ctx->plane_id, fb->width, fb->height);
123 err = drmPrimeHandleToFD(
ctx->hwctx->fd, fb->handle, O_RDONLY, &fd);
127 "framebuffer handle: %s.\n", strerror(err));
136 .size = fb->height * fb->pitch,
137 .format_modifier =
ctx->drm_format_modifier,
141 .format =
ctx->drm_format,
157#if HAVE_LIBDRM_GETFB2
164 int err,
i, nb_objects;
165 uint64_t modifier =
ctx->drm_format_modifier;
167 fb = drmModeGetFB2(
ctx->hwctx->fd, plane->fb_id);
171 "%"PRIu32
": %s.\n", plane->fb_id, strerror(err));
174 if (fb->pixel_format !=
ctx->drm_format) {
176 "format changed: now %"PRIx32
".\n",
177 ctx->plane_id, fb->pixel_format);
181 if (fb->width !=
ctx->width || fb->height !=
ctx->height) {
183 "dimensions changed: now %"PRIu32
"x%"PRIu32
".\n",
184 ctx->plane_id, fb->width, fb->height);
188 if (!fb->handles[0]) {
194 if (fb->flags & DRM_MODE_FB_MODIFIERS)
195 modifier = fb->modifier;
200 .format =
ctx->drm_format,
205 for (
i = 0;
i < 4 && fb->handles[
i];
i++) {
209 size = fb->offsets[
i] + fb->height * fb->pitches[
i];
211 for (j = 0; j <
i; j++) {
212 if (fb->handles[
i] == fb->handles[j]) {
218 obj =
desc->layers[0].planes[j].object_index;
225 .offset = fb->offsets[
i],
226 .pitch = fb->pitches[
i],
231 err = drmPrimeHandleToFD(
ctx->hwctx->fd, fb->handles[
i],
236 "framebuffer handle: %s.\n", strerror(err));
245 .format_modifier = modifier,
249 .offset = fb->offsets[
i],
250 .pitch = fb->pitches[
i],
254 desc->nb_objects = nb_objects;
255 desc->layers[0].nb_planes =
i;
267 drmModePlane *plane =
NULL;
274 if (
ctx->frame_last) {
277 delay =
ctx->frame_last +
ctx->frame_delay - now;
284 ctx->frame_last = now;
287 plane = drmModeGetPlane(
ctx->hwctx->fd,
ctx->plane_id);
291 "%"PRIu32
": %s.\n",
ctx->plane_id, strerror(err));
297 "an associated framebuffer.\n",
ctx->plane_id);
308#if HAVE_LIBDRM_GETFB2
309 if (
ctx->fb2_available)
310 err = kmsgrab_get_fb2(avctx, plane,
desc);
324 if (!
frame->hw_frames_ctx) {
331 if (!
frame->buf[0]) {
341 drmModeFreePlane(plane);
353 pkt->size =
sizeof(*frame);
360 drmModeFreePlane(plane);
413 drmModePlaneRes *plane_res =
NULL;
414 drmModePlane *plane =
NULL;
415 drmModeFB *fb =
NULL;
416#if HAVE_LIBDRM_GETFB2
417 drmModeFB2 *fb2 =
NULL;
431 err = drmSetClientCap(
ctx->hwctx->fd,
432 DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
435 "capability: primary planes will not be usable.\n");
438 if (
ctx->source_plane > 0) {
439 plane = drmModeGetPlane(
ctx->hwctx->fd,
ctx->source_plane);
443 "%s.\n",
ctx->source_plane, strerror(err));
448 if (plane->fb_id == 0) {
450 "an attached framebuffer.\n",
ctx->source_plane);
455 plane_res = drmModeGetPlaneResources(
ctx->hwctx->fd);
459 "resources: %s.\n", strerror(err));
464 for (
i = 0;
i < plane_res->count_planes;
i++) {
465 plane = drmModeGetPlane(
ctx->hwctx->fd,
466 plane_res->planes[
i]);
470 "plane %"PRIu32
": %s.\n",
471 plane_res->planes[
i], strerror(err));
476 "CRTC %"PRIu32
" FB %"PRIu32
".\n",
477 plane->plane_id, plane->crtc_id, plane->fb_id);
479 if ((
ctx->source_crtc > 0 &&
480 plane->crtc_id !=
ctx->source_crtc) ||
484 drmModeFreePlane(plane);
492 if (
i == plane_res->count_planes) {
493 if (
ctx->source_crtc > 0) {
495 "CRTC %"PRId64
".\n",
ctx->source_crtc);
504 "locate framebuffers.\n", plane->plane_id);
507 ctx->plane_id = plane->plane_id;
509#if HAVE_LIBDRM_GETFB2
510 fb2 = drmModeGetFB2(
ctx->hwctx->fd, plane->fb_id);
511 if (!fb2 && errno == ENOSYS) {
513 "will try to use GETFB instead.\n");
517 "framebuffer %"PRIu32
": %s.\n",
518 plane->fb_id, strerror(err));
523 "%"PRIu32
": %"PRIu32
"x%"PRIu32
" "
524 "format %"PRIx32
" modifier %"PRIx64
" flags %"PRIx32
".\n",
525 fb2->fb_id, fb2->width, fb2->height,
526 fb2->pixel_format, fb2->modifier, fb2->flags);
528 ctx->width = fb2->width;
529 ctx->height = fb2->height;
531 if (!fb2->handles[0]) {
533 "maybe you need some additional capabilities?\n");
543 "%"PRIx32
" does not match expected format.\n",
548 ctx->drm_format = fb2->pixel_format;
555 "%"PRIx32
" is not a known supported format.\n",
561 if (fb2->flags & DRM_MODE_FB_MODIFIERS) {
563 ctx->drm_format_modifier != fb2->modifier) {
565 "%"PRIx64
" does not match expected modifier.\n",
570 ctx->drm_format_modifier = fb2->modifier;
574 "DRM format %"PRIx32
" modifier %"PRIx64
".\n",
576 ctx->drm_format,
ctx->drm_format_modifier);
578 ctx->fb2_available = 1;
582 if (!
ctx->fb2_available) {
599 fb = drmModeGetFB(
ctx->hwctx->fd, plane->fb_id);
603 "framebuffer %"PRIu32
": %s.\n",
604 plane->fb_id, strerror(err));
610 "%"PRIu32
"x%"PRIu32
" %"PRIu32
"bpp %"PRIu32
"b depth.\n",
611 fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth);
613 ctx->width = fb->width;
614 ctx->height = fb->height;
618 "maybe you need some additional capabilities?\n");
639 if (!
ctx->frames_ref) {
646 ctx->frames->sw_format =
ctx->format,
647 ctx->frames->width =
ctx->width;
648 ctx->frames->height =
ctx->height;
653 "hardware frames context: %d.\n", err);
662 drmModeFreePlaneResources(plane_res);
663 drmModeFreePlane(plane);
665#if HAVE_LIBDRM_GETFB2
681#define OFFSET(x) offsetof(KMSGrabContext, x)
682#define FLAGS AV_OPT_FLAG_DECODING_PARAM
684 {
"device",
"DRM device path",
686 { .str =
"/dev/dri/card0" }, 0, 0,
FLAGS },
687 {
"format",
"Pixel format for framebuffer",
690 {
"format_modifier",
"DRM format modifier for framebuffer",
693 {
"crtc_id",
"CRTC ID to define capture source",
695 { .i64 = 0 }, 0, UINT32_MAX,
FLAGS },
696 {
"plane_id",
"Plane ID to define capture source",
698 { .i64 = 0 }, 0, UINT32_MAX,
FLAGS },
699 {
"framerate",
"Framerate to capture at",
701 { .dbl = 30.0 }, 0, 1000,
FLAGS },
706 .class_name =
"kmsgrab indev",
static const char *const format[]
const FFInputFormat ff_kmsgrab_demuxer
static AVFormatContext * ctx
static av_cold void close(AVCodecParserContext *s)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define i(width, name, range_min, range_max)
static int read_header(FFV1Context *f, RangeCoder *c)
@ AV_OPT_TYPE_PIXEL_FMT
Underlying C type is enum AVPixelFormat.
@ AV_OPT_TYPE_RATIONAL
Underlying C type is AVRational.
@ AV_OPT_TYPE_INT64
Underlying C type is int64_t.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
@ AV_CODEC_ID_WRAPPED_AVFRAME
Passthrough codec, AVFrames wrapped in AVPacket.
#define AV_PKT_FLAG_TRUSTED
The packet comes from a trusted source.
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define LIBAVUTIL_VERSION_INT
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
API-specific header for AV_HWDEVICE_TYPE_DRM.
static const AVClass kmsgrab_class
static int kmsgrab_get_fb(AVFormatContext *avctx, drmModePlane *plane, AVDRMFrameDescriptor *desc)
static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
static av_cold int kmsgrab_read_close(AVFormatContext *avctx)
static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt)
enum AVPixelFormat pixfmt
static void kmsgrab_free_desc(void *opaque, uint8_t *data)
#define DRM_FORMAT_MOD_INVALID
static void kmsgrab_free_frame(void *opaque, uint8_t *data)
static const struct @053221011121105173267270047366031112316067140344 kmsgrab_formats[]
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static av_cold int read_close(AVFormatContext *ctx)
@ AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
Memory handling functions.
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_BGR565BE
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
@ AV_PIX_FMT_YVYU422
packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
@ AV_PIX_FMT_DRM_PRIME
DRM-managed buffers exposed through PRIME buffer sharing.
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
@ AV_PIX_FMT_RGB565LE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
@ AV_PIX_FMT_RGB555LE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined
@ AV_PIX_FMT_BGR555BE
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined
@ AV_PIX_FMT_X2RGB10LE
packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
@ AV_PIX_FMT_GRAY16LE
Y , 16bpp, little-endian.
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
@ AV_PIX_FMT_BGR555LE
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
@ AV_PIX_FMT_BGR565LE
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
@ AV_PIX_FMT_X2RGB10BE
packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Describe the class of an AVClass context structure.
int height
The height of the video frame in pixels.
int width
The width of the video frame in pixels.
enum AVMediaType codec_type
General type of the encoded data.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
void * priv_data
Format private data.
This structure describes decoded (raw) audio or video data.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
This struct describes a set or pool of "hardware" frames (i.e.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int64_t drm_format_modifier
AVHWFramesContext * frames
AVHWDeviceContext * device
enum AVPixelFormat format
AVDRMDeviceContext * hwctx
int av_usleep(unsigned usec)
Sleep for a period of time.
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
int64_t av_gettime(void)
Get the current time in microseconds.