45#include <drm_fourcc.h>
50#include <libavcodec/avcodec.h>
51#include <libavutil/hwcontext_drm.h>
52#include <libavutil/pixdesc.h>
53#include <libavfilter/buffersink.h>
54#include <libavfilter/buffersrc.h>
55#include <libavutil/opt.h>
98 *resources = drmModeGetResources(fd);
99 if (*resources == NULL) {
100 LOGERROR(
"drmdevice: %s: cannot retrieve DRM resources (%d): %m", __FUNCTION__, errno);
115 if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &test) < 0 || test == 0)
118 if (drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
121 if (drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0)
124 if (drmGetCap(fd, DRM_CAP_PRIME, &test) < 0)
127 if (drmGetCap(fd, DRM_PRIME_CAP_EXPORT, &test) < 0)
130 if (drmGetCap(fd, DRM_PRIME_CAP_IMPORT, &test) < 0)
136#define MAX_DRM_DEVICES 64
145 int num_devices, fd = -1;
148 if (num_devices < 0) {
149 LOGERROR(
"drmdevice: %s: drmGetDevices2 failed: %s", __FUNCTION__, strerror(-num_devices));
153 for (
int i = 0; i < num_devices && fd < 0; i++) {
154 drmDevicePtr device = devices[i];
157 if (!(device->available_nodes & (1 << DRM_NODE_PRIMARY)))
159 fd = open(device->nodes[DRM_NODE_PRIMARY], O_RDWR);
175 drmFreeDevices(devices, num_devices);
178 LOGERROR(
"drmdevice: %s: no drm device found!", __FUNCTION__);
188 drmModeConnector *connector = NULL;
192 for (i = 0; i < resources->count_connectors; i++) {
193 connector = drmModeGetConnector(fd, resources->connectors[i]);
194 if (connector && connector->connection == DRM_MODE_CONNECTED)
196 drmModeFreeConnector(connector);
204 for (i = 0; i < resources->count_connectors; i++) {
205 connector = drmModeGetConnector(fd, resources->connectors[i]);
206 if (connector && connector->count_modes > 0)
208 drmModeFreeConnector(connector);
220 uint32_t objectType,
const char *propName, uint64_t *value)
224 drmModePropertyPtr Prop;
225 drmModeObjectPropertiesPtr objectProps =
226 drmModeObjectGetProperties(fdDrm, objectID, objectType);
228 for (i = 0; i < objectProps->count_props; i++) {
229 if ((Prop = drmModeGetProperty(fdDrm, objectProps->props[i])) == NULL)
230 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Unable to query property", __FUNCTION__);
232 if (strcmp(propName, Prop->name) == 0) {
233 *value = objectProps->prop_values[i];
237 drmModeFreeProperty(Prop);
243 drmModeFreeObjectProperties(objectProps);
246 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Unable to find value for property \'%s\'.", __FUNCTION__, propName);
260 drmModeRes *resources;
261 drmModeConnector *connector;
262 drmModeEncoder *encoder = NULL;
263 drmModeModeInfo *drmmode = NULL;
265 drmModePlaneRes *planeRes;
272 LOGERROR(
"drmdevice: %s: Could not open device!", __FUNCTION__);
276 LOGDEBUG2(
L_DRM,
"drmdevice: %s: fd: %d DRM have %i connectors, %i crtcs, %i encoders", __FUNCTION__,
277 m_fdDrm, resources->count_connectors, resources->count_crtcs,
278 resources->count_encoders);
283 LOGERROR(
"drmdevice: %s: cannot retrieve DRM connector (%d): %m", __FUNCTION__, errno);
290 for (i = 0; i < connector->count_modes; i++) {
291 drmModeModeInfo *current_mode = &connector->modes[i];
294 drmmode = current_mode;
295 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Use user requested mode: %dx%d@%d", __FUNCTION__, drmmode->hdisplay, drmmode->vdisplay, drmmode->vrefresh);
300 LOGWARNING(
"drmdevice: %s: User requested mode not found, try default modes", __FUNCTION__);
303 uint32_t preferred_hz[3] = {50, 60, 0};
309 while (!drmmode && preferred_hz[j]) {
310 for (i = 0, width = 0; i < connector->count_modes; i++) {
311 drmModeModeInfo *current_mode = &connector->modes[i];
312 if (preferred_hz[j] && current_mode->vrefresh != preferred_hz[j])
315 int current_width = current_mode->hdisplay;
316 if (current_width > width) {
317 drmmode = current_mode;
318 width = current_width;
325 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Use mode with the biggest width: %dx%d@%d", __FUNCTION__,
326 drmmode->hdisplay, drmmode->vdisplay, drmmode->vrefresh);
330 LOGERROR(
"drmdevice: %s: No monitor mode found! Probably no monitor connected, giving up!", __FUNCTION__);
337 for (i = 0; i < resources->count_encoders; i++) {
338 encoder = drmModeGetEncoder(
m_fdDrm, resources->encoders[i]);
339 if (encoder->encoder_id == connector->encoder_id)
341 drmModeFreeEncoder(encoder);
351 LOGERROR(
"drmdevice: %s: No crtc found!", __FUNCTION__);
359 for (i = 0; i < resources->count_crtcs; i++) {
360 if (resources->crtcs[i] ==
m_crtcId) {
368 LOGINFO(
"DRM Setup: Using Monitor Mode %dx%d@%d, m_crtcId %d crtc_idx %d",
371 drmModeFreeConnector(connector);
375 if ((planeRes = drmModeGetPlaneResources(
m_fdDrm)) == NULL) {
376 LOGERROR(
"drmdevice: %s: cannot retrieve PlaneResources (%d): %m", __FUNCTION__, errno);
388 std::vector<cDrmPlane> overlayNV12Candidates;
390 for (j = 0; j < planeRes->count_planes; j++) {
391 plane = drmModeGetPlane(
m_fdDrm, planeRes->planes[j]);
394 LOGERROR(
"drmdevice: %s: cannot query DRM-KMS plane %d", __FUNCTION__, j);
400 char pixelformats[256];
404 DRM_MODE_OBJECT_PLANE,
"type", &type)) {
405 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Failed to get property 'type'", __FUNCTION__);
408 DRM_MODE_OBJECT_PLANE,
"zpos", &zpos)) {
409 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Failed to get property 'zpos'", __FUNCTION__);
414 LOGDEBUG2(
L_DRM,
"drmdevice: %s: %s: id %i possible_crtcs %i", __FUNCTION__,
415 (type == DRM_PLANE_TYPE_PRIMARY) ?
"PRIMARY " :
416 (type == DRM_PLANE_TYPE_OVERLAY) ?
"OVERLAY " :
417 (type == DRM_PLANE_TYPE_CURSOR) ?
"CURSOR " :
"UNKNOWN",
418 plane->plane_id, plane->possible_crtcs);
419 strcpy(pixelformats,
" ");
422 for (k = 0; k < plane->count_formats; k++) {
423 if (encoder->possible_crtcs & plane->possible_crtcs) {
425 switch (plane->formats[k]) {
426 case DRM_FORMAT_NV12:
427 snprintf(tmp,
sizeof(tmp),
" %4.4s", (
char *)&plane->formats[k]);
428 strcat(pixelformats, tmp);
429 if (type == DRM_PLANE_TYPE_PRIMARY && !best_primary_video_plane.
GetId()) {
430 best_primary_video_plane.
SetId(plane->plane_id);
431 best_primary_video_plane.
SetType(type);
432 best_primary_video_plane.
SetZpos(zpos);
433 strcat(pixelformats,
"! ");
435 if (type == DRM_PLANE_TYPE_OVERLAY && !best_overlay_video_plane.
GetId()) {
436 best_overlay_video_plane.
SetId(plane->plane_id);
437 best_overlay_video_plane.
SetType(type);
438 best_overlay_video_plane.
SetZpos(zpos);
439 strcat(pixelformats,
"! ");
442 if (type == DRM_PLANE_TYPE_OVERLAY) {
444 cand.
SetId(plane->plane_id);
447 overlayNV12Candidates.push_back(cand);
450 case DRM_FORMAT_ARGB8888:
451 snprintf(tmp,
sizeof(tmp),
" %4.4s", (
char *)&plane->formats[k]);
452 strcat(pixelformats, tmp);
453 if (type == DRM_PLANE_TYPE_PRIMARY) {
454 best_primary_osd_plane.
SetId(plane->plane_id);
455 best_primary_osd_plane.
SetType(type);
456 best_primary_osd_plane.
SetZpos(zpos);
457 strcat(pixelformats,
"! ");
459 if (type == DRM_PLANE_TYPE_OVERLAY) {
460 best_overlay_osd_plane.
SetId(plane->plane_id);
461 best_overlay_osd_plane.
SetType(type);
462 best_overlay_osd_plane.
SetZpos(zpos);
463 strcat(pixelformats,
"! ");
473 drmModeFreePlane(plane);
477 if (best_primary_video_plane.
GetId() && best_overlay_osd_plane.
GetId()) {
486 }
else if (best_overlay_video_plane.
GetId() && best_primary_osd_plane.
GetId()) {
497 LOGERROR(
"drmdevice: %s: No suitable planes found!", __FUNCTION__);
503 for (
cDrmPlane &cand : overlayNV12Candidates) {
504 uint32_t pid = cand.
GetId();
507 if (!best_overlay_pip_plane.
GetId() || pid > best_overlay_pip_plane.
GetId()) {
508 best_overlay_pip_plane = cand;
512 if (best_overlay_pip_plane.
GetId()) {
518 LOGERROR(
"drmdevice: %s: no suitable pip planes found", __FUNCTION__);
523 if (best_primary_video_plane.
GetId()) {
524 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_primary_video_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
525 best_primary_video_plane.
GetId(), best_primary_video_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_primary_video_plane.
GetZpos());
527 if (best_overlay_video_plane.
GetId()) {
528 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_overlay_video_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
529 best_overlay_video_plane.
GetId(), best_overlay_video_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_overlay_video_plane.
GetZpos());
531 if (best_primary_osd_plane.
GetId()) {
532 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_primary_osd_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
533 best_primary_osd_plane.
GetId(), best_primary_osd_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_primary_osd_plane.
GetZpos());
535 if (best_overlay_osd_plane.
GetId()) {
536 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_overlay_osd_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
537 best_overlay_osd_plane.
GetId(), best_overlay_osd_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_overlay_osd_plane.
GetZpos());
539 if (best_overlay_pip_plane.
GetId()) {
540 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_overlay_pip_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
541 best_overlay_pip_plane.
GetId(), best_overlay_pip_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_overlay_pip_plane.
GetZpos());
567 strcpy(str_zpos,
"drmdevice: Init: zpos values are wrong, so ");
570 strcat(str_zpos,
"hardcode them to 0 and 1, because they are equal");
574 strcat(str_zpos,
"switch them");
582 if (drmSetMaster(
m_fdDrm) < 0) {
583 LOGDEBUG2(
L_DRM,
"drmdevice: Failed to set drm master, try authorize instead: {}", strerror(errno));
586 if (drmGetMagic(
m_fdDrm, &magic) < 0)
587 LOGFATAL(
"drmdevice: Failed to get drm magic: {}", strerror(errno));
589 if (drmAuthMagic(
m_fdDrm, magic) < 0)
590 LOGFATAL(
"drmdevice: Failed to authorize drm magic: {}", strerror(errno));
593 drmModeFreePlaneResources(planeRes);
594 drmModeFreeEncoder(encoder);
595 drmModeFreeResources(resources);
597 LOGINFO(
"DRM setup - CRTC: %i video_plane: %i (%s %" PRIu64
") osd_plane: %i (%s %" PRIu64
") pip_plane: %i (%s %" PRIu64
") m_useZpos: %d",
615 if (InitGbm(
m_drmModeInfo.hdisplay,
m_drmModeInfo.vdisplay, DRM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING)) {
616 LOGERROR(
"drmdevice: %s: failed to init gbm device and surface!", __FUNCTION__);
622 LOGERROR(
"drmdevice: %s: failed to init egl!", __FUNCTION__);
642int cDrmDevice::InitGbm(
int w,
int h, uint32_t format, uint64_t modifier)
644 m_pGbmDevice = gbm_create_device(
m_fdDrm);
646 LOGERROR(
"drmdevice: %s: failed to create gbm device!", __FUNCTION__);
650 m_pGbmSurface = gbm_surface_create(m_pGbmDevice, w, h, format, modifier);
651 if (!m_pGbmSurface) {
652 LOGERROR(
"drmdevice: %s: failed to create %d x %d surface bo", __FUNCTION__, w, h);
659PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
660PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC get_platform_surface = NULL;
662static const EGLint context_attribute_list[] =
664 EGL_CONTEXT_CLIENT_VERSION, 2,
671EGLConfig cDrmDevice::GetEGLConfig(
void)
673 EGLint config_attribute_list[] = {
675 EGL_STENCIL_SIZE, EGL_DONT_CARE,
676 EGL_DEPTH_SIZE, EGL_DONT_CARE,
677 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
678 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
681 EGLConfig *configs =
nullptr;
684 EGL_CHECK(eglGetConfigs(m_eglDisplay, NULL, 0, &count));
686 LOGFATAL(
"drmdevice: %s: no EGL configs to choose from", __FUNCTION__);
690 configs = (EGLConfig *)malloc(count *
sizeof(*configs));
692 LOGFATAL(
"drmdevice: %s: can't allocate space for EGL configs", __FUNCTION__);
694 EGL_CHECK(eglChooseConfig(m_eglDisplay, config_attribute_list, configs, count, &matched));
697 LOGFATAL(
"drmdevice: %s: no EGL configs with appropriate attributes", __FUNCTION__);
700 LOGDEBUG2(
L_OPENGL,
"drmdevice: %s: %d appropriate EGL configs found, which match attributes", __FUNCTION__, matched);
702 EGLConfig chosen = NULL;
703 for (
int i = 0; i < matched; ++i) {
705 EGL_CHECK(eglGetConfigAttrib(m_eglDisplay, configs[i], EGL_NATIVE_VISUAL_ID, &gbm_format));
707 if (gbm_format == GBM_FORMAT_ARGB8888) {
715 LOGFATAL(
"drmdevice: %s: no matching gbm config found", __FUNCTION__);
726int cDrmDevice::InitEGL(
void)
728 EGLint iMajorVersion, iMinorVersion;
730 PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress(
"eglGetPlatformDisplayEXT");
731 assert(get_platform_display != NULL);
732 PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC get_platform_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress(
"eglCreatePlatformWindowSurfaceEXT");
733 assert(get_platform_surface != NULL);
735 EGL_CHECK(m_eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, m_pGbmDevice, NULL));
737 LOGERROR(
"drmdevice: %s: failed to get eglDisplay", __FUNCTION__);
741 if (!eglInitialize(m_eglDisplay, &iMajorVersion, &iMinorVersion)) {
742 LOGERROR(
"drmdevice: %s: eglInitialize failed", __FUNCTION__);
746 LOGDEBUG2(
L_OPENGL,
"drmdevice: %s: Using display %p with EGL version %d.%d", __FUNCTION__, m_eglDisplay, iMajorVersion, iMinorVersion);
752 EGLConfig eglConfig = GetEGLConfig();
754 EGL_CHECK(eglBindAPI(EGL_OPENGL_ES_API));
755 EGL_CHECK(m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, context_attribute_list));
757 LOGERROR(
"drmdevice: %s: failed to create eglContext", __FUNCTION__);
761 EGL_CHECK(m_eglSurface = get_platform_surface(m_eglDisplay, eglConfig, m_pGbmSurface, NULL));
762 if (m_eglSurface == EGL_NO_SURFACE) {
763 LOGERROR(
"drmdevice: %s: failed to create eglSurface", __FUNCTION__);
767 EGLint s_width, s_height;
768 EGL_CHECK(eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &s_width));
769 EGL_CHECK(eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &s_height));
771 LOGDEBUG2(
L_OPENGL,
"drmdevice: %s: GLSurface %p on EGLDisplay %p for %d x %d BO created", __FUNCTION__, m_eglSurface, m_eglDisplay, s_width, s_height);
773 m_glInitiated =
true;
774 LOGINFO(
"DRM Setup: EGL context initialized");
779static void drm_fb_destroy_callback(
struct gbm_bo *bo,
void *data)
781 int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
785 drmModeRmFB(drm_fd, buf->
Id());
790__attribute__ ((weak))
union gbm_bo_handle
791gbm_bo_get_handle_for_plane(struct gbm_bo *bo,
int plane);
793__attribute__ ((weak))
int
794gbm_bo_get_fd(
struct gbm_bo *bo);
796__attribute__ ((weak)) uint64_t
797gbm_bo_get_modifier(
struct gbm_bo *bo);
799__attribute__ ((weak))
int
800gbm_bo_get_plane_count(
struct gbm_bo *bo);
802__attribute__ ((weak)) uint32_t
803gbm_bo_get_stride_for_plane(
struct gbm_bo *bo,
int plane);
805__attribute__ ((weak)) uint32_t
806gbm_bo_get_offset(
struct gbm_bo *bo,
int plane);
815cDrmBuffer *cDrmDevice::GetBufFromBo(
struct gbm_bo *bo)
818 uint32_t mod_flags = 0;
825 buf =
new cDrmBuffer(
m_fdDrm, gbm_bo_get_width(bo), gbm_bo_get_height(bo), gbm_bo_get_format(bo), bo);
827 if (gbm_bo_get_handle_for_plane && gbm_bo_get_modifier &&
828 gbm_bo_get_plane_count && gbm_bo_get_stride_for_plane &&
830 uint64_t modifiers[4] = {0};
831 modifiers[0] = gbm_bo_get_modifier(bo);
832 const int num_planes = gbm_bo_get_plane_count(bo);
834 for (
int i = 0; i < num_planes; i++) {
835 buf->
SetHandle(i, gbm_bo_get_handle_for_plane(bo, i).u32);
836 buf->
SetPitch(i, gbm_bo_get_stride_for_plane(bo, i));
837 buf->
SetOffset(i, gbm_bo_get_offset(bo, i));
838 modifiers[i] = modifiers[0];
847 mod_flags = DRM_MODE_FB_MODIFIERS;
848 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Using modifier %" PRIx64
"", __FUNCTION__, modifiers[0]);
860 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Modifiers failed!", __FUNCTION__);
863 uint32_t tmpHandle[4] = { gbm_bo_get_handle(bo).u32, 0, 0, 0};
864 uint32_t tmpStride[4] = { gbm_bo_get_stride(bo), 0, 0, 0};
865 uint32_t tmpSize[4] = { buf->
Height() * buf->
Width() * buf->
Pitch(0), 0, 0, 0};
866 memcpy(buf->
PrimeHandle(), tmpHandle,
sizeof(tmpHandle));
867 memcpy(buf->
Pitch(), tmpStride,
sizeof(tmpStride));
868 memcpy(buf->
Size(), tmpSize,
sizeof(tmpSize));
869 memset(buf->
Offset(), 0, 16);
881 LOGFATAL(
"drmdevice: %s: cannot create framebuffer (%d): %m", __FUNCTION__, errno);
886 uint32_t pixFmt = buf->
PixFmt();
887 LOGDEBUG2(
L_DRM,
"drmdevice: %s: New GL buffer %d x %d pix_fmt %4.4s fb_id %d", __FUNCTION__,
890 gbm_bo_set_user_data(bo, buf, drm_fb_destroy_callback);
902 for (i = 0; i < resources->count_crtcs; i++) {
903 const uint32_t crtc_mask = 1 << i;
904 const uint32_t crtc_id = resources->crtcs[i];
905 if (encoder->possible_crtcs & crtc_mask) {
920 for (i = 0; i < connector->count_encoders; i++) {
921 const uint32_t encoder_id = connector->encoders[i];
922 drmModeEncoder *encoder = drmModeGetEncoder(
m_fdDrm, encoder_id);
926 drmModeFreeEncoder(encoder);
960 uint32_t objectID, uint32_t objectType,
961 const char *propName, uint64_t value)
965 drmModePropertyPtr Prop;
966 drmModeObjectPropertiesPtr objectProps =
967 drmModeObjectGetProperties(
m_fdDrm, objectID, objectType);
969 for (i = 0; i < objectProps->count_props; i++) {
970 if ((Prop = drmModeGetProperty(
m_fdDrm, objectProps->props[i])) == NULL)
971 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Unable to query property", __FUNCTION__);
973 if (strcmp(propName, Prop->name) == 0) {
975 drmModeFreeProperty(Prop);
979 drmModeFreeProperty(Prop);
982 drmModeFreeObjectProperties(objectProps);
985 LOGDEBUG2(
L_DRM,
"drmdevice: %s Unable to find value for property \'%s\'.", __FUNCTION__, propName);
987 return drmModeAtomicAddProperty(ModeReq, objectID,
id, value);
Audio and alsa module header file.
Some helper functions header file.
void SetNumPlanes(int numPlanes)
void SetOffset(int idx, uint32_t offset)
void SetNumObjects(int numObjects)
void SetSize(int idx, uint32_t size)
void SetPitch(int idx, uint32_t pitch)
uint32_t PrimeHandle(int idx)
void SetHandle(int idx, uint32_t handle)
void SetObjectIndex(int idx, uint32_t objIdx)
void SetDmaBufHandle(uint32_t fd)
uint32_t m_userReqDisplayRefreshRate
user requested display refresh rate
int m_userReqDisplayHeight
user requested display height
drmModeModeInfo m_drmModeInfo
mode info
int CreatePropertyBlob(uint32_t *)
Creates a property blob.
cDrmPlane m_videoPlane
the video drm plane
cDrmDevice(cVideoRender *, const char *)
cDrmDevice constructor
int SetPropertyRequest(drmModeAtomicReqPtr, uint32_t, uint32_t, const char *, uint64_t)
Add a property to a request.
int32_t FindCrtcForConnector(const drmModeRes *, const drmModeConnector *)
Finds the CRTC_ID for the given connector.
int HandleEvent(void)
Polls for a drm event.
int m_userReqDisplayWidth
user requested display width
cDrmPlane m_pipPlane
the pip drm plane
drmModeCrtc * m_drmModeCrtcSaved
saved CRTC infos
int m_fdDrm
drm file descriptor
uint64_t m_zposPip
zpos of pip plane
void SaveCrtc(void)
Saves information of a CRTC.
virtual ~cDrmDevice(void)
cDrmDevice destructor
uint32_t m_connectorId
connector id
void RestoreCrtc(void)
Restore information of a CRTC.
void Close(void)
Close drm file handle.
uint32_t m_crtcId
current crtc ID
uint32_t m_crtcIndex
current crtc index
cVideoRender * m_pRender
pointer to cVideoRender object
int Init(void)
Initiate the drm device.
uint64_t m_zposPrimary
zpos of primary plane
drmEventContext m_drmEventCtx
drm event context
bool m_useZpos
is set, if drm hardware can use zpos
cDrmPlane m_osdPlane
the osd drm plane
void InitEvent(void)
Init the event context.
uint64_t m_zposOverlay
zpos of overlay plane
cDrmPlane - DRM plane class
int HasZpos(int)
Check, if the plane is able to set the zpos property.
void FillProperties(int)
Fill the plane properties.
void SetZpos(uint64_t zpos)
void SetType(uint64_t type)
cVideoRender - Video render class
void SetScreenSize(int, int, uint32_t)
Wrapper to set the screen size in the device.
static int TestCaps(int fd)
Test drm capabilities.
static int FindDrmDevice(drmModeRes **resources)
Find and open a suitable device with the wanted capabilities.
static int32_t FindCrtcForEncoder(const drmModeRes *resources, const drmModeEncoder *encoder)
Finds the CRTC_ID for the given encoder.
static int get_resources(int fd, drmModeRes **resources)
static int GetPropertyValue(int fdDrm, uint32_t objectID, uint32_t objectType, const char *propName, uint64_t *value)
Gets a property value.
static drmModeConnector * FindDrmConnector(int fd, drmModeRes *resources)
Find a suitable connector, preferably a connected one.
Logger class header file.
#define LOGFATAL
Logger macros.
Misc function header file.
Thread classes header file.
Rendering class header file.