]> git.vomp.tv Git - vompclient.git/blob - demuxervdr.cc
Bug fix
[vompclient.git] / demuxervdr.cc
1 /*
2     Copyright 2005-2006 Mark Calderbank
3
4     This file is part of VOMP.
5
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.
10
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.
15
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
19 */
20
21 #include "demuxervdr.h"
22 #ifndef WIN32
23 #include <endian.h>
24 #else
25 #define __LITTLE_ENDIAN 1234
26 #define __BIG_ENDIAN  4321
27 #define __BYTE_ORDER __LITTLE_ENDIAN
28 #endif
29
30 #if __BYTE_ORDER == __BIG_ENDIAN
31 #define DEMUXER_SEQ_HEAD 0x000001B3
32 #else
33 #define DEMUXER_SEQ_HEAD 0xB3010000
34 #endif
35
36 DemuxerVDR::DemuxerVDR() {
37 } //MS Visual C++ needs the Bracket after the first line other it ignores the line
38
39 void DemuxerVDR::flush()
40 {
41   state = 0;
42   submitting = false;
43   Demuxer::flush();
44 }
45
46 int DemuxerVDR::scan(UCHAR *buf, int len)
47 {
48   // Temporarily, just look for the lowest audio stream and return it
49   UCHAR HiByte = PESTYPE_AUDMAX;
50   int ret = 0;
51
52   while (len >= 4)
53   {
54     UINT pattern = *(UINT*)buf;
55     buf++; len--;
56
57 #if __BYTE_ORDER == __BIG_ENDIAN
58     if (pattern < (UINT)(0x100 | PESTYPE_AUD0) ||
59         pattern > (UINT)(0x100 | HiByte)) continue;
60     HiByte = pattern & 0xFF;
61 #else
62     if ((pattern & 0xFFFFFF) != 0x010000 ||
63          pattern < ((UINT)PESTYPE_AUD0 << 24) ||
64          pattern > ((UINT)HiByte << 24)) continue;
65     HiByte = pattern >> 24;
66 #endif
67     ret = HiByte;
68     if (HiByte == PESTYPE_AUD0) break;
69   }
70   return ret;
71 }
72
73 int DemuxerVDR::findVideoPTS(UCHAR* buf, int len, ULLONG* dest)
74 {
75   while (len >= 14)
76   {
77     UINT pattern = *(UINT*)buf;
78     buf++; len--;
79 #if __BYTE_ORDER == __BIG_ENDIAN
80     if (pattern < (0x100 | PESTYPE_VID0) ||
81         pattern > (0x100 | PESTYPE_VIDMAX)) continue;
82 #else
83     if ((pattern & 0xFFFFFF) != 0x010000 ||
84          pattern < ((UINT)PESTYPE_VID0 << 24) ||
85          pattern > ((UINT)PESTYPE_VIDMAX << 24)) continue;
86 #endif
87     if ((buf[5] & 0xC0) != 0x80) continue;
88
89     UINT packetlength = ((UINT)buf[3] << 8) | buf[4];
90
91     if ( buf[6] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
92     {
93       if ( (buf[8]  & 0x01) != 0x01 ||
94            (buf[10] & 0x01) != 0x01 ||
95            (buf[12] & 0x01) != 0x01) continue;
96
97       *dest = ( (ULLONG)(buf[8]  & 0x0E) << 29 ) |
98               ( (ULLONG)(buf[9])         << 22 ) |
99               ( (ULLONG)(buf[10] & 0xFE) << 14 ) |
100               ( (ULLONG)(buf[11])        <<  7 ) |
101               ( (ULLONG)(buf[12] & 0xFE) >>  1 );
102       return 1;
103     }
104
105     buf += 5; len -= 5;
106     buf += packetlength; len -= packetlength;
107   }
108   // No PTS found.
109   return 0;
110 }
111 #ifndef NEW_DEMUXER
112 int DemuxerVDR::put(UCHAR* buf, int len)
113 #else
114 int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos)
115 #endif
116 {
117   int ret = 0;    // return number of bytes consumed
118
119 #ifdef NEW_DEMUXER
120   ULLONG current_position = cur_pos;
121 #endif
122
123   if (submitting)
124   {
125 #ifndef NEW_DEMUXER
126     if (packet.submit() == 0) // Still full!
127 #else
128     if (packet.submit(current_position) == 0) // Still full!
129 #endif
130       return ret;
131     else
132       submitting = false;
133   }
134
135   if (state > 0) // We are half way through a PES packet.
136   {
137     if (len >= state) // The remainder of the packet is available.
138     {
139       packet.write(buf, state);
140       buf += state; len -= state; ret += state;
141       state = 0;
142 #ifndef NEW_DEMUXER
143     if (packet.submit() == 0) // Still full!
144 #else
145     if (packet.submit(current_position) == 0) // Still full!
146 #endif
147       {
148         submitting = true;
149         return ret;
150       }
151     }
152     else // Write what we have, then exit.
153     {
154       packet.write(buf, len);
155       state -= len;
156       return len;
157     }
158   }
159
160   while (len > 0)
161   {
162     switch (state)
163     {
164       case  0:
165       case -1:
166         if (*buf == 0x00) state--; else state = 0;
167         buf++; len--; ret++;
168         break;
169       case -2:
170         if (*buf == 0x01) state--; else if (*buf != 0x00) state = 0;
171         buf++; len--; ret++;
172         break;
173       case -3:
174         if ((*buf >= PESTYPE_VID0 && *buf <= PESTYPE_VIDMAX) ||
175             (*buf >= PESTYPE_AUD0 && *buf <= PESTYPE_AUDMAX) ||
176             (*buf == PESTYPE_PRIVATE_1))
177         {
178           packet.init(*buf);
179           state--;
180         }
181         else if (*buf == 0x00)
182           state = -1;
183         else
184           state = 0;
185         buf++; len--; ret++;
186         break;
187       case -4:
188         packetLength = ((UINT)*buf) << 8;
189         state--;
190         buf++; len--; ret++;
191         break;
192       case -5:
193         packetLength += *buf;
194         state--;
195         buf++; len--; ret++;
196         break;
197     }
198
199 #ifdef NEW_DEMUXER
200     current_position++;
201 #endif
202
203     if (state == -6) // Packet header complete
204     {
205       if (len >= packetLength) // The entire packet is available.
206       {
207         packet.write(buf, packetLength);
208         buf += packetLength; len -= packetLength; ret += packetLength;
209 #ifdef NEW_DEMUXER
210         current_position+=(ULLONG)packetLength;
211 #endif
212         state = 0;
213 #ifndef NEW_DEMUXER
214         if (packet.submit() == 0) // Still full!
215 #else
216         if (packet.submit(current_position) == 0) // Still full!
217 #endif
218         {
219           submitting = true;
220           return ret;
221         }
222       }
223       else // Write what we have.
224       {
225         packet.write(buf, len);
226         state = packetLength - len;
227         ret += len;
228         len = 0;
229       }
230     }
231   }
232   return ret;
233 }