switch from eclipse to android studio
[goodguy/cinelerra.git] / cinelerra-5.1 / libzmpeg3 / libzmpeg3.C
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <limits.h>
6
7 #include "libzmpeg3.h"
8
9 static uint8_t def_palette[] = { /* better than nothing */
10   0x00, 0x80, 0x80, 0x00, /* black  #000000 */
11   0xff, 0x80, 0x80, 0x00, /* white  #ffffff */
12   0x4c, 0x54, 0xff, 0x00, /* red    #ff0000 */
13   0x96, 0x2b, 0x15, 0x00, /* green  #00ff00 */
14   0x1d, 0xff, 0x6b, 0x00, /* blue   #0000ff */
15   0xe2, 0x00, 0x94, 0x00, /* yellow #ffff00 */
16   0x69, 0xd4, 0xea, 0x00, /* purple #ff00ff */
17   0xb3, 0xab, 0x00, 0x00, /* cyan   #00ffff */
18   0x80, 0x80, 0x80, 0x00, /* grey   #808080 */
19   0xa6, 0x6a, 0xbf, 0x00, /* pink   #ff8080 */
20   0xcb, 0x55, 0x4a, 0x00, /* lime   #80ff80 */
21   0x8e, 0xbf, 0x75, 0x00, /* lavndr #8080ff */
22   0xd9, 0x95, 0x40, 0x00, /* brt cyan   #80ffff */
23   0xb4, 0xaa, 0xb5, 0x00, /* brt purple #ff80ff */
24   0xf1, 0x40, 0x8a, 0x00, /* brt yellow #ffff80 */
25   0xff, 0x80, 0x80, 0x00, /* white  #ffffff */
26 };
27
28 int zmpeg3_t::
29 init(const char *title_path)
30 {
31   cpus = 1;
32   vts_title = 0;
33   total_vts_titles = 1;
34   interleave = angle = 0;
35   total_interleaves = 1;
36   bitfont_t::init_fonts();
37   demuxer = new demuxer_t(this, 0, 0, -1);
38   seekable = 1;  log_errs = getenv("LOG_ERRS") ? 1 : 0;
39   memcpy(&palette[0], &def_palette[0], sizeof(def_palette));
40   char *cp = getenv("PTS_PADDING");
41   pts_padding = cp ? atoi(cp) : 1;
42   index_bytes = 0x300000;
43   cell_time = -1.;
44   recd_fd = -1;
45   iopened = fs->is_open;
46   int ret = !iopened ? fs->open_file() : 0;
47   if( ret == 0 ) {
48     int toc_atracks = INT_MAX;
49     int toc_vtracks = INT_MAX;
50     ret = get_file_type(&toc_atracks, &toc_vtracks, title_path);
51     if( ret == 0 ) {
52       /* Start from scratch */
53       if( !demuxer->total_titles )
54         demuxer->create_title();
55       /* Generate tracks */
56       if( is_transport_stream() || is_program_stream() ) {
57         int i, n;
58         /* Create video tracks */
59         for( i=n=0; i<MAX_STREAMZ && total_vtracks<toc_vtracks; ++i ) {
60           if( demuxer->vstream_table[i] ) {
61             vtrack[total_vtracks] = new_vtrack_t(i, demuxer, n++);
62             if( vtrack[total_vtracks] ) ++total_vtracks;
63           }
64         }
65         /* Create audio tracks */
66         for( i=n=0; i<MAX_STREAMZ && total_atracks<toc_atracks; ++i ) {
67           int format = demuxer->astream_table[i];
68           if( format > 0 ) {
69             atrack[total_atracks] = new_atrack_t(i, format, demuxer, n++);
70             if( atrack[total_atracks] ) ++total_atracks;
71           }
72         }
73         /* Create subtile tracks */
74         for( i=0; i<MAX_STREAMZ; ++i ) {
75           if( demuxer->sstream_table[i] ) {
76             strack[total_stracks] = new strack_t(i);
77             if( strack[total_stracks] ) ++total_stracks;
78           }
79         }
80       }
81       else if( is_video_stream() ) {
82         /* Create video tracks */
83         vtrack[0] = new_vtrack_t(-1, demuxer, 0);
84         if( vtrack[0] ) ++total_vtracks;
85       }
86       else if( is_audio_stream() ) {
87         /* Create audio tracks */
88         atrack[0] = new_atrack_t(-1, afmt_UNKNOWN, demuxer, 0);
89         if( atrack[0] ) ++total_atracks;
90       }
91     }
92     if( (fs->access() & ZIO_SEQUENTIAL) != 0 )
93       set_pts_padding(-1);
94     demuxer->seek_byte(0);
95     restart();
96     if( !iopened )
97       fs->close_file();
98   }
99   allocate_slice_decoders();
100   return ret;
101 }
102
103 void zmpeg3_t::
104 restart()
105 {
106   int i;
107
108   for( i=0; i<total_vtracks; ++i ) {
109     vtrack_t *vtrk = vtrack[i];
110     if( vtrk && vtrk->video ) {
111       vtrk->current_position = 0;
112       vtrk->reset_pts();
113       vtrk->frame_cache->clear();
114       vtrk->video->rewind_video(0);
115     }
116   }
117
118   for( i=0; i<total_atracks; ++i ) {
119     atrack_t *atrk = atrack[i];
120     if( atrk && atrk->audio ) {
121       atrk->current_position = 0;
122       atrk->reset_pts();
123       atrk->audio->output_size = 0;
124       atrk->audio->output_position = 0;
125       atrk->audio->rewind_audio();
126     }
127   }
128
129   fs->restart();
130 }
131
132 zmpeg3_t::
133 zmpeg3_t(const char *path)
134 #ifdef ZDVB
135  : dvb(this)
136 #endif
137 {
138   fs = new fs_t(this, path);
139   cpus = 1;  log_errs = getenv("LOG_ERRS") ? 1 : 0;
140   demuxer = new demuxer_t(this, 0, 0, -1);
141 // for toc generation
142   seekable = 0;
143   memcpy(&palette[0], &def_palette[0], sizeof(def_palette));
144   char *cp = getenv("PTS_PADDING");
145   pts_padding = cp ? atoi(cp) : 1;
146   index_bytes = 0x300000;
147   cell_time = -1.;
148   recd_fd = -1;
149 }
150
151 zmpeg3_t::
152 zmpeg3_t(const char *path, int &ret, int atype, const char *title_path)
153 #ifdef ZDVB
154  : dvb(this)
155 #endif
156 {
157   fs = new fs_t(this, path, atype);
158   ret = init(title_path);
159 }
160
161 zmpeg3_t::
162 zmpeg3_t(int fd, int &ret, int atype)
163 #ifdef ZDVB
164  : dvb(this)
165 #endif
166 {
167   fs = new fs_t(this, fd, atype);
168   ret = init();
169 }
170
171 zmpeg3_t::
172 zmpeg3_t(FILE *fp, int &ret, int atype)
173 #ifdef ZDVB
174  : dvb(this)
175 #endif
176 {
177   fs = new fs_t(this, fp, atype);
178   ret = init();
179 }
180
181 zmpeg3_t::
182 ~zmpeg3_t()
183 {
184   int i;
185   int debug = 0;
186
187   if( debug ) zmsg("0\n");
188   stop_record();
189   delete_slice_decoders();
190
191   if( debug ) zmsg("1\n");
192   for( i=0; i<total_stracks; ++i )
193     delete strack[i];
194   
195   if( debug ) zmsg("2\n");
196   for( i=0; i<total_atracks; ++i )
197     delete atrack[i];
198
199   if( debug ) zmsg("3\n");
200   for( i=0; i<total_vtracks; ++i )
201     delete vtrack[i];
202
203   if( debug ) zmsg("4\n");
204   delete demuxer;
205   delete fs;
206   if( playinfo ) delete playinfo;
207
208   if( debug ) zmsg("5\n");
209   if( frame_offsets ) {
210     for( i=0; i<total_vtracks; ++i ) {
211       delete [] frame_offsets[i];
212       delete [] keyframe_numbers[i];
213     }
214
215     if( debug ) zmsg("6\n");
216     delete [] frame_offsets;
217     delete [] keyframe_numbers;
218     delete [] total_frame_offsets;
219     delete [] total_keyframe_numbers;
220     delete [] video_eof;
221   }
222
223   if( debug ) zmsg("7\n");
224   if( sample_offsets ) {
225     for( i=0; i<total_atracks; ++i )
226       delete [] sample_offsets[i];
227
228     delete [] sample_offsets;
229     delete [] total_sample_offsets;
230   }
231
232   if( debug ) zmsg("8\n");
233   delete [] channel_counts;
234   delete [] nudging;
235   delete [] total_samples;
236   delete [] audio_eof;
237
238   if( debug ) zmsg("9\n");
239   if( indexes ) {
240     for( i=0; i<total_indexes; ++i )
241       delete indexes[i];
242
243     if( debug ) zmsg("10\n");
244     delete [] indexes;
245   }
246   bitfont_t::destroy_fonts();
247 }
248
249
250 zmpeg3_t:: index_t::
251 index_t()
252 {
253   index_zoom = 1;
254 }
255
256 zmpeg3_t:: index_t::
257 ~index_t()
258 {
259   for( int i=0;i<index_channels; ++i )
260     delete [] index_data[i];
261   delete [] index_data;
262 }
263
264 // Return number of tracks in the table of contents
265 int zmpeg3_t::
266 index_tracks()
267 {
268   return total_indexes;
269 }
270
271 // Return number of channels in track
272 int zmpeg3_t::
273 index_channels(int track)
274 {
275   if( track<0 || track>=total_indexes ) return 0;
276   return indexes[track]->index_channels;
277 }
278
279 // Return zoom factor of index
280 int zmpeg3_t::
281 index_zoom()
282 {
283   return !total_indexes ? 0 : indexes[0]->index_zoom;
284 }
285
286 // Number of high/low pairs in a channel of the track
287 int zmpeg3_t::
288 index_size(int track)
289 {
290   if( track<0 || track>=total_indexes ) return 0;
291   int size = indexes[track]->index_size;
292   if( track < total_atracks && atrack[track]->nudge > 0 )
293     size -= atrack[track]->nudge / indexes[0]->index_zoom;
294   return size;
295 }
296
297 // Get data for one index channel
298 float* zmpeg3_t::
299 index_data(int track, int channel)
300 {
301   if( track<0 || track>=total_indexes ) return 0;
302   float *data = indexes[track]->index_data[channel];
303   if( track < total_atracks && atrack[track]->nudge > 0 )
304     data += (atrack[track]->nudge / indexes[0]->index_zoom) * 2;
305   return data;
306 }
307
308 zstrack_t* zmpeg3_t::
309 get_strack_id(int id, video_t *vid) 
310 {
311   for( int i=0; i<total_stracks; ++i ) {
312     strack_t *strk = strack[i];
313     if( strk->video && strk->video != vid ) continue;
314     if( strk->id == id ) return strack[i];
315   }
316   return 0;
317 }
318
319 zstrack_t* zmpeg3_t::
320 get_strack(int number) 
321 {
322   if( number >= total_stracks || number < 0 ) return 0;
323   return strack[number];
324 }
325
326 zstrack_t* zmpeg3_t::
327 create_strack(int id, zvideo_t *vid)
328 {
329   int i, j;
330   strack_t *strk = 0;
331
332   if( !(strk=get_strack_id(id, vid)) ) {
333     strk = new strack_t(id, vid);
334     for( i=0; i<total_stracks; ++i ) { 
335       /* Search for first ID > current id */
336       if( strack[i]->id > id ) {
337         /* Shift back 1 */
338         for( j=total_stracks; --j>=i; )
339           strack[j+1] = strack[j];
340         break;
341       }
342     }
343
344 /* Store in table */
345     strack[i] = strk;
346     ++total_stracks;
347   }
348
349   return strk;
350 }
351
352 int zmpeg3_t::
353 show_subtitle(int stream, int strk)
354 {
355   int result = -1;
356   if( stream>=0 && stream<total_vtracks ) {
357     vtrack_t *vtrk = vtrack[stream];
358     if( vtrk && vtrk->video )
359       result = vtrk->video->show_subtitle(strk);
360   }
361   return result;
362 }
363
364 static inline int is_toc_(uint32_t bits)
365 {
366   return (bits == zmpeg3_t::TOC_PREFIX);
367 }
368
369
370 static inline int is_ifo_(uint32_t bits)
371 {
372   return (bits == zmpeg3_t::IFO_PREFIX);
373 }
374
375 static inline int is_transport_(uint32_t bits)
376 {
377   return (((bits >> 24) & 0xff) == zmpeg3_t::SYNC_BYTE);
378 }
379
380 static inline int is_bd_(uint32_t bits1, uint32_t bits2, char *ext)
381 {
382   return (((bits2 >> 24) & 0xff) == zmpeg3_t::SYNC_BYTE) && 
383     ( !ext || (ext && 
384       (!strncasecmp(ext, ".m2ts", 5) || 
385        !strncasecmp(ext, ".mts", 4))) );
386 }
387
388 static inline int is_program_(uint32_t bits)
389 {
390   return (bits == zmpeg3_t::PACK_START_CODE);
391 }
392
393 static inline int is_mpeg_audio_(uint32_t bits)
394 {
395   return (bits & 0xfff00000) == 0xfff00000 ||
396          (bits & 0xffff0000) == 0xffe30000 ||
397          ((bits >> 8) == zmpeg3_t::ID3_PREFIX) ||
398          (bits == zmpeg3_t::RIFF_CODE);
399 }
400
401 static inline int is_mpeg_video_(uint32_t bits)
402 {
403   return (bits == zmpeg3_t::SEQUENCE_START_CODE ||
404           bits == zmpeg3_t::PICTURE_START_CODE);
405 }
406
407 static inline int is_ac3_(uint32_t bits)
408 {
409   return (((bits & 0xffff0000) >> 16) == zmpeg3_t::AC3_START_CODE);
410 }
411
412 int zmpeg3_t::
413 check_sig(char *path)
414 {
415   int result = 0;
416   fs_t *fs = new fs_t(0, path);
417
418   if( !fs->open_file() ) { /* File found */
419     char *ext = strrchr(path, '.');
420     uint32_t bits = fs->read_uint32();
421 //  uint32_t bits2 = fs->read_uint32();
422  
423     /* pre-approved suffixes */
424     if( ext && !strncasecmp(ext, ".mp3", 4) ) {
425       result = 1;
426     }
427     /* Test header */
428     else if( bits == TOC_PREFIX ) {
429       result = 1;
430     }
431 /* don't use, does not work well at all */
432 //    /* Blu-Ray or AVC-HD*/
433 //    else if( is_bd_(bits, bits2, ext) ) {
434 //      result = 1;
435 //    }
436     else if( (((bits >> 24) & 0xff) == zmpeg3_t::SYNC_BYTE ) ||
437              (bits == zmpeg3_t::PACK_START_CODE) ||
438              ((bits & 0xfff00000) == 0xfff00000) ||
439              ((bits & 0xffff0000) == 0xffe30000) ||
440              (bits == zmpeg3_t::SEQUENCE_START_CODE) ||
441              (bits == zmpeg3_t::PICTURE_START_CODE) ||
442              (((bits & 0xffff0000) >> 16) == zmpeg3_t::AC3_START_CODE) ||
443              ((bits >> 8) == zmpeg3_t::ID3_PREFIX) || 
444              (bits == zmpeg3_t::RIFF_CODE) ||
445              (bits == zmpeg3_t::IFO_PREFIX)) {
446       result = 1;
447   
448       /* Test file extension. */
449       if( ext ) {  ++ext;
450         if( strcasecmp(ext, "ifo") && 
451             strcasecmp(ext, "mp2") && 
452             strcasecmp(ext, "mp3") &&
453             strcasecmp(ext, "m1v") &&
454             strcasecmp(ext, "m2v") &&
455             strcasecmp(ext, "m2s") &&
456             strcasecmp(ext, "mpg") &&
457             strcasecmp(ext, "vob") &&
458             strcasecmp(ext, "ts") &&
459             strcasecmp(ext, "vts") &&
460             strcasecmp(ext, "mpeg") &&
461             strcasecmp(ext, "m2t") &&
462             strcasecmp(ext, "ac3") )
463           result = 0;
464       }
465     }
466     fs->close_file();
467   }
468
469   delete fs;
470   return result;
471 }
472
473 int zmpeg3_t::
474 calculate_packet_size()
475 {
476   if( is_transport_stream() )
477     return is_bd() ?  BD_PACKET_SIZE : TS_PACKET_SIZE;
478   if( is_program_stream() )
479     return 0;
480   if( is_audio_stream() || is_video_stream() )
481     return DVD_PACKET_SIZE;
482   zerr("undefined stream type.\n");
483   return -1;
484 }
485
486 int zmpeg3_t::
487 get_file_type(int *toc_atracks, int *toc_vtracks, const char *title_path)
488 {
489   int result = 0;
490   file_type = 0;
491   uint32_t bits = fs->read_uint32();
492   uint32_t bits2 = fs->read_uint32();
493
494   /* TOC  */
495   if( is_toc_(bits) ) {
496     /* Table of contents for another title set */
497     result = toc_atracks && toc_vtracks ?
498       read_toc(toc_atracks, toc_vtracks, title_path) : 1;
499     if( result ) fs->close_file();
500   }
501   else if( is_ifo_(bits) ) {
502   /* IFO file */
503     if( !read_ifo() )
504       file_type = FT_PROGRAM_STREAM | FT_IFO_FILE;
505     fs->close_file();
506   }
507   else if( is_bd_(bits,bits2,0) ) {
508     file_type = FT_TRANSPORT_STREAM | FT_BD_FILE;
509   }
510   /* Transport stream */
511   else if( is_transport_(bits) ) {
512     file_type = FT_TRANSPORT_STREAM;
513   }
514   /* Program stream */
515   /* Determine packet size empirically */
516   else if( is_program_(bits) ) {
517     file_type = FT_PROGRAM_STREAM;
518   }
519   /* MPEG Audio only */
520   else if( is_mpeg_audio_(bits) ) {
521     file_type = FT_AUDIO_STREAM;
522   }
523   /* Video only */
524   else if( is_mpeg_video_(bits) ) {
525     file_type = FT_VIDEO_STREAM;
526   }
527   /* AC3 Audio only */
528   else if( is_ac3_(bits) ) {
529     file_type = FT_AUDIO_STREAM;
530   }
531   else {
532     const char *ext = strrchr(fs->path, '.');
533     if( ext ) {
534       if( !strncasecmp(ext, ".mp3", 4) ) {
535         file_type = FT_AUDIO_STREAM;
536       }
537     }
538   }
539 //zmsgs("2 %x\n", file_type);
540   if( !file_type ) {
541     zerr("not a readable stream.\n");
542     if( !result ) result = ERR_UNDEFINED_ERROR;
543   }
544   else
545     packet_size = calculate_packet_size();
546   return result;
547 }
548
549 int zmpeg3_t::
550 set_pts_padding(int v)
551 {
552   int ret = pts_padding;
553   pts_padding = v;
554   if( pts_padding >= 0 ) {
555     for( int vtk=0; vtk<total_vtracks; ++vtk )
556       vtrack[vtk]->pts_starttime = -1.;
557     for( int atk=0; atk<total_atracks; ++atk )
558       atrack[atk]->pts_starttime = -1.;
559   }
560   else {
561     for( int vtk=0; vtk<total_vtracks; ++vtk )
562       vtrack[vtk]->pts_starttime = vtrack[vtk]->pts_offset = 0.;
563     for( int atk=0; atk<total_atracks; ++atk )
564       atrack[atk]->pts_starttime = atrack[atk]->pts_offset = 0.;
565   }
566   return ret;
567 }
568
569 int zmpeg3_t::
570 set_cpus(int cpus)
571 {
572   this->cpus = cpus;
573   int i;
574   for( i=0; i<total_vtracks; ++i )
575     vtrack[i]->video->set_cpus(cpus);
576   return 0;
577 }
578
579 int zmpeg3_t::
580 has_audio()
581 {
582   return total_atracks > 0;
583 }
584
585 int zmpeg3_t::
586 total_astreams()
587 {
588   return total_atracks;
589 }
590
591 int zmpeg3_t::
592 audio_channels(int stream)
593 {
594   return stream>=0 && stream<total_atracks ?
595     atrack[stream]->channels : -1;
596 }
597
598 double zmpeg3_t::
599 sample_rate(int stream)
600 {
601   return stream>=0 && stream<total_atracks ?
602     (double)atrack[stream]->sample_rate : -1.;
603 }
604
605 long zmpeg3_t::
606 get_sample(int stream)
607 {
608   return stream>=0 && stream<total_atracks ?
609     atrack[stream]->current_position : -1;
610 }
611
612 int zmpeg3_t::
613 set_sample(long sample, int stream)
614 {
615   int result = 1;
616   if( stream>=0 && stream<total_atracks ) {
617     atrack_t *atrk = atrack[stream];
618     if( atrk && atrk->audio ) {
619 //zmsgs("1 %d %ld\n", atrk->current_position, sample);
620       if( atrk->current_position != sample ) {
621         atrk->current_position = sample;
622         atrk->audio->seek_sample(sample);
623       }
624       result = 0;
625     }
626   }
627   return result;
628 }
629
630 long zmpeg3_t::
631 audio_nudge(int stream)
632 {
633   long result = 0;
634   if( stream>=0 && stream<total_atracks ) {
635     atrack_t *atrk = atrack[stream];
636     if( atrk ) result = atrk->nudge;
637   }
638   return result;
639 }
640
641 long zmpeg3_t::
642 audio_samples(int stream)
643 {
644   long result = -1;
645   if( stream>=0 && stream<total_atracks ) {
646     atrack_t *atrk = atrack[stream];
647     if( atrk ) result = atrk->total_samples;
648   }
649   return result;
650 }
651
652 const char* zmpeg3_t::
653 audio_format(int stream)
654 {
655   const char *result = 0;
656   if( stream>=0 && stream<total_atracks ) {
657     switch( atrack[stream]->format ) {
658     case afmt_IGNORE:  result = "Ignore";  break;
659     case afmt_UNKNOWN: result = "Unknown"; break;
660     case afmt_MPEG:    result = "MPEG";    break;
661     case afmt_AC3:     result = "AC3";     break;
662     case afmt_PCM:     result = "PCM";     break;
663     case afmt_AAC:     result = "AAC";     break;
664     case afmt_JESUS:   result = "Vorbis";  break;
665     default:           result = "Undef";   break;
666     }
667   }
668   return result;
669 }
670
671 int zmpeg3_t::
672 has_video()
673 {
674   return total_vtracks > 0;
675 }
676
677 int zmpeg3_t::
678 total_vstreams()
679 {
680   return total_vtracks;
681 }
682
683 int zmpeg3_t::
684 video_width(int stream)
685 {
686   int result = -1;
687   if( stream>=0 && stream<total_vtracks ) {
688     vtrack_t *vtrk = vtrack[stream];
689     if( vtrk ) result = vtrk->width;
690   }
691   return result;
692 }
693
694 int zmpeg3_t::
695 video_height(int stream)
696 {
697   int result = -1;
698   if( stream>=0 && stream<total_vtracks ) {
699     vtrack_t *vtrk = vtrack[stream];
700     if( vtrk ) result = vtrk->height;
701   }
702   return result;
703 }
704
705 int zmpeg3_t::
706 coded_width(int stream)
707 {
708   int result = -1;
709   if( stream>=0 && stream<total_vtracks ) {
710     vtrack_t *vtrk = vtrack[stream];
711     if( vtrk )
712       result = vtrk->video->coded_picture_width;
713   }
714   return result;
715 }
716
717 int zmpeg3_t::
718 coded_height(int stream)
719 {
720   int result = -1;
721   if( stream>=0 && stream<total_vtracks ) {
722     vtrack_t *vtrk = vtrack[stream];
723     if( vtrk )
724       result = vtrk->video->coded_picture_height;
725   }
726   return result;
727 }
728
729 int zmpeg3_t::
730 video_pid(int stream)
731 {
732   int result = -1;
733   if( stream>=0 && stream<total_vtracks ) {
734     vtrack_t *vtrk = vtrack[stream];
735     if( vtrk ) result = vtrk->pid;
736   }
737   return result;
738 }
739
740 float zmpeg3_t::
741 aspect_ratio(int stream)
742 {
743   float result = 0.0;
744   if( stream>=0 && stream<total_vtracks ) {
745     vtrack_t *vtrk = vtrack[stream];
746     if( vtrk ) result = vtrk->aspect_ratio;
747   }
748   return result;
749 }
750
751 double zmpeg3_t::
752 frame_rate(int stream)
753 {
754   double result = -1.0;
755   if( stream>=0 && stream<total_vtracks ) {
756     vtrack_t *vtrk = vtrack[stream];
757     if( vtrk ) result = vtrk->frame_rate;
758   }
759   return result;
760 }
761
762 long zmpeg3_t::
763 video_frames(int stream)
764 {
765   long result = -1;
766   if( stream>=0 && stream<total_vtracks ) {
767     vtrack_t *vtrk = vtrack[stream];
768     if( vtrk ) result = vtrk->total_frames;
769   }
770   return result;
771 }
772
773 long zmpeg3_t::
774 get_frame(int stream)
775 {
776   long result = -1;
777   if( stream>=0 && stream<total_vtracks ) {
778     vtrack_t *vtrk = vtrack[stream];
779     if( vtrk ) result = vtrk->current_position;
780   }
781   return result;
782 }
783
784 int zmpeg3_t::
785 set_frame(long frame, int stream)
786 {
787   int result = -1;
788   if( stream>=0 && stream<total_vtracks ) {
789     vtrack_t *vtrk = vtrack[stream];
790     if( vtrk && vtrk->video ) {
791       if( vtrk->current_position != frame ) {
792         vtrk->current_position = frame;
793         vtrk->video->seek_frame(frame);
794       }
795       result = 0;
796     }
797   }
798   return result;
799 }
800
801 int zmpeg3_t::
802 seek_byte(int64_t byte)
803 {
804   int i;
805
806   for( i=0; i<total_vtracks; ++i ) {
807     vtrack_t *vtrk = vtrack[i];
808     if( vtrk && vtrk->video ) {
809       vtrk->current_position = 0;
810       if( byte )
811         vtrk->video->seek_byte(byte);
812       else
813         vtrk->video->rewind_video();
814     }
815   }
816
817   for( i=0; i<total_atracks; ++i ) {
818     atrack_t *atrk = atrack[i];
819     if( atrk && atrk->audio ) {
820       atrk->current_position = 0;
821       atrk->audio->seek_byte(byte);
822     }
823   }
824
825   return 0;
826 }
827
828 int zmpeg3_t::
829 previous_frame(int stream)
830 {
831   int result = 1;
832
833   if( stream>=0 && stream<total_vtracks ) {
834     vtrack_t *vtrk = vtrack[stream];
835     if( vtrk && vtrk->video ) {
836       last_type_read = 2;
837       last_stream_read = stream;
838       result = vtrk->video->previous_frame();
839     }
840   }
841   return result;
842 }
843
844 int64_t zmpeg3_t::
845 tell_byte()
846 {
847   int64_t result = -1;
848   if( last_type_read == 1 )
849     result = atrack[last_stream_read]->demuxer->tell_byte();
850   else if( last_type_read == 2 )
851     result =vtrack[last_stream_read]->demuxer->tell_byte();
852   return result;
853 }
854
855 int64_t zmpeg3_t::
856 get_bytes()
857 {
858   return demuxer->movie_size();
859 }
860
861 double zmpeg3_t::
862 get_audio_time(int stream)
863 {
864   double atime = -1.0;
865   if( stream >= 0 && stream < total_atracks ) {
866     double samplerate = sample_rate(stream);
867     if( samplerate > 0. ) {
868       int64_t sample = get_sample(stream);
869       if( !pts_padding || is_audio_stream() || is_video_stream() ) {
870         atime = sample / samplerate;
871       }
872       else {
873         atime = atrack[stream]->audio_time +
874           (sample - atrack[stream]->pts_position) / samplerate;
875       }
876     }
877   }
878   return atime;
879 }
880
881 double zmpeg3_t::
882 get_video_time(int stream)
883 {
884   double vtime = -1.0;
885   if( stream >= 0 && stream < total_vtracks ) {
886     double framerate = frame_rate(stream);
887     if( !pts_padding || is_audio_stream() || is_video_stream() ) {
888       if( framerate > 0. )
889         vtime = (double)get_frame(stream) / framerate;
890     }
891     else {
892       vtime = vtrack[stream]->video_time;
893       if( vtime >= 0. && framerate > 0. )
894         vtime += (get_frame(stream) - vtrack[stream]->pts_position) / framerate;
895     }
896   }
897   return vtime;
898 }
899
900 /* pts timecode available only in transport stream */
901 double zmpeg3_t::
902 get_time()
903 {
904   double time = 0;
905   if( last_type_read == 1 )
906     time = get_audio_time(last_stream_read);
907   else if( last_type_read == 2 )
908     time = get_video_time(last_stream_read);
909   return time;
910 }
911
912 int zmpeg3_t::
913 get_total_vts_titles()
914 {
915   return total_vts_titles;
916 }
917
918 int zmpeg3_t::
919 set_vts_title(int title)
920 {
921   int result = vts_title;
922   if( title >= 0 )
923     vts_title = title;
924   return result;
925 }
926
927 int zmpeg3_t::
928 get_total_interleaves()
929 {
930   return total_interleaves;
931 }
932
933 int zmpeg3_t::
934 set_interleave(int inlv)
935 {
936   int result = interleave;
937   if( inlv >= 0 )
938     interleave = inlv;
939   return result;
940 }
941
942 int zmpeg3_t::
943 set_angle(int a)
944 {
945   int result = angle;
946   if( a >= 0 )
947     angle = a;
948   return result;
949 }
950
951 int zmpeg3_t::
952 set_program(int no)
953 {
954   int result = set_vts_title()*100 + set_angle()*10 + set_interleave();
955   if( no >= 0 ) {
956     set_vts_title(no / 100);
957     set_angle((no/10) % 10);
958     set_interleave(no % 10);
959   }
960   return result;
961 }
962
963 int zmpeg3_t::
964 get_cell_time(int no, double &time)
965 {
966   int result = 1, i = 0;
967   zcell_t *cell = 0;
968   while( no >= 0 ) {
969     result = demuxer->get_cell(i, cell);
970     if( result < 0 ) return result;
971     if( result > 0 ) i = cell->cell_no;
972     ++i;  --no;
973   }
974   time = cell->cell_time;
975   return 0;
976 }
977
978 int zmpeg3_t::
979 end_of_audio(int stream)
980 {
981   int result = 1;
982   if( stream>=0 && stream<total_atracks ) {
983     atrack_t *atrk = atrack[stream];
984     if( atrk && atrk->demuxer )
985       result = atrk->demuxer->eof();
986   }
987   return result;
988 }
989
990 int zmpeg3_t::
991 end_of_video(int stream)
992 {
993   int result = 1;
994   if( stream>=0 && stream<total_vtracks ) {
995     vtrack_t *vtrk = vtrack[stream];
996     if( vtrk && vtrk->demuxer )
997       result = vtrk->demuxer->eof();
998   }
999   return result;
1000 }
1001
1002 int zmpeg3_t::
1003 drop_frames(long frames, int stream)
1004 {
1005   int result = -1;
1006   if( stream>=0 && stream<total_vtracks ) {
1007     vtrack_t *vtrk = vtrack[stream];
1008     if( vtrk && vtrk->video ) {
1009       result = vtrk->video->drop_frames(frames, 0);
1010       if( frames > 0 )
1011         vtrk->current_position += frames;
1012       last_type_read = 2;
1013       last_stream_read = stream;
1014     }
1015   }
1016   return result;
1017 }
1018
1019 int zmpeg3_t::
1020 colormodel(int stream)
1021 {
1022   int result = -1;
1023   if( stream>=0 && stream<total_vtracks ) {
1024     vtrack_t *vtrk = vtrack[stream];
1025     if( vtrk && vtrk->video )
1026       result = vtrk->video->colormodel();
1027   }
1028   return result;
1029 }
1030
1031 int zmpeg3_t::
1032 set_rowspan(int bytes, int stream)
1033 {
1034   int result = 1;
1035   if( stream>=0 && stream<total_vtracks ) {
1036     vtrack_t *vtrk = vtrack[stream];
1037     if( vtrk && vtrk->video ) {
1038       vtrk->video->row_span = bytes;
1039       result = 0;
1040     }
1041   }
1042   return result;
1043 }
1044
1045
1046 int zmpeg3_t::
1047 read_frame(uint8_t **output_rows, 
1048     int in_x, int in_y, int in_w, int in_h, 
1049     int out_w, int out_h, int color_model, int stream)
1050 {
1051   int result = -1;
1052 //zmsgs("1 %d\n", vtrack[stream]->current_position);
1053   if( stream>=0 && stream<total_vtracks ) {
1054     vtrack_t *vtrk = vtrack[stream];
1055     if( vtrk && vtrk->video ) {
1056       result = vtrk->video->read_frame(output_rows,
1057           in_x, in_y, in_w, in_h, out_w, out_h, color_model);
1058 //zmsg(" 2\n");
1059       last_type_read = 2;
1060       last_stream_read = stream;
1061       vtrk->current_position++;
1062     }
1063   }
1064 //zmsgs("2 %d\n", vtrack[stream]->current_position);
1065   return result;
1066 }
1067
1068 int zmpeg3_t::
1069 read_yuvframe(char *y_output, char *u_output, char *v_output,
1070     int in_x, int in_y, int in_w, int in_h, int stream)
1071 {
1072   int result = -1;
1073 //zmsg("1\n");
1074   if( stream>=0 && stream<total_vtracks ) {
1075     vtrack_t *vtrk = vtrack[stream];
1076     if( vtrk && vtrk->video ) {
1077       result = vtrk->video->read_yuvframe(y_output, u_output, v_output,
1078           in_x, in_y, in_w, in_h);
1079       last_type_read = 2;
1080       last_stream_read = stream;
1081       vtrk->current_position++;
1082     }
1083   }
1084 //zmsg("100\n");
1085   return result;
1086 }
1087
1088 int zmpeg3_t::
1089 read_yuvframe_ptr(char **y_output, char **u_output, char **v_output,
1090     int stream)
1091 {
1092   int result = -1;
1093   if( stream>=0 && stream<total_vtracks ) {
1094     vtrack_t *vtrk = vtrack[stream];
1095     if( vtrk && vtrk->video ) {
1096       result = vtrk->video->read_yuvframe_ptr(y_output, u_output, v_output);
1097       last_type_read = 2;
1098       last_stream_read = stream;
1099       vtrk->current_position++;
1100     }
1101   }
1102   return result;
1103 }
1104
1105 int zmpeg3_t::
1106 read_audio(void *output, int type, int channel, long samples, int stream)
1107 {
1108   int result = -1;
1109   if( stream>=0 && stream<total_atracks ) {
1110     atrack_t *atrk = atrack[stream];
1111     if( atrk && atrk->audio ) {
1112       atrk->audio->update_audio_history();
1113       result = atrk->audio->decode_audio(output, type, channel, samples);
1114       last_type_read = 1;
1115       last_stream_read = stream;
1116       atrk->current_position += samples;
1117     }
1118   }
1119   return result;
1120 }
1121
1122 int zmpeg3_t::
1123 read_audio(double *output_d, int channel, long samples, int stream)
1124 {
1125   return read_audio((void *)output_d, atyp_DOUBLE, channel, samples, stream);
1126 }
1127
1128 int zmpeg3_t::
1129 read_audio(float *output_f, int channel, long samples, int stream)
1130 {
1131   return read_audio((void *)output_f, atyp_FLOAT, channel, samples, stream);
1132 }
1133
1134 int zmpeg3_t::
1135 read_audio(int *output_i, int channel, long samples, int stream)
1136 {
1137   return read_audio((void *)output_i, atyp_INT, channel, samples, stream);
1138 }
1139
1140 int zmpeg3_t::
1141 read_audio(short *output_s, int channel, long samples, int stream)
1142 {
1143   return read_audio((void *)output_s, atyp_SHORT, channel, samples, stream);
1144 }
1145
1146 int zmpeg3_t::
1147 reread_audio(void *output, int atyp, int channel, long samples, int stream)
1148 {
1149   int result = -1;
1150   if( stream>=0 && stream<total_atracks ) {
1151     atrack_t *atrk = atrack[stream];
1152     if( atrk && atrk->audio ) {
1153       set_sample( atrk->current_position-samples, stream);
1154       result = atrk->audio->decode_audio(output, atyp, channel, samples);
1155       last_type_read = 1;
1156       last_stream_read = stream;
1157       atrk->current_position += samples;
1158     }
1159   }
1160   return result;
1161 }
1162
1163 int zmpeg3_t::
1164 reread_audio(double *output_d, int channel, long samples, int stream)
1165 {
1166   return reread_audio((void *)output_d, atyp_DOUBLE, channel, samples, stream);
1167 }
1168
1169 int zmpeg3_t::
1170 reread_audio(float *output_f, int channel, long samples, int stream)
1171 {
1172   return reread_audio((void *)output_f, atyp_FLOAT, channel, samples, stream);
1173 }
1174
1175 int zmpeg3_t::
1176 reread_audio(int *output_i, int channel, long samples, int stream)
1177 {
1178   return reread_audio((void *)output_i, atyp_INT, channel, samples, stream);
1179 }
1180
1181 int zmpeg3_t::
1182 reread_audio(short *output_s, int channel, long samples, int stream)
1183 {
1184   return reread_audio((void *)output_s, atyp_SHORT, channel, samples, stream);
1185 }
1186
1187
1188 int zmpeg3_t::
1189 read_audio_chunk(uint8_t *output, long *size, long max_size, int stream)
1190 {
1191   int result = -1;
1192   if( stream>=0 && stream<total_atracks ) {
1193     atrack_t *atrk = atrack[stream];
1194     if( atrk && atrk->audio ) {
1195       result = atrk->audio->read_raw(output, size, max_size);
1196       last_type_read = 1;
1197       last_stream_read = stream;
1198     }
1199   }
1200   return result;
1201 }
1202
1203 int zmpeg3_t::
1204 read_video_chunk( uint8_t *output, long *size, long max_size, int stream)
1205 {
1206   int result = -1;
1207   if( stream>=0 && stream<total_vtracks ) {
1208     vtrack_t *vtrk = vtrack[stream];
1209     if( vtrk && vtrk->video ) {
1210       result = vtrk->video->read_raw(output, size, max_size);
1211       last_type_read = 2;
1212       last_stream_read = stream;
1213     }
1214   }
1215   return result;
1216 }
1217
1218 int64_t zmpeg3_t::
1219 memory_usage()
1220 {
1221   int64_t result = 0;
1222   for( int i=0; i<total_vtracks; ++i )
1223     if( vtrack[i]->frame_cache )
1224       result += vtrack[i]->frame_cache->memory_usage();
1225   return result;
1226 }
1227
1228 int zmpeg3_t::
1229 start_record(int fd, int bsz)
1230 {
1231   if( recd_fd >= 0 ) return 1;
1232   struct stat64 st;
1233   memset(&st, 0, sizeof(st));
1234   if( fstat64(fd, &st) < 0 ) return 1;
1235   recd_fd = fd;
1236   recd_pos = st.st_size;
1237   if (fs->start_record(bsz)) return recd_fd = -1;
1238   return 0;
1239 }
1240 int zmpeg3_t::
1241 stop_record()
1242 {
1243   if( fs->stop_record() ) return 1;
1244   recd_fd = -1;
1245   return 0;
1246 }
1247
1248 void zmpeg3_t::
1249 write_record(uint8_t *data, int len)
1250 {
1251   if( recd_fd < 0 ) return;
1252   if( write(recd_fd, data, len) < 0 ) {
1253     zmsgs("write err: %s\n",strerror(errno));
1254     return;
1255   }
1256   recd_pos += len;
1257 }
1258
1259 int zmpeg3_t::
1260 pause_reader(int v)
1261 {
1262   return fs->pause_reader(v);
1263 }
1264
1265 int zmpeg3_t::
1266 get_thumbnail(int trk, int64_t &frn, uint8_t *&t, int &w, int &h)
1267 {
1268   int result = -1;
1269   if( trk>=0 && trk<total_vtracks ) {
1270     vtrack_t *vtrk = vtrack[trk];
1271     if( vtrk ) {
1272       video_t *vid = vtrk->video;
1273       frn = vid->framenum;
1274       t = vid->tdat;
1275       w = 2*vid->mb_width;
1276       h = 2*vid->mb_height;
1277       result = 0;
1278     }
1279   }
1280   return result;
1281 }
1282
1283 int zmpeg3_t::
1284 set_thumbnail_callback(int trk, int skim, int thumb,
1285         zthumbnail_cb fn, void *p)
1286 {
1287   int result = 1;
1288   // all tracks, toc build
1289   if( trk == -1 )
1290     result = 0;
1291   // one track, commercials verify
1292   else if( trk >= 0 && trk<total_vtracks ) {
1293     vtrack_t *vtrk = vtrack[trk];
1294     if( vtrk ) {
1295       video_t *vid = vtrk->video;
1296       if( !(result=vid->seek_video()) ) {
1297         vid->skim = skim;
1298         vid->thumb = thumb;
1299         vid->ithumb = 0;
1300         result = 0;
1301       }
1302     }
1303   }
1304   if( !result ) {
1305     thumbnail_priv = p;
1306     thumbnail_fn = fn;
1307   }
1308   return result;
1309 }
1310
1311 int zmpeg3_t::
1312 set_cc_text_callback(int trk, zcc_text_cb fn)
1313 {
1314   int result = -1;
1315   if( trk>=0 && trk<total_vtracks ) {
1316     vtrack_t *vtrk = vtrack[trk];
1317     if( vtrk ) {
1318       video_t *vid = vtrk->video;
1319       vid->get_cc()->text_cb = fn;
1320       result = 0;
1321     }
1322   }
1323   return result;
1324 }
1325
1326 int64_t zmpeg3_t::
1327 calculate_source_date(char *path)
1328 {
1329   struct stat64 ostat;
1330   memset(&ostat,0,sizeof(struct stat64));
1331   return stat64(path, &ostat) < 0 ? 0 : ostat.st_mtime;
1332 }
1333
1334 int64_t zmpeg3_t::
1335 calculate_source_date(int fd)
1336 {
1337   struct stat64 ostat;
1338   memset(&ostat,0,sizeof(struct stat64));
1339   return fstat64(fd, &ostat) < 0 ? 0 : ostat.st_mtime;
1340 }
1341
1342 void zdebug(int n)
1343 {
1344   zmsgs("%d\n",n);
1345 }
1346
1347