void VideoOutputOpenGL::PrepareFrame(VideoFrame *buffer, FrameScanType t, OSD *osd) { if (!gl_context) return; OpenGLLocker ctx_lock(gl_context); if (!buffer) { buffer = vbuffers.GetScratchFrame(); if (m_deinterlacing && !IsBobDeint()) t = kScan_Interlaced; } gl_context_lock.lock(); framesPlayed = buffer->frameNumber + 1; gl_context_lock.unlock(); gl_context->BindFramebuffer(0); if (db_letterbox_colour == kLetterBoxColour_Gray25) gl_context->SetBackground(127, 127, 127, 255); else gl_context->SetBackground(0, 0, 0, 255); gl_context->ClearFramebuffer(); // stereoscopic views QRect main = gl_context->GetViewPort(); QRect first = main; QRect second = main; bool twopass = (m_stereo == kStereoscopicModeSideBySide) || (m_stereo == kStereoscopicModeTopAndBottom); if (kStereoscopicModeSideBySide == m_stereo) { first = QRect(main.left() / 2, main.top(), main.width() / 2, main.height()); second = first.translated(main.width() / 2, 0); } else if (kStereoscopicModeTopAndBottom == m_stereo) { first = QRect(main.left(), main.top() / 2, main.width(), main.height() / 2); second = first.translated(0, main.height() / 2); } // main UI when embedded MythMainWindow *mwnd = GetMythMainWindow(); if (mwnd && mwnd->GetPaintWindow() && window.IsEmbedding()) { if (twopass) gl_context->SetViewPort(first, true); mwnd->GetPaintWindow()->clearMask(); // Must force a UI redraw when embedded. If not, when the EPG or // finder screen is popped up over the video and the user then clicks // away from Myth, the UI is left blank. mwnd->GetMainStack()->GetTopScreen()->SetRedraw(); mwnd->draw(gl_painter); if (twopass) { gl_context->SetViewPort(second, true); mwnd->GetPaintWindow()->clearMask(); mwnd->GetMainStack()->GetTopScreen()->SetRedraw(); mwnd->draw(gl_painter); gl_context->SetViewPort(main, true); } } // video if (gl_videochain && !buffer->dummy) { gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect : window.GetDisplayVideoRect(), window.GetVideoRect()); gl_videochain->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, m_stereo); } // PiPs/PBPs if (gl_pipchains.size()) { QMap<MythPlayer*,OpenGLVideo*>::iterator it = gl_pipchains.begin(); for (; it != gl_pipchains.end(); ++it) { if (gl_pip_ready[it.key()]) { bool active = gl_pipchain_active == *it; if (twopass) gl_context->SetViewPort(first, true); (*it)->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, kStereoscopicModeNone, active); if (twopass) { gl_context->SetViewPort(second, true); (*it)->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, kStereoscopicModeNone, active); gl_context->SetViewPort(main); } } } } // visualisation if (m_visual && gl_painter && !window.IsEmbedding()) { if (twopass) gl_context->SetViewPort(first, true); m_visual->Draw(GetTotalOSDBounds(), gl_painter, nullptr); if (twopass) { gl_context->SetViewPort(second, true); m_visual->Draw(GetTotalOSDBounds(), gl_painter, nullptr); gl_context->SetViewPort(main); } } // OSD if (osd && gl_painter && !window.IsEmbedding()) { if (twopass) gl_context->SetViewPort(first, true); osd->DrawDirect(gl_painter, GetTotalOSDBounds().size(), true); if (twopass) { gl_context->SetViewPort(second, true); osd->DrawDirect(gl_painter, GetTotalOSDBounds().size(), true); gl_context->SetViewPort(main); } } gl_context->Flush(false); if (vbuffers.GetScratchFrame() == buffer) vbuffers.SetLastShownFrameToScratch(); }
void VideoOutputOpenGL::PrepareFrame(VideoFrame *buffer, FrameScanType t, OSD *osd) { if (!gl_context) return; OpenGLLocker ctx_lock(gl_context); if (!buffer) { buffer = vbuffers.GetScratchFrame(); if (m_deinterlacing && !IsBobDeint()) t = kScan_Interlaced; } gl_context_lock.lock(); framesPlayed = buffer->frameNumber + 1; gl_context_lock.unlock(); gl_context->BindFramebuffer(0); if (db_letterbox_colour == kLetterBoxColour_Gray25) gl_context->SetBackground(127, 127, 127, 255); else gl_context->SetBackground(0, 0, 0, 255); gl_context->ClearFramebuffer(); MythMainWindow *mwnd = GetMythMainWindow(); if (gl_context->IsShared() && mwnd && window.IsEmbedding()) { if (mwnd->GetPaintWindow()) mwnd->GetPaintWindow()->setMask(QRegion()); mwnd->draw(); } if (gl_videochain) { gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect : window.GetDisplayVideoRect(), window.GetVideoRect()); gl_videochain->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed); } if (gl_pipchains.size()) { QMap<MythPlayer*,OpenGLVideo*>::iterator it = gl_pipchains.begin(); for (; it != gl_pipchains.end(); ++it) { if (gl_pip_ready[it.key()]) { bool active = gl_pipchain_active == *it; (*it)->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, active); } } } if (m_visual && gl_painter && !window.IsEmbedding()) m_visual->Draw(GetTotalOSDBounds(), gl_painter, NULL); if (osd && gl_painter && !window.IsEmbedding()) osd->DrawDirect(gl_painter, GetTotalOSDBounds().size(), true); gl_context->Flush(false); if (vbuffers.GetScratchFrame() == buffer) vbuffers.SetLastShownFrameToScratch(); }