summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/mpegplay/mpegSystemStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/mpegplay/mpegSystemStream.cpp')
-rw-r--r--mpeglib/lib/mpegplay/mpegSystemStream.cpp235
1 files changed, 235 insertions, 0 deletions
diff --git a/mpeglib/lib/mpegplay/mpegSystemStream.cpp b/mpeglib/lib/mpegplay/mpegSystemStream.cpp
new file mode 100644
index 00000000..ca25d7e8
--- /dev/null
+++ b/mpeglib/lib/mpegplay/mpegSystemStream.cpp
@@ -0,0 +1,235 @@
+/*
+ reads paket input data
+ Copyright (C) 2000 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "mpegSystemStream.h"
+
+#define _RESYNC_STATE_INIT 0
+#define _RESYNC_STATE_NEED_PACKET 1
+#define _RESYNC_STATE_NEED_START 2
+
+#include <iostream>
+
+using namespace std;
+
+
+MpegSystemStream::MpegSystemStream(InputStream* input) {
+ this->input=input;
+ syncCode=0xff; // invalid
+ lState=_RESYNC_STATE_INIT;
+ tsSystemStream=new TSSystemStream(input);
+ psSystemStream=new PSSystemStream(input);
+ pesSystemStream=new PESSystemStream(input);
+}
+
+
+MpegSystemStream::~MpegSystemStream() {
+ delete tsSystemStream;
+ delete psSystemStream;
+ delete pesSystemStream;
+}
+
+
+int MpegSystemStream::getByteDirect() {
+ unsigned char byte;
+ if (input->read((char*)&byte,1) != 1) {
+ return -1;
+ }
+ return (int)byte;
+}
+
+int MpegSystemStream::readSyncCode() {
+ int byte;
+ byte=getByteDirect();
+ if (byte==-1) {
+ return false;
+ }
+
+ syncCode<<=8;
+ syncCode|=byte;
+ syncCode&=0xffffffff;
+ return true;
+
+}
+
+int MpegSystemStream::firstInitialize(MpegSystemHeader* mpegHeader) {
+
+ if (readSyncCode() == false) {
+ return false;
+ }
+ mpegHeader->setHeader(syncCode);
+
+ // SEQ_START_CODE: 1b3
+ if (mpegHeader->hasRAWHeader()) {
+ // If we found a seq_heade_start code we assume
+ // that we are a video only stream
+ // we must directly insert it.
+
+ // here we set for all future calls fixed
+ // parameter
+ mpegHeader->setLayer(_PACKET_NO_SYSLAYER); // no syslayer
+ mpegHeader->setPacketID(_PAKET_ID_VIDEO);
+ mpegHeader->setPacketLen(8192);
+ mpegHeader->resetAvailableLayers();
+ return true;
+ }
+ // no 1bb
+ if (syncCode == _SYSTEM_HEADER_START_CODE) return false;
+
+ // TS 1ba
+ if (processSystemHeader(mpegHeader) == true) {
+ // have init. we are a syslayer
+ mpegHeader->setLayer(_PACKET_SYSLAYER); // syslayer
+ lState=_RESYNC_STATE_NEED_START;
+ return true;
+ }
+ return false;
+
+}
+
+void MpegSystemStream::reset() {
+ lState=_RESYNC_STATE_NEED_PACKET;
+}
+
+
+int MpegSystemStream::nextPacket(MpegSystemHeader* mpegHeader) {
+ int layer=mpegHeader->getLayer();
+ if (layer == _PACKET_NO_SYSLAYER) {
+ return true;
+ }
+ // seek to packet
+ if (readSyncCode() == false) {
+ return false;
+ }
+
+
+ // default to "HLT" operation
+ mpegHeader->setPacketID(_PAKET_ID_NUKE);
+ mpegHeader->setPacketLen(0);
+
+
+ // here we know that we are a SYSLAYER (TS or 1ba)
+ if (lState == _RESYNC_STATE_NEED_PACKET) {
+ // no 1bb codes in resync state
+ if (syncCode == _SYSTEM_HEADER_START_CODE) return false;
+ }
+
+ // is this a syslayer _STARTCODE_ ?
+ if (MpegSystemHeader::isSystemHeader(syncCode)==true) {
+ // set startcode & process it
+ mpegHeader->setHeader(syncCode);
+ // TS 1ba 1bb
+ if (processSystemHeader(mpegHeader) == true) {
+ lState=_RESYNC_STATE_NEED_START;
+ return true;
+ }
+ reset();
+ return false;
+ }
+
+ if (lState != _RESYNC_STATE_NEED_START) return false;
+
+ // no syslayer startcode. PES processing
+ if ((syncCode & 0xFFFFFF00) == 0x00000100) {
+ int bytes=pesSystemStream->processStartCode(syncCode,mpegHeader);
+ if (bytes == 0) {
+ reset();
+ return false;
+ }
+ // if we are a TS layer we cannot read getPESPacketLength byte
+ // but only the bytes given by getTSPacketLength
+ // additionally we must store the mapping between pid and real packetID.
+ if (mpegHeader->hasTSHeader()) {
+ unsigned int pid=mpegHeader->getPid();
+ unsigned int id =mpegHeader->getPacketID();
+ printf("current PID:%x current PacketID:%x\n",pid,id);
+ MapPidStream* mapPidStream=mpegHeader->lookup(pid);
+ mapPidStream->psType=id;
+ mapPidStream->pesPacketSize=mpegHeader->getPESPacketLen();
+
+ int ts=mpegHeader->getTSPacketLen();
+ if (bytes > ts) {
+ cout << "ERROR PES READ MORE than TS HAS"<<endl;
+ return false;
+ }
+ mpegHeader->setTSPacketLen(ts-bytes);
+ return demux_ts_pes_buffer(mpegHeader);
+ }
+ // 1ba stream
+ mpegHeader->setPacketLen(mpegHeader->getPESPacketLen());
+ return true;
+ }
+
+ // something unknown/else went wrong
+ return false;
+}
+
+int MpegSystemStream::demux_ts_pes_buffer(MpegSystemHeader* mpegHeader) {
+
+
+ if (lState == _RESYNC_STATE_NEED_PACKET) {
+ cout << "NO ts_pes because of resync"<<endl;
+ return false;
+ }
+ MapPidStream* mapPidStream=mpegHeader->lookup(mpegHeader->getPid());
+
+ int pes=mapPidStream->pesPacketSize;
+ int ts=mpegHeader->getTSPacketLen();
+ int wantRead=pes;
+
+ // bug workaround for PES packetlength == 0
+ if (pes > 0) {
+ if (ts < wantRead) {
+ cout << "TS is less setting wantRead:"<<ts<<endl;
+ mapPidStream->pesPacketSize=pes-ts;
+ wantRead=ts;
+ } else {
+ // pes < ts
+ mpegHeader->setTSPacketLen(ts-pes);
+ wantRead=pes;
+ }
+ } else {
+ // in case of bug, always put the whole packet for pid in
+ wantRead=ts;
+ }
+ mpegHeader->setPacketID(mapPidStream->psType);
+ mpegHeader->setPacketLen(wantRead);
+ return true;
+}
+
+
+int MpegSystemStream::processSystemHeader(MpegSystemHeader* mpegHeader) {
+ if (mpegHeader->hasTSHeader()) {
+ if (tsSystemStream->processStartCode(mpegHeader) == true) {
+ if (mpegHeader->getPacketID() == _PAKET_ID_NUKE) {
+ // nuke the data by signalling how much bytes to nuke
+ mpegHeader->setPacketLen(mpegHeader->getTSPacketLen());
+ return true;
+ }
+ unsigned int pus=mpegHeader->getPayload_unit_start_indicator();
+ if (pus == false) {
+ // we need to append data
+ return demux_ts_pes_buffer(mpegHeader);
+ }
+ return true;
+ }
+ return false;
+ }
+ if (mpegHeader->hasPSHeader()) {
+ return (psSystemStream->processStartCode(mpegHeader));
+ }
+ return false;
+
+}
+
+
+