I don’t think your solution is solving my problem.
You created a new api call, which is then used from video_dec_drm to render correctly the UI.
But the error is also coming when using the api with enqueBuffer. If I see it correctly you did not change anything on that workflow. The new function is not called from inside NvDrmRenderer itself.
So the video should not be disabled for your test.
I modified the setPlane function to have the same algorithm to find the plane id like in nvdrmvideosink GStreamer element. The new function looks like this:
int NvDrmRenderer::setPlane(uint32_t pl_index,
uint32_t fb_id,
uint32_t crtc_x,
uint32_t crtc_y,
uint32_t crtc_w,
uint32_t crtc_h,
uint32_t src_x,
uint32_t src_y,
uint32_t src_w,
uint32_t src_h)
{
drmModePlaneResPtr plane_res_info = NULL;
drmModePlanePtr plane_info = NULL;
int plane_result;
int plane_count;
int ret = -1;
// Set Plane Info
plane_res_info = drmModeGetPlaneResources( drm_fd);
plane_count = plane_res_info->count_planes;
if (!plane_res_info) {
printf ("Unable to get plane resource info \n");
goto error;
}
// Check bound
if ((pl_index >= plane_count) || (pl_index < 0)) {
printf ("Invalid plane id \n");
goto error;
}
for (int i = 0; i < plane_count; i++) {
int plane_id = plane_res_info->planes[i];
plane_info = drmModeGetPlane (drm_fd, plane_id);
if (!plane_info) {
printf ("Unable to get plane info\n");
}
if (plane_info->possible_crtcs & (1 << drm_crtc_index)) {
if (pl_index == 0) {
plane_result = plane_id;
break;
} else {
pl_index--;
}
}
}
if (pl_index != 0) {
goto error;
}
ret = drmModeSetPlane(drm_fd, plane_result, drm_crtc_id,
fb_id, 0, crtc_x, crtc_y, crtc_w,
crtc_h, src_x, src_y,
src_w, src_h);
error:
drmModeFreePlane(plane_info);
drmModeFreePlaneResources(plane_res_info);
return ret;
}
This is the initialization part, which is also borrowed from nvdrmvideosink:
drm_fd = drmOpen(DRM_DEVICE_NAME, NULL);
if (drm_fd == -1) {
COMP_ERROR_MSG("Couldn't open device: " << DRM_DEVICE_NAME);
goto error;
}
if (drmSetClientCap (drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) {
COMP_ERROR_MSG ("Failed to set universal planes \n");
goto error;
}
// Obtain DRM-KMS resources
drm_res_info = drmModeGetResources(drm_fd);
if (!drm_res_info) {
COMP_ERROR_MSG("Couldn't obtain DRM-KMS resources ");
goto error;
}
COMP_DEBUG_MSG("Obtained device information ");
// If a specific crtc was requested, make sure it exists
if (crtc >= drm_res_info->count_crtcs) {
COMP_ERROR_MSG("Requested crtc index " << crtc << " exceeds count " << drm_res_info->count_crtcs);
goto error;
}
// Query info for requested connector
if (conn >= drm_res_info->count_connectors) {
COMP_ERROR_MSG("Requested connector index " << conn << " exceeds count " << drm_res_info->count_connectors);
goto error;
}
drm_conn_id = drm_res_info->connectors[conn];
drm_conn_info = drmModeGetConnector(drm_fd, drm_conn_id);
if (!drm_conn_info) {
COMP_ERROR_MSG("Unable to obtain info for connector " << drm_conn_id);
goto error;
} else if (drm_conn_info->connection != DRM_MODE_CONNECTED) {
COMP_ERROR_MSG("Requested connnector is not connected ");
goto error;
} else if (drm_conn_info->count_modes <= 0) {
COMP_ERROR_MSG("Requested connnector has no available modes ");
goto error;
}
COMP_DEBUG_MSG("Obtained connector information\n");
// If there is already an encoder attached to the connector, choose
// it unless not compatible with crtc/plane
drm_enc_id = drm_conn_info->encoder_id;
drm_enc_info = drmModeGetEncoder(drm_fd, drm_enc_id);
if (!drm_enc_info) {
// If connector does not have a connected encoder use first one
drm_enc_id = drm_conn_info->encoders[0];
drm_enc_info = drmModeGetEncoder (drm_fd, drm_enc_id);
if (!drm_enc_info) {
COMP_DEBUG_MSG("Unable to find suitable encoder \n");
goto error;
}
}
// Set CRTC info
drm_crtc_id = drm_enc_info->crtc_id;
drm_crtc_info = drmModeGetCrtc (drm_fd, drm_crtc_id);
// If the encoder has no connected CRTC, use the first one supported
if (!drm_crtc_info && drm_enc_info->possible_crtcs) {
drm_crtc_id = drm_res_info->crtcs[(drm_enc_info->possible_crtcs) - 1];
drm_crtc_info = drmModeGetCrtc (drm_fd, drm_crtc_id);
}
if (hdrSupported()) {
ret = setHDRMetadataSmpte2086(metadata);
if(ret!=0)
COMP_DEBUG_MSG("Error while getting HDR mastering display data\n");
}
else {
COMP_DEBUG_MSG("APP_INFO : HDR not supported \n");
}
// Query info for crtc
drm_crtc_info = drmModeGetCrtc(drm_fd, drm_crtc_id);
if (!drm_crtc_info) {
COMP_ERROR_MSG("Unable to obtain info for crtc " << drm_crtc_id);
goto error;
}
if (!drm_crtc_info) {
printf ("Unable to find usable crtc for encoder \n");
goto error;
}
for (int is = 0; is < drm_res_info->count_crtcs; is++) {
if (drm_res_info->crtcs[is] == drm_crtc_id) {
drm_crtc_index = is;
break;
}
}
if (drm_crtc_index == -1) {
printf ("Unable to locate crtc_id=%d in resource list\n", drm_crtc_id);
goto error;
}
COMP_DEBUG_MSG("Obtained crtc information\n");
I added
uint32_t drm_crtc_index;
as a new private class variable in NvDrmRenderer.h
Do you think my solution is legit? It seems to work so far.