/*! ************************************************************************ * \brief * This function terminates a slice (but doesn't write it out), * the old terminate_slice (0) * \return * 0 if OK, \n * 1 in case of error * ************************************************************************ */ int terminate_slice() { int bytes_written; Bitstream *currStream; Slice *currSlice = img->currentSlice; EncodingEnvironmentPtr eep; int i; int byte_pos_before_startcode_emu_prevention; if (input->symbol_mode == CABAC) write_terminating_bit (1); // only once, not for all partitions for (i=0; i<currSlice->max_part_nr; i++) { currStream = (currSlice->partArr[i]).bitstream; if (input->symbol_mode == UVLC) { SODBtoRBSP(currStream); byte_pos_before_startcode_emu_prevention = currStream->byte_pos; currStream->byte_pos = RBSPtoEBSP(currStream->streamBuffer, 0 , currStream->byte_pos, 0); *(stat->em_prev_bits) += (currStream->byte_pos - byte_pos_before_startcode_emu_prevention) * 8; } else // CABAC { eep = &((currSlice->partArr[i]).ee_cabac); // terminate the arithmetic code arienco_done_encoding(eep); currStream->bits_to_go = eep->Ebits_to_go; currStream->byte_buf = 0; bytes_written = currStream->byte_pos; byte_pos_before_startcode_emu_prevention= currStream->byte_pos; currStream->byte_pos = RBSPtoEBSP(currStream->streamBuffer, 0, currStream->byte_pos, eep->E); *(stat->em_prev_bits) += (currStream->byte_pos - byte_pos_before_startcode_emu_prevention) * 8; } // CABAC } // partition loop if( input->symbol_mode == CABAC ) { store_contexts(); } return 0; }
//++ 参见标准7.3.2.2、7.4.2.2节 int GeneratePic_parameter_set_rbsp (pic_parameter_set_rbsp_t *pps, char *rbsp) { DataPartition *partition; int len = 0, LenInBytes; unsigned i; unsigned NumberBitsPerSliceGroupId; assert (rbsp != NULL); // In order to use the entropy coding functions from golomb.c we need // to allocate a partition structure. It will be freed later in this // function if ((partition=calloc(1,sizeof(DataPartition)))==NULL) no_mem_exit("PicParameterSet:partition"); if ((partition->bitstream=calloc(1, sizeof(Bitstream)))==NULL) no_mem_exit("PicParameterSet:bitstream"); // .. and use the rbsp provided (or allocated above) for the data partition->bitstream->streamBuffer = rbsp; partition->bitstream->bits_to_go = 8; //sw paff pps->pic_order_present_flag = img->pic_order_present_flag; len+=ue_v ("PPS: pic_parameter_set_id", pps->pic_parameter_set_id, partition); len+=ue_v ("PPS: seq_parameter_set_id", pps->seq_parameter_set_id, partition); len+=u_1 ("PPS: entropy_coding_mode_flag", pps->entropy_coding_mode_flag, partition); len+=u_1 ("PPS: pic_order_present_flag", pps->pic_order_present_flag, partition); len+=ue_v ("PPS: num_slice_groups_minus1", pps->num_slice_groups_minus1, partition); // FMO stuff if(pps->num_slice_groups_minus1 > 0 ) { len+=ue_v ("PPS: slice_group_map_type", pps->slice_group_map_type, partition); if (pps->slice_group_map_type == 0) for (i=0; i<=pps->num_slice_groups_minus1; i++) len+=ue_v ("PPS: run_length_minus1[i]", pps->run_length_minus1[i], partition); else if (pps->slice_group_map_type==2) for (i=0; i<pps->num_slice_groups_minus1; i++) { len+=ue_v ("PPS: top_left[i]", pps->top_left[i], partition); len+=ue_v ("PPS: bottom_right[i]", pps->bottom_right[i], partition); } else if (pps->slice_group_map_type == 3 || pps->slice_group_map_type == 4 || pps->slice_group_map_type == 5) { len+=u_1 ("PPS: slice_group_change_direction_flag", pps->slice_group_change_direction_flag, partition); len+=ue_v ("PPS: slice_group_change_rate_minus1", pps->slice_group_change_rate_minus1, partition); } else if (pps->slice_group_map_type == 6) { if (pps->num_slice_groups_minus1>=4) NumberBitsPerSliceGroupId=3; else if (pps->num_slice_groups_minus1>=2) NumberBitsPerSliceGroupId=2; else if (pps->num_slice_groups_minus1>=1) NumberBitsPerSliceGroupId=1; else NumberBitsPerSliceGroupId=0; len+=ue_v ("PPS: pic_size_in_map_units_minus1", pps->pic_size_in_map_units_minus1, partition); for(i=0; i<=pps->pic_size_in_map_units_minus1; i++) len+= u_v (NumberBitsPerSliceGroupId, "PPS: >slice_group_id[i]", pps->slice_group_id[i], partition); } } // End of FMO stuff len+=ue_v ("PPS: num_ref_idx_l0_active_minus1", pps->num_ref_idx_l0_active_minus1, partition); len+=ue_v ("PPS: num_ref_idx_l1_active_minus1", pps->num_ref_idx_l1_active_minus1, partition); len+=u_1 ("PPS: weighted_pred_flag", pps->weighted_pred_flag, partition); len+=u_v (2, "PPS: weighted_bipred_idc", pps->weighted_bipred_idc, partition); len+=se_v ("PPS: pic_init_qp_minus26", pps->pic_init_qp_minus26, partition); len+=se_v ("PPS: pic_init_qs_minus26", pps->pic_init_qs_minus26, partition); len+=se_v ("PPS: chroma_qp_index_offset", pps->chroma_qp_index_offset, partition); len+=u_1 ("PPS: deblocking_filter_control_present_flag", pps->deblocking_filter_control_present_flag, partition); len+=u_1 ("PPS: constrained_intra_pred_flag", pps->constrained_intra_pred_flag, partition); len+=u_1 ("PPS: redundant_pic_cnt_present_flag", pps->redundant_pic_cnt_present_flag, partition); SODBtoRBSP(partition->bitstream); // copies the last couple of bits into the byte buffer LenInBytes=partition->bitstream->byte_pos; // Get rid of the helper structures free (partition->bitstream); free (partition); return LenInBytes; }
//++ 参见标准7.3.2.1、7.4.2.1节 int GenerateSeq_parameter_set_rbsp (seq_parameter_set_rbsp_t *sps, char *rbsp) { DataPartition *partition; int len = 0, LenInBytes; unsigned i; assert (rbsp != NULL); // In order to use the entropy coding functions from golomb.c we need // to allocate a partition structure. It will be freed later in this // function if ((partition=calloc(1,sizeof(DataPartition)))==NULL) no_mem_exit("SeqParameterSet:partition"); if ((partition->bitstream=calloc(1, sizeof(Bitstream)))==NULL) no_mem_exit("SeqParameterSet:bitstream"); // .. and use the rbsp provided (or allocated above) for the data partition->bitstream->streamBuffer = rbsp; partition->bitstream->bits_to_go = 8; len+=u_v (8, "SPS: profile_idc", sps->profile_idc, partition); len+=u_1 ("SPS: constrained_set0_flag", sps->constrained_set0_flag, partition); len+=u_1 ("SPS: constrained_set1_flag", sps->constrained_set1_flag, partition); len+=u_1 ("SPS: constrained_set2_flag", sps->constrained_set2_flag, partition); len+=u_v (5, "SPS: reserved_zero", 0, partition); len+=u_v (8, "SPS: level_idc", sps->level_idc, partition); len+=ue_v ("SPS: seq_parameter_set_id", sps->seq_parameter_set_id, partition); len+=ue_v ("SPS: log2_max_frame_num_minus4", sps->log2_max_frame_num_minus4, partition); len+=ue_v ("SPS: pic_order_cnt_type", sps->pic_order_cnt_type, partition); // POC200301 if (sps->pic_order_cnt_type == 0) len+=ue_v ("SPS: log2_max_pic_order_cnt_lsb_minus4", sps->log2_max_pic_order_cnt_lsb_minus4, partition); else if (sps->pic_order_cnt_type == 1) { len+=u_1 ("SPS: delta_pic_order_always_zero_flag", sps->delta_pic_order_always_zero_flag, partition); len+=se_v ("SPS: offset_for_non_ref_pic", sps->offset_for_non_ref_pic, partition); len+=se_v ("SPS: offset_for_top_to_bottom_field", sps->offset_for_top_to_bottom_field, partition); len+=ue_v ("SPS: num_ref_frames_in_pic_order_cnt_cycle", sps->num_ref_frames_in_pic_order_cnt_cycle, partition); for (i=0; i<sps->num_ref_frames_in_pic_order_cnt_cycle; i++) len+=se_v ("SPS: offset_for_ref_frame", sps->offset_for_ref_frame[i], partition); } len+=ue_v ("SPS: num_ref_frames", sps->num_ref_frames, partition); len+=u_1 ("SPS: gaps_in_frame_num_value_allowed_flag", sps->gaps_in_frame_num_value_allowed_flag, partition); len+=ue_v ("SPS: pic_width_in_mbs_minus1", sps->pic_width_in_mbs_minus1, partition); len+=ue_v ("SPS: pic_height_in_map_units_minus1", sps->pic_height_in_map_units_minus1, partition); len+=u_1 ("SPS: frame_mbs_only_flag", sps->frame_mbs_only_flag, partition); if (!sps->frame_mbs_only_flag) { len+=u_1 ("SPS: mb_adaptive_frame_field_flag", sps->mb_adaptive_frame_field_flag, partition); } len+=u_1 ("SPS: direct_8x8_inference_flag", sps->direct_8x8_inference_flag, partition); len+=u_1 ("SPS: frame_cropping_flag", sps->frame_cropping_flag, partition); if (sps->frame_cropping_flag) { len+=ue_v ("SPS: frame_cropping_rect_left_offset", sps->frame_cropping_rect_left_offset, partition); len+=ue_v ("SPS: frame_cropping_rect_right_offset", sps->frame_cropping_rect_right_offset, partition); len+=ue_v ("SPS: frame_cropping_rect_top_offset", sps->frame_cropping_rect_top_offset, partition); len+=ue_v ("SPS: frame_cropping_rect_bottom_offset", sps->frame_cropping_rect_bottom_offset, partition); } len+=u_1 ("SPS: vui_parameters_present_flag", sps->vui_parameters_present_flag, partition); if (sps->vui_parameters_present_flag) len+=GenerateVUISequenceParameters(); // currently a dummy, asserting SODBtoRBSP(partition->bitstream); // copies the last couple of bits into the byte buffer LenInBytes=partition->bitstream->byte_pos; free (partition->bitstream); free (partition); return LenInBytes; }