public void write(MemoryStream outb) { BitWriter writer = new BitWriter(outb); CAVLCWriter.writeUE(writer, pic_parameter_set_id, "PPS: pic_parameter_set_id"); CAVLCWriter.writeUE(writer, seq_parameter_set_id, "PPS: seq_parameter_set_id"); CAVLCWriter.writeBool(writer, entropy_coding_mode_flag, "PPS: entropy_coding_mode_flag"); CAVLCWriter.writeBool(writer, pic_order_present_flag, "PPS: pic_order_present_flag"); CAVLCWriter.writeUE(writer, num_slice_groups_minus1, "PPS: num_slice_groups_minus1"); if (num_slice_groups_minus1 > 0) { CAVLCWriter.writeUE(writer, slice_group_map_type, "PPS: slice_group_map_type"); int[] top_left = new int[1]; int[] bottom_right = new int[1]; int[] run_length_minus1 = new int[1]; if (slice_group_map_type == 0) { for (int iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++) { CAVLCWriter.writeUE(writer, run_length_minus1[iGroup], "PPS: "); } } else if (slice_group_map_type == 2) { for (int iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++) { CAVLCWriter.writeUE(writer, top_left[iGroup], "PPS: "); CAVLCWriter.writeUE(writer, bottom_right[iGroup], "PPS: "); } } else if (slice_group_map_type == 3 || slice_group_map_type == 4 || slice_group_map_type == 5) { CAVLCWriter.writeBool(writer, slice_group_change_direction_flag, "PPS: slice_group_change_direction_flag"); CAVLCWriter.writeUE(writer, slice_group_change_rate_minus1, "PPS: slice_group_change_rate_minus1"); } else if (slice_group_map_type == 6) { int NumberBitsPerSliceGroupId; if (num_slice_groups_minus1 + 1 > 4) { NumberBitsPerSliceGroupId = 3; } else if (num_slice_groups_minus1 + 1 > 2) { NumberBitsPerSliceGroupId = 2; } else { NumberBitsPerSliceGroupId = 1; } CAVLCWriter.writeUE(writer, slice_group_id.Length, "PPS: "); for (int i = 0; i <= slice_group_id.Length; i++) { CAVLCWriter.writeU(writer, slice_group_id[i], NumberBitsPerSliceGroupId); } } } CAVLCWriter.writeUE(writer, num_ref_idx_active_minus1[0], "PPS: num_ref_idx_l0_active_minus1"); CAVLCWriter.writeUE(writer, num_ref_idx_active_minus1[1], "PPS: num_ref_idx_l1_active_minus1"); CAVLCWriter.writeBool(writer, weighted_pred_flag, "PPS: weighted_pred_flag"); CAVLCWriter.writeNBit(writer, weighted_bipred_idc, 2, "PPS: weighted_bipred_idc"); CAVLCWriter.writeSE(writer, pic_init_qp_minus26, "PPS: pic_init_qp_minus26"); CAVLCWriter.writeSE(writer, pic_init_qs_minus26, "PPS: pic_init_qs_minus26"); CAVLCWriter.writeSE(writer, chroma_qp_index_offset, "PPS: chroma_qp_index_offset"); CAVLCWriter.writeBool(writer, deblocking_filter_control_present_flag, "PPS: deblocking_filter_control_present_flag"); CAVLCWriter.writeBool(writer, constrained_intra_pred_flag, "PPS: constrained_intra_pred_flag"); CAVLCWriter.writeBool(writer, redundant_pic_cnt_present_flag, "PPS: redundant_pic_cnt_present_flag"); if (extended != null) { CAVLCWriter.writeBool(writer, extended.transform_8x8_mode_flag, "PPS: transform_8x8_mode_flag"); CAVLCWriter.writeBool(writer, extended.scalindMatrix != null, "PPS: scalindMatrix"); if (extended.scalindMatrix != null) { for (int i = 0; i < 6 + 2 * (extended.transform_8x8_mode_flag ? 1 : 0); i++) { if (i < 6) { CAVLCWriter.writeBool(writer, extended.scalindMatrix.ScalingList4x4[i] != null, "PPS: "); if (extended.scalindMatrix.ScalingList4x4[i] != null) { extended.scalindMatrix.ScalingList4x4[i].write(writer); } } else { CAVLCWriter.writeBool(writer, extended.scalindMatrix.ScalingList8x8[i - 6] != null, "PPS: "); if (extended.scalindMatrix.ScalingList8x8[i - 6] != null) { extended.scalindMatrix.ScalingList8x8[i - 6].write(writer); } } } } CAVLCWriter.writeSE(writer, extended.second_chroma_qp_index_offset, "PPS: "); } CAVLCWriter.writeTrailingBits(writer); }
public void write(SliceHeader sliceHeader, bool idrSlice, int nalRefIdc, BitWriter writer) { SeqParameterSet sps = sliceHeader.sps; PictureParameterSet pps = sliceHeader.pps; CAVLCWriter.writeUE(writer, sliceHeader.first_mb_in_slice, "SH: first_mb_in_slice"); CAVLCWriter.writeUE(writer, (int)sliceHeader.slice_type + (sliceHeader.slice_type_restr ? 5 : 0), "SH: slice_type"); CAVLCWriter.writeUE(writer, sliceHeader.pic_parameter_set_id, "SH: pic_parameter_set_id"); CAVLCWriter.writeU(writer, sliceHeader.frame_num, sps.log2_max_frame_num_minus4 + 4, "SH: frame_num"); if (!sps.frame_mbs_only_flag) { CAVLCWriter.writeBool(writer, sliceHeader.field_pic_flag, "SH: field_pic_flag"); if (sliceHeader.field_pic_flag) { CAVLCWriter.writeBool(writer, sliceHeader.bottom_field_flag, "SH: bottom_field_flag"); } } if (idrSlice) { CAVLCWriter.writeUE(writer, sliceHeader.idr_pic_id, "SH: idr_pic_id"); } if (sps.pic_order_cnt_type == 0) { CAVLCWriter.writeU(writer, sliceHeader.pic_order_cnt_lsb, sps.log2_max_pic_order_cnt_lsb_minus4 + 4); if (pps.pic_order_present_flag && !sps.field_pic_flag) { CAVLCWriter.writeSE(writer, sliceHeader.delta_pic_order_cnt_bottom, "SH: delta_pic_order_cnt_bottom"); } } if (sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag) { CAVLCWriter.writeSE(writer, sliceHeader.delta_pic_order_cnt[0], "SH: delta_pic_order_cnt"); if (pps.pic_order_present_flag && !sps.field_pic_flag) { CAVLCWriter.writeSE(writer, sliceHeader.delta_pic_order_cnt[1], "SH: delta_pic_order_cnt"); } } if (pps.redundant_pic_cnt_present_flag) { CAVLCWriter.writeUE(writer, sliceHeader.redundant_pic_cnt, "SH: redundant_pic_cnt"); } if (sliceHeader.slice_type == SliceType.B) { CAVLCWriter.writeBool(writer, sliceHeader.direct_spatial_mv_pred_flag, "SH: direct_spatial_mv_pred_flag"); } if (sliceHeader.slice_type == SliceType.P || sliceHeader.slice_type == SliceType.SP || sliceHeader.slice_type == SliceType.B) { CAVLCWriter.writeBool(writer, sliceHeader.num_ref_idx_active_override_flag, "SH: num_ref_idx_active_override_flag"); if (sliceHeader.num_ref_idx_active_override_flag) { CAVLCWriter.writeUE(writer, sliceHeader.num_ref_idx_active_minus1[0], "SH: num_ref_idx_l0_active_minus1"); if (sliceHeader.slice_type == SliceType.B) { CAVLCWriter.writeUE(writer, sliceHeader.num_ref_idx_active_minus1[1], "SH: num_ref_idx_l1_active_minus1"); } } } writeRefPicListReordering(sliceHeader, writer); if ((pps.weighted_pred_flag && (sliceHeader.slice_type == SliceType.P || sliceHeader.slice_type == SliceType.SP)) || (pps.weighted_bipred_idc == 1 && sliceHeader.slice_type == SliceType.B)) { writePredWeightTable(sliceHeader, writer); } if (nalRefIdc != 0) { writeDecRefPicMarking(sliceHeader, idrSlice, writer); } if (pps.entropy_coding_mode_flag && sliceHeader.slice_type.isInter()) { CAVLCWriter.writeUE(writer, sliceHeader.cabac_init_idc, "SH: cabac_init_idc"); } CAVLCWriter.writeSE(writer, sliceHeader.slice_qp_delta, "SH: slice_qp_delta"); if (sliceHeader.slice_type == SliceType.SP || sliceHeader.slice_type == SliceType.SI) { if (sliceHeader.slice_type == SliceType.SP) { CAVLCWriter.writeBool(writer, sliceHeader.sp_for_switch_flag, "SH: sp_for_switch_flag"); } CAVLCWriter.writeSE(writer, sliceHeader.slice_qs_delta, "SH: slice_qs_delta"); } if (pps.deblocking_filter_control_present_flag) { CAVLCWriter.writeUE(writer, sliceHeader.disable_deblocking_filter_idc, "SH: disable_deblocking_filter_idc"); if (sliceHeader.disable_deblocking_filter_idc != 1) { CAVLCWriter.writeSE(writer, sliceHeader.slice_alpha_c0_offset_div2, "SH: slice_alpha_c0_offset_div2"); CAVLCWriter.writeSE(writer, sliceHeader.slice_beta_offset_div2, "SH: slice_beta_offset_div2"); } } if (pps.num_slice_groups_minus1 > 0 && pps.slice_group_map_type >= 3 && pps.slice_group_map_type <= 5) { int len = (sps.pic_height_in_map_units_minus1 + 1) * (sps.pic_width_in_mbs_minus1 + 1) / (pps.slice_group_change_rate_minus1 + 1); if (((sps.pic_height_in_map_units_minus1 + 1) * (sps.pic_width_in_mbs_minus1 + 1)) % (pps.slice_group_change_rate_minus1 + 1) > 0) { len += 1; } len = CeilLog2(len + 1); CAVLCWriter.writeU(writer, sliceHeader.slice_group_change_cycle, len); } }