📄 rv34.c
字号:
: r->s.dsp.put_h264_qpel_pixels_tab, r->s.dsp.put_h264_chroma_pixels_tab); rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab : r->s.dsp.avg_h264_qpel_pixels_tab, r->s.dsp.avg_h264_chroma_pixels_tab);}static void rv34_mc_2mv_skip(RV34DecContext *r){ int i, j, k; for(j = 0; j < 2; j++) for(i = 0; i < 2; i++){ rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30, r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab : r->s.dsp.put_h264_qpel_pixels_tab, r->s.dsp.put_h264_chroma_pixels_tab); rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30, r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab : r->s.dsp.avg_h264_qpel_pixels_tab, r->s.dsp.avg_h264_chroma_pixels_tab); }}/** number of motion vectors in each macroblock type */static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };/** * Decode motion vector differences * and perform motion vector reconstruction and motion compensation. */static int rv34_decode_mv(RV34DecContext *r, int block_type){ MpegEncContext *s = &r->s; GetBitContext *gb = &s->gb; int i, j, k, l; int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; int next_bt; memset(r->dmv, 0, sizeof(r->dmv)); for(i = 0; i < num_mvs[block_type]; i++){ r->dmv[i][0] = svq3_get_se_golomb(gb); r->dmv[i][1] = svq3_get_se_golomb(gb); } switch(block_type){ case RV34_MB_TYPE_INTRA: case RV34_MB_TYPE_INTRA16x16: fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); return 0; case RV34_MB_SKIP: if(s->pict_type == FF_P_TYPE){ fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); break; } case RV34_MB_B_DIRECT: //surprisingly, it uses motion scheme from next reference frame next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride]; for(j = 0; j < 2; j++) for(i = 0; i < 2; i++) for(k = 0; k < 2; k++) for(l = 0; l < 2; l++) s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]); if(IS_16X16(next_bt)) //we can use whole macroblock MC rv34_mc_2mv(r, block_type); else rv34_mc_2mv_skip(r); fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); break; case RV34_MB_P_16x16: case RV34_MB_P_MIX16x16: rv34_pred_mv(r, block_type, 0, 0); rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); break; case RV34_MB_B_FORWARD: case RV34_MB_B_BACKWARD: r->dmv[1][0] = r->dmv[0][0]; r->dmv[1][1] = r->dmv[0][1]; rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD); rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD); break; case RV34_MB_P_16x8: case RV34_MB_P_8x16: rv34_pred_mv(r, block_type, 0, 0); rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1); if(block_type == RV34_MB_P_16x8){ rv34_mc_1mv(r, block_type, 0, 0, 0, 2, 1, 0); rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0); } if(block_type == RV34_MB_P_8x16){ rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0); rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0); } break; case RV34_MB_B_BIDIR: rv34_pred_mv_b (r, block_type, 0); rv34_pred_mv_b (r, block_type, 1); rv34_mc_2mv (r, block_type); break; case RV34_MB_P_8x8: for(i=0;i< 4;i++){ rv34_pred_mv(r, block_type, i, i); rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0); } break; } return 0;}/** @} */ // mv group/** * @defgroup recons Macroblock reconstruction functions * @{ *//** mapping of RV30/40 intra prediction types to standard H.264 types */static const int ittrans[9] = { DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED, VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,};/** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */static const int ittrans16[4] = { DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,};/** * Perform 4x4 intra prediction. */static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right){ uint8_t *prev = dst - stride + 4; uint32_t topleft; if(!up && !left) itype = DC_128_PRED; else if(!up){ if(itype == VERT_PRED) itype = HOR_PRED; if(itype == DC_PRED) itype = LEFT_DC_PRED; }else if(!left){ if(itype == HOR_PRED) itype = VERT_PRED; if(itype == DC_PRED) itype = TOP_DC_PRED; if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN; } if(!down){ if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN; if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN; if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN; } if(!right && up){ topleft = dst[-stride + 3] * 0x01010101;#ifdef __CW32__ prev = (unsigned char*)&topleft;#else prev = &topleft;#endif } r->h.pred4x4[itype](dst, prev, stride);}/** add_pixels_clamped for 4x4 block */static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off){ int x, y; for(y = 0; y < 4; y++) for(x = 0; x < 4; x++) dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);}static inline int adjust_pred16(int itype, int up, int left){ if(!up && !left) itype = DC_128_PRED8x8; else if(!up){ if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8; if(itype == VERT_PRED8x8) itype = HOR_PRED8x8; if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8; }else if(!left){ if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8; if(itype == HOR_PRED8x8) itype = VERT_PRED8x8; if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8; } return itype;}static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int cbp, int is16){ MpegEncContext *s = &r->s; DSPContext *dsp = &s->dsp; int i, j; uint8_t *Y, *U, *V; int itype; int avail[6*8] = {0}; int idx; // Set neighbour information. if(r->avail_cache[0]) avail[0] = 1; if(r->avail_cache[1]) avail[1] = avail[2] = 1; if(r->avail_cache[2]) avail[3] = avail[4] = 1; if(r->avail_cache[3]) avail[5] = 1; if(r->avail_cache[4]) avail[8] = avail[16] = 1; if(r->avail_cache[8]) avail[24] = avail[32] = 1; Y = s->dest[0]; U = s->dest[1]; V = s->dest[2]; if(!is16){ for(j = 0; j < 4; j++){ idx = 9 + j*8; for(i = 0; i < 4; i++, cbp >>= 1, Y += 4, idx++){ rv34_pred_4x4_block(r, Y, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]); avail[idx] = 1; if(cbp & 1) rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32); } Y += s->linesize * 4 - 4*4; intra_types += s->b4_stride; } intra_types -= s->b4_stride * 4; fill_rectangle(r->avail_cache + 5, 2, 2, 4, 0, 4); for(j = 0; j < 2; j++){ idx = 5 + j*4; for(i = 0; i < 2; i++, cbp >>= 1, idx++){ rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); r->avail_cache[idx] = 1; if(cbp & 0x01) rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32); if(cbp & 0x10) rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32); } } }else{ itype = ittrans16[intra_types[0]]; itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]); r->h.pred16x16[itype](Y, s->linesize); dsp->add_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]); dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]); Y += s->current_picture.linesize[0] * 8; dsp->add_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]); dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]); itype = ittrans16[intra_types[0]]; if(itype == PLANE_PRED8x8) itype = DC_PRED8x8; itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]); r->h.pred8x8[itype](U, s->uvlinesize); dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize); r->h.pred8x8[itype](V, s->uvlinesize); dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize); }}/** @} */ // recons group/** * @addtogroup bitstream * Decode macroblock header and return CBP in case of success, -1 otherwise. */static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types){ MpegEncContext *s = &r->s; GetBitContext *gb = &s->gb; int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int i, t; if(!r->si.type){ r->is16 = get_bits1(gb); if(!r->is16 && !r->rv30){ if(!get_bits1(gb)) av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); } s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; }else{ r->block_type = r->decode_mb_info(r); if(r->block_type == -1) return -1; s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; r->mb_type[mb_pos] = r->block_type; if(r->block_type == RV34_MB_SKIP){ if(s->pict_type == FF_P_TYPE) r->mb_type[mb_pos] = RV34_MB_P_16x16; if(s->pict_type == FF_B_TYPE) r->mb_type[mb_pos] = RV34_MB_B_DIRECT; } r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); rv34_decode_mv(r, r->block_type); if(r->block_type == RV34_MB_SKIP){ fill_rectangle(intra_types, 4, 4, s->b4_stride, 0, sizeof(intra_types[0])); return 0; } r->chroma_vlc = 1; r->luma_vlc = 0; } if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ if(r->is16){ t = get_bits(gb, 2); fill_rectangle(intra_types, 4, 4, s->b4_stride, t, sizeof(intra_types[0])); r->luma_vlc = 2; }else{ if(r->decode_intra_types(r, gb, intra_types) < 0) return -1; r->luma_vlc = 1; } r->chroma_vlc = 0; r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); }else{ for(i = 0; i < 16; i++) intra_types[(i & 3) + (i>>2) * s->b4_stride] = 0; r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ r->is16 = 1; r->chroma_vlc = 1; r->luma_vlc = 2; r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); } } return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);}/** * @addtogroup recons * @{ *//** * mask for retrieving all bits in coded block pattern * corresponding to one 8x8 block */#define LUMA_CBP_BLOCK_MASK 0x303#define U_CBP_MASK 0x0F0000#define V_CBP_MASK 0xF00000
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -