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; }
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); } } }