void CRenderManager::StartRenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags) { CSingleLock lock(m_captCritSect); std::map<unsigned int, CRenderCapture*>::iterator it; it = m_captures.find(captureId); if (it == m_captures.end()) { CLog::Log(LOGERROR, "CRenderManager::Capture - unknown capture id: %d", captureId); return; } CRenderCapture *capture = it->second; capture->SetState(CAPTURESTATE_NEEDSRENDER); capture->SetUserState(CAPTURESTATE_WORKING); capture->SetWidth(width); capture->SetHeight(height); capture->SetFlags(flags); capture->GetEvent().Reset(); if (g_application.IsCurrentThread()) { if (flags & CAPTUREFLAG_IMMEDIATELY) { //render capture and read out immediately RenderCapture(capture); capture->SetUserState(capture->GetState()); capture->GetEvent().Set(); } } if (!m_captures.empty()) m_hasCaptures = true; }
void CXBMCRenderManager::ManageCaptures() { //no captures, return here so we don't do an unnecessary lock if (!m_hasCaptures) return; CSingleLock lock(m_captCritSect); std::list<CRenderCapture*>::iterator it = m_captures.begin(); while (it != m_captures.end()) { CRenderCapture* capture = *it; if (capture->GetState() == CAPTURESTATE_NEEDSDELETE) { delete capture; it = m_captures.erase(it); continue; } if (capture->GetState() == CAPTURESTATE_NEEDSRENDER) RenderCapture(capture); else if (capture->GetState() == CAPTURESTATE_NEEDSREADOUT) capture->ReadOut(); if (capture->GetState() == CAPTURESTATE_DONE || capture->GetState() == CAPTURESTATE_FAILED) { //tell the thread that the capture is done or has failed capture->SetUserState(capture->GetState()); capture->GetEvent().Set(); if (capture->GetFlags() & CAPTUREFLAG_CONTINUOUS) { capture->SetState(CAPTURESTATE_NEEDSRENDER); //if rendering this capture continuously, and readout is async, render a new capture immediately if (capture->IsAsync() && !(capture->GetFlags() & CAPTUREFLAG_IMMEDIATELY)) RenderCapture(capture); it++; } else { it = m_captures.erase(it); } } else { it++; } } if (m_captures.empty()) m_hasCaptures = false; }
void CLightEffectServices::Process() { if (InitConnection()) { ApplyUserSettings(); m_lighteffect->SetScanRange(m_width, m_height); SetBling(); int priority = -1; CRenderCapture *capture = nullptr; while (!m_bStop) { if (g_application.m_pPlayer->IsPlayingVideo()) { // if starting, alloc a rendercapture and start capturing if (capture == nullptr) { capture = g_renderManager.AllocRenderCapture(); g_renderManager.Capture(capture, m_width, m_height, CAPTUREFLAG_CONTINUOUS); } // reset static bool for later m_staticON = false; m_lightsON = true; if (priority != 128) { priority = 128; m_lighteffect->SetPriority(priority); } capture->GetEvent().WaitMSec(1000); if (capture->GetUserState() == CAPTURESTATE_DONE) { //read out the pixels unsigned char *pixels = capture->GetPixels(); for (int y = 0; y < m_height; ++y) { int row = m_width * y * 4; for (int x = 0; x < m_width; ++x) { int pixel = row + (x * 4); int rgb[3] = { pixels[pixel + 2], pixels[pixel + 1], pixels[pixel] }; m_lighteffect->SetPixel(rgb, x, y); } } m_lighteffect->SendLights(true); } } else { if (capture != nullptr) { g_renderManager.ReleaseRenderCapture(capture); capture = nullptr; } // set static if its enabled if (CSettings::GetInstance().GetBool(CSettings::SETTING_SERVICES_LIGHTEFFECTSSTATICON)) { // only set static colour once, no point doing it over and over again if (!m_staticON) { m_staticON = true; m_lightsON = true; SetAllLightsToStaticRGB(); } } // or kill the lights else { if (m_lightsON) { m_lightsON = false; if (priority != 255) { priority = 255; m_lighteffect->SetPriority(priority); } } } usleep(50 * 1000); } } // have to check this in case we go // right from playing to death. if (capture != nullptr) { g_renderManager.ReleaseRenderCapture(capture); capture = nullptr; } m_lighteffect->SetPriority(255); SAFE_DELETE(m_lighteffect); } }