add audio to proxy, and minor bug fixes
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / video / video.C
1 #include "../libzmpeg3.h"
2
3 /* zig-zag scan */
4 uint8_t zvideo_t::
5 zig_zag_scan_nommx[64] = {
6    0 , 1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5, 
7   12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28, 
8   35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 
9   58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,
10 };
11
12 /* alternate scan */
13 uint8_t zvideo_t::
14 alternate_scan_nommx[64] = {
15    0,  8, 16, 24, 1,  9,  2, 10, 17, 25, 32, 40, 48, 56, 57, 49, 
16   41, 33, 26, 18, 3, 11,  4, 12, 19, 27, 34, 42, 50, 58, 35, 43, 
17   51, 59, 20, 28, 5, 13,  6, 14, 21, 29, 36, 44, 52, 60, 37, 45, 
18   53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63,
19 };
20
21 /* default intra quantization matrix */
22 uint8_t zvideo_t::
23 default_intra_quantizer_matrix[64] = {
24    8, 16, 19, 22, 26, 27, 29, 34,
25   16, 16, 22, 24, 27, 29, 34, 37,
26   19, 22, 26, 27, 29, 34, 34, 38,
27   22, 22, 26, 27, 29, 34, 37, 40,
28   22, 26, 27, 29, 32, 35, 40, 48,
29   26, 27, 29, 32, 35, 40, 48, 58,
30   26, 27, 29, 34, 38, 46, 56, 69,
31   27, 29, 35, 38, 46, 56, 69, 83,
32 };
33
34 double zvideo_t::
35 frame_rate_table[16] = {
36   0.0,   /* Pad */
37   (double)24000.0/1001.0,       /* Official frame rates */
38   (double)24.0,
39   (double)25.0,
40   (double)30000.0/1001.0,
41   (double)30.0,
42   (double)50.0,
43   (double)60000.0/1001.0,
44   (double)60.0,
45
46   1.0, 5.0, 10.0, 12.0, 15.0,   /* Unofficial economy rates */
47   0.0, 0.0,
48 };
49
50 static int blk_cnt_tab[3] = { 6, 8, 12 };
51
52 int zvideo_t::
53 init_decoder()
54 {
55   int i, j, sz, cc;
56   long size[4], padding[2];         /* Size of Y, U, and V buffers */
57
58   if( !mpeg2 ) { /* force MPEG-1 parameters */
59     prog_seq = 1;
60     prog_frame = 1;
61     pict_struct = pics_FRAME_PICTURE;
62     frame_pred_dct = 1;
63     chroma_format = cfmt_420;
64     matrix_coefficients = 5;
65   }
66
67 /* Get dimensions rounded to nearest multiple of coded macroblocks */
68   mb_width = (horizontal_size + 15) / 16;
69   mb_height = (mpeg2 && !prog_seq) ? 
70     (2 * ((vertical_size + 31) / 32)) : ((vertical_size + 15) / 16);
71   coded_picture_width = 16 * mb_width;
72   coded_picture_height = 16 * mb_height;
73   chrom_width = (chroma_format == cfmt_444) ? 
74     coded_picture_width : (coded_picture_width >> 1);
75   chrom_height = (chroma_format != cfmt_420) ? 
76     coded_picture_height : (coded_picture_height >> 1);
77   blk_cnt = blk_cnt_tab[chroma_format - 1];
78
79 /* Get sizes of YUV buffers */
80   padding[0] = 16*coded_picture_width + 16;
81   size[0] = coded_picture_width*coded_picture_height + padding[0];
82
83   padding[1] = 16*chrom_width + 16;
84   size[1] = chrom_width*chrom_height + padding[1];
85   size[3] = (size[2] = (llw * llh)) / 4;
86
87 /* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
88   sz = size[0] + 2*size[1];
89   yuv_buffer[0] = new uint8_t[sz]; memset(yuv_buffer[0],0,sz);
90   yuv_buffer[1] = new uint8_t[sz]; memset(yuv_buffer[1],0,sz);
91   yuv_buffer[2] = new uint8_t[sz]; memset(yuv_buffer[2],0,sz);
92
93   if( scalable_mode == slice_decoder_t::sc_SPAT ) {
94     sz = size[2] + 2 * size[3];
95     yuv_buffer[3] = new uint8_t[sz]; memset(yuv_buffer[3],0,sz);
96     yuv_buffer[4] = new uint8_t[sz]; memset(yuv_buffer[4],0,sz);
97   }
98
99   tdat = new uint8_t[4 * mb_width * mb_height];
100   memset(tdat, 0, 4 * mb_width * mb_height);
101
102   slice_decoder_t::init_tables();
103
104 /* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */  
105   for( cc=0; cc<3; ++cc ) {
106     llframe0[cc] = 0;
107     llframe1[cc] = 0;
108     newframe[cc] = 0;
109   }
110
111   refframe[0]    = yuv_buffer[0];
112   oldrefframe[0] = yuv_buffer[1];
113   auxframe[0]    = yuv_buffer[2];
114   sz             = size[0];
115   refframe[2]    = yuv_buffer[0] + sz;
116   oldrefframe[2] = yuv_buffer[1] + sz;
117   auxframe[2]    = yuv_buffer[2] + sz;
118   sz            += size[1];
119   refframe[1]    = yuv_buffer[0] + sz;
120   oldrefframe[1] = yuv_buffer[1] + sz;
121   auxframe[1]    = yuv_buffer[2] + sz;
122
123   if( scalable_mode == slice_decoder_t::sc_SPAT ) {
124 /* this assumes lower layer is 4:2:0 */
125     sz          = padding[0];
126     llframe0[0] = yuv_buffer[3] + sz;
127     llframe1[0] = yuv_buffer[4] + sz;
128     sz          = padding[1] + size[2];
129     llframe0[2] = yuv_buffer[3] + sz;
130     llframe1[2] = yuv_buffer[4] + sz;
131     sz         += size[3];
132     llframe0[1] = yuv_buffer[3] + sz;
133     llframe1[1] = yuv_buffer[4] + sz;
134   }
135
136 /* Initialize the YUV tables for software YUV decoding */
137   cr_to_r = new int[256];
138   crb_to_g = new int[256*256];
139   cb_to_b = new int[256];
140   int *cr_to_r_ptr = cr_to_r + 128;
141   int *crb_to_g_ptr = crb_to_g + 128*256 + 128;
142   int *cb_to_b_ptr = cb_to_b + 128;
143
144   for( i=-128; i<128; ++i ) {
145     cr_to_r_ptr[i] = (int)(1.371*i * 65536.);
146     for( j=-128; j<128; ++j )
147       crb_to_g_ptr[i*256 + j] = (int)((-0.698*i + -0.336*j) * 65536.);
148     cb_to_b_ptr[i] = (int)((1.732*i) * 65536.);
149   }
150
151   decoder_initted = 1;
152   return 0;
153 }
154
155 int zvideo_t::
156 delete_decoder()
157 {
158   if( yuv_buffer[0] ) delete [] yuv_buffer[0];
159   if( yuv_buffer[1] ) delete [] yuv_buffer[1];
160   if( yuv_buffer[2] ) delete [] yuv_buffer[2];
161
162   if( subtitle_frame[0] ) delete [] subtitle_frame[0];
163   if( subtitle_frame[1] ) delete [] subtitle_frame[1];
164   if( subtitle_frame[2] ) delete [] subtitle_frame[2];
165
166   if( llframe0[0] ) {
167     delete [] yuv_buffer[3];
168     delete [] yuv_buffer[4];
169   }
170   delete [] tdat;
171
172   delete [] cr_to_r;
173   delete [] crb_to_g;
174   delete [] cb_to_b;
175   return 0;
176 }
177
178 void zvideo_t::
179 init_scantables()
180 {
181   zigzag_scan_table = zig_zag_scan_nommx;
182   alternate_scan_table = alternate_scan_nommx;
183 }
184
185 void zvideo_t::
186 init_video()
187 {
188   int result;
189   init_decoder();
190   track->width = horizontal_size;
191   track->height = vertical_size;
192   track->frame_rate = frame_rate;
193   demuxer_t *demux = vstream->demuxer;
194
195   /* Try to get the length of the file from GOP's */
196   if( !track->frame_offsets ) {
197     if( src->is_video_stream() ) {
198       /* Load the first GOP */
199       rewind_video(0);
200       result = vstream->next_code(GOP_START_CODE);
201       if( !result ) vstream->get_bits(32);
202       if( !result ) result = get_gop_header();
203       first_frame = gop_to_frame(&gop_timecode);
204       /* GOPs are supposed to have 16 frames */
205       frames_per_gop = 16;
206       /* Read the last GOP in the file by seeking backward. */
207       demux->seek_byte(demux->movie_size());
208       demux->start_reverse();
209       result = demux->prev_code(GOP_START_CODE);
210       demux->start_forward();
211       vstream->reset();
212       vstream->get_bits(8);
213       if(!result) result = get_gop_header();
214       last_frame = gop_to_frame(&gop_timecode);
215 //zmsgs("3 %p\n", this);
216       /* Count number of frames to end */
217       while( !result ) {
218         result = vstream->next_code(PICTURE_START_CODE);
219         if( !result ) {
220           vstream->get_byte_noptr();
221           ++last_frame;
222         }
223       }
224
225       track->total_frames = last_frame-first_frame+1;
226 //zmsgs("mpeg3video_new 3 %ld\n", track->total_frames);
227     }
228     else {
229       /* Try to get the length of the file from the multiplexing. */
230       /* Need a table of contents */
231 /*       first_frame = 0;
232  *       track->total_frames = last_frame =
233  *         (long)(demux->length() * frame_rate);
234  *       first_frame = 0;
235  */
236     }
237   }
238   else {
239     /* Get length from table of contents */
240     track->total_frames = track->total_frame_offsets-1;
241   }
242
243   maxframe = track->total_frames;
244   rewind_video(0);
245 }
246
247 int zvideo_t::
248 video_pts_padding()
249 {
250   int result = 0;
251   if( track->video_time >= 0 && src->pts_padding > 0 ) {
252     int pts_framenum = track->video_time*track->frame_rate + 0.5;
253     int padding = pts_framenum - track->pts_position;
254     if( padding > 0 ) {
255       if( track->vskip <= 0 ) {
256         int limit = 3;
257         if( padding > limit ) {
258           zmsgs("video start padding  pid %02x @ %12d (%12.6f) %d\n",
259                 track->pid, framenum, track->get_video_time(), padding);
260           track->vskip = 1;
261           result = 1;
262         }
263       }
264       else if( !(++track->vskip & 1) || padding > track->frame_rate )
265         result = 1;
266       if( result ) ++track->pts_position;
267     }
268     else if( track->vskip > 0 ) {
269       zmsgs("video end   padding  pid %02x @ %12d (%12.6f) %d\n",
270             track->pid, framenum, track->get_video_time(), (1+track->vskip)/2);
271       track->vskip = 0;
272     }
273   }
274   return result;
275 }
276
277 int zvideo_t::
278 video_pts_skipping()
279 {
280   int result = 0;
281   if( track->video_time >= 0 && src->pts_padding > 0 ) {
282     int pts_framenum = track->video_time*track->frame_rate + 0.5;
283     int skipping = track->pts_position - pts_framenum;
284     if( skipping > 0 ) {
285       if( track->vskip >= 0 ) {
286         int limit = 3;
287         if( skipping > limit ) {
288           zmsgs("video start skipping pid %02x @ %12d (%12.6f) %d frames\n",
289                 track->pid, framenum, track->get_video_time(), skipping);
290           track->vskip = -1;
291           result = 1;
292         }
293       }
294       else if( !(--track->vskip & 1) || skipping > track->frame_rate )
295         result = 1;
296       if( result ) --track->pts_position;
297     }
298     else if( track->vskip < 0 ) {
299         zmsgs("video end   skipping pid %02x @ %12d (%12.6f) %d frames\n",
300                 track->pid, framenum, track->get_video_time(), (1-track->vskip)/2);
301       track->vskip = 0;
302     }
303   }
304   return result;
305 }
306
307 int zvideo_t::
308 eof()
309 {
310   while( vstream->eof() ) {
311     demuxer_t *demux = vstream->demuxer;
312     if( demux->seek_phys() ) return 1;
313   }
314   return 0;
315 }
316
317
318 /* The way they do field based encoding,  */
319 /* the I frames have the top field but both the I frame and */
320 /* subsequent P frame are interlaced to make the keyframe. */
321
322 int zvideo_t::
323 read_picture()
324 {
325   int result = 0;
326   int field = 0;
327   got_top = got_bottom = 0;
328   secondfield = 0;
329
330   do {
331     if( (result=eof()) != 0 ) break;
332     if( (result=get_header()) != 0 ) break;
333     if( pict_struct != pics_FRAME_PICTURE ) secondfield = field;
334     /* if dropping frames then skip B frames, */
335     /*   Don't skip the B frames which generate original */
336     /*   repeated frames at the end of the skip sequence */
337     if( !skip_bframes || pict_type != pic_type_B ||
338         repeat_fields > 2*skip_bframes ) {
339       if( (result=get_picture()) != 0 ) break;
340     }
341     ++field;
342     if( pict_struct == pics_FRAME_PICTURE ) { got_top = got_bottom = field; break; }
343     if( pict_struct == pics_TOP_FIELD ) got_top = field;
344     else if( pict_struct == pics_BOTTOM_FIELD ) got_bottom = field;
345   } while( !secondfield );
346
347   if( pict_type != pic_type_B )
348     ++ref_frames;
349
350   return result;
351 }
352
353 int zvideo_t::
354 read_frame_backend(int zskip_bframes)
355 {
356   int result = 0;
357 //if( src->seekable ) {
358 //  int app_pos = track->apparent_position();
359 //  double vtime = track->get_video_time();
360 //  int pts_frm = vtime * track->frame_rate + 0.5;
361 //  zmsgs(" apr_pos %f: %d/%d + %d: pts_frame %d + %d\n", vtime,
362 //    app_pos, framenum, app_pos - framenum, pts_frm, pts_frm-framenum);
363 //}
364   if( !mpeg2 ) current_field = repeat_fields = 0;
365
366   /* Repeat if current_field is more than 1 field from repeat_fields */
367   if( !repeat_fields || current_field+2 >= repeat_fields ) {
368     if( (repeat_fields -= current_field) < 0 ) repeat_fields = 0;
369     track->update_video_time();
370
371     // if pts lags framenum, skip to next picture
372     //  only skip once (double speed) to catch up
373     while( !(result=find_header()) ) {
374       if( !video_pts_skipping() ) break;
375       vstream->refill();
376     }
377
378     // if framenum lags pts, repeat picture
379     if( !result && !video_pts_padding() ) {
380       track->update_frame_pts();
381       skip_bframes = zskip_bframes;
382 //static const char *pstruct[] = { "nil", "top", "bot", "fld" };
383 //zmsgs("video %d PID %02x frame %d vtime %12.5f %c/%s %d 0x%010lx/0x%010lx %d/%d\n",
384 //  result, track->pid, framenum, track->get_video_time(), "XIPBD"[pict_type],
385 //  pstruct[pict_struct], skip_bframes, vstream->demuxer->last_packet_start,
386 //  vstream->demuxer->absolute_position()-vstream->demuxer->zdata.length(),
387 //  repeat_fields, current_field);
388       result = read_picture();
389 #if 0
390 { char fn[512];
391   snprintf(&fn[0],sizeof(fn),"/tmp/dat/f%05d.pnm",framenum);
392   int fd = open(&fn[0],O_CREAT+O_TRUNC+O_WRONLY,0666);
393   write(fd,&fn, snprintf(&fn[0],sizeof(fn),
394     "P5\n%d %d\n255\n", coded_picture_width, coded_picture_height));
395   write(fd,output_src[0],coded_picture_width*coded_picture_height);
396   close(fd);
397 }
398 #endif
399     }
400   }
401
402   if( !result ) {
403     if( mpeg2 ) current_field  = !repeat_fields ? 0 : current_field+2;
404     decode_subtitle();
405     last_number = framenum++;
406   }
407
408   return result;
409 }
410
411 int* zvideo_t::
412 get_scaletable(int in_l, int out_l)
413 {
414   int *result = new int[out_l];
415   double scale = (double)in_l / out_l;
416   for( int i=0; i<out_l; ++i ) {
417     result[i] = (int)(scale * i);
418   }
419   return result;
420 }
421
422 long zvideo_t::
423 gop_to_frame(timecode_t *gop_timecode)
424 {
425 /* Mirror of what mpeg2enc does */
426   int fps = (int)(frame_rate + 0.5);
427   int hour = gop_timecode->hour;
428   int minute = gop_timecode->minute;
429   int second = gop_timecode->second;
430   int frame = gop_timecode->frame;
431   long result = ((long)hour*3600 + minute*60 + second)*fps + frame;
432   return result;
433 }
434
435
436 /* ======================================================================= */
437 /*                                    ENTRY POINTS */
438 /* ======================================================================= */
439
440
441
442 zvideo_t::
443 video_t(zmpeg3_t *zsrc, zvtrack_t *ztrack)
444 {
445   src = zsrc;
446   track = ztrack;
447   vstream = new bits_t(zsrc, track->demuxer);
448 //zmsgs("%d\n", vstream->eof());
449   last_number = -1;
450 /* First frame is all green */
451   framenum = -1;
452   byte_seek = -1;
453   frame_seek = -1;
454   subtitle_track = -1;
455
456   init_scantables();
457   init_output();
458   allocate_slice_buffers();
459   slice_wait.lock();
460 }
461
462 zvideo_t *zmpeg3_t::
463 new_video_t(zvtrack_t *ztrack)
464 {
465   int result = 0;
466   video_t *new_video = new video_t(this,ztrack);
467
468 /* Get encoding parameters from stream */
469   if( seekable ) {
470     result = new_video->get_header();
471     if( !result )
472       new_video->init_video();
473     else {
474 /* No header found */
475 #ifdef TODO
476       zerr("no header found.\n");
477       delete new_video;
478       new_video = 0;
479 #endif
480     }
481   }
482
483   return new_video;
484 }
485
486 zvideo_t::
487 ~video_t()
488 {
489   delete_slice_buffers();
490   if( decoder_initted )
491     delete_decoder();
492   delete vstream;
493   delete cc;
494   if( x_table ) {
495     delete [] x_table;
496     delete [] y_table;
497   }
498 }
499
500 int zvideo_t::
501 set_cpus(int cpus)
502 {
503   return 0;
504 }
505
506 int zvideo_t::
507 set_mmx(int use_mmx)
508 {
509   init_scantables();
510   return 0;
511 }
512
513 /* Read all the way up to and including the next picture start code */
514 int zvideo_t::
515 read_raw(uint8_t *output, long *size, long max_size)
516 {
517   uint32_t zcode = 0;
518   long sz = 0;
519   while( zcode!=PICTURE_START_CODE && zcode!=SEQUENCE_END_CODE &&
520          sz < max_size && !eof() ) {
521     uint8_t byte = vstream->get_byte_noptr();
522     *output++ = byte;
523     zcode = (zcode << 8) | byte;
524     ++sz;
525   }
526   *size = sz;
527   return eof();
528 }
529
530 int zvideo_t::read_frame( uint8_t **output_rows,
531     int in_x, int in_y, int in_w, int in_h, 
532     int out_w, int out_h, int color_model)
533 {
534   uint8_t *y, *u, *v;
535   int frame_number, result;
536   result = 0;
537   want_yvu = 0;
538   this->output_rows = output_rows;
539   this->color_model = color_model;
540
541 /* Get scaling tables */
542   if( this->out_w != out_w || this->out_h != out_h ||
543       this->in_w != in_w   || this->in_h != in_h ||
544       this->in_x != in_x   || this->in_y != in_y) {
545     if(x_table) {
546       delete [] x_table;  x_table = 0;
547       delete [] y_table;  y_table = 0;
548     }
549   }
550
551   this->out_w = out_w; this->out_h = out_h;
552   this->in_w = in_w;   this->in_h = in_h;
553   this->in_x = in_x;   this->in_y = in_y;
554
555   if( !x_table ) {
556     x_table = get_scaletable(in_w, out_w);
557     y_table = get_scaletable(in_h, out_h);
558   }
559 //zmsgs("mpeg3video_read_frame 1 %d\n", framenum);
560
561 /* Recover from cache */
562   frame_number = frame_seek >= 0 ? frame_seek : framenum;
563   cache_t *cache = track->frame_cache;
564   if( frame_seek != last_number &&
565       cache->get_frame(frame_number, &y, &u, &v) ) {
566 //zmsgs("1 %d\n", frame_number);
567     /* Transfer with cropping */
568     if( y ) present_frame(y, u, v);
569     /* Advance either framenum or frame_seek */
570     if( frame_number == framenum )
571       framenum = ++frame_number;
572     else if( frame_number == frame_seek )
573       frame_seek = ++frame_number;
574   }
575   else {
576     /* Only decode if it's a different frame */
577     if( frame_seek < 0 || last_number < 0 ||
578         frame_seek != last_number) {
579       if( !result ) result = seek();
580       if( !result ) result = read_frame_backend(0);
581     }
582     else {
583       framenum = frame_seek + 1;
584       last_number = frame_seek;
585       frame_seek = -1;
586     }
587     if( output_src[0] )
588       present_frame(output_src[0], output_src[1], output_src[2]);
589   }
590   return result;
591 }
592
593 int zvideo_t::
594 read_yuvframe(char *y_output, char *u_output, char *v_output,
595               int in_x, int in_y, int in_w, int in_h)
596 {
597   uint8_t *y = 0, *u = 0, *v = 0;
598   int result = 0;
599 //zmsgs("1 %d\n", framenum);
600   want_yvu = 1;
601   this->y_output = y_output;
602   this->u_output = u_output;
603   this->v_output = v_output;
604   this->in_x = in_x;
605   this->in_y = in_y;
606   this->in_w = in_w;
607   this->in_h = in_h;
608
609   /* Recover from cache if framenum exists */
610   int frame_number = frame_seek >= 0 ? frame_seek : framenum;
611   cache_t *cache = track->frame_cache;
612   if( cache->get_frame(frame_number, &y, &u, &v) ) {
613 //zmsgs("1 %d\n", frame_number);
614     /* Transfer with cropping */
615     if( y ) present_frame(y, u, v);
616     /* Advance either framenum or frame_seek */
617     if( frame_number == framenum )
618       framenum = ++frame_number;
619     else if( frame_number == frame_seek )
620       frame_seek = ++frame_number;
621   }
622   else {
623     if( !result ) result = seek();
624     if( !result ) result = read_frame_backend(0);
625     if( !result && output_src[0] )
626       present_frame(output_src[0], output_src[1], output_src[2]);
627   }
628
629   want_yvu = 0;
630   byte_seek = -1;
631   return result;
632 }
633
634 int zvideo_t::
635 read_yuvframe_ptr(char **y_output, char **u_output, char **v_output)
636 {
637   uint8_t *y, *u, *v;
638   int frame_number, result;
639   int debug = 0;
640   result = 0;
641   want_yvu = 1;
642   *y_output = *u_output = *v_output = 0;
643
644   frame_number = frame_seek >= 0 ? frame_seek : framenum;
645   cache_t *cache = track->frame_cache;
646   if( debug ) zmsgs("%d\n", __LINE__);
647   if( cache->get_frame(frame_number, &y, &u, &v) ) {
648     if( debug ) zmsgs("%d\n", __LINE__);
649     *y_output = (char*)y;
650     *u_output = (char*)u;
651     *v_output = (char*)v;
652     /* Advance either framenum or frame_seek */
653     if( frame_number == framenum )
654       framenum = ++frame_number;
655     else if( frame_number == frame_seek )
656       frame_seek = ++frame_number;
657     if( debug ) zmsgs("%d\n", __LINE__);
658   }
659   /* Only decode if it's a different frame */
660   else if( frame_seek < 0 || last_number < 0 ||
661            frame_seek != last_number) {
662     if( debug ) zmsgs("%d\n", __LINE__);
663     if( !result ) result = seek();
664     if( debug ) zmsgs("%d\n", __LINE__);
665     if( !result ) result = read_frame_backend(0);
666     if( debug ) zmsgs("%d\n", __LINE__);
667
668     if( output_src[0] ) {
669       *y_output = (char*)output_src[0];
670       *u_output = (char*)output_src[1];
671       *v_output = (char*)output_src[2];
672     }
673     if( debug ) zmsgs("%d\n", __LINE__);
674   }
675   else {
676     if( debug ) zmsgs("%d\n", __LINE__);
677     framenum = frame_seek + 1;
678     last_number = frame_seek;
679     frame_seek = -1;
680
681     if( output_src[0 ]) {
682       *y_output = (char*)output_src[0];
683       *u_output = (char*)output_src[1];
684       *v_output = (char*)output_src[2];
685     }
686     if( debug ) zmsgs("%d\n", __LINE__);
687   }
688
689   if( debug ) zmsgs("%d\n", __LINE__);
690   want_yvu = 0;
691 /* Caching not used if byte seek */
692   byte_seek = -1;
693   return result;
694 }
695
696 int zvideo_t::
697 colormodel()
698 {
699   switch( chroma_format ) {
700     case cfmt_422: return cmdl_YUV422P; break;
701     case cfmt_420: return cmdl_YUV420P; break;
702   }
703   return cmdl_YUV420P;
704 }
705
706 zcc_t *zvideo_t::
707 get_cc()
708 {
709   if( !cc )
710     cc = new cc_t(this);
711   return cc;
712 }
713
714 void zvideo_t::
715 reset_subtitles()
716 {
717   for( int i=0; i<src->total_stracks; ++i ) {
718     strack_t *strack = src->strack[i];
719     if( strack->video != this ) continue;
720     strack->del_all_subtitles();
721   }
722 }
723
724 int zvideo_t::
725 show_subtitle(int strk)
726 {
727   int ret = subtitle_track;
728   if( subtitle_track != strk ) {
729     reset_subtitles();
730     subtitle_track = strk;
731     if( cc ) {
732       if( strk >= 0 ) cc->reset();
733       else { delete cc;  cc = 0; }
734     }
735   }
736   return ret;
737 }
738
739 void zvideo_t::
740 dump()
741 {
742   zmsg("\n");
743   zmsg(" *** sequence extension 1\n");
744   zmsgs("prog_seq=%d\n", prog_seq);
745   zmsg(" *** picture header 1\n");
746   zmsgs("pict_type=%d field_sequence=%d\n", pict_type, field_sequence);
747   zmsg(" *** picture coding extension 1\n");
748   zmsgs("field_sequence=%d repeatfirst=%d prog_frame=%d pict_struct=%d\n", 
749     field_sequence, repeatfirst, prog_frame, pict_struct);
750 }
751