X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;ds=sidebyside;f=cinelerra-5.0%2Flibzmpeg3%2Fvideo%2Fslice.C;fp=cinelerra-5.0%2Flibzmpeg3%2Fvideo%2Fslice.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=b880f7ffdc021f08789e684d44c4d7abea849f74;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/libzmpeg3/video/slice.C b/cinelerra-5.0/libzmpeg3/video/slice.C deleted file mode 100644 index b880f7ff..00000000 --- a/cinelerra-5.0/libzmpeg3/video/slice.C +++ /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; compblk_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; compblk_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(); -} -