Beispiel #1
0
int cVNSIDemuxer::Read(sStreamPacket *packet)
{
  uint8_t *buf;
  int len;
  cTSStream *stream;

  cMutexLock lock(&m_Mutex);

  // clear packet
  if (!packet)
    return -1;
  packet->data = NULL;
  packet->streamChange = false;
  packet->pmtChange = false;

  // read TS Packet from buffer
  len = m_VideoBuffer->Read(&buf, TS_SIZE, m_endTime, m_wrapTime);
  // eof
  if (len == -2)
    return -2;
  else if (len != TS_SIZE)
    return -1;

  m_Error &= ~ERROR_DEMUX_NODATA;

  int ts_pid = TsPid(buf);

  // parse PAT/PMT
  if (ts_pid == PATPID)
  {
    m_PatPmtParser.ParsePat(buf, TS_SIZE);
  }
#if APIVERSNUM >= 10733
  else if (m_PatPmtParser.IsPmtPid(ts_pid))
#else
  else if (ts_pid == m_PatPmtParser.PmtPid())
#endif
  {
    int patVersion, pmtVersion;
    m_PatPmtParser.ParsePmt(buf, TS_SIZE);
    if (m_PatPmtParser.GetVersions(patVersion, pmtVersion))
    {
      if (pmtVersion != m_OldPmtVersion)
      {
        cChannel pmtChannel(m_CurrentChannel);
        SetChannelPids(&pmtChannel, &m_PatPmtParser);
        SetChannelStreams(&pmtChannel);
        m_PatPmtParser.Reset();
        m_OldPmtVersion = pmtVersion;
        if (EnsureParsers())
        {
          packet->pmtChange = true;
            return 1;
        }
      }
    }
  }
  else if (stream = FindStream(ts_pid))
  {
    int error = stream->ProcessTSPacket(buf, packet, m_WaitIFrame);
    if (error == 0)
    {
      if (m_WaitIFrame)
      {
        if (packet->pts != DVD_NOPTS_VALUE)
          m_FirstFramePTS = packet->pts;
        m_WaitIFrame = false;
      }

      if (packet->pts < m_FirstFramePTS)
        return 0;

      packet->serial = m_MuxPacketSerial;
      if (m_SetRefTime)
      {
        m_refTime = m_VideoBuffer->GetRefTime();
        packet->reftime = m_refTime;
        m_SetRefTime = false;
      }
      return 1;
    }
    else if (error < 0)
    {
      m_Error |= abs(error);
    }
  }

  return 0;
}
Beispiel #2
0
void cLiveStreamer::Action(void)
{
  int size = 0;
  unsigned char *buf = NULL;
  m_startup = true;

  // reset timer
  m_last_tick.Set(0);

  INFOLOG("streamer thread started.");

  while (Running())
  {
    size = 0;
    buf = Get(size);

    // try to switch channel if we aren't attached yet
    {
      cMutexLock lock(&m_FilterMutex);
      if (!IsAttached()) {
        TryChannelSwitch();
      }
    }

    if(!IsStarting() && (m_last_tick.Elapsed() > (uint64_t)(m_scanTimeout*1000)) && !m_SignalLost)
    {
      INFOLOG("timeout. signal lost!");
      sendStatus(XVDR_STREAM_STATUS_SIGNALLOST);
      m_SignalLost = true;

      // retune to restore
      cMutexLock lock(&m_FilterMutex);
      if(m_PatFilter != NULL && m_Device != NULL) {
        m_Device->Detach(m_PatFilter);
        delete m_PatFilter;
        m_PatFilter = NULL;
      }

      if(IsAttached()) {
        Detach();
      }
    }

    // no data
    if (buf == NULL || size <= TS_SIZE)
      continue;

    // Sync to TS packet
    int used = 0;
    while (size > TS_SIZE)
    {
      if (buf[0] == TS_SYNC_BYTE && buf[TS_SIZE] == TS_SYNC_BYTE)
        break;
      used++;
      buf++;
      size--;
    }
    Del(used);

    while (size >= TS_SIZE)
    {
      if(!Running())
        break;

      // TS packet sync not found !
      if (buf[0] != TS_SYNC_BYTE)
        break;

      unsigned int ts_pid = TsPid(buf);

      {
        cMutexLock lock(&m_FilterMutex);
        cTSDemuxer *demuxer = FindStreamDemuxer(ts_pid);

        if (demuxer)
          demuxer->ProcessTSPacket(buf);
      }

      buf += TS_SIZE;
      size -= TS_SIZE;
      Del(TS_SIZE);
    }
  }

  INFOLOG("streamer thread ended.");
}
void cLiveStreamer::Action(void)
{
  int size = 0;
  unsigned char *buf = NULL;
  m_startup = true;

  while (Running())
  {
    size = 0;
    buf = Get(size);

    {
      cMutexLock lock(&m_FilterMutex);
      if (!IsAttached())
      {
        INFOLOG("returning from streamer thread, receiver is no more attached");
        Clear();
        sendDetach();
        return;
      }
    }

    if(!IsStarting() && (m_last_tick.Elapsed() > (uint64_t)(m_scanTimeout*1000)) && !m_SignalLost)
    {
      INFOLOG("timeout. signal lost!");
      sendStatus(XVDR_STREAM_STATUS_SIGNALLOST);
      m_SignalLost = true;
    }

    // no data
    if (buf == NULL || size <= TS_SIZE)
      continue;

    // Sync to TS packet
    int used = 0;
    while (size > TS_SIZE)
    {
      if (buf[0] == TS_SYNC_BYTE && buf[TS_SIZE] == TS_SYNC_BYTE)
        break;
      used++;
      buf++;
      size--;
    }
    Del(used);


    while (size >= TS_SIZE)
    {
      if(!Running())
        break;

      // TS packet sync not found !
      if (buf[0] != TS_SYNC_BYTE)
        break;

      unsigned int ts_pid = TsPid(buf);

      {
        cMutexLock lock(&m_FilterMutex);
        cTSDemuxer *demuxer = FindStreamDemuxer(ts_pid);

        if (demuxer)
          demuxer->ProcessTSPacket(buf);
      }

      buf += TS_SIZE;
      size -= TS_SIZE;
      Del(TS_SIZE);
    }
  }
}