/** * decodes a slice header. * This will also call MPV_common_init() and frame_start() as needed. * * @param h h264context * @param h0 h264 master context (differs from 'h' when doing sliced based parallel decoding) * * @return 0 if okay, <0 if an error occurred, 1 if decoding must not be multithreaded */ public static int decode_slice_header(H264Context h, H264Context h0) { MpegEncContext s = h.s; MpegEncContext s0 = h0.s; /*unsigned */ int first_mb_in_slice; /*unsigned */ int pps_id; int num_ref_idx_active_override_flag; /*unsigned */ int slice_type, tmp, i, j; int default_ref_list_done = 0; int last_pic_structure; s.dropable = (h.nal_ref_idc == 0) ? 1 : 0; s.me.qpel_put = DSPContext.put_h264_qpel_pixels_tab; s.me.qpel_avg = DSPContext.avg_h264_qpel_pixels_tab; first_mb_in_slice = s.gb.get_ue_golomb("first_mb_in_slice"); if (first_mb_in_slice == 0) { //FIXME better field boundary detection if ((h0.current_slice != 0) && (s.picture_structure != Constants.PICT_FRAME)) { h.field_end(); } // if h0.current_slice = 0; if (0 == s0.first_field) s.current_picture_ptr = null; } slice_type = s.gb.get_ue_golomb_31("slice_type"); if (slice_type > 9) { // DebugTool.printDebugString(" --- decode_slide_header error case 0\n"); //av_log(h.s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h.slice_type, s.mb_x, s.mb_y); return -60; } if (slice_type > 4) { slice_type -= 5; h.slice_type_fixed = 1; } else h.slice_type_fixed = 0; slice_type = H264Data.golomb_to_pict_type[slice_type]; /* if(slice_type == H264Context.FF_I_TYPE) { //Console.WriteLine("Decoding I-Slice."); } else if(slice_type == H264Context.FF_P_TYPE) { //Console.WriteLine("Decoding P-Slice."); } else if(slice_type == H264Context.FF_B_TYPE) { //Console.WriteLine("Decoding B-Slice."); } else if(slice_type == H264Context.FF_S_TYPE) { //Console.WriteLine("Decoding S-Slice."); } else if(slice_type == H264Context.FF_SI_TYPE) { //Console.WriteLine("Decoding SI-Slice."); } else if(slice_type == H264Context.FF_SP_TYPE) { //Console.WriteLine("Decoding SP-Slice."); } else if(slice_type == H264Context.FF_BI_TYPE) { //Console.WriteLine("Decoding BI-Slice."); } // if */ if (slice_type == FF_I_TYPE || (h0.current_slice != 0 && slice_type == h0.last_slice_type)) { default_ref_list_done = 1; } h.slice_type = slice_type; h.slice_type_nos = slice_type & 3; s.pict_type = h.slice_type; // to make a few old functions happy, it's wrong though pps_id = s.gb.get_ue_golomb("pps_id"); if (pps_id >= MAX_PPS_COUNT) { //av_log(h.s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); // DebugTool.printDebugString(" --- decode_slide_header error case 1\n"); return -61; } if (null == h0.pps_buffers[pps_id]) { //av_log(h.s.avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id); // DebugTool.printDebugString(" --- decode_slide_header error case 2\n"); return -62; } h0.pps_buffers[pps_id].copyTo(h.pps); if (null == h0.sps_buffers[(int)h.pps.sps_id]) { //av_log(h.s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h.pps.sps_id); // DebugTool.printDebugString(" --- decode_slide_header error case 3\n"); return -63; } h0.sps_buffers[(int)h.pps.sps_id].copyTo(h.sps); s.profile = h.sps.profile_idc; s.level = h.sps.level_idc; s.refs = h.sps.ref_frame_count; if (h == h0 && h.dequant_coeff_pps != pps_id) { h.dequant_coeff_pps = pps_id; h.init_dequant_tables(); } s.mb_width = h.sps.mb_width; s.mb_height = h.sps.mb_height * (2 - h.sps.frame_mbs_only_flag); h.b_stride = s.mb_width * 4; s.width = (int)(16 * s.mb_width - 2 * Math.Min(h.sps.crop_right, 7)); if (h.sps.frame_mbs_only_flag != 0) s.height = (int)(16 * s.mb_height - 2 * Math.Min(h.sps.crop_bottom, 7)); else s.height = (int)(16 * s.mb_height - 4 * Math.Min(h.sps.crop_bottom, 7)); if (s.context_initialized != 0 && ( /*s.width != s.avctx.width || s.height != s.avctx.height ||*/ av_cmp_q(h.sps.sar, s.sample_aspect_ratio) != 0)) { if (h != h0) { // DebugTool.printDebugString(" --- decode_slide_header error case 4\n"); return -64; // width / height changed during parallelized decoding } h.free_tables(); s.flush_dpb(); s.MPV_common_end(); } if (0 == s.context_initialized) { if (h != h0) { // DebugTool.printDebugString(" --- decode_slide_header error case 5\n"); return -65; // we cant (re-)initialize context during parallel decoding } s.avcodec_set_dimensions(s.width, s.height); s.sample_aspect_ratio = h.sps.sar; //av_assert0(s.avctx.sample_aspect_ratio.den); if (0 != h.sps.video_signal_type_present_flag) { s.color_range = ((h.sps.full_range != 0) ? MpegEncContext.AVCOL_RANGE_JPEG : MpegEncContext.AVCOL_RANGE_MPEG); if (h.sps.colour_description_present_flag != 0) { s.color_primaries = h.sps.color_primaries; s.color_trc = h.sps.color_trc; s.colorspace = h.sps.colorspace; } } if (h.sps.timing_info_present_flag != 0) { long den = h.sps.time_scale; if (h.x264_build < 44) den *= 2; int[] param = new int[] { s.time_base.num, s.time_base.den, }; av_reduce(param, h.sps.num_units_in_tick, den, 1 << 30); s.time_base.num = param[0]; s.time_base.den = param[1]; } s.pix_fmt = MpegEncContext.get_format( s.codec.pix_fmts != null ? s.codec.pix_fmts : s.color_range == MpegEncContext.AVCOL_RANGE_JPEG ? hwaccel_pixfmt_list_h264_jpeg_420 : MpegEncContext.ff_hwaccel_pixfmt_list_420); s.hwaccel = 0; // No H/W Accel!! // ff_find_hwaccel(s.avctx.codec.id, s.avctx.pix_fmt); if (s.MPV_common_init() < 0) { // DebugTool.printDebugString(" --- decode_slide_header error case 6\n"); return -66; } s.first_field = 0; h.prev_interlaced_frame = 1; h.init_scan_tables(); h.ff_h264_alloc_tables(); /*// We use single thread decoder for(i = 1; i < 1; i++) { H264Context c; c = h.thread_context[i] = new H264Context(); memcpy(c, h.s.thread_context[i], sizeof(MpegEncContext)); memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext)); c.h264dsp = h.h264dsp; c.sps = h.sps; c.pps = h.pps; c.init_scan_tables(); clone_tables(c, h, i); } */ for (i = 0; i < s.thread_count; i++) if (h.thread_context[i].context_init() < 0) { // DebugTool.printDebugString(" --- decode_slide_header error case 7\n"); return -67; } } h.frame_num = (int)s.gb.get_bits(h.sps.log2_max_frame_num, "frame_num"); h.mb_mbaff = 0; h.mb_aff_frame = 0; last_pic_structure = s0.picture_structure; if (h.sps.frame_mbs_only_flag != 0) { s.picture_structure = Constants.PICT_FRAME; } else { if (s.gb.get_bits1("field_pic_flag") != 0) { //field_pic_flag s.picture_structure = (int)(Constants.PICT_TOP_FIELD + s.gb.get_bits1("bottom_field_flag")); //bottom_field_flag } else { s.picture_structure = Constants.PICT_FRAME; h.mb_aff_frame = h.sps.mb_aff; } } h.mb_field_decoding_flag = ((s.picture_structure) != Constants.PICT_FRAME ? 1 : 0); if (h0.current_slice == 0) { while (h.frame_num != h.prev_frame_num && h.frame_num != ((h.prev_frame_num + 1) % (1 << h.sps.log2_max_frame_num))) { AVFrame prev = ((h.short_ref_count != 0) ? h.short_ref[0] : null); //av_log(h.s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h.frame_num, h.prev_frame_num); if (h.ff_h264_frame_start() < 0) { // DebugTool.printDebugString(" --- decode_slide_header error case 8\n"); return -68; } h.prev_frame_num++; h.prev_frame_num %= 1 << h.sps.log2_max_frame_num; s.current_picture_ptr.frame_num = h.prev_frame_num; h.ff_generate_sliding_window_mmcos(); h.ff_h264_execute_ref_pic_marking(h.mmco, h.mmco_index); /* Error concealment: if a ref is missing, copy the previous ref in its place. * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions * about there being no actual duplicates. * FIXME: this doesn't copy padding for out-of-frame motion vectors. Given we're * concealing a lost frame, this probably isn't noticable by comparison, but it should * be fixed. */ if (h.short_ref_count != 0) { if (prev != null) { ImageUtils.av_image_copy(h.short_ref[0].data_base, h.short_ref[0].data_offset, h.short_ref[0].linesize, /*( uint8_t**)*/prev.data_base, prev.data_offset, prev.linesize, s.pix_fmt, s.mb_width * 16, s.mb_height * 16); h.short_ref[0].poc = prev.poc + 2; } h.short_ref[0].frame_num = h.prev_frame_num; } } /* See if we have a decoded first field looking for a pair... */ if (s0.first_field != 0) { ////assert(s0.current_picture_ptr); ////assert(s0.current_picture_ptr->data[0]); ////assert(s0.current_picture_ptr->reference != DELAYED_PIC_REF); /* figure out if we have a complementary field pair */ if (!(s.picture_structure != Constants.PICT_FRAME) || s.picture_structure == last_pic_structure) { /* * Previous field is unmatched. Don't display it, but let it * remain for reference if marked as such. */ s0.current_picture_ptr = null; s0.first_field = ((s.picture_structure != Constants.PICT_FRAME) ? 1 : 0); } else { if (h.nal_ref_idc != 0 && s0.current_picture_ptr.reference != 0 && s0.current_picture_ptr.frame_num != h.frame_num) { /* * This and previous field were reference, but had * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference * purposes. */ s0.first_field = 1; s0.current_picture_ptr = null; } else { /* Second field in complementary pair */ s0.first_field = 0; } } } else { /* Frame or first field in a potentially complementary pair */ ////assert(!s0.current_picture_ptr); s0.first_field = ((s.picture_structure != Constants.PICT_FRAME) ? 1 : 0); } if ((0 == ((s.picture_structure != Constants.PICT_FRAME) ? 1 : 0) || 0 != s0.first_field) && h.ff_h264_frame_start() < 0) { s0.first_field = 0; // DebugTool.printDebugString(" --- decode_slide_header error case 9\n"); return -69; } } if (h != h0) clone_slice(h, h0); s.current_picture_ptr.frame_num = h.frame_num; //FIXME frame_num cleanup ////assert(s.mb_num == s.mb_width * s.mb_height); if (first_mb_in_slice << ((h.mb_aff_frame != 0 || (s.picture_structure != Constants.PICT_FRAME)) ? 1 : 0) >= s.mb_num || first_mb_in_slice >= s.mb_num) { //av_log(h.s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n"); // DebugTool.printDebugString(" --- decode_slide_header error case 10\n"); return -70; } s.resync_mb_x = s.mb_x = first_mb_in_slice % s.mb_width; s.resync_mb_y = s.mb_y = (first_mb_in_slice / s.mb_width) << ((h.mb_aff_frame != 0 || (s.picture_structure != Constants.PICT_FRAME)) ? 1 : 0); if (s.picture_structure == Constants.PICT_BOTTOM_FIELD) s.resync_mb_y = s.mb_y = s.mb_y + 1; //assert(s.mb_y < s.mb_height); if (s.picture_structure == Constants.PICT_FRAME) { h.curr_pic_num = h.frame_num; h.max_pic_num = 1 << h.sps.log2_max_frame_num; } else { h.curr_pic_num = 2 * h.frame_num + 1; h.max_pic_num = 1 << (h.sps.log2_max_frame_num + 1); } if (h.nal_unit_type == NAL_IDR_SLICE) { s.gb.get_ue_golomb("idr_pic_id"); /* idr_pic_id */ } if (h.sps.poc_type == 0) { h.poc_lsb = (int)s.gb.get_bits(h.sps.log2_max_poc_lsb, "poc_lsb"); if (h.pps.pic_order_present == 1 && s.picture_structure == Constants.PICT_FRAME) { h.delta_poc_bottom = s.gb.get_se_golomb("delta_poc_bottom"); } } if (h.sps.poc_type == 1 && 0 == h.sps.delta_pic_order_always_zero_flag) { h.delta_poc[0] = s.gb.get_se_golomb("delta_poc[0]"); if (h.pps.pic_order_present == 1 && s.picture_structure == Constants.PICT_FRAME) h.delta_poc[1] = s.gb.get_se_golomb("delta_poc[1]"); } h.init_poc(); if (h.pps.redundant_pic_cnt_present != 0) { h.redundant_pic_count = s.gb.get_ue_golomb("redundant_pic_count"); } //set defaults, might be overridden a few lines later h.ref_count[0] = h.pps.ref_count[0]; h.ref_count[1] = h.pps.ref_count[1]; if (h.slice_type_nos != FF_I_TYPE) { if (h.slice_type_nos == FF_B_TYPE) { h.direct_spatial_mv_pred = (int)s.gb.get_bits1("direct_spatial_mv_pred"); } num_ref_idx_active_override_flag = (int)s.gb.get_bits1("num_ref_idx_active_override_flag"); if (num_ref_idx_active_override_flag != 0) { h.ref_count[0] = s.gb.get_ue_golomb("ref_count[0]") + 1; if (h.slice_type_nos == FF_B_TYPE) h.ref_count[1] = s.gb.get_ue_golomb("ref_count[1]") + 1; if (h.ref_count[0] - 1 > 32 - 1 || h.ref_count[1] - 1 > 32 - 1) { //av_log(h.s.avctx, AV_LOG_ERROR, "reference overflow\n"); h.ref_count[0] = h.ref_count[1] = 1; // DebugTool.printDebugString(" --- decode_slide_header error case 11\n"); return -71; } } if (h.slice_type_nos == FF_B_TYPE) h.list_count = 2; else h.list_count = 1; } else h.list_count = 0; if (0 == default_ref_list_done) { h.ff_h264_fill_default_ref_list(); } if (h.slice_type_nos != FF_I_TYPE && h.ff_h264_decode_ref_pic_list_reordering() < 0) { // DebugTool.printDebugString(" --- decode_slide_header error case 12\n"); return -72; } if (h.slice_type_nos != FF_I_TYPE) { s.last_picture_ptr = h.ref_list[0][0]; MpegEncContext.ff_copy_picture(s.last_picture, s.last_picture_ptr); } if (h.slice_type_nos == FF_B_TYPE) { s.next_picture_ptr = h.ref_list[1][0]; MpegEncContext.ff_copy_picture(s.next_picture, s.next_picture_ptr); } if ((h.pps.weighted_pred != 0 && h.slice_type_nos == FF_P_TYPE) || (h.pps.weighted_bipred_idc == 1 && h.slice_type_nos == FF_B_TYPE)) h.pred_weight_table(); else if (h.pps.weighted_bipred_idc == 2 && h.slice_type_nos == FF_B_TYPE) { h.implicit_weight_table(-1); } else { h.use_weight = 0; for (i = 0; i < 2; i++) { h.luma_weight_flag[i] = 0; h.chroma_weight_flag[i] = 0; } } if (h.nal_ref_idc != 0) h0.ff_h264_decode_ref_pic_marking(s.gb); if (h.mb_aff_frame != 0) { h.ff_h264_fill_mbaff_ref_list(); if (h.pps.weighted_bipred_idc == 2 && h.slice_type_nos == FF_B_TYPE) { h.implicit_weight_table(0); h.implicit_weight_table(1); } } if (h.slice_type_nos == FF_B_TYPE && 0 == h.direct_spatial_mv_pred) h.ff_h264_direct_dist_scale_factor(); h.ff_h264_direct_ref_list_init(); if (h.slice_type_nos != FF_I_TYPE && h.pps.cabac != 0) { tmp = s.gb.get_ue_golomb_31("cabac_init_idc"); if (tmp > 2) { //av_log(s.avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n"); // DebugTool.printDebugString(" --- decode_slide_header error case 13\n"); return -73; } h.cabac_init_idc = tmp; } h.last_qscale_diff = 0; tmp = h.pps.init_qp + s.gb.get_se_golomb("init_qp"); if (tmp > 51) { //av_log(s.avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp); // DebugTool.printDebugString(" --- decode_slide_header error case 14\n"); return -74; } s.qscale = tmp; h.chroma_qp[0] = h.pps.chroma_qp_table[0][s.qscale]; h.chroma_qp[1] = h.pps.chroma_qp_table[1][s.qscale]; //FIXME qscale / qp ... stuff if (h.slice_type == FF_SP_TYPE) { s.gb.get_bits1("sp_for_switch_flag"); /* sp_for_switch_flag */ } if (h.slice_type == FF_SP_TYPE || h.slice_type == FF_SI_TYPE) { s.gb.get_se_golomb("slice_qs_delta"); /* slice_qs_delta */ } h.deblocking_filter = 1; h.slice_alpha_c0_offset = 52; h.slice_beta_offset = 52; if (0 != h.pps.deblocking_filter_parameters_present) { tmp = s.gb.get_ue_golomb_31("deblocking_filter_idc"); if (tmp > 2) { // DebugTool.printDebugString(" --- decode_slide_header error case 15\n"); //av_log(s.avctx, AV_LOG_ERROR, "deblocking_filter_idc %u out of range\n", tmp); return -75; } h.deblocking_filter = tmp; if (h.deblocking_filter < 2) h.deblocking_filter ^= 1; // 1<->0 if (0 != h.deblocking_filter) { h.slice_alpha_c0_offset += s.gb.get_se_golomb("slice_alpha_c0_offset") << 1; h.slice_beta_offset += s.gb.get_se_golomb("slice_beta_offset") << 1; if (h.slice_alpha_c0_offset > 104 || h.slice_beta_offset > 104) { // DebugTool.printDebugString(" --- decode_slide_header error case 16\n"); //av_log(s.avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h.slice_alpha_c0_offset, h.slice_beta_offset); return -76; } } } if (s.skip_loop_filter >= MpegEncContext.AVDISCARD_ALL || (s.skip_loop_filter >= MpegEncContext.AVDISCARD_NONKEY && h.slice_type_nos != FF_I_TYPE) || (s.skip_loop_filter >= MpegEncContext.AVDISCARD_BIDIR && h.slice_type_nos == FF_B_TYPE) || (s.skip_loop_filter >= MpegEncContext.AVDISCARD_NONREF && h.nal_ref_idc == 0)) h.deblocking_filter = 0; if (h.deblocking_filter == 1 && h0.max_contexts > 1) { if ((s.flags2 & MpegEncContext.CODEC_FLAG2_FAST) != 0) { /* Cheat slightly for speed: Do not bother to deblock across slices. */ h.deblocking_filter = 2; } else { h0.max_contexts = 1; if (0 == h0.single_decode_warning) { //av_log(s.avctx, AV_LOG_INFO, "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n"); h0.single_decode_warning = 1; } if (h != h0) { // DebugTool.printDebugString(" --- decode_slide_header error case 17\n"); return 1; // deblocking switched inside frame } } } h.qp_thresh = 15 + 52 - Math.Min(h.slice_alpha_c0_offset, h.slice_beta_offset) - Math.Max(Math.Max(0, h.pps.chroma_qp_index_offset[0]), h.pps.chroma_qp_index_offset[1]); /* #if 0 //FMO if( h.pps.num_slice_groups > 1 && h.pps.mb_slice_group_map_type >= 3 && h.pps.mb_slice_group_map_type <= 5) slice_group_change_cycle= s.gb.get_bits( ?); #endif */ h0.last_slice_type = slice_type; h.slice_num = ++h0.current_slice; if (h.slice_num >= MAX_SLICES) { //av_log(s.avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n"); } for (j = 0; j < 2; j++) { int[] id_list = new int[16]; int[] ref2frm = h.ref2frm[h.slice_num & (MAX_SLICES - 1)][j]; for (i = 0; i < 16; i++) { id_list[i] = 60; if (h.ref_list[j][i].data_base[0] != null) { int k; //uint8_t *base= h.ref_list[j][i].base[0]; byte[] @base = h.ref_list[j][i].@base[0]; for (k = 0; k < h.short_ref_count; k++) if (h.short_ref[k].@base[0] == @base) { id_list[i] = k; break; } for (k = 0; k < h.long_ref_count; k++) if (h.long_ref[k] != null && h.long_ref[k].@base[0] == @base) { id_list[i] = h.short_ref_count + k; break; } } } ref2frm[0] = ref2frm[1] = -1; for (i = 0; i < 16; i++) ref2frm[i + 2] = 4 * id_list[i] + (h.ref_list[j][i].reference & 3); ref2frm[18 + 0] = ref2frm[18 + 1] = -1; for (i = 16; i < 48; i++) ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] + (h.ref_list[j][i].reference & 3); } h.emu_edge_width = ((s.flags & MpegEncContext.CODEC_FLAG_EMU_EDGE) != 0 ? 0 : 16); h.emu_edge_height = (0 != h.mb_aff_frame || (s.picture_structure != Constants.PICT_FRAME)) ? 0 : h.emu_edge_width; /* No debug if((s.debug&FF_DEBUG_PICT_INFO)!=0){ av_log(h.s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n", h.slice_num, (s.picture_structure==PICT_FRAME ? "F" : s.picture_structure==PICT_TOP_FIELD ? "T" : "B"), first_mb_in_slice, av_get_pict_type_char(h.slice_type), h.slice_type_fixed ? " fix" : "", h.nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", pps_id, h.frame_num, s.current_picture_ptr->field_poc[0], s.current_picture_ptr->field_poc[1], h.ref_count[0], h.ref_count[1], s.qscale, h.deblocking_filter, h.slice_alpha_c0_offset/2-26, h.slice_beta_offset/2-26, h.use_weight, h.use_weight==1 && h.use_weight_chroma ? "c" : "", h.slice_type == FF_B_TYPE ? (h.direct_spatial_mv_pred ? "SPAT" : "TEMP") : "" ); } */ // DebugTool.printDebugString(" --- decode_slide_header OK\n"); return 0; }