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

Contents of /t2sami/trunk/TScan.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 255 - (show annotations) (download)
Mon Apr 25 03:37:29 2011 UTC (11 years ago) by jeremyd2019
File size: 25123 byte(s)
fix a crash during caption extraction.  Added some asserts to help track down that crash.
1 // T2Scan.cpp : implementation file
2 //
3 //********************************************************************
4 //
5 // Copyright (c) 2005-2007 James Memmott <jmemmott@braeman.com>
6 //
7 // This software is provided 'as-is', without any express or implied warranty.
8 // In no event will the author be held liable for any damages arising from the
9 // use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose, including
12 // commercial applications, and to alter it and redistribute it freely, subject to
13 // the following restrictions:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the disclaimer.
17 //
18 // 2. The origin of this software must not be misrepresented; you must not claim
19 // that you wrote the original software. If you use this software in a product,
20 // an acknowledgment in the product documentation would be appreciated but is
21 // not required.
22 //
23 // 3. Altered source versions must be plainly marked as such, and must not be
24 // misrepresented as being the original software.
25 //
26 //********************************************************************
27 //
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include "TScan.h"
34 #include "Utility.h"
35 #include <boost/format.hpp>
36 #include <fcntl.h>
37 #include <errno.h>
38
39 #ifndef O_BINARY
40 # define O_BINARY 0
41 #endif
42
43 CTivoScan::CTivoScan()
44 {
45 m_Cc.m_pParent = this;
46 m_lastGOPHour = 0;
47 m_lastGOPMinute = 0;
48 m_lastGOPSecond = 0;
49 m_lastGOPFrame = 0;
50 m_lastPTS = 0.0;
51 m_lastDTS = 0.0;
52 n_pks = 0;
53 n_sp = 0;
54 n_ap = 0;
55 n_vp = 0;
56 n_psm = 0;
57 n_op = 0;
58 m_SampleDiff = 0;
59 m_validSampleDiff = false;
60
61 m_nSyncBias = 0;
62 m_csFontWeight = "normal";
63 m_csFontSize = "medium";
64 m_csFontFamily = "sans-serif";
65 m_bUseCutoffDuration = false;
66 m_nCutoffDuration = 0;
67 m_nCaptionFormat = FMT_SAMI;
68 m_bDoHtmlEncode = false;
69 m_bShowSummary = false;
70 m_bQuiet = false;
71 m_bAddSpaces = false;
72 m_nCcChannel = 1;
73
74 }
75
76 CTivoScan::~CTivoScan()
77 {
78 }
79
80 void CTivoScan::ProcessAudioPES()
81 {
82 #if defined(DumpAudioPESData)
83 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
84 #endif
85 int jmp = m_cStream.ret_value(2);
86 m_cStream.skip_info(1);
87 int dif=1;
88 bool stp=m_cStream.ret_bit(1);
89
90 std::string stamp("No PTS");
91
92 if (m_cStream.ret_bit(0)) {
93 m_cStream.skip_info(2);
94 dif=dif+2;
95 double PTS=m_cStream.get_PES_stamp();
96 stamp = boost::str(boost::format("PTS = %.2f") % PTS );
97 dif=dif+5;
98 }
99
100 if (stp) {
101 double DTS=m_cStream.get_PES_stamp();
102 std::string dts;
103 dts = boost::str(boost::format(", DTS = %.2f") % DTS);
104 stamp+=dts;
105 dif=dif+5;
106 } else
107 stamp+=", No DTS";
108
109 m_cStream.skip_info(jmp-dif);
110
111 n_ap++;
112 jmp += 6;
113 s_ap=s_ap+jmp;
114
115 #if defined(DumpAudioPESData)
116 fprintf(m_nFile, " %08x: Audio PES \t\tnr. %d\t\tSize :\t%d bytes\t%s\n", xloc, n_ap, jmp, stamp.c_str() );
117 #endif
118
119 }
120
121 int CTivoScan::ProcessSequenceHeader()
122 {
123 #if defined(DumpVideoPESData)
124 static char *sAspect[] = {"Forbidden", "1:1", "4:3", "16:9", "2.21:1", "Reserved" };
125 static char *sFRate[] = {"Forbidden", "23.976", "24", "25", "29.97", "30", "50", "59.94", "60", "Reserved" };
126
127 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
128 #endif
129 int dif = 0;
130
131 int horizontal_size = m_cStream.ret_value(1)<<4;
132 horizontal_size |= m_cStream.ret_bit_value(0,3,false);
133 dif += 1;
134
135 m_nMbWidth = horizontal_size / 16;
136 if (m_nMbWidth % 16) m_nMbWidth++;
137
138 m_nVerticalSize = m_cStream.ret_bit_value(4,7,true)<<8;
139 m_nVerticalSize |= m_cStream.ret_value(1);
140 dif += 2;
141
142 int aspect_ratio_information = m_cStream.ret_bit_value(0,3,false);
143 if( aspect_ratio_information > 5 ) aspect_ratio_information = 5;
144 int frame_rate_code = m_cStream.ret_bit_value(4,7,true);
145 if( frame_rate_code > 9 ) frame_rate_code = 9;
146 dif += 1;
147
148 unsigned long bit_rate_value = m_cStream.ret_value(2)<<2;
149 bit_rate_value |= m_cStream.ret_bit_value(0,1,true);
150 bit_rate_value *= 400;
151 dif += 3;
152
153 bool loadiq=m_cStream.ret_bit(6);
154 if( loadiq ) { // Skip Intraquantiser Matrix
155 m_cStream.skip_info(64);
156 dif += 64;
157 }
158
159 bool loadniq=m_cStream.ret_bit(7);
160 if( loadniq ) { // Skip non-Intraquantiser Matrix
161 m_cStream.skip_info(64);
162 dif += 64;
163 }
164
165 m_cStream.skip_info(1);
166 dif += 1;
167
168 #if defined(DumpVideoPESData)
169 fprintf(m_nFile, " %08x: Sequence Header.\tResolution : %d x %d\n", xloc, horizontal_size, m_nVerticalSize );
170 fprintf(m_nFile, " \tAspect Ratio : %s\n", sAspect[aspect_ratio_information] );
171 fprintf(m_nFile, " \tFrame Rate : %s\n", sFRate[frame_rate_code] );
172 fprintf(m_nFile, " \tBit Rate : %ld\n", bit_rate_value );
173 #endif
174
175 dif += (int)m_cStream.skip2code();
176
177 return dif;
178
179 }
180
181 int CTivoScan::ProcessGroupStart()
182 {
183 #if defined(DumpVideoPESData)
184 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
185 #endif
186 int dif = 0;
187 m_cStream.ret_bit(0);
188
189 m_lastGOPHour = m_cStream.ret_bit_value(1,5,false);
190 m_lastGOPMinute = m_cStream.ret_bit_value(6,7,true)<<4;
191 dif += 1;
192
193 m_lastGOPMinute |= m_cStream.ret_bit_value(0,3,false);
194 m_lastGOPSecond = m_cStream.ret_bit_value(5,7,true)<<3;
195 dif += 1;
196
197 m_lastGOPSecond |= m_cStream.ret_bit_value(0,2,false);
198 m_lastGOPFrame = m_cStream.ret_bit_value(3,7,true)<<1;
199 dif += 1;
200
201 if( m_cStream.ret_bit(0) )
202 m_lastGOPFrame++;
203
204 m_cStream.ret_bit(1);
205 m_cStream.ret_bit(2);
206
207 #if defined(DumpVideoPESData)
208 fprintf(m_nFile, " %08x: Group of Pictures\tSize :\t%d bytes\tTime %02d:%02d:%02d:%02d\n", xloc, dif, m_lastGOPHour, m_lastGOPMinute, m_lastGOPSecond, m_lastGOPFrame );
209 #endif
210
211 dif += (int)m_cStream.skip2code();
212
213 return dif;
214
215 }
216
217 int CTivoScan::ProcessSequenceDisplayExtension()
218 {
219
220 int dif = 0;
221
222 #if defined(DumpVideoPESData)
223 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
224 fprintf(m_nFile, " %08x: Sequence Display Extension\tSize :\t%d bytes\n", xloc, dif );
225 #endif
226
227 return dif;
228
229 }
230
231 int CTivoScan::ProcessSequenceScalableExtension()
232 {
233 #if defined(DumpVideoPESData)
234 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
235 #endif
236 int dif = 0;
237
238 m_bSequenceScalableExtension = true;
239 m_nScalableMode = m_cStream.ret_bit_value(4,5,false);
240
241 int layer_id = m_cStream.ret_bit_value(6,7,true)<<2;
242 dif += 1;
243 layer_id |= m_cStream.ret_bit_value(0,1,false);
244
245 #if defined(DumpVideoPESData)
246 fprintf(m_nFile, " %08x: Sequence Display Scalable\tSize :\t%d bytes\t%d - %d\n", xloc, dif, m_nScalableMode, layer_id );
247 #endif
248
249 return dif;
250
251 }
252
253 int CTivoScan::ProcessExtensiondata( int etype )
254 {
255 #if defined(DumpVideoPESData)
256 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
257 #endif
258 int dif = 0;
259
260 switch( etype ) {
261
262 case SEQUENCE_EXTENSION:
263
264 m_bSequenceScalableExtension = false;
265 if( m_cStream.ret_bit_value(0,3,false) == SEQUENCE_DISPLAY_EXTENSION_ID )
266 dif += ProcessSequenceDisplayExtension();
267 else if( m_cStream.ret_bit_value(0,3,false) == SEQUENCE_SCALABLE_EXTENSION_ID )
268 dif += ProcessSequenceScalableExtension();
269
270 break;
271
272 case GROUP_EXTENSION:
273
274 // Note at this time, no Group Extensions have been defined.
275
276 break;
277
278 case PICTURE_EXTENSION:
279
280 break;
281
282 } // switch
283
284 // Eat up the bitstream until we find another code of interest...
285
286 bool valid = false;
287 int cod;
288 for(;;) {
289
290 cod = m_cStream.next_code(&valid);
291 if( !valid ) {
292 m_cStream.ret_value(1);
293 dif += 1;
294 } else
295 break;
296
297 } // for
298
299 #if defined(DumpVideoPESData)
300 fprintf(m_nFile, " %08x: Extension Data\tSize :\t%d bytes\n", xloc, dif );
301 #endif
302
303 return dif;
304
305 }
306
307 int CTivoScan::ASTCDecode( int dif )
308 {
309
310 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 8);
311 //Jrm
312 // To set a break location at a specific byte count in the .tivo file...
313 // if( xloc == 0x00e4ee12 )
314 // int jrm = 1;
315 //Jrm
316
317 bool bEndAtsc = false;
318 do {
319
320 int typecode = (unsigned char)m_cStream.ret_value(1);
321 dif++;
322
323 if( typecode == 0x03 ) {
324
325 bool process_em_data = m_cStream.ret_bit(1);
326 bool process_cc_data = m_cStream.ret_bit(1);
327 bool additional_data = m_cStream.ret_bit(1);
328 int cc_count = m_cStream.ret_bit_value(3,7,true);
329 dif++;
330 int em_data = (unsigned char)m_cStream.ret_value(1);
331 dif++;
332
333 for( int i=0; i < cc_count; i++) {
334
335 byte cc_field = (unsigned char)m_cStream.ret_value(1);
336 dif++;
337 byte b1 = (unsigned char)m_cStream.ret_value(1);
338 dif++;
339 byte b2 = (unsigned char)m_cStream.ret_value(1);
340 dif++;
341
342 if( cc_field == 0xFC ) {
343
344 #if defined(DumpUserData)
345 byte c1 = b1 & 0x7f;
346 if( c1 < 0x20 ) c1 = 0x20;
347 byte c2 = b2 & 0x7f;
348 if( c2 < 0x20 ) c2 = 0x20;
349 fprintf(m_nFile, " \tATSC User Data : %2x(%c), %2x(%c)\n", b1, c1, b2, c2 );
350 #endif
351
352 m_Cc.CcDecode( b1, b2 );
353
354 }
355
356 }
357
358 } else if( typecode == 0xFF ) {
359 dif += (int)m_cStream.skip2code();
360 bEndAtsc = true;
361 } else {
362
363 byte b;
364
365 do {
366
367 b = (unsigned char)m_cStream.ret_value(1);
368 dif++;
369
370 if( b == 0xFF ) {
371
372 dif += (int)m_cStream.skip2code();
373 bEndAtsc = true;
374 b = 0;
375
376 } else if( b == 0x00 ) {
377
378 b = (unsigned char)m_cStream.ret_value(1);
379 dif++;
380
381 if( b == 0xFF ) {
382
383 dif += (int)m_cStream.skip2code();
384 bEndAtsc = true;
385 b = 0;
386
387 }
388
389 }
390
391 } while( b != 0 );
392
393 }
394
395 } while( !bEndAtsc );
396
397 #if defined(DumpUserData)
398 fprintf(m_nFile, " %08x: ATSC User Data\tSize :\t%d bytes\n", xloc, dif );
399 #endif
400
401 return dif;
402
403 }
404
405 int CTivoScan::ProcessUserdata()
406 {
407 #if defined(DumpUserData)
408 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
409 #endif
410 int dif = 0;
411
412 //Jrm
413 // To set a break location at a specific byte count in the .tivo file...
414 // if( xloc == 0x00e4ee12 )
415 // int jrm = 1;
416 //Jrm
417
418 unsigned char data[256];
419 memset( data, 0, sizeof(data) );
420 bool valid = false;
421 int cod;
422
423 data[0] = (unsigned char)m_cStream.ret_value(1);
424 dif++;
425 if( data[0] == 0x47 ) {
426
427 data[1] = (unsigned char)m_cStream.ret_value(1);
428 dif++;
429 if( data[1] == 0x41 ) {
430
431 data[2] = (unsigned char)m_cStream.ret_value(1);
432 dif++;
433 if( data[2] == 0x39 ) {
434
435 data[3] = (unsigned char)m_cStream.ret_value(1);
436 dif++;
437 if( data[3] == 0x34 )
438 return ASTCDecode( dif );
439 }
440 }
441 }
442
443 // Eats up the bitstream until we find another code of interest...
444 size_t nd;
445 for( nd=dif; nd<sizeof(data); nd++ ) {
446
447 cod = m_cStream.next_code(&valid);
448 if( !valid ) {
449 data[nd] = (unsigned char)m_cStream.ret_value(1);
450 dif += 1;
451 } else
452 break;
453
454 } // for
455
456 dif += (int)m_cStream.skip2code();
457
458 #if defined(DumpUserData)
459 fprintf(m_nFile, " %08x: User Data\tSize :\t%d bytes\n", xloc, dif );
460 fprintf(m_nFile, " ");
461 std::string dvalue;
462 size_t i, l;
463 for( i=0, l=1; i<=nd; i++, l++ ) {
464 fprintf(m_nFile, " %02X", data[i] );
465 if( l >= 20 ) {
466 fprintf(m_nFile, "\n ");
467 l = 0;
468 }
469 }
470 if( l != 0 )
471 fprintf(m_nFile, "\n");
472 #endif
473
474 return dif;
475
476 }
477
478 int CTivoScan::ProcessPictureHeader()
479 {
480 #if defined(DumpVideoPESData)
481 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
482 #endif
483 int dif = 0;
484
485 int temporal_reference = m_cStream.ret_value(1)<<2;
486 temporal_reference |= m_cStream.ret_bit_value(0,1,false);
487 dif += 1;
488
489 m_nPictureCodingType = m_cStream.ret_bit_value(2,4,true); // 1: I-Picture, 2: P-Picture, 3: B-Picture
490 dif += 1;
491
492 m_cStream.skip_info(1); // VBV Delay
493 dif += 1;
494
495 int epos;
496
497 switch( m_nPictureCodingType ) {
498
499 case 1:
500 epos = 5;
501 break;
502
503 case 2:
504 m_cStream.skip_info(1); // full_pel_backward_vector
505 dif += 1;
506 epos = 1;
507 break;
508
509 case 3:
510 m_cStream.skip_info(1); // full_pel_forward_vector and full_pel_backward_vector
511 dif += 1;
512 epos = 5;
513 break;
514
515 default:
516 m_cStream.go_back(dif+1);
517 dif = (int)m_cStream.skip2code();
518 return 0;
519
520 }
521
522 while( m_cStream.ret_bit(epos) ) {
523
524 m_cStream.skip_info(1);
525 dif += 1;
526
527 epos++;
528 if( epos > 7 ) {
529 m_cStream.skip_info(1);
530 dif += 1;
531 epos = 0;
532 }
533
534 }
535
536 m_cStream.skip_info(1);
537 dif += 1;
538
539 dif += (int)m_cStream.skip2code();
540
541 #if defined(DumpVideoPESData)
542 fprintf(m_nFile, " %08x: Picture Header\tSize :\t%d bytes, type : %d\n", xloc, dif, m_nPictureCodingType );
543 #endif
544
545 return dif;
546
547 }
548
549 int CTivoScan::ProcessPictureCodingExtension()
550 {
551
552 int dif = 0;
553 bool valid = false;
554 if( m_cStream.next_code(&valid) != 181 || !valid )
555 return dif;
556
557 int cod;
558 m_cStream.read_code(&cod);
559 dif += 4;
560
561 #if defined(DumpVideoPESData)
562 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
563 #endif
564
565 // Eat up the bitstream until we find another code of interest...
566 dif += (int)m_cStream.skip2code();
567
568 #if defined(DumpVideoPESData)
569 fprintf(m_nFile, " %08x: Picture Coding Extension\tSize :\t%d bytes\n", xloc, dif );
570 #endif
571
572 return dif;
573
574 }
575
576 int CTivoScan::ProcessPictureData()
577 {
578 #if defined(DumpVideoPESData) || defined(DumpPictureData)
579 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
580 #endif
581 int dif = 0;
582 bool valid = true;
583
584 while( m_cStream.next_code(&valid) > 0x000 && m_cStream.next_code(&valid) <= 0x0AF&& valid ) { // Slice Data
585
586 int cod;
587 if( m_cStream.read_code(&cod) )
588 dif += 4;
589 else
590 break;
591
592 #if defined(DumpPictureData)
593 int slice_vertical_position = cod & 0xFF;
594 unsigned long tloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
595 #endif
596
597 // Eats up the bitstream until we find another code of interest...
598 int slice = (int)m_cStream.skip2code();
599
600 #if defined(DumpPictureData)
601 fprintf(m_nFile, " %08x: Slice Data (%d)\tSize :\t%d bytes\n", tloc, slice_vertical_position, slice );
602 #endif
603
604 dif += slice;
605
606 }
607
608 #if defined(DumpVideoPESData)
609 fprintf(m_nFile, " %08x: Frame Data\tSize :\t%d bytes\n", xloc, dif );
610 #endif
611
612 return dif;
613
614 }
615
616 int CTivoScan::ProcessExtensionAndUserdata( int etype )
617 {
618
619 int dif = 0;
620 bool valid = true;
621
622 while( ( m_cStream.next_code(&valid) == 178 && valid ) || // USERDATA_START_CODE
623 ( m_cStream.next_code(&valid) == 181 && valid ) ) { // EXTENSION_START_CODE
624
625 int cod;
626 if( m_cStream.read_code(&cod) )
627 dif += 4;
628 else
629 break;
630
631 if( cod == 181 )
632 dif += ProcessExtensiondata( etype );
633 else if ( cod == 178)
634 dif += ProcessUserdata();
635
636 }
637
638 return dif;
639
640 }
641
642 int CTivoScan::ProcessSequenceExtension()
643 {
644 #if defined(DumpVideoPESData)
645 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
646 #endif
647 int dif = 0;
648 bool valid = false;
649
650 if( m_cStream.next_code(&valid) == 181 && valid ) { // EXTENSION_START_CODE
651
652 int cod;
653 m_cStream.read_code(&cod);
654 dif += 4;
655
656 // Eat up the bitstream until we find another code of interest...
657
658 for(;;) {
659
660 cod = m_cStream.next_code(&valid);
661 if( !valid ) {
662 m_cStream.ret_value(1);
663 dif += 1;
664 } else
665 break;
666
667 } // for
668
669 #if defined(DumpVideoPESData)
670 fprintf(m_nFile, " %08x: Sequence Extension Data\tSize :\t%d bytes\n", xloc, dif );
671 #endif
672
673 }
674
675 return dif;
676
677 }
678
679 void CTivoScan::ProcessVideoPES()
680 {
681 #if defined(DumpVideoPESData)
682 unsigned long xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
683 #endif
684
685 int jmp = m_cStream.ret_value(2);
686
687 int dif=0;
688 m_cStream.skip_info(1);
689 dif += 1;
690
691 bool stp=m_cStream.ret_bit(0);
692 bool std=m_cStream.ret_bit(1);
693 m_cStream.skip_info(1);
694
695 int hdr=m_cStream.ret_value(1);
696 dif += 2;
697
698 std::string stamp("No PTS");
699
700 if (stp){
701 m_lastPTS = m_cStream.get_PES_stamp();
702 stamp = boost::str(boost::format("PTS = %.2f") % m_lastPTS );
703 dif += 5;
704 hdr -= 5;
705 }
706
707 if (std) {
708 m_lastDTS = m_cStream.get_PES_stamp();
709 std::string dts;
710 dts = boost::str(boost::format(", DTS = %.2f") % m_lastDTS );
711 stamp+=dts;
712 dif += 5;
713 hdr -= 5;
714 } else
715 stamp+=", No DTS";
716
717 n_vp++;
718
719 s_vp = s_vp + jmp + 6;
720
721 #if defined(DumpVideoPESData)
722 fprintf(m_nFile, " %08x: Video PES \t\tnr. %d\t\tSize :\t%d bytes\t%s\n", xloc, n_vp, jmp, stamp.c_str() );
723 #endif
724
725 m_cStream.skip_info(hdr);
726 dif += hdr;
727 jmp -= dif;
728 bool done = false;
729
730 int cod;
731 bool valid;
732
733 jmp -= (int)m_cStream.skip2code();
734
735 if( m_cStream.next_code(&valid) == 179 && valid ) { // SEQUENCE HEADER
736
737 if( m_cStream.read_code(&cod) ) {
738 jmp -= 4;
739 jmp -= ProcessSequenceHeader();
740 jmp -= ProcessSequenceExtension();
741 } else
742 goto exitReturn;
743
744 }
745
746 // Make sure we are on the next start code
747 while( jmp > 0 && !done ) {
748
749
750 jmp -= ProcessExtensionAndUserdata( SEQUENCE_EXTENSION );
751
752 do {
753
754 if( m_cStream.next_code(&valid) == 184 && valid ) { // GROUP START CODE)
755
756 if( m_cStream.read_code(&cod) )
757 jmp -= 4;
758 else
759 goto exitReturn;
760
761 jmp -= ProcessGroupStart();
762 jmp -= ProcessExtensionAndUserdata( GROUP_EXTENSION );
763
764 } else if( m_cStream.next_code(&valid) == 000 && valid ) { // PICTURE START CODE
765
766 if( m_cStream.read_code(&cod) )
767 jmp -= 4;
768 else
769 goto exitReturn;
770
771 jmp -= ProcessPictureHeader();
772 jmp -= ProcessPictureCodingExtension();
773 jmp -= ProcessExtensionAndUserdata( PICTURE_EXTENSION );
774 jmp -= ProcessPictureData();
775
776 } else if( m_cStream.next_code(&valid) <= 0x0AF && valid ) { // Slice Data
777 jmp -= ProcessPictureData();
778 } else {
779 break;
780 }
781
782 } while( ( m_cStream.next_code(&valid) <= 0x0AF && valid ) || // PICTURE_START_CODE or Slice Data
783 ( m_cStream.next_code(&valid) == 184 && valid ) ); // GROUP_START_CODE
784
785 if( jmp > 0 ) {
786
787 if( m_cStream.next_code(&valid) == 179 && valid ) { // SEQUENCE HEADER
788
789 if( m_cStream.read_code(&cod) ) {
790 jmp -= 4;
791 jmp -= ProcessSequenceHeader();
792 jmp -= ProcessSequenceExtension();
793 } else
794 goto exitReturn;
795
796 } else {
797
798 m_cStream.skip_info(jmp);
799 jmp = 0;
800
801 }
802
803 }
804
805 } // while
806
807 exitReturn:
808
809 if (jmp > 0)
810 m_cStream.skip_info(jmp);
811 m_cStream.skip2code();
812
813 }
814
815 bool CTivoScan::ProcessPS( const char * lpFileName, const std::string & szOutputName )
816 {
817
818 std::string szInputFile(lpFileName);
819
820 int percent = 0;
821 int p;
822
823 int cod;
824 double SCR;
825 std::string stamp;
826 bool r_ok;
827 bool r_end;
828
829 r_ok=true;
830 r_end=false;
831 n_pks = 0;
832 n_sp = 0;
833 n_ap = 0;
834 n_vp = 0;
835 n_psm = 0;
836 n_op = 0;
837
838 s_pks=s_sp=s_vp=s_ap=s_op=s_psm=0;
839
840 #ifdef _DEBUG
841
842 std::string szOutputFile = szOutputName + ".txt\0";
843 m_nFile = fopen( szOutputFile.c_str(), "wb");
844 if( m_nFile == NULL ) {
845 TRACE("m_cFile could not be opened %0x\n", errno);
846 return false;
847 }
848
849 fprintf(m_nFile, "This File lists the packets found in %s\n", szInputFile.c_str() );
850
851 #endif
852
853 m_cStream.m_dwBufferBase = 0;
854
855 if( !m_Cc.Initialize(szOutputName) )
856 return false;
857 m_szOutputCaptionFile = m_Cc.getOutputFileName();
858
859 m_cStream.Initialize(szInputFile);
860
861 m_cStream.fill_buffer(0);
862 int jmp = 0;
863 unsigned long xloc;
864
865 while((!r_end)&&(m_cStream.pos<=m_cStream.buf_len)&&(r_ok)) {
866
867 m_cStream.read_code(&cod);
868
869 if( !m_bQuiet )
870 if( (p=m_cStream.PercentDone()) > percent ) {
871 percent = p;
872 if (m_cbPercentChange)
873 m_cbPercentChange (percent);
874 }
875
876 switch( cod ) {
877
878 case 0: // Unknown packet
879 r_ok=false;
880 break;
881
882 case 185: // MPEG_end
883 r_end=true;
884 break;
885
886 case 186: // Pack header
887
888 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
889
890 //Jrm
891 // if( xloc == 0x0190fff3 )
892 // int jrm = 1;
893 //Jrm
894
895 SCR=m_cStream.get_SCR();
896 m_cStream.skip_info(3);
897 if (!m_cStream.zero()) {
898
899 jmp = m_cStream.ret_bit_value(5,7,true);
900 m_cStream.skip_info(jmp);
901 jmp=jmp+14;
902
903 } else {
904
905 m_cStream.go_back(1);
906 jmp=12;
907
908 }
909
910 n_pks++;
911 s_pks=s_pks+jmp;
912 #if defined(DumpPSData)
913 fprintf(m_nFile, " %08x: PACK header \t\tnr. %d\t\tSize :\t%d bytes\tSCR = %d\n", xloc, n_pks, jmp, SCR);
914 #endif
915 break;
916
917 case 187: // System header
918
919 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
920 jmp=m_cStream.ret_value(2);
921 m_cStream.skip_info(jmp);
922 n_sp++;
923 jmp=jmp+6;
924 s_sp=s_sp+jmp;
925 #if defined(DumpPSData)
926 fprintf(m_nFile, " %08x: System header \t\tnr. %d\t\tSize :\t%d bytes\n", xloc, n_sp, jmp );
927 #endif
928 break;
929
930 case 188: //PSM
931
932 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
933 jmp=m_cStream.ret_value(2);
934 m_cStream.skip_info(jmp);
935 n_psm++;
936 jmp=jmp+6;
937 s_psm=s_psm+jmp;
938 #if defined(DumpPSData)
939 fprintf(m_nFile, " %08x: Program Stream Map \t\tnr. %d\t\tSize :\t%d bytes\n", xloc, n_psm, jmp );
940 #endif
941 break;
942
943 case 189: // PES Private 1
944
945 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
946 jmp=m_cStream.ret_value(2);
947 m_cStream.skip_info(jmp);
948 n_op++;
949 jmp=jmp+6;
950 s_op=s_op+jmp;
951 #if defined(DumpPSData)
952 fprintf(m_nFile, " %08x: Private m_cStream 1 PES \tnr. %d\t\tSize :\t%d bytes\n", xloc, n_op, jmp );
953 #endif
954 break;
955
956 case 190: // PES Padding
957
958 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
959 jmp=m_cStream.ret_value(2);
960 m_cStream.skip_info(jmp);
961 n_op++;
962 jmp=jmp+6;
963 s_op=s_op+jmp;
964 #if defined(DumpPSData)
965 fprintf(m_nFile, " %08x: Padding m_cStream PES \tnr. %d\t\tSize :\t%d bytes\n", xloc, n_op, jmp );
966 #endif
967 break;
968
969 case 191: // PES Private 2
970
971 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
972 jmp=m_cStream.ret_value(2);
973 m_cStream.skip_info(jmp);
974 n_op++;
975 jmp=jmp+6;
976 s_op=s_op+jmp;
977 #if defined(DumpPSData)
978 fprintf(m_nFile, " %08x: Private m_cStream 2 PES \tnr. %d\t\tSize :\t%d bytes\n", xloc, n_op, jmp );
979 #endif
980 break;
981
982 default:
983
984 if ( (cod>=192) && (cod<=223) ) { // PES Audio
985
986 ProcessAudioPES();
987
988 } else if( (cod>=224) && (cod<=239) ) { // PES Video
989
990 ProcessVideoPES();
991
992 } else if( (cod>=240) && (cod<=255) ) { // PES Data
993
994 xloc = (unsigned long)(m_cStream.m_dwBufferBase + m_cStream.pos - 4);
995 jmp=m_cStream.ret_value(2);
996 m_cStream.skip_info(jmp);
997 n_op++;
998 jmp=jmp+6;
999 s_op=s_op+jmp;
1000
1001 #if defined(DumpPSData)
1002 fprintf(m_nFile, " %08x: Data PES \t\tnr. %d\t\tSize :\t%d bytes\n", xloc, n_op, jmp );
1003 #endif
1004
1005 }
1006
1007 break;
1008
1009 } // switch
1010
1011 } // while
1012
1013 #ifdef _DEBUG
1014
1015 if(r_end)
1016 fprintf(m_nFile, "MPEG end packet reached\n");
1017 else
1018 fprintf(m_nFile, "No MPEG end packet encountered !\n");
1019
1020 if(r_ok)
1021 fprintf(m_nFile, "Read - OK...\n");
1022 else
1023 fprintf(m_nFile, "Read - Error...\n");
1024
1025 fprintf(m_nFile, "\nStatistics :\n");
1026 fprintf(m_nFile, "-----------\n");
1027 fprintf(m_nFile, "Pack headers : %d\t Total size : %lld bytes\n", n_pks, s_pks );
1028 fprintf(m_nFile, "System headers : %d\t Total size : %lld bytes\n", n_sp, s_sp );
1029 fprintf(m_nFile, "PSM packets : %d\t Total size : %lld bytes\n", n_psm, s_psm );
1030 fprintf(m_nFile, "Video packets : %d\t Total size : %lld bytes\n", n_vp, s_vp );
1031 fprintf(m_nFile, "Audio packets : %d\t Total size : %lld bytes\n", n_ap, s_ap );
1032 fprintf(m_nFile, "Other packets : %d\t Total size : %lld bytes\n", n_op, s_op );
1033
1034 #endif
1035
1036 m_Cc.WriteSubtitles();
1037
1038 switch( m_nCaptionFormat ) {
1039
1040 case FMT_SAMI:
1041
1042 {
1043 int nSync;
1044 if( m_bUseCutoffDuration )
1045 nSync = m_nLastSync + m_nCutoffDuration;
1046 else
1047 nSync = m_nLastSync + 5000;
1048
1049 fprintf (m_Cc.m_nFile, "<SYNC Start=%d>\n", nSync );
1050 m_Cc.WriteLine( "<P CLASS=ENUSCC>&nbsp;</P>" );
1051 m_Cc.WriteLine( "</SYNC>" );
1052
1053 }
1054
1055 break;
1056
1057 case FMT_SRT:
1058
1059 if( !m_csCurrentCaption.empty() ) {
1060
1061 int nStartTime = m_nLastSync;
1062 int nEndTime;
1063 if( m_bUseCutoffDuration )
1064 nEndTime = m_nLastSync + m_nCutoffDuration;
1065 else
1066 nEndTime = m_nLastSync + 5000;
1067
1068 m_nCaptionCount++;
1069 fprintf(m_Cc.m_nFile, "%d\n", m_nCaptionCount );
1070
1071 fprintf(m_Cc.m_nFile, "%s --> %s\n", SrtTimeString(nStartTime).c_str(), SrtTimeString(nEndTime).c_str() );
1072
1073 fprintf(m_Cc.m_nFile, "%s\n\n", m_csCurrentCaption.c_str() );
1074
1075 }
1076
1077 break;
1078
1079 } // switch
1080
1081 if( m_bShowSummary ) {
1082
1083 m_Cc.WriteLine( "<!--" );
1084
1085 if(r_end)
1086 fprintf(m_Cc.m_nFile, "MPEG_end packet reached\n");
1087 else
1088 fprintf(m_Cc.m_nFile, "No MPEG_end packet encountered !\n");
1089
1090 if(r_ok)
1091 fprintf(m_Cc.m_nFile, "Read - OK...\n");
1092 else
1093 fprintf(m_Cc.m_nFile, "Read - Error...\n");
1094
1095 fprintf(m_Cc.m_nFile, "\n");
1096
1097 fprintf(m_Cc.m_nFile, "Statistics :\n");
1098
1099 fprintf(m_Cc.m_nFile, "-----------\n");
1100
1101 fprintf(m_Cc.m_nFile,"Pack headers : %d\t Total size : %lld bytes\n", n_pks, s_pks );
1102
1103 fprintf(m_Cc.m_nFile,"System headers : %d\t Total size : %lld bytes\n", n_sp, s_sp );
1104
1105 fprintf(m_Cc.m_nFile, "PSM packets : %d\t Total size : %lld bytes\n", n_psm, s_psm );
1106
1107 fprintf(m_Cc.m_nFile, "Video packets : %d\t Total size : %lld bytes\n", n_vp, s_vp );
1108
1109 fprintf(m_Cc.m_nFile, "Audio packets : %d\t Total size : %lld bytes\n", n_ap, s_ap );
1110
1111 fprintf(m_Cc.m_nFile, "Other packets : %d\t Total size : %lld bytes\n", n_op, s_op );
1112
1113 m_Cc.WriteLine( "-->" );
1114
1115 }
1116
1117 #ifdef _DEBUG
1118 CloseFile();
1119 #endif
1120
1121 m_Cc.Close();
1122
1123 m_cStream.end_PS();
1124 return r_ok;
1125 }
1126
1127 //
1128 // CloseFile
1129 //
1130 void CTivoScan::CloseFile()
1131 {
1132
1133 if( m_nFile != NULL ) {
1134 fclose( m_nFile );
1135 m_nFile = NULL;
1136 }
1137
1138 }
1139
1140 //
1141 // WriteString
1142 //
1143 void CTivoScan::WriteString( const std::string & szString )
1144 {
1145 // If the file has already been closed, don't continue
1146 if( m_nFile == NULL )
1147 return;
1148
1149 fwrite(szString.data(), 1, szString.length(), m_nFile );
1150
1151 }

cvs@jdrake.com
ViewVC Help
Powered by ViewVC 1.1.13