/* * Video On Demand Samples * * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * You may also obtain this software under a propriety license from Microchip. * Please contact Microchip for further information. * */ #include #include "Source.h" #include "Stream.h" #include "TsPacket.h" uint32_t CStream::m_nInstCnt = 0; CStream::CStream() : CRingBuffer(CTsPacket::TS_PACKET_LEN, CTsPacket::TS_PACKET_LEN, NUM_PACKETS_BUFFERED) , m_nInst(m_nInstCnt++) , m_MacAddr(NULL) , m_pCurrSource(NULL) , m_pNextSource(NULL) , m_nBytesSent(0) , m_nErrBufOvfl(0) { } CStream::~CStream() { if (NULL != m_MacAddr) { delete m_MacAddr; m_MacAddr = NULL; } if (NULL != m_pCurrSource) { m_pCurrSource->RemoveStream(this); } } bool CStream::ReadHdd() { if (NULL != m_pNextSource) { //Switch sources, if there is a new one stored. if (NULL != m_pCurrSource) // release old source m_pCurrSource->RemoveStream(this); m_pCurrSource = m_pNextSource; // store new source m_pNextSource = NULL; m_pCurrSource->AddStream(this); // start listening to this source } return (NULL == m_pCurrSource) ? false : m_pCurrSource->FillBuffer(); } void CStream::SendPmt() { if ( !GetCanWrite() ) { m_nErrBufOvfl++; return; } m_TsPmt[3] = (m_TsPmt[3] & 0xF0) | // update continuity counter (((m_TsPmt[3] & 0x0F) + 1) & 0x0F); memcpy(GetWritePos(), m_TsPmt, CTsPacket::TS_PACKET_LEN); WriteDone(); } void CStream::SendAudio(uint8_t *pTs) { if ( !GetCanWrite() ) { m_nErrBufOvfl++; return; } pTs[1] = (pTs[1] & 0xE0) | (mPID_AUDIO >> 8); // replace Audio PID pTs[2] = mPID_AUDIO & 0xFF; memcpy(GetWritePos(), pTs, CTsPacket::TS_PACKET_LEN); WriteDone(); } void CStream::SendVideo(uint8_t *pTs) { if ( !GetCanWrite() ) { m_nErrBufOvfl++; return; } pTs[1] = (pTs[1] & 0xE0) | (mPID_VIDEO >> 8); // replace video PID pTs[2] = mPID_VIDEO & 0xFF; memcpy(GetWritePos(), pTs, CTsPacket::TS_PACKET_LEN); WriteDone(); } bool CStream::GetTsPacket(uint8_t *pTs) { if ( NULL == pTs || // pointer check NULL == m_MacAddr ) // we have a target address? return false; if ( !GetCanRead() ) // ring buffer empty? if ( m_pCurrSource ) m_pCurrSource->SendTsPacket(this); // get data from source if ( !GetCanRead() ) // ring buffer still empty? return false; memcpy(pTs, GetReadPos(), CTsPacket::TS_PACKET_LEN); ReadDone(); m_nBytesSent += CTsPacket::TS_PACKET_LEN; return true; } void CStream::SetMacAddr(CMacAddr *pMacAddr) { if (NULL != m_MacAddr) { delete m_MacAddr; m_MacAddr = NULL; } m_MacAddr = new CMacAddr(pMacAddr); if (NULL != m_MacAddr) CTsPacket::CreatePmt(m_TsPmt, mPID_AUDIO, mPID_VIDEO, mPID_PMT); } uint64_t CStream::GetBytesRead() { return (NULL == m_pCurrSource) ? 0 : m_pCurrSource->GetBytesRead(); } uint64_t CStream::GetErrBufUnderflow() { return m_pCurrSource ? m_pCurrSource->GetErrBuf() : 0; } uint32_t CStream::GetErrBufOverflow() { uint32_t nRet = m_nErrBufOvfl; m_nErrBufOvfl = 0; return nRet; } uint64_t CStream::GetErrPcr() { return m_pCurrSource ? m_pCurrSource->GetErrPcr() : 0; }; uint64_t CStream::GetErrTs() { return m_pCurrSource ? m_pCurrSource->GetErrTs() : 0; }; void CStream::SetPause(bool bPause) { if (NULL != m_pCurrSource) m_pCurrSource->SetPause(bPause); } void CStream::SetRepetition(bool bRepetition) { if (m_pCurrSource) m_pCurrSource->SetRepetition(bRepetition); } void CStream::SetPos(uint16_t nPos) { if ( m_pCurrSource ) m_pCurrSource->SetPos(nPos); } void CStream::PrintStream() { ConsolePrintf( PRIO_HIGH, " %2u %3d %3u %s\r\n" , GetInstId() , NULL == m_pCurrSource ? (-1) : (m_pCurrSource->GetInstId()) , m_nErrBufOvfl , NULL == m_MacAddr ? "NULL " : m_MacAddr->ToString() ); }