public void mc_part_weighted(int n, int square, int chroma_height, int delta, byte[] dest_y_base, int dest_y_offset, byte[] dest_cb_base, int dest_cb_offset, byte[] dest_cr_base, int dest_cr_offset, int x_offset, int y_offset, DSPContext.Ih264_qpel_mc_func[] qpix_put, DSPContext.Ih264_chroma_mc_func chroma_put, H264DSPContext.IH264WeightFunctionStub luma_weight_op, H264DSPContext.IH264WeightFunctionStub chroma_weight_op, H264DSPContext.IH264BiWeightFunctionStub luma_weight_avg, H264DSPContext.IH264BiWeightFunctionStub chroma_weight_avg, int list0, int list1) { dest_y_offset += 2 * x_offset + 2 * y_offset * this.mb_linesize; dest_cb_offset += x_offset + y_offset * this.mb_uvlinesize; dest_cr_offset += x_offset + y_offset * this.mb_uvlinesize; x_offset += 8 * s.mb_x; y_offset += 8 * (s.mb_y >> mb_field_decoding_flag); if (list0 != 0 && list1 != 0) { /* don't optimize for luma-only case, since B-frames usually * use implicit weights => chroma too. */ byte[] tmp_cb_base = s.obmc_scratchpad; int tmp_cb_offset = 0; byte[] tmp_cr_base = s.obmc_scratchpad; int tmp_cr_offset = 8; byte[] tmp_y_base = s.obmc_scratchpad; int tmp_y_offset = 8 * this.mb_uvlinesize; int refn0 = this.ref_cache[0][scan8[n]]; int refn1 = this.ref_cache[1][scan8[n]]; mc_dir_part(this.ref_list[0][refn0], n, square, chroma_height, delta, 0, dest_y_base, dest_y_offset, dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset, x_offset, y_offset, qpix_put, chroma_put); mc_dir_part(this.ref_list[1][refn1], n, square, chroma_height, delta, 1, tmp_y_base, tmp_y_offset, tmp_cb_base, tmp_cb_offset, tmp_cr_base, tmp_cr_offset, x_offset, y_offset, qpix_put, chroma_put); if (this.use_weight == 2) { int weight0 = this.implicit_weight[refn0][refn1][s.mb_y & 1]; int weight1 = 64 - weight0; luma_weight_avg(dest_y_base, dest_y_offset, tmp_y_base, tmp_y_offset, this.mb_linesize, 5, weight0, weight1, 0); chroma_weight_avg(dest_cb_base, dest_cb_offset, tmp_cb_base, tmp_cb_offset, this.mb_uvlinesize, 5, weight0, weight1, 0); chroma_weight_avg(dest_cr_base, dest_cr_offset, tmp_cr_base, tmp_cr_offset, this.mb_uvlinesize, 5, weight0, weight1, 0); } else { luma_weight_avg(dest_y_base, dest_y_offset, tmp_y_base, tmp_y_offset, this.mb_linesize, this.luma_log2_weight_denom, this.luma_weight[refn0][0][0], this.luma_weight[refn1][1][0], this.luma_weight[refn0][0][1] + this.luma_weight[refn1][1][1]); chroma_weight_avg(dest_cb_base, dest_cb_offset, tmp_cb_base, tmp_cb_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom, this.chroma_weight[refn0][0][0][0], this.chroma_weight[refn1][1][0][0], this.chroma_weight[refn0][0][0][1] + this.chroma_weight[refn1][1][0][1]); chroma_weight_avg(dest_cr_base, dest_cr_offset, tmp_cr_base, tmp_cr_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom, this.chroma_weight[refn0][0][1][0], this.chroma_weight[refn1][1][1][0], this.chroma_weight[refn0][0][1][1] + this.chroma_weight[refn1][1][1][1]); } } else { int list = (list1 != 0 ? 1 : 0); int refn = this.ref_cache[list][scan8[n]]; AVFrame @ref = this.ref_list[list][refn]; mc_dir_part(@ref, n, square, chroma_height, delta, list, dest_y_base, dest_y_offset, dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset, x_offset, y_offset, qpix_put, chroma_put); luma_weight_op(dest_y_base, dest_y_offset, this.mb_linesize, this.luma_log2_weight_denom, this.luma_weight[refn][list][0], this.luma_weight[refn][list][1]); if (this.use_weight_chroma != 0) { chroma_weight_op(dest_cb_base, dest_cb_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom, this.chroma_weight[refn][list][0][0], this.chroma_weight[refn][list][0][1]); chroma_weight_op(dest_cr_base, dest_cr_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom, this.chroma_weight[refn][list][1][0], this.chroma_weight[refn][list][1][1]); } } }
public void mc_part_std(int n, int square, int chroma_height, int delta, byte[] dest_y_base, int dest_y_offset, byte[] dest_cb_base, int dest_cb_offset, byte[] dest_cr_base, int dest_cr_offset, int x_offset, int y_offset, DSPContext.Ih264_qpel_mc_func[] qpix_put, DSPContext.Ih264_chroma_mc_func chroma_put, DSPContext.Ih264_qpel_mc_func[] qpix_avg, DSPContext.Ih264_chroma_mc_func chroma_avg, int list0, int list1) { DSPContext.Ih264_qpel_mc_func[] qpix_op = qpix_put; DSPContext.Ih264_chroma_mc_func chroma_op = chroma_put; dest_y_offset += 2 * x_offset + 2 * y_offset * this.mb_linesize; dest_cb_offset += x_offset + y_offset * this.mb_uvlinesize; dest_cr_offset += x_offset + y_offset * this.mb_uvlinesize; x_offset += 8 * s.mb_x; y_offset += 8 * (s.mb_y >> mb_field_decoding_flag); if (list0 != 0) { AVFrame @ref = this.ref_list[0][this.ref_cache[0][scan8[n]]]; mc_dir_part(@ref, n, square, chroma_height, delta, 0, dest_y_base, dest_y_offset, dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset, x_offset, y_offset, qpix_op, chroma_op); qpix_op = qpix_avg; chroma_op = chroma_avg; } if (list1 != 0) { AVFrame @ref = this.ref_list[1][this.ref_cache[1][scan8[n]]]; mc_dir_part(@ref, n, square, chroma_height, delta, 1, dest_y_base, dest_y_offset, dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset, x_offset, y_offset, qpix_op, chroma_op); } }
//////////////////////////////// // Motion functions //public void mc_dir_part(Picture pic, int n, int square, int chroma_height, int delta, int list, // uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, // int src_x_offset, int src_y_offset, // qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op){ public void mc_dir_part(AVFrame pic, int n, int square, int chroma_height, int delta, int list, byte[] dest_y_base, int dest_y_offset, byte[] dest_cb_base, int dest_cb_offset, byte[] dest_cr_base, int dest_cr_offset, int src_x_offset, int src_y_offset, DSPContext.Ih264_qpel_mc_func[] qpix_op, DSPContext.Ih264_chroma_mc_func chroma_op) { int mx = this.mv_cache[list][scan8[n]][0] + src_x_offset * 8; int my = this.mv_cache[list][scan8[n]][1] + src_y_offset * 8; int luma_xy = (mx & 3) + ((my & 3) << 2); //uint8_t * src_y = pic.data[0] + (mx>>2) + (my>>2)*this.mb_linesize; //uint8_t * src_cb, * src_cr; byte[] src_y_base = pic.data_base[0]; int _src_y_offset = pic.data_offset[0] + (mx >> 2) + (my >> 2) * this.mb_linesize; byte[] src_cb_base; int src_cb_offset; byte[] src_cr_base; int src_cr_offset; int extra_width = this.emu_edge_width; int extra_height = this.emu_edge_height; int emu = 0; int full_mx = mx >> 2; int full_my = my >> 2; int pic_width = 16 * s.mb_width; int pic_height = 16 * s.mb_height >> mb_field_decoding_flag; // DebugTool.printDebugString("***mc_dir_part: src_x_offset="+src_x_offset+", src_y_offset="+src_y_offset+", list="+list+", n="+n+", mv_cache[0]="+this.mv_cache[list][ scan8[n] ][0]+", mv_cache[1]="+this.mv_cache[list][ scan8[n] ][1]+"\n"); // DebugTool.printDebugString("***mc_dir_part: mx="+mx+", my="+my+", luma_xy="+luma_xy+", _src_y_offset="+((mx>>2) + (my>>2)*this.mb_linesize)+"\n"); if ((mx & 7) != 0) extra_width -= 3; if ((my & 7) != 0) 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) { // DebugTool.printDebugString("***mc_dir_part: case 1\n"); s.dsp.ff_emulated_edge_mc(s.allocated_edge_emu_buffer, s.edge_emu_buffer_offset , src_y_base, _src_y_offset - 2 - 2 * this.mb_linesize , this.mb_linesize, 16 + 5, 16 + 5/*FIXME*/ , full_mx - 2, full_my - 2 , pic_width, pic_height); src_y_base = s.allocated_edge_emu_buffer; _src_y_offset = s.edge_emu_buffer_offset + 2 + 2 * this.mb_linesize; emu = 1; } qpix_op[luma_xy](dest_y_base, dest_y_offset, src_y_base, _src_y_offset, this.mb_linesize); //FIXME try variable height perhaps? if (0 == square) { // DebugTool.printDebugString("***mc_dir_part: case 2\n"); qpix_op[luma_xy](dest_y_base, dest_y_offset + delta, src_y_base, _src_y_offset + delta, this.mb_linesize); } //if(MpegEncContext.CONFIG_GRAY !=0 && (s.flags&MpegEncContext.CODEC_FLAG_GRAY)!=0) return; if (mb_field_decoding_flag != 0) { // DebugTool.printDebugString("***mc_dir_part: case 3\n"); // chroma offset when predicting from a field of opposite parity my += 2 * ((s.mb_y & 1) - (pic.reference - 1)); emu |= (((my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1)) ? 1 : 0); } src_cb_base = pic.data_base[1]; src_cb_offset = pic.data_offset[1] + (mx >> 3) + (my >> 3) * this.mb_uvlinesize; src_cr_base = pic.data_base[2]; src_cr_offset = pic.data_offset[2] + (mx >> 3) + (my >> 3) * this.mb_uvlinesize; if (emu != 0) { // DebugTool.printDebugString("***mc_dir_part: case 4\n"); s.dsp.ff_emulated_edge_mc(s.allocated_edge_emu_buffer, s.edge_emu_buffer_offset, src_cb_base, src_cb_offset, this.mb_uvlinesize, 9, 9/*FIXME*/, (mx >> 3), (my >> 3), pic_width >> 1, pic_height >> 1); src_cb_base = s.allocated_edge_emu_buffer; src_cb_offset = s.edge_emu_buffer_offset; } chroma_op(dest_cb_base, dest_cb_offset, src_cb_base, src_cb_offset, this.mb_uvlinesize, chroma_height, mx & 7, my & 7); if (emu != 0) { // DebugTool.printDebugString("***mc_dir_part: case 5\n"); s.dsp.ff_emulated_edge_mc(s.allocated_edge_emu_buffer, s.edge_emu_buffer_offset, src_cr_base, src_cr_offset, this.mb_uvlinesize, 9, 9/*FIXME*/, (mx >> 3), (my >> 3), pic_width >> 1, pic_height >> 1); src_cr_base = s.allocated_edge_emu_buffer; src_cr_offset = s.edge_emu_buffer_offset; } chroma_op(dest_cr_base, dest_cr_offset, src_cr_base, src_cr_offset, this.mb_uvlinesize, chroma_height, mx & 7, my & 7); }
/* public void mc_part(int n, 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, h264_weight_func *weight_op, h264_biweight_func *weight_avg, int list0, int list1){ */ public void mc_part(int n, int square, int chroma_height, int delta, byte[] dest_y_base, int dest_y_offset, byte[] dest_cb_base, int dest_cb_offset, byte[] dest_cr_base, int dest_cr_offset, int x_offset, int y_offset, DSPContext.Ih264_qpel_mc_func[] qpix_put, DSPContext.Ih264_chroma_mc_func chroma_put, DSPContext.Ih264_qpel_mc_func[] qpix_avg, DSPContext.Ih264_chroma_mc_func chroma_avg, H264DSPContext.IH264WeightFunctionStub[] weight_op_base, int weight_op_offset, H264DSPContext.IH264BiWeightFunctionStub[] weight_avg_base, int weight_avg_offset, int list0, int list1) { if ((this.use_weight == 2 && list0 != 0 && list1 != 0 && (this.implicit_weight[this.ref_cache[0][scan8[n]]][this.ref_cache[1][scan8[n]]][this.s.mb_y & 1] != 32)) || this.use_weight == 1) mc_part_weighted(n, square, chroma_height, delta, dest_y_base, dest_y_offset, dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset, x_offset, y_offset, qpix_put, chroma_put, weight_op_base[weight_op_offset + 0], weight_op_base[weight_op_offset + 3], weight_avg_base[weight_avg_offset + 0], weight_avg_base[weight_avg_offset + 3] , list0, list1); else mc_part_std(n, square, chroma_height, delta, dest_y_base, dest_y_offset, dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset, x_offset, y_offset, qpix_put, chroma_put, qpix_avg, chroma_avg, list0, list1); }
// public void hl_motion(uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, // qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put), // qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg), // h264_weight_func *weight_op, h264_biweight_func *weight_avg){ public void hl_motion( byte[] dest_y_base, int dest_y_offset, byte[] dest_cb_base, int dest_cb_offset, byte[] dest_cr_base, int dest_cr_offset, DSPContext.Ih264_qpel_mc_func[][] qpix_put, DSPContext.Ih264_chroma_mc_func[] chroma_put, DSPContext.Ih264_qpel_mc_func[][] qpix_avg, DSPContext.Ih264_chroma_mc_func[] chroma_avg, H264DSPContext.IH264WeightFunctionStub[] weight_op, H264DSPContext.IH264BiWeightFunctionStub[] weight_avg) { int mb_xy = this.mb_xy; int mb_type = (int)s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy]; ////assert(IS_INTER(mb_type)); prefetch_motion(0); if ((mb_type & MB_TYPE_16x16) != 0) { mc_part(0, 1, 8, 0, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , 0, 0, qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0], weight_op, 0, weight_avg, 0, IS_DIR(mb_type, 0, 0) , IS_DIR(mb_type, 0, 1)); } else if ((mb_type & MB_TYPE_16x8) != 0) { mc_part(0, 0, 4, 8, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , 0, 0, qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0], weight_op, 1, weight_avg, 1, IS_DIR(mb_type, 0, 0) , IS_DIR(mb_type, 0, 1)); mc_part(8, 0, 4, 8, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , 0, 4, qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0], weight_op, 1, weight_avg, 1, IS_DIR(mb_type, 1, 0) , IS_DIR(mb_type, 1, 1)); } else if ((mb_type & MB_TYPE_8x16) != 0) { mc_part(0, 0, 8, 8 * this.mb_linesize, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , 0, 0, qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1], weight_op, 2, weight_avg, 2, IS_DIR(mb_type, 0, 0) , IS_DIR(mb_type, 0, 1)); mc_part(4, 0, 8, 8 * this.mb_linesize, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , 4, 0, qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1], weight_op, 2, weight_avg, 2, IS_DIR(mb_type, 1, 0) , IS_DIR(mb_type, 1, 1)); } else { int i; ////assert(IS_8X8(mb_type)); for (i = 0; i < 4; i++) { int sub_mb_type = this.sub_mb_type[i]; int n = 4 * i; int x_offset = (i & 1) << 2; int y_offset = (i & 2) << 1; if ((sub_mb_type & MB_TYPE_16x16) != 0) { mc_part(n, 1, 4, 0, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , x_offset, y_offset, qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1], weight_op, 3, weight_avg, 3, IS_DIR(sub_mb_type, 0, 0) , IS_DIR(sub_mb_type, 0, 1)); } else if ((sub_mb_type & MB_TYPE_16x8) != 0) { mc_part(n, 0, 2, 4, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , x_offset, y_offset, qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1], weight_op, 4, weight_avg, 4, IS_DIR(sub_mb_type, 0, 0) , IS_DIR(sub_mb_type, 0, 1)); mc_part(n + 2, 0, 2, 4, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , x_offset, y_offset + 2, qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1], weight_op, 4, weight_avg, 4, IS_DIR(sub_mb_type, 0, 0) , IS_DIR(sub_mb_type, 0, 1)); } else if ((sub_mb_type & MB_TYPE_8x16) != 0) { mc_part(n, 0, 4, 4 * this.mb_linesize, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , x_offset, y_offset, qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2], weight_op, 5, weight_avg, 5, IS_DIR(sub_mb_type, 0, 0) , IS_DIR(sub_mb_type, 0, 1)); mc_part(n + 1, 0, 4, 4 * this.mb_linesize, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , x_offset + 2, y_offset, qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2], weight_op, 5, weight_avg, 5, IS_DIR(sub_mb_type, 0, 0) , IS_DIR(sub_mb_type, 0, 1)); } else { int j; ////assert(IS_SUB_4X4(sub_mb_type)); for (j = 0; j < 4; j++) { int sub_x_offset = x_offset + 2 * (j & 1); int sub_y_offset = y_offset + (j & 2); mc_part(n + j, 1, 2, 0, dest_y_base, dest_y_offset , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset , sub_x_offset, sub_y_offset, qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2], weight_op, 6, weight_avg, 6, IS_DIR(sub_mb_type, 0, 0) , IS_DIR(sub_mb_type, 0, 1)); } } } } prefetch_motion(1); }