CStdString CApplicationMessenger::GetResponse() { CStdString tmp; CSingleLock lock (m_critBuffer); tmp=bufferResponse; lock.Leave(); return tmp; }
void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait) { message.waitEvent.reset(); std::shared_ptr<CEvent> waitEvent; if (wait) { // check that we're not being called from our application thread, else we'll be waiting // forever! if (!g_application.IsCurrentThread()) { message.waitEvent.reset(new CEvent(true)); waitEvent = message.waitEvent; } else { //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n"); //OutputDebugString("Sending immediately\n"); ProcessMessage(&message); return; } } CSingleLock lock (m_critSection); if (g_application.m_bStop) { if (message.waitEvent) message.waitEvent.reset(); return; } ThreadMessage* msg = new ThreadMessage(); msg->dwMessage = message.dwMessage; msg->param1 = message.param1; msg->param2 = message.param2; msg->waitEvent = message.waitEvent; msg->lpVoid = message.lpVoid; msg->strParam = message.strParam; msg->params = message.params; if (msg->dwMessage == TMSG_DIALOG_DOMODAL) m_vecWindowMessages.push(msg); else m_vecMessages.push(msg); lock.Leave(); // this releases the lock on the vec of messages and // allows the ProcessMessage to execute and therefore // delete the message itself. Therefore any accesss // of the message itself after this point consittutes // a race condition (yarc - "yet another race condition") // if (waitEvent) // ... it just so happens we have a spare reference to the // waitEvent ... just for such contingencies :) { // ensure the thread doesn't hold the graphics lock CSingleExit exit(g_graphicsContext); waitEvent->Wait(); } }
int CApplicationMessenger::SendMsg(ThreadMessage&& message, bool wait) { std::shared_ptr<CEvent> waitEvent; std::shared_ptr<int> result; if (wait) { //Initialize result here as it's not needed for posted messages message.result = std::make_shared<int>(-1); // check that we're not being called from our application thread, else we'll be waiting // forever! if (!CThread::IsCurrentThread(m_guiThreadId)) { message.waitEvent.reset(new CEvent(true)); waitEvent = message.waitEvent; result = message.result; } else { //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n"); //OutputDebugString("Sending immediately\n"); ProcessMessage(&message); return *message.result; } } if (m_bStop) return -1; ThreadMessage* msg = new ThreadMessage(std::move(message)); CSingleLock lock (m_critSection); if (msg->dwMessage == TMSG_GUI_MESSAGE) m_vecWindowMessages.push(msg); else m_vecMessages.push(msg); lock.Leave(); // this releases the lock on the vec of messages and // allows the ProcessMessage to execute and therefore // delete the message itself. Therefore any access // of the message itself after this point constitutes // a race condition (yarc - "yet another race condition") // if (waitEvent) // ... it just so happens we have a spare reference to the // waitEvent ... just for such contingencies :) { // ensure the thread doesn't hold the graphics lock CSingleExit exit(g_graphicsContext); waitEvent->Wait(); return *result; } return -1; }
void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait) { message.hWaitEvent = NULL; if (wait) { // check that we're not being called from our application thread, else we'll be waiting // forever! if (!g_application.IsCurrentThread()) message.hWaitEvent = CreateEvent(NULL, true, false, NULL); else { //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n"); //OutputDebugString("Sending immediately\n"); ProcessMessage(&message); return; } } CSingleLock lock (m_critSection); if (g_application.m_bStop) { if (message.hWaitEvent) { CloseHandle(message.hWaitEvent); message.hWaitEvent = NULL; } return; } ThreadMessage* msg = new ThreadMessage(); msg->dwMessage = message.dwMessage; msg->dwParam1 = message.dwParam1; msg->dwParam2 = message.dwParam2; msg->hWaitEvent = message.hWaitEvent; msg->lpVoid = message.lpVoid; msg->strParam = message.strParam; msg->params = message.params; if (msg->dwMessage == TMSG_DIALOG_DOMODAL) m_vecWindowMessages.push(msg); else m_vecMessages.push(msg); lock.Leave(); if (message.hWaitEvent) { // ensure the thread doesn't hold the graphics lock CSingleExit exit(g_graphicsContext); WaitForSingleObject(message.hWaitEvent, INFINITE); CloseHandle(message.hWaitEvent); message.hWaitEvent = NULL; } }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.m_pPlayer->IsPlayingVideo()) { // why are we here if nothing is playing??? g_windowManager.PreviousWindow(); return true; } g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. // switch resolution g_graphicsContext.SetFullScreenVideo(true); // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; return true; } case GUI_MSG_WINDOW_DEINIT: { // close all active modal dialogs g_windowManager.CloseInternalModalDialogs(true); CGUIWindow::OnMessage(message); CSettings::GetInstance().Save(); CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(false); lock.Leave(); return true; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }
void CCdgReader::Process() { double fCurTime = 0.0f; double fNewTime=0.f; CStdString strExt; CUtil::GetExtension(m_pLoader->GetFileName(),strExt); strExt = m_pLoader->GetFileName().substr(0,m_pLoader->GetFileName().size()-strExt.size()); while (!CThread::m_bStop) { CSingleLock lock (m_CritSection); double fDiff; const CMusicInfoTag* tag = g_infoManager.GetCurrentSongTag(); if (!tag || tag->GetURL().substr(0,strExt.size()) != strExt) { Sleep(15); if (CThread::m_bStop) return; CUtil::GetExtension(m_pLoader->GetFileName(),strExt); strExt = m_pLoader->GetFileName().substr(0,m_pLoader->GetFileName().size()-strExt.size()); fDiff = 0.f; } else { fNewTime=m_pLyrics->getSongTime(); fDiff = fNewTime-fCurTime-m_fAVDelay; } if (fDiff < -0.3f) { CStdString strFile = m_pLoader->GetFileName(); m_pLoader->StopStream(); while (m_pLoader->GetCurSubCode()) {} m_pLoader->StreamFile(strFile); m_uiNumReadSubCodes = 0; m_Cdg.ClearDisplay(); fNewTime = m_pLyrics->getSongTime(); SkipUpToTime((float)fNewTime-m_fAVDelay); } else ReadUpToTime((float)fNewTime-m_fAVDelay); fCurTime = fNewTime; lock.Leave(); Sleep(15); } }
int CApplicationMessenger::SetResponse(CStdString response) { /* 参数: 1、 返回: 1、 说明: 1、 */ CSingleLock lock (m_critBuffer); bufferResponse=response; lock.Leave(); return 0; }
void CApplicationMessenger::SendMsg(ThreadMessage&& message, bool wait) { std::shared_ptr<CEvent> waitEvent; if (wait) { // check that we're not being called from our application thread, else we'll be waiting // forever! if (!g_application.IsCurrentThread()) { message.waitEvent.reset(new CEvent(true)); waitEvent = message.waitEvent; } else { ProcessMessage(&message); return; } } if (g_application.m_bStop) return; ThreadMessage* msg = new ThreadMessage(std::move(message)); CSingleLock lock (m_critSection); if (msg->dwMessage == TMSG_GUI_MESSAGE) m_vecWindowMessages.push(msg); else m_vecMessages.push(msg); lock.Leave(); // this releases the lock on the vec of messages and // allows the ProcessMessage to execute and therefore // delete the message itself. Therefore any accesss // of the message itself after this point consittutes // a race condition (yarc - "yet another race condition") // if (waitEvent) // ... it just so happens we have a spare reference to the // waitEvent ... just for such contingencies :) { // ensure the thread doesn't hold the graphics lock CSingleExit exit(g_graphicsContext); waitEvent->Wait(); } }
void CApplicationMessenger::ProcessWindowMessages() { CSingleLock lock (m_critSection); //message type is window, process window messages while (m_vecWindowMessages.size() > 0) { ThreadMessage* pMsg = m_vecWindowMessages.front(); //first remove the message from the queue, else the message could be processed more then once m_vecWindowMessages.pop(); // leave here in case we make more thread messages from this one lock.Leave(); ProcessMessage(pMsg); if (pMsg->hWaitEvent) SetEvent(pMsg->hWaitEvent); delete pMsg; lock.Enter(); } }
void CApplicationMessenger::ProcessMessages() { /* 参数: 1、 返回: 1、 说明: 1、处理消息,实质就是从m_vecMessages 队列中取出每个消息,然后分别对此 消息调用ProcessMessage 进行处理,见消息队列m_vecMessages 的定义 2、注意此函数与ProcessMessage 方法的区别( 注意此函数多一个s 字母),此函数 是处理m_vecMessages 队列中的所有消息的,而ProcessMessage 只是处理一个消息 */ // process threadmessages CSingleLock lock (m_critSection); while (m_vecMessages.size() > 0) { ThreadMessage* pMsg = m_vecMessages.front(); //first remove the message from the queue, else the message could be processed more then once m_vecMessages.pop(); //Leave here as the message might make another //thread call processmessages or sendmessage boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent; lock.Leave(); // <- see the large comment in SendMessage ^ ProcessMessage(pMsg); /* 处理一条消息*/ if (waitEvent) waitEvent->Set(); delete pMsg; lock.Enter(); } }
void CApplicationMessenger::ProcessMessages() { // process threadmessages CSingleLock lock (m_critSection); while (m_vecMessages.size() > 0) { ThreadMessage* pMsg = m_vecMessages.front(); //first remove the message from the queue, else the message could be processed more then once m_vecMessages.pop(); //Leave here as the message might make another //thread call processmessages or sendmessage lock.Leave(); ProcessMessage(pMsg); if (pMsg->hWaitEvent) SetEvent(pMsg->hWaitEvent); delete pMsg; lock.Enter(); } }
void CApplicationMessenger::ProcessWindowMessages() { CSingleLock lock (m_critSection); //message type is window, process window messages while (!m_vecWindowMessages.empty()) { ThreadMessage* pMsg = m_vecWindowMessages.front(); //first remove the message from the queue, else the message could be processed more then once m_vecWindowMessages.pop(); // leave here in case we make more thread messages from this one std::shared_ptr<CEvent> waitEvent = pMsg->waitEvent; lock.Leave(); // <- see the large comment in SendMessage ^ ProcessMessage(pMsg); if (waitEvent) waitEvent->Set(); delete pMsg; lock.Enter(); } }
void CApplicationMessenger::ProcessMessages() { // process threadmessages CSingleLock lock (m_critSection); while (!m_vecMessages.empty()) { ThreadMessage* pMsg = m_vecMessages.front(); //first remove the message from the queue, else the message could be processed more then once m_vecMessages.pop(); //Leave here as the message might make another //thread call processmessages or sendmessage std::shared_ptr<CEvent> waitEvent = pMsg->waitEvent; lock.Leave(); // <- see the large comment in SendMessage ^ ProcessMessage(pMsg); if (waitEvent) waitEvent->Set(); delete pMsg; lock.Enter(); } }
void CApplicationMessenger::ProcessWindowMessages() { /* 参数: 1、 返回: 1、 说明: 1、处理消息,实质就是从m_vecWindowMessages 队列中取出每个消息,然后分别对此 消息调用ProcessMessage 进行处理 2、见消息队列m_vecWindowMessages 的定义 */ CSingleLock lock (m_critSection); //message type is window, process window messages while (m_vecWindowMessages.size() > 0) { ThreadMessage* pMsg = m_vecWindowMessages.front(); //first remove the message from the queue, else the message could be processed more then once m_vecWindowMessages.pop(); // leave here in case we make more thread messages from this one boost::shared_ptr<CEvent> waitEvent = pMsg->waitEvent; lock.Leave(); // <- see the large comment in SendMessage ^ ProcessMessage(pMsg); if (waitEvent) waitEvent->Set(); delete pMsg; lock.Enter(); } }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.IsPlayingVideo()) { // why are we here if nothing is playing??? g_windowManager.PreviousWindow(); return true; } g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; m_bGroupSelectShow = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. // switch resolution g_graphicsContext.SetFullScreenVideo(true); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(false); #endif // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; if (CUtil::IsUsingTTFSubtitles()) { CSingleLock lock (m_fontLock); CStdString fontPath = "special://xbmc/media/Fonts/"; fontPath += g_guiSettings.GetString("subtitles.font"); // We scale based on PAL4x3 - this at least ensures all sizing is constant across resolutions. RESOLUTION_INFO pal(720, 576, 0); CGUIFont *subFont = g_fontManager.LoadTTF("__subtitle__", fontPath, color[g_guiSettings.GetInt("subtitles.color")], 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), false, 1.0f, 1.0f, &pal, true); CGUIFont *borderFont = g_fontManager.LoadTTF("__subtitleborder__", fontPath, 0xFF000000, 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), true, 1.0f, 1.0f, &pal, true); if (!subFont || !borderFont) CLog::Log(LOGERROR, "CGUIWindowFullScreen::OnMessage(WINDOW_INIT) - Unable to load subtitle font"); else m_subsLayout = new CGUITextLayout(subFont, true, 0, borderFont); } else m_subsLayout = NULL; return true; } case GUI_MSG_WINDOW_DEINIT: { CGUIWindow::OnMessage(message); CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT); if (pDialog) pDialog->Close(true); CGUIDialogSlider *slider = (CGUIDialogSlider *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER); if (slider) slider->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_GUIDE); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_DIRECTOR); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CUTTER); if (pDialog) pDialog->Close(true); FreeResources(true); CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(false); lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(false); #endif CSingleLock lockFont(m_fontLock); if (m_subsLayout) { g_fontManager.Unload("__subtitle__"); g_fontManager.Unload("__subtitleborder__"); delete m_subsLayout; m_subsLayout = NULL; } return true; } case GUI_MSG_CLICKED: { unsigned int iControl = message.GetSenderId(); if (iControl == CONTROL_GROUP_CHOOSER && g_PVRManager.IsStarted()) { // Get the currently selected label of the Select button CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl); OnMessage(msg); CStdString strLabel = msg.GetLabel(); CPVRChannelPtr playingChannel; if (g_PVRManager.GetCurrentChannel(playingChannel)) { CPVRChannelGroupPtr selectedGroup = g_PVRChannelGroups->Get(playingChannel->IsRadio())->GetByName(strLabel); if (selectedGroup) { g_PVRManager.SetPlayingGroup(selectedGroup); CLog::Log(LOGDEBUG, "%s - switched to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str()); if (!selectedGroup->IsGroupMember(*playingChannel)) { CLog::Log(LOGDEBUG, "%s - channel '%s' is not a member of '%s', switching to channel 1 of the new group", __FUNCTION__, playingChannel->ChannelName().c_str(), selectedGroup->GroupName().c_str()); CFileItemPtr switchChannel = selectedGroup->GetByChannelNumber(1); if (switchChannel && switchChannel->HasPVRChannelInfoTag()) OnAction(CAction(ACTION_CHANNEL_SWITCH, (float) switchChannel->GetPVRChannelInfoTag()->ChannelNumber())); else { CLog::Log(LOGERROR, "%s - cannot find channel '1' in group %s", __FUNCTION__, selectedGroup->GroupName().c_str()); CApplicationMessenger::Get().MediaStop(false); } } } else { CLog::Log(LOGERROR, "%s - could not switch to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str()); CApplicationMessenger::Get().MediaStop(false); } } else { CLog::Log(LOGERROR, "%s - cannot find the current channel", __FUNCTION__); CApplicationMessenger::Get().MediaStop(false); } // hide the control and reset focus m_bGroupSelectShow = false; SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER); // SET_CONTROL_FOCUS(0, 0); return true; } break; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.IsPlayingVideo()) { // why are we here if nothing is playing??? g_windowManager.PreviousWindow(); return true; } g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. // switch resolution g_graphicsContext.SetFullScreenVideo(true); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(false); #endif // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; if (CUtil::IsUsingTTFSubtitles()) { CSingleLock lock (m_fontLock); CStdString fontPath = "special://xbmc/media/Fonts/"; fontPath += g_guiSettings.GetString("subtitles.font"); // We scale based on PAL4x3 - this at least ensures all sizing is constant across resolutions. RESOLUTION_INFO pal(720, 576, 0); CGUIFont *subFont = g_fontManager.LoadTTF("__subtitle__", fontPath, color[g_guiSettings.GetInt("subtitles.color")], 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), false, 1.0f, 1.0f, &pal, true); CGUIFont *borderFont = g_fontManager.LoadTTF("__subtitleborder__", fontPath, 0xFF000000, 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), true, 1.0f, 1.0f, &pal, true); if (!subFont || !borderFont) CLog::Log(LOGERROR, "CGUIWindowFullScreen::OnMessage(WINDOW_INIT) - Unable to load subtitle font"); else m_subsLayout = new CGUITextLayout(subFont, true, 0, borderFont); } else m_subsLayout = NULL; return true; } case GUI_MSG_WINDOW_DEINIT: { CGUIWindow::OnMessage(message); CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT); if (pDialog) pDialog->Close(true); CGUIDialogSlider *slider = (CGUIDialogSlider *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER); if (slider) slider->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO); if (pDialog) pDialog->Close(true); FreeResources(true); CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(false); lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(false); #endif CSingleLock lockFont(m_fontLock); if (m_subsLayout) { g_fontManager.Unload("__subtitle__"); g_fontManager.Unload("__subtitleborder__"); delete m_subsLayout; m_subsLayout = NULL; } return true; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }
int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts, bool &settings_changed) { CSingleLock lock (m_critSection); OMX_ERRORTYPE omx_err; if( m_drop_state || !m_is_open ) return true; unsigned int demuxer_bytes = (unsigned int)iSize; uint8_t *demuxer_content = pData; if (demuxer_content && demuxer_bytes > 0) { OMX_U32 nFlags = 0; if(m_setStartTime) { nFlags |= OMX_BUFFERFLAG_STARTTIME; CLog::Log(LOGDEBUG, "OMXVideo::Decode VDec : setStartTime %f\n", (pts == DVD_NOPTS_VALUE ? 0.0 : pts) / DVD_TIME_BASE); m_setStartTime = false; } if (pts == DVD_NOPTS_VALUE && dts == DVD_NOPTS_VALUE) nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; else if (pts == DVD_NOPTS_VALUE) nFlags |= OMX_BUFFERFLAG_TIME_IS_DTS; while(demuxer_bytes) { // 500ms timeout OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(500); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "OMXVideo::Decode timeout\n"); return false; } omx_buffer->nFlags = nFlags; omx_buffer->nOffset = 0; omx_buffer->nTimeStamp = ToOMXTime((uint64_t)(pts != DVD_NOPTS_VALUE ? pts : dts != DVD_NOPTS_VALUE ? dts : 0)); omx_buffer->nFilledLen = std::min((OMX_U32)demuxer_bytes, omx_buffer->nAllocLen); memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen); demuxer_bytes -= omx_buffer->nFilledLen; demuxer_content += omx_buffer->nFilledLen; if(demuxer_bytes == 0) omx_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); m_omx_decoder.DecoderEmptyBufferDone(m_omx_decoder.GetComponent(), omx_buffer); return false; } //CLog::Log(LOGINFO, "VideD: dts:%.0f pts:%.0f size:%d)\n", dts, pts, iSize); ResolutionUpdateInfo resinfo = {}; omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, 0); if (omx_err == OMX_ErrorNone) { if(!PortSettingsChanged(resinfo)) { CLog::Log(LOGERROR, "%s::%s - error PortSettingsChanged omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); return false; } } omx_err = m_omx_decoder.WaitForEvent(OMX_EventParamOrConfigChanged, 0); if (omx_err == OMX_ErrorNone) { if(!PortSettingsChanged(resinfo)) { CLog::Log(LOGERROR, "%s::%s - error PortSettingsChanged (EventParamOrConfigChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } } lock.Leave(); if (resinfo.changed && m_res_callback) m_res_callback(m_res_ctx, resinfo.width, resinfo.height, resinfo.framerate, resinfo.display_aspect); } settings_changed = m_settings_changed; return true; } return false; }
void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait) { /* 参数: 1、message : 传入要发送的消息( 即要被处理的消息) 2、wait : 此消息是否允许被等待后在处理( 初步理解如此。。。) 返回: 1、 说明: 1、发送消息的原理: a、 b、 c、 */ message.waitEvent.reset(); boost::shared_ptr<CEvent> waitEvent; if (wait) /* 需要等待*/ { // check that we're not being called from our application thread, else we'll be waiting // forever! if (!g_application.IsCurrentThread()) /* 如果不是主线程,需要等待*/ { message.waitEvent.reset(new CEvent(true)); waitEvent = message.waitEvent; } else /* 是主线程,不需要等待则直接处理消息*/ { //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n"); //OutputDebugString("Sending immediately\n"); ProcessMessage(&message); return; } } /* 程序执行到此处有两种情况 1、wait 参数为false,即不需要等待 2、wait 参数为true,即需要等待,但不是主线程 */ CSingleLock lock (m_critSection); if(g_application.m_bStop) { /* 主线程已经stop 了,则返回*/ if (message.waitEvent) message.waitEvent.reset(); return; } /* 程序执行到此处时,主线程没有stop */ ThreadMessage* msg = new ThreadMessage(); msg->dwMessage = message.dwMessage; msg->dwParam1 = message.dwParam1; msg->dwParam2 = message.dwParam2; msg->waitEvent = message.waitEvent; msg->lpVoid = message.lpVoid; msg->strParam = message.strParam; msg->params = message.params; /* 将消息添加到相应的消息队列中,即m_vecWindowMessages、m_vecMessages 中的一个*/ if (msg->dwMessage == TMSG_DIALOG_DOMODAL)/* 模态显示的消息*/ m_vecWindowMessages.push(msg); else m_vecMessages.push(msg); lock.Leave(); // this releases the lock on the vec of messages and // allows the ProcessMessage to execute and therefore // delete the message itself. Therefore any accesss // of the message itself after this point consittutes // a race condition (yarc - "yet another race condition") // if (waitEvent) // ... it just so happens we have a spare reference to the // waitEvent ... just for such contingencies :) { // ensure the thread doesn't hold the graphics lock CSingleExit exit(g_graphicsContext); waitEvent->Wait(); } }
void CApplicationRenderer::Process() { #ifndef HAS_SDL int iWidth = 0; int iHeight = 0; int iLeft = 0; int iTop = 0; LPDIRECT3DSURFACE8 lpSurfaceBack = NULL; LPDIRECT3DSURFACE8 lpSurfaceFront = NULL; while (!m_bStop) { if (!m_enabled || g_graphicsContext.IsFullScreenVideo()) { Sleep(50); continue; } if (!m_pWindow || iWidth == 0 || iHeight == 0 || m_Resolution != g_graphicsContext.GetVideoResolution()) { m_pWindow = (CGUIDialogBusy*)m_gWindowManager.GetWindow(WINDOW_DIALOG_BUSY); if (m_pWindow) { m_pWindow->Initialize();//need to load the window to determine size. if (m_pWindow->GetID() == WINDOW_INVALID) { //busywindow couldn't be loaded so stop this thread. m_pWindow = NULL; m_bStop = true; break; } SAFE_RELEASE(m_lpSurface); FRECT rect = m_pWindow->GetScaledBounds(); m_pWindow->ClearAll(); //unload iLeft = (int)floor(rect.left); iTop = (int)floor(rect.top); iWidth = (int)ceil(rect.right - rect.left); iHeight = (int)ceil(rect.bottom - rect.top); m_Resolution = g_graphicsContext.GetVideoResolution(); } } float t0 = (1000.0f/g_graphicsContext.GetFPS()); float t1 = m_time + t0; //time when we expect a new render float t2 = (float)timeGetTime(); if (t1 < t2) //we're late rendering { try { if (timeGetTime() >= (m_time + g_advancedSettings.m_busyDialogDelay)) { CSingleLock lockg (g_graphicsContext); if (m_prevbusycount != m_busycount) { Sleep(1); continue; } if (!m_pWindow || iWidth == 0 || iHeight == 0) { Sleep(1000); continue; } if (m_Resolution != g_graphicsContext.GetVideoResolution()) { continue; } if (m_busycount > 0) m_busycount--; //no busy indicator if a progress dialog is showing if ((m_gWindowManager.HasModalDialog() && (m_gWindowManager.GetTopMostModalDialogID() != WINDOW_VIDEO_INFO) && (m_gWindowManager.GetTopMostModalDialogID() != WINDOW_MUSIC_INFO)) || (m_gWindowManager.GetTopMostModalDialogID() == WINDOW_DIALOG_PROGRESS)) { //TODO: render progress dialog here instead of in dialog::Progress m_time = timeGetTime(); lockg.Leave(); Sleep(1); continue; } if (m_lpSurface == NULL) { D3DSURFACE_DESC desc; g_application.RenderNoPresent(); HRESULT result = g_graphicsContext.Get3DDevice()->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceFront); if (SUCCEEDED(result)) { lpSurfaceFront->GetDesc( &desc ); iLeft = 0; iTop = 0; iWidth = desc.Width; iHeight = desc.Height; } else { lockg.Leave(); Sleep(1000); continue; } if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->CreateImageSurface(iWidth, iHeight, desc.Format, &m_lpSurface))) { SAFE_RELEASE(lpSurfaceFront); lockg.Leave(); Sleep(1000); continue; } //copy part underneeth busy dialog const RECT rc = { iLeft, iTop, iLeft + iWidth, iTop + iHeight }; const RECT rcDest = { 0, 0, iWidth, iHeight }; if (!CopySurface(lpSurfaceFront, &rc, m_lpSurface, &rcDest)) { SAFE_RELEASE(lpSurfaceFront); SAFE_RELEASE(m_lpSurface); lockg.Leave(); Sleep(1000); continue; } //copy front buffer to backbuffer(s) to avoid jumping bool bBufferCopied = true; for (int i = 0; i < g_graphicsContext.GetBackbufferCount(); i++) { if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->GetBackBuffer( i, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceBack))) { bBufferCopied = false; break; } if (!CopySurface(lpSurfaceFront, NULL, lpSurfaceBack, NULL)) { bBufferCopied = false; break; } SAFE_RELEASE(lpSurfaceBack); } if (!bBufferCopied) { SAFE_RELEASE(lpSurfaceFront); SAFE_RELEASE(lpSurfaceBack); SAFE_RELEASE(m_lpSurface); lockg.Leave(); Sleep(1000); continue; } SAFE_RELEASE(lpSurfaceFront); } if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceBack))) { lockg.Leave(); Sleep(1000); continue; } g_graphicsContext.Get3DDevice()->BeginScene(); //copy dialog background to backbuffer const RECT rc = { 0, 0, iWidth, iHeight }; const RECT rcDest = { iLeft, iTop, iLeft + iWidth, iTop + iHeight }; const D3DRECT rc2 = { iLeft, iTop, iLeft + iWidth, iTop + iHeight }; g_graphicsContext.Get3DDevice()->Clear(1, &rc2, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00010001, 1.0f, 0L); if (!CopySurface(m_lpSurface, &rc, lpSurfaceBack, &rcDest)) { SAFE_RELEASE(lpSurfaceBack); g_graphicsContext.Get3DDevice()->EndScene(); lockg.Leave(); Sleep(1000); continue; } SAFE_RELEASE(lpSurfaceBack); if (!m_busyShown) { m_pWindow->Show(); m_busyShown = true; } m_pWindow->Render(); g_graphicsContext.Get3DDevice()->EndScene(); //D3DSWAPEFFECT_DISCARD is used so we can't just present the busy rect but can only present the entire screen. g_graphicsContext.Get3DDevice()->Present( NULL, NULL, NULL, NULL ); } m_busycount++; m_prevbusycount = m_busycount; } catch (...) { CLog::Log(LOGERROR, __FUNCTION__" - Exception caught when busy rendering"); SAFE_RELEASE(lpSurfaceFront); SAFE_RELEASE(lpSurfaceBack); SAFE_RELEASE(m_lpSurface); } } Sleep(1); } #endif }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.IsPlayingVideo()) { // why are we here if nothing is playing??? m_gWindowManager.PreviousWindow(); return true; } m_bLastRender = false; g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. #ifdef HAS_XBOX_HARDWARE // Disable nav sounds if spindown is active as they are loaded // from HDD all the time. if ( !g_application.CurrentFileItem().IsHD() && (g_guiSettings.GetInt("harddisk.remoteplayspindown") || g_guiSettings.GetInt("harddisk.spindowntime")) ) { if (!g_guiSettings.GetBool("lookandfeel.soundsduringplayback")) g_audioManager.Enable(false); } #endif // setup the brightness, contrast and resolution CUtil::SetBrightnessContrastGammaPercent(g_stSettings.m_currentVideoSettings.m_Brightness, g_stSettings.m_currentVideoSettings.m_Contrast, g_stSettings.m_currentVideoSettings.m_Gamma, false); // switch resolution CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(true); #ifdef HAS_VIDEO_PLAYBACK RESOLUTION res = g_renderManager.GetResolution(); g_graphicsContext.SetVideoResolution(res, false, false); #endif lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(false); #endif // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; if (CUtil::IsUsingTTFSubtitles()) { CSingleLock lock (m_fontLock); CStdString fontPath = _P("Q:\\media\\Fonts\\"); fontPath += g_guiSettings.GetString("subtitles.font"); #ifdef __APPLE__ // We scale based on PAL16x9 - this at least ensures all sizing is constant across resolutions. // I'm picking 16x9 because the 4x3 aspect below gives me squashed subtitles. // CGUIFont *subFont = g_fontManager.LoadTTF("__subtitle__", PTH_IC(fontPath), color[g_guiSettings.GetInt("subtitles.color")], 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), 1.0f, 1.0f, PAL_16x9); #else // We scale based on PAL4x3 - this at least ensures all sizing is constant across resolutions CGUIFont *subFont = g_fontManager.LoadTTF("__subtitle__", PTH_IC(fontPath), color[g_guiSettings.GetInt("subtitles.color")], 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), 1.0f, 1.0f, PAL_4x3); #endif if (!subFont) CLog::Log(LOGERROR, "CGUIWindowFullScreen::OnMessage(WINDOW_INIT) - Unable to load subtitle font"); else m_subsLayout = new CGUITextLayout(subFont, true); } else m_subsLayout = NULL; return true; } case GUI_MSG_WINDOW_DEINIT: { CGUIWindow::OnMessage(message); CGUIDialog *pDialog = (CGUIDialog *)m_gWindowManager.GetWindow(WINDOW_OSD); if (pDialog) pDialog->Close(true); FreeResources(true); CSingleLock lock (g_graphicsContext); CUtil::RestoreBrightnessContrastGamma(); g_graphicsContext.SetFullScreenVideo(false); #ifndef HAS_SDL g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution, TRUE); #endif lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(false); #endif CSingleLock lockFont(m_fontLock); if (m_subsLayout) { g_fontManager.Unload("__subtitle__"); delete m_subsLayout; m_subsLayout = NULL; } if (g_guiSettings.GetBool("lookandfeel.soundsduringplayback")) g_audioManager.Enable(true); return true; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.m_pPlayer->IsPlayingVideo()) { // why are we here if nothing is playing??? g_windowManager.PreviousWindow(); return true; } g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; m_bGroupSelectShow = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. // switch resolution g_graphicsContext.SetFullScreenVideo(true); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(); #endif // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; return true; } case GUI_MSG_WINDOW_DEINIT: { CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_GUIDE); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_DIRECTOR); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CUTTER); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SUBTITLES); if (pDialog) pDialog->Close(true); CGUIWindow::OnMessage(message); CSettings::Get().Save(); CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(false); lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(); #endif return true; } case GUI_MSG_CLICKED: { unsigned int iControl = message.GetSenderId(); if (iControl == CONTROL_GROUP_CHOOSER && g_PVRManager.IsStarted()) { // Get the currently selected label of the Select button CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl); OnMessage(msg); CStdString strLabel = msg.GetLabel(); CPVRChannelPtr playingChannel; if (g_PVRManager.GetCurrentChannel(playingChannel)) { CPVRChannelGroupPtr selectedGroup = g_PVRChannelGroups->Get(playingChannel->IsRadio())->GetByName(strLabel); if (selectedGroup) { g_PVRManager.SetPlayingGroup(selectedGroup); CLog::Log(LOGDEBUG, "%s - switched to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str()); if (!selectedGroup->IsGroupMember(*playingChannel)) { CLog::Log(LOGDEBUG, "%s - channel '%s' is not a member of '%s', switching to channel 1 of the new group", __FUNCTION__, playingChannel->ChannelName().c_str(), selectedGroup->GroupName().c_str()); CFileItemPtr switchChannel = selectedGroup->GetByChannelNumber(1); if (switchChannel && switchChannel->HasPVRChannelInfoTag()) g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float) switchChannel->GetPVRChannelInfoTag()->ChannelNumber())); else { CLog::Log(LOGERROR, "%s - cannot find channel '1' in group %s", __FUNCTION__, selectedGroup->GroupName().c_str()); CApplicationMessenger::Get().MediaStop(false); } } } else { CLog::Log(LOGERROR, "%s - could not switch to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str()); CApplicationMessenger::Get().MediaStop(false); } } else { CLog::Log(LOGERROR, "%s - cannot find the current channel", __FUNCTION__); CApplicationMessenger::Get().MediaStop(false); } // hide the control and reset focus m_bGroupSelectShow = false; SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER); // SET_CONTROL_FOCUS(0, 0); return true; } break; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.m_pPlayer->IsPlayingVideo()) { // why are we here if nothing is playing??? g_windowManager.PreviousWindow(); return true; } g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. // switch resolution g_graphicsContext.SetFullScreenVideo(true); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(); #endif // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; return true; } case GUI_MSG_WINDOW_DEINIT: { CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_GUIDE); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SUBTITLES); if (pDialog) pDialog->Close(true); CGUIWindow::OnMessage(message); CSettings::Get().Save(); CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(false); lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(); g_renderManager.FrameFinish(); #endif return true; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }