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)
79 for (
i = 0;
i <
desc->nb_objects;
i++)
80 close(
desc->objects[
i].fd);
100 fb = drmModeGetFB(
ctx->hwctx->fd, plane->fb_id);
104 "%"PRIu32
": %s.\n", plane->fb_id, strerror(err));
108 if (
fb->width !=
ctx->width ||
fb->height !=
ctx->height) {
110 "dimensions changed: now %"PRIu32
"x%"PRIu32
".\n",
111 ctx->plane_id,
fb->width,
fb->height);
121 err = drmPrimeHandleToFD(
ctx->hwctx->fd,
fb->handle, O_RDONLY, &fd);
125 "framebuffer handle: %s.\n", strerror(err));
134 .size =
fb->height *
fb->pitch,
135 .format_modifier =
ctx->drm_format_modifier,
139 .format =
ctx->drm_format,
155 #if HAVE_LIBDRM_GETFB2
162 int err,
i, nb_objects;
163 uint64_t modifier =
ctx->drm_format_modifier;
165 fb = drmModeGetFB2(
ctx->hwctx->fd, plane->fb_id);
169 "%"PRIu32
": %s.\n", plane->fb_id, strerror(err));
172 if (
fb->pixel_format !=
ctx->drm_format) {
174 "format changed: now %"PRIx32
".\n",
175 ctx->plane_id,
fb->pixel_format);
179 if (
fb->width !=
ctx->width ||
fb->height !=
ctx->height) {
181 "dimensions changed: now %"PRIu32
"x%"PRIu32
".\n",
182 ctx->plane_id,
fb->width,
fb->height);
186 if (!
fb->handles[0]) {
192 if (
fb->flags & DRM_MODE_FB_MODIFIERS)
193 modifier =
fb->modifier;
198 .format =
ctx->drm_format,
203 for (
i = 0;
i < 4 &&
fb->handles[
i];
i++) {
209 for (j = 0; j <
i; j++) {
210 if (
fb->handles[
i] ==
fb->handles[j]) {
216 obj =
desc->layers[0].planes[j].object_index;
223 .offset =
fb->offsets[
i],
224 .pitch =
fb->pitches[
i],
229 err = drmPrimeHandleToFD(
ctx->hwctx->fd,
fb->handles[
i],
234 "framebuffer handle: %s.\n", strerror(err));
243 .format_modifier = modifier,
247 .offset =
fb->offsets[
i],
248 .pitch =
fb->pitches[
i],
252 desc->nb_objects = nb_objects;
253 desc->layers[0].nb_planes =
i;
265 drmModePlane *plane =
NULL;
272 if (
ctx->frame_last) {
275 delay =
ctx->frame_last +
ctx->frame_delay - now;
282 ctx->frame_last = now;
285 plane = drmModeGetPlane(
ctx->hwctx->fd,
ctx->plane_id);
289 "%"PRIu32
": %s.\n",
ctx->plane_id, strerror(err));
295 "an associated framebuffer.\n",
ctx->plane_id);
306 #if HAVE_LIBDRM_GETFB2
307 if (
ctx->fb2_available)
308 err = kmsgrab_get_fb2(avctx, plane,
desc);
322 if (!
frame->hw_frames_ctx) {
329 if (!
frame->buf[0]) {
339 drmModeFreePlane(plane);
358 drmModeFreePlane(plane);
364 static const struct {
372 #ifdef DRM_FORMAT_R16
411 drmModePlaneRes *plane_res =
NULL;
412 drmModePlane *plane =
NULL;
414 #if HAVE_LIBDRM_GETFB2
415 drmModeFB2 *fb2 =
NULL;
429 err = drmSetClientCap(
ctx->hwctx->fd,
430 DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
433 "capability: primary planes will not be usable.\n");
436 if (
ctx->source_plane > 0) {
437 plane = drmModeGetPlane(
ctx->hwctx->fd,
ctx->source_plane);
441 "%s.\n",
ctx->source_plane, strerror(err));
446 if (plane->fb_id == 0) {
448 "an attached framebuffer.\n",
ctx->source_plane);
453 plane_res = drmModeGetPlaneResources(
ctx->hwctx->fd);
457 "resources: %s.\n", strerror(err));
462 for (
i = 0;
i < plane_res->count_planes;
i++) {
463 plane = drmModeGetPlane(
ctx->hwctx->fd,
464 plane_res->planes[
i]);
468 "plane %"PRIu32
": %s.\n",
469 plane_res->planes[
i], strerror(err));
474 "CRTC %"PRIu32
" FB %"PRIu32
".\n",
475 plane->plane_id, plane->crtc_id, plane->fb_id);
477 if ((
ctx->source_crtc > 0 &&
478 plane->crtc_id !=
ctx->source_crtc) ||
482 drmModeFreePlane(plane);
490 if (
i == plane_res->count_planes) {
491 if (
ctx->source_crtc > 0) {
493 "CRTC %"PRId64
".\n",
ctx->source_crtc);
502 "locate framebuffers.\n", plane->plane_id);
505 ctx->plane_id = plane->plane_id;
507 #if HAVE_LIBDRM_GETFB2
508 fb2 = drmModeGetFB2(
ctx->hwctx->fd, plane->fb_id);
509 if (!fb2 && errno == ENOSYS) {
511 "will try to use GETFB instead.\n");
515 "framebuffer %"PRIu32
": %s.\n",
516 plane->fb_id, strerror(err));
521 "%"PRIu32
": %"PRIu32
"x%"PRIu32
" "
522 "format %"PRIx32
" modifier %"PRIx64
" flags %"PRIx32
".\n",
523 fb2->fb_id, fb2->width, fb2->height,
524 fb2->pixel_format, fb2->modifier, fb2->flags);
526 ctx->width = fb2->width;
527 ctx->height = fb2->height;
529 if (!fb2->handles[0]) {
531 "maybe you need some additional capabilities?\n");
541 "%"PRIx32
" does not match expected format.\n",
546 ctx->drm_format = fb2->pixel_format;
553 "%"PRIx32
" is not a known supported format.\n",
559 if (fb2->flags & DRM_MODE_FB_MODIFIERS) {
561 ctx->drm_format_modifier != fb2->modifier) {
563 "%"PRIx64
" does not match expected modifier.\n",
568 ctx->drm_format_modifier = fb2->modifier;
572 "DRM format %"PRIx32
" modifier %"PRIx64
".\n",
574 ctx->drm_format,
ctx->drm_format_modifier);
576 ctx->fb2_available = 1;
580 if (!
ctx->fb2_available) {
597 fb = drmModeGetFB(
ctx->hwctx->fd, plane->fb_id);
601 "framebuffer %"PRIu32
": %s.\n",
602 plane->fb_id, strerror(err));
608 "%"PRIu32
"x%"PRIu32
" %"PRIu32
"bpp %"PRIu32
"b depth.\n",
609 fb->fb_id,
fb->width,
fb->height,
fb->bpp,
fb->depth);
611 ctx->width =
fb->width;
612 ctx->height =
fb->height;
616 "maybe you need some additional capabilities?\n");
637 if (!
ctx->frames_ref) {
644 ctx->frames->sw_format =
ctx->format,
645 ctx->frames->width =
ctx->width;
646 ctx->frames->height =
ctx->height;
651 "hardware frames context: %d.\n", err);
660 drmModeFreePlaneResources(plane_res);
661 drmModeFreePlane(plane);
663 #if HAVE_LIBDRM_GETFB2
679 #define OFFSET(x) offsetof(KMSGrabContext, x)
680 #define FLAGS AV_OPT_FLAG_DECODING_PARAM
682 {
"device",
"DRM device path",
684 { .str =
"/dev/dri/card0" }, 0, 0,
FLAGS },
685 {
"format",
"Pixel format for framebuffer",
688 {
"format_modifier",
"DRM format modifier for framebuffer",
691 {
"crtc_id",
"CRTC ID to define capture source",
693 { .i64 = 0 }, 0, UINT32_MAX,
FLAGS },
694 {
"plane_id",
"Plane ID to define capture source",
696 { .i64 = 0 }, 0, UINT32_MAX,
FLAGS },
697 {
"framerate",
"Framerate to capture at",
699 { .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
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
enum AVMediaType codec_type
General type of the encoded data.
#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.
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 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
int64_t drm_format_modifier
#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 AVInputFormat 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
static const struct @194 kmsgrab_formats[]
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
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
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_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
#define flags(name, subs,...)
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
static const AVClass kmsgrab_class
#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.