+++ /dev/null
-#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();
-}
-