Beispiel #1
0
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;
}
Beispiel #2
0
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();
}
Beispiel #3
0
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();
}
Beispiel #4
0
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();
}
Beispiel #5
0
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;
}