summaryrefslogtreecommitdiffstats
path: root/Src/Multiplexer/Stream.cpp
diff options
context:
space:
mode:
authorChristian Gromm <christian.gromm@microchip.com>2016-12-08 16:46:07 +0100
committerChristian Gromm <christian.gromm@microchip.com>2016-12-08 16:46:07 +0100
commit0a28683a1ff9f3975c8b68b15017cf342bab5f3d (patch)
tree2f350b709db4d45532fc0624cfce22ec11e43ccf /Src/Multiplexer/Stream.cpp
parent18c9e9fc0000861257ab06f6a033612b0c567674 (diff)
src: vod-server: import sources
This patch adds the source tree of the Video-On-Demand server and its configuration scripts. Change-Id: I6db8c43d46c7450baf117a541bd7153496dbcd4c Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Diffstat (limited to 'Src/Multiplexer/Stream.cpp')
-rw-r--r--Src/Multiplexer/Stream.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/Src/Multiplexer/Stream.cpp b/Src/Multiplexer/Stream.cpp
new file mode 100644
index 0000000..37fa93b
--- /dev/null
+++ b/Src/Multiplexer/Stream.cpp
@@ -0,0 +1,236 @@
+/*
+ * 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 <stdint.h>
+#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()
+ );
+}