/*
* 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 2 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()
);
}