MsgQueueReturnCode CDVDMessageQueue::Put(CDVDMsg* pMsg) { if (!m_bInitialized) { CLog::Log(LOGWARNING, "CDVDMessageQueue::Put MSGQ_NOT_INITIALIZED"); pMsg->Release(); return MSGQ_NOT_INITIALIZED; } if (!pMsg) { CLog::Log(LOGFATAL, "CDVDMessageQueue::Put MSGQ_INVALID_MSG"); return MSGQ_INVALID_MSG; } DVDMessageListItem* msgItem = new DVDMessageListItem; if (!msgItem) { CLog::Log(LOGFATAL, "CDVDMessageQueue::Put MSGQ_OUT_OF_MEMORY"); return MSGQ_OUT_OF_MEMORY; } msgItem->pMsg = pMsg; msgItem->pNext = NULL; EnterCriticalSection(&m_critSection); if (!m_pFirstMessage) m_pFirstMessage = msgItem; else m_pLastMessage->pNext = msgItem; m_pLastMessage = msgItem; if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg; m_iDataSize += pMsgDemuxerPacket->GetPacketSize(); } SetEvent(m_hEvent); // inform waiter for new packet LeaveCriticalSection(&m_critSection); return MSGQ_OK; }
void CDVDPlayerSubtitle::SendMessage(CDVDMsg* pMsg) { if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg; DemuxPacket* pPacket = pMsgDemuxerPacket->GetPacket(); if (m_pOverlayCodec) { double pts = pPacket->dts != DVD_NOPTS_VALUE ? pPacket->dts : pPacket->pts; double duration = pPacket->duration; int result = m_pOverlayCodec->Decode(pPacket->pData, pPacket->iSize, pts, duration); if(result == OC_OVERLAY) { CDVDOverlay* overlay; while((overlay = m_pOverlayCodec->GetOverlay()) != NULL) { overlay->iGroupId = pPacket->iGroupId; // we assume pts is better than what // decoder gives us, only take duration // from decoder if available if(overlay->iPTSStopTime > overlay->iPTSStartTime) duration = overlay->iPTSStopTime - overlay->iPTSStartTime; else if(pPacket->duration != DVD_NOPTS_VALUE) duration = pPacket->duration; else duration = 0.0; if (pPacket->pts != DVD_NOPTS_VALUE) pts = pPacket->pts; else if(pPacket->dts != DVD_NOPTS_VALUE) pts = pPacket->dts; else pts = overlay->iPTSStartTime; overlay->iPTSStartTime = pts; if(duration) overlay->iPTSStopTime = pts + duration; else { overlay->iPTSStopTime = 0; overlay->replace = true; } m_pOverlayContainer->Add(overlay); overlay->Release(); } } } else if (m_streaminfo.codec == CODEC_ID_DVD_SUBTITLE) { CDVDOverlaySpu* pSPUInfo = m_dvdspus.AddData(pPacket->pData, pPacket->iSize, pPacket->pts); if (pSPUInfo) { CLog::Log(LOGDEBUG, "CDVDPlayer::ProcessSubData: Got complete SPU packet"); pSPUInfo->iGroupId = pPacket->iGroupId; m_pOverlayContainer->Add(pSPUInfo); pSPUInfo->Release(); } } } else if( pMsg->IsType(CDVDMsg::SUBTITLE_CLUTCHANGE) ) { CDVDMsgSubtitleClutChange* pData = (CDVDMsgSubtitleClutChange*)pMsg; for (int i = 0; i < 16; i++) { BYTE* color = m_dvdspus.m_clut[i]; BYTE* t = (BYTE*)pData->m_data[i]; // pData->m_data[i] points to an uint32_t // Byte swapping is needed between big and little endian systems #ifdef WORDS_BIGENDIAN color[0] = t[1]; // Y color[1] = t[2]; // Cr color[2] = t[3]; // Cb #else color[0] = t[2]; // Y color[1] = t[0]; // Cr color[2] = t[1]; // Cb #endif } m_dvdspus.m_bHasClut = true; } else if( pMsg->IsType(CDVDMsg::GENERAL_FLUSH) || pMsg->IsType(CDVDMsg::GENERAL_RESET) ) { m_dvdspus.Reset(); if (m_pSubtitleFileParser) m_pSubtitleFileParser->Reset(); if (m_pOverlayCodec) m_pOverlayCodec->Flush(); m_lastPts = DVD_NOPTS_VALUE; } pMsg->Release(); }
void CDVDPlayerSubtitle::SendMessage(CDVDMsg* pMsg) { CSingleLock lock(m_section); if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg; DemuxPacket* pPacket = pMsgDemuxerPacket->GetPacket(); if (m_pOverlayCodec) { int result = m_pOverlayCodec->Decode(pPacket); if(result == OC_OVERLAY) { CDVDOverlay* overlay; while((overlay = m_pOverlayCodec->GetOverlay()) != NULL) { overlay->iGroupId = pPacket->iGroupId; m_pOverlayContainer->Add(overlay); overlay->Release(); } } } else if (m_streaminfo.codec == CODEC_ID_DVD_SUBTITLE) { CDVDOverlaySpu* pSPUInfo = m_dvdspus.AddData(pPacket->pData, pPacket->iSize, pPacket->pts); if (pSPUInfo) { CLog::Log(LOGDEBUG, "CDVDPlayer::ProcessSubData: Got complete SPU packet"); pSPUInfo->iGroupId = pPacket->iGroupId; m_pOverlayContainer->Add(pSPUInfo); pSPUInfo->Release(); } } } else if( pMsg->IsType(CDVDMsg::SUBTITLE_CLUTCHANGE) ) { CDVDMsgSubtitleClutChange* pData = (CDVDMsgSubtitleClutChange*)pMsg; for (int i = 0; i < 16; i++) { BYTE* color = m_dvdspus.m_clut[i]; BYTE* t = (BYTE*)pData->m_data[i]; // pData->m_data[i] points to an uint32_t // Byte swapping is needed between big and little endian systems #ifdef WORDS_BIGENDIAN color[0] = t[1]; // Y color[1] = t[2]; // Cr color[2] = t[3]; // Cb #else color[0] = t[2]; // Y color[1] = t[0]; // Cr color[2] = t[1]; // Cb #endif } m_dvdspus.m_bHasClut = true; } else if( pMsg->IsType(CDVDMsg::GENERAL_FLUSH) || pMsg->IsType(CDVDMsg::GENERAL_RESET) ) { m_dvdspus.Reset(); if (m_pSubtitleFileParser) m_pSubtitleFileParser->Reset(); if (m_pOverlayCodec) m_pOverlayCodec->Flush(); /* We must flush active overlays on flush or if we have a file * parser since it will re-populate active items. */ if(pMsg->IsType(CDVDMsg::GENERAL_FLUSH) || m_pSubtitleFileParser) m_pOverlayContainer->Clear(); m_lastPts = DVD_NOPTS_VALUE; } pMsg->Release(); }
void CDVDPlayerSubtitle::SendMessage(CDVDMsg* pMsg) { if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg; DemuxPacket* pPacket = pMsgDemuxerPacket->GetPacket(); if (m_pOverlayCodec) { double pts = pPacket->dts != DVD_NOPTS_VALUE ? pPacket->dts : pPacket->pts; double duration = pPacket->duration; int result = m_pOverlayCodec->Decode(pPacket->pData, pPacket->iSize, pts, duration); if(result == OC_OVERLAY) { CDVDOverlay* overlay; while((overlay = m_pOverlayCodec->GetOverlay()) != NULL) { overlay->iGroupId = pPacket->iGroupId; if(pts == DVD_NOPTS_VALUE) { if(overlay->iPTSStartTime == 0 && overlay->iPTSStopTime == 0) CLog::Log(LOGWARNING, "%s - unable to find timestamp for overlay", __FUNCTION__); } else { // we assume pts is better than what // decoder gives us, only take duration // from decoder if available overlay->iPTSStopTime -= overlay->iPTSStartTime; overlay->iPTSStartTime = pts; if(overlay->iPTSStopTime == 0.0) overlay->iPTSStopTime = duration; overlay->iPTSStopTime += overlay->iPTSStartTime; } m_pOverlayContainer->Add(overlay); overlay->Release(); } } } else if (m_streaminfo.codec == CODEC_ID_DVD_SUBTITLE) { CSPUInfo* pSPUInfo = m_dvdspus.AddData(pPacket->pData, pPacket->iSize, pPacket->pts); if (pSPUInfo) { CLog::Log(LOGDEBUG, "CDVDPlayer::ProcessSubData: Got complete SPU packet"); pSPUInfo->iGroupId = pPacket->iGroupId; m_pOverlayContainer->Add(pSPUInfo); pSPUInfo->Release(); } } } else if( pMsg->IsType(CDVDMsg::SUBTITLE_CLUTCHANGE) ) { CDVDMsgSubtitleClutChange* pData = (CDVDMsgSubtitleClutChange*)pMsg; for (int i = 0; i < 16; i++) { BYTE* color = m_dvdspus.m_clut[i]; BYTE* t = (BYTE*)pData->m_data[i]; color[0] = t[2]; // Y color[1] = t[1]; // Cr color[2] = t[0]; // Cb } m_dvdspus.m_bHasClut = true; } else if( pMsg->IsType(CDVDMsg::GENERAL_FLUSH) ) { m_dvdspus.Reset(); if (m_pSubtitleFileParser) m_pSubtitleFileParser->Reset(); if (m_pOverlayCodec) m_pOverlayCodec->Flush(); m_lastPts = DVD_NOPTS_VALUE; } pMsg->Release(); }
MsgQueueReturnCode CDVDMessageQueue::Get(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds) { *pMsg = NULL; DVDMessageListItem* msgItem; int ret = 0; if (!m_bInitialized) { CLog::Log(LOGFATAL, "CDVDMessageQueue::Get MSGQ_NOT_INITIALIZED"); return MSGQ_NOT_INITIALIZED; } EnterCriticalSection(&m_critSection); while (!m_bAbortRequest) { msgItem = m_pFirstMessage; if (msgItem && !m_bCaching) { m_pFirstMessage = msgItem->pNext; if (!m_pFirstMessage) m_pLastMessage = NULL; if (msgItem->pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)msgItem->pMsg; m_iDataSize -= pMsgDemuxerPacket->GetPacketSize(); } *pMsg = msgItem->pMsg; delete msgItem; // free the list item we allocated in ::Put() ret = MSGQ_OK; break; } else if (!iTimeoutInMilliSeconds) { ret = MSGQ_TIMEOUT; break; } else { ResetEvent(m_hEvent); LeaveCriticalSection(&m_critSection); // wait for a new message if (WaitForSingleObject(m_hEvent, iTimeoutInMilliSeconds) == WAIT_TIMEOUT) { // just return here directly, we have already left critical section return MSGQ_TIMEOUT; } EnterCriticalSection(&m_critSection); } } LeaveCriticalSection(&m_critSection); if (m_bAbortRequest) return MSGQ_ABORT; return (MsgQueueReturnCode)ret; }