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

📄 h264.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 5 页
字号:
        *(uint64_t*)(p + 0+2*stride)=        *(uint64_t*)(p + 8+2*stride)=        *(uint64_t*)(p + 0+3*stride)=        *(uint64_t*)(p + 8+3*stride)= size==4 ? val*0x0100000001ULL : val*0x0101010101010101ULL;    }else        assert(0);}static inline void fill_caches(H264Context *h, int mb_type){    MpegEncContext * const s = &h->s;    const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;    int topleft_xy, top_xy, topright_xy, left_xy[2];    int topleft_type, top_type, topright_type, left_type[2];    int left_block[4];    int i;    //wow what a mess, why didnt they simplify the interlacing&intra stuff, i cant imagine that these complex rules are worth it         if(h->sps.mb_aff){    //FIXME        topleft_xy = 0; /* avoid warning */        top_xy = 0; /* avoid warning */        topright_xy = 0; /* avoid warning */    }else{        topleft_xy = mb_xy-1 - s->mb_stride;        top_xy     = mb_xy   - s->mb_stride;        topright_xy= mb_xy+1 - s->mb_stride;        left_xy[0]   = mb_xy-1;        left_xy[1]   = mb_xy-1;        left_block[0]= 0;        left_block[1]= 1;        left_block[2]= 2;        left_block[3]= 3;    }    topleft_type = h->slice_table[topleft_xy ] == h->slice_num ? s->current_picture.mb_type[topleft_xy] : 0;    top_type     = h->slice_table[top_xy     ] == h->slice_num ? s->current_picture.mb_type[top_xy]     : 0;    topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0;    left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0;    left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0;    if(IS_INTRA(mb_type)){        h->topleft_samples_available=         h->top_samples_available=         h->left_samples_available= 0xFFFF;        h->topright_samples_available= 0xEEEA;        if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){            h->topleft_samples_available= 0xB3FF;            h->top_samples_available= 0x33FF;            h->topright_samples_available= 0x26EA;        }        for(i=0; i<2; i++){            if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){                h->topleft_samples_available&= 0xDF5F;                h->left_samples_available&= 0x5F5F;            }        }                if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred))            h->topleft_samples_available&= 0x7FFF;                if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred))            h->topright_samples_available&= 0xFBFF;            if(IS_INTRA4x4(mb_type)){            if(IS_INTRA4x4(top_type)){                h->intra4x4_pred_mode_cache[4+8*0]= h->intra4x4_pred_mode[top_xy][4];                h->intra4x4_pred_mode_cache[5+8*0]= h->intra4x4_pred_mode[top_xy][5];                h->intra4x4_pred_mode_cache[6+8*0]= h->intra4x4_pred_mode[top_xy][6];                h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3];            }else{                int pred;                if(IS_INTRA16x16(top_type) || (IS_INTER(top_type) && !h->pps.constrained_intra_pred))                    pred= 2;                else{                    pred= -1;                }                h->intra4x4_pred_mode_cache[4+8*0]=                h->intra4x4_pred_mode_cache[5+8*0]=                h->intra4x4_pred_mode_cache[6+8*0]=                h->intra4x4_pred_mode_cache[7+8*0]= pred;            }            for(i=0; i<2; i++){                if(IS_INTRA4x4(left_type[i])){                    h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[0+2*i]];                    h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]];                }else{                    int pred;                    if(IS_INTRA16x16(left_type[i]) || (IS_INTER(left_type[i]) && !h->pps.constrained_intra_pred))                        pred= 2;                    else{                        pred= -1;                    }                    h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=                    h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= pred;                }            }        }    }        /*0 . T T. T T T T 1 L . .L . . . . 2 L . .L . . . . 3 . T TL . . . . 4 L . .L . . . . 5 L . .. . . . . *///FIXME constraint_intra_pred & partitioning & nnz (lets hope this is just a typo in the spec)    if(top_type){        h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][0];        h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][1];        h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][2];        h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][3];            h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][7];        h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][8];            h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][10];        h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][11];    }else{        h->non_zero_count_cache[4+8*0]=              h->non_zero_count_cache[5+8*0]=        h->non_zero_count_cache[6+8*0]=        h->non_zero_count_cache[7+8*0]=            h->non_zero_count_cache[1+8*0]=        h->non_zero_count_cache[2+8*0]=            h->non_zero_count_cache[1+8*3]=        h->non_zero_count_cache[2+8*3]= 64;    }        if(left_type[0]){        h->non_zero_count_cache[3+8*1]= h->non_zero_count[left_xy[0]][6];        h->non_zero_count_cache[3+8*2]= h->non_zero_count[left_xy[0]][5];        h->non_zero_count_cache[0+8*1]= h->non_zero_count[left_xy[0]][9]; //FIXME left_block        h->non_zero_count_cache[0+8*4]= h->non_zero_count[left_xy[0]][12];    }else{        h->non_zero_count_cache[3+8*1]=         h->non_zero_count_cache[3+8*2]=         h->non_zero_count_cache[0+8*1]=         h->non_zero_count_cache[0+8*4]= 64;    }        if(left_type[1]){        h->non_zero_count_cache[3+8*3]= h->non_zero_count[left_xy[1]][4];        h->non_zero_count_cache[3+8*4]= h->non_zero_count[left_xy[1]][3];        h->non_zero_count_cache[0+8*2]= h->non_zero_count[left_xy[1]][8];        h->non_zero_count_cache[0+8*5]= h->non_zero_count[left_xy[1]][11];    }else{        h->non_zero_count_cache[3+8*3]=         h->non_zero_count_cache[3+8*4]=         h->non_zero_count_cache[0+8*2]=         h->non_zero_count_cache[0+8*5]= 64;    }    #if 1    if(IS_INTER(mb_type)){        int list;        for(list=0; list<2; list++){            if((!IS_8X8(mb_type)) && !USES_LIST(mb_type, list)){                /*if(!h->mv_cache_clean[list]){                    memset(h->mv_cache [list],  0, 8*5*2*sizeof(int16_t)); //FIXME clean only input? clean at all?                    memset(h->ref_cache[list], PART_NOT_AVAILABLE, 8*5*sizeof(int8_t));                    h->mv_cache_clean[list]= 1;                }*/                continue; //FIXME direct mode ...            }            h->mv_cache_clean[list]= 0;                        if(IS_INTER(topleft_type)){                const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride;                const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + h->b8_stride;                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy];                h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy];            }else{                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= 0;                h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;            }                        if(IS_INTER(top_type)){                const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;                const int b8_xy= h->mb2b8_xy[top_xy] + h->b8_stride;                *(uint32_t*)h->mv_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 0];                *(uint32_t*)h->mv_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 1];                *(uint32_t*)h->mv_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 2];                *(uint32_t*)h->mv_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 3];                h->ref_cache[list][scan8[0] + 0 - 1*8]=                h->ref_cache[list][scan8[0] + 1 - 1*8]= s->current_picture.ref_index[list][b8_xy + 0];                h->ref_cache[list][scan8[0] + 2 - 1*8]=                h->ref_cache[list][scan8[0] + 3 - 1*8]= s->current_picture.ref_index[list][b8_xy + 1];            }else{                *(uint32_t*)h->mv_cache [list][scan8[0] + 0 - 1*8]=                 *(uint32_t*)h->mv_cache [list][scan8[0] + 1 - 1*8]=                 *(uint32_t*)h->mv_cache [list][scan8[0] + 2 - 1*8]=                 *(uint32_t*)h->mv_cache [list][scan8[0] + 3 - 1*8]= 0;                *(uint32_t*)&h->ref_cache[list][scan8[0] + 0 - 1*8]= ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101;            }            if(IS_INTER(topright_type)){                const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride;                const int b8_xy= h->mb2b8_xy[topright_xy] + h->b8_stride;                *(uint32_t*)h->mv_cache[list][scan8[0] + 4 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy];                h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][b8_xy];            }else{                *(uint32_t*)h->mv_cache [list][scan8[0] + 4 - 1*8]= 0;                h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;            }                        //FIXME unify cleanup or sth            if(IS_INTER(left_type[0])){                const int b_xy= h->mb2b_xy[left_xy[0]] + 3;                const int b8_xy= h->mb2b8_xy[left_xy[0]] + 1;                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 0*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0]];                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[1]];                h->ref_cache[list][scan8[0] - 1 + 0*8]=                 h->ref_cache[list][scan8[0] - 1 + 1*8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[0]>>1)];            }else{                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 0*8]=                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 1*8]= 0;                h->ref_cache[list][scan8[0] - 1 + 0*8]=                h->ref_cache[list][scan8[0] - 1 + 1*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE;            }                        if(IS_INTER(left_type[1])){                const int b_xy= h->mb2b_xy[left_xy[1]] + 3;                const int b8_xy= h->mb2b8_xy[left_xy[1]] + 1;                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 2*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[2]];                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 3*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[3]];                h->ref_cache[list][scan8[0] - 1 + 2*8]=                 h->ref_cache[list][scan8[0] - 1 + 3*8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[2]>>1)];            }else{                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 2*8]=                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 3*8]= 0;                h->ref_cache[list][scan8[0] - 1 + 2*8]=                h->ref_cache[list][scan8[0] - 1 + 3*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE;            }            h->ref_cache[list][scan8[5 ]+1] =             h->ref_cache[list][scan8[7 ]+1] =             h->ref_cache[list][scan8[13]+1] =  //FIXME remove past 3 (init somewher else)            h->ref_cache[list][scan8[4 ]] =             h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE;            *(uint32_t*)h->mv_cache [list][scan8[5 ]+1]=            *(uint32_t*)h->mv_cache [list][scan8[7 ]+1]=            *(uint32_t*)h->mv_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewher else)            *(uint32_t*)h->mv_cache [list][scan8[4 ]]=            *(uint32_t*)h->mv_cache [list][scan8[12]]= 0;            if( h->pps.cabac ) {                /* XXX beurk, Load mvd */                if(IS_INTER(topleft_type)){                    const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride;                    *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy];                }else{                    *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 - 1*8]= 0;                }                if(IS_INTER(top_type)){                    const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;                    *(uint32_t*)h->mvd_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 0];                    *(uint32_t*)h->mvd_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 1];                    *(uint32_t*)h->mvd_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 2];                    *(uint32_t*)h->mvd_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 3];                }else{                    *(uint32_t*)h->mvd_cache [list][scan8[0] + 0 - 1*8]=                     *(uint32_t*)h->mvd_cache [list][scan8[0] + 1 - 1*8]=                     *(uint32_t*)h->mvd_cache [list][scan8[0] + 2 - 1*8]=                     *(uint32_t*)h->mvd_cache [list][scan8[0] + 3 - 1*8]= 0;                }                if(IS_INTER(left_type[0])){                    const int b_xy= h->mb2b_xy[left_xy[0]] + 3;                    *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 0*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[0]];                    *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[1]];                }else{                    *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 0*8]=                    *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 1*8]= 0;                }                if(IS_INTER(left_type[1])){                    const int b_xy= h->mb2b_xy[left_xy[1]] + 3;                    *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 2*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[2]];                    *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 3*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[3]];                }else{                    *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 2*8]=                    *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 3*8]= 0;                }                *(uint32_t*)h->mvd_cache [list][scan8[5 ]+1]=                *(uint32_t*)h->mvd_cache [list][scan8[7 ]+1]=                *(uint32_t*)h->mvd_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewher else)                *(uint32_t*)h->mvd_cache [list][scan8[4 ]]=                *(uint32_t*)h->mvd_cache [list][scan8[12]]= 0;            }        }//FIXME    }#endif}static inline void write_back_intra_pred_mode(H264Context *h){    MpegEncContext * const s = &h->s;    const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;    h->intra4x4_pred_mode[mb_xy][0]= h->intra4x4_pred_mode_cache[7+8*1];    h->intra4x4_pred_mode[mb_xy][1]= h->intra4x4_pred_mode_cache[7+8*2];    h->intra4x4_pred_mode[mb_xy][2]= h->intra4x4_pred_mode_cache[7+8*3];    h->intra4x4_pred_mode[mb_xy][3]= h->intra4x4_pred_mode_cache[7+8*4];    h->intra4x4_pred_mode[mb_xy][4]= h->intra4x4_pred_mode_cache[4+8*4];    h->intra4x4_pred_mode[mb_xy][5]= h->intra4x4_pred_mode_cache[5+8*4];    h->intra4x4_pred_mode[mb_xy][6]= h->intra4x4_pred_mode_cache[6+8*4];}/** * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. */static inline int check_intra4x4_pred_mode(H264Context *h){    MpegEncContext * const s = &h->s;    static const int8_t top [12]= {-1, 0,LEFT_DC_PRED,-1,-1,-1,-1,-1, 0};    static const int8_t left[12]= { 0,-1, TOP_DC_PRED, 0,-1,-1,-1, 0,-1,DC_128_PRED};    int i;        if(!(h->top_samples_available&0x8000)){        for(i=0; i<4; i++){            int status= top[ h->intra4x4_pred_mode_cache[scan8[0] + i] ];            if(status<0){                av_log(h->s.avctx, AV_LOG_ERROR, "top block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y);                return -1;            } else if(status){                h->intra4x4_pred_mode_cache[scan8[0] + i]= status;            }        }    }        if(!(h->left_samples_available&0x8000)){        for(i=0; i<4; i++){            int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ];            if(status<0){                av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y);                return -1;            } else if(status){                h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status;            }        }    }    return 0;} //FIXME cleanup like next/** * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. */static inline int check_intra_pred_mode(H264Context *h, int mode){    MpegEncContext * const s = &h->s;    static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1};    static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8};        if(!(h->top_samples_available&0x8000)){        mode= top[ mode ];        if(mode<0){            av_log(h->s.avctx, AV_LOG_ERROR, "top block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);            return -1;        }    }        if(!(h->left_samples_available&0x8000)){        mode= left[ mode ];        if(mode<0){            av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);            return -1;        }     }    return mode;}/** * gets the predicted intra4x4 prediction mode. */static inline int pred_intra_mode(H264Context *h, int n){    const int index8= scan8[n];

⌨️ 快捷键说明

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