2 Copyright 2006-2008 Mark Calderbank
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "demuxerts.h"
24 DemuxerTS::DemuxerTS(int p_vID, int p_aID, int p_subID, int p_tID)
26 vID = p_vID; vActive = false;
27 aID = p_aID; aActive = false;
28 subID = p_subID; subActive = false;
34 void DemuxerTS::flush()
39 vPacket.init(PESTYPE_VID0);
43 aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
47 aPacket.init(PESTYPE_AUD0);
50 subPacket.init(PESTYPE_PRIVATE_1);
51 tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
60 int DemuxerTS::scan(UCHAR *buf, int len)
65 return PESTYPE_PRIVATE_1;
72 void DemuxerTS::setVID(int p_vID)
75 vPacket.init(PESTYPE_VID0);
79 void DemuxerTS::setAID(int p_aID, int type)
86 aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
87 setAudioStream(PESTYPE_SUBSTREAM_AC30);
91 aPacket.init(PESTYPE_AUD0);
92 setAudioStream(PESTYPE_AUD0);
98 void DemuxerTS::setSubID(int p_subID)
101 subPacket.init(PESTYPE_PRIVATE_1);
106 void DemuxerTS::setTID(int p_tID)
109 tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
114 int DemuxerTS::findPTS(UCHAR* buf, int len, ULLONG* dest)
116 UINT LoPattern = 0x100 | PESTYPE_VID0,
117 HiPattern = 0x100 | PESTYPE_VIDMAX;
121 UINT pattern = *(UINT*)buf;
123 if (pattern < LoPattern || pattern > HiPattern) continue;
125 UINT framelength = ((UINT)buf[3] << 8) | buf[4];
128 if ( buf[1] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
130 *dest = ( (ULLONG)(buf[3] & 0x0E) << 29 ) |
131 ( (ULLONG)(buf[4]) << 22 ) |
132 ( (ULLONG)(buf[5] & 0xFE) << 14 ) |
133 ( (ULLONG)(buf[6]) << 7 ) |
134 ( (ULLONG)(buf[7] & 0xFE) >> 1 );
138 buf += framelength; len -= framelength;
144 int DemuxerTS::put(UCHAR* buf, int len)
146 int ret = 0; // return number of bytes consumed
150 if (len >= TS_SIZE + 1 - partPacket)
151 { // Remainder of partial packet is available, plus one
152 memcpy(store+partPacket, buf, TS_SIZE - partPacket);
153 ret += TS_SIZE - partPacket;
154 buf += TS_SIZE - partPacket;
155 len -= TS_SIZE - partPacket;
156 partPacket = TS_SIZE;
158 { // Packet is properly terminated
159 int rc = processTS(store);
161 partPacket = 0; // Successfully processed
163 return ret; // Try again later.
166 { // Packet not terminated. Find another candidate, and shift store
167 Log::getInstance()->log("TS Demuxer", Log::ERR, "TS Misaligned!");
169 while (search < partPacket && store[search] != TS_SIG)
171 partPacket -= search;
172 if (partPacket) memcpy(store, store+search, partPacket);
176 { // Still don't have complete packet. Consume what we do have.
177 memcpy(store+partPacket, buf, len);
184 // Position ourselves at a candidate TS packet
185 while (len > 0 && *buf != TS_SIG)
187 Log::getInstance()->log("TS Demuxer", Log::ERR, "TS Misaligned!");
193 if (len < TS_SIZE + 1)
194 { // Not enough data. Store what we have.
195 memcpy(store, buf, len);
201 if (buf[TS_SIZE] != TS_SIG)
202 { // Not terminated correctly.
204 while (len > 0 && *buf != TS_SIG)
211 int rc = processTS(buf);
213 { // Successfully processed
214 buf += TS_SIZE; ret += TS_SIZE; len -= TS_SIZE;
217 { // Processing failed.
225 int DemuxerTS::processTS(UCHAR* buf)
227 int datalen = TS_SIZE - 4;
228 int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
229 UCHAR payload = buf[1] & 0x40;
231 if (buf[3] & 0x20) // Adaptation field is present
232 datalen -= (buf[4] + 1);
233 if (datalen < 0) // Error in stream TODO log this
235 if (datalen == 0) // Null packet
237 buf += (TS_SIZE - datalen);
249 parsePacketDetails(vPacket);
252 rc = submitPacket(vPacket);
262 parsePacketDetails(aPacket);
265 rc = submitPacket(aPacket);
275 parsePacketDetails(subPacket);
278 rc = submitPacket(subPacket);
282 if (isteletextdecoded && pid == tID)
288 parsePacketDetails(tPacket);
291 rc = submitPacket(tPacket);
295 if (rc == 0) return 0;
300 vPacket.init(PESTYPE_VID0);
301 buf += 6; datalen -= 6;
308 aPacket.init(PESTYPE_PRIVATE_1, PESTYPE_SUBSTREAM_AC30);
312 aPacket.init(PESTYPE_AUD0);
315 buf += 6; datalen -= 6;
319 subPacket.init(PESTYPE_PRIVATE_1);
320 subLength = (buf[4] << 8) + buf[5];
321 buf += 6; datalen -= 6;
323 if (isteletextdecoded && pid == tID)
325 tPacket.init(PESTYPE_PRIVATE_1,PESTYPE_SUBSTREAM_TELETEXTMAX);
326 buf += 6; datalen -= 6;
330 if ( (pid == vID && vActive) ||
331 (pid == aID && aActive) ||
332 (pid == tID && tActive) ||
333 (pid == subID && subActive) )
335 PESPacket* packet = NULL;
336 if (pid == vID) packet = &vPacket;
337 if (pid == aID) packet = &aPacket;
340 MessageBox(0,"sub","usb",0);
344 if (pid == tID) packet = &tPacket;
347 if (packet->write(buf, datalen) == 0)
348 { // Writing to packet failed. It has overflowed.
351 parsePacketDetails(*packet);
354 if (submitPacket(*packet) == 0) return 0;
357 packet->write((UCHAR*)"\200\000\000", 3);
358 packet->write(buf, datalen);
363 if (pid == subID && subActive && subPacket.getLength() == subLength)
365 parsePacketDetails(subPacket);
366 Log::getInstance()->log("DEMUXERTS", Log::DEBUG, "SUBMITTING A SUBTITLE PACKET %d %x", subLength, subPacket.getSubstream());
367 submitPacket(subPacket);