// [188] [188] [188] [100] [88] // 0..187 188..375 376..563 564..663 0..87 // datalen=664 void CPacketSync::OnRawData(byte* pData, int nDataLen) { int syncOffset=0; if (m_tempBufferPos >=0 ) { syncOffset = TS_PACKET_LEN - m_tempBufferPos; memcpy(&m_tempBuffer[m_tempBufferPos], pData, syncOffset); OnTsPacket(m_tempBuffer); m_tempBufferPos = 0; } while (syncOffset < nDataLen) { if (syncOffset + TS_PACKET_LEN > nDataLen) break; if (pData[syncOffset] != TS_PACKET_SYNC) { syncOffset++; continue; } OnTsPacket( &pData[syncOffset] ); syncOffset += TS_PACKET_LEN; } if (syncOffset < nDataLen) { m_tempBufferPos= nDataLen - syncOffset; memcpy( m_tempBuffer, &pData[syncOffset], m_tempBufferPos ); } }
/// This method reads the next READ_SIZE bytes from the file /// and processes the raw data /// When a TS packet has been discovered, OnTsPacket(byte* tsPacket) gets called // which in its turn deals with the packet int CDeMultiplexer::ReadFromFile(bool pollEvents) { if (m_filter.IsStopping()) return 0; CAutoLock lock (&m_sectionRead); int dwReadBytes = 0; bool pause = false; int readSize = sizeof(m_readBuffer); if (pollEvents) readSize = 0; dwReadBytes = m_filter.lib.Read(m_readBuffer, readSize, pause, false); if (dwReadBytes > 0) { int pos = 4; while (pos < dwReadBytes) { OnTsPacket(&m_readBuffer[pos]); pos += 192; } m_iReadErrors = 0; if (dwReadBytes < sizeof(m_readBuffer)) FlushPESBuffers(false, true); return dwReadBytes; } else if (dwReadBytes == -1) { LogDebug("Read failed...failure on libbluray side"); m_bReadFailed = true; m_iReadErrors++; if (m_iReadErrors > MAX_CONSECUTIVE_READ_ERRORS) { LogDebug("Read failed too many times... EOF or broken disc?"); m_bEndOfFile = true; m_filter.NotifyEvent(EC_ERRORABORT, 0, 0); } } /*else if (!pause) { LogDebug("Read failed...EOF"); m_bEndOfFile = true; m_filter.NotifyEvent(EC_ERRORABORT, 0, 0); }*/ else if (pause && m_bFlushBuffersOnPause) { m_bFlushBuffersOnPause = false; FlushPESBuffers(false, true); } return 0; }
void CSectionDecoder::OnTsPacket(byte* tsPacket) { if (m_pid < 0) return; if (tsPacket == NULL) return; m_header.Decode(tsPacket); OnTsPacket(m_header, tsPacket); }
// Ambass : Now, need to have 2 consecutive TS_PACKET_SYNC to try avoiding bad synchronisation. // In case of data flow change ( Seek, tv Zap .... ) Reset() should be called first to flush buffer. void CPacketSync::OnRawData(byte* pData, int nDataLen) { int syncOffset = 0; if (m_tempBufferPos > 0 ) { if (pData[TS_PACKET_LEN - m_tempBufferPos] == TS_PACKET_SYNC) { syncOffset = TS_PACKET_LEN - m_tempBufferPos; if (syncOffset) memcpy(&m_tempBuffer[m_tempBufferPos], pData, syncOffset); OnTsPacket(m_tempBuffer); } m_tempBufferPos = 0; } while (syncOffset + TS_PACKET_LEN < nDataLen) { if ((pData[syncOffset] == TS_PACKET_SYNC) && (pData[syncOffset + TS_PACKET_LEN] == TS_PACKET_SYNC)) { OnTsPacket( &pData[syncOffset] ); syncOffset += TS_PACKET_LEN; } else syncOffset++; } // Here we have less than 188+1 bytes while (syncOffset < nDataLen) { if (pData[syncOffset] == TS_PACKET_SYNC) { m_tempBufferPos = nDataLen - syncOffset; memcpy( m_tempBuffer, &pData[syncOffset], m_tempBufferPos ); return; } else syncOffset++; } m_tempBufferPos = 0 ; }
// Ambass : Now, need to have 2 consecutive TS_PACKET_SYNC to try avoiding bad synchronisation. // In case of data flow change ( Seek, tv Zap .... ) Reset() should be called first to flush buffer. void CPacketSync::OnRawData(byte* pData, int nDataLen) { int syncOffset=0; int tempBuffOffset=0; bool goodPacket = false; if (m_tempBufferPos > 0 ) //We have some residual data from the last call { syncOffset = TS_PACKET_LEN - m_tempBufferPos; if (nDataLen <= syncOffset) { //not enough total data to scan through a packet length, //so add pData to the tempBuffer and return memcpy(&m_tempBuffer[m_tempBufferPos], pData, nDataLen); m_tempBufferPos += nDataLen; return ; } while ((nDataLen > syncOffset) && (m_tempBufferPos > tempBuffOffset)) { if ((m_tempBuffer[tempBuffOffset]==TS_PACKET_SYNC) && (pData[syncOffset]==TS_PACKET_SYNC)) //found a good packet { if (syncOffset) { memcpy(&m_tempBuffer[m_tempBufferPos], pData, syncOffset); } OnTsPacket(&m_tempBuffer[tempBuffOffset]); goodPacket = true; m_bInSync = true; break; } else if (m_bInSync && ((m_tempBuffer[tempBuffOffset]==TS_PACKET_SYNC) || (pData[syncOffset]==TS_PACKET_SYNC))) //found a good packet { if (syncOffset) { memcpy(&m_tempBuffer[m_tempBufferPos], pData, syncOffset); } m_tempBuffer[tempBuffOffset] = TS_PACKET_SYNC; pData[syncOffset] = TS_PACKET_SYNC; OnTsPacket(&m_tempBuffer[tempBuffOffset]); goodPacket = true; m_bInSync = false; break; } else { syncOffset++; tempBuffOffset++; m_bInSync = false; } } if (!goodPacket) { if (tempBuffOffset >= m_tempBufferPos) { //We have scanned all of the data in m_tempBuffer, //so continue search from the start of pData buffer. syncOffset = 0; } else { //move data down to discard data we have already scanned m_tempBufferPos -= tempBuffOffset; memmove(m_tempBuffer, &m_tempBuffer[tempBuffOffset], m_tempBufferPos); //add pData to the tempBuffer and return memcpy(&m_tempBuffer[m_tempBufferPos], pData, nDataLen); m_tempBufferPos += nDataLen; return; } } } m_tempBufferPos = 0; //We have consumed the residual data while (nDataLen > (syncOffset + TS_PACKET_LEN)) //minimum of TS_PACKET_LEN+1 bytes available { if (!goodPacket && (syncOffset > (TS_PACKET_LEN * 8)) ) { //No sync - abandon the buffer Reset(); return; } if ((pData[syncOffset] == TS_PACKET_SYNC) && (pData[syncOffset + TS_PACKET_LEN]==TS_PACKET_SYNC)) { OnTsPacket( &pData[syncOffset] ); syncOffset += TS_PACKET_LEN; goodPacket = true; m_bInSync = true; } else if (m_bInSync && ((pData[syncOffset] == TS_PACKET_SYNC) || (pData[syncOffset + TS_PACKET_LEN]==TS_PACKET_SYNC))) { pData[syncOffset] = TS_PACKET_SYNC; pData[syncOffset + TS_PACKET_LEN] = TS_PACKET_SYNC; OnTsPacket( &pData[syncOffset] ); syncOffset += TS_PACKET_LEN; goodPacket = true; m_bInSync = false; } else { syncOffset++; m_bInSync = false; } } // We have less than TS_PACKET_LEN+1 bytes available - store residual data for next time m_tempBufferPos= nDataLen - syncOffset; if (m_tempBufferPos) { memcpy( m_tempBuffer, &pData[syncOffset], m_tempBufferPos ); } }