Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / libzmpeg3 / video / slice.C
diff --git a/cinelerra-5.0/libzmpeg3/video/slice.C b/cinelerra-5.0/libzmpeg3/video/slice.C
deleted file mode 100644 (file)
index b880f7f..0000000
+++ /dev/null
@@ -1,933 +0,0 @@
-#include "../libzmpeg3.h"
-
-#ifdef __x86_64__
-#define USE_MMX
-#endif
-#ifdef USE_MMX
-#include "mmx.h"
-#if defined(__x86_64__)
-#define m_(v) (*(mmx_t*)(v))
-#else
-#define m_(v) (*(char*)(v))
-#endif
-#endif
-
-
-
-zslice_buffer_t::
-slice_buffer_t()
-{
-  data = new uint8_t[buffer_allocation=4096];
-  buffer_size = 0;
-  buffer_position = 0;
-  bits_size = 0;
-  bits = 0;
-}
-
-zslice_buffer_t::
-~slice_buffer_t()
-{
-  delete [] data;
-}
-
-uint8_t *zslice_buffer_t::
-expand_buffer(int bfrsz)
-{
-  long new_allocation = 2*buffer_allocation;
-  uint8_t *new_buffer = new uint8_t[new_allocation];
-  if( bfrsz > 0 ) memcpy(new_buffer,data,bfrsz);
-  delete [] data;
-  data = new_buffer;
-  buffer_allocation = new_allocation;
-  buffer_size = buffer_allocation-bfrsz-4;
-  return data + bfrsz;
-}
-
-    
-void zslice_buffer_t::
-fill_buffer(zbits_t *vstream)
-{
-  uint8_t *sbp = data;
-  vstream->next_byte_align();
-  demuxer_t *demux = vstream->demuxer;
-  /* sync stream to zcode and access demuxer */
-  uint32_t zcode = vstream->show_bits32_noptr();
-  for( int i=32; i>0; ) *sbp++ = (zcode>>(i-=8));
-  vstream->reset();
-  buffer_size = buffer_allocation-(4+4); /* sizeof(zcode)+padding */
-
-  /* Read the slice into the buffer including the slice start code */
-  while( !vstream->eof() ) {
-    if( buffer_size <= 0 ) sbp = expand_buffer(sbp - data);
-    if( (zcode&0xff) != 0 ) {
-      buffer_size -= 3;
-      zcode = (zcode<<8) | (*sbp++ = demux->read_char());
-      zcode = (zcode<<8) | (*sbp++ = demux->read_char());
-    }
-    else
-      --buffer_size;
-    zcode = (zcode<<8) | (*sbp++ = demux->read_char());
-    if( (zcode&0xffffff) == PACKET_START_CODE_PREFIX ) break;
-  }
-
-  /* finish trailing code as picture start code (0x100) */
-  *sbp++ = 0;
-  buffer_size = sbp - data;
-  /* reload stream bfr, position to start code */
-  vstream->reset(zcode);
-  vstream->get_byte_noptr();
-}
-
-/* limit coefficients to -2048..2047 */
-
-/* move/add 8x8-Block from block[comp] to refframe */
-
-int zslice_decoder_t::
-add_block(int comp, int bx, int by, int dct_type, int addflag)
-{
-  int cc, i, iincr;
-  uint8_t *rfp;
-  short *bp;
-  /* color component index */
-  cc = (comp < 4) ? 0 : (comp & 1) + 1; 
-
-  if( cc == 0 ) {   
-    /* luminance */
-    if( video->pict_struct == video_t::pics_FRAME_PICTURE ) {
-      if( dct_type ) {
-        /* field DCT coding */
-        rfp = video->newframe[0] + video->coded_picture_width *
-                (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3);
-        iincr = (video->coded_picture_width << 1);
-      }
-      else {
-        /* frame DCT coding */
-        rfp = video->newframe[0] + video->coded_picture_width *
-                (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
-        iincr = video->coded_picture_width;
-      }
-    }
-    else {
-      /* field picture */
-      rfp = video->newframe[0] + (video->coded_picture_width << 1) *
-              (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
-      iincr = (video->coded_picture_width << 1);
-    }
-  }
-  else {
-    /* chrominance */
-
-    /* scale coordinates */
-    if( video->chroma_format != video_t::cfmt_444 ) bx >>= 1;
-    if( video->chroma_format == video_t::cfmt_420 ) by >>= 1;
-    if( video->pict_struct == video_t::pics_FRAME_PICTURE ) {
-      if( dct_type && (video->chroma_format != video_t::cfmt_420) ) {
-        /* field DCT coding */
-        rfp = video->newframe[cc] + video->chrom_width *
-                (by + ((comp & 2) >> 1)) + bx + (comp & 8);
-        iincr = (video->chrom_width << 1);
-      }
-      else {
-        /* frame DCT coding */
-        rfp = video->newframe[cc] + video->chrom_width *
-                (by + ((comp & 2) << 2)) + bx + (comp & 8);
-        iincr = video->chrom_width;
-      }
-    }
-    else {
-      /* field picture */
-      rfp = video->newframe[cc] + (video->chrom_width << 1) *
-              (by + ((comp & 2) << 2)) + bx + (comp & 8);
-      iincr = (video->chrom_width << 1);
-    }
-  }
-
-  bp = block[comp];
-
-  if( addflag ) {
-    for( i=0; i<8; ++i ) {
-#ifndef USE_MMX
-      rfp[0] = clip(bp[0] + rfp[0]);
-      rfp[1] = clip(bp[1] + rfp[1]);
-      rfp[2] = clip(bp[2] + rfp[2]);
-      rfp[3] = clip(bp[3] + rfp[3]);
-      rfp[4] = clip(bp[4] + rfp[4]);
-      rfp[5] = clip(bp[5] + rfp[5]);
-      rfp[6] = clip(bp[6] + rfp[6]);
-      rfp[7] = clip(bp[7] + rfp[7]);
-#else
-      movq_m2r(m_(rfp),mm1);      /* rfp[0..7] */
-      pxor_r2r(mm3,mm3);          /* zero */
-      pxor_r2r(mm4,mm4);          /* zero */
-      movq_m2r(m_(bp+0),mm5);     /* bp[0..3] */
-      movq_r2r(mm1,mm2);          /* copy rfp[0..7] */
-      movq_m2r(m_(bp+4),mm6);     /* bp[4..7] */
-      punpcklbw_r2r(mm3,mm1);     /* rfp[0..3] */
-      punpckhbw_r2r(mm3,mm2);     /* rfp[4..7] */
-      paddsw_r2r(mm5,mm1);        /* + bp[0..3] */
-      paddsw_r2r(mm6,mm2);        /* + bp[4..7] */
-      pcmpgtw_r2r(mm1,mm3);       /* 1s to fields < 0 */
-      pcmpgtw_r2r(mm2,mm4);       /* 1s to fields < 0 */
-      pandn_r2r(mm1,mm3);         /* clip <0 = zero */
-      pandn_r2r(mm2,mm4);         /* clip <0 = zero */
-      packuswb_r2r(mm4,mm3);      /* pack/clip >255 = 255 */
-      movq_r2m(mm3,m_(rfp));      /* store rfp[0..7] */
-#endif
-      rfp += iincr;
-      bp += 8;
-    }
-  }
-  else {
-    for( i=0; i<8; ++i ) {
-#ifndef USE_MMX
-      rfp[0] = clip(bp[0] + 128);
-      rfp[1] = clip(bp[1] + 128);
-      rfp[2] = clip(bp[2] + 128);
-      rfp[3] = clip(bp[3] + 128);
-      rfp[4] = clip(bp[4] + 128);
-      rfp[5] = clip(bp[5] + 128);
-      rfp[6] = clip(bp[6] + 128);
-      rfp[7] = clip(bp[7] + 128);
-#else
-      static short i128[4] = { 128, 128, 128, 128 };
-      movq_m2r(m_(i128),mm1);     /* 128,,128 */
-      pxor_r2r(mm3,mm3);          /* zero */
-      pxor_r2r(mm4,mm4);          /* zero */
-      movq_m2r(m_(bp+0),mm5);     /* bp[0..3] */
-      movq_r2r(mm1,mm2);          /* 128,,128 */
-      movq_m2r(m_(bp+4),mm6);     /* bp[4..7] */
-      paddsw_r2r(mm5,mm1);        /* + bp[0..3] */
-      paddsw_r2r(mm6,mm2);        /* + bp[4..7] */
-      pcmpgtw_r2r(mm1,mm3);       /* 1s to fields < 0 */
-      pcmpgtw_r2r(mm2,mm4);       /* 1s to fields < 0 */
-      pandn_r2r(mm1,mm3);         /* clip <0 = zero */
-      pandn_r2r(mm2,mm4);         /* clip <0 = zero */
-      packuswb_r2r(mm4,mm3);      /* pack/clip >255 = 255 */
-      movq_r2m(mm3,m_(rfp));      /* store rfp[0..7] */
-#endif
-      rfp+= iincr;
-      bp += 8;
-    }
-  }
-#ifdef USE_MMX
-  emms();
-#endif
-  return 0;
-}
-
-
-uint8_t zslice_decoder_t::
-non_linear_mquant_table[32] = {
-   0,  1,  2,  3,  4,  5,  6,  7,
-   8, 10, 12, 14, 16, 18, 20, 22,
-  24, 28, 32, 36, 40, 44, 48, 52,
-  56, 64, 72, 80, 88, 96,104,112,
-};
-
-int zslice_decoder_t::
-decode_slice()
-{
-  int comp;
-  int mb_type, cbp, motion_type = 0, dct_type;
-  int macroblock_address, mba_inc, mba_max;
-  int slice_vert_pos_ext;
-  uint32_t zcode;
-  int dc_dct_pred[3];
-  int mv_count, mv_format, mvscale;
-  int pmv[2][2][2], mv_field_sel[2][2];
-  int dmv, dmvector[2];
-  int qs;
-  int stwtype, stwclass; 
-  int snr_cbp;
-  int i;
-  /* number of macroblocks per picture */
-  mba_max = video->mb_width * video->mb_height;
-
-  /* field picture has half as many macroblocks as frame */
-  if( video->pict_struct != video_t::pics_FRAME_PICTURE )
-    mba_max >>= 1; 
-  macroblock_address = 0; 
-  /* first macroblock in slice is not skipped */
-  mba_inc = 0;
-  fault = 0;
-  zcode = slice_buffer->get_bits(32);
-  /* decode slice header (may change quant_scale) */
-  slice_vert_pos_ext = get_slice_hdr();
-  /* reset all DC coefficient and motion vector predictors */
-  dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
-  pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
-  pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
-
-  for( i=0; !slice_buffer->eob(); ++i ) {
-    if( mba_inc == 0 ) {
-      if( !slice_buffer->show_bits(23) ) break; /* Done */
-      /* decode macroblock address increment */
-      mba_inc = get_macroblock_address();
-      if( fault ) return 1;
-      if( i == 0 ) {
-        /* Get the macroblock_address */
-        int mline = (slice_vert_pos_ext << 7) + (zcode&0xff) - 1;
-        macroblock_address = mline * video->mb_width + mba_inc - 1;
-        /* first macroblock in slice: not skipped */
-        mba_inc = 1;
-      }
-    }
-
-    if( fault ) return 1;
-    if( macroblock_address >= mba_max ) {
-      /* mba_inc points beyond picture dimensions */
-//zerr("too many macroblocks in picture\n"); */
-        return 1;
-    }
-
-    /* not skipped */
-    if( mba_inc == 1 ) {
-      macroblock_modes(&mb_type, &stwtype, &stwclass, &motion_type,
-        &mv_count, &mv_format, &dmv, &mvscale, &dct_type);
-      if( fault ) return 1;
-
-      if( mb_type & mb_QUANT ) {
-        qs = slice_buffer->get_bits(5);
-        if( video->mpeg2 )
-          quant_scale = video->qscale_type ?
-            non_linear_mquant_table[qs] : (qs << 1);
-        else 
-          quant_scale = qs;
-
-        /* make sure quant_scale is valid */
-        if( video->scalable_mode == sc_DP )
-          quant_scale = quant_scale; /*???*/
-      }
-
-      /* motion vectors */
-
-      /* decode forward motion vectors */
-      if( (mb_type & mb_FORWARD) ||
-          ((mb_type & mb_INTRA) && video->conceal_mv) ) {
-        if( video->mpeg2 )
-          motion_vectors(pmv, dmvector, mv_field_sel, 0, mv_count, mv_format,
-            video->h_forw_r_size, video->v_forw_r_size, dmv, mvscale);
-        else
-          motion_vector(pmv[0][0], dmvector,
-            video->forw_r_size, video->forw_r_size, 0, 0, video->full_forw);
-      }
-      if( fault ) return 1;
-
-      /* decode backward motion vectors */
-      if( mb_type & mb_BACKWARD ) {
-        if( video->mpeg2 )
-          motion_vectors(pmv, dmvector, mv_field_sel, 1, mv_count, mv_format, 
-          video->h_back_r_size, video->v_back_r_size, 0, mvscale);
-        else
-          motion_vector(pmv[0][1], dmvector, 
-            video->back_r_size, video->back_r_size, 0, 0, video->full_back);
-      }
-
-      if( fault ) return 1;
-
-      /* remove marker_bit */
-      if( (mb_type & mb_INTRA) && video->conceal_mv )
-        slice_buffer->flush_bit();
-
-      /* macroblock_pattern */
-      if( mb_type & mb_PATTERN ) {
-        cbp = get_cbp();
-        if( video->chroma_format == video_t::cfmt_422 ) {
-          /* coded_block_pattern_1 */
-          cbp = (cbp << 2) | slice_buffer->get_bits(2); 
-        }
-        else if( video->chroma_format == video_t::cfmt_444 ) {
-          /* coded_block_pattern_2 */
-          cbp = (cbp << 6) | slice_buffer->get_bits(6); 
-        }
-      }
-      else
-        cbp = (mb_type & mb_INTRA) ? ((1 << video->blk_cnt) - 1) : 0;
-      if( fault ) return 1;
-
-      /* decode blocks */
-      clear_block(0, video->blk_cnt);
-      for( comp=0; comp<video->blk_cnt; ++comp ) {
-        if( cbp & (1 << (video->blk_cnt-comp-1)) ) {
-          if( mb_type & mb_INTRA ) {
-            if( video->mpeg2 )
-              get_mpg2_intra_block(comp, dc_dct_pred);
-            else
-              get_intra_block(comp, dc_dct_pred);
-          }
-          else {
-            if( video->mpeg2 )
-              get_mpg2_inter_block(comp);
-            else           
-              get_inter_block(comp);
-          }
-          if( fault ) return 1;
-        }
-      }
-
-      /* reset intra_dc predictors */
-      if( !(mb_type & mb_INTRA) )
-        dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
-
-      /* reset motion vector predictors */
-      if( (mb_type & mb_INTRA) && !video->conceal_mv ) {
-        /* intra mb without concealment motion vectors */
-        pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
-        pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
-      }
-
-      if( (video->pict_type == video_t::pic_type_P) &&
-          !(mb_type & (mb_FORWARD | mb_INTRA)) ) {
-        /* non-intra mb without forward mv in a P picture */
-        pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
-
-        /* derive motion_type */
-        if( video->pict_struct == video_t::pics_FRAME_PICTURE )
-          motion_type = mc_FRAME;
-        else {
-          motion_type = mc_FIELD;
-          /* predict from field of same parity */
-          mv_field_sel[0][0] = video->pict_struct == video_t::pics_BOTTOM_FIELD ? 1 : 0;
-        }
-      }
-
-      if( stwclass == 4 ) {
-        /* purely spatially predicted macroblock */
-        pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
-        pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
-      }
-    }
-    else {
-      /* mba_inc!=1: skipped macroblock */
-      clear_block(0, video->blk_cnt);
-
-      /* reset intra_dc predictors */
-      dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
-
-      /* reset motion vector predictors */
-      if( video->pict_type == video_t::pic_type_P )
-        pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
-
-      /* derive motion_type */
-      if( video->pict_struct == video_t::pics_FRAME_PICTURE )
-        motion_type = mc_FRAME;
-      else {
-        motion_type = mc_FIELD;
-        /* predict from field of same parity */
-        mv_field_sel[0][0] = mv_field_sel[0][1] =
-          (video->pict_struct == video_t::pics_BOTTOM_FIELD) ? 1 : 0;
-      }
-
-      /* skipped I are spatial-only predicted, */
-      /* skipped P and B are temporal-only predicted */
-      stwtype = video->pict_type == video_t::pic_type_I ? 8 : 0;
-      mb_type &= ~mb_INTRA; /* clear mb_INTRA */
-      cbp = 0; /* no block data */
-    }
-
-    snr_cbp = 0;
-
-    /* pixel coordinates of top left corner of current macroblock */
-    int mx = macroblock_address % video->mb_width;
-    int my = macroblock_address / video->mb_width;
-
-    /* thumbnails */
-    if( video->thumb && video->pict_type == video_t::pic_type_I ) {
-      uint8_t *ap = video->tdat + 4*my*video->mb_width + 2*mx;
-      uint8_t *bp = ap + 2*video->mb_width;
-      if( (mb_type&mb_INTRA) != 0 ) {
-        *ap = clip(128 + block[0][0]/8);  ++ap;
-        *ap = clip(128 + block[1][0]/8);
-        *bp = clip(128 + block[2][0]/8);  ++bp;
-        *bp = clip(128 + block[3][0]/8);
-      }
-      else {
-        *ap = clip(*ap + block[0][0]/8);  ++ap;
-        *ap = clip(*ap + block[1][0]/8);
-        *bp = clip(*bp + block[2][0]/8);  ++bp;
-        *bp = clip(*bp + block[3][0]/8);
-      }
-    }
-    /* skimming */
-    if( !video->skim ) {
-      int bx = 16*mx, by = 16*my;
-      /* motion compensation */
-      if( !(mb_type & mb_INTRA) )
-        video->reconstruct( bx, by, mb_type, motion_type, pmv, 
-          mv_field_sel, dmvector, stwtype);
-
-      /* copy or add block data into picture */
-      for( comp=0; comp<video->blk_cnt; ++comp ) {
-        if( (cbp | snr_cbp) & (1 << (video->blk_cnt-1-comp)) ) {
-          idct_conversion(block[comp]);
-          add_block(comp, bx, by, dct_type, !(mb_type & mb_INTRA) ? 1 : 0);
-        }
-      }
-    }
-
-    /* advance to next macroblock */
-    ++macroblock_address;
-    --mba_inc;
-  }
-
-  return 0;
-}
-
-void zslice_decoder_t::
-slice_loop()
-{
-  while( !done ) {
-    input_lock.lock();
-    while( !done ) {
-      decode_slice();
-      video->put_slice_buffer(slice_buffer);
-      if( get_active_slice_buffer() ) break;
-    }
-  }
-}
-
-void *zslice_decoder_t::
-the_slice_loop(void *the_slice_decoder)
-{
-  ((slice_decoder_t *)the_slice_decoder)->slice_loop();
-  return 0;
-}
-
-zslice_decoder_t::
-slice_decoder_t()
-{
-  owner = pthread_self();
-  video = 0;
-  slice_buffer = 0;
-  done = 0;
-  input_lock.lock();
-  pthread_create(&tid,0,the_slice_loop, this);
-}
-
-zslice_decoder_t::
-~slice_decoder_t()
-{
-  done = 1;
-  input_lock.unlock();
-  pthread_join(tid, 0);
-}
-
-
-int zslice_decoder_t::
-get_cbp()
-{
-  int zcode;
-  if( (zcode=slice_buffer->show_bits(9)) >= 128 ) {
-    zcode >>= 4;
-    slice_buffer->flush_bits(CBPtab0[zcode].len);
-    return CBPtab0[zcode].val;
-  }
-
-  if( zcode >= 8 ) {
-    zcode >>= 1;
-    slice_buffer->flush_bits(CBPtab1[zcode].len);
-    return CBPtab1[zcode].val;
-  }
-
-  if( zcode < 1 ) {
-//zerr("invalid coded_block_pattern code\n");
-    fault = 1;
-    return 0;
-  }
-
-  slice_buffer->flush_bits(CBPtab2[zcode].len);
-  return CBPtab2[zcode].val;
-}
-
-
-/* set block to zero */
-int zslice_decoder_t::
-clear_block(int comp, int size)
-{
-  sparse[comp] = 1;
-  memset(block[comp], 0, size*sizeof(block[0]));
-  return 0;
-}
-
-int zslice_buffer_t::
-get_dc_lum()
-{
-  int zcode, size, val;
-  zcode = show_bits(5); /* decode length */
-  if( zcode < 31 ) {
-    size = DClumtab0[zcode].val;
-    flush_bits(DClumtab0[zcode].len);
-  }
-  else {
-    zcode = show_bits(9) - 0x1f0;
-    size = DClumtab1[zcode].val;
-    flush_bits(DClumtab1[zcode].len);
-  }
-
-  if( size ) {
-    val = get_bits(size);
-    if( (val & (1 << (size-1))) == 0 )
-      val -= (1 << size)-1;
-  }
-  else
-    val = 0;
-
-  return val;
-}
-
-
-int zslice_buffer_t::
-get_dc_chrom()
-{
-  int zcode, size, val;
-  zcode = show_bits(5); /* decode length */
-  if( zcode < 31 ) {
-    size = DCchromtab0[zcode].val;
-    flush_bits(DCchromtab0[zcode].len);
-  }
-  else {
-    zcode = show_bits(10) - 0x3e0;
-    size = DCchromtab1[zcode].val;
-    flush_bits(DCchromtab1[zcode].len);
-  }
-
-  if( size ) {
-    val = get_bits(size);
-    if( (val & (1 << (size-1))) == 0 )
-      val -= (1 << size)-1;
-  }
-  else 
-    val = 0;
-
-  return val;
-}
-
-uint16_t *zslice_decoder_t::DCTlutab[3] = { 0, };
-
-void zslice_decoder_t::
-init_lut(uint16_t *&lutbl, DCTtab_t *tabn, DCTtab_t *tab0, DCTtab_t *tab1)
-{
-  int i = 0;
-  uint16_t *lut = new uint16_t[0x10000];
-  while( i < 0x0010 ) { lut[i] = 0;  ++i; }
-  while( i < 0x0020 ) { lut[i] = lu_pack(&DCTtab6[i - 16]);         ++i; }
-  while( i < 0x0040 ) { lut[i] = lu_pack(&DCTtab5[(i >> 1) - 16]);  ++i; }
-  while( i < 0x0080 ) { lut[i] = lu_pack(&DCTtab4[(i >> 2) - 16]);  ++i; }
-  while( i < 0x0100 ) { lut[i] = lu_pack(&DCTtab3[(i >> 3) - 16]);  ++i; }
-  while( i < 0x0200 ) { lut[i] = lu_pack(&DCTtab2[(i >> 4) - 16]);  ++i; }
-  while( i < 0x0400 ) { lut[i] = lu_pack(   &tab1[(i >> 6) - 8]);   ++i; }
-  int tblsz = !tabn ? 0x10000 : 0x4000;
-  while( i < tblsz  ) { lut[i] = lu_pack(   &tab0[(i >> 8) - 4]);   ++i; }
-  while( i <0x10000 ) { lut[i] = lu_pack(   &tabn[(i >>12) - 4]);   ++i; }
-  lutbl = lut;
-}
-
-void zslice_decoder_t::
-init_tables()
-{
-  if( DCTlutab[0] ) return;
-  init_lut(DCTlutab[0], DCTtabfirst, DCTtab0,  DCTtab1);
-  init_lut(DCTlutab[1], DCTtabnext , DCTtab0,  DCTtab1);
-  init_lut(DCTlutab[2],          0 , DCTtab0a, DCTtab1a);
-}
-
-/* decode one MPEG-1 coef */
-
-inline int zslice_decoder_t::
-get_coef(uint16_t *lut)
-{
-  int v, s, i = idx;
-  uint16_t zcode = slice_buffer->show_bits(16);
-  uint16_t lu = lut[zcode];
-  if( !lu ) return fault = 1;
-  int len = lu_len(lu);
-  slice_buffer->flush_bits(len);
-  int run = lu_run(lu);
-  if( run >= 32 ) {       /* escape */
-    if( run == 32 ) return -1;  /* end of block */
-    i += slice_buffer->get_bits(6);
-    if( (v = slice_buffer->get_bits(8)) < 128 ) {
-      s = 0;
-      if( !v ) v = slice_buffer->get_bits(8);
-    }
-    else {
-      if( v == 128 ) v = slice_buffer->get_bits(8);
-      s = 1;  v = 256 - v;
-    }
-  }
-  else {
-    i += run;
-    v = lu_level(lu);
-    s = slice_buffer->get_bit();
-  }
-  if( i >= 64 ) return fault = 1;
-  val = v;  sign = s;  idx = i;
-  return 0;
-}
-
-/* decode one MPEG-2 coef */
-
-inline int zslice_decoder_t::
-get_mpg2_coef(uint16_t *lut)
-{
-  int v, s, i = idx;
-  uint16_t zcode = slice_buffer->show_bits(16);
-  uint16_t lu = lut[zcode];
-  if( !lu ) return fault = 1;
-  int len = lu_len(lu);
-  slice_buffer->flush_bits(len);
-  int run = lu_run(lu);
-  if( run >= 32 ) {       /* escape */
-    if( run == 32 ) return -1;  /* end of block */
-    i += slice_buffer->get_bits(6);
-    v = slice_buffer->get_bits(12);
-    if( (v & 2047) == 0 ) return fault = 1;
-    s = (v >= 2048) ? 1 : 0;
-    if( s != 0 ) v = 4096 - v;
-  }
-  else {
-    i += run;
-    v = lu_level(lu);
-    s = slice_buffer->get_bit();
-  }
-  if( i >= 64 ) return fault = 1;
-  val = v;  sign = s;  idx = i;
-  return 0;
-}
-
-
-/* decode one intra coded MPEG-1 block */
-
-void zslice_decoder_t::
-get_intra_block(int comp, int dc_dct_pred[])
-{
-  int dc_coef = /* decode DC coefficients */
-    comp <  4 ? (dc_dct_pred[0] += slice_buffer->get_dc_lum())   :
-    comp == 4 ? (dc_dct_pred[1] += slice_buffer->get_dc_chrom()) :
-                (dc_dct_pred[2] += slice_buffer->get_dc_chrom()) ;
-  short *bp = block[comp];
-  bp[0] = dc_coef << 3;
-
-  /* decode AC coefficients */
-  int *qmat = video->intra_quantizer_matrix;
-  int j = 0;
-  idx = 1;
-  while( !get_coef(DCTlutab[1]) ) {
-    j = video->zigzag_scan_table[idx++];
-    int v = (((val * quant_scale*qmat[j])>>3)-1) | 1;
-    bp[j] = sign ? -v : v;
-  }
-
-  if( j > 0 ) /* not a sparse matrix ! */
-    sparse[comp] = 0;
-}
-
-/* decode one intra coded MPEG-2 block */
-void zslice_decoder_t::
-get_mpg2_intra_block(int comp, int dc_dct_pred[])
-{
-  int *qmat = (comp < 4 || video->chroma_format == video_t::cfmt_420) ?
-    video->intra_quantizer_matrix : video->chroma_intra_quantizer_matrix;
-  int dc_coef = /* decode DC coefficients */
-    comp < 4  ? (dc_dct_pred[0] += slice_buffer->get_dc_lum())   :
-    !(comp&1) ? (dc_dct_pred[1] += slice_buffer->get_dc_chrom()) :
-                (dc_dct_pred[2] += slice_buffer->get_dc_chrom()) ;
-/* with data partitioning, data always goes to base layer */
-  short *bp = block[comp]; 
-  bp[0] = dc_coef << (3 - video->dc_prec);
-
-  uint8_t *scan_table = video->altscan ?
-    video->alternate_scan_table : video->zigzag_scan_table;
-  uint16_t *lutbl = !video->intravlc ? DCTlutab[1] : DCTlutab[2];
-
-  int j = 0;
-  idx = 1;
-  while( !get_mpg2_coef(lutbl) ) { /* decode AC coefficients */
-    j = scan_table[idx++];
-    int v = (val * quant_scale*qmat[j]) >> 4;
-    bp[j] = sign ? -v : v;
-  }
-
-  if( j > 0 ) /* not a sparse matrix ! */
-    sparse[comp] = 0;
-}
-
-
-/* decode one non-intra coded MPEG-1 block */
-
-void zslice_decoder_t::
-get_inter_block(int comp)
-{
-  short *bp = block[comp];
-
-  idx = 0;
-  if( get_coef(DCTlutab[0])) return;
-  int j = video->zigzag_scan_table[idx++];
-  int *qmat = video->non_intra_quantizer_matrix;
-  int v = (((((val<<1) + 1) * quant_scale*qmat[j])>>4)-1) | 1;
-  bp[j] = sign ? -v : v;
-
-  /* decode AC coefficients */
-  while( !get_coef(DCTlutab[1]) ) {
-    j = video->zigzag_scan_table[idx++];
-    v = (((((val<<1) + 1) * quant_scale*qmat[j])>>4)-1) | 1;
-    bp[j] = sign ? -v : v;
-  }
-
-  if( j > 0 ) /* not a sparse matrix ! */
-    sparse[comp] = 0;
-}
-
-
-/* decode one non-intra coded MPEG-2 block */
-
-void zslice_decoder_t::
-get_mpg2_inter_block(int comp)
-{
-  /* with data partitioning, data always goes to base layer */
-  short *bp = block[comp];
-  int *qmat = (comp < 4 || video->chroma_format == video_t::cfmt_420) ?
-    video->non_intra_quantizer_matrix : video->chroma_non_intra_quantizer_matrix;
-  uint8_t *scan_table = video->altscan ?
-    video->alternate_scan_table : video->zigzag_scan_table;
-
-  idx = 0;
-  if( get_mpg2_coef(DCTlutab[0]) ) return;
-  int j = scan_table[idx++];
-  int v = (((val << 1)+1) * quant_scale*qmat[j]) >> 5;
-  bp[j] = sign ? -v : v ;
-
-  /* decode AC coefficients */
-  while( !get_mpg2_coef(DCTlutab[1]) ) {
-    j = scan_table[idx++];
-    int v = (((val << 1)+1) * quant_scale*qmat[j]) >> 5;
-    bp[j] = sign ? -v : v ;
-  }
-
-  if( j > 0 ) /* not a sparse matrix ! */
-    sparse[comp] = 0;
-}
-
-
-void zmpeg3_t::
-decode_slice(zslice_buffer_t *buffer)
-{
-  decoder_lock.lock();
-  if( avail_slice_decoders ) {
-    zslice_decoder_t *decoder = avail_slice_decoders;
-    avail_slice_decoders = decoder->next;
-    decoder->slice_buffer = buffer;
-    decoder->video = buffer->video;
-    if( !decoder_active_locked++ )
-      decoder_active.lock();
-    decoder->input_lock.unlock();
-  }
-  else {
-    buffer->next = active_slice_buffers;
-    active_slice_buffers = buffer;
-  }
-  decoder_lock.unlock();
-}
-
-int zslice_decoder_t::
-get_active_slice_buffer()
-{
-  int result;
-  src->decoder_lock.lock();
-  zslice_buffer_t *buffer = src->active_slice_buffers;
-  if( !buffer ) {
-    next = src->avail_slice_decoders;
-    src->avail_slice_decoders = this;
-    if( !--src->decoder_active_locked )
-      src->decoder_active.unlock();
-    slice_buffer = 0;
-    video = 0;
-    result = 1;
-  }
-  else {
-    src->active_slice_buffers = buffer->next;
-    slice_buffer = buffer;
-    video = buffer->video;
-    result = 0;
-  }
-  src->decoder_lock.unlock();
-  return result;
-}
-
-void zmpeg3_t::
-allocate_slice_decoders()
-{
-  if( slice_decoders ) return;
-  int count = cpus;
-  if( count > MAX_CPUS ) count = MAX_CPUS;
-  slice_decoders = new slice_decoder_t[count];
-  slice_decoder_t *decoder = &slice_decoders[0];
-  avail_slice_decoders = 0;
-  for( int i=count; --i>=0; ++decoder ) {
-    decoder->src = this;
-    decoder->next = avail_slice_decoders;
-    avail_slice_decoders = decoder;
-  }
-  total_slice_decoders = count;
-}
-
-void zmpeg3_t::
-delete_slice_decoders()
-{
-  if( !slice_decoders ) return;
-  delete [] slice_decoders;
-  slice_decoders = 0;
-  total_slice_decoders = 0;
-}
-
-void zmpeg3_t::
-reallocate_slice_decoders()
-{
-  decoder_active.lock();
-  decoder_active.unlock();
-  decoder_lock.lock();
-  if( !decoder_active_locked ) {
-    delete_slice_decoders();
-    allocate_slice_decoders();
-  }
-  decoder_lock.unlock();
-}
-
-void zvideo_t::
-allocate_slice_buffers()
-{
-  if( slice_buffers ) return;
-  int count = 2*src->cpus;
-  if( count > 2*MAX_CPUS ) count = 2*MAX_CPUS;
-  slice_buffers = new slice_buffer_t[count];
-  slice_buffer_t *buffer = &slice_buffers[0];
-  avail_slice_buffers = 0;
-  for( int i=count; --i>=0; ++buffer ) {
-    buffer->next = avail_slice_buffers;
-    avail_slice_buffers = buffer;
-  }
-  total_slice_buffers = count;
-}
-
-void zvideo_t::
-delete_slice_buffers()
-{
-  if( !slice_buffers ) return;
-  delete [] slice_buffers;
-  slice_buffers = 0;
-  total_slice_buffers = 0;
-}
-
-void zvideo_t::
-reallocate_slice_buffers()
-{
-  slice_active.lock();
-  slice_active.unlock();
-  slice_lock.lock();
-  if( !slice_active_locked ) {
-    delete_slice_buffers();
-    allocate_slice_buffers();
-  }
-  slice_lock.unlock();
-} 
-