summaryrefslogtreecommitdiff
path: root/remux/ts2ps.c
blob: 222c39a4f7111087aa1f2e102509463f87aaddaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "remux/ts2ps.h"

class cTS2PS {
	friend void PutPES(uint8_t *Buffer, int Size, void *Data);

private:
	ipack m_Ipack;
	uint8_t *m_ResultBuffer;
	int *m_ResultCount;

public:
	cTS2PS(uint8_t *ResultBuffer, int *ResultCount, uint8_t AudioCid = 0x00, 
			bool PS = false);
	~cTS2PS();

	void PutTSPacket(const uint8_t *Buffer);
};

void PutPES(uint8_t *Buffer, int Size, void *Data) {
	cTS2PS *This = (cTS2PS*)Data;
	if (*This->m_ResultCount + Size > RESULTBUFFERSIZE) {
		esyslog("ERROR: result buffer overflow (%d + %d > %d)", 
				*This->m_ResultCount, Size, RESULTBUFFERSIZE);
		Size = RESULTBUFFERSIZE - *This->m_ResultCount;
	}
	memcpy(This->m_ResultBuffer + *This->m_ResultCount, Buffer, Size);
	*This->m_ResultCount += Size;
}

cTS2PS::cTS2PS(uint8_t *ResultBuffer, int *ResultCount, uint8_t AudioCid, 
		bool PS) {
	m_ResultBuffer = ResultBuffer;
	m_ResultCount = ResultCount;

	init_ipack(&m_Ipack, IPACKS, PutPES, PS);
	m_Ipack.cid = AudioCid;
	m_Ipack.data = (void*)this;
}

cTS2PS::~cTS2PS() {
}

void cTS2PS::PutTSPacket(const uint8_t *Buffer) {
  if (!Buffer)
     return;

  if (Buffer[1] & 0x80) { // ts error
		// TODO
	}

  if (Buffer[1] & 0x40) { // payload start
		if (m_Ipack.plength == MMAX_PLENGTH - 6 && m_Ipack.found > 6) {
    	m_Ipack.plength = m_Ipack.found - 6;
      m_Ipack.found = 0;
      send_ipack(&m_Ipack);
      reset_ipack(&m_Ipack);
    }
  }

	uint8_t off = 0;

  if (Buffer[3] & 0x20) {  // adaptation field?
		off = Buffer[4] + 1;
    if (off + 4 > TS_SIZE - 1)
      return;
  }

  instant_repack((uint8_t*)(Buffer + 4 + off), TS_SIZE - 4 - off, &m_Ipack);
}

cTS2PSRemux::cTS2PSRemux(int VPid, int APid1, int APid2, int DPid1, 
		int DPid2, bool PS) {
	m_VPid  = VPid;
	m_APid1 = APid1;
	m_APid2 = APid2;
	m_DPid1 = DPid1;
	m_DPid2 = DPid2;
  m_VRemux  =         new cTS2PS(m_ResultBuffer, &m_ResultCount, 0x00, PS);
  m_ARemux1 =         new cTS2PS(m_ResultBuffer, &m_ResultCount, 0xC0, PS);
  m_ARemux2 = APid2 ? new cTS2PS(m_ResultBuffer, &m_ResultCount, 0xC1, PS) 
	                  : NULL;
  m_DRemux1 = DPid1 ? new cTS2PS(m_ResultBuffer, &m_ResultCount, 0x00, PS) 
	                  : NULL;
  //XXX don't yet know how to tell apart primary and secondary DD data...
  m_DRemux2 = /*XXX m_DPid2 ? new cTS2PS(m_ResultBuffer, &m_ResultCount, 
			0x00, PS) : XXX*/ NULL;
}

cTS2PSRemux::~cTS2PSRemux() {
	if (m_DRemux2) delete m_DRemux2;
	if (m_DRemux1) delete m_DRemux1;
	if (m_ARemux2) delete m_ARemux2;
	delete m_ARemux1;
	delete m_VRemux;
}

void cTS2PSRemux::PutTSPacket(int Pid, const uint8_t *Data) {
	if      (Pid == m_VPid)               m_VRemux->PutTSPacket(Data);
	else if (Pid == m_APid1)              m_ARemux1->PutTSPacket(Data);
	else if (Pid == m_APid2 && m_ARemux2) m_ARemux2->PutTSPacket(Data);
	else if (Pid == m_DPid1 && m_DRemux1) m_DRemux1->PutTSPacket(Data);
	else if (Pid == m_DPid2 && m_DRemux2) m_DRemux2->PutTSPacket(Data);
}