summaryrefslogtreecommitdiffstats
path: root/Src/Multiplexer/StreamList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Multiplexer/StreamList.cpp')
-rw-r--r--Src/Multiplexer/StreamList.cpp246
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();
+}