diff options
Diffstat (limited to 'Src/Multiplexer/StreamList.cpp')
-rw-r--r-- | Src/Multiplexer/StreamList.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/Src/Multiplexer/StreamList.cpp b/Src/Multiplexer/StreamList.cpp new file mode 100644 index 0000000..a2766e0 --- /dev/null +++ b/Src/Multiplexer/StreamList.cpp @@ -0,0 +1,246 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + * + * You may also obtain this software under a propriety license from Microchip. + * Please contact Microchip for further information. + * + */ + +#include <time.h> +#include "StreamList.h" +#include "TsPacket.h" + + +uint32_t CStreamList::m_nInstCnt = 0; + +CStreamList::CStreamList() + : m_nInst(m_nInstCnt++) + , m_nPatVersion(1) + , m_nPatCont(0) + , m_nNextStreamSending(0) +{ +} + + + + +bool CStreamList::ReadHdd() +{ + bool bRead = false; // no read done yet + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + bRead |= m_Stream[n].ReadHdd(); // read from HDD + + return bRead; // return if there was a read +} + + + + +void CStreamList::SetSource(CSource *pSource) +{ + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + if (NULL != + m_Stream[n].GetMacAddr()) // only set in active streams + m_Stream[n].SetSource(pSource); +} + + + + +void CStreamList::GetPat(uint8_t *pTs) +{ + // ---------------------------------------------------- // + // create PAT packet // + // ---------------------------------------------------- // + pTs[0] = 0x47; // packet start + + pTs[1] = (1 << 6); // Payload Unit start indicator, PID = 0; + pTs[2] = 0; + + pTs[3] = (1 << 4) | // no adaption field + m_nPatCont; // continuity counter + + m_nPatCont = (m_nPatCont + 1) & 0xF; // update 4 bit continuity counter + + pTs[4] = 0; // PointerField: new section + + uint8_t *pPat = pTs + 5; // pointer to PAT + + pPat[0] = 0; // Table ID: Program Association Section + + uint16_t wSectionLength = 4 + 5 + 0; // 4 byte CRC, 5 bytes offset to entries, zero 4 byte entry, + + pPat[3] = 0; // stream ID (HB) + pPat[4] = 0; // stream ID (LB) + + pPat[5] = (3 << 6) | // reserved + (m_nPatVersion << 1) | // version + 1; // current/next + + pPat[6] = 0; // section number + pPat[7] = 0; // last section number + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) { // run over all streams + CMacAddr *pMac = m_Stream[n].GetMacAddr(); + if (pMac) { + pPat[wSectionLength - 4 + 3 + 0] = (PID_PMT((*pMac)[5]) >> 8); // program number + pPat[wSectionLength - 4 + 3 + 1] = PID_PMT((*pMac)[5]) & 0xFF; + + pPat[wSectionLength - 4 + 3 + 2] = (7 << 5) | // reserved + (PID_PMT((*pMac)[5]) >> 8); // Pmt PID (HB) + pPat[wSectionLength - 4 + 3 + 3] = PID_PMT((*pMac)[5]) & 0xFF; // Pmt PID (LB) + + wSectionLength += 4; + } + } + + pPat[1] = (1 << 7) | // section syntax indicator + (3 << 4) | // reserved + (wSectionLength >> 8); // section syntax 1, section length + + pPat[2] = wSectionLength & 0xFF; + + uint32_t nCrc = CTsPacket::GetCrc32(pPat,wSectionLength + 3 - 4); // CRC over entire PAT section without 4 CRC bytes + pPat[wSectionLength + 3 - 4 + 0] = (nCrc >> 24) & 0xFF; + pPat[wSectionLength + 3 - 4 + 1] = (nCrc >> 16) & 0xFF; + pPat[wSectionLength + 3 - 4 + 2] = (nCrc >> 8) & 0xFF; + pPat[wSectionLength + 3 - 4 + 3] = (nCrc) & 0xFF; + + // fill remaining packet with 0xFF + for (uint8_t *p = 1 + &pPat[wSectionLength + 3 - 4 + 3]; p < pTs + 188; p++) + *p = 0xFF; +} + +bool CStreamList::GetPatPacket(uint8_t *pTs) +{ + GetPat(pTs); + return true; +} + +bool CStreamList::GetTsPacket(uint8_t *pTs) +{ + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + { + m_nNextStreamSending++; + if ( m_nNextStreamSending >= MAX_STREAM_LIST_LEN ) + m_nNextStreamSending = 0; + + if ( m_Stream[m_nNextStreamSending].GetTsPacket(pTs) ) + return true; + } + + return false; +} + + + + +uint32_t CStreamList::GetBytesRead() +{ + uint32_t nSum = 0; + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + nSum += m_Stream[n].GetBytesRead(); + + return nSum; +} + + + + +uint32_t CStreamList::GetBytesSent() +{ + uint32_t nSum = 0; + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + nSum += m_Stream[n].GetBytesSent(); + + return nSum; +} + + + + +uint32_t CStreamList::GetErrPcr() +{ + uint32_t nSum = 0; + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + nSum += m_Stream[n].GetErrPcr(); + + return nSum; +} + + + + +uint32_t CStreamList::GetErrBufUnderflow() +{ + uint32_t nSum = 0; + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + nSum += m_Stream[n].GetErrBufUnderflow(); + + return nSum; +} + + + + +uint32_t CStreamList::GetErrTs() +{ + uint32_t nSum = 0; + + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) // run over all streams + nSum += m_Stream[n].GetErrTs(); + + return nSum; +} + + + + +CStream *CStreamList::GetStream(CMacAddr *pMacAddr) +{ + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) { + CMacAddr *pSource = m_Stream[n].GetMacAddr(); + if (NULL == pMacAddr) { + //In case of a given NULL pointer, return the first unassigned stream + if (NULL == pSource) + return &m_Stream[n]; + } else if (NULL != pSource) { + //Else search for the correct instance + if (*pMacAddr == *pSource) + return &m_Stream[n]; + } + } + return NULL; +} + + + + +void CStreamList::PrintStreamList() +{ + ConsolePrintfStart( PRIO_HIGH, "StreamListID: %u\n\n", m_nInst); + ConsolePrintfContinue("StreamID SourceID Ovfl MAC \n"); + ConsolePrintfExit("-----------------------------------------------------------\n"); + for (uint32_t n = 0; n < MAX_STREAM_LIST_LEN; n++) + m_Stream[n].PrintStream(); +} |