public int ff_h264_decode_mb_cavlc(H264Context h) { MpegEncContext s = h.s; int mb_xy; int partition_count; int mb_type, cbp; int dct8x8_allowed = h.pps.transform_8x8_mode; // DebugTool.dumpDebugFrameData(h, "BEFORE-ff_h264_decode_mb_cavlc"); mb_xy = h.mb_xy = s.mb_x + s.mb_y * s.mb_stride; //tprintf(s.avctx, "pic:%d mb:%d/%d\n", h.frame_num, s.mb_x, s.mb_y); cbp = 0; /* avoid warning. FIXME: find a solution without slowing down the code */ if (h.slice_type_nos != H264Context.FF_I_TYPE) { if (s.mb_skip_run == -1) s.mb_skip_run = s.gb.get_ue_golomb("mb_skip_run"); if (0 != s.mb_skip_run--) { if (h.mb_aff_frame != 0 && (s.mb_y & 1) == 0) { if (s.mb_skip_run == 0) h.mb_mbaff = h.mb_field_decoding_flag = (int)s.gb.get_bits1("mb_mbaff"); } h.decode_mb_skip(); return 0; } } if (h.mb_aff_frame != 0) { if ((s.mb_y & 1) == 0) h.mb_mbaff = h.mb_field_decoding_flag = (int)s.gb.get_bits1("mb_field_decoding_flag"); } h.prev_mb_skipped = 0; mb_type = s.gb.get_ue_golomb("mb_type"); if (h.slice_type_nos == H264Context.FF_B_TYPE) { if (mb_type < 23) { partition_count = H264Data.b_mb_type_info[mb_type].partition_count; mb_type = H264Data.b_mb_type_info[mb_type].type; } else { mb_type -= 23; // goto decode_intra_mb; // decode_intra_mb: if (mb_type > 25) { //av_log(h.s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h.slice_type), s.mb_x, s.mb_y); return -1; } partition_count = 0; cbp = H264Data.i_mb_type_info[mb_type].cbp; h.intra16x16_pred_mode = H264Data.i_mb_type_info[mb_type].pred_mode; mb_type = H264Data.i_mb_type_info[mb_type].type; } } else if (h.slice_type_nos == H264Context.FF_P_TYPE) { if (mb_type < 5) { partition_count = H264Data.p_mb_type_info[mb_type].partition_count; mb_type = H264Data.p_mb_type_info[mb_type].type; } else { mb_type -= 5; // goto decode_intra_mb; // decode_intra_mb: if (mb_type > 25) { //av_log(h.s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h.slice_type), s.mb_x, s.mb_y); return -1; } partition_count = 0; cbp = H264Data.i_mb_type_info[mb_type].cbp; h.intra16x16_pred_mode = H264Data.i_mb_type_info[mb_type].pred_mode; mb_type = H264Data.i_mb_type_info[mb_type].type; } } else { //assert(h.slice_type_nos == H264Context.FF_I_TYPE); if (h.slice_type == H264Context.FF_SI_TYPE && mb_type != 0) mb_type--; //decode_intra_mb: if (mb_type > 25) { //av_log(h.s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h.slice_type), s.mb_x, s.mb_y); return -1; } partition_count = 0; cbp = H264Data.i_mb_type_info[mb_type].cbp; h.intra16x16_pred_mode = H264Data.i_mb_type_info[mb_type].pred_mode; mb_type = H264Data.i_mb_type_info[mb_type].type; } if (h.mb_field_decoding_flag != 0) mb_type |= H264Context.MB_TYPE_INTERLACED; h.slice_table_base[h.slice_table_offset + mb_xy] = h.slice_num; if (0 != (mb_type & H264Context.MB_TYPE_INTRA_PCM)) { int x; // We assume these blocks are very rare so we do not optimize it. s.gb.align_get_bits(); // The pixels are stored in the same order as levels in h.mb array. for (x = 0; x < ((h.sps.chroma_format_idc != 0) ? 384 : 256); x += 2) { // Combine 2 byte to get a short. //((uint8_t*)h.mb)[x]= (int)s.gb.get_bits(8); int val = (int)s.gb.get_bits(8, "val"); val = val | (((int)s.gb.get_bits(8, "val")) << 8); h.mb[x / 2] = (short)val; } // In deblocking, the quantizer is 0 s.current_picture.qscale_table[mb_xy] = 0; // All coeffs are present //memset(h.non_zero_count[mb_xy], 16, 32); Arrays.Fill(h.non_zero_count[mb_xy], 0, 32, 16); s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy] = mb_type; return 0; } if (h.mb_mbaff != 0) { h.ref_count[0] <<= 1; h.ref_count[1] <<= 1; } h.fill_decode_neighbors(mb_type); h.fill_decode_caches(mb_type); //mb_pred if (0 != (mb_type & 7)) { int pred_mode; // init_top_left_availability(h); if (0 != (mb_type & H264Context.MB_TYPE_INTRA4x4)) { int i; int di = 1; if (dct8x8_allowed != 0 && s.gb.get_bits1("MB_TYPE_8x8DCT?") != 0) { mb_type |= H264Context.MB_TYPE_8x8DCT; di = 4; } // fill_intra4x4_pred_table(h); for (i = 0; i < 16; i += di) { int mode = h.pred_intra_mode(i); if (0 == s.gb.get_bits1("rem_mode")) { int rem_mode = (int)s.gb.get_bits(3, "rem_mode"); mode = rem_mode + ((rem_mode >= mode) ? 1 : 0); } if (di == 4) Rectangle.fill_rectangle_sign(h.intra4x4_pred_mode_cache, H264Context.scan8[i], 2, 2, 8, mode, 1); else h.intra4x4_pred_mode_cache[H264Context.scan8[i]] = mode; } h.ff_h264_write_back_intra_pred_mode(); if (h.ff_h264_check_intra4x4_pred_mode() < 0) return -1; } else { h.intra16x16_pred_mode = h.ff_h264_check_intra_pred_mode(h.intra16x16_pred_mode); if (h.intra16x16_pred_mode < 0) return -1; } if (h.sps.chroma_format_idc != 0) { pred_mode = h.ff_h264_check_intra_pred_mode(s.gb.get_ue_golomb_31("pred_mode")); if (pred_mode < 0) return -1; h.chroma_pred_mode = pred_mode; } } else if (partition_count == 4) { int i, j; int[] sub_partition_count = new int[4]; int list; int[][] @ref = Arrays.Create<int>(2, 4); if (h.slice_type_nos == H264Context.FF_B_TYPE) { for (i = 0; i < 4; i++) { h.sub_mb_type[i] = s.gb.get_ue_golomb_31("sub_mb_type"); if (h.sub_mb_type[i] >= 13) { //av_log(h.s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h.sub_mb_type[i], s.mb_x, s.mb_y); return -1; } sub_partition_count[i] = H264Data.b_sub_mb_type_info[h.sub_mb_type[i]].partition_count; h.sub_mb_type[i] = H264Data.b_sub_mb_type_info[h.sub_mb_type[i]].type; } if (0 != ((h.sub_mb_type[0] | h.sub_mb_type[1] | h.sub_mb_type[2] | h.sub_mb_type[3]) & H264Context.MB_TYPE_DIRECT2)) { mb_type = h.ff_h264_pred_direct_motion(mb_type); h.ref_cache[0][H264Context.scan8[4]] = h.ref_cache[1][H264Context.scan8[4]] = h.ref_cache[0][H264Context.scan8[12]] = h.ref_cache[1][H264Context.scan8[12]] = H264Context.PART_NOT_AVAILABLE; } } else { //assert(h.slice_type_nos == H264Context.FF_P_TYPE); //FIXME SP correct ? for (i = 0; i < 4; i++) { h.sub_mb_type[i] = s.gb.get_ue_golomb_31("sub_mb_type"); if (h.sub_mb_type[i] >= 4) { //av_log(h.s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h.sub_mb_type[i], s.mb_x, s.mb_y); return -1; } sub_partition_count[i] = H264Data.p_sub_mb_type_info[h.sub_mb_type[i]].partition_count; h.sub_mb_type[i] = H264Data.p_sub_mb_type_info[h.sub_mb_type[i]].type; } } for (list = 0; list < h.list_count; list++) { int ref_count = ((mb_type & H264Context.MB_TYPE_REF0) != 0) ? 1 : (int)h.ref_count[list]; for (i = 0; i < 4; i++) { if (0 != (h.sub_mb_type[i] & H264Context.MB_TYPE_DIRECT2)) continue; if (0 != ((h.sub_mb_type[i]) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list))))) { int tmp; if (ref_count == 1) { tmp = 0; } else if (ref_count == 2) { tmp = (int)s.gb.get_bits1("ref_count?") ^ 1; } else { tmp = s.gb.get_ue_golomb_31("ref_count?"); if (tmp >= ref_count) { //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp); return -1; } } @ref[list][i] = tmp; } else { //FIXME @ref[list][i] = -1; } } } if (dct8x8_allowed != 0) dct8x8_allowed = h.get_dct8x8_allowed(); for (list = 0; list < h.list_count; list++) { for (i = 0; i < 4; i++) { if (0 != (h.sub_mb_type[i] & H264Context.MB_TYPE_DIRECT2)) { h.ref_cache[list][H264Context.scan8[4 * i]] = h.ref_cache[list][H264Context.scan8[4 * i] + 1]; continue; } h.ref_cache[list][H264Context.scan8[4 * i]] = h.ref_cache[list][H264Context.scan8[4 * i] + 1] = h.ref_cache[list][H264Context.scan8[4 * i] + 8] = h.ref_cache[list][H264Context.scan8[4 * i] + 9] = @ref[list][i]; if (((h.sub_mb_type[i]) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))) != 0) {//IS_DIR(h.sub_mb_type[i], 0, list)){ int sub_mb_type = h.sub_mb_type[i]; int block_width = ((sub_mb_type & (H264Context.MB_TYPE_16x16 | H264Context.MB_TYPE_16x8)) != 0 ? 2 : 1); for (j = 0; j < sub_partition_count[i]; j++) { int mx, my; int index = 4 * i + block_width * j; //int16_t (* mv_cache)[2]= &h.mv_cache[list][ H264Context.scan8[index] ]; int[][] mv_cache_base = h.mv_cache[list]; int my_cache_offset = H264Context.scan8[index]; int[] mxmy = new int[2]; h.pred_motion(index, block_width, list, h.ref_cache[list][H264Context.scan8[index]], mxmy); mx = mxmy[0]; my = mxmy[1]; mx += s.gb.get_se_golomb("mx?"); my += s.gb.get_se_golomb("my?"); //tprintf(s.avctx, "final mv:%d %d\n", mx, my); if (0 != (sub_mb_type & H264Context.MB_TYPE_16x16)) { mv_cache_base[my_cache_offset + 1][0] = mv_cache_base[my_cache_offset + 8][0] = mv_cache_base[my_cache_offset + 9][0] = mx; mv_cache_base[my_cache_offset + 1][1] = mv_cache_base[my_cache_offset + 8][1] = mv_cache_base[my_cache_offset + 9][1] = my; } else if (0 != (sub_mb_type & H264Context.MB_TYPE_16x8)) { mv_cache_base[my_cache_offset + 1][0] = mx; mv_cache_base[my_cache_offset + 1][1] = my; } else if (0 != (sub_mb_type & H264Context.MB_TYPE_8x16)) { mv_cache_base[my_cache_offset + 8][0] = mx; mv_cache_base[my_cache_offset + 8][1] = my; } mv_cache_base[my_cache_offset + 0][0] = mx; mv_cache_base[my_cache_offset + 0][1] = my; } } else { /* uint32_t *p= (uint32_t *)&h.mv_cache[list][ scan8[4*i] ][0]; p[0] = p[1]= p[8] = p[9]= 0; */ h.mv_cache[list][H264Context.scan8[4 * i] + 0][0] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 1][0] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 8][0] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 9][0] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 0][1] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 1][1] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 8][1] = (short)0; h.mv_cache[list][H264Context.scan8[4 * i] + 9][1] = (short)0; } } } } else if (0 != (mb_type & H264Context.MB_TYPE_DIRECT2)) { mb_type = h.ff_h264_pred_direct_motion(mb_type); dct8x8_allowed &= h.sps.direct_8x8_inference_flag; } else { int list, mx = 0, my = 0, i; //FIXME we should set ref_idx_l? to 0 if we use that later ... if (0 != (mb_type & H264Context.MB_TYPE_16x16)) { for (list = 0; list < h.list_count; list++) { int val; if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))) != 0) { if (h.ref_count[list] == 1) { val = 0; } else if (h.ref_count[list] == 2) { val = (int)(s.gb.get_bits1("ref_count?") ^ 1); } else { val = s.gb.get_ue_golomb_31("ref_count?"); if (val >= h.ref_count[list]) { //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val); return -1; } } Rectangle.fill_rectangle_sign(h.ref_cache[list], H264Context.scan8[0], 4, 4, 8, val, 1); } } for (list = 0; list < h.list_count; list++) { if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))) != 0) { int[] mxmy = new int[] { mx, my }; h.pred_motion(0, 4, list, h.ref_cache[list][H264Context.scan8[0]], mxmy); mx = mxmy[0]; my = mxmy[1]; mx += s.gb.get_se_golomb("mx?"); my += s.gb.get_se_golomb("my?"); //int val = h.pack16to32(mx,my); // DebugTool.printDebugString(" ****(1) mx="+mx+", my="+my+", val="+val+"\n"); //tprintf(s.avctx, "final mv:%d %d\n", mx, my); Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], H264Context.scan8[0], 4, 4, 8, H264Context.pack16to32(mx, my), 4); } } } else if (0 != (mb_type & H264Context.MB_TYPE_16x8)) { for (list = 0; list < h.list_count; list++) { for (i = 0; i < 2; i++) { int val; if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0) { if (h.ref_count[list] == 1) { val = 0; } else if (h.ref_count[list] == 2) { val = (int)(s.gb.get_bits1("ref_count?") ^ 1); } else { val = s.gb.get_ue_golomb_31("ref_count?"); if (val >= h.ref_count[list]) { //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val); return -1; } } } else { //!!?????????????????????? Need unsigneded?? val = H264Context.LIST_NOT_USED; } // if Rectangle.fill_rectangle_sign(h.ref_cache[list], H264Context.scan8[0] + 16 * i, 4, 2, 8, val, 1); } } for (list = 0; list < h.list_count; list++) { for (i = 0; i < 2; i++) { int val; if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0) { int[] mxmy = new int[] { mx, my }; h.pred_16x8_motion(8 * i, list, h.ref_cache[list][H264Context.scan8[0] + 16 * i], mxmy); mx = mxmy[0]; my = mxmy[1]; mx += s.gb.get_se_golomb("mx?"); my += s.gb.get_se_golomb("my?"); //tprintf(s.avctx, "final mv:%d %d\n", mx, my); val = H264Context.pack16to32(mx, my); // DebugTool.printDebugString(" ****(2) mx="+mx+", my="+my+", val="+val+"\n"); } else val = 0; Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], H264Context.scan8[0] + 16 * i, 4, 2, 8, val, 4); } } } else { ////assert(IS_8X16(mb_type)); for (list = 0; list < h.list_count; list++) { for (i = 0; i < 2; i++) { int val; if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0) { //FIXME optimize if (h.ref_count[list] == 1) { val = 0; } else if (h.ref_count[list] == 2) { val = (int)(s.gb.get_bits1("ref-count?") ^ 1); } else { val = s.gb.get_ue_golomb_31("ref-count?"); if (val >= h.ref_count[list]) { //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val); return -1; } } } else { // !!?????????? Need Unsigned val = H264Context.LIST_NOT_USED; } // if Rectangle.fill_rectangle_sign(h.ref_cache[list], H264Context.scan8[0] + 2 * i, 2, 4, 8, val, 1); } } for (list = 0; list < h.list_count; list++) { for (i = 0; i < 2; i++) { int val; if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0) { int[] mxmy = new int[] { mx, my }; h.pred_8x16_motion(i * 4, list, h.ref_cache[list][H264Context.scan8[0] + 2 * i], mxmy); mx = mxmy[0]; my = mxmy[1]; mx += s.gb.get_se_golomb("mx?"); my += s.gb.get_se_golomb("my?"); //tprintf(s.avctx, "final mv:%d %d\n", mx, my); val = H264Context.pack16to32(mx, my); // DebugTool.printDebugString(" ****(3) mx="+mx+", my="+my+", val="+val+"\n"); } else val = 0; Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], H264Context.scan8[0] + 2 * i, 2, 4, 8, val, 4); } } } } if (0 != (mb_type & (H264Context.MB_TYPE_16x16 | H264Context.MB_TYPE_16x8 | H264Context.MB_TYPE_8x16 | H264Context.MB_TYPE_8x8))) h.write_back_motion(mb_type); if (0 == (mb_type & H264Context.MB_TYPE_INTRA16x16)) { cbp = s.gb.get_ue_golomb("cbp"); if (cbp > 47) { //av_log(h.s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s.mb_x, s.mb_y); return -1; } if (h.sps.chroma_format_idc != 0) { if (0 != (mb_type & H264Context.MB_TYPE_INTRA4x4)) cbp = H264Data.golomb_to_intra4x4_cbp[cbp]; else cbp = H264Data.golomb_to_inter_cbp[cbp]; } else { if (0 != (mb_type & H264Context.MB_TYPE_INTRA4x4)) cbp = golomb_to_intra4x4_cbp_gray[cbp]; else cbp = golomb_to_inter_cbp_gray[cbp]; } } if (dct8x8_allowed != 0 && (cbp & 15) != 0 && 0 == (mb_type & 7)) { mb_type |= (int)(H264Context.MB_TYPE_8x8DCT * s.gb.get_bits1("mb_type")); } h.cbp = h.cbp_table[mb_xy] = cbp; s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy] = mb_type; if (cbp != 0 || 0 != (mb_type & H264Context.MB_TYPE_INTRA16x16)) { int i8x8, i4x4, chroma_idx; int dquant; GetBitContext gb = (((mb_type & 7) != 0) ? h.intra_gb_ptr : h.inter_gb_ptr); //uint8_t *scan, *scan8x8; byte[] scan; byte[] scan8x8; if (0 != (mb_type & H264Context.MB_TYPE_INTERLACED)) { scan8x8 = (s.qscale != 0 ? h.field_scan8x8_cavlc : h.field_scan8x8_cavlc_q0); scan = (s.qscale != 0 ? h.field_scan : h.field_scan_q0); } else { scan8x8 = (s.qscale != 0 ? h.zigzag_scan8x8_cavlc : h.zigzag_scan8x8_cavlc_q0); scan = (s.qscale != 0 ? h.zigzag_scan : h.zigzag_scan_q0); } dquant = s.gb.get_se_golomb("dquant"); s.qscale += dquant; if ((/*(unsigned)*/s.qscale) > 51) { if (s.qscale < 0) s.qscale += 52; else s.qscale -= 52; if ((/*(unsigned)*/s.qscale) > 51) { //av_log(h.s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s.mb_x, s.mb_y); return -1; } } h.chroma_qp[0] = h.pps.chroma_qp_table[0][s.qscale]; h.chroma_qp[1] = h.pps.chroma_qp_table[1][s.qscale]; if (0 != (mb_type & H264Context.MB_TYPE_INTRA16x16)) { // Fill 16 uint16_t with 0 Arrays.Fill(h.mb_luma_dc, 0, 16, (short)0); //AV_ZERO128(h.mb_luma_dc+0); //AV_ZERO128(h.mb_luma_dc+8); if (decode_residual(h, h.intra_gb_ptr, h.mb_luma_dc, 0, H264Context.LUMA_DC_BLOCK_INDEX, scan, 0, h.dequant4_coeff[0][s.qscale], 0, 16) < 0) { return -1; //FIXME continue if partitioned and other return -1 too } //assert((cbp&15) == 0 || (cbp&15) == 15); if ((cbp & 15) != 0) { ///////////////////////////////// for (i8x8 = 0; i8x8 < 4; i8x8++) { for (i4x4 = 0; i4x4 < 4; i4x4++) { int index = i4x4 + 4 * i8x8; if (decode_residual(h, h.intra_gb_ptr, h.mb, 16 * index, index, scan, 1, h.dequant4_coeff[0][s.qscale], 0, 15) < 0) { return -1; } } } } else { Rectangle.fill_rectangle_unsign(h.non_zero_count_cache, H264Context.scan8[0], 4, 4, 8, 0, 1); } } else { for (i8x8 = 0; i8x8 < 4; i8x8++) { if ((cbp & (1 << i8x8)) != 0) { if (0 != (mb_type & H264Context.MB_TYPE_8x8DCT)) { short[] buf_base = h.mb; int buf_offset = 64 * i8x8; for (i4x4 = 0; i4x4 < 4; i4x4++) { if (decode_residual(h, gb, buf_base, buf_offset, i4x4 + 4 * i8x8, scan8x8, 16 * i4x4, h.dequant8_coeff[(0 != (mb_type & 7)) ? 0 : 1][s.qscale], 0, 16) < 0) return -1; } int[] nnz_base = h.non_zero_count_cache; int nnz_offset = H264Context.scan8[4 * i8x8]; nnz_base[nnz_offset + 0] += nnz_base[nnz_offset + 1] + nnz_base[nnz_offset + 8] + nnz_base[nnz_offset + 9]; } else { for (i4x4 = 0; i4x4 < 4; i4x4++) { int index = i4x4 + 4 * i8x8; if (decode_residual(h, gb, h.mb, 16 * index, index, scan, 0, h.dequant4_coeff[(mb_type & 7) != 0 ? 0 : 3][s.qscale], 0, 16) < 0) { return -1; } } } } else { int[] nnz_base = h.non_zero_count_cache; int nnz_offset = H264Context.scan8[4 * i8x8]; nnz_base[nnz_offset + 0] = nnz_base[nnz_offset + 1] = nnz_base[nnz_offset + 8] = nnz_base[nnz_offset + 9] = 0; } } } if ((cbp & 0x030) != 0) { // Fill 2x4 uint_16t with 0 Arrays.Fill(h.mb_chroma_dc[0], (short)0); Arrays.Fill(h.mb_chroma_dc[1], (short)0); //AV_ZERO128(h.mb_chroma_dc); for (chroma_idx = 0; chroma_idx < 2; chroma_idx++) { if (decode_residual(h, gb, h.mb_chroma_dc[chroma_idx], 0, H264Context.CHROMA_DC_BLOCK_INDEX + chroma_idx, H264Data.chroma_dc_scan, 0, null, 0, 4) < 0) { // DebugTool.printDebugString("----Error type 16\n"); return -1; } } } if ((cbp & 0x020) != 0) { for (chroma_idx = 0; chroma_idx < 2; chroma_idx++) { long[] qmul = h.dequant4_coeff[chroma_idx + 1 + (((mb_type & 7) != 0) ? 0 : 3)][h.chroma_qp[chroma_idx]]; for (i4x4 = 0; i4x4 < 4; i4x4++) { int index = 16 + 4 * chroma_idx + i4x4; if (decode_residual(h, gb, h.mb, 16 * index, index, scan, 1, qmul, 0, 15) < 0) { return -1; } } } } else { int[] nnz = h.non_zero_count_cache; nnz[H264Context.scan8[16] + 0] = nnz[H264Context.scan8[16] + 1] = nnz[H264Context.scan8[16] + 8] = nnz[H264Context.scan8[16] + 9] = nnz[H264Context.scan8[20] + 0] = nnz[H264Context.scan8[20] + 1] = nnz[H264Context.scan8[20] + 8] = nnz[H264Context.scan8[20] + 9] = 0; } } else { int[] nnz = h.non_zero_count_cache; Rectangle.fill_rectangle_unsign(nnz, H264Context.scan8[0], 4, 4, 8, 0, 1); nnz[H264Context.scan8[16] + 0] = nnz[H264Context.scan8[16] + 1] = nnz[H264Context.scan8[16] + 8] = nnz[H264Context.scan8[16] + 9] = nnz[H264Context.scan8[20] + 0] = nnz[H264Context.scan8[20] + 1] = nnz[H264Context.scan8[20] + 8] = nnz[H264Context.scan8[20] + 9] = 0; } s.current_picture.qscale_table[mb_xy] = s.qscale; h.write_back_non_zero_count(); if (h.mb_mbaff != 0) { h.ref_count[0] >>= 1; h.ref_count[1] >>= 1; } // DebugTool.dumpDebugFrameData(h, "AFTER-ff_h264_decode_mb_cavlc"); return 0; }