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

📄 cavs.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 4 页
字号:
    const int pic_width  = 16*h->mb_width;    const int pic_height = 16*h->mb_height;    if(!pic->data[0])        return;    if(mx&7) extra_width -= 3;    if(my&7) extra_height -= 3;    if(   full_mx < 0-extra_width          || full_my < 0-extra_height          || full_mx + 16/*FIXME*/ > pic_width + extra_width          || full_my + 16/*FIXME*/ > pic_height + extra_height){        ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride,                            16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);        src_y= s->edge_emu_buffer + 2 + 2*h->l_stride;        emu=1;    }    qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps?    if(!square){        qpix_op[luma_xy](dest_y + delta, src_y + delta, h->l_stride);    }    if(emu){        ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, h->c_stride,                            9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);        src_cb= s->edge_emu_buffer;    }    chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7);    if(emu){        ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, h->c_stride,                            9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);        src_cr= s->edge_emu_buffer;    }    chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7);}static inline void mc_part_std(AVSContext *h,int square,int chroma_height,int delta,                        uint8_t *dest_y,uint8_t *dest_cb,uint8_t *dest_cr,                        int x_offset, int y_offset,qpel_mc_func *qpix_put,                        h264_chroma_mc_func chroma_put,qpel_mc_func *qpix_avg,                        h264_chroma_mc_func chroma_avg, vector_t *mv){    qpel_mc_func *qpix_op=  qpix_put;    h264_chroma_mc_func chroma_op= chroma_put;    dest_y  += 2*x_offset + 2*y_offset*h->l_stride;    dest_cb +=   x_offset +   y_offset*h->c_stride;    dest_cr +=   x_offset +   y_offset*h->c_stride;    x_offset += 8*h->mbx;    y_offset += 8*h->mby;    if(mv->ref >= 0){        Picture *ref= &h->DPB[mv->ref];        mc_dir_part(h, ref, square, chroma_height, delta, 0,                    dest_y, dest_cb, dest_cr, x_offset, y_offset,                    qpix_op, chroma_op, mv);        qpix_op=  qpix_avg;        chroma_op= chroma_avg;    }    if((mv+MV_BWD_OFFS)->ref >= 0){        Picture *ref= &h->DPB[0];        mc_dir_part(h, ref, square, chroma_height, delta, 1,                    dest_y, dest_cb, dest_cr, x_offset, y_offset,                    qpix_op, chroma_op, mv+MV_BWD_OFFS);    }}static void inter_pred(AVSContext *h, enum mb_t mb_type) {    if(partition_flags[mb_type] == 0){ // 16x16        mc_part_std(h, 1, 8, 0, h->cy, h->cu, h->cv, 0, 0,                h->s.dsp.put_cavs_qpel_pixels_tab[0],                h->s.dsp.put_h264_chroma_pixels_tab[0],                h->s.dsp.avg_cavs_qpel_pixels_tab[0],                h->s.dsp.avg_h264_chroma_pixels_tab[0],&h->mv[MV_FWD_X0]);    }else{        mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 0, 0,                h->s.dsp.put_cavs_qpel_pixels_tab[1],                h->s.dsp.put_h264_chroma_pixels_tab[1],                h->s.dsp.avg_cavs_qpel_pixels_tab[1],                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X0]);        mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 4, 0,                h->s.dsp.put_cavs_qpel_pixels_tab[1],                h->s.dsp.put_h264_chroma_pixels_tab[1],                h->s.dsp.avg_cavs_qpel_pixels_tab[1],                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X1]);        mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 0, 4,                h->s.dsp.put_cavs_qpel_pixels_tab[1],                h->s.dsp.put_h264_chroma_pixels_tab[1],                h->s.dsp.avg_cavs_qpel_pixels_tab[1],                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X2]);        mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 4, 4,                h->s.dsp.put_cavs_qpel_pixels_tab[1],                h->s.dsp.put_h264_chroma_pixels_tab[1],                h->s.dsp.avg_cavs_qpel_pixels_tab[1],                h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X3]);    }    /* set intra prediction modes to default values */    h->pred_mode_Y[3] =  h->pred_mode_Y[6] = INTRA_L_LP;    h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = INTRA_L_LP;}/***************************************************************************** * * motion vector prediction * ****************************************************************************/static inline void set_mvs(vector_t *mv, enum block_t size) {    switch(size) {    case BLK_16X16:        mv[MV_STRIDE  ] = mv[0];        mv[MV_STRIDE+1] = mv[0];    case BLK_16X8:        mv[1] = mv[0];        break;    case BLK_8X16:        mv[MV_STRIDE] = mv[0];        break;    }}static inline void store_mvs(AVSContext *h) {    h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 0] = h->mv[MV_FWD_X0];    h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 1] = h->mv[MV_FWD_X1];    h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 2] = h->mv[MV_FWD_X2];    h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 3] = h->mv[MV_FWD_X3];}static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, vector_t *src, int distp) {    int den = h->scale_den[src->ref];    *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9;    *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9;}static inline void mv_pred_median(AVSContext *h, vector_t *mvP, vector_t *mvA, vector_t *mvB, vector_t *mvC) {    int ax, ay, bx, by, cx, cy;    int len_ab, len_bc, len_ca, len_mid;    /* scale candidates according to their temporal span */    scale_mv(h, &ax, &ay, mvA, mvP->dist);    scale_mv(h, &bx, &by, mvB, mvP->dist);    scale_mv(h, &cx, &cy, mvC, mvP->dist);    /* find the geometrical median of the three candidates */    len_ab = abs(ax - bx) + abs(ay - by);    len_bc = abs(bx - cx) + abs(by - cy);    len_ca = abs(cx - ax) + abs(cy - ay);    len_mid = mid_pred(len_ab, len_bc, len_ca);    if(len_mid == len_ab) {        mvP->x = cx;        mvP->y = cy;    } else if(len_mid == len_bc) {        mvP->x = ax;        mvP->y = ay;    } else {        mvP->x = bx;        mvP->y = by;    }}static inline void mv_pred_direct(AVSContext *h, vector_t *pmv_fw,                                  vector_t *col_mv) {    vector_t *pmv_bw = pmv_fw + MV_BWD_OFFS;    int den = h->direct_den[col_mv->ref];    int m = col_mv->x >> 31;    pmv_fw->dist = h->dist[1];    pmv_bw->dist = h->dist[0];    pmv_fw->ref = 1;    pmv_bw->ref = 0;    /* scale the co-located motion vector according to its temporal span */    pmv_fw->x = (((den+(den*col_mv->x*pmv_fw->dist^m)-m-1)>>14)^m)-m;    pmv_bw->x = m-(((den+(den*col_mv->x*pmv_bw->dist^m)-m-1)>>14)^m);    m = col_mv->y >> 31;    pmv_fw->y = (((den+(den*col_mv->y*pmv_fw->dist^m)-m-1)>>14)^m)-m;    pmv_bw->y = m-(((den+(den*col_mv->y*pmv_bw->dist^m)-m-1)>>14)^m);}static inline void mv_pred_sym(AVSContext *h, vector_t *src, enum block_t size) {    vector_t *dst = src + MV_BWD_OFFS;    /* backward mv is the scaled and negated forward mv */    dst->x = -((src->x * h->sym_factor + 256) >> 9);    dst->y = -((src->y * h->sym_factor + 256) >> 9);    dst->ref = 0;    dst->dist = h->dist[0];    set_mvs(dst, size);}static void mv_pred(AVSContext *h, enum mv_loc_t nP, enum mv_loc_t nC,                    enum mv_pred_t mode, enum block_t size, int ref) {    vector_t *mvP = &h->mv[nP];    vector_t *mvA = &h->mv[nP-1];    vector_t *mvB = &h->mv[nP-4];    vector_t *mvC = &h->mv[nC];    const vector_t *mvP2 = NULL;    mvP->ref = ref;    mvP->dist = h->dist[mvP->ref];    if(mvC->ref == NOT_AVAIL)        mvC = &h->mv[nP-5]; // set to top-left (mvD)    if((mode == MV_PRED_PSKIP) &&       ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) ||           ((mvA->x | mvA->y | mvA->ref) == 0)  ||           ((mvB->x | mvB->y | mvB->ref) == 0) )) {        mvP2 = &un_mv;    /* if there is only one suitable candidate, take it */    } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) {        mvP2= mvA;    } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) {        mvP2= mvB;    } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) {        mvP2= mvC;    } else if(mode == MV_PRED_LEFT     && mvA->ref == ref){        mvP2= mvA;    } else if(mode == MV_PRED_TOP      && mvB->ref == ref){        mvP2= mvB;    } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){        mvP2= mvC;    }    if(mvP2){        mvP->x = mvP2->x;        mvP->y = mvP2->y;    }else        mv_pred_median(h, mvP, mvA, mvB, mvC);    if(mode < MV_PRED_PSKIP) {        mvP->x += get_se_golomb(&h->s.gb);        mvP->y += get_se_golomb(&h->s.gb);    }    set_mvs(mvP,size);}/***************************************************************************** * * residual data decoding * ****************************************************************************//** kth-order exponential golomb code */static inline int get_ue_code(GetBitContext *gb, int order) {    if(order) {        int ret = get_ue_golomb(gb) << order;        return ret + get_bits(gb,order);    }    return get_ue_golomb(gb);}/** * decode coefficients from one 8x8 block, dequantize, inverse transform *  and add them to sample block * @param r pointer to 2D VLC table * @param esc_golomb_order escape codes are k-golomb with this order k * @param qp quantizer * @param dst location of sample block * @param stride line stride in frame buffer */static int decode_residual_block(AVSContext *h, GetBitContext *gb,                                 const residual_vlc_t *r, int esc_golomb_order,                                 int qp, uint8_t *dst, int stride) {    int i,pos = -1;    int level_code, esc_code, level, run, mask;    int level_buf[64];    int run_buf[64];    int dqm = dequant_mul[qp];    int dqs = dequant_shift[qp];    int dqa = 1 << (dqs - 1);    const uint8_t *scantab = h->scantable.permutated;    DCTELEM *block = h->block;    for(i=0;i<65;i++) {        level_code = get_ue_code(gb,r->golomb_order);        if(level_code >= ESCAPE_CODE) {            run = ((level_code - ESCAPE_CODE) >> 1) + 1;            esc_code = get_ue_code(gb,esc_golomb_order);            level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);            while(level > r->inc_limit)                r++;            mask = -(level_code & 1);            level = (level^mask) - mask;        } else {            level = r->rltab[level_code][0];            if(!level) //end of block signal                break;            run   = r->rltab[level_code][1];            r += r->rltab[level_code][2];        }        level_buf[i] = level;        run_buf[i] = run;    }    /* inverse scan and dequantization */    while(--i >= 0){        pos += run_buf[i];        if(pos > 63) {            av_log(h->s.avctx, AV_LOG_ERROR,                   "position out of block bounds at pic %d MB(%d,%d)\n",                   h->picture.poc, h->mbx, h->mby);            return -1;        }        block[scantab[pos]] = (level_buf[i]*dqm + dqa) >> dqs;    }    h->s.dsp.cavs_idct8_add(dst,block,stride);    return 0;}static inline void decode_residual_chroma(AVSContext *h) {    if(h->cbp & (1<<4))        decode_residual_block(h,&h->s.gb,chroma_2dvlc,0, chroma_qp[h->qp],                              h->cu,h->c_stride);    if(h->cbp & (1<<5))        decode_residual_block(h,&h->s.gb,chroma_2dvlc,0, chroma_qp[h->qp],                              h->cv,h->c_stride);}static inline int decode_residual_inter(AVSContext *h) {    int block;    /* get coded block pattern */    int cbp= get_ue_golomb(&h->s.gb);    if(cbp > 63){        av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n");        return -1;    }    h->cbp = cbp_tab[cbp][1];    /* get quantizer */    if(h->cbp && !h->qp_fixed)        h->qp = (h->qp + get_se_golomb(&h->s.gb)) & 63;    for(block=0;block<4;block++)        if(h->cbp & (1<<block))            decode_residual_block(h,&h->s.gb,inter_2dvlc,0,h->qp,                                  h->cy + h->luma_scan[block], h->l_stride);    decode_residual_chroma(h);    return 0;}/***************************************************************************** * * macroblock level * ****************************************************************************//** * initialise predictors for motion vectors and intra prediction */static inline void init_mb(AVSContext *h) {    int i;    /* copy predictors from top line (MB B and C) into cache */    for(i=0;i<3;i++) {        h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i];        h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i];    }    h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0];    h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1];    /* clear top predictors if MB B is not available */    if(!(h->flags & B_AVAIL)) {        h->mv[MV_FWD_B2] = un_mv;        h->mv[MV_FWD_B3] = un_mv;        h->mv[MV_BWD_B2] = un_mv;        h->mv[MV_BWD_B3] = un_mv;        h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;        h->flags &= ~(C_AVAIL|D_AVAIL);    } else if(h->mbx) {        h->flags |= D_AVAIL;    }    if(h->mbx == h->mb_width-1) //MB C not available        h->flags &= ~C_AVAIL;    /* clear top-right predictors if MB C is not available */    if(!(h->flags & C_AVAIL)) {        h->mv[MV_FWD_C2] = un_mv;        h->mv[MV_BWD_C2] = un_mv;    }    /* clear top-left predictors if MB D is not available */    if(!(h->flags & D_AVAIL)) {        h->mv[MV_FWD_D3] = un_mv;        h->mv[MV_BWD_D3] = un_mv;    }    /* set pointer for co-located macroblock type */    h->col_type = &h->col_type_base[h->mby*h->mb_width + h->mbx];}

⌨️ 快捷键说明

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