/* ************************************************************************* * Function: decode picture display extension * Input: * Output: * Return: * Attention: ************************************************************************* */ void picture_display_extension() { int NumberOfFrameCentreOffsets; int i; if (progressive_sequence == 1) { if (repeat_first_field == 1){ if (top_field_first == 1) NumberOfFrameCentreOffsets = 3; else NumberOfFrameCentreOffsets = 2; } else { NumberOfFrameCentreOffsets = 1; } } else { if (img->picture_structure == 0){ NumberOfFrameCentreOffsets = 1; } else { if (repeat_first_field == 1) NumberOfFrameCentreOffsets = 3; else NumberOfFrameCentreOffsets = 2; } } for(i = 0; i < NumberOfFrameCentreOffsets; i++){ frame_centre_horizontal_offset[i] = u_v(16, "frame_centre_horizontal_offset"); u_v(1,"marker_bit"); frame_centre_vertical_offset[i] = u_v(16, "frame_centre_vertical_offset"); u_v(1,"marker_bit"); } }
/*! ************************************************************************ * \brief * Interpret the Sub-sequence layer characteristics SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_subsequence_layer_characteristics_info( byte* payload, int size, ImageParameters *img ) { Bitstream* buf; long num_sub_layers, accurate_statistics_flag, average_bit_rate, average_frame_rate; int i; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; num_sub_layers = 1 + ue_v("SEI: num_sub_layers_minus1", buf); #ifdef PRINT_SUBSEQUENCE_LAYER_CHAR printf("Sub-sequence layer characteristics SEI message\n"); printf("num_sub_layers_minus1 = %d\n", num_sub_layers - 1); #endif for (i=0; i<num_sub_layers; i++) { accurate_statistics_flag = u_1( "SEI: accurate_statistics_flag", buf); average_bit_rate = u_v(16,"SEI: average_bit_rate" , buf); average_frame_rate = u_v(16,"SEI: average_frame_rate" , buf); #ifdef PRINT_SUBSEQUENCE_LAYER_CHAR printf("layer %d: accurate_statistics_flag = %ld \n", i, accurate_statistics_flag); printf("layer %d: average_bit_rate = %ld \n", i, average_bit_rate); printf("layer %d: average_frame_rate = %ld \n", i, average_frame_rate); #endif } free (buf); }
/*! ************************************************************************ * \brief * Interpret the Buffering period SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_buffering_period_info( byte* payload, int size, ImageParameters *img ) { int seq_parameter_set_id, initial_cpb_removal_delay, initial_cpb_removal_delay_offset; unsigned int k; Bitstream* buf; seq_parameter_set_rbsp_t *sps; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; seq_parameter_set_id = ue_v("SEI: seq_parameter_set_id" , buf); sps = &SeqParSet[seq_parameter_set_id]; #ifdef PRINT_BUFFERING_PERIOD_INFO printf("Buffering period SEI message\n"); printf("seq_parameter_set_id = %d\n", seq_parameter_set_id); #endif if (sps->vui_seq_parameters.nal_hrd_parameters_present_flag) { for (k=0; k<sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt; k++) { initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay" , buf); initial_cpb_removal_delay_offset = u_v(sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay_offset" , buf); #ifdef PRINT_BUFFERING_PERIOD_INFO printf("nal initial_cpb_removal_delay[%d] = %d\n", k, initial_cpb_removal_delay); printf("nal initial_cpb_removal_delay_offset[%d] = %d\n", k, initial_cpb_removal_delay_offset); #endif } } if (sps->vui_seq_parameters.vcl_hrd_parameters_present_flag) { for (k=0; k<sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt; k++) { initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay" , buf); initial_cpb_removal_delay_offset = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay_offset" , buf); #ifdef PRINT_BUFFERING_PERIOD_INFO printf("vcl initial_cpb_removal_delay[%d] = %d\n", k, initial_cpb_removal_delay); printf("vcl initial_cpb_removal_delay_offset[%d] = %d\n", k, initial_cpb_removal_delay_offset); #endif } } free (buf); #ifdef PRINT_BUFFERING_PERIOD_INFO #undef PRINT_BUFFERING_PERIOD_INFO #endif }
/*! ******************************************************************************************** * \brief * Write a slice header ******************************************************************************************** */ int SliceHeader(int first_mb_in_slice) { //ue_v(img.current_mb_nr); ue_v(first_mb_in_slice); ue_v(get_picture_type ()); ue_v(0); //assert (img.frame_num < 1<<(LOG2_MAX_FRAME_NUM_MINUS4+4)); // check that it fits u_v (LOG2_MAX_FRAME_NUM_MINUS4 + 4, img.frame_num); //added by eskim as what jjs said for another decoder to decode result stream, such as JM11 and GOM player if(img.number == 0) ue_v (0); img.pic_order_cnt_lsb = (img.framepoc & 0xff); u_v (LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4+4, img.pic_order_cnt_lsb); // ist there any sense in the following assignments ??? if (img.type == P_SLICE) { // num_ref_idx_active_override_flag here always 1 u_1 (1); ue_v (img.num_ref_idx_l0_active-1); } ref_pic_list_reordering(); if (img.nal_reference_idc) dec_ref_pic_marking(); // we transmit zero in the pps, so here the real QP se_v((img.qp - 26)); if (input.LFSendParameters) { ue_v(input.LFDisableIdc); // Turn loop filter on/off on slice basis if (input.LFDisableIdc!=1) { se_v (input.LFAlphaC0Offset / 2); se_v (input.LFBetaOffset / 2); } } //MSG(SLICE_HEADER); return 0; }
void extension_data(char *buf,int startcodepos, int length) { int ext_ID; memcpy (currStream->streamBuffer, buf, length); currStream->code_len = currStream->bitstream_length = length; currStream->read_len = currStream->frame_bitoffset = (startcodepos+1)*8; ext_ID = u_v(4,"extension ID"); switch (ext_ID) { case SEQUENCE_DISPLAY_EXTENSION_ID: sequence_display_extension(); break; case COPYRIGHT_EXTENSION_ID: copyright_extension(); break; case PICTURE_DISPLAY_EXTENSION_ID: picture_display_extension(); case CAMERAPARAMETERS_EXTENSION_ID: cameraparameters_extension(); break; default: printf("reserved extension start code ID %d\n",ext_ID); break; } }
/*! ************************************************************************ * \brief * Interpret the Random access point SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_random_access_info( byte* payload, int size, ImageParameters *img ) { int recovery_frame_cnt, exact_match_flag, broken_link_flag, changing_slice_group_idc; Bitstream* buf; #ifdef ESLCPP buf = (Bitstream*)malloc(sizeof(Bitstream)); #else buf = malloc(sizeof(Bitstream)); #endif buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; recovery_frame_cnt = ue_v( "SEI: recovery_frame_cnt" , buf); exact_match_flag = u_1 ( "SEI: exact_match_flag" , buf); broken_link_flag = u_1 ( "SEI: broken_link_flag" , buf); changing_slice_group_idc = u_v ( 2, "SEI: changing_slice_group_idc", buf); #ifdef PRINT_RANDOM_ACCESS printf("Random access point SEI message\n"); printf("recovery_frame_cnt = %d\n", recovery_frame_cnt); printf("exact_match_flag = %d\n", exact_match_flag); printf("broken_link_flag = %d\n", broken_link_flag); printf("changing_slice_group_idc = %d\n", changing_slice_group_idc); #endif free (buf); #ifdef PRINT_RANDOM_ACCESS #undef PRINT_RANDOM_ACCESS #endif }
/*! ************************************************************************ * \brief * read the first part of the header (only the pic_parameter_set_id) * \return * Length of the first part of the slice header (in bits) ************************************************************************ */ int FirstPartOfSliceHeader(Slice *currSlice) { VideoParameters *p_Vid = currSlice->p_Vid; byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; DataPartition *partition = &(currSlice->partArr[dP_nr]); Bitstream *currStream = partition->bitstream; int tmp; p_Dec->UsedBits= partition->bitstream->frame_bitoffset; // was hardcoded to 31 for previous start-code. This is better. // Get first_mb_in_slice currSlice->start_mb_nr = ue_v ("SH: first_mb_in_slice", currStream); tmp = ue_v ("SH: slice_type", currStream); if (tmp > 4) tmp -= 5; p_Vid->type = currSlice->slice_type = (SliceType) tmp; currSlice->pic_parameter_set_id = ue_v ("SH: pic_parameter_set_id", currStream); if( p_Vid->separate_colour_plane_flag ) currSlice->colour_plane_id = u_v (2, "SH: colour_plane_id", currStream); else currSlice->colour_plane_id = PLANE_Y; return p_Dec->UsedBits; }
/* ************************************************************************* * Function: decode sequence display extension * Input: * Output: * Return: * Attention: ************************************************************************* */ void sequence_display_extension() { video_format = u_v(3,"video format ID"); video_range = u_v(1,"video range"); color_description = u_v(1,"color description"); if (color_description) { color_primaries = u_v(8,"color primaries"); transfer_characteristics = u_v(8,"transfer characteristics"); matrix_coefficients = u_v(8,"matrix coefficients"); } display_horizontal_size = u_v(14,"display_horizontaol_size"); u_v (1, "marker bit" ); display_vertical_size = u_v(14,"display_vertical_size"); u_v (2, "reserved bits" ); }
void copyright_extension() { int reserved_data; int marker_bit; copyright_flag = u_v(1,"copyright_flag"); copyright_identifier = u_v(8,"copyright_identifier"); original_or_copy = u_v(1,"original_or_copy"); /* reserved */ reserved_data = u_v(7,"reserved_data"); marker_bit = u_v(1,"marker_bit"); copyright_number_1 = u_v(20,"copyright_number_1"); marker_bit = u_v(1,"marker_bit"); copyright_number_2 = u_v(22,"copyright_number_2"); marker_bit = u_v(1,"marker_bit"); copyright_number_3 = u_v(22,"copyright_number_3"); }
void user_data(char *buf,int startcodepos, int length) { int user_data; int i; memcpy (currStream->streamBuffer, buf, length); currStream->code_len = currStream->bitstream_length = length; currStream->read_len = currStream->frame_bitoffset = (startcodepos+1)*8; for(i=0; i<length-4; i++) user_data = u_v (8, "user data"); }
void nal_unit_header_mvc_extension(NALUnitHeaderMVCExt_t *NaluHeaderMVCExt, Bitstream *s) { //to be implemented; NaluHeaderMVCExt->non_idr_flag = u_v (1, "non_idr_flag" , s); NaluHeaderMVCExt->priority_id = u_v (6, "priority_id" , s); NaluHeaderMVCExt->view_id = u_v (10, "view_id" , s); NaluHeaderMVCExt->temporal_id = u_v (3, "temporal_id" , s); NaluHeaderMVCExt->anchor_pic_flag = u_v (1, "anchor_pic_flag" , s); NaluHeaderMVCExt->inter_view_flag = u_v (1, "inter_view_flag" , s); NaluHeaderMVCExt->reserved_one_bit = u_v (1, "reserved_one_bit" , s); if(NaluHeaderMVCExt->reserved_one_bit != 1) { printf("Nalu Header MVC Extension: reserved_one_bit is not 1!\n"); } }
void cameraparameters_extension() { // int marker_bit1,marker_bit,marker_bit2; // float reserved_data; /* reserved */ u_v(1,"reserved"); u_v(7,"camera id"); u_v(1,"marker bit"); u_v(22,"height_of_image_device"); u_v(1,"marker bit"); u_v(22,"focal_length"); u_v(1,"marker bit"); u_v(22,"f_number"); u_v(1,"marker bit"); u_v(22,"vertical_angle_of_view"); u_v(1,"marker bit"); u_v(16,"camera_position_x_upper"); u_v(1,"marker bit"); u_v(16,"camera_position_x_lower"); u_v(1,"marker bit"); u_v(16,"camera_position_y_upper"); u_v(1,"marker bit"); u_v(16,"camera_position_y_lower"); u_v(1,"marker bit"); u_v(16,"camera_position_z_upper"); u_v(1,"marker bit"); u_v(16,"camera_position_z_lower"); u_v(1,"marker bit"); u_v(22,"camera_direction_x"); u_v(1,"marker bit"); u_v(22,"camera_direction_y"); u_v(1,"marker bit"); u_v(22,"camera_direction_z"); u_v(1,"marker bit"); u_v(22,"image_plane_vertical_x"); u_v(1,"marker bit"); u_v(22,"image_plane_vertical_y"); u_v(1,"marker bit"); u_v(22,"image_plane_vertical_z"); u_v(1,"marker bit"); u_v(32,"reserved data"); }
/*! ************************************************************************ * \brief * read the scond part of the header (without the pic_parameter_set_id * \return * Length of the second part of the Slice header in bits ************************************************************************ */ int RestOfSliceHeader(Slice *currSlice) { VideoParameters *p_Vid = currSlice->p_Vid; InputParameters *p_Inp = currSlice->p_Inp; seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps; byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; DataPartition *partition = &(currSlice->partArr[dP_nr]); Bitstream *currStream = partition->bitstream; int val, len; currSlice->frame_num = u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream); /* Tian Dong: frame_num gap processing, if found */ if(currSlice->idr_flag) //if (p_Vid->idr_flag) { p_Vid->pre_frame_num = currSlice->frame_num; // picture error concealment p_Vid->last_ref_pic_poc = 0; assert(currSlice->frame_num == 0); } if (active_sps->frame_mbs_only_flag) { p_Vid->structure = FRAME; currSlice->field_pic_flag=0; } else { // field_pic_flag u(1) currSlice->field_pic_flag = u_1("SH: field_pic_flag", currStream); if (currSlice->field_pic_flag) { // bottom_field_flag u(1) currSlice->bottom_field_flag = (byte) u_1("SH: bottom_field_flag", currStream); p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD; } else { p_Vid->structure = FRAME; currSlice->bottom_field_flag = FALSE; } } currSlice->structure = (PictureStructure) p_Vid->structure; currSlice->mb_aff_frame_flag = (active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag==0)); //currSlice->mb_aff_frame_flag = p_Vid->mb_aff_frame_flag; if (p_Vid->structure == FRAME ) assert (currSlice->field_pic_flag == 0); if (p_Vid->structure == TOP_FIELD ) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == FALSE)); if (p_Vid->structure == BOTTOM_FIELD) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == TRUE )); if (currSlice->idr_flag) { currSlice->idr_pic_id = ue_v("SH: idr_pic_id", currStream); } if (active_sps->pic_order_cnt_type == 0) { currSlice->pic_order_cnt_lsb = u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream); else currSlice->delta_pic_order_cnt_bottom = 0; } if( active_sps->pic_order_cnt_type == 1) { if ( !active_sps->delta_pic_order_always_zero_flag ) { currSlice->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream); else currSlice->delta_pic_order_cnt[ 1 ] = 0; // set to zero if not in stream } else { currSlice->delta_pic_order_cnt[ 0 ] = 0; currSlice->delta_pic_order_cnt[ 1 ] = 0; } } //! redundant_pic_cnt is missing here if (p_Vid->active_pps->redundant_pic_cnt_present_flag) { currSlice->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream); } if(currSlice->slice_type == B_SLICE) { currSlice->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream); } currSlice->num_ref_idx_active[LIST_0] = p_Vid->active_pps->num_ref_idx_l0_active_minus1 + 1; currSlice->num_ref_idx_active[LIST_1] = p_Vid->active_pps->num_ref_idx_l1_active_minus1 + 1; if(p_Vid->type==P_SLICE || p_Vid->type == SP_SLICE || p_Vid->type==B_SLICE) { val = u_1 ("SH: num_ref_idx_override_flag", currStream); if (val) { currSlice->num_ref_idx_active[LIST_0] = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream); if(p_Vid->type==B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream); } } } if (currSlice->slice_type!=B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 0; } #if (MVC_EXTENSION_ENABLE) if (currSlice->svc_extension_flag == 0 || currSlice->svc_extension_flag == 1) ref_pic_list_mvc_modification(currSlice); else ref_pic_list_reordering(currSlice); #else ref_pic_list_reordering(currSlice); #endif currSlice->weighted_pred_flag = (unsigned short) ((currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE) ? p_Vid->active_pps->weighted_pred_flag : (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc == 1)); currSlice->weighted_bipred_idc = (unsigned short) (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc > 0); if ((p_Vid->active_pps->weighted_pred_flag&&(p_Vid->type==P_SLICE|| p_Vid->type == SP_SLICE))|| (p_Vid->active_pps->weighted_bipred_idc==1 && (p_Vid->type==B_SLICE))) { pred_weight_table(currSlice); } if (currSlice->nal_reference_idc) dec_ref_pic_marking(p_Vid, currStream, currSlice); if (p_Vid->active_pps->entropy_coding_mode_flag && p_Vid->type!=I_SLICE && p_Vid->type!=SI_SLICE) { currSlice->model_number = ue_v("SH: cabac_init_idc", currStream); } else { currSlice->model_number = 0; } currSlice->slice_qp_delta = val = se_v("SH: slice_qp_delta", currStream); //currSlice->qp = p_Vid->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val; currSlice->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val; if ((currSlice->qp < -p_Vid->bitdepth_luma_qp_scale) || (currSlice->qp > 51)) error ("slice_qp_delta makes slice_qp_y out of range", 500); if(p_Vid->type==SP_SLICE || p_Vid->type == SI_SLICE) { if(p_Vid->type==SP_SLICE) { currSlice->sp_switch = u_1 ("SH: sp_for_switch_flag", currStream); } currSlice->slice_qs_delta = val = se_v("SH: slice_qs_delta", currStream); currSlice->qs = 26 + p_Vid->active_pps->pic_init_qs_minus26 + val; if ((currSlice->qs < 0) || (currSlice->qs > 51)) error ("slice_qs_delta makes slice_qs_y out of range", 500); } if ( !HI_INTRA_ONLY_PROFILE || (HI_INTRA_ONLY_PROFILE && (p_Inp->intra_profile_deblocking == 1) )) //then read flags and parameters from bistream { if (p_Vid->active_pps->deblocking_filter_control_present_flag) { currSlice->DFDisableIdc = (short) ue_v ("SH: disable_deblocking_filter_idc", currStream); if (currSlice->DFDisableIdc!=1) { currSlice->DFAlphaC0Offset = (short) (2 * se_v("SH: slice_alpha_c0_offset_div2", currStream)); currSlice->DFBetaOffset = (short) (2 * se_v("SH: slice_beta_offset_div2", currStream)); } else { currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } } else { currSlice->DFDisableIdc = currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } } else //By default the Loop Filter is Off { //444_TEMP_NOTE: change made below. 08/07/07 //still need to parse the SEs (read flags and parameters from bistream) but will ignore if (p_Vid->active_pps->deblocking_filter_control_present_flag) { currSlice->DFDisableIdc = (short) ue_v ("SH: disable_deblocking_filter_idc", currStream); if (currSlice->DFDisableIdc!=1) { currSlice->DFAlphaC0Offset = (short) (2 * se_v("SH: slice_alpha_c0_offset_div2", currStream)); currSlice->DFBetaOffset = (short) (2 * se_v("SH: slice_beta_offset_div2", currStream)); } }//444_TEMP_NOTE. the end of change. 08/07/07 //Ignore the SEs, by default the Loop Filter is Off currSlice->DFDisableIdc =1; currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } if (p_Vid->active_pps->num_slice_groups_minus1>0 && p_Vid->active_pps->slice_group_map_type>=3 && p_Vid->active_pps->slice_group_map_type<=5) { len = (active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1)/ (p_Vid->active_pps->slice_group_change_rate_minus1+1); if (((active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1))% (p_Vid->active_pps->slice_group_change_rate_minus1+1)) len +=1; len = CeilLog2(len+1); currSlice->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream); } p_Vid->PicHeightInMbs = p_Vid->FrameHeightInMbs / ( 1 + currSlice->field_pic_flag ); p_Vid->PicSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->PicHeightInMbs; p_Vid->FrameSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->FrameHeightInMbs; return p_Dec->UsedBits; }
//++ 参见标准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; }
/*! ************************************************************************************* * \brief * ue_v, reads an u(1) syntax element, the length in bits is stored in * the global UsedBits variable * * \param tracestring * the string for the trace file * * \param bitstream * the stream to be read from * * \return * the value of the coded syntax element * ************************************************************************************* */ Boolean u_1 (char *tracestring, Bitstream *bitstream) { return (Boolean) u_v (1, tracestring, bitstream); }
void I_Picture_Header(char *buf,int startcodepos, int length) { currStream->frame_bitoffset = currStream->read_len = (startcodepos+1)*8; currStream->code_len = currStream->bitstream_length = length; memcpy (currStream->streamBuffer, buf, length); bbv_delay = u_v(16,"bbv delay"); time_code_flag = u_v(1,"time_code_flag"); if (time_code_flag) time_code =u_v(24,"time_code"); marker_bit =u_v(1,"marker_bit"); picture_distance = u_v(8,"picture_distance"); if(low_delay) { bbv_check_times = ue_v("bbv check times"); } progressive_frame = u_v(1,"progressive_frame"); if (!progressive_frame) { img->picture_structure = u_v(1,"picture_structure"); }else { img->picture_structure = 1; } top_field_first = u_v(1,"top_field_first"); repeat_first_field = u_v(1,"repeat_first_field"); fixed_picture_qp = u_v(1,"fixed_picture_qp"); picture_qp = u_v(6,"picture_qp"); if(progressive_frame==0) { if(img->picture_structure == 0) { skip_mode_flag =u_v(1,"skip mode flag"); } } u_v(4,"reserved bits"); loop_filter_disable = u_v(1,"loop_filter_disable"); if (!loop_filter_disable) { loop_filter_parameter_flag = u_v(1,"loop_filter_parameter_flag"); if (loop_filter_parameter_flag) { alpha_offset = se_v("alpha_offset"); beta_offset = se_v("beta_offset"); } else { alpha_offset = 0; beta_offset = 0; } } img->qp = picture_qp; img->pic_distance = picture_distance; img->type = I_IMG; }
/*********************************************************************** *\brief Header_parsing * - Code not related to baseline removed. * * "Muhammad Tahir Awan" <*****@*****.**>, * "Umair Razzak" <*****@*****.**> **************************** * Changes till 21-11-2005 *********************************************************************** */ int RestOfSliceHeader_baseline( h264_decoder* dec_params ) { Slice *currSlice = dec_params->img->currentSlice; //int dP_nr = assignSE2partition[PAR_DP_1][SE_HEADER]; //int dP_nr = 0; DataPartition *partition = &(currSlice->partArr[0]); Bitstream *currStream = partition->bitstream; int val, len; // reading frame number (7.3.3) dec_params->img->frame_num = u_v (dec_params->active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream,dec_params); /* Tian Dong: frame_num gap processing, if found */ if (dec_params->img->idr_flag) { dec_params->img->pre_frame_num = dec_params->img->frame_num; assert(dec_params->img->frame_num == 0); } //{ // dec_params->img->structure = FRAME; //} //currSlice->structure = FRAME; //assert (dec_params->img->field_pic_flag == 0); if (dec_params->img->idr_flag) { dec_params->img->idr_pic_id = ue_v("SH: idr_pic_id", currStream,dec_params); } if (dec_params->active_sps->pic_order_cnt_type == 0) { dec_params->img->pic_order_cnt_lsb = u_v(dec_params->active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream,dec_params); if( dec_params->active_pps->pic_order_present_flag == 1) dec_params->img->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream,dec_params); else dec_params->img->delta_pic_order_cnt_bottom = 0; } if( dec_params->active_sps->pic_order_cnt_type == 1 && !dec_params->active_sps->delta_pic_order_always_zero_flag ) { dec_params->img->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream,dec_params); if( dec_params->active_pps->pic_order_present_flag == 1 ) dec_params->img->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream,dec_params); }else { if (dec_params->active_sps->pic_order_cnt_type == 1) { dec_params->img->delta_pic_order_cnt[ 0 ] = 0; dec_params->img->delta_pic_order_cnt[ 1 ] = 0; } } //! redundant_pic_cnt is missing here if (dec_params->active_pps->redundant_pic_cnt_present_flag) { //dec_params->img->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream,dec_params); } if(dec_params->img->type==B_SLICE) { dec_params->img->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream,dec_params); } dec_params->img->num_ref_idx_l0_active = dec_params->active_pps->num_ref_idx_l0_active_minus1 + 1; dec_params->img->num_ref_idx_l1_active = dec_params->active_pps->num_ref_idx_l1_active_minus1 + 1; if(dec_params->img->type==P_SLICE || dec_params->img->type==B_SLICE)// added by Faisal Abdullah for B frames { val = u_1 ("SH: num_ref_idx_override_flag", currStream,dec_params); if (val) { dec_params->img->num_ref_idx_l0_active = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream,dec_params); if(dec_params->img->type==B_SLICE) { dec_params->img->num_ref_idx_l1_active = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream,dec_params); } } } if (dec_params->img->type!=B_SLICE) { dec_params->img->num_ref_idx_l1_active = 0; } ref_pic_list_reordering( dec_params ); // for weighted prediction in B and P frames dec_params->img->apply_weights = ((dec_params->active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE ) ) || ((dec_params->active_pps->weighted_bipred_idc > 0 ) && (currSlice->picture_type == B_SLICE))); /*dec_params->img->apply_weights = ((dec_params->active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE ) ) || ((dec_params->active_pps->weighted_bipred_idc == 1 ) && (currSlice->picture_type == B_SLICE)));*/ dec_params->img->apply_weights_bi = 0; dec_params->img->apply_weights_luma = 0; dec_params->img->apply_weights_chr = 0; if ((dec_params->active_pps->weighted_pred_flag&&(dec_params->img->type==P_SLICE))|| (dec_params->active_pps->weighted_bipred_idc==1 && (dec_params->img->type==B_SLICE))) { pred_weight_table(dec_params); } dec_params->img->apply_weights_bi = (dec_params->active_pps->weighted_bipred_idc==2 && (dec_params->img->type==B_SLICE)); if (dec_params->img->nal_reference_idc) dec_ref_pic_marking(currStream,dec_params); //__CABAC__ if (dec_params->active_pps->entropy_coding_mode_flag && dec_params->img->type!=I_SLICE && dec_params->img->type!=SI_SLICE) { dec_params->img->model_number = ue_v("SH: cabac_init_idc", currStream, dec_params); } else { dec_params->img->model_number = 0; } //__CABAC__ val = se_v("SH: slice_qp_delta", currStream,dec_params); //currSlice->qp = dec_params->img->qp = 26 + dec_params->active_pps->pic_init_qp_minus26 + val; dec_params->img->qp = 26 + dec_params->active_pps->pic_init_qp_minus26 + val; //currSlice->slice_qp_delta = val; if (dec_params->active_pps->deblocking_filter_control_present_flag) { currSlice->LFDisableIdc = ue_v ("SH: disable_deblocking_filter_idc", currStream,dec_params); if (currSlice->LFDisableIdc!=1) { currSlice->LFAlphaC0Offset = 2 * se_v("SH: slice_alpha_c0_offset_div2", currStream,dec_params); currSlice->LFBetaOffset = 2 * se_v("SH: slice_beta_offset_div2", currStream,dec_params); } else { currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0; } } else { currSlice->LFDisableIdc = currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0; } if (dec_params->active_pps->num_slice_groups_minus1>0 && dec_params->active_pps->slice_group_map_type>=3 && dec_params->active_pps->slice_group_map_type<=5) { len = (dec_params->active_sps->pic_height_in_map_units_minus1+1)*(dec_params->active_sps->pic_width_in_mbs_minus1+1)/ (dec_params->active_pps->slice_group_change_rate_minus1+1); if (((dec_params->active_sps->pic_height_in_map_units_minus1+1)*(dec_params->active_sps->pic_width_in_mbs_minus1+1))% (dec_params->active_pps->slice_group_change_rate_minus1+1)) len +=1; len = CeilLog2(len+1); dec_params->img->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream,dec_params); } dec_params->img->FrameSizeInMbs = dec_params->img->FrameWidthInMbs * dec_params->img->FrameHeightInMbs; return dec_params->UsedBits; }
/*! ************************************************************************ * \brief * Interpret the Sub-sequence characteristics SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_subsequence_characteristics_info( byte* payload, int size, ImageParameters *img ) { Bitstream* buf; int i; int sub_seq_layer_num, sub_seq_id, duration_flag, average_rate_flag, accurate_statistics_flag; unsigned long sub_seq_duration, average_bit_rate, average_frame_rate; int num_referenced_subseqs, ref_sub_seq_layer_num, ref_sub_seq_id, ref_sub_seq_direction; #ifdef ESLCPP buf = (Bitstream*)malloc(sizeof(Bitstream)); #else buf = malloc(sizeof(Bitstream)); #endif buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; sub_seq_layer_num = ue_v("SEI: sub_seq_layer_num", buf); sub_seq_id = ue_v("SEI: sub_seq_id", buf); duration_flag = u_1 ("SEI: duration_flag", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("Sub-sequence characteristics SEI message\n"); printf("sub_seq_layer_num = %d\n", sub_seq_layer_num ); printf("sub_seq_id = %d\n", sub_seq_id); printf("duration_flag = %d\n", duration_flag); #endif if ( duration_flag ) { sub_seq_duration = u_v (32, "SEI: duration_flag", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("sub_seq_duration = %ld\n", sub_seq_duration); #endif } average_rate_flag = u_1 ("SEI: average_rate_flag", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("average_rate_flag = %d\n", average_rate_flag); #endif if ( average_rate_flag ) { accurate_statistics_flag = u_1 ( "SEI: accurate_statistics_flag", buf); average_bit_rate = u_v (16, "SEI: average_bit_rate", buf); average_frame_rate = u_v (16, "SEI: average_frame_rate", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("accurate_statistics_flag = %d\n", accurate_statistics_flag); printf("average_bit_rate = %ld\n", average_bit_rate); printf("average_frame_rate = %ld\n", average_frame_rate); #endif } num_referenced_subseqs = ue_v("SEI: num_referenced_subseqs", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("num_referenced_subseqs = %d\n", num_referenced_subseqs); #endif for (i=0; i<num_referenced_subseqs; i++) { ref_sub_seq_layer_num = ue_v("SEI: ref_sub_seq_layer_num", buf); ref_sub_seq_id = ue_v("SEI: ref_sub_seq_id", buf); ref_sub_seq_direction = u_1 ("SEI: ref_sub_seq_direction", buf); #ifdef PRINT_SUBSEQUENCE_CHAR printf("ref_sub_seq_layer_num = %d\n", ref_sub_seq_layer_num); printf("ref_sub_seq_id = %d\n", ref_sub_seq_id); printf("ref_sub_seq_direction = %d\n", ref_sub_seq_direction); #endif } free( buf ); #ifdef PRINT_SUBSEQUENCE_CHAR #undef PRINT_SUBSEQUENCE_CHAR #endif }
/*! ************************************************************************************* * \brief * ue_v, reads an u(1) syntax element, the length in bits is stored in * the global UsedBits variable * * \param tracestring * the string for the trace file * * \param bitstream * the stream to be read from * * \return * the value of the coded syntax element * ************************************************************************************* */ int u_1 (char *tracestring, Bitstream *bitstream) { return u_v (1, tracestring, bitstream); }
/* ************************************************************************* * Function:pb picture header * Input: * Output: * Return: * Attention: ************************************************************************* */ void PB_Picture_Header(char *buf,int startcodepos, int length) { currStream->frame_bitoffset = currStream->read_len = (startcodepos+1)*8; currStream->code_len = currStream->bitstream_length = length; memcpy (currStream->streamBuffer, buf, length); bbv_delay = u_v(16,"bbv delay"); picture_coding_type = u_v(2,"picture_coding_type"); picture_distance = u_v(8,"picture_distance"); if(low_delay) { bbv_check_times = ue_v("bbv check times"); } progressive_frame = u_v(1,"progressive_frame"); if (!progressive_frame) { img->picture_structure = u_v(1,"picture_structure"); if (!img->picture_structure) img->advanced_pred_mode_disable = u_v(1,"advanced_pred_mode_disable"); }else img->picture_structure = 1; top_field_first = u_v(1,"top_field_first"); repeat_first_field = u_v(1,"repeat_first_field"); fixed_picture_qp = u_v(1,"fixed_picture_qp"); picture_qp = u_v(6,"picture_qp"); if (!(picture_coding_type==2 && img->picture_structure==1)) { picture_reference_flag = u_v(1,"picture_reference_flag"); } img->no_forward_reference = u_v(1, "no_forward_reference_flag"); u_v(3,"reserved bits"); skip_mode_flag = u_v(1,"skip_mode_flag"); loop_filter_disable = u_v(1,"loop_filter_disable"); if (!loop_filter_disable) { loop_filter_parameter_flag = u_v(1,"loop_filter_parameter_flag"); if (loop_filter_parameter_flag) { alpha_offset = se_v("alpha_offset"); beta_offset = se_v("beta_offset"); } else // 20071009 { alpha_offset = 0; beta_offset = 0; } } img->qp = picture_qp; if(picture_coding_type==1) { img->type = P_IMG; vec_flag = 0; } else { img->type = B_IMG; } img->pic_distance = picture_distance; }
/*! ************************************************************************ * \brief * Interpret the Picture timing SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_picture_timing_info( byte* payload, int size, ImageParameters *img ) { int cpb_removal_delay, dpb_output_delay, picture_structure_present_flag, picture_structure; int clock_time_stamp_flag; int ct_type, nuit_field_based_flag, counting_type, full_timestamp_flag, discontinuity_flag, cnt_dropped_flag, nframes; int seconds_value, minutes_value, hours_value, seconds_flag, minutes_flag, hours_flag, time_offset; int NumClockTs = 0; int i; Bitstream* buf; #ifdef ESLCPP buf = (Bitstream*)malloc(sizeof(Bitstream)); #else buf = malloc(sizeof(Bitstream)); #endif buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; assert (NULL!=active_sps); #ifdef PRINT_PCITURE_TIMING_INFO printf("Picture timing SEI message\n"); #endif if ((active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)|| (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)) { cpb_removal_delay = ue_v("SEI: cpb_removal_delay" , buf); dpb_output_delay = ue_v("SEI: dpb_output_delay" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("cpb_removal_delay = %d\n",cpb_removal_delay); printf("dpb_output_delay = %d\n",dpb_output_delay); #endif } picture_structure_present_flag = u_1("SEI: picture_structure_present_flag" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("picture_structure_present_flag = %d\n",picture_structure_present_flag); #endif if (picture_structure_present_flag) { picture_structure = u_v(3, "SEI: picture_structure" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("picture_structure = %d\n",picture_structure); #endif switch (picture_structure) { case 0: case 1: case 2: NumClockTs = 1; break; case 3: case 4: case 7: NumClockTs = 2; break; case 5: case 6: case 8: NumClockTs = 3; break; default: error("reserved picture_structure used (can't determine NumClockTs)", 500); } for (i=0; i<NumClockTs; i++) { clock_time_stamp_flag = u_1("SEI: clock_time_stamp_flag" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("clock_time_stamp_flag = %d\n",clock_time_stamp_flag); #endif if (clock_time_stamp_flag) { ct_type = u_v(2, "SEI: ct_type" , buf); nuit_field_based_flag = u_1( "SEI: nuit_field_based_flag" , buf); counting_type = u_v(5, "SEI: counting_type" , buf); full_timestamp_flag = u_1( "SEI: full_timestamp_flag" , buf); discontinuity_flag = u_1( "SEI: discontinuity_flag" , buf); cnt_dropped_flag = u_1( "SEI: cnt_dropped_flag" , buf); nframes = u_v(8, "SEI: nframes" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("ct_type = %d\n",ct_type); printf("nuit_field_based_flag = %d\n",nuit_field_based_flag); printf("full_timestamp_flag = %d\n",full_timestamp_flag); printf("discontinuity_flag = %d\n",discontinuity_flag); printf("cnt_dropped_flag = %d\n",cnt_dropped_flag); printf("nframes = %d\n",nframes); #endif if (full_timestamp_flag) { seconds_value = u_v(6, "SEI: seconds_value" , buf); minutes_value = u_v(6, "SEI: minutes_value" , buf); hours_value = u_v(5, "SEI: hours_value" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("seconds_value = %d\n",seconds_value); printf("minutes_value = %d\n",minutes_value); printf("hours_value = %d\n",hours_value); #endif } else { seconds_flag = u_1( "SEI: seconds_flag" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("seconds_flag = %d\n",seconds_flag); #endif if (seconds_flag) { seconds_value = u_v(6, "SEI: seconds_value" , buf); minutes_flag = u_1( "SEI: minutes_flag" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("seconds_value = %d\n",seconds_value); printf("minutes_flag = %d\n",minutes_flag); #endif if(minutes_flag) { minutes_value = u_v(6, "SEI: minutes_value" , buf); hours_flag = u_1( "SEI: hours_flag" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("minutes_value = %d\n",minutes_value); printf("hours_flag = %d\n",hours_flag); #endif if(hours_flag) { hours_value = u_v(5, "SEI: hours_value" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("hours_value = %d\n",hours_value); #endif } } } } if(active_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length) //!KS which HRD params shall be used? { time_offset=0; // time_offset = i_v(active_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length, "SEI: time_offset" , buf); #ifdef PRINT_PCITURE_TIMING_INFO printf("time_offset = %d\n",time_offset); #endif } } } } free (buf); #ifdef PRINT_PCITURE_TIMING_INFO #undef PRINT_PCITURE_TIMING_INFO #endif }
void SliceHeader (char *buf,int startcodepos, int length) { int i; int weight_para_num; int mb_row; int mb_index; int mb_width, mb_height; memcpy (currStream->streamBuffer, buf, length); currStream->code_len = currStream->bitstream_length = length; currStream->read_len = currStream->frame_bitoffset = (startcodepos)*8; slice_vertical_position = u_v (8, "slice vertical position"); if(vertical_size > 2800) slice_vertical_position_extension = u_v (3, "slice vertical position extension"); if (vertical_size > 2800) mb_row = (slice_vertical_position_extension << 7) + slice_vertical_position; else mb_row = slice_vertical_position; mb_width = (horizontal_size + 15) / 16; if(!progressive_sequence) mb_height = 2 * ((vertical_size + 31) / 32); else mb_height = (vertical_size + 15) / 16; mb_index = mb_row * mb_width; if (!img->picture_structure && img->type==I_IMG && (mb_index >= mb_width*mb_height/2) ) { second_IField = 1; img->type = P_IMG; pre_img_type = P_IMG; } if (!fixed_picture_qp) { fixed_slice_qp = u_v (1,"fixed_slice_qp"); slice_qp = u_v (6,"slice_qp"); img->qp=slice_qp; } if(img->type != I_IMG){ img->slice_weighting_flag = u_v(1,"slice weighting flag"); if(img->slice_weighting_flag) { if(second_IField && !img->picture_structure) //I bottom weight_para_num=1; else if(img->type==P_IMG && img->picture_structure) //P frame coding weight_para_num=2; else if(img->type==P_IMG && !img->picture_structure) //P field coding weight_para_num=4; else if(img->type==B_IMG && img->picture_structure) //B frame coding weight_para_num=2; else if(img->type==B_IMG && !img->picture_structure) //B field coding weight_para_num=4; for(i=0;i<weight_para_num;i++) { img->lum_scale[i] = u_v(8,"luma scale"); img->lum_shift[i] =i_8("luma shift"); u_1 ("insert bit"); img->chroma_scale[i] = u_v(8,"chroma scale"); img->chroma_shift[i] = i_8("chroma shift"); u_1 ("insert bit"); } img->mb_weighting_flag =u_v(1,"MB weighting flag"); } } }
void SequenceHeader (char *buf,int startcodepos, int length) { memcpy (currStream->streamBuffer, buf, length); currStream->code_len = currStream->bitstream_length = length; currStream->read_len = currStream->frame_bitoffset = (startcodepos+1)*8; profile_id = u_v (8, "profile_id" ); level_id = u_v (8, "level_id" ); progressive_sequence = u_v (1, "progressive_sequence" ); horizontal_size = u_v (14, "horizontal_size" ); vertical_size = u_v (14, "vertical_size" ); chroma_format = u_v (2, "chroma_format" ); sample_precision = u_v (3, "sample_precision" ); aspect_ratio_information = u_v (4, "aspect_ratio_information" ); frame_rate_code = u_v (4, "frame_rate_code" ); bit_rate_lower = u_v (18, "bit_rate_lower" ); u_v (1, "marker bit" ); bit_rate_upper = u_v (12, "bit_rate_upper" ); low_delay = u_v (1, "low_delay" ); u_v (1, "marker bit" ); bbv_buffer_size = u_v(18,"bbv buffer size"); u_v (3,"reseved bits" ); img->width = horizontal_size; img->height = vertical_size; img->width_cr = (img->width>>1); if(chroma_format==2) img->height_cr = (img->height); else img->height_cr = (img->height>>1); img->PicWidthInMbs = img->width/MB_BLOCK_SIZE; img->PicHeightInMbs = img->height/MB_BLOCK_SIZE; img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs; img->buf_cycle = input->buf_cycle+1; img->max_mb_nr =(img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE); }
/*! ************************************************************************ * \brief * read the scond part of the header (without the pic_parameter_set_id * \return * Length of the second part of the Slice header in bits ************************************************************************ */ int RestOfSliceHeader() { Slice *currSlice = img->currentSlice; int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; DataPartition *partition = &(currSlice->partArr[dP_nr]); Bitstream *currStream = partition->bitstream; int val, len; img->frame_num = u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream); /* Tian Dong: frame_num gap processing, if found */ if (img->idr_flag) { img->pre_frame_num = img->frame_num; // picture error concealment img->last_ref_pic_poc = 0; assert(img->frame_num == 0); } if (active_sps->frame_mbs_only_flag) { img->structure = FRAME; img->field_pic_flag=0; } else { // field_pic_flag u(1) img->field_pic_flag = u_1("SH: field_pic_flag", currStream); if (img->field_pic_flag) { // bottom_field_flag u(1) img->bottom_field_flag = u_1("SH: bottom_field_flag", currStream); img->structure = img->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD; } else { img->structure = FRAME; img->bottom_field_flag=0; } } currSlice->structure = img->structure; img->MbaffFrameFlag=(active_sps->mb_adaptive_frame_field_flag && (img->field_pic_flag==0)); if (img->structure == FRAME ) assert (img->field_pic_flag == 0); if (img->structure == TOP_FIELD ) assert (img->field_pic_flag == 1 && img->bottom_field_flag == 0); if (img->structure == BOTTOM_FIELD) assert (img->field_pic_flag == 1 && img->bottom_field_flag == 1); if (img->idr_flag) { img->idr_pic_id = ue_v("SH: idr_pic_id", currStream); } if (active_sps->pic_order_cnt_type == 0) { img->pic_order_cnt_lsb = u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream); if( active_pps->pic_order_present_flag == 1 && !img->field_pic_flag ) img->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream); else img->delta_pic_order_cnt_bottom = 0; } if( active_sps->pic_order_cnt_type == 1 && !active_sps->delta_pic_order_always_zero_flag ) { img->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream); if( active_pps->pic_order_present_flag == 1 && !img->field_pic_flag ) img->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream); }else { if (active_sps->pic_order_cnt_type == 1) { img->delta_pic_order_cnt[ 0 ] = 0; img->delta_pic_order_cnt[ 1 ] = 0; } } //! redundant_pic_cnt is missing here if (active_pps->redundant_pic_cnt_present_flag) { img->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream); } if(img->type==B_SLICE) { img->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream); } img->num_ref_idx_l0_active = active_pps->num_ref_idx_l0_active_minus1 + 1; img->num_ref_idx_l1_active = active_pps->num_ref_idx_l1_active_minus1 + 1; if(img->type==P_SLICE || img->type == SP_SLICE || img->type==B_SLICE) { val = u_1 ("SH: num_ref_idx_override_flag", currStream); if (val) { img->num_ref_idx_l0_active = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream); if(img->type==B_SLICE) { img->num_ref_idx_l1_active = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream); } } } if (img->type!=B_SLICE) { img->num_ref_idx_l1_active = 0; } ref_pic_list_reordering(); img->apply_weights = ((active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE || currSlice->picture_type == SP_SLICE) ) || ((active_pps->weighted_bipred_idc > 0 ) && (currSlice->picture_type == B_SLICE))); if ((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))|| (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) { pred_weight_table(); } if (img->nal_reference_idc) dec_ref_pic_marking(currStream); if (active_pps->entropy_coding_mode_flag && img->type!=I_SLICE && img->type!=SI_SLICE) { img->model_number = ue_v("SH: cabac_init_idc", currStream); } else { img->model_number = 0; } val = se_v("SH: slice_qp_delta", currStream); currSlice->qp = img->qp = 26 + active_pps->pic_init_qp_minus26 + val; currSlice->slice_qp_delta = val; if(img->type==SP_SLICE || img->type == SI_SLICE) { if(img->type==SP_SLICE) { img->sp_switch = u_1 ("SH: sp_for_switch_flag", currStream); } val = se_v("SH: slice_qs_delta", currStream); img->qpsp = 26 + active_pps->pic_init_qs_minus26 + val; } if (active_pps->deblocking_filter_control_present_flag) { currSlice->LFDisableIdc = ue_v ("SH: disable_deblocking_filter_idc", currStream); if (currSlice->LFDisableIdc!=1) { currSlice->LFAlphaC0Offset = 2 * se_v("SH: slice_alpha_c0_offset_div2", currStream); currSlice->LFBetaOffset = 2 * se_v("SH: slice_beta_offset_div2", currStream); } else { currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0; } } else { currSlice->LFDisableIdc = currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0; } if (active_pps->num_slice_groups_minus1>0 && active_pps->slice_group_map_type>=3 && active_pps->slice_group_map_type<=5) { len = (active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1)/ (active_pps->slice_group_change_rate_minus1+1); if (((active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1))% (active_pps->slice_group_change_rate_minus1+1)) len +=1; len = CeilLog2(len+1); img->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream); } img->PicHeightInMbs = img->FrameHeightInMbs / ( 1 + img->field_pic_flag ); img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs; img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs; return UsedBits; }