Go to the documentation of this file.
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++)
82 close(
desc->objects[
i].fd);
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++) {
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);
360 drmModeFreePlane(plane);
366 static const struct {
374 #ifdef DRM_FORMAT_R16
413 drmModePlaneRes *plane_res =
NULL;
414 drmModePlane *plane =
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 },
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
#define AV_LOG_WARNING
Something somehow does not look correct.
AVPixelFormat
Pixel format.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
enum AVMediaType codec_type
General type of the encoded data.
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
This structure describes decoded (raw) audio or video data.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
@ AV_PIX_FMT_DRM_PRIME
DRM-managed buffers exposed through PRIME buffer sharing.
static int kmsgrab_get_fb(AVFormatContext *avctx, drmModePlane *plane, AVDRMFrameDescriptor *desc)
#define AV_LOG_VERBOSE
Detailed information.
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
@ AV_OPT_TYPE_RATIONAL
Underlying C type is AVRational.
AVHWFramesContext * frames
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
static av_cold int kmsgrab_read_close(AVFormatContext *avctx)
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
static av_cold int read_close(AVFormatContext *ctx)
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_ARRAY_ELEMS(a)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
#define DRM_FORMAT_MOD_INVALID
@ AV_OPT_TYPE_INT64
Underlying C type is int64_t.
int64_t drm_format_modifier
static const struct @300 kmsgrab_formats[]
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
int av_usleep(unsigned usec)
Sleep for a period of time.
@ AV_CODEC_ID_WRAPPED_AVFRAME
Passthrough codec, AVFrames wrapped in AVPacket.
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
AVCodecParameters * codecpar
Codec parameters associated with this stream.
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
@ AV_PIX_FMT_RGB565LE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
#define LIBAVUTIL_VERSION_INT
static int read_header(FFV1Context *f)
Describe the class of an AVClass context structure.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Rational number (pair of numerator and denominator).
@ AV_PIX_FMT_BGR565LE
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
const char * av_default_item_name(void *ptr)
Return the context name.
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
@ AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_BGR555BE
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
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.
@ AV_PIX_FMT_X2RGB10LE
packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
const FFInputFormat ff_kmsgrab_demuxer
enum AVPixelFormat format
AVDRMDeviceContext * hwctx
@ AV_PIX_FMT_BGR565BE
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
int flags
A combination of AV_PKT_FLAG values.
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
#define AV_LOG_INFO
Standard information.
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
@ AV_PIX_FMT_RGB555LE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined
#define i(width, name, range_min, range_max)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
static void kmsgrab_free_frame(void *opaque, uint8_t *data)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
@ AV_PIX_FMT_X2RGB10BE
packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined
This struct describes a set or pool of "hardware" frames (i.e.
@ AV_PIX_FMT_YVYU422
packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb
enum AVPixelFormat pixfmt
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
@ 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...
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
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.
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
static const AVOption options[]
@ AV_OPT_TYPE_PIXEL_FMT
Underlying C type is enum AVPixelFormat.
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
int64_t av_gettime(void)
Get the current time in microseconds.
@ AV_PIX_FMT_GRAY16LE
Y , 16bpp, little-endian.
A reference to a data buffer.
@ AV_PIX_FMT_BGR555LE
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined
static void kmsgrab_free_desc(void *opaque, uint8_t *data)
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
This structure stores compressed data.
AVHWDeviceContext * device
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
static const AVClass kmsgrab_class
@ 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...
#define AV_PKT_FLAG_TRUSTED
The packet comes from a trusted source.
void * priv_data
Format private data.
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.