2 Copyright 2005-2006 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
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "demuxervdr.h"
25 #define __LITTLE_ENDIAN 1234
26 #define __BIG_ENDIAN 4321
27 #define __BYTE_ORDER __LITTLE_ENDIAN
30 #if __BYTE_ORDER == __BIG_ENDIAN
31 #define DEMUXER_SEQ_HEAD 0x000001B3
33 #define DEMUXER_SEQ_HEAD 0xB3010000
36 #define PTSMAP_MAXENTRIES 300
38 DemuxerVDR::DemuxerVDR()
40 frameCounting = false;
43 void DemuxerVDR::flush()
47 frameCounting = false;
51 int DemuxerVDR::scan(UCHAR *buf, int len)
53 // Temporarily, just look for the lowest audio stream and return it
54 UCHAR HiByte = PESTYPE_AUDMAX;
59 UINT pattern = *(UINT*)buf;
62 #if __BYTE_ORDER == __BIG_ENDIAN
63 if (pattern < (UINT)(0x100 | PESTYPE_AUD0) ||
64 pattern > (UINT)(0x100 | HiByte)) continue;
65 HiByte = pattern & 0xFF;
67 if ((pattern & 0xFFFFFF) != 0x010000 ||
68 pattern < ((UINT)PESTYPE_AUD0 << 24) ||
69 pattern > ((UINT)HiByte << 24)) continue;
70 HiByte = pattern >> 24;
73 if (HiByte == PESTYPE_AUD0) break;
78 int DemuxerVDR::findVideoPTS(UCHAR* buf, int len, ULLONG* dest)
82 UINT pattern = *(UINT*)buf;
84 #if __BYTE_ORDER == __BIG_ENDIAN
85 if (pattern < (0x100 | PESTYPE_VID0) ||
86 pattern > (0x100 | PESTYPE_VIDMAX)) continue;
88 if ((pattern & 0xFFFFFF) != 0x010000 ||
89 pattern < ((UINT)PESTYPE_VID0 << 24) ||
90 pattern > ((UINT)PESTYPE_VIDMAX << 24)) continue;
92 if ((buf[5] & 0xC0) != 0x80) continue;
94 UINT packetlength = ((UINT)buf[3] << 8) | buf[4];
96 if ( buf[6] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
98 if ( (buf[8] & 0x01) != 0x01 ||
99 (buf[10] & 0x01) != 0x01 ||
100 (buf[12] & 0x01) != 0x01) continue;
102 *dest = ( (ULLONG)(buf[8] & 0x0E) << 29 ) |
103 ( (ULLONG)(buf[9]) << 22 ) |
104 ( (ULLONG)(buf[10] & 0xFE) << 14 ) |
105 ( (ULLONG)(buf[11]) << 7 ) |
106 ( (ULLONG)(buf[12] & 0xFE) >> 1 );
111 buf += packetlength; len -= packetlength;
117 void DemuxerVDR::setFrameNum(ULONG frame)
119 frameCounting = true;
124 int DemuxerVDR::put(UCHAR* buf, int len)
126 int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos)
129 int ret = 0; // return number of bytes consumed
132 ULLONG current_position = cur_pos;
138 if (packet.submit() == 0) // Still full!
140 if (packet.submit(current_position) == 0) // Still full!
147 if (state > 0) // We are half way through a PES packet.
149 if (len >= state) // The remainder of the packet is available.
151 packet.write(buf, state);
152 buf += state; len -= state; ret += state;
155 if (packet.submit() == 0) // Stream is full
157 if (packet.submit(current_position) == 0) // Stream is full
164 else // Write what we have, then exit.
166 packet.write(buf, len);
178 if (*buf == 0x00) state--; else state = 0;
182 if (*buf == 0x01) state--; else if (*buf != 0x00) state = 0;
186 if ((*buf >= PESTYPE_VID0 && *buf <= PESTYPE_VIDMAX) ||
187 (*buf >= PESTYPE_AUD0 && *buf <= PESTYPE_AUDMAX) ||
188 (*buf == PESTYPE_PRIVATE_1))
193 else if (*buf == 0x00)
200 packetLength = ((UINT)*buf) << 8;
205 packetLength += *buf;
215 if (state == -6) // Packet header complete
217 if (len >= packetLength) // The entire packet is available.
219 packet.write(buf, packetLength);
220 buf += packetLength; len -= packetLength; ret += packetLength;
222 current_position+=(ULLONG)packetLength;
226 if (packet.submit() == 0) // Stream is full
228 if (packet.submit(current_position) == 0) // Stream is full
235 else // Write what we have.
237 packet.write(buf, len);
238 state = packetLength - len;
247 void DemuxerVDR::PESPacketVDR::parseDetails()
249 DemuxerVDR* dx = (DemuxerVDR*)(DemuxerVDR::getInstance());
250 PESPacket::parseDetails();
251 if (dx->frameCounting && pts != PTS_INVALID)
255 me.frame = dx->frameNumber;
256 dx->PTSMap.push_back(me);
257 if (dx->PTSMap.size() == PTSMAP_MAXENTRIES) dx->PTSMap.pop_front();