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

📄 msmpeg4.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
            int val = ((code >> (5 - i)) & 1);            if (i < 4) {                int pred = coded_block_pred(s, i, &coded_val);                val = val ^ pred;                *coded_val = val;            }            cbp |= val << (5 - i);        }    }    if (!s->mb_intra) {        int mx, my;//printf("P at %d %d\n", s->mb_x, s->mb_y);        if(s->per_mb_rl_table && cbp){            s->rl_table_index = decode012(&s->gb);            s->rl_chroma_table_index = s->rl_table_index;        }        set_stat(ST_MV);        h263_pred_motion(s, 0, &mx, &my);        if (msmpeg4_decode_motion(s, &mx, &my) < 0)            return -1;        s->mv_dir = MV_DIR_FORWARD;        s->mv_type = MV_TYPE_16X16;        s->mv[0][0][0] = mx;        s->mv[0][0][1] = my;        *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;    } else {//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24));        set_stat(ST_INTRA_MB);        s->ac_pred = get_bits1(&s->gb);        *mb_type_ptr = MB_TYPE_INTRA;        if(s->inter_intra_pred){            s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);//            printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);        }        if(s->per_mb_rl_table && cbp){            s->rl_table_index = decode012(&s->gb);            s->rl_chroma_table_index = s->rl_table_index;        }    }    for (i = 0; i < 6; i++) {        if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)	{	    av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);	    return -1;	}    }        return 0;}//#define ERROR_DETAILSstatic inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,                              int n, int coded, const uint8_t *scan_table){    int level, i, last, run, run_diff;    int dc_pred_dir;    RLTable *rl;    RL_VLC_ELEM *rl_vlc;    int qmul, qadd;    if (s->mb_intra) {        qmul=1;        qadd=0;	/* DC coef */        set_stat(ST_DC);        level = msmpeg4_decode_dc(s, n, &dc_pred_dir);                if (level < 0){            av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);            if(s->inter_intra_pred) level=0;            else                    return -1;        }        if (n < 4) {            rl = &rl_table[s->rl_table_index];            if(level > 256*s->y_dc_scale){                av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale);                if(!s->inter_intra_pred) return -1;            }        } else {            rl = &rl_table[3 + s->rl_chroma_table_index];            if(level > 256*s->c_dc_scale){                av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale);                if(!s->inter_intra_pred) return -1;            }        }        block[0] = level;        run_diff = 0;        i = 0;        if (!coded) {            goto not_coded;        }        if (s->ac_pred) {            if (dc_pred_dir == 0)                 scan_table = s->intra_v_scantable.permutated; /* left */            else                scan_table = s->intra_h_scantable.permutated; /* top */        } else {            scan_table = s->intra_scantable.permutated;        }        set_stat(ST_INTRA_AC);        rl_vlc= rl->rl_vlc[0];    } else {        qmul = s->qscale << 1;        qadd = (s->qscale - 1) | 1;        i = -1;        rl = &rl_table[3 + s->rl_table_index];        if(s->msmpeg4_version==2)            run_diff = 0;        else            run_diff = 1;        if (!coded) {            s->block_last_index[n] = i;            return 0;        }        if(!scan_table)            scan_table = s->inter_scantable.permutated;        set_stat(ST_INTER_AC);        rl_vlc= rl->rl_vlc[s->qscale];    }  {    OPEN_READER(re, &s->gb);    for(;;) {        UPDATE_CACHE(re, &s->gb);        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);        if (level==0) {            int cache;            cache= GET_CACHE(re, &s->gb);            /* escape */            if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {                if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {                    /* third escape */                    if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);                    UPDATE_CACHE(re, &s->gb);                    if(s->msmpeg4_version<=3){                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);                        run=   SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);                        level= SHOW_SBITS(re, &s->gb, 8); LAST_SKIP_CACHE(re, &s->gb, 8);                        SKIP_COUNTER(re, &s->gb, 1+6+8);                    }else{                                                int sign;                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);                        if(!s->esc3_level_length){                            int ll;                            //printf("ESC-3 %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y);                            if(s->qscale<8){                                ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);                                if(ll==0){                                    if(SHOW_UBITS(re, &s->gb, 1)) av_log(s->avctx, AV_LOG_ERROR, "cool a new vlc code ,contact the ffmpeg developers and upload the file\n");                                    SKIP_BITS(re, &s->gb, 1);                                    ll=8;                                }                            }else{                                ll=2;                                while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){                                    ll++;                                    SKIP_BITS(re, &s->gb, 1);                                }                                if(ll<8) SKIP_BITS(re, &s->gb, 1);                            }                            s->esc3_level_length= ll;                            s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);//printf("level length:%d, run length: %d\n", ll, s->esc3_run_length);                            UPDATE_CACHE(re, &s->gb);                        }                        run=   SHOW_UBITS(re, &s->gb, s->esc3_run_length);                         SKIP_BITS(re, &s->gb, s->esc3_run_length);                                                sign=  SHOW_UBITS(re, &s->gb, 1);                         SKIP_BITS(re, &s->gb, 1);                                                level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);                         SKIP_BITS(re, &s->gb, s->esc3_level_length);                        if(sign) level= -level;                    }//printf("level: %d, run: %d at %d %d\n", level, run, s->mb_x, s->mb_y);#if 0 // waste of time / this will detect very few errors                    {                        const int abs_level= ABS(level);                        const int run1= run - rl->max_run[last][abs_level] - run_diff;                        if(abs_level<=MAX_LEVEL && run<=MAX_RUN){                            if(abs_level <= rl->max_level[last][run]){                                fprintf(stderr, "illegal 3. esc, vlc encoding possible\n");                                return DECODING_AC_LOST;                            }                            if(abs_level <= rl->max_level[last][run]*2){                                fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n");                                return DECODING_AC_LOST;                            }                            if(run1>=0 && abs_level <= rl->max_level[last][run1]){                                fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n");                                return DECODING_AC_LOST;                            }                        }                    }#endif		    //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;		    if (level>0) level= level * qmul + qadd;                    else         level= level * qmul - qadd;#if 0 // waste of time too :(                    if(level>2048 || level<-2048){                        fprintf(stderr, "|level| overflow in 3. esc\n");                        return DECODING_AC_LOST;                    }#endif                    i+= run + 1;                    if(last) i+=192;#ifdef ERROR_DETAILS                if(run==66)                    fprintf(stderr, "illegal vlc code in ESC3 level=%d\n", level);                else if((i>62 && i<192) || i>192+63)                    fprintf(stderr, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);#endif                } else {                    /* second escape */#if MIN_CACHE_BITS < 23                    LAST_SKIP_BITS(re, &s->gb, 2);                    UPDATE_CACHE(re, &s->gb);#else                    SKIP_BITS(re, &s->gb, 2);#endif                    GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);                    i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);                    LAST_SKIP_BITS(re, &s->gb, 1);#ifdef ERROR_DETAILS                if(run==66)                    fprintf(stderr, "illegal vlc code in ESC2 level=%d\n", level);                else if((i>62 && i<192) || i>192+63)                    fprintf(stderr, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);#endif                }            } else {                /* first escape */#if MIN_CACHE_BITS < 22                LAST_SKIP_BITS(re, &s->gb, 1);                UPDATE_CACHE(re, &s->gb);#else                SKIP_BITS(re, &s->gb, 1);#endif                GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);                i+= run;                level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);                LAST_SKIP_BITS(re, &s->gb, 1);#ifdef ERROR_DETAILS                if(run==66)                    fprintf(stderr, "illegal vlc code in ESC1 level=%d\n", level);                else if((i>62 && i<192) || i>192+63)                    fprintf(stderr, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);#endif            }        } else {            i+= run;            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);            LAST_SKIP_BITS(re, &s->gb, 1);#ifdef ERROR_DETAILS                if(run==66)                    fprintf(stderr, "illegal vlc code level=%d\n", level);                else if((i>62 && i<192) || i>192+63)                    fprintf(stderr, "run overflow i=%d run=%d level=%d\n", i, run, level);#endif        }        if (i > 62){            i-= 192;            if(i&(~63)){                const int left= s->gb.size_in_bits - get_bits_count(&s->gb);                if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<=1) && left>=0){                    av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);                    break;                }else{                    av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);                    return -1;                }            }            block[scan_table[i]] = level;            break;        }        block[scan_table[i]] = level;    }    CLOSE_READER(re, &s->gb);  } not_coded:    if (s->mb_intra) {        mpeg4_pred_ac(s, block, n, dc_pred_dir);        if (s->ac_pred) {            i = 63; /* XXX: not optimal */        }    }    if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize    s->block_last_index[n] = i;        return 0;}static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr){    int level, pred;    if(s->msmpeg4_version<=2){        if (n < 4) {            level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3);        } else {            level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3);        }        if (level < 0)             return -1;        level-=256;    }else{  //FIXME optimize use unified tables & index        if (n < 4) {            level = get_vlc2(&s->gb, dc_lum_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);        } else {            level = get_vlc2(&s->gb, dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);        }        if (level < 0){            av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");            return -1;        }        if (level == DC_MAX) {            level = get_bits(&s->gb, 8);            if (get_bits1(&s->gb))                level = -level;        } else if (level != 0) {            if (get_bits1(&s->gb))                level = -level;        }    }    if(s->msmpeg4_version==1){        int32_t *dc_val;        pred = msmpeg4v1_pred_dc(s, n, &dc_val);        level += pred;                /* update predictor */        *dc_val= level;    }else{        uint16_t *dc_val;        pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);        level += pred;        /* update predictor */        if (n < 4) {            *dc_val = level * s->y_dc_scale;        } else {            *dc_val = level * s->c_dc_scale;        }    }    return level;}static int msmpeg4_decode_motion(MpegEncContext * s,                                  int *mx_ptr, int *my_ptr){    MVTable *mv;    int code, mx, my;    mv = &mv_tables[s->mv_table_index];    code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2);    if (code < 0){        av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y);        return -1;    }    if (code == mv->n) {//printf("MV ESC %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y);        mx = get_bits(&s->gb, 6);        my = get_bits(&s->gb, 6);    } else {        mx = mv->table_mvx[code];        my = mv->table_mvy[code];    }    mx += *mx_ptr - 32;    my += *my_ptr - 32;    /* WARNING : they do not do exactly modulo encoding */    if (mx <= -64)        mx += 64;    else if (mx >= 64)        mx -= 64;    if (my <= -64)        my += 64;    else if (my >= 64)        my -= 64;    *mx_ptr = mx;    *my_ptr = my;    return 0;}/* cleanest way to support it * there is too much shared between versions so that we cant have 1 file per version & 1 common * as allmost everything would be in the common file  */#include "wmv2.c"

⌨️ 快捷键说明

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