/[tivodecode]/t2sami/trunk/PS.cpp
ViewVC logotype

Contents of /t2sami/trunk/PS.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 255 - (hide annotations) (download)
Mon Apr 25 03:37:29 2011 UTC (11 years, 2 months ago) by jeremyd2019
File size: 6392 byte(s)
fix a crash during caption extraction.  Added some asserts to help track down that crash.
1 jeremyd 79 // PS.cpp : implementation file
2     //
3     //********************************************************************
4     //
5    
6 jeremyd2019 198 #ifdef HAVE_CONFIG_H
7     # include "config.h"
8     #endif
9    
10 jeremyd 83 #include <fcntl.h>
11     #include <errno.h>
12 jeremyd 79
13 jeremyd2019 198 #ifdef HAVE_STRING_H
14     # include <string.h>
15     #endif
16    
17 jeremyd 83 #ifdef WIN32
18 jeremyd2019 198 # include <winsock2.h>
19 jeremyd 83 #endif
20 jeremyd2019 198 #ifdef HAVE_NETINET_IN_H
21     # include <netinet/in.h>
22     #endif
23 jeremyd 83
24 jeremyd2019 198 #include "TScan.h"
25     #include "Utility.h"
26    
27 jeremyd 83 #ifndef O_BINARY
28     # define O_BINARY 0
29     #endif
30    
31 jeremyd2019 198 #if defined(HAVE_STRCASECMP)
32     # define ICASE_STR_COMPARE(a, b) strcasecmp(a, b)
33     #elif defined(HAVE__STRICMP)
34     # define ICASE_STR_COMPARE(a, b) _stricmp(a, b)
35     #elif defined(HAVE_STRICMP)
36     # define ICASE_STR_COMPARE(a, b) stricmp(a, b)
37     #else
38     # error No known case-insensitive string compare function for this platform
39     #endif
40    
41 jeremyd 79 CPs::CPs()
42     {
43    
44 jeremyd 95 m_nFile = NULL;
45 jeremyd 79 buf = NULL;
46     buf_len = 0;
47     pos = 0;
48     m_dwFileLength = 0;
49     m_dwBufferBase = 0;
50     m_pParent = NULL;
51    
52     }
53    
54     CPs::~CPs()
55     {
56    
57     CleanUp();
58    
59     }
60    
61     bool CPs::CleanUp(void)
62     {
63    
64 jeremyd 95 if( m_nFile != NULL ) {
65     hclose( m_nFile );
66     m_nFile = NULL;
67 jeremyd 79 }
68    
69     if( buf != NULL ) {
70     free( buf );
71     buf = NULL;
72     }
73    
74     return true;
75    
76     }
77    
78 jeremyd 83 bool CPs::Initialize( std::string szInputFile )
79 jeremyd 79 {
80    
81     CleanUp();
82    
83     if( buf == NULL )
84     buf = (byte *)malloc(PS_BUFFER_LENGTH);
85    
86     memset( buf, 0, PS_BUFFER_LENGTH);
87    
88     buf_len=0;
89     pos=0;
90    
91 jeremyd2019 243 if(szInputFile == "-")
92     m_nFile = hattach(stdin);
93     else
94     m_nFile = hopen( szInputFile.c_str(), "rb");
95 jeremyd 95 if( m_nFile == NULL ) {
96 jeremyd 79 TRACE("File could not be opened %0x\n", errno );
97     return false;
98     } else {
99 jeremyd2019 243 if (szInputFile != "-")
100     {
101     hseek(m_nFile, 0L, SEEK_END);
102     m_dwFileLength = htell( m_nFile );
103     hseek( m_nFile, 0, SEEK_SET );
104 jeremyd 79
105 jeremyd2019 243 std::string csExt = GetFileExtFromPath(szInputFile.c_str());
106     if( ICASE_STR_COMPARE(csExt.c_str(), ".tivo") != 0)
107     return false;
108     }
109 jeremyd 79
110 jeremyd2019 243 char fingerprint[5];
111     memset( fingerprint, 0, 5 );
112     hread( fingerprint, 4, m_nFile );
113 jeremyd 79
114 jeremyd2019 243 if( ICASE_STR_COMPARE( fingerprint, "tivo" ) )
115     {
116     /* rewind. This should be OK because happyfile is
117     * careful to buffer
118     */
119     hseek(m_nFile, 0, SEEK_SET);
120     return false;
121     }
122 jeremyd 79
123 jeremyd2019 243 hseek( m_nFile, 0x0A, SEEK_SET );
124     boost::uint32_t offset = 0;
125     hread( &offset, 4, m_nFile );
126     m_dwBufferBase = ntohl(offset);
127 jeremyd 79
128 jeremyd2019 243 hseek( m_nFile, m_dwBufferBase, SEEK_SET ); // Skip xml notice and file fingerprint information
129 jeremyd 79
130     return true;
131    
132     }
133     }
134    
135     int CPs::PercentDone()
136     {
137     if( m_dwFileLength == 0 )
138     return 0;
139     else
140     return (int)(( 100 * (m_dwBufferBase + pos ))/m_dwFileLength);
141     }
142    
143 jeremyd2019 198 void CPs::fill_buffer(size_t st)
144 jeremyd 79 {
145 jeremyd 95 buf_len = hread( buf+st, PS_BUFFER_LENGTH-st, m_nFile) + st;
146     m_dwBufferBase = htell( m_nFile ) - buf_len; // File location for start of buffer
147 jeremyd 79 pos=0;
148     }
149 jeremyd 95
150 jeremyd2019 198 bool CPs::check_buffer( size_t need )
151 jeremyd 79 {
152 jeremyd2019 198 size_t i;
153 jeremyd 79 #ifdef _DEBUG
154     byte *pj = &buf[pos]; // Gives me a convenient place for a break point...
155     #endif
156    
157     if( (buf_len - pos) < need ) {
158     if( buf_len==PS_BUFFER_LENGTH ) {
159     for(i=pos;i<buf_len;i++)
160     buf[i-pos]=buf[i];
161     fill_buffer(buf_len-pos);
162     } else
163     return false;
164     }
165    
166     return true;
167    
168     }
169    
170     int CPs::next_code(bool *valid )
171     {
172    
173     if( !check_buffer(4) ) {
174     // premature file EOF : Synthesize MPEG end
175     *valid = true;
176     return 185;
177     }
178    
179 jeremyd2019 198 if (b.ret_value(buf,(int)pos,(int)pos+2)!=1) // Invalid sync - not code sequence
180 jeremyd 79 *valid = false;
181     else
182     *valid = true;
183    
184 jeremyd2019 198 int code = (int)b.ret_value(buf,(int)pos+3,(int)pos+3);
185 jeremyd 79 return code;
186    
187     }
188    
189     bool CPs::read_code(int *code )
190     {
191    
192     bool rtcode;
193     *code = next_code( &rtcode );
194     pos += 4;
195     return rtcode;
196    
197     }
198    
199 jeremyd2019 198 size_t CPs::skip2code()
200 jeremyd 79 {
201    
202 jeremyd2019 198 size_t dif = 0;
203 jeremyd 79 bool valid;
204    
205     for(;;) {
206    
207 jeremyd2019 255 if( buf_len-pos > 4 )
208     if( buf[pos] != 0 ) {
209 jeremyd 79
210     byte *p = (byte *)memchr( &buf[pos], 0, buf_len-pos );
211     if( p != NULL ) {
212    
213 jeremyd2019 198 ptrdiff_t nch = p - &buf[pos];
214 jeremyd2019 255 assert(nch >= 0);
215 jeremyd 79 pos += nch;
216     dif += nch;
217    
218     if( (buf_len-pos > 4) && (buf[pos+1] != '\0') ) {
219     pos++;
220     dif++;
221     continue;
222     }
223    
224     }
225    
226     }
227    
228 jeremyd 83 next_code(&valid);
229 jeremyd 79 if( !valid ) {
230     skip_info(1);
231     dif += 1;
232     } else
233     break;
234    
235     }
236    
237     return dif;
238    
239     }
240    
241     bool CPs::end_mb( int st_bit )
242     {
243    
244     check_buffer(4);
245    
246 jeremyd2019 198 size_t p = pos;
247 jeremyd 79 for( int i=0; i<23; i++ ) {
248    
249     if( b.ret_bit( buf[p], st_bit ) )
250     return false;
251    
252     st_bit++;
253     if( st_bit > 0 ) {
254     st_bit = 0;
255     p++;
256     }
257    
258     }
259    
260     return true;
261    
262     }
263    
264     void CPs::skip_info(int n_bytes)
265     {
266 jeremyd2019 255 assert(n_bytes >= 0);
267 jeremyd 79 check_buffer(n_bytes);
268     pos=pos+n_bytes;
269     }
270    
271     int CPs::ret_value(int n_bytes)
272     {
273     int val;
274 jeremyd2019 255 assert(n_bytes >= 0);
275 jeremyd 79 check_buffer(n_bytes);
276 jeremyd2019 198 val = b.ret_value(buf,(int)pos,(int)pos+n_bytes-1);
277 jeremyd 79 pos=pos+n_bytes;
278     return val;
279     }
280    
281     int CPs::ret_bit_value(int st_bit,int end_bit,bool act)
282     {
283     int val;
284     check_buffer(1);
285     val=b.ret_bit_value(buf[pos],st_bit,end_bit);
286     if(act) pos++;
287     return val;
288     }
289    
290     int CPs::get_bit_value( int *st_bit, int *dif, int nbits )
291     {
292    
293     int val = 0;
294     int nb;
295     while( *st_bit + nbits > 7 ) {
296    
297     nb = 8 - *st_bit;
298     val = (val << nb) + b.ret_bit_value( buf[pos], *st_bit, 7 );
299    
300     *st_bit = 0;
301     pos++;
302     (*dif)++;
303     nbits -= nb;
304    
305     } // while
306    
307     if( nbits > 0 ) {
308     val = (val << nbits) + b.ret_bit_value( buf[pos], *st_bit, *st_bit + nbits - 1 );
309     *st_bit += nbits;
310     }
311    
312     return val;
313    
314     }
315    
316     void CPs::end_PS()
317     {
318     CleanUp();
319     }
320    
321     bool CPs::zero()
322     {
323 jeremyd2019 173 check_buffer(1);
324 jeremyd 79 if (buf[pos]==0) return true;
325     return false;
326     }
327    
328     void CPs::go_back(int step)
329     {
330 jeremyd2019 255 assert(-step <= pos);
331 jeremyd 79 pos=pos-step;
332     }
333    
334     double CPs::get_SCR()
335     {
336     int SCR;
337     double scr_val;
338    
339     SCR=ret_bit_value(2,4,false); // SCR(32..30)
340     scr_val=(SCR>3)?4294967296.0:0.0; // caz pt. SCR[32]=1 -> overflow
341     SCR=SCR<<30;
342     SCR|=ret_bit_value(6,7,true)<<28; // SCR(29,28)
343     SCR|=ret_value(1)<<20; // SCR(27..20)
344     SCR|=ret_bit_value(0,4,false)<<15; // SCR(19..15)
345     SCR|=ret_bit_value(6,7,true)<<13; // SCR(14,13)
346     SCR|=ret_value(1)<<5; // SCR(12..5)
347     SCR|=ret_bit_value(0,4,false); // SCR(4..0)
348     scr_val+=SCR;
349     scr_val*=300.0;
350     SCR=ret_bit_value(6,7,true)<<7; // SCR_ext(8,7)
351     SCR|=ret_bit_value(0,6,true); // SCR_ext(6..0)
352     scr_val+=SCR;
353     return scr_val/27000.0; // 27Mhz clock
354    
355     }
356    
357     double CPs::get_PES_stamp()
358     {
359    
360     int stamp;
361     double val;
362    
363     stamp=ret_bit_value(4,6,true); // PTS(32..30)
364     val=(stamp>3)?4294967296.0:0.0; // caz de overflow (PTS[32]=1)
365     stamp=stamp<<30;
366     stamp|=ret_value(1)<<22; // PTS(29..22)
367     stamp|=ret_bit_value(0,6,true)<<15; // PTS(21..15)
368     stamp|=ret_value(1)<<7; // PTS(14..7)
369     stamp|=ret_bit_value(0,6,true); // PTS(6..0)
370     val+=stamp;
371     return val/90.0; // 90Khz clock
372    
373     }
374    
375     bool CPs::ret_bit(int pz)
376     {
377     return b.ret_bit(buf[pos],pz);
378     }

cvs@jdrake.com
ViewVC Help
Powered by ViewVC 1.1.13