1 /*
2 * demuxer.c
3 *
4 * Copyright (C) Thomas Oestreich - June 2001
5 *
6 * This file is part of transcode, a video stream processing tool
7 *
8 * transcode is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * transcode is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24 #include "transcode.h"
25 #include "libtc/libtc.h"
26 #include "tcinfo.h"
27
28 #include "ioaux.h"
29 #include "aux_pes.h"
30 #include "seqinfo.h"
31 #include "demuxer.h"
32 #include "packets.h"
33
34 #include <math.h>
35
36 static int demux_mode=TC_DEMUX_SEQ_ADJUST;
37
38 int gop, gop_pts, gop_cnt;
39
40 typedef struct timecode_struc /* Time_code Struktur laut MPEG */
41 { unsigned long msb; /* fuer SCR, DTS, PTS */
42 unsigned long lsb;
43 unsigned long reference_ext;
44 unsigned long negative; /* for delays when doing multiple files */
45 } Timecode_struc;
46
47 #define MAX_FFFFFFFF 4294967295.0 /* = 0xffffffff in hex. */
48
49 /* ------------------------------------------------------------
50 *
51 * support code (scr_rewrite()) moved from aux_pes.c
52 *
53 * ------------------------------------------------------------*/
54
make_timecode(double timestamp,Timecode_struc * pointer)55 static void make_timecode (double timestamp, Timecode_struc *pointer)
56 {
57 double temp_ts;
58
59 if (timestamp < 0.0) {
60 pointer->negative = 1;
61 timestamp = -timestamp;
62 } else
63 pointer->negative = 0;
64
65 temp_ts = floor(timestamp / 300.0);
66
67 if (temp_ts > MAX_FFFFFFFF) {
68 pointer->msb=1;
69 temp_ts -= MAX_FFFFFFFF;
70 pointer->lsb=(unsigned long)temp_ts;
71 } else {
72 pointer->msb=0;
73 pointer->lsb=(unsigned long)temp_ts;
74 }
75
76 pointer->reference_ext = (unsigned long)(timestamp - (floor(timestamp / 300.0) * 300.0));
77
78 }
79
80 #define MPEG2_MARKER_SCR 1 /* MPEG2 Marker SCR */
81
82 /*************************************************************************
83 Kopiert einen TimeCode in einen Bytebuffer. Dabei wird er nach
84 MPEG-Verfahren in bits aufgesplittet.
85
86 Makes a Copy of a TimeCode in a Buffer, splitting it into bitfields
87 according to MPEG-System
88 *************************************************************************/
89
buffer_timecode_scr(Timecode_struc * pointer,unsigned char ** buffer)90 static void buffer_timecode_scr (Timecode_struc *pointer, unsigned char **buffer)
91 {
92
93 unsigned char temp;
94 unsigned char marker=MPEG2_MARKER_SCR;
95
96
97 temp = (marker << 6) | (pointer->msb << 5) |
98 ((pointer->lsb >> 27) & 0x18) | 0x4 | ((pointer->lsb >> 28) & 0x3);
99 *((*buffer)++)=temp;
100 temp = (pointer->lsb & 0x0ff00000) >> 20;
101 *((*buffer)++)=temp;
102 temp = ((pointer->lsb & 0x000f8000) >> 12) | 0x4 |
103 ((pointer->lsb & 0x00006000) >> 13);
104 *((*buffer)++)=temp;
105 temp = (pointer->lsb & 0x00001fe0) >> 5;
106 *((*buffer)++)=temp;
107 temp = ((pointer->lsb & 0x0000001f) << 3) | 0x4 |
108 ((pointer->reference_ext & 0x00000180) >> 7);
109 *((*buffer)++)=temp;
110 temp = ((pointer->reference_ext & 0x0000007F) << 1) | 1;
111 *((*buffer)++)=temp;
112
113 }
114
scr_rewrite(char * buf,uint32_t pts)115 static void scr_rewrite(char *buf, uint32_t pts)
116 {
117 Timecode_struc timecode;
118 unsigned char * ucbuf = (unsigned char *)buf;
119
120 timecode.msb = 0;
121 timecode.lsb = 0;
122 timecode.reference_ext = 0;
123 timecode.negative = 0;
124
125 make_timecode((double) pts, &timecode);
126
127 buffer_timecode_scr(&timecode, &ucbuf);
128 }
129
130 /* ------------------------------------------------------------
131 *
132 * demuxer / synchronization thread
133 *
134 * ------------------------------------------------------------*/
135
tcdemux_thread(info_t * ipipe)136 void tcdemux_thread(info_t *ipipe)
137 {
138
139 int k, id=0, zz=0;
140
141 int j, i, bytes, filesize;
142 char *buffer=NULL;
143
144 int payload_id=0, select=PACKAGE_ALL;
145
146 double pts=0.0f, ref_pts=0.0f, resync_pts=-1.0f, pts_diff=0.0f, track_initial_pts=0.0f;
147 double av_fine_pts1=-1.0f, av_fine_pts2=-1.0f, av_fine_diff=0.0f;
148
149 uint32_t frame_based_lpts=0;
150
151 int unit_seek=0, unit, track=0, is_track=0;
152
153 int resync_seq1=0, resync_seq2=INT_MAX, seq_dump, seq_seek;
154 int keep_seq = 0;
155 int hard_fps = 0;
156
157 int has_pts_dts=0, demux_video=0, demux_audio=0;
158
159 int flag_flush = 0;
160 int flag_force = 0;
161 int flag_eos = 0;
162 int flag_has_audio = 0;
163 int flag_append_audio = 0;
164 int flag_notify = 1;
165 int flag_avsync = 1;
166 int flag_skip = 0;
167 int flag_sync_reset = 0;
168 int flag_sync_active = 0;
169 int flag_loop_all = 0;
170 int flag_av_fine_tune = 0;
171 int flag_rewrite_scr = 0;
172 int flag_field_encoded= 0;
173
174 //for demux_mode=2
175 int seq_picture_ctr=0, pack_picture_ctr=0, sequence_ctr=0, packet_ctr=0;
176
177 char buf[256];
178 const char *logfile;
179 unsigned long i_pts, i_dts;
180 unsigned int packet_size=VOB_PACKET_SIZE;
181 seq_list_t *ptr=NULL;
182 double fps;
183
184
185 // allocate space
186 if((buffer = tc_zalloc(packet_size))==NULL) {
187 tc_log_perror(__FILE__, "out of memory");
188 exit(1);
189 }
190
191 // copy info parameter to local variables
192
193 unit_seek = ipipe->ps_unit;
194 resync_seq1 = ipipe->ps_seq1;
195 resync_seq2 = ipipe->ps_seq2;
196 track = ipipe->track;
197
198 //map track on substream id
199
200 switch(ipipe->codec) {
201
202 case TC_CODEC_SUB:
203 track+=0x20;
204 flag_rewrite_scr=1;
205 break;
206 case TC_CODEC_AC3:
207 track+=0x80;
208 break;
209 case TC_CODEC_PCM:
210 track+=0xA0;
211 break;
212 case TC_CODEC_MP3:
213 track+=0xC0;
214 break;
215 case TC_CODEC_MPEG2:
216 // for MPEG2 video, use this substream id for sync adjustment
217 track=ipipe->subid;
218 demux_video=1;
219 break;
220 }
221
222 //0.6.0pre4
223 if(demux_video==0) {
224
225 if(ipipe->demux == TC_DEMUX_SEQ_FSYNC)
226 ipipe->demux=TC_DEMUX_SEQ_ADJUST;
227
228 if(ipipe->demux == TC_DEMUX_SEQ_FSYNC2)
229 ipipe->demux=TC_DEMUX_SEQ_ADJUST2;
230
231 //substream synchonized with video in "force frame rate" mode
232 demux_audio=1;
233 }
234
235 if(ipipe->demux == TC_DEMUX_SEQ_FSYNC || ipipe->demux == TC_DEMUX_SEQ_FSYNC2 || ipipe->demux == TC_DEMUX_SEQ_LIST) {
236
237 //allocate buffer
238 if(flush_buffer_init(ipipe->fd_out, ipipe->verbose)<0) {
239 tc_log_error(__FILE__, "flush buffer facility init failed");
240 exit(1);
241 }
242
243 //need to open the logfile
244 if(seq_init(ipipe->name, ipipe->fd_log, ipipe->fps, ipipe->verbose)<0) {
245 tc_log_error(__FILE__, "sync mode init failed");
246 exit(1);
247 }
248 }
249
250
251 //new default behaving:
252 // if(unit_seek==0 && resync_seq1==0 && resync_seq2 == INT_MAX) flag_loop_all=1;
253 //changes 0.6.0pre3:
254 //tcprobe selects start unit --> switch to flag_loop_all always true
255 // for any given unit
256 if(resync_seq1==0 && resync_seq2 == INT_MAX) flag_loop_all=1;
257
258 demux_mode = ipipe->demux;
259 select = ipipe->select;
260 fps = ipipe->fps;
261 logfile = ipipe->name;
262 keep_seq = ipipe->keep_seq;
263 hard_fps = ipipe->hard_fps_flag;
264
265 j=0; //packet counter
266 i=0; //skipped packets counter
267 k=0; //unit counter
268
269 // will be switched on as soon start of sequences to flush is reached
270 flag_flush=0;
271
272 flag_notify=1;
273
274 flag_avsync=0;
275 flag_append_audio=0;
276
277 if(keep_seq) flag_sync_active=1;
278
279 unit=unit_seek;
280
281 seq_seek = resync_seq1;
282 seq_dump = resync_seq2 - resync_seq1;
283
284 ++unit_seek;
285 ++seq_seek;
286
287 if(!flag_loop_all) {
288 tc_log_msg(__FILE__, "seeking to sequence %d:%d ...", unit, resync_seq1);
289 }
290
291 filesize = 0;
292 for(;;) {
293
294 /* ------------------------------------------------------------
295 *
296 * (I) read a 2048k block
297 *
298 * ------------------------------------------------------------*/
299
300 if((bytes=tc_pread(ipipe->fd_in, buffer, packet_size)) != packet_size) {
301
302 //program end code?
303 if(bytes==4) {
304 if(scan_pack_header(buffer, MPEG_PROGRAM_END_CODE)) {
305 if(ipipe->verbose & TC_DEBUG)
306 tc_log_msg(__FILE__, "(pid=%d) program stream end code detected",
307 getpid());
308 break;
309 }
310 }
311
312 if(bytes)
313 tc_log_warn(__FILE__, "invalid program stream packet size (%d/%d)",
314 bytes, packet_size);
315
316 break;
317 }
318 filesize += bytes;
319
320 // do not make any tests in pass-through mode
321 if(demux_mode==TC_DEMUX_OFF) goto flush_packet;
322
323 /* ------------------------------------------------------------
324 *
325 * (II) packet header ok?
326 *
327 * ------------------------------------------------------------*/
328
329
330 if(!scan_pack_header(buffer, TC_MAGIC_VOB)) {
331
332 if(flag_notify && (ipipe->verbose & TC_DEBUG))
333 tc_log_warn(__FILE__, "(pid=%d) invalid packet header detected",
334 getpid());
335
336 // something else?
337
338 if(scan_pack_header(buffer, MPEG_VIDEO) | scan_pack_header(buffer, MPEG_AUDIO)) {
339
340 if(ipipe->verbose & TC_STATS)
341 tc_log_msg(__FILE__, "(pid=%d) MPEG system stream detected",
342 getpid());
343
344 if(scan_pack_header(buffer, MPEG_VIDEO)) payload_id=PACKAGE_VIDEO;
345 if(scan_pack_header(buffer, MPEG_AUDIO)) payload_id=PACKAGE_AUDIO_MP3;
346
347 // no further processing
348 goto flush_packet;
349 } else {
350
351 tc_log_warn(__FILE__, "(pid=%d) '0x%02x%02x%02x%02x' not yet supported",
352 getpid(), buffer[0] & 0xff, buffer[1] & 0xff,
353 buffer[2] & 0xff, buffer[3] & 0xff);
354 break;
355 }
356 } else {
357
358 //MPEG1?
359 if ((buffer[4] & 0xf0) == 0x20) {
360
361 payload_id=PACKAGE_MPEG1;
362 flag_flush=1;
363
364 if(ipipe->verbose & TC_STATS)
365 tc_log_msg(__FILE__, "(pid=%d) MPEG-1 video stream detected",
366 getpid());
367
368 // no further processing
369 goto flush_packet;
370 }
371 }
372
373
374 /* ------------------------------------------------------------
375 *
376 * (III) analyze packet contents
377 *
378 * ------------------------------------------------------------*/
379
380
381 // proceed with a valid package, assume defaults
382
383 flag_skip=0; //do not skip
384 has_pts_dts=0; //no pts_dts stamp
385 payload_id=0; //payload unknown
386 flag_sync_reset=0; //no reset of syncinfo
387
388 id = buffer[17] & 0xff; //payload id byte
389
390 //MPEG 2?
391 if ((buffer[4] & 0xc0) == 0x40) {
392
393 // do not change any flags
394
395 if(ipipe->verbose & TC_STATS) {
396 //display info only once
397 tc_log_msg(__FILE__, "(pid=%d) MPEG-2 video stream detected",
398 getpid());
399 }
400 } else {
401
402 //MPEG1
403 if ((buffer[4] & 0xf0) == 0x20) {
404
405 payload_id=PACKAGE_MPEG1;
406
407 if(ipipe->verbose & TC_STATS) {
408 //display info only once
409 tc_log_msg(__FILE__, "(pid=%d) MPEG-1 video stream detected",
410 getpid());
411 }
412 } else {
413
414 payload_id=PACKAGE_PASS;
415
416 if(ipipe->verbose & TC_DEBUG)
417 tc_log_warn(__FILE__, "(pid=%d) unknown stream packet id detected",
418 getpid());
419 }
420
421 //flush all MPEG1 stuff
422 goto flush_packet;
423 }
424
425 /* ------------------------------------------------------------
426 *
427 * (IV) audio payload
428 *
429 * ------------------------------------------------------------*/
430
431 // check payload id
432 // process this audio packet?
433
434 // sync to AC3 audio mode?
435 if(id == P_ID_AC3) payload_id = PACKAGE_PRIVATE_STREAM;
436
437 // sync to MP3 audio mode?
438 if(id >= 0xc0 && id <= 0xdf) payload_id = PACKAGE_AUDIO_MP3;
439
440 // are we dealing with the right track?
441 // check here:
442
443 is_track=0;
444
445 if(payload_id == PACKAGE_PRIVATE_STREAM) {
446
447 //position of track code
448 uint8_t *_buf=buffer+14;
449 uint8_t *_tmp=_buf + 9 + _buf[8];
450
451 is_track = ((*_tmp) == track) ? 1:0;
452
453 if(ipipe->verbose & TC_STATS)
454 tc_log_msg(__FILE__, "substream [0x%x] %d", *_tmp, is_track);
455
456 if(is_track==0) {
457 flag_skip=1; //drop this packet
458 } else {
459 flag_skip=0;
460 goto sync_track;
461 }
462 }
463
464 if(payload_id & PACKAGE_AUDIO_MP3) {
465
466 is_track = ((id) == track) ? 1:0;
467 if(is_track==0) flag_skip=1; //drop this packet
468
469 if(ipipe->verbose & TC_STATS)
470 tc_log_msg(__FILE__, "MPEG audio track [0x%x] %d", id, is_track);
471 }
472
473 sync_track:
474
475 if(is_track) {
476
477
478 if(flag_sync_active==0) {
479
480 //first valid audio packet!
481
482 // get pts time stamp:
483 ac_memcpy(buf, &buffer[20], 16);
484 has_pts_dts=get_pts_dts(buf, &i_pts, &i_dts);
485
486 if(has_pts_dts) {
487 track_initial_pts=(double)i_pts/90000.;
488 } else {
489 //fallback to scr time stamp:
490 ac_memcpy(buf, &buffer[4], 6);
491 track_initial_pts = read_time_stamp(buf);
492 }
493
494 if(resync_pts<0) {
495 pts_diff = track_initial_pts;
496 } else {
497 pts_diff = track_initial_pts - resync_pts;
498 }
499
500 //pts_diff<0 is OK, the packets will be dropped to establish sync
501 //pts_diff>0 is not so simple, since we need to drop video
502 //packets, already submitted to flush buffer
503
504 //enable sync mode, check for PTS giant leap????
505 if(pts_diff < TC_DEMUX_MIN_PTS || pts_diff > TC_DEMUX_CRIT_PTS)
506 flag_sync_active = 1;
507
508 //0.6.0pre5: frame dropping handled by transcode
509 flag_sync_active=1;
510
511 //unless this flag is on, the video sequence is dropped
512 //in TC_DEMUX_SEQ_FSYNC mode
513 }
514
515
516 // sync now, if requested:
517
518 if(!unit_seek) flag_has_audio=1; //unit has audio packets
519
520
521 // need to find the time difference of two audio packets
522 // for fine-tuning AV sync.
523
524 if(flag_av_fine_tune == 0) {
525 // get pts time stamp:
526 ac_memcpy(buf, &buffer[20], 16);
527 has_pts_dts=get_pts_dts(buf, &i_pts, &i_dts);
528
529 if(av_fine_pts1<0) {
530 av_fine_pts1 = (double)i_pts/90000.;
531 } else {
532 av_fine_pts2 = (double)i_pts/90000.;
533 flag_av_fine_tune=1;
534 }
535
536 //diff:
537 if(flag_av_fine_tune==1) {
538 av_fine_diff=av_fine_pts2-av_fine_pts1;
539 if(ipipe->verbose & TC_DEBUG)
540 tc_log_msg(__FILE__, "AV fine-tuning: %d ms",
541 (int)(av_fine_diff*1000));
542 }
543
544 //sanity check:
545 if(av_fine_diff<0) av_fine_diff=0.0f;
546
547 }
548
549 //Pre-processing: check if we need to re-sync?
550
551 if(demux_mode == TC_DEMUX_SEQ_FSYNC2 || demux_mode == TC_DEMUX_SEQ_ADJUST2) {
552 //new demux modes let transcode handle audio sync shift
553 flag_avsync=0;
554 flag_skip=0;
555 }
556
557 if(flag_avsync) {
558
559 // get pts time stamp:
560 ac_memcpy(buf, &buffer[20], 16);
561 has_pts_dts=get_pts_dts(buf, &i_pts, &i_dts);
562
563 if(has_pts_dts) {
564 pts=(double)i_pts/90000.;
565 } else {
566 //fallback to scr time stamp:
567 ac_memcpy(buf, &buffer[4], 6);
568 pts = read_time_stamp(buf);
569 }
570
571 pts_diff = pts - resync_pts;
572
573 //correction
574 //FIXME
575 pts_diff += av_fine_diff;
576
577 if(pts_diff<0) {
578 flag_skip=1;
579
580 if(ipipe->verbose & TC_DEBUG)
581 tc_log_msg(__FILE__, "(pid=%d) audio packet %06d for PU [%d] skipped (%.4f)",
582 getpid(), j, ((k==0)? 0:k-1), pts-resync_pts);
583 } else {
584 //reset
585 flag_skip=0;
586 flag_avsync=0;
587 if(ipipe->verbose)
588 tc_log_msg(__FILE__, "(pid=%d) AV sync established for PU [%d] at PTS=%.4f (%.4f)",
589 getpid(), k-1, pts, pts-resync_pts);
590 }
591 }
592
593 //Post-processing: more audio packets?
594
595 if(flag_append_audio) {
596
597 //need to flush a few audio packets, if video ahead
598
599 // get pts time stamp:
600 ac_memcpy(buf, &buffer[20], 16);
601 has_pts_dts=get_pts_dts(buf, &i_pts, &i_dts);
602
603 if(has_pts_dts) {
604 pts=(double)i_pts/90000.;
605 } else {
606 //fallback to scr time stamp:
607 ac_memcpy(buf, &buffer[4], 6);
608 pts = read_time_stamp(buf);
609 }
610
611 pts_diff = pts - resync_pts;
612
613 if(pts_diff<0) {
614
615 //append this packet
616 flag_skip=0;
617
618 if(ipipe->verbose & TC_DEBUG)
619 tc_log_msg(__FILE__, "(pid=%d) audio packet %06d for PU [%d] appended (%.4f)",
620 getpid(), j, ((k==0)? 0:k-1), pts-resync_pts);
621 } else {
622 //abort - all done
623 flag_eos=1;
624 if(ipipe->verbose)
625 tc_log_msg(__FILE__, "(pid=%d) AV sync abandoned for PU [%d] at PTS=%.4f (%.4f)",
626 getpid(), k-1, pts, pts-resync_pts);
627 }
628 }
629 }
630
631 //only go for audio in this phase
632 if(flag_append_audio) goto flush_packet;
633
634 /* ------------------------------------------------------------
635 *
636 * (V) misc payload
637 *
638 * ------------------------------------------------------------*/
639
640
641 if(id == P_ID_PROG || id == P_ID_PADD) {
642
643 payload_id=PACKAGE_NAV;
644
645 // get pts time stamp:
646 ac_memcpy(buf, &buffer[20], 16);
647 has_pts_dts=get_pts_dts(buf, &i_pts, &i_dts);
648
649 if(has_pts_dts) {
650 pts=(double)i_pts/90000.;
651 } else {
652 //fallback to scr time stamp:
653 ac_memcpy(buf, &buffer[4], 6);
654 pts = read_time_stamp(buf);
655 }
656
657 //do not dump this packet
658 flag_skip=1;
659 }
660
661 /* ------------------------------------------------------------
662 *
663 * (VI) video payload
664 *
665 * ------------------------------------------------------------*/
666
667
668 if(id == P_ID_MPEG) {
669
670 payload_id = PACKAGE_VIDEO;
671
672 // get pts time stamp:
673 ac_memcpy(buf, &buffer[4], 6);
674 pts = read_time_stamp(buf);
675
676 //read full packet header
677 ac_memcpy(buf, &buffer[20], 16);
678 has_pts_dts=get_pts_dts(buf, &i_pts, &i_dts);
679
680 //need frame/field encoding information
681 zz=scan_pack_ext(buffer);
682 if(zz>0) flag_field_encoded=zz;
683
684 //need precise number of pics in this sequence
685 pack_picture_ctr = scan_pack_pics(buffer);
686
687 seq_picture_ctr += pack_picture_ctr;
688
689 frame_based_lpts = (seq_picture_ctr-1);
690
691 //need this pack for subtitle PTS information
692 if(flag_rewrite_scr && has_pts_dts) flag_force=1;
693
694 // only process packets with pts/dts time stamp, since
695 // they (all?) have a sequence start code
696
697 if(has_pts_dts) {
698
699 if (ipipe->verbose & TC_STATS)
700 tc_log_msg(__FILE__, "(pid=%d) PTS-DTS detected in packet [%06d]",
701 getpid(), j);
702
703 // default first(=0) unit ?
704 if(k==0) {
705
706 --unit_seek;
707 flag_sync_reset=1;
708
709 if(ipipe->verbose & TC_DEBUG)
710 tc_log_msg(__FILE__, "(pid=%d) MPEG sequence start code in packet %06d for PU [0]",
711 getpid(), j);
712
713 k++;
714 }
715
716
717 if(pts<ref_pts) {
718
719 --unit_seek;
720 flag_sync_reset=1;
721
722 // past next unit - abort
723 // or process all following units?
724
725 if(unit_seek<0 && flag_loop_all==0) flag_eos=1;
726
727 //experimental: try to resync
728 //flag_avsync = 1;
729
730 if(ipipe->verbose & TC_DEBUG)
731 tc_log_msg(__FILE__, "(pid=%d) PTS reset (%.3f->%.3f) in packet %06d for PU [%d]",
732 getpid(), ref_pts, pts, j, k);
733
734 k++;
735 }
736
737
738 // only decrement sequence counter in right unit, i.e.
739 // unit_seek=0;
740 if(!unit_seek) --seq_seek;
741
742 // flush all sequences until the end of the unit
743 // or end of stream
744 // or resync_seq2 is reached
745
746 if(seq_seek==0) {
747
748 //re read packet header
749 ac_memcpy(buf, &buffer[20], 16);
750 get_pts_dts(buf, &i_pts, &i_dts);
751
752 resync_pts = (double) i_pts / 90000;
753
754 if(!flag_flush) {
755
756 // need to dump requested seq_dump sequences
757 seq_seek=seq_dump;
758 flag_flush = 1;
759
760 flag_avsync = 1;
761
762 // may be a useful info for the user
763 if(ipipe->verbose)
764 tc_log_msg(__FILE__, "(pid=%d) processing PU [%d], on at PTS=%.4f sec",
765 getpid(), k-1, resync_pts);
766
767 } else {
768 // finished, all sequences flushed, switch
769 // to audio packets post processing
770 flag_append_audio = 1;
771 flag_skip = 1; //flush mode on, but do not write this one
772
773 // may be a useful info for the user
774 if(ipipe->verbose)
775 tc_log_msg(__FILE__, "(pid=%d) processing PU [%d], off at PTS=%.4f sec",
776 getpid(), k-1, resync_pts);
777 }
778 }
779
780 //---------------------------------------------------
781 //gather information on the sequences before flushing
782 //---------------------------------------------------
783
784 if((demux_mode == TC_DEMUX_SEQ_FSYNC || demux_mode == TC_DEMUX_SEQ_FSYNC2) && flag_flush) {
785
786 ptr = seq_register(sequence_ctr);
787
788 zz=(flag_field_encoded==3)?(seq_picture_ctr-pack_picture_ctr):
789 (seq_picture_ctr-pack_picture_ctr)/2;
790
791 if(sequence_ctr) seq_update(ptr->prev, i_pts, zz, packet_ctr, flag_sync_active, hard_fps);
792
793 //init sequence information structure for current sequence
794
795 ptr->pts = i_pts;
796 ptr->dts = i_dts;
797 ptr->pics_first_packet = pack_picture_ctr;
798 ptr->sync_reset = flag_sync_reset;
799
800 //reset/update
801 seq_picture_ctr = 0;
802 packet_ctr = 0;
803 ++sequence_ctr;
804
805 //shift resync_pts, since sequence is dropped
806 if(flag_sync_active==0) resync_pts=(double) i_pts / 90000;
807
808 } //end TC_DEMUX_SEQ_FSYNC mode
809
810 //---------------------------------------------------
811 //print out sequence information for frame navigation
812 //---------------------------------------------------
813
814 if((demux_mode == TC_DEMUX_SEQ_LIST) && flag_flush) {
815
816 ptr = seq_register(sequence_ctr);
817
818 zz=(flag_field_encoded==3)?(seq_picture_ctr-pack_picture_ctr):
819 (seq_picture_ctr-pack_picture_ctr)/2;
820
821 if(sequence_ctr) seq_list(ptr->prev, i_pts, zz, packet_ctr, flag_sync_active);
822
823 //init sequence information structure for current sequence
824
825 ptr->pts = i_pts;
826 ptr->dts = i_dts;
827 ptr->pics_first_packet = pack_picture_ctr;
828 ptr->sync_reset = flag_sync_reset;
829 ptr->packet_ctr=j;
830
831 //reset/update
832 seq_picture_ctr = 0;
833 packet_ctr = 0;
834 ++sequence_ctr;
835
836 //shift resync_pts, since sequence is dropped
837 if(flag_sync_active==0) resync_pts=(double) i_pts / 90000;
838
839 } //end TC_DEMUX_SEQ_LIST mode
840
841 //reset sync pts, if no audio/substream has been found (0.6.0pre4)
842 if(flag_sync_active==0 && demux_audio) {
843 resync_pts=(double) i_pts / 90000;
844 if(ipipe->verbose & TC_DEBUG)
845 tc_log_msg(__FILE__, "new initial PTS=%f", resync_pts);
846 }
847
848 }// PTS-DTS flag yes
849
850 ref_pts=pts;
851
852 }// MPEG video packet
853
854 /* ------------------------------------------------------------
855 *
856 * (VII) evaluate scan results - flush packet
857 *
858 * ------------------------------------------------------------*/
859
860 flush_packet:
861
862
863 if(ipipe->verbose & TC_STATS)
864 tc_log_msg(__FILE__, "INFO: j=%05d, i=%05d, skip=%d, flush=%d, force=%d, pay=%3d, sid=0x%02x, eos=%d",
865 j, i, flag_skip, flag_flush, flag_force, payload_id, id, flag_eos);
866
867 //need to rewrite SCR pack header entry based on
868 //frame_based_pts information for transcode:
869 if(flag_rewrite_scr) scr_rewrite(&buffer[4], ((flag_field_encoded==3)?frame_based_lpts:frame_based_lpts/2));
870
871 //flush here:
872
873 switch(demux_mode) {
874
875 case TC_DEMUX_DEBUG:
876 if((flag_flush && !flag_skip && (payload_id & select))
877 || flag_force) scan_pack_payload(buffer, packet_size, j, ipipe->verbose);
878 break;
879
880 case TC_DEMUX_DEBUG_ALL:
881 scan_pack_payload(buffer, packet_size, j, ipipe->verbose);
882 break;
883
884 case TC_DEMUX_SEQ_FSYNC:
885 case TC_DEMUX_SEQ_FSYNC2:
886
887 if((flag_flush && !flag_skip && (payload_id & select)) || flag_force) {
888
889 //count current sequence packets to be flushed
890 ++packet_ctr;
891
892 if(ipipe->verbose & TC_STATS)
893 tc_log_msg(__FILE__, "flushing packet (%d/%d)", sequence_ctr, j);
894
895 if(flush_buffer_write(ipipe->fd_out, buffer, packet_size) != packet_size) {
896 tc_log_perror(__FILE__, "write program stream packet");
897 exit(1);
898 }
899
900 //reset
901 flag_force=0;
902 }
903
904 break;
905
906 case TC_DEMUX_SEQ_ADJUST:
907 case TC_DEMUX_SEQ_ADJUST2:
908
909 if((flag_flush && !flag_skip && (payload_id & select)) || flag_force) {
910
911 if(tc_pwrite(ipipe->fd_out, buffer, packet_size) != packet_size) {
912 tc_log_perror(__FILE__, "write program stream packet");
913 exit(1);
914 }
915
916 //reset
917 flag_force=0;
918
919 if(ipipe->verbose & TC_STATS)
920 tc_log_msg(__FILE__, "writing packet %d", j);
921
922 } else {
923
924 ++i;
925 if(ipipe->verbose & TC_STATS)
926 tc_log_msg(__FILE__, "skipping packet %d", j);
927 }
928
929 break;
930
931
932 case TC_DEMUX_SEQ_LIST:
933
934 //count packs
935 ++packet_ctr;
936
937 // nothing to do
938 break;
939
940 case TC_DEMUX_OFF:
941
942 if(tc_pwrite(ipipe->fd_out, buffer, packet_size) != packet_size) {
943 tc_log_perror(__FILE__, "write program stream packet");
944 exit(1);
945 }
946
947 if(ipipe->verbose & TC_STATS)
948 tc_log_msg(__FILE__, "writing packet %d", j);
949
950 break;
951 }
952
953 //aborting?
954 if(flag_eos) break;
955
956 //total packs (2k each) counter
957 ++j;
958
959 } // process next packet/block
960
961 if(ipipe->verbose & TC_SYNC)
962 tc_log_msg(__FILE__, "EOS - flushing packet buffer");
963
964 //post processing
965
966 if(demux_mode == TC_DEMUX_SEQ_FSYNC || demux_mode == TC_DEMUX_SEQ_FSYNC2) {
967 seq_close();
968 flush_buffer_close();
969 }
970
971 if(demux_mode == TC_DEMUX_SEQ_LIST) {
972
973 ptr = seq_register(sequence_ctr);
974
975 zz=(flag_field_encoded==3)?(seq_picture_ctr-pack_picture_ctr):
976 (seq_picture_ctr-pack_picture_ctr)/2;
977
978 if(ptr!=NULL && ptr->id) seq_list(ptr->prev, ref_pts, zz, packet_ctr, flag_sync_active);
979
980 fflush(stdout);
981
982 //summary
983 seq_list_frames();
984
985 seq_close();
986 flush_buffer_close();
987
988 }
989
990 //summary
991 if(ipipe->verbose & TC_DEBUG)
992 tc_log_msg(__FILE__, "(pid=%d) %d/%d packets discarded", getpid(), i, j);
993
994 if(buffer!=NULL) free(buffer);
995
996 return;
997 }
998
999