Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / libzmpeg3 / video / video.C
diff --git a/cinelerra-5.0/libzmpeg3/video/video.C b/cinelerra-5.0/libzmpeg3/video/video.C
deleted file mode 100644 (file)
index 5df6740..0000000
+++ /dev/null
@@ -1,751 +0,0 @@
-#include "../libzmpeg3.h"
-
-/* zig-zag scan */
-uint8_t zvideo_t::
-zig_zag_scan_nommx[64] = {
-   0 , 1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5, 
-  12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28, 
-  35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 
-  58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,
-};
-
-/* alternate scan */
-uint8_t zvideo_t::
-alternate_scan_nommx[64] = {
-   0,  8, 16, 24, 1,  9,  2, 10, 17, 25, 32, 40, 48, 56, 57, 49, 
-  41, 33, 26, 18, 3, 11,  4, 12, 19, 27, 34, 42, 50, 58, 35, 43, 
-  51, 59, 20, 28, 5, 13,  6, 14, 21, 29, 36, 44, 52, 60, 37, 45, 
-  53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63,
-};
-
-/* default intra quantization matrix */
-uint8_t zvideo_t::
-default_intra_quantizer_matrix[64] = {
-   8, 16, 19, 22, 26, 27, 29, 34,
-  16, 16, 22, 24, 27, 29, 34, 37,
-  19, 22, 26, 27, 29, 34, 34, 38,
-  22, 22, 26, 27, 29, 34, 37, 40,
-  22, 26, 27, 29, 32, 35, 40, 48,
-  26, 27, 29, 32, 35, 40, 48, 58,
-  26, 27, 29, 34, 38, 46, 56, 69,
-  27, 29, 35, 38, 46, 56, 69, 83,
-};
-
-double zvideo_t::
-frame_rate_table[16] = {
-  0.0,   /* Pad */
-  (double)24000.0/1001.0,       /* Official frame rates */
-  (double)24.0,
-  (double)25.0,
-  (double)30000.0/1001.0,
-  (double)30.0,
-  (double)50.0,
-  (double)60000.0/1001.0,
-  (double)60.0,
-
-  1.0, 5.0, 10.0, 12.0, 15.0,   /* Unofficial economy rates */
-  0.0, 0.0,
-};
-
-static int blk_cnt_tab[3] = { 6, 8, 12 };
-
-int zvideo_t::
-init_decoder()
-{
-  int i, j, sz, cc;
-  long size[4], padding[2];         /* Size of Y, U, and V buffers */
-
-  if( !mpeg2 ) { /* force MPEG-1 parameters */
-    prog_seq = 1;
-    prog_frame = 1;
-    pict_struct = pics_FRAME_PICTURE;
-    frame_pred_dct = 1;
-    chroma_format = cfmt_420;
-    matrix_coefficients = 5;
-  }
-
-/* Get dimensions rounded to nearest multiple of coded macroblocks */
-  mb_width = (horizontal_size + 15) / 16;
-  mb_height = (mpeg2 && !prog_seq) ? 
-    (2 * ((vertical_size + 31) / 32)) : ((vertical_size + 15) / 16);
-  coded_picture_width = 16 * mb_width;
-  coded_picture_height = 16 * mb_height;
-  chrom_width = (chroma_format == cfmt_444) ? 
-    coded_picture_width : (coded_picture_width >> 1);
-  chrom_height = (chroma_format != cfmt_420) ? 
-    coded_picture_height : (coded_picture_height >> 1);
-  blk_cnt = blk_cnt_tab[chroma_format - 1];
-
-/* Get sizes of YUV buffers */
-  padding[0] = 16*coded_picture_width + 16;
-  size[0] = coded_picture_width*coded_picture_height + padding[0];
-
-  padding[1] = 16*chrom_width + 16;
-  size[1] = chrom_width*chrom_height + padding[1];
-  size[3] = (size[2] = (llw * llh)) / 4;
-
-/* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
-  sz = size[0] + 2*size[1];
-  yuv_buffer[0] = new uint8_t[sz]; memset(yuv_buffer[0],0,sz);
-  yuv_buffer[1] = new uint8_t[sz]; memset(yuv_buffer[1],0,sz);
-  yuv_buffer[2] = new uint8_t[sz]; memset(yuv_buffer[2],0,sz);
-
-  if( scalable_mode == slice_decoder_t::sc_SPAT ) {
-    sz = size[2] + 2 * size[3];
-    yuv_buffer[3] = new uint8_t[sz]; memset(yuv_buffer[3],0,sz);
-    yuv_buffer[4] = new uint8_t[sz]; memset(yuv_buffer[4],0,sz);
-  }
-
-  tdat = new uint8_t[4 * mb_width * mb_height];
-  memset(tdat, 0, 4 * mb_width * mb_height);
-
-  slice_decoder_t::init_tables();
-
-/* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */  
-  for( cc=0; cc<3; ++cc ) {
-    llframe0[cc] = 0;
-    llframe1[cc] = 0;
-    newframe[cc] = 0;
-  }
-
-  refframe[0]    = yuv_buffer[0];
-  oldrefframe[0] = yuv_buffer[1];
-  auxframe[0]    = yuv_buffer[2];
-  sz             = size[0];
-  refframe[2]    = yuv_buffer[0] + sz;
-  oldrefframe[2] = yuv_buffer[1] + sz;
-  auxframe[2]    = yuv_buffer[2] + sz;
-  sz            += size[1];
-  refframe[1]    = yuv_buffer[0] + sz;
-  oldrefframe[1] = yuv_buffer[1] + sz;
-  auxframe[1]    = yuv_buffer[2] + sz;
-
-  if( scalable_mode == slice_decoder_t::sc_SPAT ) {
-/* this assumes lower layer is 4:2:0 */
-    sz          = padding[0];
-    llframe0[0] = yuv_buffer[3] + sz;
-    llframe1[0] = yuv_buffer[4] + sz;
-    sz          = padding[1] + size[2];
-    llframe0[2] = yuv_buffer[3] + sz;
-    llframe1[2] = yuv_buffer[4] + sz;
-    sz         += size[3];
-    llframe0[1] = yuv_buffer[3] + sz;
-    llframe1[1] = yuv_buffer[4] + sz;
-  }
-
-/* Initialize the YUV tables for software YUV decoding */
-  cr_to_r = new int[256];
-  crb_to_g = new int[256*256];
-  cb_to_b = new int[256];
-  int *cr_to_r_ptr = cr_to_r + 128;
-  int *crb_to_g_ptr = crb_to_g + 128*256 + 128;
-  int *cb_to_b_ptr = cb_to_b + 128;
-
-  for( i=-128; i<128; ++i ) {
-    cr_to_r_ptr[i] = (int)(1.371*i * 65536.);
-    for( j=-128; j<128; ++j )
-      crb_to_g_ptr[i*256 + j] = (int)((-0.698*i + -0.336*j) * 65536.);
-    cb_to_b_ptr[i] = (int)((1.732*i) * 65536.);
-  }
-
-  decoder_initted = 1;
-  return 0;
-}
-
-int zvideo_t::
-delete_decoder()
-{
-  if( yuv_buffer[0] ) delete [] yuv_buffer[0];
-  if( yuv_buffer[1] ) delete [] yuv_buffer[1];
-  if( yuv_buffer[2] ) delete [] yuv_buffer[2];
-
-  if( subtitle_frame[0] ) delete [] subtitle_frame[0];
-  if( subtitle_frame[1] ) delete [] subtitle_frame[1];
-  if( subtitle_frame[2] ) delete [] subtitle_frame[2];
-
-  if( llframe0[0] ) {
-    delete [] yuv_buffer[3];
-    delete [] yuv_buffer[4];
-  }
-  delete [] tdat;
-
-  delete [] cr_to_r;
-  delete [] crb_to_g;
-  delete [] cb_to_b;
-  return 0;
-}
-
-void zvideo_t::
-init_scantables()
-{
-  zigzag_scan_table = zig_zag_scan_nommx;
-  alternate_scan_table = alternate_scan_nommx;
-}
-
-void zvideo_t::
-init_video()
-{
-  int result;
-  init_decoder();
-  track->width = horizontal_size;
-  track->height = vertical_size;
-  track->frame_rate = frame_rate;
-  demuxer_t *demux = vstream->demuxer;
-
-  /* Try to get the length of the file from GOP's */
-  if( !track->frame_offsets ) {
-    if( src->is_video_stream() ) {
-      /* Load the first GOP */
-      rewind_video(0);
-      result = vstream->next_code(GOP_START_CODE);
-      if( !result ) vstream->get_bits(32);
-      if( !result ) result = get_gop_header();
-      first_frame = gop_to_frame(&gop_timecode);
-      /* GOPs are supposed to have 16 frames */
-      frames_per_gop = 16;
-      /* Read the last GOP in the file by seeking backward. */
-      demux->seek_byte(demux->movie_size());
-      demux->start_reverse();
-      result = demux->prev_code(GOP_START_CODE);
-      demux->start_forward();
-      vstream->reset();
-      vstream->get_bits(8);
-      if(!result) result = get_gop_header();
-      last_frame = gop_to_frame(&gop_timecode);
-//zmsgs("3 %p\n", this);
-      /* Count number of frames to end */
-      while( !result ) {
-        result = vstream->next_code(PICTURE_START_CODE);
-        if( !result ) {
-          vstream->get_byte_noptr();
-          ++last_frame;
-        }
-      }
-
-      track->total_frames = last_frame-first_frame+1;
-//zmsgs("mpeg3video_new 3 %ld\n", track->total_frames);
-    }
-    else {
-      /* Try to get the length of the file from the multiplexing. */
-      /* Need a table of contents */
-/*       first_frame = 0;
- *       track->total_frames = last_frame =
- *         (long)(demux->length() * frame_rate);
- *       first_frame = 0;
- */
-    }
-  }
-  else {
-    /* Get length from table of contents */
-    track->total_frames = track->total_frame_offsets-1;
-  }
-
-  maxframe = track->total_frames;
-  rewind_video(0);
-}
-
-int zvideo_t::
-video_pts_padding()
-{
-  int result = 0;
-  if( track->video_time >= 0 && src->pts_padding > 0 ) {
-    int pts_framenum = track->video_time*track->frame_rate + 0.5;
-    int padding = pts_framenum - track->pts_position;
-    if( padding > 0 ) {
-      if( track->vskip <= 0 ) {
-        int limit = 3;
-        if( padding > limit ) {
-          zmsgs("video start padding  pid %02x @ %12d (%12.6f) %d\n",
-                track->pid, framenum, track->get_video_time(), padding);
-          track->vskip = 1;
-          result = 1;
-        }
-      }
-      else if( !(++track->vskip & 1) || padding > track->frame_rate )
-        result = 1;
-      if( result ) ++track->pts_position;
-    }
-    else if( track->vskip > 0 ) {
-      zmsgs("video end   padding  pid %02x @ %12d (%12.6f) %d\n",
-            track->pid, framenum, track->get_video_time(), (1+track->vskip)/2);
-      track->vskip = 0;
-    }
-  }
-  return result;
-}
-
-int zvideo_t::
-video_pts_skipping()
-{
-  int result = 0;
-  if( track->video_time >= 0 && src->pts_padding > 0 ) {
-    int pts_framenum = track->video_time*track->frame_rate + 0.5;
-    int skipping = track->pts_position - pts_framenum;
-    if( skipping > 0 ) {
-      if( track->vskip >= 0 ) {
-        int limit = 3;
-        if( skipping > limit ) {
-          zmsgs("video start skipping pid %02x @ %12d (%12.6f) %d frames\n",
-                track->pid, framenum, track->get_video_time(), skipping);
-          track->vskip = -1;
-          result = 1;
-        }
-      }
-      else if( !(--track->vskip & 1) || skipping > track->frame_rate )
-        result = 1;
-      if( result ) --track->pts_position;
-    }
-    else if( track->vskip < 0 ) {
-        zmsgs("video end   skipping pid %02x @ %12d (%12.6f) %d frames\n",
-                track->pid, framenum, track->get_video_time(), (1-track->vskip)/2);
-      track->vskip = 0;
-    }
-  }
-  return result;
-}
-
-int zvideo_t::
-eof()
-{
-  while( vstream->eof() ) {
-    demuxer_t *demux = vstream->demuxer;
-    if( demux->seek_phys() ) return 1;
-  }
-  return 0;
-}
-
-
-/* The way they do field based encoding,  */
-/* the I frames have the top field but both the I frame and */
-/* subsequent P frame are interlaced to make the keyframe. */
-
-int zvideo_t::
-read_picture()
-{
-  int result = 0;
-  int field = 0;
-  got_top = got_bottom = 0;
-  secondfield = 0;
-
-  do {
-    if( (result=eof()) != 0 ) break;
-    if( (result=get_header()) != 0 ) break;
-    if( pict_struct != pics_FRAME_PICTURE ) secondfield = field;
-    /* if dropping frames then skip B frames, */
-    /*   Don't skip the B frames which generate original */
-    /*   repeated frames at the end of the skip sequence */
-    if( !skip_bframes || pict_type != pic_type_B ||
-        repeat_fields > 2*skip_bframes ) {
-      if( (result=get_picture()) != 0 ) break;
-    }
-    ++field;
-    if( pict_struct == pics_FRAME_PICTURE ) { got_top = got_bottom = field; break; }
-    if( pict_struct == pics_TOP_FIELD ) got_top = field;
-    else if( pict_struct == pics_BOTTOM_FIELD ) got_bottom = field;
-  } while( !secondfield );
-
-  if( pict_type != pic_type_B )
-    ++ref_frames;
-
-  return result;
-}
-
-int zvideo_t::
-read_frame_backend(int zskip_bframes)
-{
-  int result = 0;
-//if( src->seekable ) {
-//  int app_pos = track->apparent_position();
-//  double vtime = track->get_video_time();
-//  int pts_frm = vtime * track->frame_rate + 0.5;
-//  zmsgs(" apr_pos %f: %d/%d + %d: pts_frame %d + %d\n", vtime,
-//    app_pos, framenum, app_pos - framenum, pts_frm, pts_frm-framenum);
-//}
-  if( !mpeg2 ) current_field = repeat_fields = 0;
-
-  /* Repeat if current_field is more than 1 field from repeat_fields */
-  if( !repeat_fields || current_field+2 >= repeat_fields ) {
-    if( (repeat_fields -= current_field) < 0 ) repeat_fields = 0;
-    track->update_video_time();
-
-    // if pts lags framenum, skip to next picture
-    //  only skip once (double speed) to catch up
-    while( !(result=find_header()) ) {
-      if( !video_pts_skipping() ) break;
-      vstream->refill();
-    }
-
-    // if framenum lags pts, repeat picture
-    if( !result && !video_pts_padding() ) {
-      track->update_frame_pts();
-      skip_bframes = zskip_bframes;
-//static const char *pstruct[] = { "nil", "top", "bot", "fld" };
-//zmsgs("video %d PID %02x frame %d vtime %12.5f %c/%s %d 0x%010lx/0x%010lx %d/%d\n",
-//  result, track->pid, framenum, track->get_video_time(), "XIPBD"[pict_type],
-//  pstruct[pict_struct], skip_bframes, vstream->demuxer->last_packet_start,
-//  vstream->demuxer->absolute_position()-vstream->demuxer->zdata.length(),
-//  repeat_fields, current_field);
-      result = read_picture();
-#if 0
-{ char fn[512];
-  snprintf(&fn[0],sizeof(fn),"/tmp/dat/f%05d.pnm",framenum);
-  int fd = open(&fn[0],O_CREAT+O_TRUNC+O_WRONLY,0666);
-  write(fd,&fn, snprintf(&fn[0],sizeof(fn),
-    "P5\n%d %d\n255\n", coded_picture_width, coded_picture_height));
-  write(fd,output_src[0],coded_picture_width*coded_picture_height);
-  close(fd);
-}
-#endif
-    }
-  }
-
-  if( !result ) {
-    if( mpeg2 ) current_field  = !repeat_fields ? 0 : current_field+2;
-    decode_subtitle();
-    last_number = framenum++;
-  }
-
-  return result;
-}
-
-int* zvideo_t::
-get_scaletable(int in_l, int out_l)
-{
-  int *result = new int[out_l];
-  double scale = (double)in_l / out_l;
-  for( int i=0; i<out_l; ++i ) {
-    result[i] = (int)(scale * i);
-  }
-  return result;
-}
-
-long zvideo_t::
-gop_to_frame(timecode_t *gop_timecode)
-{
-/* Mirror of what mpeg2enc does */
-  int fps = (int)(frame_rate + 0.5);
-  int hour = gop_timecode->hour;
-  int minute = gop_timecode->minute;
-  int second = gop_timecode->second;
-  int frame = gop_timecode->frame;
-  long result = ((long)hour*3600 + minute*60 + second)*fps + frame;
-  return result;
-}
-
-
-/* ======================================================================= */
-/*                                    ENTRY POINTS */
-/* ======================================================================= */
-
-
-
-zvideo_t::
-video_t(zmpeg3_t *zsrc, zvtrack_t *ztrack)
-{
-  src = zsrc;
-  track = ztrack;
-  vstream = new bits_t(zsrc, track->demuxer);
-//zmsgs("%d\n", vstream->eof());
-  last_number = -1;
-/* First frame is all green */
-  framenum = -1;
-  byte_seek = -1;
-  frame_seek = -1;
-  subtitle_track = -1;
-
-  init_scantables();
-  init_output();
-  allocate_slice_buffers();
-  slice_wait.lock();
-}
-
-zvideo_t *zmpeg3_t::
-new_video_t(zvtrack_t *ztrack)
-{
-  int result = 0;
-  video_t *new_video = new video_t(this,ztrack);
-
-/* Get encoding parameters from stream */
-  if( seekable ) {
-    result = new_video->get_header();
-    if( !result )
-      new_video->init_video();
-    else {
-/* No header found */
-#ifdef TODO
-      zerr("no header found.\n");
-      delete new_video;
-      new_video = 0;
-#endif
-    }
-  }
-
-  return new_video;
-}
-
-zvideo_t::
-~video_t()
-{
-  delete_slice_buffers();
-  if( decoder_initted )
-    delete_decoder();
-  delete vstream;
-  delete cc;
-  if( x_table ) {
-    delete [] x_table;
-    delete [] y_table;
-  }
-}
-
-int zvideo_t::
-set_cpus(int cpus)
-{
-  return 0;
-}
-
-int zvideo_t::
-set_mmx(int use_mmx)
-{
-  init_scantables();
-  return 0;
-}
-
-/* Read all the way up to and including the next picture start code */
-int zvideo_t::
-read_raw(uint8_t *output, long *size, long max_size)
-{
-  uint32_t zcode = 0;
-  long sz = 0;
-  while( zcode!=PICTURE_START_CODE && zcode!=SEQUENCE_END_CODE &&
-         sz < max_size && !eof() ) {
-    uint8_t byte = vstream->get_byte_noptr();
-    *output++ = byte;
-    zcode = (zcode << 8) | byte;
-    ++sz;
-  }
-  *size = sz;
-  return eof();
-}
-
-int zvideo_t::read_frame( uint8_t **output_rows,
-    int in_x, int in_y, int in_w, int in_h, 
-    int out_w, int out_h, int color_model)
-{
-  uint8_t *y, *u, *v;
-  int frame_number, result;
-  result = 0;
-  want_yvu = 0;
-  this->output_rows = output_rows;
-  this->color_model = color_model;
-
-/* Get scaling tables */
-  if( this->out_w != out_w || this->out_h != out_h ||
-      this->in_w != in_w   || this->in_h != in_h ||
-      this->in_x != in_x   || this->in_y != in_y) {
-    if(x_table) {
-      delete [] x_table;  x_table = 0;
-      delete [] y_table;  y_table = 0;
-    }
-  }
-
-  this->out_w = out_w; this->out_h = out_h;
-  this->in_w = in_w;   this->in_h = in_h;
-  this->in_x = in_x;   this->in_y = in_y;
-
-  if( !x_table ) {
-    x_table = get_scaletable(in_w, out_w);
-    y_table = get_scaletable(in_h, out_h);
-  }
-//zmsgs("mpeg3video_read_frame 1 %d\n", framenum);
-
-/* Recover from cache */
-  frame_number = frame_seek >= 0 ? frame_seek : framenum;
-  cache_t *cache = track->frame_cache;
-  if( frame_seek != last_number &&
-      cache->get_frame(frame_number, &y, &u, &v) ) {
-//zmsgs("1 %d\n", frame_number);
-    /* Transfer with cropping */
-    if( y ) present_frame(y, u, v);
-    /* Advance either framenum or frame_seek */
-    if( frame_number == framenum )
-      framenum = ++frame_number;
-    else if( frame_number == frame_seek )
-      frame_seek = ++frame_number;
-  }
-  else {
-    /* Only decode if it's a different frame */
-    if( frame_seek < 0 || last_number < 0 ||
-        frame_seek != last_number) {
-      if( !result ) result = seek();
-      if( !result ) result = read_frame_backend(0);
-    }
-    else {
-      framenum = frame_seek + 1;
-      last_number = frame_seek;
-      frame_seek = -1;
-    }
-    if( output_src[0] )
-      present_frame(output_src[0], output_src[1], output_src[2]);
-  }
-  return result;
-}
-
-int zvideo_t::
-read_yuvframe(char *y_output, char *u_output, char *v_output,
-              int in_x, int in_y, int in_w, int in_h)
-{
-  uint8_t *y = 0, *u = 0, *v = 0;
-  int result = 0;
-//zmsgs("1 %d\n", framenum);
-  want_yvu = 1;
-  this->y_output = y_output;
-  this->u_output = u_output;
-  this->v_output = v_output;
-  this->in_x = in_x;
-  this->in_y = in_y;
-  this->in_w = in_w;
-  this->in_h = in_h;
-
-  /* Recover from cache if framenum exists */
-  int frame_number = frame_seek >= 0 ? frame_seek : framenum;
-  cache_t *cache = track->frame_cache;
-  if( cache->get_frame(frame_number, &y, &u, &v) ) {
-//zmsgs("1 %d\n", frame_number);
-    /* Transfer with cropping */
-    if( y ) present_frame(y, u, v);
-    /* Advance either framenum or frame_seek */
-    if( frame_number == framenum )
-      framenum = ++frame_number;
-    else if( frame_number == frame_seek )
-      frame_seek = ++frame_number;
-  }
-  else {
-    if( !result ) result = seek();
-    if( !result ) result = read_frame_backend(0);
-    if( !result && output_src[0] )
-      present_frame(output_src[0], output_src[1], output_src[2]);
-  }
-
-  want_yvu = 0;
-  byte_seek = -1;
-  return result;
-}
-
-int zvideo_t::
-read_yuvframe_ptr(char **y_output, char **u_output, char **v_output)
-{
-  uint8_t *y, *u, *v;
-  int frame_number, result;
-  int debug = 0;
-  result = 0;
-  want_yvu = 1;
-  *y_output = *u_output = *v_output = 0;
-
-  frame_number = frame_seek >= 0 ? frame_seek : framenum;
-  cache_t *cache = track->frame_cache;
-  if( debug ) zmsgs("%d\n", __LINE__);
-  if( cache->get_frame(frame_number, &y, &u, &v) ) {
-    if( debug ) zmsgs("%d\n", __LINE__);
-    *y_output = (char*)y;
-    *u_output = (char*)u;
-    *v_output = (char*)v;
-    /* Advance either framenum or frame_seek */
-    if( frame_number == framenum )
-      framenum = ++frame_number;
-    else if( frame_number == frame_seek )
-      frame_seek = ++frame_number;
-    if( debug ) zmsgs("%d\n", __LINE__);
-  }
-  /* Only decode if it's a different frame */
-  else if( frame_seek < 0 || last_number < 0 ||
-           frame_seek != last_number) {
-    if( debug ) zmsgs("%d\n", __LINE__);
-    if( !result ) result = seek();
-    if( debug ) zmsgs("%d\n", __LINE__);
-    if( !result ) result = read_frame_backend(0);
-    if( debug ) zmsgs("%d\n", __LINE__);
-
-    if( output_src[0] ) {
-      *y_output = (char*)output_src[0];
-      *u_output = (char*)output_src[1];
-      *v_output = (char*)output_src[2];
-    }
-    if( debug ) zmsgs("%d\n", __LINE__);
-  }
-  else {
-    if( debug ) zmsgs("%d\n", __LINE__);
-    framenum = frame_seek + 1;
-    last_number = frame_seek;
-    frame_seek = -1;
-
-    if( output_src[0 ]) {
-      *y_output = (char*)output_src[0];
-      *u_output = (char*)output_src[1];
-      *v_output = (char*)output_src[2];
-    }
-    if( debug ) zmsgs("%d\n", __LINE__);
-  }
-
-  if( debug ) zmsgs("%d\n", __LINE__);
-  want_yvu = 0;
-/* Caching not used if byte seek */
-  byte_seek = -1;
-  return result;
-}
-
-int zvideo_t::
-colormodel()
-{
-  switch( chroma_format ) {
-    case cfmt_422: return cmdl_YUV422P; break;
-    case cfmt_420: return cmdl_YUV420P; break;
-  }
-  return cmdl_YUV420P;
-}
-
-zcc_t *zvideo_t::
-get_cc()
-{
-  if( !cc )
-    cc = new cc_t(this);
-  return cc;
-}
-
-void zvideo_t::
-reset_subtitles()
-{
-  for( int i=0; i<src->total_stracks; ++i ) {
-    strack_t *strack = src->strack[i];
-    if( strack->video != this ) continue;
-    strack->del_all_subtitles();
-  }
-}
-
-int zvideo_t::
-show_subtitle(int strk)
-{
-  int ret = subtitle_track;
-  if( subtitle_track != strk ) {
-    reset_subtitles();
-    subtitle_track = strk;
-    if( cc ) {
-      if( strk >= 0 ) cc->reset();
-      else { delete cc;  cc = 0; }
-    }
-  }
-  return ret;
-}
-
-void zvideo_t::
-dump()
-{
-  zmsg("\n");
-  zmsg(" *** sequence extension 1\n");
-  zmsgs("prog_seq=%d\n", prog_seq);
-  zmsg(" *** picture header 1\n");
-  zmsgs("pict_type=%d field_sequence=%d\n", pict_type, field_sequence);
-  zmsg(" *** picture coding extension 1\n");
-  zmsgs("field_sequence=%d repeatfirst=%d prog_frame=%d pict_struct=%d\n", 
-    field_sequence, repeatfirst, prog_frame, pict_struct);
-}
-