Last active
July 25, 2018 05:03
-
-
Save mihailescu2m/1889c6b3a804f58b566bc004b3f03b83 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
------- init() function -------- | |
monitor_width = m_destRect.Width(); // from kodi | |
monitor_height = m_destRect.Height(); // from kodi | |
struct drm_mode_create_dumb dumb_buffer; | |
/* create dumb buffer */ | |
memset(&dumb_buffer, 0, sizeof(dumb_buffer)); | |
dumb_buffer.width = monitor_width; | |
dumb_buffer.height = monitor_height; | |
dumb_buffer.bpp = 32; | |
ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dumb_buffer); | |
if (ret < 0 || !ret.pitch) { | |
quit error | |
} | |
/* do we need to do mmap ?? */ | |
struct drm_mode_map_dumb mreq; | |
memset(&mreq, 0, sizeof(mreq)); | |
mreq.handle = dumb_buffer.handle; | |
ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); | |
if (ret) { | |
quit error | |
} | |
// actual mmap | |
mmap(0, dumb_buffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset); | |
---------- END ---------- | |
CHANGES IN KODI: | |
void CRendererDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer) | |
{ | |
buffer->m_drm_fd = m_DRM->GetFileDescriptor(); | |
AVDRMFrameDescriptor* descriptor = buffer->GetDescriptor(); | |
if (descriptor && descriptor->nb_layers) | |
{ | |
uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; | |
uint64_t modifier[4] = {0}; | |
int ret; | |
// convert Prime FD to GEM handle | |
for (int object = 0; object < descriptor->nb_objects; object++) | |
{ | |
ret = drmPrimeFDToHandle(m_DRM->GetFileDescriptor(), descriptor->objects[object].fd, &buffer->m_handles[object]); | |
if (ret < 0) | |
{ | |
CLog::Log(LOGERROR, "CRendererDRMPRIME::%s - failed to retrieve the GEM handle from prime fd %d, ret = %d", __FUNCTION__, descriptor->objects[object].fd, ret); | |
return; | |
} | |
} | |
AVDRMLayerDescriptor* layer = &descriptor->layers[0]; | |
for (int plane = 0; plane < layer->nb_planes; plane++) | |
{ | |
int object = layer->planes[plane].object_index; | |
uint32_t handle = buffer->m_handles[object]; | |
if (handle && layer->planes[plane].pitch) | |
{ | |
handles[plane] = handle; | |
pitches[plane] = layer->planes[plane].pitch; | |
offsets[plane] = layer->planes[plane].offset; | |
modifier[plane] = descriptor->objects[object].format_modifier; | |
} | |
} | |
---------- START IPPv2 job for conversion ---------- | |
not clear: we do this by plane? we should not, since we have only 1 handle and pitch is the same for all planes (=bytesperline) | |
struct exynos_drm_ipp_std_task task = { }; | |
struct drm_exynos_ioctl_ipp_commit arg = { }; | |
uint32_t id = 0; /* hardcoded first available IPP module */ | |
task.buf[0].id = DRM_EXYNOS_IPP_TASK_BUFFER | | |
DRM_EXYNOS_IPP_TASK_TYPE_SOURCE; | |
task.buf[0].fourcc = DRM_FORMAT_NV12; | |
task.buf[0].width = buffer->GetWidth(); | |
task.buf[0].height = buffer->GetHeight(); | |
task.buf[0].pitch[0] = pitches[0]; // all (2 nv12) planes have the same pitch (bytesperline) | |
task.buf[0].gem_id[0] = handles[0]; // all (2 nv12) planes have the same handle | |
task.buf[1].id = DRM_EXYNOS_IPP_TASK_BUFFER | | |
DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION; | |
task.buf[1].fourcc = DRM_FORMAT_XRGB8888; | |
task.buf[1].width = monitor_width; // determined in init() | |
task.buf[1].height = monitor_height; // determined in init() | |
task.buf[1].pitch[0] = dumb_buffer.pitch; // dumb_buffer from init() | |
task.buf[1].gem_id[0] = dumb_buffer.handle; | |
task.rect[0].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | | |
DRM_EXYNOS_IPP_TASK_TYPE_SOURCE; | |
task.rect[0].x = 0; | |
task.rect[0].y = 0; | |
task.rect[0].w = buffer->GetWidth(); | |
task.rect[0].h = buffer->GetHeight(); | |
task.rect[1].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | | |
DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION; | |
task.rect[1].x = 0; | |
task.rect[1].y = 0; | |
task.rect[1].w = monitor_width; | |
task.rect[1].h = monitor_height; | |
task.transform.id = DRM_EXYNOS_IPP_TASK_TRANSFORM; | |
task.transform.rotation = DRM_MODE_ROTATE_0; // there is no rotation | |
// but we have different width/height and fourcc | |
// so it should do transform and scale, right ? | |
arg.flags = 0; | |
arg.ipp_id = id; | |
arg.params_size = sizeof(task); | |
arg.params_ptr = (unsigned long)(&task); | |
arg.user_data = 0; | |
if (drmCommandWriteRead(fd, DRM_EXYNOS_IPP_COMMIT, &arg, sizeof(arg))) { | |
fprintf(stderr, "failed to commit Exynos IPP task (%d): %m\n", | |
errno); | |
return errno; | |
} | |
---------- END ---------- | |
// add the video frame FB | |
// ret = drmModeAddFB2WithModifiers(m_DRM->GetFileDescriptor(), buffer->GetWidth(), buffer->GetHeight(), layer->format, handles, pitches, offsets, modifier, &buffer->m_fb_id, 0); | |
// we add our own buffer not the one received from FFMPEG | |
// we still use "buffer->m_fb_id" to store the returned *buf_id, since we pretend we are displaying "buffer" not our own "dumb_buffer" | |
// also we lose the modifiers, and send NULL instead; offset is 0 .... XRGB has 1 plane only | |
!! ret = drmModeAddFB2WithModifiers(m_DRM->GetFileDescriptor(), monitor_width, monitor_height, DRM_FORMAT_XRGB8888, [dumb_buffer.handle], [dumb_buffer.pitch], [0], NULL, &buffer->m_fb_id, 0); | |
if (ret < 0) | |
{ | |
CLog::Log(LOGERROR, "CRendererDRMPRIME::%s - failed to add drm layer %d, ret = %d", __FUNCTION__, buffer->m_fb_id, ret); | |
return; | |
} | |
int32_t crtc_x = static_cast<int32_t>(m_destRect.x1) & ~1; | |
int32_t crtc_y = static_cast<int32_t>(m_destRect.y1) & ~1; | |
uint32_t crtc_w = (static_cast<uint32_t>(m_destRect.Width()) + 1) & ~1; | |
uint32_t crtc_h = (static_cast<uint32_t>(m_destRect.Height()) + 1) & ~1; | |
uint32_t src_x = 0; | |
uint32_t src_y = 0; | |
!! uint32_t src_w = monitor_width << 16; //buffer->GetWidth() << 16; | |
!! uint32_t src_h = monitor_height << 16; //buffer->GetHeight() << 16; | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "FB_ID", buffer->m_fb_id); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "CRTC_ID", m_DRM->GetCrtc()->crtc->crtc_id); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "SRC_X", src_x); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "SRC_Y", src_y); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "SRC_W", src_w); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "SRC_H", src_h); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "CRTC_X", crtc_x); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "CRTC_Y", crtc_y); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "CRTC_W", crtc_w); | |
m_DRM->AddProperty(m_DRM->GetPrimaryPlane(), "CRTC_H", crtc_h); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment