update SVT-AV1 to latest version of 2.3.0 from 2.2.1
[goodguy/cinelerra.git] / cinelerra-5.1 / libzmpeg3 / toc.C
1 #include "libzmpeg3.h"
2
3 #define PUT_INT32(x) do { \
4  uint32_t be = htobe32(x); \
5  fwrite((uint8_t*)&be,1,sizeof(be),toc_fp); \
6 } while(0)
7
8 #define PUT_INT64(x) do { \
9  uint64_t be = htobe64(x); \
10  fwrite((uint8_t*)&be,1,sizeof(be),toc_fp); \
11 } while(0)
12
13
14 //#define DATA_DUMP
15 #ifdef DATA_DUMP
16 #include <stdio.h>
17 static FILE **video_fp = 0;
18 static FILE **audio_fp = 0;
19 #endif
20
21 static inline void read_data(uint8_t *bfr, int &pos, uint8_t *out, int len)
22 {
23   memcpy(out, bfr + pos, len);
24   pos += len;
25 }
26
27 /* Concatenate title and toc directory if title is not absolute and */
28 /*  toc path has a directory section. */
29 static inline void concat_path(char *full_path, char *toc_path, char *path)
30 {
31   if( path[0] != '/' ) {
32     char *ptr = strrchr(toc_path, '/');
33     if( ptr ) {
34       strcpy(full_path, toc_path);
35       strcpy(&full_path[ptr - toc_path + 1], path);
36     }
37   }
38   else
39     strcpy(full_path, path);
40 }
41
42 int zmpeg3_t::
43 read_toc(int *atracks_return, int *vtracks_return, const char *title_path)
44 {
45   int i, j;
46   int64_t current_byte = 0;
47   int debug = 0;
48   /* Fix title paths for Cinelerra VFS */
49   int vfs_len = strlen(ZRENDERFARM_FS_PREFIX);
50   int is_vfs = !strncmp(fs->path,ZRENDERFARM_FS_PREFIX, vfs_len) ? 1 : 0;
51   fs->seek(0);
52   /* Test version */
53   fs->read_uint32();
54   uint32_t toc_version = fs->read_uint32();
55   if( toc_version != TOC_VERSION ) {
56     zerrs("invalid TOC version %08x (should be %08x)\n", 
57       toc_version, TOC_VERSION);
58     return ERR_INVALID_TOC_VERSION;
59   }
60   /* File type */
61   while( !fs->eof() ) {
62   /* Get section type */
63     int section_type = fs->read_uint32();
64 //zmsgs("section_type=%d position=%jx\n", section_type, fs->tell());
65     switch( section_type ) {
66       case toc_FILE_TYPE_PROGRAM:
67         file_type = FT_PROGRAM_STREAM;
68         break;
69       case toc_FILE_TYPE_TRANSPORT:
70         file_type = FT_TRANSPORT_STREAM;
71         break;
72       case toc_FILE_TYPE_AUDIO:
73         file_type = FT_AUDIO_STREAM;
74         break;
75       case toc_FILE_TYPE_VIDEO:
76         file_type = FT_VIDEO_STREAM;
77         break;
78
79       case toc_FILE_INFO: {
80         char string[STRLEN];
81         char string2[STRLEN];
82         fs->read_data((uint8_t*)&string[0],STRLEN);
83         if( title_path )
84           strcpy(string2, title_path);
85         else
86           concat_path(string2, fs->path, string);
87         source_date = fs->read_uint64();
88         int64_t current_date = calculate_source_date(string2);
89 //zmsgs("zsrc=%s source_date=%jd current_date=%jd\n", 
90 // string2, source_date, current_date);
91         if( current_date != source_date ) {
92           zerrs("date mismatch %jx (should be %jx)\n",
93              current_date, source_date);
94           return ERR_TOC_DATE_MISMATCH;
95         }
96         break; }
97
98       case toc_STREAM_AUDIO: {
99         int n = fs->read_uint32();
100         demuxer->astream_table[n] = fs->read_uint32();
101         break; }
102
103       case toc_STREAM_VIDEO: {
104         int n = fs->read_uint32();
105         demuxer->vstream_table[n] = fs->read_uint32();
106         break; }
107
108
109       case toc_ATRACK_COUNT: {
110         int atracks = fs->read_uint32();
111         *atracks_return = atracks;
112         channel_counts = znew(int,atracks);
113         nudging = znew(int,atracks);
114         sample_offsets = znew(int64_t*,atracks);
115         total_sample_offsets = znew(int,atracks);
116         audio_eof = znew(int64_t,atracks);
117         total_samples = znew(int64_t,atracks);
118         indexes = znew(index_t*,atracks);
119         total_indexes = atracks;
120         for( i=0; i < atracks; ++i ) {
121           audio_eof[i] = fs->read_uint64();
122           channel_counts[i] = fs->read_uint32();
123           nudging[i] = fs->read_uint32();
124           total_sample_offsets[i] = fs->read_uint32();
125           total_samples[i] = fs->read_uint64();
126
127           if(total_samples[i] < 1) total_samples[i] = 1;
128           sample_offsets[i] = znew(int64_t,total_sample_offsets[i]);
129           for( j=0; j < total_sample_offsets[i]; ++j ) {
130             sample_offsets[i][j] = fs->read_uint64();
131           }
132
133           index_t *index = indexes[i] = new index_t();
134           index->index_size = fs->read_uint32();
135           index->index_zoom = fs->read_uint32();
136 //zmsgs("%d %d %d\n", i, index->index_size, index->index_zoom);
137           int channels = index->index_channels = channel_counts[i];
138           if( channels ) {
139             index->index_data = znew(float*,channels);
140             for( j=0; j < channels; ++j ) {
141               index->index_data[j] = znew(float,index->index_size*2);
142               fs->read_data((uint8_t*)index->index_data[j], 
143                 sizeof(float) * index->index_size * 2);
144             }
145           }
146         }
147         break; }
148
149       case toc_VTRACK_COUNT: {
150         int vtracks = fs->read_uint32();
151         *vtracks_return = vtracks;
152         frame_offsets = znew(int64_t*,vtracks);
153         total_frame_offsets = znew(int,vtracks);
154         keyframe_numbers = znew(int*,vtracks);
155         total_keyframe_numbers = znew(int,vtracks);
156         video_eof = znew(int64_t,vtracks);
157         for( i=0; i < vtracks; ++i ) {
158           video_eof[i] = fs->read_uint64();
159           total_frame_offsets[i] = fs->read_uint32();
160           frame_offsets[i] = new int64_t[total_frame_offsets[i]];
161           if( debug ) zmsgs("62 %d %jx %jx\n",
162             total_frame_offsets[i], fs->tell(), fs->ztotal_bytes());
163           for( j=0; j < total_frame_offsets[i]; ++j ) {
164             frame_offsets[i][j] = fs->read_uint64();
165 //zmsgs("frame %llx\n", frame_offsets[i][j]);
166           }
167           if(debug) zmsg("64\n");
168           total_keyframe_numbers[i] = fs->read_uint32();
169           keyframe_numbers[i] = new int[total_keyframe_numbers[i]];
170           for( j=0; j < total_keyframe_numbers[i]; ++j ) {
171             keyframe_numbers[i][j] = fs->read_uint32();
172           }
173         }
174         break; }
175
176       case toc_STRACK_COUNT: {
177         total_stracks = fs->read_uint32();
178         for( i=0; i < total_stracks; ++i ) {
179           int id = fs->read_uint32();
180           strack_t *strk = new strack_t(id);
181           strack[i] = strk;
182           strk->total_offsets = fs->read_uint32();
183           strk->offsets = znew(int64_t,strk->total_offsets);
184           strk->allocated_offsets = strk->total_offsets;
185           for( j=0; j < strk->total_offsets; ++j ) {
186             strk->offsets[j] = fs->read_uint64();
187           }
188         }
189         break; }
190
191       case toc_TITLE_PATH: {
192         if(debug) zmsg("11\n");
193         char string[STRLEN];
194         fs->read_data((uint8_t*)string, STRLEN);
195         /* Detect Blu-Ray */
196         if( debug ) printf("11 position=%jx\n", fs->tell());
197         char *ext = strrchr(string, '.');
198         if( ext ) {
199           if( !strncasecmp(ext, ".m2ts", 5) ||
200               !strncasecmp(ext, ".mts", 4) ) file_type |= FT_BD_FILE;
201         }
202         if(debug) printf("12\n");
203         // if title_path concatenate dirname title_path and basename path
204         if( title_path ) {
205           char string2[STRLEN], *bp = string2, *cp = string2;
206           for( const char *tp=title_path; (*cp++=*tp) != 0; ++tp )
207             if( *tp == '/' ) bp = cp;
208           for( char *sp=cp=string; *sp != 0; ++sp )
209             if( *sp == '/' ) cp = sp+1;
210           while( (*bp++=*cp++)!=0 );
211           strcpy(string, string2);
212         }
213         // Test title availability
214         if( access(string,R_OK) ) {
215           /* Concatenate title and toc directory if title is not absolute and */
216           /* toc path has a directory section. */
217           if( (!is_vfs && string[0] != '/') ||
218                (is_vfs && string[vfs_len] != '/') ) {
219             /* Get toc filename without path */
220             char *ptr = strrchr(fs->path, '/');
221             if( ptr ) {
222               char string2[STRLEN];
223               /* Stack filename on toc path */
224               strcpy(string2, fs->path);
225               if( !is_vfs )
226                 strcpy(&string2[ptr - fs->path + 1], string);
227               else
228                 strcpy(&string2[ptr - fs->path + 1], string + vfs_len);
229               if( access(string2,R_OK) ) {
230                 zerrs("failed to open %s or %s\n", string, string2);
231                 return 1;
232               }
233               strcpy(string, string2);
234             }
235             else {
236               zerrs("failed to open %s\n", string);
237               return 1;
238             }
239           }
240           else {
241             zerrs("failed to open %s\n", string);
242             return 1;
243           }
244         }
245
246         if(debug) zmsg("30\n");
247         demuxer_t::title_t *title = new demuxer_t::title_t(this, string);
248         demuxer->titles[demuxer->total_titles++] = title;
249         title->total_bytes = fs->read_uint64();
250         title->start_byte = current_byte;
251         title->end_byte = title->start_byte + title->total_bytes;
252         current_byte = title->end_byte;
253         /* Cells */
254         title->cell_table_allocation = fs->read_uint32();
255         title->cell_table_size = title->cell_table_allocation;
256 //zmsgs("40 %llx %d\n", title->total_bytes, title->cell_table_size);
257         title->cell_table =
258           new demuxer_t::title_t::cell_t[title->cell_table_size];
259         for( i=0; i < title->cell_table_size; ++i ) {
260           demuxer_t::title_t::cell_t *cell = &title->cell_table[i];
261           cell->title_start = fs->read_uint64();
262           cell->title_end = fs->read_uint64();
263           cell->program_start = fs->read_uint64();
264           cell->program_end = fs->read_uint64();
265           union { double d; uint64_t u; } cell_time;
266           cell_time.u = fs->read_uint64();
267           cell->cell_time = cell_time.d;
268           cell->cell_no = fs->read_uint32();
269           cell->discontinuity = fs->read_uint32();
270 //zmsgs("50 %jx-%jx %jx-%jx %d %d\n", 
271 // cell->title_start, cell->title_end, cell->program_start,
272 // cell->program_end, cell->cell_no, cell->discontinuity);
273         }
274         break; }
275
276       case toc_IFO_PALETTE:
277         for(i = 0; i < 16; i++) {
278           int k = i*4;
279           palette[k + 0] = fs->read_char();
280           palette[k + 1] = fs->read_char();
281           palette[k + 2] = fs->read_char();
282           palette[k + 3] = fs->read_char();
283 //zmsgs("color %02d: 0x%02x 0x%02x 0x%02x 0x%02x\n", 
284 // i, palette[k+0], palette[k+1], palette[k+2], palette[k+3]);
285         }
286         have_palette = 1;
287         break;
288       case toc_IFO_PLAYINFO: {
289         int ncells = fs->read_uint32();
290         icell_table_t *cells = new icell_table_t();
291         if( playinfo ) delete playinfo;
292         playinfo = cells;
293         while( --ncells >= 0 ) {
294           icell_t *cell = cells->append_cell();
295           cell->start_byte = fs->read_uint64();
296           cell->end_byte = fs->read_uint64();
297           cell->vob_id = fs->read_uint32();
298           cell->cell_id = fs->read_uint32();
299           cell->inlv = fs->read_uint32();
300           cell->discon = fs->read_uint32();
301         }
302         break;
303       }
304       case toc_SRC_PROGRAM: {
305         vts_title = fs->read_uint32();
306         total_vts_titles = fs->read_uint32();
307         int inlv = fs->read_uint32();
308         angle = inlv / 10;  interleave = inlv % 10;
309         total_interleaves = fs->read_uint32();
310         break;
311       }
312     }
313   }
314   if(debug) zmsg("90\n");
315   demuxer->open_title(0);
316   if(debug) zmsg("100\n");
317
318   return 0;
319 }
320
321
322 zmpeg3_t* zmpeg3_t::
323 start_toc(const char *path, const char *toc_path,
324     int program, int64_t *total_bytes)
325 {
326   if( total_bytes ) *total_bytes = 0;
327   zmpeg3_t *zsrc = new zmpeg3_t(path);
328   zsrc->toc_fp = fopen(toc_path, "w");
329   if(!zsrc->toc_fp) {
330     perrs("%s",toc_path);
331     delete zsrc;
332     return 0;
333   }
334   
335   zsrc->set_vts_title(program / 100);
336   zsrc->set_angle((program / 10) % 10);
337   zsrc->set_interleave(program % 10);
338   zsrc->last_cell_no = 0;
339
340   if( !total_bytes ) {
341     zsrc->fs->sequential();
342     zsrc->file_type = FT_TRANSPORT_STREAM;
343     zsrc->packet_size = zsrc->calculate_packet_size();
344   }
345
346   /* Authenticate encryption before reading a single byte */
347   /*  and Determine file type */
348   int toc_atracks = 0, toc_vtracks = 0;
349   if( zsrc->fs->open_file() ||
350       (!zsrc->file_type &&
351         zsrc->get_file_type(&toc_atracks, &toc_vtracks, 0) ) ) {
352     fclose(zsrc->toc_fp);  zsrc->toc_fp = 0;
353     delete zsrc;
354     return 0;
355   }
356
357   demuxer_t *demux = zsrc->demuxer;
358   /* Create title without scanning for tracks */
359   if( !demux->total_titles ) {
360     demuxer_t::title_t *title = new demuxer_t::title_t(zsrc);
361     demux->titles[0] = title;
362     demux->total_titles = 1;
363     demux->open_title(0);
364     title->total_bytes = title->fs->ztotal_bytes();
365     title->start_byte = 0;
366     title->end_byte = title->total_bytes;
367     title->new_cell(title->end_byte);
368   }
369
370   /*  mpeg3demux_seek_byte(zsrc->demuxer, 0x1734e4800LL); */
371   demux->seek_byte(0);
372   demux->read_all = -1;
373   int64_t bytes = demux->movie_size();
374   if( total_bytes ) *total_bytes = bytes;
375
376 //*total_bytes = 500000000;
377   zsrc->allocate_slice_decoders();
378   return zsrc;
379 }
380
381 void zmpeg3_t::
382 divide_index(int track_number)
383 {
384   if( total_indexes <= track_number ) return;
385   index_t *idx = indexes[track_number];
386   idx->index_size /= 2;
387   idx->index_zoom *= 2;
388   for( int i=0; i < idx->index_channels; ++i ) {
389     float *current_channel = idx->index_data[i];
390     float *out = current_channel;
391     float *in = current_channel;
392     for( int j=0; j < idx->index_size; ++j ) {
393       float max = ZMAX(in[0], in[2]);
394       float min = ZMIN(in[1], in[3]);
395       *out++ = max;
396       *out++ = min;
397       in += 4;
398     }
399   }
400 }
401
402 int zmpeg3_t::
403 update_index(int track_number, int flush)
404 {
405   int i, j, k, n;
406   int result = 0;
407   atrack_t *atrk = atrack[track_number];
408   if( track_number >= total_indexes ) {
409     /* Create index table */
410     int new_allocation = track_number + 1;
411     index_t **new_indexes = new index_t*[new_allocation];
412     for( i=0; i<total_indexes; ++i )
413       new_indexes[i] = indexes[i];
414     while( i < new_allocation )
415       new_indexes[i++] = new index_t();
416     delete [] indexes;
417     indexes = new_indexes;
418     total_indexes = new_allocation;
419   }
420   index_t *idx = indexes[track_number];
421   audio_t *aud = atrk->audio;
422 //zmsgs("%d atrk->audio->output_size=%d\n", __LINE__, aud->output_size);
423   while( ( flush && aud->output_size) ||
424          (!flush && aud->output_size > AUDIO_CHUNKSIZE) ) {
425     int fragment = AUDIO_CHUNKSIZE;
426     if( aud->output_size < fragment ) fragment = aud->output_size;
427     int index_fragments = fragment / idx->index_zoom;
428     if( flush ) ++index_fragments;
429     int new_index_samples = index_fragments + idx->index_size;
430     /* Update number of channels */
431     if( idx->index_allocated && idx->index_channels < atrk->channels ) {
432       float **new_index_data = znew(float*,atrk->channels);
433       for( i=0; i < idx->index_channels; ++i )
434         new_index_data[i] = idx->index_data[i];
435       for( i=idx->index_channels; i < atrk->channels; ++i )
436         new_index_data[i] = znew(float,idx->index_allocated*2);
437       idx->index_channels = atrk->channels;
438       delete [] idx->index_data;
439       idx->index_data = new_index_data;
440     }
441
442     /* Allocate index buffer */
443     if( new_index_samples > idx->index_allocated ) {
444       /* Double current number of samples */
445       idx->index_allocated = new_index_samples * 2;
446       if( !idx->index_data ) {
447         idx->index_data = znew(float*,atrk->channels);
448       }
449       /* Allocate new size in high and low pairs */
450       k = idx->index_allocated * sizeof(float*) * 2;
451       for( i=0; i < atrk->channels; ++i ) {
452         float *old_data = idx->index_data[i];
453         float *new_data = new float[k];
454         n = idx->index_size*2;
455         for( j=0; j<n; ++j ) new_data[j] = old_data[j];
456         while( j < k ) new_data[j++] = 0.;
457         delete [] idx->index_data[i];
458         idx->index_data[i] = new_data;
459       }
460       idx->index_channels = atrk->channels;
461     }
462
463     /* Calculate new index chunk */
464     for( i=0; i<atrk->channels; ++i ) {
465       float *in_channel = i < aud->output_channels ? aud->output[i] : 0;
466       float *out_channel = idx->index_data[i] + idx->index_size*2;
467       /* Calculate index frames */
468       for( j=0; j < index_fragments; ++j ) {
469         float min = 0;
470         float max = 0;
471         int remaining_fragment = fragment - j*idx->index_zoom;
472         int len = remaining_fragment < idx->index_zoom ?
473           remaining_fragment : idx->index_zoom;
474         if( in_channel && len > 0 ) {
475           min = max = *in_channel++;
476           for( k=1; k < len; ++k ) {
477             if( *in_channel > max ) max = *in_channel;
478             else if( *in_channel < min ) min = *in_channel;
479             ++in_channel;
480           }
481         }
482         *out_channel++ = max;
483         *out_channel++ = min;
484       }
485     }
486
487     idx->index_size = new_index_samples;
488     /* Shift audio buffer */
489     aud->shift_audio(fragment);
490     /* Create new toc entry */
491     atrk->append_samples(atrk->prev_offset);
492     atrk->current_position += fragment;
493     result = 1;
494   }
495   /* Divide index by 2 and increase zoom */
496   k = idx->index_size * atrk->channels * sizeof(float) * 2;
497   if( k > index_bytes && !(idx->index_size % 2) )
498     divide_index(track_number);
499   return result;
500 }
501
502
503 int zatrack_t::
504 handle_audio_data(int track_number)
505 {
506   zmpeg3_t *zsrc = audio->src;
507   /* Decode samples */
508   while( !audio->decode_audio(0, atyp_NONE, 0, AUDIO_HISTORY) ) {
509     /* add downsampled samples to the index buffer and create toc entry. */
510     if( !zsrc->update_index(track_number, 0) ) break;
511     prev_offset = curr_offset;
512   }
513   return 0;
514 }
515
516 int zatrack_t::
517 handle_audio(int track_number)
518 {
519 #ifdef DATA_DUMP
520 if( !audio_fp ) {
521   audio_fp = new FILE*[65536];
522   memset(audio_fp,0,65536*sizeof(FILE*));
523 }
524 if( !audio_fp[pid] ) {
525   char fn[512];
526   sprintf(fn,"/tmp/dat/a%04x.mpg",pid);
527   audio_fp[pid] = fopen(fn,"w");
528 }
529 if( audio_fp[pid] ) {
530   zmpeg3_t *zsrc = audio->src;
531   demuxer_t *demux = zsrc->demuxer;
532   if( demux->zaudio.size )
533     fwrite(demux->zaudio.buffer, demux->zaudio.size, 1, audio_fp[pid]);
534   else if( demux->zdata.size )
535     fwrite(demux->zdata.buffer, demux->zdata.size, 1, audio_fp[pid]);
536 }
537 #endif
538
539   int result = 0;
540   if( format != afmt_IGNORE ) {
541     zmpeg3_t *zsrc = audio->src;
542     demuxer_t *demux = zsrc->demuxer;
543     /* Assume last packet of stream */
544     audio_eof = demux->tell_byte();
545     /* Append demuxed data to track buffer */
546     if( demux->zaudio.size )
547       demuxer->append_data(demux->zaudio.buffer,demux->zaudio.size);
548     else if( demux->zdata.size )
549       demuxer->append_data(demux->zdata.buffer,demux->zdata.size);
550     if( demux->pes_audio_pid == pid && demux->pes_audio_time >= 0 ) {
551       demuxer->pes_audio_time = demux->pes_audio_time;
552       demux->pes_audio_time = -1.;
553     }
554     if( !sample_rate ) {
555       /* check for audio starting past first cell */
556       if( zsrc->pts_padding > 0 && zsrc->cell_time >= 0. ) {
557         audio_time = zsrc->cell_time;
558         pts_position = 0;
559         if( pts_starttime < 0. ) {
560           pts_offset = zsrc->cell_time;
561           pts_starttime = 0.;
562         }
563       }
564     }
565 //zmsgs("%d pid=%p zaudio.size=%d zdata.size=%d\n", __LINE__,
566 //  demux->pid, demux->zaudio.size, demux->zdata.size);
567 #if 0
568   if( pid == 0x1100 ) {
569     static FILE *test = 0;
570     if( !test ) test = fopen("/hmov/test.ac3", "w");
571     fwrite(demux->zaudio.buffer,
572            demux->zaudio.size, 1, test);
573   }
574 #endif
575     result = handle_audio_data(track_number);
576     demuxer->shift_data();
577   }
578   return result;
579 }
580
581 int zvtrack_t::
582 handle_video_data(int track_number, int prev_data_size)
583 {
584   zmpeg3_t *zsrc = video->src;
585   /* Scan for a start code a certain number of bytes from the end of the  */
586   /* buffer.  Then scan the header using the video decoder to get the  */
587   /* repeat count. */
588   while( demuxer->zdata.length() >= VIDEO_STREAM_SIZE ) {
589     if( !demuxer->last_code ) {
590       if( video->thumb && video->pict_type == video_t::pic_type_I ) {
591         if( tcode >= SLICE_MIN_START && tcode <= SLICE_MAX_START ) {
592           // start a new slice
593           slice = video->get_slice_buffer();
594 //int vtrk, sbfr = slice - &video->slice_buffers[0];
595 //for( vtrk=0; vtrk<zsrc->total_vtracks && video!=zsrc->vtrack[vtrk]->video; ++vtrk );
596 //printf("get_slice_buffer %p vtrk=%d, sbfr=%d\n",slice,vtrk,sbfr);
597           sbp = slice->data;
598           for( int i=32; i>0; ) *sbp++ = (tcode>>(i-=8));
599           sb_size = slice->buffer_allocation-4-4;
600           tcode = ~0;
601         }
602       }
603
604       if( !slice ) {
605         for(;;) {
606           if( (uint8_t)tcode != 0 ) {
607             tcode = (tcode<<8) | demuxer->read_char();
608             tcode = (tcode<<8) | demuxer->read_char();
609           }
610           tcode = (tcode<<8) | demuxer->read_char();
611           if( (tcode&0xffffff) == PACKET_START_CODE_PREFIX ) break;
612           if( demuxer->zdata.length() < VIDEO_STREAM_SIZE ) return 0;
613         }
614         tcode = (tcode<<8) | demuxer->read_char();
615       }
616       else {
617         for(;;) {
618           if( sb_size <= 0 ) {
619             sbp = slice->expand_buffer(sbp - slice->data);
620             sb_size = slice->buffer_size;
621           }
622           if( (uint8_t)tcode != 0 ) {
623             sb_size -= 3;
624             tcode = (tcode<<8) | (*sbp++ = demuxer->read_char());
625             tcode = (tcode<<8) | (*sbp++ = demuxer->read_char());
626           }
627           else
628             --sb_size;
629           tcode = (tcode<<8) | (*sbp++ = demuxer->read_char());
630           if( (tcode&0xffffff) == PACKET_START_CODE_PREFIX ) break;
631           if( demuxer->zdata.length() < VIDEO_STREAM_SIZE ) return 0;
632         }
633         tcode = (tcode<<8) | (*sbp++ = demuxer->read_char());
634         // finish slice
635         slice->buffer_size = sbp - slice->data;
636         *--sbp = 0;  sbp = 0;
637 //#define MULTI_THREADED
638 #ifdef MULTI_THREADED
639 // this is actually slower than single threaded
640         zsrc->decode_slice(slice);
641 #else
642         slice_decoder_t *decoder = &zsrc->slice_decoders[0];
643         decoder->slice_buffer = slice;
644         decoder->video = video;
645         decoder->decode_slice();
646         video->put_slice_buffer(slice);
647 #endif
648         slice = 0;
649       }
650 //zmsgs("trk=%d, pos=0x%04x,size=0x%04x,length=0x%04x, cur_pos 0x%012lx/0x%012lx, tcode=0x%08x\n",
651 // track_number, demuxer->zdata.position, demuxer->zdata.size, demuxer->zdata.length(),
652 // prev_offset, curr_offset, tcode);
653       switch( tcode ) {
654       case GOP_START_CODE:
655       case PICTURE_START_CODE:
656         if( !video->found_seqhdr ) continue;
657         /* else fall through */
658       case SEQUENCE_START_CODE:
659         /* save start of packet, data before prev_data_size from prev_offset */
660         if( prev_frame_offset == -1 )
661           prev_frame_offset = demuxer->zdata.position < prev_data_size ?
662             prev_offset : curr_offset;
663         video->vstream->reset(tcode);
664         break;
665       default:
666         continue;
667       }
668
669       /* Wait for decoders to finish */
670       if( video->slice_active_locked ) {
671         video->slice_active.lock();
672         video->slice_active.unlock();
673       }
674  
675       if( total_frame_offsets-1 > video->framenum ) { 
676         video->framenum = total_frame_offsets-1;
677         update_video_time();
678         if( video->framenum >= 0 ) {
679           int64_t last_frame_offset = frame_offsets[video->framenum];
680           while( video->video_pts_padding() ) {
681             append_frame(last_frame_offset, 0);
682             video->framenum = total_frame_offsets-1;
683           }
684         }
685         if( video->video_pts_skipping() )
686           continue;
687         update_frame_pts();
688       }
689       /* if last frame was P-Frame after I-Frame show thumbnail */
690       if( video->thumb && video->decoder_initted ) {
691         switch( video->pict_type ) {
692         case video_t::pic_type_P:
693           if( !video->ithumb ) break;
694           video->ithumb = 0;
695           zsrc->thumbnail_fn(zsrc->thumbnail_priv, track_number);
696           break;
697         case video_t::pic_type_I:
698           video->ithumb = 1;
699           break;
700         }
701       }
702     }
703
704     /* Use video decoder to get repeat count and field type. */
705     /* Should never hit EOF in here.  This rereads up to the current ptr */
706     /* since zdata.position isn't updated by handle_video. */
707     /* if get_header fails, try this offset again with more data */
708     int data_position = demuxer->zdata.position;
709     int have_seqhdr = video->found_seqhdr;
710     int32_t repeat_data = video->repeat_data;
711     if( video->get_header() ) {
712       if( video->found_seqhdr ) {
713         /* try again with more data */
714         demuxer->last_code = tcode;
715         demuxer->zdata.position = data_position;
716       }
717       video->found_seqhdr = have_seqhdr;
718       video->repeat_data = repeat_data;
719       break;
720     }
721
722     if( !video->decoder_initted ) {
723       video->init_decoder();
724       width = video->horizontal_size;
725       height = video->vertical_size;
726       frame_rate = video->frame_rate;
727     }
728
729     /* check for video starting past first cell */
730     if( !have_seqhdr && zsrc->pts_padding > 0 &&
731         video_time < 0 && zsrc->cell_time >= 0. ) {
732       video_time = zsrc->cell_time;
733       pts_position = 0;
734       if( pts_starttime < 0. ) {
735         pts_offset = zsrc->cell_time;
736         pts_starttime = 0.;
737       }
738     }
739
740     video->secondfield = 0;
741     if( video->pict_struct != video_t::pics_FRAME_PICTURE ) {
742       if( video->got_top || video->got_bottom )
743         video->secondfield = 1;
744     }
745     
746     int field = video->secondfield ? 2 : 1;
747     if( video->pict_struct == video_t::pics_TOP_FIELD )
748       video->got_top = field;
749     else if( video->pict_struct == video_t::pics_BOTTOM_FIELD )
750       video->got_bottom = field;
751
752     if( video->pict_struct == video_t::pics_FRAME_PICTURE ||
753         video->secondfield || !video->pict_struct ) {
754 //zmsgs("video pid %02x framenum %d video_time %12.5f %c 0x%012lx rep %d\n",
755 //  pid, video->framenum, get_video_time(), "XIPBD"[video->pict_type],
756 //  prev_frame_offset, video->repeat_fields-2);
757       if( video->pict_type == video_t::pic_type_I )
758         got_keyframe = 1;
759       append_frame(prev_frame_offset, got_keyframe);
760       /* Add entry for every repeat count. */
761       video->current_field += 2;
762       while( video->repeat_fields-video->current_field >= 2 ) {
763         append_frame(prev_frame_offset, 0);
764         video->current_field += 2;
765       }
766       if( (video->repeat_fields-=video->current_field) < 0 )
767         video->repeat_fields = 0;
768       /* Shift out data from before frame */
769       prev_frame_offset = -1;
770       got_keyframe = 0;
771     }
772     else {
773       // This was a TOP/BOTTOM FIELD and was not secondfield
774       // Shift out data from this field
775       if( video->pict_type == video_t::pic_type_I )
776         got_keyframe = 1;
777       video->current_field += 2;
778     }
779     tcode = video->vstream->show_bits(32);
780     if( !video->repeat_fields ) video->current_field = 0;
781     demuxer->last_code = 0;
782   }
783   return 0;
784 }
785
786 int zvtrack_t::
787 handle_video(int track_number)
788 {
789   zmpeg3_t *zsrc = video->src;
790   demuxer_t *demux = zsrc->demuxer;
791   /* Assume last packet of stream */
792   video_eof = demux->tell_byte();
793   int prev_data_size = demuxer->zdata.size;
794 //zmsgs("%d %d %02x %02x %02x %02x %02x %02x %02x %02x\n", 
795 // demux->zvideo.size, demux->zdata.size,
796 // demux->zvideo.buffer[0], demux->zvideo.buffer[1],
797 // demux->zvideo.buffer[2], demux->zvideo.buffer[3],
798 // demux->zvideo.buffer[4], demux->zvideo.buffer[5],
799 // demux->zvideo.buffer[6], demux->zvideo.buffer[7]);
800
801 #ifdef DATA_DUMP
802 if( !video_fp ) {
803   video_fp = new FILE*[65536];
804   memset(video_fp,0,65536*sizeof(FILE*));
805 }
806 if( !video_fp[pid] ) {
807   char fn[512];
808   sprintf(fn,"/tmp/dat/v%04x.mpg",pid);
809   video_fp[pid] = fopen(fn,"w");
810 }
811 if( video_fp[pid] ) {
812   if( demux->zvideo.size )
813     fwrite(demux->zvideo.buffer, demux->zvideo.size, 1, video_fp[pid]);
814   else if( demux->zdata.size )
815     fwrite(demux->zdata.buffer, demux->zdata.size, 1, video_fp[pid]);
816 }
817 #endif
818
819   /* Append demuxed data to track buffer */
820   if( demux->zvideo.size )
821     demuxer->append_data(demux->zvideo.buffer, demux->zvideo.size);
822   else if( demux->zdata.size )
823     demuxer->append_data(demux->zdata.buffer, demux->zdata.size);
824   if( demux->pes_video_pid == pid && demux->pes_video_time >= 0 ) {
825     demuxer->pes_video_time = demux->pes_video_time;
826     demux->pes_video_time = -1.;
827   }
828 #if 0
829   if( !test_file ) test_file = fopen("/tmp/test.m2v", "w");
830   if( demuxer->zdata.position > 0 ) fwrite(demuxer->zdata.buffer,
831            demuxer->zdata.position, 1, test_file);
832 #endif
833
834   handle_video_data(track_number, prev_data_size);
835   demuxer->shift_data();
836   return 0;
837 }
838
839 void zmpeg3_t::
840 handle_subtitle()
841 {
842   for( int i=0; i<total_stracks; ++i ) {
843     strack_t *strk = get_strack(i);
844     while( strk->total_subtitles ) {
845       subtitle_t *subtitle = strk->subtitles[0];
846       strk->append_subtitle_offset(subtitle->offset);
847       strk->del_subtitle(subtitle);
848     }
849   }
850 }
851
852 void zmpeg3_t::
853 handle_cell(int cell_no)
854 {
855   int idx;
856   cell_time = -1.;
857
858 //zmsgs("cell %d\n", cell_no);
859   for( idx=0; idx<total_vtracks; ++idx ) {
860     zvtrack_t *vtrk = vtrack[idx];
861     zvideo_t *vid = vtrk->video;
862     if( !vid ) continue;
863     double pts = vtrk->get_video_time();
864 //zmsgs("  vtrack %d = %f\n", idx, pts);
865     if( cell_time < pts ) cell_time = pts;
866   }
867   for( idx=0; idx<total_atracks; ++idx ) {
868     zatrack_t *atrk = atrack[idx];
869     zaudio_t *aud = atrk->audio;
870     if( !aud ) continue;
871     double pts = atrk->get_audio_time();
872 //zmsgs("  atrack %d = %f\n", idx, pts);
873     if( cell_time < pts ) cell_time = pts;
874   }
875
876   zcell_t *cell = 0;
877   if( !demuxer->get_cell(cell_no, cell) )
878     cell->cell_time = cell_time;
879   if( pts_padding <= 0 ) return;
880
881   int discon = cell ? cell->discontinuity : 0;
882 //zmsgs("cell %d cell_time=%f pos=%jx discon %d\n",
883 //  cell_no, cell_time, !cell? -1 : cell->program_start, discon);
884   if( !discon ) return;
885
886   for( idx=0; idx<total_vtracks; ++idx ) {
887     zvtrack_t *vtrk = vtrack[idx];
888     zvideo_t *vid = vtrk->video;
889     if( !vid ) continue;
890     if( !vtrk->total_frame_offsets ) continue;
891     vtrk->video_time = cell_time;
892     vid->framenum = vtrk->pts_position = vtrk->total_frame_offsets-1;
893     if( vid->framenum >= 0 ) {
894       int64_t prev_frame_offset = vtrk->frame_offsets[vid->framenum];
895       while( vid->video_pts_padding() ) {
896         vtrk->append_frame(prev_frame_offset, 0);
897         vid->framenum = vtrk->total_frame_offsets-1;
898       }
899     }
900     if( discon ) {
901       vtrk->reset_pts();
902       vtrk->pts_offset = cell_time;
903       if( discon < 0 ) vtrk->pts_starttime = 0.;
904     }
905   }
906
907   for( idx=0; idx<total_atracks; ++idx ) {
908     zatrack_t *atrk = atrack[idx];
909     zaudio_t *aud = atrk->audio;
910     if( !aud ) continue;
911     atrk->audio_time = cell_time;
912     atrk->pts_position = aud->audio_position();
913     while( aud->audio_pts_padding() ) {
914       if( update_index(idx, 0) )
915         atrk->prev_offset = atrk->curr_offset;
916     }
917     if( discon ) {
918       atrk->reset_pts();
919       atrk->pts_offset = cell_time;
920       if( discon < 0 ) atrk->pts_starttime = 0.;
921     }
922   }
923 }
924
925 int zmpeg3_t::
926 handle_nudging()
927 {
928   int i, n, atrk, vtrk;
929   int ret = 0;
930   for( i=0; i<total_atracks; ++i )
931     atrack[i]->nudge = 0;
932
933   int total_channels = dvb.channel_count();
934 #if 1
935 // lines up first apts/vpts
936   for( n=0; n<total_channels; ++n ) {
937     int astreams, vstreams;
938     dvb.total_vstreams(n, vstreams);
939     double apts = -1., vpts = -1.;
940     for( i=0; i<vstreams; ++i ) {
941       dvb.vstream_number(n, i, vtrk);
942       if( vtrack[vtrk]->pts_origin > vpts )
943         vpts = vtrack[vtrk]->pts_origin;
944     }
945     dvb.total_astreams(n, astreams);
946     for( i=0; i<astreams; ++i ) {
947       dvb.astream_number(n, i, atrk);
948       double samplerate = sample_rate(atrk);
949       if( samplerate < 0. ) samplerate = 0.;
950       apts = atrack[atrk]->pts_origin;
951       if( apts >= 0. && vpts >= 0. ) {
952         atrack[atrk]->nudge = (long)((vpts - apts) * samplerate);
953         ++ret;
954       }
955     }
956   }
957 #else
958 // lines up nearest apts/vpts
959   class elem_t {
960   public:
961     elem_t *next;  int vtrk, atrk;
962     double apts, vpts, pts_nudge;
963     uint64_t apos, vpos, pts_dist;
964     elem_t(elem_t *p, int vtrk, int atrk)
965     : next(p), vtrk(vtrk), atrk(atrk) {
966       apos = vpos = 0; apts = vpts = 0.;
967       pts_dist = ~0;   pts_nudge = 0;
968     }
969   } *ep, *elems = 0;
970   // collect all vtrk[0]-atrk[i] associations
971   for( n=0; n<total_channels; ++n ) {
972     int astreams, vstreams;
973     dvb.total_vstreams(n, vstreams);
974     if( vstreams <= 0 ) continue;
975     dvb.vstream_number(n, 0, vtrk);
976     if( vtrk < 0 || vtrk >= total_vtracks ) continue;
977     dvb.total_astreams(n, astreams);
978     for( i=0; i<astreams; ++i ) {
979       dvb.astream_number(n, i, atrk);
980       if( atrk < 0 || atrk >= total_atracks ) continue;
981       elems = new elem_t(elems, vtrk, atrk);
982     }
983   }
984
985   demuxer->pes_audio_time = -1.;
986   demuxer->pes_video_time = -1.;
987   demuxer->seek_byte(START_BYTE);
988
989   // probe for atrk/vtrk pts nearest to each other in file
990   while( !demuxer->titles[0]->fs->eof() ) {
991     int64_t pos = demuxer->absolute_position();
992     if( pos > START_BYTE + MAX_TS_PROBE ) break;
993     if( demuxer->read_next_packet() ) break;
994     ep = 0;
995     if( demuxer->pes_audio_time >= 0 ) {
996       for( ep=elems; ep && atrack[ep->atrk]->pid!=demuxer->pid; ep=ep->next );
997       if( ep ) { ep->apos = pos; ep->apts = demuxer->pes_audio_time; }
998       demuxer->pes_audio_time = -1.;
999     }
1000     if( demuxer->pes_video_time >= 0 ) {
1001       for( ep=elems; ep && vtrack[ep->vtrk]->pid!=demuxer->pid; ep=ep->next );
1002       if( ep ) { ep->vpos = pos; ep->vpts = demuxer->pes_video_time; }
1003       demuxer->pes_video_time = -1.;
1004     }
1005     if( !ep || !ep->apos || !ep->vpos ) continue;
1006     int64_t dist = ep->apos - ep->vpos;
1007     if( dist < 0 ) dist = -dist;
1008     if( (uint64_t)dist < ep->pts_dist ) {
1009       ep->pts_dist = dist;
1010       ep->pts_nudge = ep->vpts - ep->apts;
1011     }
1012   }
1013
1014   // nudge audio to align timestamps
1015   while( elems ) {
1016     ep = elems;  elems = elems->next;
1017 //zmsgs("v/atrk %d/%d, dist %jd\n", ep->vtrk, ep->atrk, ep->pts_dist);
1018 //zmsgs("   v/apts %f/%f, nudge %f\n", ep->vpts, ep->apts, ep->pts_nudge);
1019 //zmsgs("   v/aorg %f/%f, nudge %f\n",
1020 // vtrack[ep->vtrk]->pts_origin, atrack[ep->atrk]->pts_origin,
1021 // vtrack[ep->vtrk]->pts_origin-atrack[ep->atrk]->pts_origin);
1022     double samplerate = sample_rate(ep->atrk);
1023     if( samplerate < 0. ) samplerate = 0.;
1024     if( ep->apts >= 0. && ep->vpts >= 0. ) {
1025       atrack[ep->atrk]->nudge = (long)(ep->pts_nudge * samplerate);
1026       ++ret;
1027     }
1028     delete ep;
1029   }
1030 #endif
1031   return ret;
1032 }
1033
1034 int zmpeg3_t::
1035 do_toc(int64_t *bytes_processed)
1036 {
1037   /* Starting byte before our packet read */
1038   int64_t start_byte = demuxer->tell_byte();
1039 //zmsgs("%d offset=%llx file_type=%x\n", __LINE__, 
1040 //  start_byte, file_type);
1041   int result = demuxer->seek_phys();
1042   if( !result ) {
1043     int cell_no = demuxer->current_cell_no();
1044     if( last_cell_no != cell_no )
1045       handle_cell(last_cell_no=cell_no);
1046     result = demuxer->read_next_packet();
1047   }
1048 //zmsgs("%d %d %llx\n", __LINE__, result, demuxer->tell_byte());
1049   /* if(start_byte > 0x1b0000 && start_byte < 0x1c0000) */
1050 //zmsgs("1 start_byte=%llx custum_id=%x got_audio=%d got_video=%d"
1051 //      " zaudio.size=%d zvideo.size=%d zdata.size=%d\n", start_byte, 
1052 // demuxer->custom_id, demuxer->got_audio, demuxer->got_video,
1053 // demuxer->zaudio.size, demuxer->zvideo.size, demuxer->zdata.size);
1054   if( !result ) {
1055     int idx = 0;
1056     /* Find current PID in tracks. */
1057     /* Got subtitle */
1058     if( demuxer->got_subtitle )
1059       handle_subtitle();
1060     if( is_transport_stream() )
1061       dvb.atsc_tables(demuxer, demuxer->custom_id);
1062      /* In a transport stream the audio or video is determined by the PID. */
1063      /* In other streams the data type is determined by stream ID. */
1064     if( demuxer->got_audio >= 0 || is_transport_stream() || is_audio_stream() ) {
1065       int audio_pid = is_transport_stream() ? demuxer->custom_id : demuxer->got_audio;
1066       atrack_t *atrk = 0;
1067       for( idx=0; idx < total_atracks; ++idx ) {
1068         if( atrack[idx]->pid == audio_pid ) { /* Update an audio track */
1069           atrk = atrack[idx];
1070           break;
1071         }
1072       }
1073       if( !atrk ) {
1074         if( is_audio_stream() ||
1075             (audio_pid >= 0 && demuxer->astream_table[audio_pid]) ) {
1076           int format = demuxer->astream_table[audio_pid];
1077           atrk = new_atrack_t(audio_pid, format, demuxer, total_atracks);
1078           if( atrk ) {
1079             atrack[idx=total_atracks++] = atrk;
1080             atrk->prev_offset = start_byte;
1081           }
1082         }
1083       }
1084       if( atrk ) {
1085         atrk->curr_offset = start_byte;
1086         atrk->handle_audio(idx);
1087       }
1088     }
1089     if( demuxer->got_video >= 0 || is_transport_stream() || is_video_stream() ) {
1090       int video_pid = is_transport_stream() ? demuxer->custom_id : demuxer->got_video;
1091       vtrack_t *vtrk = 0;
1092       for( idx=0; idx < total_vtracks; ++idx ) {
1093         if( vtrack[idx]->pid == video_pid ) { /* Update a video track */
1094           vtrk = vtrack[idx];
1095           break;
1096         }
1097       }
1098       if( !vtrk ) {
1099         if( is_video_stream() ||
1100             (video_pid >= 0 && demuxer->vstream_table[video_pid]) ) {
1101           vtrk = new_vtrack_t(video_pid, demuxer, total_vtracks);
1102           /* Make the first offset correspond to the */
1103           /*  start of the first packet. */
1104           if( vtrk ) {
1105             vtrack[total_vtracks++] = vtrk;
1106             vtrk->tcode = ~0;
1107             vtrk->prev_frame_offset = -1;
1108             vtrk->curr_offset = start_byte;
1109             if( thumbnail_fn )
1110               vtrk->video->thumb = vtrk->video->skim = 1;
1111           }
1112         }
1113       }
1114       if( vtrk ) {
1115         vtrk->prev_offset = vtrk->curr_offset;
1116         vtrk->curr_offset = start_byte;
1117         vtrk->handle_video(idx);
1118       }
1119     }
1120   }
1121   /* Make user value independant of data type in packet */
1122   *bytes_processed = demuxer->tell_byte();
1123 //zmsgs("1000 %jx\n", *bytes_processed);
1124   return 0;
1125 }
1126
1127 void zmpeg3_t::
1128 stop_toc()
1129 {
1130   delete_slice_decoders();
1131   if( !is_ifo_file() ) {
1132     int64_t total_bytes = demuxer->tell_byte();
1133     demuxer->end_title(total_bytes);
1134   }
1135   /* Create final chunk for audio tracks to count the last samples. */
1136   int i, j, k;
1137   atrack_t *atrk;
1138   index_t *idx;
1139   /* Flush audio indexes */
1140   for( i=0; i < total_atracks; ++i )
1141     update_index(i, 1);
1142   for( i=0; i < total_atracks; ++i ) {
1143     atrk = atrack[i];
1144     atrk->append_samples(atrk->curr_offset);
1145   }
1146
1147   /* Make all indexes the same scale */
1148   int max_scale = 1;
1149   for( i=0; i < total_atracks; ++i ) {
1150     atrk = atrack[i];
1151     idx = indexes[i];
1152     if( idx->index_data && idx->index_zoom > max_scale )
1153       max_scale = idx->index_zoom;
1154   }
1155   for( i=0; i < total_atracks; ++i ) {
1156     atrk = atrack[i];
1157     idx = indexes[i];
1158     if( idx->index_data && idx->index_zoom < max_scale ) {
1159       while( idx->index_zoom < max_scale )
1160         divide_index(i);
1161     }
1162   }
1163   /* delete vtracks with no frames */
1164   for( i=0; i < total_vtracks; ) {
1165     if( !vtrack[i]->total_frame_offsets ) {
1166       demuxer->vstream_table[vtrack[i]->pid] = 0;
1167       delete vtrack[i];
1168       --total_vtracks;
1169       for( j=i; j < total_vtracks; ++j )
1170         vtrack[j] = vtrack[j+1];
1171       continue;
1172     }
1173     ++i;
1174   }
1175   for( i=0; i < MAX_STREAMZ; ++i ) {
1176     if( demuxer->vstream_table[i] ) {
1177       for( j=total_vtracks; --j>=0; )
1178         if( vtrack[j]->pid == i ) break;
1179       if( j < 0 )
1180         demuxer->vstream_table[i] = 0;
1181     }
1182   }
1183   /* delete atracks with no samples */
1184   for( i=0; i < total_atracks; ) {
1185     if( !atrack[i]->total_sample_offsets || atrack[i]->format == afmt_IGNORE ) {
1186       demuxer->astream_table[atrack[i]->pid] = 0;
1187       delete atrack[i];  delete indexes[i];
1188       --total_atracks; --total_indexes;
1189       for( j=i; j < total_atracks; ++j ) {
1190         indexes[j] = indexes[j+1];
1191         atrack[j] = atrack[j+1];
1192       }
1193       continue;
1194     }
1195     ++i;
1196   }
1197   for( i=0; i < MAX_STREAMZ; ++i ) {
1198     if( demuxer->astream_table[i] ) {
1199       for( j=total_atracks; --j>=0; )
1200         if( atrack[j]->pid == i ) break;
1201       if( j < 0 )
1202         demuxer->astream_table[i] = 0;
1203     }
1204   }
1205   /* Sort tracks by PID */
1206   int done = 0;
1207   while( !done ) {
1208     done = 1;
1209     for( i=1; i < total_atracks; ++i ) {
1210       atrack_t *atrk0 = atrack[i - 0];
1211       atrack_t *atrk1 = atrack[i - 1];
1212       if( atrk1->pid > atrk0->pid ) {
1213         atrack[i - 1] = atrk0;
1214         atrack[i - 0] = atrk1;
1215         index_t *idx0 = indexes[i - 0];
1216         index_t *idx1 = indexes[i - 1];
1217         indexes[i - 1] = idx0;
1218         indexes[i - 0] = idx1;
1219         done = 0;
1220       }
1221     }
1222   }
1223   for( i=0; i < total_atracks; ++i )
1224     atrack[i]->number = i;
1225   done = 0;
1226   while( !done ) {
1227     done = 1;
1228     for( i=1; i < total_vtracks; ++i ) {
1229       vtrack_t *vtrk0 = vtrack[i - 0];
1230       vtrack_t *vtrk1 = vtrack[i - 1];
1231       if( vtrk1->pid > vtrk0->pid ) {
1232         vtrack[i - 1] = vtrk0;
1233         vtrack[i - 0] = vtrk1;
1234         done = 0;
1235       }
1236     }
1237   }
1238   for( i=0; i < total_vtracks; ++i )
1239     vtrack[i]->number = i;
1240
1241   if( is_transport_stream() )
1242     handle_nudging();
1243
1244   demuxer->read_all = 0;
1245
1246   /* Output toc to file */
1247   /* Write file type */
1248   fputc('T', toc_fp);
1249   fputc('O', toc_fp);
1250   fputc('C', toc_fp);
1251   fputc(' ', toc_fp);
1252   /* Write version */
1253   PUT_INT32(TOC_VERSION);
1254   /* Write program */
1255   PUT_INT32(toc_SRC_PROGRAM);
1256   PUT_INT32(vts_title);
1257   PUT_INT32(total_vts_titles);
1258   PUT_INT32(angle*10 + interleave);
1259   PUT_INT32(total_interleaves);
1260   /* Write stream type */
1261   if( is_program_stream() )
1262     PUT_INT32(toc_FILE_TYPE_PROGRAM);
1263   else if( is_transport_stream() )
1264     PUT_INT32(toc_FILE_TYPE_TRANSPORT);
1265   else if( is_audio_stream() )
1266     PUT_INT32(toc_FILE_TYPE_AUDIO);
1267   else if( is_video_stream() )
1268     PUT_INT32(toc_FILE_TYPE_VIDEO);
1269   /* Store file information */
1270   PUT_INT32(toc_FILE_INFO);
1271   char *path = fs->path;
1272   fprintf(toc_fp, "%s", path);
1273   for( j=strlen(path); j < STRLEN; ++j ) fputc(0, toc_fp);
1274   source_date = calculate_source_date(path);
1275   PUT_INT64(source_date);
1276   /* Write stream ID's */
1277   /* Only program and transport streams have these */
1278   for( i=0; i < MAX_STREAMZ; ++i ) {
1279     if( demuxer->astream_table[i] ) {
1280       PUT_INT32(toc_STREAM_AUDIO);
1281       PUT_INT32(i);
1282       PUT_INT32(demuxer->astream_table[i]);
1283     }
1284     if( demuxer->vstream_table[i] ) {
1285       PUT_INT32(toc_STREAM_VIDEO);
1286       PUT_INT32(i);
1287       PUT_INT32(demuxer->vstream_table[i]);
1288     }
1289   }
1290   /* Write titles */
1291   for( i=0; i < demuxer->total_titles; ++i ) {
1292     demuxer_t::title_t *title = demuxer->titles[i];
1293     /* Path */
1294     PUT_INT32(toc_TITLE_PATH);
1295     path = !is_program_stream() ? path : title->fs->path;
1296     fprintf(toc_fp, "%s", path);
1297     for( j=strlen(path); j < STRLEN; ++j ) fputc(0, toc_fp);
1298     /* Total bytes */
1299     PUT_INT64(title->total_bytes);
1300     /* Total cells in title */
1301     PUT_INT32(demuxer->titles[i]->cell_table_size);
1302     for( j=0; j < title->cell_table_size; ++j ) {
1303       demuxer_t::title_t::cell_t *cell = &title->cell_table[j];
1304 //zmsgs("%x: %llx-%llx %llx-%llx %d %d %d\n",
1305 //  ftell(toc_fp), cell->title_start, cell->title_end,
1306 //  cell->program_start, cell->program_end, cell->cell_no,
1307 //  cell->program, cell->discontinuity);
1308       PUT_INT64(cell->title_start);
1309       PUT_INT64(cell->title_end);
1310       PUT_INT64(cell->program_start);
1311       PUT_INT64(cell->program_end);
1312       union { double d; uint64_t u; } cell_time;
1313       cell_time.d = cell->cell_time;
1314       PUT_INT64(cell_time.u);
1315       PUT_INT32(cell->cell_no);
1316       PUT_INT32(cell->discontinuity);
1317     }
1318   }
1319   PUT_INT32(toc_ATRACK_COUNT);
1320   PUT_INT32(total_atracks);
1321   /* Audio streams */
1322   for( j=0; j < total_atracks; ++j ) {
1323     atrack_t *atrk = atrack[j];
1324     PUT_INT64(atrk->audio_eof);
1325     PUT_INT32(atrk->channels);
1326     PUT_INT32(atrk->nudge);
1327     PUT_INT32(atrk->total_sample_offsets);
1328     /* Total samples */
1329     PUT_INT64(atrk->current_position);
1330     /* Sample offsets */
1331     for( i=0; i < atrk->total_sample_offsets; ++i )
1332       PUT_INT64(atrk->sample_offsets[i]);
1333     /* Index */
1334     index_t *idx = indexes[j];
1335     if( idx->index_data ) {
1336       PUT_INT32(idx->index_size);
1337       PUT_INT32(idx->index_zoom);
1338       for( k=0; k < atrk->channels; ++k ) {
1339         fwrite(idx->index_data[k], 2*sizeof(float), 
1340             idx->index_size, toc_fp);
1341       }
1342     }
1343     else {
1344       PUT_INT32(0);
1345       PUT_INT32(1);
1346     }
1347   }
1348   PUT_INT32(toc_VTRACK_COUNT);
1349   PUT_INT32(total_vtracks);
1350   /* Video streams */
1351   for( j=0; j < total_vtracks; ++j ) {
1352     vtrack_t *vtrk = vtrack[j];
1353     PUT_INT64(vtrk->video_eof);
1354     PUT_INT32(vtrk->total_frame_offsets);
1355     for( i=0; i < vtrk->total_frame_offsets; ++i )
1356       PUT_INT64(vtrk->frame_offsets[i]);
1357     PUT_INT32(vtrk->total_keyframe_numbers);
1358     for( i=0; i < vtrk->total_keyframe_numbers; ++i )
1359       PUT_INT32(vtrk->keyframe_numbers[i]);
1360   }
1361   PUT_INT32(toc_STRACK_COUNT);
1362   PUT_INT32(total_stracks);
1363   /* Subtitle tracks */
1364   for( i=0; i < total_stracks; ++i ) {
1365     strack_t *strk = strack[i];
1366     PUT_INT32(strk->id);
1367     PUT_INT32(strk->total_offsets);
1368     for(j = 0; j < strk->total_offsets; j++)
1369       PUT_INT64(strk->offsets[j]);
1370   }
1371   PUT_INT32(toc_IFO_PALETTE);
1372   for( i=0; i < 16*4; ++i )
1373     fputc(palette[i], toc_fp);
1374   if( playinfo ) {
1375     PUT_INT32(toc_IFO_PLAYINFO);
1376     PUT_INT32(playinfo->total_cells);
1377     icell_t *cell = &playinfo->cells[0];
1378     for( i=playinfo->total_cells; --i>=0; ++cell ) {
1379       PUT_INT64(cell->start_byte);
1380       PUT_INT64(cell->end_byte);
1381       PUT_INT32(cell->vob_id);
1382       PUT_INT32(cell->cell_id);
1383       PUT_INT32(cell->inlv);
1384       PUT_INT32(cell->discon);
1385     }
1386   }
1387
1388   fs->close_file();
1389   fclose(toc_fp);
1390   delete this;
1391 }
1392
1393 int zmpeg3_t::
1394 show_toc(int flags)
1395 {
1396   int i, j, k;
1397   int64_t current_byte = 0;
1398
1399   fs->seek(0);
1400   fs->read_uint32();
1401   uint32_t toc_version = fs->read_uint32();
1402   if( toc_version != TOC_VERSION ) {
1403     zmsgs("invalid TOC version %08x (should be %08x)\n", 
1404       toc_version, TOC_VERSION);
1405     return ERR_INVALID_TOC_VERSION;
1406   }
1407
1408   while( !fs->eof() ) {
1409   /* Get section type */
1410     int section_type = fs->read_uint32();
1411     switch( section_type ) {
1412       case toc_FILE_TYPE_PROGRAM:
1413         zmsg("is_program_stream\n");
1414         break;
1415
1416       case toc_FILE_TYPE_TRANSPORT:
1417         zmsg("is_transport_stream\n");
1418         break;
1419
1420       case toc_FILE_TYPE_AUDIO:
1421         zmsg("is_audio_stream\n");
1422         break;
1423
1424       case toc_FILE_TYPE_VIDEO:
1425         zmsg("is_video_stream\n");
1426         break;
1427
1428       case toc_FILE_INFO: {
1429         char string[STRLEN];
1430         char string2[STRLEN];
1431         fs->read_data((uint8_t*)&string[0],STRLEN);
1432         concat_path(string2, fs->path, string);
1433         int64_t sdate = fs->read_uint64();
1434         zmsgs("zsrc=%s source_date=%jd\n", string2, sdate);
1435         break; }
1436
1437       case toc_STREAM_AUDIO: {
1438         static const char *afmts[] = {
1439           "unknown", "mpeg", "ac3", "pcm", "aac", "jesus",
1440         };
1441         int n = fs->read_uint32();
1442         int fmt = fs->read_uint32();
1443         if( fmt < 0 || fmt >= lengthof(afmts) ) fmt = 0;
1444         zmsgs("  audio stream 0x%04x is %s\n", n, afmts[fmt]);
1445         break; }
1446
1447       case toc_STREAM_VIDEO: {
1448         int n = fs->read_uint32();
1449         fs->read_uint32();
1450         zmsgs("  video stream 0x%04x\n", n);
1451         break; }
1452
1453
1454       case toc_ATRACK_COUNT: {
1455         zmsg("\n");
1456         int atracks = fs->read_uint32();
1457         zmsgs("audio tracks = %d\n", atracks);
1458         for( i=0; i < atracks; ++i ) {
1459           int64_t eof = fs->read_uint64();
1460           int channels = fs->read_uint32();
1461           int nudge = fs->read_uint32();
1462           int total_sample_offsets = fs->read_uint32();
1463           int64_t total_samples = fs->read_uint64();
1464           zmsgs(" audio %d, eof=0x%012jx ch=%d, offsets=%d samples=%jd nudge=%d\n",
1465             i, eof, channels, total_sample_offsets, total_samples, nudge);
1466           if( flags & show_toc_SAMPLE_OFFSETS ) {
1467             for( j=0; j < total_sample_offsets; ) {
1468               if( !(j&7) ) zmsgs(" %8d: ",j*AUDIO_CHUNKSIZE);
1469               printf(" %08jx", fs->read_uint64());
1470               if( !(++j&7) ) printf("\n");
1471             }
1472             if( (j&7) ) printf("\n");
1473           }
1474           else
1475             fs->seek_relative(sizeof(int64_t) * total_sample_offsets);
1476           int index_size = fs->read_uint32();
1477           int index_zoom = fs->read_uint32();
1478           zmsgs(" index_size=%d index_zoom=%d\n", index_size, index_zoom);
1479           for( j=0; j < channels; ++j ) {
1480             if( flags & show_toc_AUDIO_INDEX ) {
1481               zmsgs("audio track %d, channel %d\n",i,j);
1482               for( k=0; k<index_size; ) {
1483                 union { int i; float f; } min, max;
1484                 min.i = bswap_32(fs->read_uint32());
1485                 max.i = bswap_32(fs->read_uint32());
1486                 if( !(k&3) ) zmsgs(" %08x: ",k*index_zoom);
1487                 printf(" %5.3f/%-5.3f",min.f,max.f);
1488                 if( !(++k&3) ) printf("\n");
1489               }
1490               if( (k&3) ) printf("\n");
1491             }
1492             else
1493               fs->seek_relative(sizeof(float) * index_size * 2);
1494           }
1495         }
1496         break; }
1497
1498       case toc_VTRACK_COUNT: {
1499         zmsg("\n");
1500         int vtracks = fs->read_uint32();
1501         zmsgs("video tracks = %d\n", vtracks);
1502         for( i=0; i < vtracks; ++i ) {
1503           int64_t eof = fs->read_uint64();
1504           int total_frame_offsets = fs->read_uint32();
1505           if( flags & show_toc_FRAME_OFFSETS ) {
1506             int64_t *frame_offsets = new int64_t[total_frame_offsets];
1507             for( k=0; k<total_frame_offsets; ++k ) {
1508               frame_offsets[k] = fs->read_uint64();
1509             }
1510             int total_keyframes = fs->read_uint32();
1511             zmsgs(" video %d, eof=0x%012jx offsets=%d keyframes=%d\n",
1512               i, eof, total_frame_offsets, total_keyframes);
1513             int *keyframe_numbers = new int[total_keyframes];
1514             for( j=0; j<total_keyframes; ++j ) {
1515               keyframe_numbers[j] = fs->read_uint32();
1516             }
1517             for( j=k=0; k<total_frame_offsets; ) {
1518               if( !(k&7) ) zmsgs(" %8d: ",k);
1519               if( k >= keyframe_numbers[j] ) {
1520                 printf(" *");  ++j;
1521               }
1522               else
1523                 printf("  ");
1524               printf("%08jx",frame_offsets[k]);
1525               if( !(++k&7) ) printf("\n");
1526             }
1527             if( (k&7) ) printf("\n");
1528             delete [] keyframe_numbers;
1529             delete [] frame_offsets;
1530           }
1531           else {
1532             fs->seek_relative(sizeof(int64_t) * total_frame_offsets);
1533             int total_keyframes = fs->read_uint32();
1534             zmsgs(" video %d, eof=0x%012jx offsets=%d keyframes=%d\n",
1535               i, eof, total_frame_offsets, total_keyframes);
1536             fs->seek_relative(sizeof(int) * total_keyframes);
1537           }
1538         }
1539         break; }
1540
1541       case toc_STRACK_COUNT: {
1542         total_stracks = fs->read_uint32();
1543         for( i=0; i < total_stracks; ++i ) {
1544           int id = fs->read_uint32();
1545           int total_offsets = fs->read_uint32();
1546           for( j=0; j < total_offsets; ++j ) {
1547             fs->read_uint64();
1548           }
1549           zmsgs(" subtitle %d, id=0x%04x offsets=%d\n",
1550             i, id, total_offsets);
1551         }
1552         break; }
1553
1554       case toc_TITLE_PATH: {
1555         char string[STRLEN];
1556         fs->read_data((uint8_t*)string, STRLEN);
1557         int64_t total_bytes = fs->read_uint64();
1558         int64_t start_byte = current_byte;
1559         int64_t end_byte = start_byte + total_bytes;
1560         current_byte = end_byte;
1561         zmsgs("title %s,\n", &string[0]);
1562         zmsgs(" bytes=0x%012jx, start=0x%012jx, end=0x%012jx\n",
1563           total_bytes, start_byte, end_byte);
1564         int cell_table_size = fs->read_uint32();
1565         for( i=0; i < cell_table_size; ++i ) {
1566           int64_t title_start = fs->read_uint64();
1567           int64_t title_end = fs->read_uint64();
1568           int64_t program_start = fs->read_uint64();
1569           int64_t program_end = fs->read_uint64();
1570           union { double d; uint64_t u; } cell_time;
1571           cell_time.u = fs->read_uint64();
1572           int cell_no = fs->read_uint32();
1573           int discontinuity = fs->read_uint32();
1574           zmsgs("  cell[%2d],  title 0x%012jx-0x%012jx, cell_no %2d, cell_time %5.3f\n",
1575             i, title_start, title_end, cell_no, cell_time.d);
1576           zmsgs("     discon %d program 0x%012jx-0x%012jx\n",
1577             discontinuity, program_start, program_end);
1578         }
1579         break; }
1580
1581       case toc_IFO_PALETTE:
1582         zmsg("\n");
1583         zmsg("palette\n");
1584         for( i=0; i<16/4; ++i ) {
1585           uint32_t rgb0 = fs->read_uint32();
1586           uint32_t rgb1 = fs->read_uint32();
1587           uint32_t rgb2 = fs->read_uint32();
1588           uint32_t rgb3 = fs->read_uint32();
1589           zmsgs(" 0x%08x 0x%08x 0x%08x 0x%08x\n", rgb0, rgb1, rgb2, rgb3);
1590         }
1591         break;
1592
1593       case toc_IFO_PLAYINFO: {
1594         zmsg("\n");
1595         int ncells = fs->read_uint32();
1596         zmsgs("playcells %d\n", ncells);
1597         for( i=0; i<ncells; ++i) {
1598           int64_t start_byte = fs->read_uint64();
1599           int64_t end_byte = fs->read_uint64();
1600           int vob_id = fs->read_uint32();
1601           int cell_id = fs->read_uint32();
1602           int inlv = fs->read_uint32();
1603           int discon = fs->read_uint32();
1604           zmsgs("  cell[%2d], start=0x%012jx, end=0x%012jx discon %d\n",
1605             i, start_byte, end_byte, discon);
1606           zmsgs("             vob_id %d, cell_id %d, inlv %d\n",
1607             vob_id, cell_id, inlv);
1608         }
1609         break;
1610       }
1611
1612       case toc_SRC_PROGRAM: {
1613         int vtitl = fs->read_uint32();
1614         int vtotl = fs->read_uint32();
1615         int inlv = fs->read_uint32();
1616         int tinlv = fs->read_uint32();
1617         zmsgs("vts_title %d\n",vtitl);
1618         zmsgs("total_vts_title %d\n",vtotl);
1619         zmsgs("interleave/angle %d/%d\n",inlv%10,inlv/10);
1620         zmsgs("total_interleaves %d\n",tinlv);
1621         break;
1622       }
1623     }
1624   }
1625
1626   return 0;
1627 }
1628