]> git.vomp.tv Git - vompclient.git/blob - demuxervdr.cc
Changes for demuxer. New mutex code
[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 #include <endian.h>
23
24 DemuxerVDR::DemuxerVDR() {}
25
26 void DemuxerVDR::flush()
27 {
28   state = 0;
29   submitting = false;
30   Demuxer::flush();
31 }
32
33 int DemuxerVDR::scan(UCHAR *buf, int len)
34 {
35   // Temporarily, just look for the lowest audio stream and return it
36   UCHAR HiByte = PESTYPE_AUDMAX;
37   int ret = 0;
38
39   while (len >= 4)
40   {
41     UINT pattern = *(UINT*)buf;
42     buf++; len--;
43
44 #if __BYTE_ORDER == __BIG_ENDIAN
45     if (pattern < (UINT)(0x100 | PESTYPE_AUD0) ||
46         pattern > (UINT)(0x100 | HiByte)) continue;
47     HiByte = pattern & 0xFF;
48 #else
49     if ((pattern & 0xFFFFFF) != 0x010000 ||
50          pattern < ((UINT)PESTYPE_AUD0 << 24) ||
51          pattern > ((UINT)HiByte << 24)) continue;
52     HiByte = pattern >> 24;
53 #endif
54     ret = HiByte;
55     if (HiByte == PESTYPE_AUD0) break;
56   }
57   return ret;
58 }
59     
60 int DemuxerVDR::findVideoPTS(UCHAR* buf, int len, ULLONG* dest)
61 {
62   while (len >= 14)
63   {
64     UINT pattern = *(UINT*)buf;
65     buf++; len--;
66 #if __BYTE_ORDER == __BIG_ENDIAN
67     if (pattern < (0x100 | PESTYPE_VID0) ||
68         pattern > (0x100 | PESTYPE_VIDMAX)) continue;
69 #else
70     if ((pattern & 0xFFFFFF) != 0x010000 ||
71          pattern < ((UINT)PESTYPE_VID0 << 24) ||
72          pattern > ((UINT)PESTYPE_VIDMAX << 24)) continue;
73 #endif
74     if ((buf[5] & 0xC0) != 0x80) continue;
75
76     UINT packetlength = ((UINT)buf[3] << 8) | buf[4];
77
78     if ( buf[6] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
79     {
80       if ( (buf[8]  & 0x01) != 0x01 ||
81            (buf[10] & 0x01) != 0x01 ||
82            (buf[12] & 0x01) != 0x01) continue;
83
84       *dest = ( (ULLONG)(buf[8]  & 0x0E) << 29 ) |
85               ( (ULLONG)(buf[9])         << 22 ) |
86               ( (ULLONG)(buf[10] & 0xFE) << 14 ) |
87               ( (ULLONG)(buf[11])        <<  7 ) |
88               ( (ULLONG)(buf[12] & 0xFE) >>  1 );
89       return 1;
90     }
91
92     buf += 5; len -= 5;
93     buf += packetlength; len -= packetlength;
94   }
95   // No PTS found.
96   return 0;
97 }
98
99 int DemuxerVDR::put(UCHAR* buf, int len)
100 {
101   int ret = 0;    // return number of bytes consumed
102
103   if (submitting)
104   {
105     if (packet.submit() == 0) // Still full!
106       return ret;
107     else
108       submitting = false;
109   }
110
111   if (state > 0) // We are half way through a PES packet.
112   {
113     if (len >= state) // The remainder of the packet is available.
114     {
115       packet.write(buf, state);
116       buf += state; len -= state; ret += state;
117       state = 0;
118       if (packet.submit() == 0) // Stream is full.
119       {
120         submitting = true;
121         return ret;
122       }
123     }
124     else // Write what we have, then exit.
125     {
126       packet.write(buf, len);
127       state -= len;
128       return len;
129     }
130   }
131
132   while (len >= 0)
133   {
134     switch (state)
135     {
136       case  0:
137       case -1:
138         if (*buf == 0x00) state--; else state = 0;
139         break;
140       case -2:
141         if (*buf == 0x01) state--; else if (*buf != 0x00) state = 0;
142         break;
143       case -3:
144         if ((*buf >= PESTYPE_VID0 && *buf <= PESTYPE_VIDMAX) ||
145             (*buf >= PESTYPE_AUD0 && *buf <= PESTYPE_AUDMAX) ||
146             (*buf == PESTYPE_PRIVATE_1))
147         {
148           packet.init(*buf);
149           state--;
150           break;
151         }
152         else if (*buf == 0x00)
153           state = -1;
154         else
155           state = 0;
156         break;
157       case -4:
158         packetLength = ((UINT)*buf) << 8;
159         state--;
160         break;
161       case -5:
162         packetLength += *buf;
163         state--;
164         break;
165     }
166
167     buf++; len--; ret++;
168
169     if (state == -6) // Packet header complete
170     {
171       if (len >= packetLength) // The entire packet is available.
172       {
173         packet.write(buf, packetLength);
174         buf += packetLength; len -= packetLength; ret += packetLength;
175         state = 0;
176         if (packet.submit() == 0) // Stream is full.
177         {
178           submitting = true;
179           return ret;
180         }
181       }
182       else // Write what we have.
183       {
184         packet.write(buf, len);
185         state = packetLength - len;
186         ret += len;
187         len = 0;
188       }
189     }
190   }
191   return ret;
192 }