3 #define ABS(x) ((x) >= 0 ? (x) : -(x))
9 dmp(unsigned char *bp,int l)
12 unsigned char ch[rowsz];
16 printf(" %04x -",fad);
17 for( i=0; i<rowsz && l>=0; ++i ) {
20 ch[i] = c>=' ' && c<='~' ? c : ' ';
23 for( n=i; i<rowsz; ++i ) printf(" ");
25 for( i=0; i<n; ++i ) printf("%c", ch[i]);
26 printf("\n"); fad += n;
32 get_adaptation_field()
34 //zmsgs("get_adaptation_field %d\n", adaptation_field_control);
36 /* get adaptation field length */
37 int length = packet_read_char();
38 int avail = raw_size - raw_offset;
39 if( length > avail ) length = avail;
41 int flags = packet_read_char();
42 if( ((flags >> 7) & 1) != 0 )
44 int pcr_flag = (flags >> 4) & 1;
46 uint32_t clk_ref_base = packet_read_int32();
47 uint32_t clk_ref_ext = packet_read_int16();
48 if (clk_ref_base > 0x7fffffff ) { /* correct for invalid numbers */
49 clk_ref_base = 0; /* ie. longer than 32 bits when multiplied by 2 */
50 clk_ref_ext = 0; /* multiplied by 2 corresponds to shift left 1 (<<=1) */
52 else { /* Create space for bit */
54 clk_ref_base |= (clk_ref_ext >> 15); /* Take bit */
55 clk_ref_ext &= 0x01ff; /* Only lower 9 bits */
57 time = ((double)clk_ref_base + clk_ref_ext / 300) / 90000;
59 packet_skip(length-7);
60 if( dump ) zmsgs(" pcr_flag=%x time=%f\n", pcr_flag, time);
63 packet_skip(length-1);
69 get_program_association_table()
71 ++program_association_tables;
72 table_id = packet_read_char();
73 section_length = packet_read_int16() & 0xfff;
74 transport_stream_id = packet_read_int16();
75 packet_skip(raw_size - raw_offset);
77 zmsgs("table_id=0x%x section_length=%d transport_stream_id=0x%x\n",
78 table_id, section_length, transport_stream_id);
84 get_transport_payload(int is_audio, int is_video)
86 int bytes = raw_size - raw_offset;
88 // zerr("got negative payload size!\n");
91 /* if( zdata.size + bytes > RAW_SIZE )
92 bytes = RAW_SIZE - zdata.size; */
93 //zmsgs("2 %d %d %d\n", bytes, read_all, is_audio);
95 if( read_all && is_audio ) {
96 // if( pid == 0x1100 )
97 // zmsgs("1 0x%x %d\n", audio_pid, bytes);
98 memcpy(zaudio.buffer+zaudio.size, raw_data+raw_offset, bytes);
101 else if( read_all && is_video ) {
102 //zmsgs("2 0x%x %d\n", video_pid, bytes);
103 memcpy(zvideo.buffer+zvideo.size, raw_data+raw_offset, bytes);
104 zvideo.size += bytes;
107 memcpy(zdata.buffer+zdata.size, raw_data+raw_offset, bytes);
109 //zmsgs("10 pid=0x%x bytes=0x%x zdata.size=0x%x\n", pid, bytes, zdata.size);
116 get_pes_packet_header(uint64_t *pts, uint64_t *dts)
118 uint32_t pes_header_bytes = 0;
120 /* drop first 8 bits */
122 uint32_t pts_dts_flags = (packet_read_char() >> 6) & 0x3;
123 int pes_header_data_length = packet_read_char();
125 /* Get Presentation Time stamps and Decoding Time Stamps */
126 if( pts_dts_flags & 2 ) {
127 uint64_t tpts = (packet_read_char() >> 1) & 7; /* Only low 4 bits (7==1111) */
129 tpts |= (packet_read_int16() >> 1);
131 tpts |= (packet_read_int16() >> 1);
133 if( pts_dts_flags & 1 ) {
134 uint64_t tdts = (packet_read_char() >> 1) & 7; /* Only low 4 bits (7==1111) */
136 tdts |= (packet_read_int16() >> 1);
138 tdts |= (packet_read_int16() >> 1);
140 pes_header_bytes = 10;
143 pes_header_bytes = 5;
145 /* extract other stuff here! */
146 packet_skip(pes_header_data_length-pes_header_bytes);
147 time = (double)*pts / 90000;
149 zmsgs("pos=0x%012jx pid=%04x pts=%f dts=%f pts_dts_flags=0x%02x\n",
150 absolute_position(), pid, (double)*pts / 90000, (double)*dts / 90000, pts_dts_flags);
158 int bytes = raw_size - raw_offset;
159 memcpy(zdata.buffer+zdata.size, raw_data+raw_offset, bytes);
166 get_transport_pes_packet()
168 uint64_t pts = 0, dts = 0;
169 get_pes_packet_header(&pts, &dts);
170 //zmsgs("get_transport_pes_packet: stream_id=%x\n", stream_id);
171 /* check ac3 audio (0xbd) or Blu-Ray audio (0xfd) */
172 if( stream_id == 0xbd || stream_id == 0xfd ) {
173 //zmsgs("get_transport_pes_packet %x\n", pid);
176 custom_id = got_audio = pid;
178 if( read_all ) astream_table[custom_id] = afmt_AC3;
179 if( astream == -1 ) astream = custom_id;
181 zmsgs("offset=0x%jx 0x%x bytes AC3 custom_id=0x%x astream=0x%x do_audio=%p\n",
182 absolute_position(), raw_size - raw_offset,
183 custom_id, astream, do_audio);
185 if( (custom_id == astream && do_audio) || read_all ) {
187 set_audio_pts(pts, 90000.);
188 return get_transport_payload(1, 0);
191 else if( (stream_id >> 4) == 0x0c || (stream_id >> 4) == 0x0d ) {
193 custom_id = got_audio = pid;
194 /* Just pick the first available stream if no ID is set */
195 if( read_all ) astream_table[custom_id] = afmt_MPEG;
196 if( astream == -1 ) astream = custom_id;
197 if( dump ) zmsgs(" 0x%x bytes MP2 audio\n", raw_size-raw_offset);
198 if( (custom_id == astream && do_audio) || read_all ) {
200 set_audio_pts(pts, 90000.);
201 return get_transport_payload(1, 0);
204 else if( (stream_id >> 4) == 0x0e ) {
206 custom_id = got_video = pid;
208 /* Just pick the first available stream if no ID is set */
210 vstream_table[custom_id] = 1;
211 else if( vstream == -1 )
213 if( dump ) zmsgs(" 0x%x bytes video data\n", raw_size - raw_offset);
214 if( (custom_id == vstream && do_video) || read_all ) {
216 set_video_pts(pts, 90000.);
217 return get_transport_payload(0, 1);
220 packet_skip(raw_size - raw_offset);
230 stream_id = packet_read_char();
231 if( dump ) zmsgs(" stream_id=0x%02x\n", stream_id);
233 /* Skip pes packet length */
236 if( (stream_id >= 0xc0 && stream_id < 0xf0) ||
237 stream_id == 0x0bd || stream_id == 0x0fd )
238 return get_transport_pes_packet();
240 switch( stream_id ) {
241 case PRIVATE_STREAM_2:
242 zmsg("stream_id == PRIVATE_STREAM_2\n");
244 packet_skip(raw_size-raw_offset);
249 zmsgs("unknown stream_id (0x%02x) in pes packet\n", stream_id);
250 packet_skip(raw_size-raw_offset);
257 //zmsgs("get_payload 1 pid=0x%x unit_start=%d\n", pid, payload_unit_start_indicator);
258 if( payload_unit_start_indicator ) {
260 get_program_association_table();
262 else if( read_all && src->dvb.atsc_pid(pid) )
263 get_transport_payload(0, 0);
265 else if( packet_next_int24() == PACKET_START_CODE_PREFIX )
268 packet_skip(raw_size-raw_offset);
271 if( dump ) zmsgs(" 0x%x bytes elementary data\n", raw_size-raw_offset);
272 // if( pid == 0x1100 ) zmsgs("get_payload 1 0x%x\n", audio_pid);
273 if( pid == audio_pid && (do_audio || read_all) ) {
274 if( do_audio ) got_audio = audio_pid;
276 zmsgs(" offset=0x%jx 0x%x bytes AC3 pid=0x%x\n",
277 absolute_position(), raw_size-raw_offset, pid);
279 get_transport_payload(1, 0);
281 else if( pid == video_pid && (do_video || read_all) ) {
282 if( do_video ) got_video = video_pid;
283 get_transport_payload(0, 1);
287 get_transport_payload(0, 0);
289 /* packet_skip(raw_size-raw_offset); */
295 /* Read a transport packet */
301 title_t *title = titles[current_title];
304 /* Packet size is known for transport streams */
305 raw_size = src->packet_size;
312 //zerrs("read transport 1 %jx %jx\n", title->fs->current_byte, title->fs->total_bytes);
314 /* Skip BD or AVC-HD header */
316 title->fs->read_uint32();
318 /* Search for Sync byte */
319 for( int i=0x10000; --i>=0 && !title->fs->eof(); ) {
320 if( (bits=title->fs->read_char()) == SYNC_BYTE ) break;
323 program_byte = absolute_position();
324 /* Store byte just read as first byte */
325 if( !title->fs->eof() && bits == SYNC_BYTE ) {
326 last_packet_start = program_byte-1;
327 raw_data[0] = SYNC_BYTE;
329 int fragment_size = src->packet_size - 1;
335 title->fs->read_data(raw_data+1, fragment_size);
344 bits = packet_read_int24() & 0x00ffffff;
345 transport_error_indicator = (bits >> 23) & 0x1;
346 payload_unit_start_indicator = (bits >> 22) & 0x1;
347 pid = custom_id = (bits >> 8) & 0x00001fff;
349 transport_scrambling_control = (bits >> 6) & 0x3;
350 adaptation_field_control = (bits >> 4) & 0x3;
351 continuity_counter = bits & 0xf;
353 is_padding = pid == 0x1fff ? 1 : 0;
355 zmsgs("offset=0x%jx pid=0x%02x continuity=0x%02x padding=%d adaptation=%d unit_start=%d\n",
356 last_packet_start, pid, continuity_counter, is_padding,
357 adaptation_field_control, payload_unit_start_indicator);
360 /* Abort if padding. Should abort after pid == 0x1fff for speed. */
361 if( is_padding || transport_error_indicator || (!read_all && (
362 (do_video && do_video->pid != pid) ||
363 (do_audio && do_audio->pid != pid))) ) {
364 program_byte = absolute_position();
368 /* Get pid from table */
370 for( table_entry=0; table_entry<total_pids; ++table_entry ) {
371 if( pid == pid_table[table_entry] ) {
377 /* Not in pid table */
378 if( !result && total_pids<PIDMAX ) {
379 pid_table[table_entry] = pid;
380 continuity_counters[table_entry] = continuity_counter; /* init */
385 if( adaptation_field_control & 0x2 )
386 result = get_adaptation_field();
388 /* Need to enter in astream and vstream table: */
389 /* PID ored with stream_id */
390 if( adaptation_field_control & 0x1 )
391 result = get_payload();
393 program_byte = absolute_position();
400 title_t *title = titles[current_title];
401 int length = title->fs->read_uint16();
402 title->fs->seek_relative(length);
406 uint64_t zdemuxer_t::
410 title_t *title = titles[current_title];
411 /* Only low 4 bits (7==1111) */
412 timestamp = (title->fs->read_char() >> 1) & 7;
414 timestamp |= (title->fs->read_uint16() >> 1);
416 timestamp |= (title->fs->read_uint16() >> 1);
424 uint32_t clock_ref, clock_ref_ext;
425 title_t *title = titles[current_title];
427 /* Get the time code */
428 if( (title->fs->next_char() >> 4) == 2 ) {
429 time = (double)get_timestamp() / 90000; /* MPEG-1 */
430 title->fs->read_uint24(); /* Skip 3 bytes */
432 else if( (title->fs->next_char() & 0x40) ) {
433 i = title->fs->read_uint32();
434 j = title->fs->read_uint16();
435 if( (i & 0x40000000) || (i >> 28) == 2 ) {
436 clock_ref = ((i & 0x38000000) << 3);
437 clock_ref |= ((i & 0x03fff800) << 4);
438 clock_ref |= ((i & 0x000003ff) << 5);
439 clock_ref |= ((j & 0xf800) >> 11);
440 clock_ref_ext = (j >> 1) & 0x1ff;
441 time = (double)(clock_ref + clock_ref_ext / 300) / 90000;
443 title->fs->read_uint24();
444 i = title->fs->read_char() & 0x7;
446 title->fs->seek_relative(i);
450 title->fs->seek_relative(2);
456 get_program_payload(int bytes, int is_audio, int is_video)
458 title_t *title = titles[current_title];
460 if( read_all && is_audio ) {
461 if( (n=zaudio.allocated-zaudio.size) > bytes ) n = bytes;
462 title->fs->read_data(zaudio.buffer+zaudio.size, n);
465 else if( read_all && is_video ) {
466 if( (n=zvideo.allocated-zvideo.size) > bytes ) n = bytes;
467 title->fs->read_data(zvideo.buffer+zvideo.size, n);
471 if( (n=zdata.allocated-zdata.size) > bytes ) n = bytes;
472 title->fs->read_data(zdata.buffer+zdata.size, n);
476 title->fs->seek_relative(bytes - n);
481 handle_scrambling(int decryption_offset)
483 title_t *title = titles[current_title];
484 /* Advance 2048 bytes if scrambled. We might pick up a spurrius */
485 /* packet start code in the scrambled data otherwise. */
486 int64_t next_packet_position = last_packet_start + DVD_PACKET_SIZE;
487 if( next_packet_position > absolute_position() ) {
488 title->fs->seek_relative(next_packet_position-absolute_position());
490 /* Descramble if desired. */
491 if( zdata.size || zaudio.size || zvideo.size ) {
492 uint8_t *buffer_ptr = 0;
493 if( zdata.size ) buffer_ptr = zdata.buffer;
494 else if( zaudio.size ) buffer_ptr = zaudio.buffer;
495 else if( zvideo.size ) buffer_ptr = zvideo.buffer;
496 //zmsgs(" zdata.size=%x decryption_offset=%x\n",
497 // zdata.size, decryption_offset);
498 if( title->fs->css.decrypt_packet(buffer_ptr, decryption_offset)) {
499 zerr("handle_scrambling: Decryption not available\n");
507 del_subtitle(int idx)
509 delete subtitles[idx];
510 for( int i=idx; ++i<total_subtitles; )
511 subtitles[i-1] = subtitles[i];
515 /* Create new subtitle object if none with the same id is in the table */
516 zsubtitle_t* zdemuxer_t::
517 get_subtitle(int id, int64_t offset)
519 //zmsgs(" id=0x%04x ofs=%012lx\n", id, offset);
520 subtitle_t *subtitle = 0, *reuse = 0;
521 /* Get current/reuse subtitle object for the stream */
522 /* delete extra expired subtitles */
524 while( i < total_subtitles ) {
525 subtitle_t *sp = subtitles[i];
527 if( reuse ) { del_subtitle(i); continue; }
530 else if( !subtitle && !sp->done && sp->id == id )
534 /* found current unfinished subtitle */
535 if( subtitle ) return subtitle;
536 /* Make new/reused subtitle object */
539 subtitle->data_used = 0;
542 subtitle->active = 0;
544 subtitle->frame_time = 0;
546 else if( total_subtitles < MAX_SUBTITLES ) {
547 subtitle = new subtitle_t();
548 subtitles[total_subtitles++] = subtitle;
553 subtitle->offset = offset;
560 uint8_t *new_data = new uint8_t[n];
561 memcpy(new_data,data,data_used);
562 delete [] data; data = new_data;
567 handle_subtitle(zmpeg3_t *src, int stream_id, int bytes)
569 int pos = zdata.position;
570 int size = zdata.size - zdata.position;
571 zdata.size = zdata.position = 0;
572 if( size < bytes ) bytes = size;
573 subtitle_t *subtitle = get_subtitle(stream_id, program_byte);
574 if( !subtitle ) return;
575 size = subtitle->data_used + bytes;
576 if( subtitle->data_allocated < size ) subtitle->realloc_data(size);
577 memcpy(subtitle->data+subtitle->data_used,zdata.buffer+pos,bytes);
578 subtitle->data_used += bytes;
579 if( subtitle->data_used >= 2 ) {
580 uint8_t *bfr = subtitle->data;
581 size = (bfr[0]<<8) + bfr[1];
582 if( subtitle->data_used >= size ) {
583 zvideo_t *vid = do_video ? do_video->video : 0;
584 strack_t *strack = src->create_strack(subtitle->id, vid);
585 if( strack->append_subtitle(subtitle) )
594 handle_pcm(int bytes)
596 /* Synthesize PCM header and delete MPEG header for PCM data */
597 /* Must be done after decryption */
604 uint8_t *data_buffer = 0;
609 if( read_all && zaudio.size ) {
610 output = zaudio.buffer + zaudio.start;
611 data_buffer = zaudio.buffer;
612 data_start = zaudio.start;
613 data_size = &zaudio.size;
616 output = zdata.buffer + zdata.start;
617 data_buffer = zdata.buffer;
618 data_start = zdata.start;
619 data_size = &zdata.size;
622 /* Shift audio back */
624 j = *data_size+zaudio_t::PCM_HEADERSIZE-3-1;
625 for( i=*data_size-1; i>=data_start; --i,--j )
626 *(data_buffer+j) = *(data_buffer+i);
627 *data_size += zaudio_t::PCM_HEADERSIZE - 3;
629 bits_code = (zcode >> 6) & 3;
630 samplerate_code = (zcode >>4) & 1;
637 switch( samplerate_code ) {
638 case 1: samplerate = 96000; break;
639 default: samplerate = 48000; break;
641 *(int32_t*)(output + 4) = samplerate;
643 switch( bits_code ) {
644 case 0: bits = 16; break;
645 case 1: bits = 20; break;
646 case 2: bits = 24; break;
647 default: bits = 16; break;
649 *(int32_t*)(output+ 8) = bits;
650 *(int32_t*)(output+12) = (zcode & 0x7) + 1; /* Channels */
651 *(int32_t*)(output+16) = bytes - 3 +
652 zaudio_t::PCM_HEADERSIZE; /* Framesize */
653 //zmsgs(" %d %d %d\n", *(int32_t*)(output+ 8),
654 // *(int32_t*)(output+12), *(int32_t*)(output+16));
658 /* Program packet reading core */
660 get_program_pes_packet( uint32_t header)
662 uint64_t pts = 0, dts = 0;
663 int pes_packet_length;
664 int64_t pes_packet_start, pes_packet_end;
665 int decryption_offset = 0;
666 title_t *title = titles[current_title];
671 zdata.start = zdata.size;
672 zaudio.start = zaudio.size;
673 zvideo.start = zvideo.size;
675 stream_id = header & 0xff;
676 pes_packet_length = title->fs->read_uint16();
677 pes_packet_start = absolute_position();
678 pes_packet_end = pes_packet_start + pes_packet_length;
679 //zmsgs(" pes_packet_start=0x%jx pes_packet_length=%x zdata.size=%x\n",
680 // pes_packet_start, pes_packet_length, zdata.size);
682 if( stream_id != PRIVATE_STREAM_2 && stream_id != PADDING_STREAM ) {
683 if( (title->fs->next_char() >> 6) == 0x02 ) {
684 /* Get MPEG-2 packet */
685 int pes_header_bytes = 0;
687 int pes_header_data_length;
688 last_packet_decryption = absolute_position();
689 scrambling = title->fs->read_char() & 0x30;
690 /* scrambling = 1; */
691 /* Reset scrambling bit for the mpeg3cat utility */
692 /* if( scrambling ) raw_data[raw_offset - 1] &= 0xcf; */
693 /* Force packet length if scrambling */
695 pes_packet_length = DVD_PACKET_SIZE - pes_packet_start + last_packet_start;
696 pts_dts_flags = (title->fs->read_char() >> 6) & 0x3;
697 pes_header_data_length = title->fs->read_char();
699 /* Get Presentation and Decoding Time Stamps */
700 if( pts_dts_flags == 2 ) {
701 pts = get_timestamp();
702 if( dump ) zmsgs("pts=0x%jx\n", pts);
703 pes_header_bytes += 5;
705 else if( pts_dts_flags == 3 ) {
706 pts = get_timestamp();
707 dts = get_timestamp();
708 if( dump ) zmsgs("pts=%jd dts=%jd\n", pts, dts);
709 /* pts = (title->fs->read_char() >> 1) & 7;
711 * pts |= (title->fs->read_uint16() >> 1);
713 * pts |= (title->fs->read_uint16() >> 1);
714 * dts = (title->fs->read_char() >> 1) & 7;
716 * dts |= (title->fs->read_uint16() >> 1);
718 * dts |= (title->fs->read_uint16() >> 1);
720 pes_header_bytes += 10;
722 //zmsgs("get_program_pes_packet do_audio=%p do_video=%p pts=%x dts=%x\n",
723 // do_audio, do_video, pts, dts);
725 title->fs->seek_relative(pes_header_data_length-pes_header_bytes);
729 /* Get MPEG-1 packet */
730 while( !title->fs->eof() && title->fs->next_char() == 0xff ) {
731 title->fs->read_char();
733 /* Skip STD buffer scale */
734 if( (title->fs->next_char() & 0x40) ) {
735 title->fs->seek_relative(2);
737 /* Decide which timestamps are available */
738 pts_dts_flags = title->fs->next_char();
739 if( pts_dts_flags >= 0x30 ) {
740 /* Get the presentation and decoding time stamp */
741 pts = get_timestamp();
742 dts = get_timestamp();
744 else if( pts_dts_flags >= 0x20 ) {
745 /* Get just the presentation time stamp */
746 pts = get_timestamp();
748 else if( pts_dts_flags == 0x0f ) {
749 /* End of timestamps */
750 title->fs->read_char();
753 return 1; /* Error */
756 /* Now extract the payload. */
757 if( (stream_id >> 4) == 0xc || (stream_id >> 4) == 0xd ) {
759 /* Take first stream ID if -1 */
760 pes_packet_length -= absolute_position() - pes_packet_start;
761 custom_id = got_audio = stream_id & 0x0f;
763 astream_table[custom_id] = afmt_MPEG;
764 else if( astream == -1 )
766 if( (custom_id == astream && do_audio) || read_all ) {
767 set_audio_pts(pts, 90000.); //60000
768 decryption_offset = absolute_position() - last_packet_start;
770 zmsgs(" MP2 audio data offset=0x%jx custom_id=%x size=%x\n",
771 program_byte, custom_id, pes_packet_length);
773 get_program_payload(pes_packet_length, 1, 0);
776 if( dump ) zmsgs(" skipping audio size=%x\n", pes_packet_length);
779 else if( (stream_id >> 4) == 0xe ) {
781 /* Take first stream ID if -1 */
782 pes_packet_length -= absolute_position() - pes_packet_start;
783 custom_id = got_video = stream_id & 0x0f;
785 vstream_table[custom_id] = 1;
786 } else if( vstream == -1 )
788 if( (custom_id == vstream && do_video) || read_all ) {
789 set_video_pts(pts, 90000.); //60000
790 decryption_offset = absolute_position() - last_packet_start;
792 zmsgs(" video offset=0x%jx custom_id=%x size=%x\n",
793 program_byte, custom_id, pes_packet_length);
795 get_program_payload(pes_packet_length, 0, 1);
798 if( dump ) zmsgs(" skipping video size=%x\n", pes_packet_length);
801 else if( (stream_id == 0xbd || stream_id == 0xbf) &&
802 ((title->fs->next_char() & 0xf0) == 0x20) ) {
803 /* DVD subtitle data */
804 stream_id = title->fs->read_char();
805 custom_id = stream_id & 0x0f;
807 if( !sstream_table[custom_id] ) {
808 sstream_table[custom_id] = 1;
809 src->strack[src->total_stracks] = new strack_t(custom_id);
810 if( src->strack[src->total_stracks] ) ++src->total_stracks;
813 /* Get data length */
814 pes_packet_length -= absolute_position() - pes_packet_start;
816 decryption_offset = absolute_position() - last_packet_start;
817 get_program_payload(pes_packet_length, 0, 0);
821 if( dump ) zmsgs(" skipping subtitle size=%x\n", pes_packet_length);
823 //zmsgs("id=0x%02x size=%d\n", stream_id, pes_packet_length);
825 else if( (stream_id == 0xbd || stream_id == 0xbf) &&
826 title->fs->next_char() != 0xff &&
827 ((title->fs->next_char() & 0xf0) == 0x80 ||
828 (title->fs->next_char() & 0xf0) == 0xa0) ) {
830 /* Get the audio format */
831 int format = (title->fs->next_char() & 0xf0) == 0xa0 ?
833 /* Picks up bogus data if (& 0xf) or (& 0x7f) */
834 stream_id = title->fs->next_char();
835 /* only 8 streams, counting from 0x80 */
836 custom_id = stream_id & 0x87;
837 if( astream_table[custom_id] >= 0 ) {
838 got_audio = custom_id;
839 /* Take first stream ID if not building TOC. */
841 astream_table[custom_id] = format;
842 else if( astream == -1 )
844 if( (custom_id == astream && do_audio) || read_all ) {
845 set_audio_pts(pts, 90000.); //60000
847 title->fs->read_uint32();
848 pes_packet_length -= absolute_position() - pes_packet_start;
849 decryption_offset = absolute_position() - last_packet_start;
850 if( format == afmt_PCM )
852 //zmsgs("get_program_pes_packet 5 %x\n", decryption_offset);
853 if( dump ) zmsgs(" AC3 audio offset=0x%jx, custom_id=%03x, size=%x\n",
854 program_byte, custom_id, pes_packet_length);
855 get_program_payload(pes_packet_length, 1, 0);
860 else if( stream_id == PRIVATE_STREAM_2 || stream_id == PADDING_STREAM ) {
861 pes_packet_length -= absolute_position() - pes_packet_start;
862 if( stream_id == NAV_PACKET_STREAM /* == PRIVATE_STREAM_2 */ ) {
863 if( !nav ) nav = new nav_t();
864 int sub_stream = title->fs->read_char();
866 switch( sub_stream ) {
868 if( pes_packet_length >= NAV_PCI_BYTES ) {
869 title->fs->read_data(&nav->pci[0],NAV_PCI_BYTES);
870 //zmsgs("nav_pci: %lu + %lu\n",absolute_position()/2048,absolute_position()%2048);
871 //dmp(&nav->pci[0],NAV_PCI_BYTES);
872 pes_packet_length -= NAV_PCI_BYTES;
876 if( pes_packet_length >= NAV_DSI_BYTES ) {
877 title->fs->read_data(&nav->dsi[0],NAV_DSI_BYTES);
878 //zmsgs("nav_dsi: %lu + %lu\n",absolute_position()/2048,absolute_position()%2048);
879 //dmp(&nav->dsi[0],NAV_DSI_BYTES);
880 pes_packet_length -= NAV_DSI_BYTES;
881 int64_t blk_pos = ((int64_t)nav->dsi_gi_pck_lbn() & 0x7fffffffU) * DVD_PACKET_SIZE;
882 if( blk_pos != 0 && last_packet_start != blk_pos )
883 zmsgs("blk_pos 0x%jx != 0x%jx last_packet_start\n", blk_pos, last_packet_start);
884 int64_t next_pos, next_vobu, end_byte, end_pos;
885 int64_t blk_size = (int64_t)nav->dsi_gi_vobu_ea() * DVD_PACKET_SIZE;
886 nav_cell_end_byte = program_byte + blk_size + DVD_PACKET_SIZE;
887 end_pos = program_to_absolute(nav_cell_end_byte, &end_byte);
888 if( end_byte != nav_cell_end_byte )
889 zmsgs("end_byte 0x%jx != 0x%jx nav_cell_end_byte\n", end_byte, nav_cell_end_byte);
890 uint32_t next_vobu_offset = nav->dsi_si_next_vobu();
891 if( next_vobu_offset == NAV_SRI_END_OF_CELL ) {
892 next_vobu = playinfo_next_cell();
893 next_pos = next_vobu >= 0 ? program_to_absolute(next_vobu) : -1;
896 next_pos = blk_pos + ((int64_t)next_vobu_offset & 0x7fffffffU) * DVD_PACKET_SIZE;
897 next_vobu = absolute_to_program(next_pos);
899 if( next_vobu > 0 && end_pos != next_pos ) {
900 nav_cell_next_vobu = next_vobu;
901 zmsgs("blk end_pos 0x%jx != 0x%jx next_pos, jump to 0x%jx\n",
902 end_pos, next_pos, nav_cell_next_vobu);
905 nav_cell_end_byte = nav_cell_next_vobu = -1;
906 if( nav_cell_end_byte >= 0 )
907 zmsgs("nav pkt at 0x%jx ends 0x%jx next_vobu 0x%jx/0x%jx\n",
908 program_byte, nav_cell_end_byte, nav_cell_next_vobu, next_pos);
915 int64_t len = pes_packet_end - absolute_position();
917 title->fs->seek_relative(len);
920 handle_scrambling(decryption_offset);
922 handle_pcm(pes_packet_length);
923 else if( do_subtitle )
924 handle_subtitle(src, custom_id, pes_packet_length);
933 title_t *title = titles[current_title];
944 if( title->fs->eof() ) return 1;
945 last_packet_start = absolute_position();
946 program_byte = absolute_to_program(last_packet_start);
948 /* Search for next header */
949 /* Parse packet until the next packet start code */
951 title = titles[current_title];
953 zmsgs("%d %d 0x%jx 0x%jx\n",
954 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
955 if( title->fs->eof() ) break;
956 pos = absolute_position();
957 header = title->fs->read_uint32();
958 if( header == PACK_START_CODE ) {
960 zmsgs("%d %d 0x%jx 0x%jx\n",
961 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
962 /* Second start code in this call. Don't read it. */
964 title->fs->seek_relative(-4);
967 last_packet_start = pos;
968 result = get_pack_header();
971 zmsgs("%d %d 0x%jx 0x%jx\n",
972 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
974 else if( header == SYSTEM_START_CODE && pack_count ) {
976 zmsgs("%d %d 0x%jx 0x%jx\n",
977 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
978 result = get_system_header();
980 zmsgs("%d %d 0x%jx 0x%jx\n",
981 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
983 else if( header == PROGRAM_END_CODE ) {
984 title->fs->total_bytes = title->fs->current_byte;
985 stream_end = program_byte;
987 else if( (header >> 8) == PACKET_START_CODE_PREFIX && pack_count ) {
989 zmsgs("%d %d 0x%jx 0x%jx\n",
990 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
991 result = get_program_pes_packet(header);
993 zmsgs("%d %d 0x%jx 0x%jx\n",
994 __LINE__, result, title->fs->current_byte, title->fs->total_bytes);
997 /* if whamming on bad blocks, if possible skip to the next cell and continue */
998 int errs = title->fs->errors();
1000 if( total_titles > 1 || title->cell_table_size > 1 ) {
1001 zmsgs("%d device errs, truncating cell %d\n", errs, current_cell_no());
1002 program_byte = absolute_to_program(last_packet_start);
1003 src->demuxer->titles[current_title]->cell_table[title_cell].program_end =
1004 title->cell_table[title_cell].program_end = program_byte;
1005 nav_cell_end_byte = 0;
1009 /* Try again starting with next byte */
1010 program_byte = absolute_to_program(pos) + 1;
1011 result = seek_phys();
1012 last_packet_start = absolute_position();
1015 /* Ignore errors in the parsing. Just quit if eof. */
1018 zmsgs("%d\n", __LINE__);
1019 last_packet_end = absolute_position();
1020 pos = absolute_to_program(last_packet_start);
1021 program_byte = pos + (last_packet_end - last_packet_start);
1023 zmsgs("%d\n", __LINE__);
1028 get_cell(int no, zcell_t *&v)
1030 for( int i=0; i<total_titles; ++i ) {
1031 title_t *title = titles[i];
1032 int n = title->cell_table_size;
1033 for( int k=0; k<n; ++k ) {
1034 zcell_t *cell = &title->cell_table[k];
1035 if( cell->cell_no >= no ) {
1037 return cell->cell_no == no ? 0 : 1;
1047 int last_cell_no = current_cell_no();
1049 int64_t next_byte = program_byte;
1050 if( !reverse && nav_cell_end_byte >= 0 && next_byte >= nav_cell_end_byte ) {
1051 if( nav_cell_next_vobu >= 0 ) {
1052 if( next_byte != nav_cell_next_vobu ) {
1053 zmsgs("next_vobu 0x%jx!=0x%jx next_byte\n", nav_cell_next_vobu, next_byte);
1054 next_byte = nav_cell_next_vobu;
1056 nav_cell_next_vobu = -1;
1058 nav_cell_end_byte = -1;
1061 int next_title, next_cell;
1062 int64_t pos = program_to_absolute(next_byte, &next_byte, &next_title, &next_cell);
1063 if( next_byte < 0 ) return 1;
1066 int do_cell_change = 0;
1067 if( program_byte != next_byte ) {
1068 zmsgs("program_byte hopped from 0x%jx to 0x%jx\n", program_byte, next_byte);
1069 program_byte = next_byte;
1072 if( next_title != current_title ) {
1073 open_title(next_title);
1076 if( title_cell != next_cell ) {
1077 title_cell = next_cell;
1081 if( do_cell_change ) {
1082 /* Need to change cells if we get here. */
1083 int cell_no = current_cell_no();
1084 if( last_cell_no != cell_no ) {
1085 nav_cell_end_byte = -1;
1088 if( !get_cell(cell_no, cell) && cell->discontinuity ) {
1090 atrack_t *atrk = do_audio;
1092 atrk->pts_offset = atrk->audio_time = cell->cell_time;
1093 atrk->pts_position = atrk->audio_time * atrk->sample_rate;
1096 vtrack_t *vtrk = do_video;
1098 vtrk->pts_offset = vtrk->video_time = cell->cell_time;
1099 vtrk->pts_position = vtrk->video_time * vtrk->frame_rate;
1106 if( !zdata.length() ) {
1107 if( program_byte >= movie_size() ) return 1;
1108 if( stream_end >= 0 && program_byte >= stream_end ) return 1;
1111 title_t *title = titles[current_title];
1112 title->fs->seek(pos - title->start_byte);
1117 next_code(uint32_t zcode)
1119 uint32_t result = 0;
1122 while( result!=zcode && !error ) {
1124 title_t *title = titles[current_title];
1125 result |= title->fs->read_char() & 0xff;
1127 error = seek_phys();
1133 /* Read packet in the forward direction */
1137 if( current_title < 0 ) return 1;
1139 title_t *title = titles[current_title];
1140 /* Reset output buffer */
1145 //zmsgs("%d program_byte=0x%jx reverse=%d\n",
1146 // __LINE__, program_byte, reverse);
1148 /* Switch to forward direction. */
1150 /* Don't reread anything if we're at the beginning of the file. */
1151 if( program_byte < 0 ) {
1153 result = seek_phys();
1154 /* First character was the -1 byte which brings us to 0 after this function. */
1157 else if( src->packet_size > 0 ) { /* Transport or elementary stream */
1158 program_byte += src->packet_size;
1159 result = seek_phys();
1162 /* Packet just read */
1164 result = next_code(PACK_START_CODE);
1167 result = next_code(PACK_START_CODE);
1172 /* Read packets until the output buffer is full. */
1173 /* Read a single packet if not fetching audio or video. */
1175 title = titles[current_title];
1176 //zmsgs("10 0x%jx\n", absolute_position());
1177 if( src->is_transport_stream() ) {
1178 result = seek_phys();
1180 result = read_transport();
1182 else if( src->is_program_stream() ) {
1183 result = seek_phys();
1184 //zmsgs("%d 0x%jx\n", __LINE__, tell_byte());
1186 result = read_program();
1187 //zmsgs("%d 0x%jx\n", __LINE__, tell_byte());
1190 if( read_all && src->is_audio_stream() ) {
1191 /* Read elementary stream. */
1192 result = title->fs->read_data(zaudio.buffer, src->packet_size);
1193 zaudio.size = src->packet_size;
1195 else if( read_all && src->is_video_stream() ) {
1196 /* Read elementary stream. */
1197 result = title->fs->read_data(zvideo.buffer, src->packet_size);
1198 zvideo.size = src->packet_size;
1201 result = title->fs->read_data(zdata.buffer, src->packet_size);
1202 zdata.size = src->packet_size;
1204 program_byte += src->packet_size;
1205 result |= seek_phys();
1207 //zmsgs("100 result=%d zdata.size=0x%x\n", result, zdata.size);
1208 } while( !result && zdata.size == 0 && (do_audio || do_video) );
1210 //zmsgs("%d result=%d zdata.size=0x%x\n", __LINE__, result, zdata.size);
1215 previous_code(uint32_t zcode)
1217 uint32_t result = 0;
1220 while( result!=zcode && program_byte>0 && !error ) {
1222 title_t *title = titles[current_title];
1223 title->fs->seek(program_byte-title->start_byte-1);
1224 result |= (title->fs->read_char() & 0xff) << 24;
1226 error = seek_phys();
1231 /* Read the packet right before the packet we're currently on. */
1236 title_t *title = titles[current_title];
1237 nav_cell_end_byte = -1;
1240 /* Switch to reverse direction */
1243 /* Transport stream or elementary stream case */
1244 if( src->packet_size > 0 ) {
1245 program_byte -= src->packet_size;
1246 result = seek_phys();
1248 else { /* Program stream */
1249 result = previous_code(PACK_START_CODE);
1253 /* Go to beginning of previous packet */
1255 title = titles[current_title];
1257 /* Transport stream or elementary stream case */
1258 if( src->packet_size > 0 ) {
1259 //zmsgs("1 result=%d title=%d tell=0x%jx program_byte=0x%jx\n",
1260 // result, current_title, absolute_position(), program_byte);
1261 program_byte -= src->packet_size;
1262 result = seek_phys();
1263 //zmsgs("100 result=%d title=%d tell=0x%jx program_byte=0x%jx\n",
1264 // result, current_title, absolute_position(), program_byte);
1268 result = previous_code(PACK_START_CODE);
1271 /* Read packet and then rewind it */
1272 title = titles[current_title];
1273 if( src->is_transport_stream() && !result ) {
1274 result = read_transport();
1276 if( program_byte > 0 ) {
1277 program_byte -= src->packet_size;
1278 result = seek_phys();
1281 else if( src->is_program_stream() && !result ) {
1282 int64_t cur_position = program_byte;
1284 result = read_program();
1286 while( program_byte > cur_position && !result ) {
1287 result = previous_code(PACK_START_CODE);
1290 else if( !result ) {
1291 /* Elementary stream */
1292 /* Read the packet forwards and seek back to the start */
1293 result = title->fs->read_data(zdata.buffer, src->packet_size);
1295 zdata.size = src->packet_size;
1296 result = title->fs->seek(program_byte);
1299 } while (!result && zdata.size == 0 && (do_audio || do_video) );
1306 read_data(uint8_t *output, int size)
1312 if( zdata.position >= 0 ) {
1315 while( count<size && !result ) {
1316 int fragment_size = size - count;
1317 int len = zdata.length();
1318 if( fragment_size > len ) fragment_size = len;
1319 memcpy(output+count, zdata.buffer+zdata.position, fragment_size);
1320 zdata.position += fragment_size;
1321 count += fragment_size;
1322 if( count >= size ) break;
1323 result = read_next_packet();
1324 //zmsgs("10 offset=0x%jx pid=0x%x bytes=0x%x i=0x%x\n",
1325 // tell_byte(), pid, zdata.size, count);
1330 int cur_position = zdata.position;
1331 /* Read backwards a full packet. */
1332 /* Only good for reading less than the size of a full packet, but */
1333 /* this routine should only be used for searching for previous markers. */
1334 result = read_prev_packet();
1335 if( !result ) zdata.position = zdata.size + cur_position;
1336 memcpy(output, zdata.buffer+zdata.position, size);
1337 zdata.position += size;
1341 error_flag = result;
1345 uint8_t zdemuxer_t::
1350 if( zdata.position >= zdata.size )
1351 error_flag = read_next_packet();
1353 next_char = zdata.buffer[zdata.position++];
1357 uint8_t zdemuxer_t::
1358 read_prev_char_packet()
1361 if( --zdata.position < 0 ) {
1362 error_flag = read_prev_packet();
1363 if( !error_flag ) zdata.position = zdata.size - 1;
1366 if( zdata.position >= 0 )
1367 next_char = zdata.buffer[zdata.position];
1372 open_title(int title_number)
1376 if( title_number<total_titles && title_number >= 0 ) {
1377 if( current_title >= 0 ) {
1378 titles[current_title]->fs->close_file();
1381 title = titles[title_number];
1382 if( title->fs->open_file() ) {
1384 perrs("%s",title->fs->path);
1387 current_title = title_number;
1390 zerrs("title_number = %d\n", title_number);
1395 copy_titles(zdemuxer_t *dst)
1398 memcpy(&dst->vstream_table[0],&vstream_table[0],sizeof(dst->vstream_table));
1399 memcpy(&dst->astream_table[0],&astream_table[0],sizeof(dst->astream_table));
1400 memcpy(&dst->sstream_table[0],&sstream_table[0],sizeof(dst->sstream_table));
1402 for( i=0; i<dst->total_titles; ++i )
1403 delete dst->titles[i];
1405 dst->total_titles = total_titles;
1406 for( i=0; i<total_titles; ++i ) {
1407 dst->titles[i] = new title_t(*titles[i]);
1410 if( current_title >= 0 )
1411 dst->open_title(current_title);
1413 dst->title_cell = -1;
1418 end_title(int64_t end_byte)
1420 if( !total_titles ) return;
1421 title_t *title = titles[total_titles-1];
1422 title->total_bytes = end_byte - title->start_byte;
1423 title->end_byte = end_byte;
1424 if( !title->cell_table_size ) return;
1425 title_t::cell_t *cell = &title->cell_table[title->cell_table_size-1];
1426 cell->title_end = title->total_bytes;
1427 cell->program_end = cell->title_end - cell->title_start + cell->program_start;
1430 /* ==================================================================== */
1432 /* ==================================================================== */
1435 demuxer_t(zmpeg3_t *zsrc, zatrack_t *do_aud, zvtrack_t *do_vid, int cust_id)
1437 /* The demuxer will change the default packet size for its own use. */
1442 /* Allocate buffer + padding */
1443 raw_data = new uint8_t[RAW_SIZE];
1444 zdata.buffer = new uint8_t[zdata.allocated=RAW_SIZE];
1445 zaudio.buffer = new uint8_t[zaudio.allocated=RAW_SIZE];
1446 zvideo.buffer = new uint8_t[zvideo.allocated=RAW_SIZE];
1448 /* System specific variables */
1449 audio_pid = cust_id;
1450 video_pid = cust_id;
1451 subtitle_pid = cust_id;
1456 pes_audio_time = -1.;
1457 pes_video_time = -1.;
1458 //zmsgs("%f\n", time);
1460 nav_cell_end_byte = -1;
1468 if( current_title >= 0 )
1469 titles[current_title]->fs->close_file();
1471 for( i=0; i<total_titles; ++i )
1474 if( zdata.buffer ) delete [] zdata.buffer;
1475 if( raw_data ) delete [] raw_data;
1476 if( zaudio.buffer ) delete [] zaudio.buffer;
1477 if( zvideo.buffer ) delete [] zvideo.buffer;
1479 for( i=0; i<total_subtitles; ++i )
1480 delete subtitles[i];
1482 if( nav ) delete nav;
1485 uint8_t zdemuxer_t::
1488 if( zdata.position )
1489 return zdata.buffer[--zdata.position];
1490 return read_prev_char_packet();
1496 return current_title == 0 && titles[0]->fs->bof();
1502 if( !src->seekable ) return zdata.eof();
1503 if( error() ) return 1;
1504 if( current_title >= total_titles ) return 1;
1505 if( current_title >= 0 && titles[current_title]->fs->eof() ) return 1;
1506 /* Same operation performed in seek_phys */
1507 return stream_end >= 0 && program_byte >= stream_end && !zdata.length();
1522 /* Seek to absolute byte */
1524 seek_byte(int64_t byte)
1526 /* for( int i=0; i<total_titles; ++i ) titles[i]->dump_title(); */
1529 nav_cell_end_byte = -1;
1530 program_byte = byte;
1534 int result = seek_phys();
1535 //zmsgs("1 %p %d 0x%jx 0x%jx\n", do_video, result, byte, program_byte);
1540 set_audio_pts(uint64_t pts, const double denom)
1542 if( pts && pes_audio_time < 0 ) {
1543 pes_audio_pid = custom_id;
1544 pes_audio_time = pts / denom;
1545 //zmsgs("pid 0x%03x, pts %f @0x%jx\n",pes_audio_pid, pes_audio_time,
1546 // absolute_position());
1551 set_video_pts(uint64_t pts, const double denom)
1553 if( pts && pes_video_time < 0 ) {
1554 pes_video_pid = custom_id;
1555 pes_video_time = pts / denom;
1556 //zmsgs("pid 0x%03x, pts %f @0x%jx\n",pes_video_pid, pes_video_time,
1557 // absolute_position());
1564 atrack_t *atrk = do_audio;
1565 vtrack_t *vtrk = do_video;
1566 if( !atrk && !vtrk ) {
1567 for( int i=0; !atrk && i<src->total_atracks; ++i )
1568 if( src->atrack[i]->pid == pid ) atrk = src->atrack[i];
1569 for( int i=0; !vtrk && i<src->total_vtracks; ++i )
1570 if( src->vtrack[i]->pid == pid ) vtrk = src->vtrack[i];
1572 if( atrk ) atrk->reset_pts();
1573 if( vtrk ) vtrk->reset_pts();
1579 int64_t start_position = tell_byte();
1580 int64_t end_position = start_position + PTS_RANGE;
1581 int64_t current_position = start_position;
1585 while( !result && current_position < end_position &&
1586 ( (do_audio && pes_audio_time < 0) ||
1587 (do_video && pes_video_time < 0) ) ) {
1588 result = read_next_packet();
1589 current_position = tell_byte();
1592 /* Seek back to starting point */
1593 seek_byte(start_position);
1595 if( do_audio ) return pes_audio_time;
1596 if( do_video ) return pes_video_time;
1597 zerr("no active data to scan\n");
1602 goto_pts(double pts)
1604 int64_t start_position = tell_byte();
1605 int64_t end_position = start_position + PTS_RANGE;
1606 int64_t current_position = start_position;
1609 /* Search forward for nearest pts */
1611 while( !result && current_position < end_position ) {
1612 result = read_next_packet();
1613 if( pes_audio_time > pts ) break;
1614 current_position = tell_byte();
1617 /* Search backward for nearest pts */
1618 end_position = current_position - PTS_RANGE;
1620 while( !result && current_position > end_position ) {
1621 result = read_prev_packet();
1622 if( pes_audio_time < pts ) break;
1623 current_position = tell_byte();
1631 if( current_title < 0 || current_title >= total_titles ) return -1;
1632 title_t *title = titles[current_title];
1633 if( !title->cell_table || title_cell < 0 ) return -1;
1634 return title->cell_table[title_cell].cell_no;
1637 int64_t zdemuxer_t::
1638 absolute_to_program(int64_t byte)
1640 //zmsgs("%d\n", zdata.size);
1641 /* Can only offset to current cell since we can't know what cell the */
1642 /* byte corresponds to. */
1643 title_t *title = titles[current_title];
1644 title_t::cell_t *cell = &title->cell_table[title_cell];
1645 return byte - cell->title_start - title->start_byte + cell->program_start;
1648 int64_t zdemuxer_t::
1649 prog2abs_fwd(int64_t byte, int64_t *nbyte, int *ntitle, int *ncell)
1651 int ltitle = -1, lcell = -1;
1653 int ititle = current_title;
1654 int icell = title_cell;
1656 title_t::cell_t *cell;
1657 // check current cell first
1658 if( ititle >= 0 && ititle < total_titles ) {
1659 title = titles[ititle];
1660 if( icell >= 0 && icell < title->cell_table_size ) {
1661 cell = &title->cell_table[icell];
1662 if( byte >= cell->program_start && byte < cell->program_end ) goto xit;
1666 for( ititle=0; ititle<total_titles; ++ititle ) {
1667 // check all title cells
1668 title = titles[ititle];
1669 int ncells = title->cell_table_size;
1670 if( ncells <= 0 ) continue;
1671 if( byte >= title->cell_table[ncells-1].program_end ) continue;
1672 for( icell=0; icell<ncells; ++icell ) {
1673 cell = &title->cell_table[icell];
1674 if( byte < cell->program_end ) goto xit;
1675 if( lbyte > cell->program_end ) continue;
1676 lbyte = cell->program_end;
1677 ltitle = ititle; lcell = icell;
1680 // not found, return search region boundry
1681 if( nbyte ) *nbyte = lbyte;
1682 if( ntitle ) *ntitle = ltitle;
1683 if( ncell ) *ncell = lcell;
1684 return total_titles>0 ? titles[total_titles-1]->end_byte : -1;
1687 if( byte < cell->program_start ) byte = cell->program_start;
1688 if( nbyte ) *nbyte = byte;
1689 if( ntitle ) *ntitle = ititle;
1690 if( ncell ) *ncell = icell;
1691 return title->start_byte + cell->title_start + byte - cell->program_start;
1694 int64_t zdemuxer_t::
1695 prog2abs_rev(int64_t byte, int64_t *nbyte, int *ntitle, int *ncell)
1697 int ititle = current_title;
1698 int icell = title_cell;
1700 title_t::cell_t *cell;
1701 // check current cell first
1702 if( ititle >= 0 && ititle < total_titles ) {
1703 title = titles[ititle];
1704 if( icell >= 0 && icell < title->cell_table_size ) {
1705 cell = &title->cell_table[icell];
1706 if( byte > cell->program_start && byte <= cell->program_end ) goto xit;
1710 for( ititle=total_titles; --ititle>=0; ) {
1711 // check all title cells
1712 title = titles[ititle];
1713 int ncells = title->cell_table_size;
1714 if( ncells <= 0 ) continue;
1715 if( byte < title->cell_table[0].program_start ) continue;
1716 for( icell=ncells; --icell>=0; ) {
1717 cell = &title->cell_table[icell];
1718 if( byte > cell->program_start ) goto xit;
1721 // not found, return search region boundry
1722 if( nbyte ) *nbyte = 0;
1723 if( ntitle ) *ntitle = 0;
1724 if( ncell ) *ncell = 0;
1728 if( byte > cell->program_end ) byte = cell->program_end;
1729 if( nbyte ) *nbyte = byte;
1730 if( ntitle ) *ntitle = ititle;
1731 if( ncell ) *ncell = icell;
1732 return title->start_byte + cell->title_start + byte - cell->program_start;
1735 int64_t zdemuxer_t::
1736 program_to_absolute(int64_t byte, int64_t *nbyte, int *ntitle, int *ncell)
1739 prog2abs_fwd(byte, nbyte, ntitle, ncell) :
1740 prog2abs_rev(byte, nbyte, ntitle, ncell) ;
1743 int64_t zdemuxer_t::
1746 if( !total_bytes ) {
1749 for( i=0; i<total_titles; ++i ) {
1750 title_t *title = titles[i];
1751 if( title->cell_table ) {
1752 for( j=0; j<title->cell_table_size; ++j ) {
1753 title_t::cell_t *cell = &title->cell_table[j];
1754 /* result = cell->program_end - cell->program_start; */
1755 if( result < cell->program_end ) result = cell->program_end;
1758 /* result += titles[i]->total_bytes; */
1760 total_bytes = result;
1765 int64_t zdemuxer_t::
1768 if( current_title < 0 || current_title >= total_titles ) return -1;
1769 int i = current_title;
1770 if( !titles[i]->cell_table || title_cell < 0 ) return -1;
1772 int n = titles[i]->cell_table[k].cell_no;
1774 /* always forward search, stop when cell_no changes */
1775 while ( i < total_titles && titles[i]->cell_table[k].cell_no == n ) {
1777 /* some titles have no cells (may be another program) */
1778 while( !titles[i]->cell_table || k >= titles[i]->cell_table_size ) {
1779 if( ++i >= total_titles ) break;
1784 return i < total_titles ? titles[i]->cell_table[k].program_start : movie_size();
1787 int64_t zdemuxer_t::
1788 playinfo_next_cell()
1790 int64_t result = -1;
1792 int pcell_no = titles[current_title]->cell_table[i++].cell_no;
1794 for( int n=current_title ; result<0 && n<total_titles; ++n ) {
1795 title_t *title = titles[n];
1796 for( ; result<0 && i<title->cell_table_size; ++i ) {
1797 if( title->cell_table[i].cell_no != pcell_no )
1798 result = title->cell_table[i].program_start;
1806 int64_t zdemuxer_t::
1809 title_t *title = titles[current_title];
1810 return title->total_bytes;
1814 append_data(uint8_t *data, int bytes)
1816 if( bytes <= 0 ) return;
1817 int new_data_size = zdata.size + bytes;
1818 if( zdata.size + new_data_size >= zdata.allocated ) {
1819 zdata.allocated = (zdata.size + new_data_size) * 2;
1820 uint8_t *new_data_buffer = new uint8_t[zdata.allocated];
1821 memcpy(new_data_buffer,zdata.buffer,zdata.size);
1822 delete [] zdata.buffer;
1823 zdata.buffer = new_data_buffer;
1826 memcpy(zdata.buffer+zdata.size, data, bytes);
1827 zdata.size += bytes;
1833 if( zdata.position <= 0 ) return;
1834 memmove(zdata.buffer,
1835 zdata.buffer+zdata.position,
1836 zdata.size-zdata.position);
1837 zdata.size -= zdata.position;
1841 /* Create a title and get PID's by scanning first few bytes. */
1843 create_title(int full_scan)
1850 /* Create a single title */
1851 if( !total_titles ) {
1852 titles[0] = new title_t(src);
1857 title_t *title = titles[0];
1858 title->total_bytes = title->fs->ztotal_bytes();
1859 title->start_byte = 0;
1860 title->end_byte = title->total_bytes;
1862 zmsgs("%d path=%s total_bytes=%jd\n",
1863 __LINE__, src->fs->path, title->total_bytes);
1865 /* Create default cell */
1866 if( !title->cell_table_size )
1867 title->new_cell(title->end_byte);
1869 /* Get PID's and tracks */
1870 if( src->is_transport_stream() || src->is_program_stream() ) {
1871 title->fs->seek(START_BYTE);
1872 int64_t next_byte = START_BYTE;
1873 int64_t last_time_pos = next_byte;
1874 // only spend a few seconds on this
1876 gettimeofday(&tv,NULL);
1877 double start_time = tv.tv_sec + tv.tv_usec/1000000.0;
1878 while( !title->fs->eof() ) {
1879 if( read_next_packet() ) break;
1880 next_byte = title->fs->tell();
1882 if( src->is_transport_stream() ) {
1883 src->dvb.atsc_tables(this, custom_id);
1886 if( full_scan ) continue;
1887 if( src->is_transport_stream() ) {
1888 if( next_byte > START_BYTE + MAX_TS_PROBE ) break;
1890 if( src->dvb.signal_time() > 3 ) break;
1893 else if( src->is_program_stream() )
1894 if( next_byte > START_BYTE + MAX_PGM_PROBE ) break;
1895 if( next_byte - last_time_pos > 0x40000 ) {
1896 gettimeofday(&tv,NULL);
1897 double next_time = tv.tv_sec + tv.tv_usec/1000000.0;
1898 if( next_time - start_time > 3 ) break;
1899 last_time_pos = next_byte;
1904 if( src->is_transport_stream() )
1905 src->dvb.read_dvb(this);
1907 title->fs->seek(START_BYTE);
1915 uint32_t header = 0;
1916 title_t *title = titles[current_title];
1920 header &= 0xffffffff;
1921 header |= title->fs->read_char();
1922 } while( header != PICTURE_START_CODE && !title->fs->eof() );
1924 * if(!mpeg3io_eof(title->fs))
1925 * mpeg3io_seek_relative(title->fs, -4);
1927 src->last_type_read = 2;