⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intrax8.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
       similar it would trigger if e.g. x=3;y=2;       I guess somebody wrote something wrong and it became standard. */    if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);    w->est_run>>=2;    a&=3;    b&=3;    c&=3;    i=( 0xFFEAF4C4>>(2*b+8*a) )&3;    if(i!=3) w->orient=i;    else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;/*lut1[b][a]={->{0, 1, 0, pad},  {0, 1, X, pad},  {2, 2, 2, pad}}   pad 2   2  2; pad X  1  0; pad 0  1  0 <--> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4lut2[q>12][c]={  ->{0,2,1,pad},    {2,2,2,pad}}   pad 2  2  2; pad 1  2  0 <--> 11 10'10 10 '11 01'10 00=>0xEAD8*/}static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){    MpegEncContext * const s= w->s;    int t;#define B(x,y)  s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]#define T(x)  ((x) * dc_level + 0x8000) >> 16;    switch(direction){    case 0:        t = T(3811);//h        B(1,0) -= t;        B(0,1) -= t;        t = T(487);//e        B(2,0) -= t;        B(0,2) -= t;        t = T(506);//f        B(3,0) -= t;        B(0,3) -= t;        t = T(135);//c        B(4,0) -= t;        B(0,4) -= t;        B(2,1) += t;        B(1,2) += t;        B(3,1) += t;        B(1,3) += t;        t = T(173);//d        B(5,0) -= t;        B(0,5) -= t;        t = T(61);//b        B(6,0) -= t;        B(0,6) -= t;        B(5,1) += t;        B(1,5) += t;        t = T(42); //a        B(7,0) -= t;        B(0,7) -= t;        B(4,1) += t;        B(1,4) += t;        B(4,4) += t;        t = T(1084);//g        B(1,1) += t;        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);        break;    case 1:        B(0,1) -= T(6269);        B(0,3) -= T( 708);        B(0,5) -= T( 172);        B(0,7) -= T(  73);        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);        break;    case 2:        B(1,0) -= T(6269);        B(3,0) -= T( 708);        B(5,0) -= T( 172);        B(7,0) -= T(  73);        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);        break;    }#undef B#undef T}static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){    int k;    for(k=0;k<8;k++){        memset(dst,pix,8);        dst+=linesize;    }}static const int16_t quant_table[64] = {    256, 256, 256, 256,  256, 256, 259, 262,    265, 269, 272, 275,  278, 282, 285, 288,    292, 295, 299, 303,  306, 310, 314, 317,    321, 325, 329, 333,  337, 341, 345, 349,    353, 358, 362, 366,  371, 375, 379, 384,    389, 393, 398, 403,  408, 413, 417, 422,    428, 433, 438, 443,  448, 454, 459, 465,    470, 476, 482, 488,  493, 499, 505, 511};static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){    MpegEncContext * const s= w->s;    uint8_t * scantable;    int final,run,level;    int ac_mode,dc_mode,est_run,dc_level;    int pos,n;    int zeros_only;    int use_quant_matrix;    int sign;    assert(w->orient<12);    memset(s->block[0],0x00,64*sizeof(DCTELEM));    if(chroma){        dc_mode=2;    }else{        dc_mode=!!w->est_run;//0,1    }    if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;    n=0;    zeros_only=0;    if(!final){//decode ac        use_quant_matrix=w->use_quant_matrix;        if(chroma){            ac_mode = 1;            est_run = 64;//not used        }else{            if (w->raw_orient < 3){                use_quant_matrix = 0;            }            if(w->raw_orient > 4){                ac_mode = 0;                est_run = 64;            }else{                if(w->est_run > 1){                    ac_mode = 2;                    est_run=w->est_run;                }else{                    ac_mode = 3;                    est_run = 64;                }            }        }        x8_select_ac_table(w,ac_mode);        /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-        -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */        scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;        pos=0;        do {            n++;            if( n >= est_run ){                ac_mode=3;                x8_select_ac_table(w,3);            }            x8_get_ac_rlf(w,ac_mode,&run,&level,&final);            pos+=run+1;            if(pos>63){                //this also handles vlc error in x8_get_ac_rlf                return -1;            }            level= (level+1) * w->dquant;            level+= w->qsum;            sign = - get_bits1(&s->gb);            level = (level ^ sign) - sign;            if(use_quant_matrix){                level = (level*quant_table[pos])>>8;            }            s->block[0][ scantable[pos] ]=level;        }while(!final);        s->block_last_index[0]=pos;    }else{//DC only        s->block_last_index[0]=0;        if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]            int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:                                            w->divide_quant_dc_chroma;            int32_t dc_quant    = !chroma ? w->quant:                                            w->quant_dc_chroma;            //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding            dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;            dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),                                   s->dest[chroma], s->current_picture.linesize[!!chroma]);            goto block_placed;        }        zeros_only = (dc_level == 0);    }    if(!chroma){        s->block[0][0] = dc_level*w->quant;    }else{        s->block[0][0] = dc_level*w->quant_dc_chroma;    }    //there is !zero_only check in the original, but dc_level check is enough    if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){        int direction;        /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-        -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */        direction= (0x6A017C>>(w->orient*2))&3;        if (direction != 3){            x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]        }    }    if(w->flat_dc){        dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]);    }else{        s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer,                                            s->dest[chroma],                                            s->current_picture.linesize[!!chroma] );    }    if(!zeros_only)        s->dsp.idct_add ( s->dest[chroma],                          s->current_picture.linesize[!!chroma],                          s->block[0] );block_placed:    if(!chroma){        x8_update_predictions(w,w->orient,n);    }    if(s->loop_filter){        uint8_t* ptr = s->dest[chroma];        int linesize = s->current_picture.linesize[!!chroma];        if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){            s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);        }        if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){            s->dsp.x8_v_loop_filter(ptr, linesize, w->quant);        }    }    return 0;}static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*//not s->linesize as this would be wrong for field pics//not that IntraX8 has interlacing support ;)    const int linesize  = s->current_picture.linesize[0];    const int uvlinesize= s->current_picture.linesize[1];    s->dest[0] = s->current_picture.data[0];    s->dest[1] = s->current_picture.data[1];    s->dest[2] = s->current_picture.data[2];    s->dest[0] +=   s->mb_y        *   linesize << 3;    s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows    s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;}/** * Initialize IntraX8 frame decoder. * Requires valid MpegEncContext with valid s->mb_width before calling. * @param w pointer to IntraX8Context * @param s pointer to MpegEncContext of the parent codec */void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){    w->s=s;    x8_vlc_init();    assert(s->mb_width>0);    w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]);    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]);    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]);}/** * Destroy IntraX8 frame structure. * @param w pointer to IntraX8Context */void ff_intrax8_common_end(IntraX8Context * w){    av_freep(&w->prediction_table);}/** * Decode single IntraX8 frame. * The parent codec must fill s->loopfilter and s->gb (bitstream). * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function. * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function. * This function does not use MPV_decode_mb(). * lowres decoding is theoretically impossible. * @param w pointer to IntraX8Context * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1. * @param quant_offset offset away from zero *///FIXME extern uint8_t wmv3_dc_scale_table[32];int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){    MpegEncContext * const s= w->s;    int mb_xy;    assert(s);    w->use_quant_matrix = get_bits1(&s->gb);    w->dquant = dquant;    w->quant  = dquant >> 1;    w->qsum   = quant_offset;    w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;    if(w->quant < 5){        w->quant_dc_chroma =  w->quant;        w->divide_quant_dc_chroma = w->divide_quant_dc_luma;    }else{        w->quant_dc_chroma =  w->quant+((w->quant+3)>>3);        w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;    }    x8_reset_vlc_tables(w);    s->resync_mb_x=0;    s->resync_mb_y=0;    for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){        x8_init_block_index(s);        mb_xy=(s->mb_y>>1)*s->mb_stride;        for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){            x8_get_prediction(w);            if(x8_setup_spatial_predictor(w,0)) goto error;            if(x8_decode_intra_mb(w,0)) goto error;            if( s->mb_x & s->mb_y & 1 ){                x8_get_prediction_chroma(w);                /*when setting up chroma, no vlc is read,                so no error condition can be reached*/                x8_setup_spatial_predictor(w,1);                if(x8_decode_intra_mb(w,1)) goto error;                x8_setup_spatial_predictor(w,2);                if(x8_decode_intra_mb(w,2)) goto error;                s->dest[1]+= 8;                s->dest[2]+= 8;                /*emulate MB info in the relevant tables*/                s->mbskip_table [mb_xy]=0;                s->mbintra_table[mb_xy]=1;                s->current_picture.qscale_table[mb_xy]=w->quant;                mb_xy++;            }            s->dest[0]+= 8;        }        if(s->mb_y&1){            ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);        }    }error:    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,                        (s->mb_x>>1)-1, (s->mb_y>>1)-1,                        (AC_END|DC_END|MV_END) );    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -