📄 getpic.cc
字号:
/* File: getpic.cc*/#include <string.h>#include "all.hh"#ifdef HAVE_MMXextern "C" void IDCT_mmx(short *);extern "C" void add_block_mmx(unsigned char *, short *, int);extern "C" void set_block_mmx(unsigned char *, short *, int);static unsigned long long MMX_128 = 0x80008000800080LL;#endif/* ---------------------------------------------------*/static void j_rev_dct_sparse (short *data){ short int val; int v; int quant; v = *data;#ifdef HAVE_MMX quant = 8 * 16;#else quant = 8;#endif if (v < 0) { val = -v; val += (quant >> 1); val /= quant; val = -val; } else { val = (v + (quant >> 1)) / quant; } *data = val; return;}// decode one frame or field picturevoid LayerData::getpicture(int framenum){ if (pict_struct==FRAME_PICTURE && secondfield){ /* recover from illegal number of field pictures */ printf("odd number of field pictures\n"); secondfield = 0; } for (int i=0; i<3; i++){ if (pict_type==B_TYPE) newframe[i] = auxframe[i]; else { if (!secondfield){ unsigned char* tmp = oldrefframe[i]; oldrefframe[i] = refframe[i]; refframe[i] = tmp; } newframe[i] = refframe[i]; } if (pict_struct==BOTTOM_FIELD) newframe[i]+= (i==0) ? coded_picture_width : chrom_width; }//if (pict_scal && !secondfield) getspatref(); getMBs(framenum); if (framenum!=0){ if (pict_struct==FRAME_PICTURE || secondfield){ if (pict_type==B_TYPE) display->dither(auxframe); else display->dither(oldrefframe); } else display->display_second_field(); } if (pict_struct!=FRAME_PICTURE) secondfield = !secondfield;}// store last framevoid LayerData::putlast(){ if (secondfield) printf("last frame incomplete, not stored\n"); else display->dither(refframe);}/* decode all macroblocks of the current picture */void LayerData::getMBs(int framenum){ int comp; int MBA, MBAmax, MBAinc, mb_type, cbp, motion_type(0), dct_type; int slice_vert_pos_ext; int bx, by; unsigned int code; 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 SNRcbp;// int SNRMBA(0), SNRmb_type,, SNRMBAinc(0), SNRdct_type, dummy; // SNR scal. /* number of macroblocks per picture */ MBAmax = mb_width*mb_height; if (pict_struct!=FRAME_PICTURE) MBAmax>>=1; /* field picture has half as mnay macroblocks as frame */ MBA = 0; /* macroblock address */ MBAinc = 0;/* if (twostreams && enhan.scalable_mode==SC_SNR){ SNRMBA=0; SNRMBAinc=0; }*/ fault=0; for (;;){#ifdef TRACE if (trace) printf("frame %d, MB %d\n",framenum,MBA);#endif if (!prog_seq && pict_struct==FRAME_PICTURE && MBA==(MBAmax>>1) && framenum!=0)// && display->getType()==T_X11) display->display_second_field();// ld = &base; if (MBAinc==0){// if (scalable_mode==SC_DP && pri_brk==1) ld = &enhan; if (!input->showbits(23) || fault){ /* startcode or fault */resync: /* if fault: resynchronize to next startcode */ fault = 0; if (MBA>=MBAmax) return; /* all macroblocks decoded */ code=input->startcode(); if (code<Slice_min_start || code>Slice_max_start){ /* only slice headers are allowed in picture_data */ if (!quiet) printf("Premature end of picture\n"); return; } input->flushbits(32); /* decode slice header (may change quant_scale) */ slice_vert_pos_ext = getslicehdr();/* if (scalable_mode==SC_DP){ ld = &enhan; input->startcode(); code = input->showbits(32); if (code<SLICE_MIN_START || code>SLICE_MAX_START){ // only slice headers are allowed in picture_data if (!quiet) printf("Premature end of picture\n"); return; } input->flushbits(32); // decode slice header (may change quant_scale) slice_vert_pos_ext = getslicehdr();// if (pri_brk!=1) ld = &base; }*/ /* decode macroblock address increment */ MBAinc = getMBA(); if (fault) goto resync; /* set current location */ MBA = ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + MBAinc - 1; MBAinc = 1; /* first macroblock in slice: not skipped */ /* 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; } else { /* neither startcode nor fault */ if (MBA>=MBAmax){ if (!quiet) printf("Too many macroblocks in picture\n"); return; }/* if (scalable_mode==SC_DP && pri_brk==1) ld = &enhan;*/ /* decode macroblock address increment */ MBAinc = getMBA(); if (fault) goto resync; } } if (MBA>=MBAmax){ /* MBAinc points beyond picture dimensions */ if (!quiet) printf("Too many macroblocks in picture\n"); return; } if (MBAinc==1) /* not skipped */{/* if (scalable_mode==SC_DP){ if (pri_brk<=2) ld = &enhan; else ld = &base; }*/ macroblock_modes(&mb_type, &stwtype, &stwclass, &motion_type, &mv_count, &mv_format, &dmv, &mvscale, &dct_type); if (fault) goto resync; if (mb_type & MB_QUANT){ qs = input->getbits(5);#ifdef TRACE if (trace){ printf("quantiser_scale_code ("); printbits(qs,5,5); printf("): %d\n",qs); }#endif if (mpeg2) quant_scale = qscale_type ? non_linear_mquant_table[qs] : (qs << 1); else quant_scale = qs; if (scalable_mode==SC_DP) /* make sure quant_scale is valid */ quant_scale = quant_scale; } /* motion vectors */ /* decode forward motion vectors */ if ((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && conceal_mv)){ if (mpeg2) motion_vectors(PMV,dmvector,mv_field_sel, 0,mv_count,mv_format,h_forw_r_size,v_forw_r_size,dmv,mvscale); else motion_vector(PMV[0][0],dmvector, forw_r_size,forw_r_size,0,0,full_forw); } if (fault) goto resync; /* decode backward motion vectors */ if (mb_type & MB_BACKWARD){ if (mpeg2) motion_vectors(PMV,dmvector,mv_field_sel, 1,mv_count,mv_format,h_back_r_size,v_back_r_size,0,mvscale); else motion_vector(PMV[0][1],dmvector, back_r_size,back_r_size,0,0,full_back); } if (fault) goto resync; if ((mb_type & MB_INTRA) && conceal_mv) input->flushbits(1); /* remove marker_bit *//* if (scalable_mode==SC_DP && pri_brk==3) ld = &enhan;*/ /* macroblock_pattern */ if (mb_type & MB_PATTERN){ cbp = getCBP(); if (chroma_format==CHROMA422){ cbp = (cbp<<2) | input->getbits(2); /* coded_block_pattern_1 */#ifdef TRACE if (trace){ printf("coded_block_pattern_1: "); printbits(cbp,2,2); printf(" (%d)\n",cbp&3); }#endif } else if (chroma_format==CHROMA444){ cbp = (cbp<<6) | input->getbits(6); /* coded_block_pattern_2 */#ifdef TRACE if (trace){ printf("coded_block_pattern_2: "); printbits(cbp,6,6); printf(" (%d)\n",cbp&63); }#endif } } else cbp = (mb_type & MB_INTRA) ? (1<<blk_cnt)-1 : 0; if (fault) goto resync; /* decode blocks */ clearblock(0,blk_cnt); for (comp=0; comp<blk_cnt; comp++){// if (scalable_mode==SC_DP) ld = &base; if (cbp & (1<<(blk_cnt-1-comp))){ if (mb_type & MB_INTRA){ if (mpeg2) getmpg2intrablock(comp,dc_dct_pred); else getintrablock(comp,dc_dct_pred); } else { if (mpeg2) getmpg2interblock(comp); else getinterblock(comp); } if (fault) goto resync; } } /* 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) && !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 ((pict_type==P_TYPE) && !(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 (pict_struct==FRAME_PICTURE) motion_type = MC_FRAME; else { motion_type = MC_FIELD; /* predict from field of same parity */ mv_field_sel[0][0] = (pict_struct==BOTTOM_FIELD); } } 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 { /* MBAinc!=1: skipped macroblock */// if (scalable_mode==SC_DP) ld = &base; clearblock(0,blk_cnt); /* reset intra_dc predictors */ dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; /* reset motion vector predictors */ if (pict_type==P_TYPE) PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; /* derive motion_type */ if (pict_struct==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] = (pict_struct==BOTTOM_FIELD); } /* skipped I are spatial-only predicted, */ /* skipped P and B are temporal-only predicted */ stwtype = (pict_type==I_TYPE) ? 8 : 0; /* clear MB_INTRA */ mb_type&= ~MB_INTRA; cbp = 0; /* no block data */ } SNRcbp = 0;#ifdef ENHANCEMENT if (twostreams && enhan.scalable_mode==SC_SNR){ ld = &enhan; if (SNRMBAinc==0){ if (!input->showbits(23)){ /* startcode */ code=input->startcode();// code = input->showbits(32); if (code<SLICE_MIN_START || code>SLICE_MAX_START){ /* only slice headers are allowed in picture_data */ if (!quiet) printf("Premature end of picture\n"); return; } input->flushbits(32); /* decode slice header (may change quant_scale) */ slice_vert_pos_ext = getslicehdr(); /* decode macroblock address increment */ SNRMBAinc = getMBA(); /* set current location */ SNRMBA = ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + SNRMBAinc - 1; SNRMBAinc = 1; /* first macroblock in slice: not skipped */ } else { /* not startcode */ if (SNRMBA>=MBAmax){ if (!quiet) printf("Too many macroblocks in picture\n"); return; } /* decode macroblock address increment */ SNRMBAinc = getMBA(); } } if (SNRMBA!=MBA){ /* streams out of sync */ if (!quiet) printf("Cant't synchronize streams\n"); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -