/*! ************************************************************************ * \brief * Interpret the Pan scan rectangle 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_pan_scan_rect_info( byte* payload, int size, ImageParameters *img ) { int pan_scan_rect_id, pan_scan_rect_left_offset, pan_scan_rect_right_offset; int pan_scan_rect_top_offset, pan_scan_rect_bottom_offset; Bitstream* buf; buf = malloc(sizeof(Bitstream)); buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; UsedBits = 0; pan_scan_rect_id = ue_v("SEI: pan_scan_rect_id", buf); pan_scan_rect_left_offset = se_v("SEI: pan_scan_rect_left_offset" , buf); pan_scan_rect_right_offset = se_v("SEI: pan_scan_rect_right_offset" , buf); pan_scan_rect_top_offset = se_v("SEI: pan_scan_rect_top_offset" , buf); pan_scan_rect_bottom_offset = se_v("SEI: pan_scan_rect_bottom_offset", buf); #ifdef PRINT_PAN_SCAN_RECT printf("Pan scan rectangle SEI message\n"); printf("pan_scan_rect_id = %d\n", pan_scan_rect_id); printf("pan_scan_rect_left_offset = %d\n", pan_scan_rect_left_offset); printf("pan_scan_rect_right_offset = %d\n", pan_scan_rect_right_offset); printf("pan_scan_rect_top_offset = %d\n", pan_scan_rect_top_offset); printf("pan_scan_rect_bottom_offset = %d\n", pan_scan_rect_bottom_offset); #endif free (buf); #ifdef PRINT_PAN_SCAN_RECT #undef PRINT_PAN_SCAN_RECT #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; }
/* update video->mb_skip_run */ AVCDec_Status DecodeMB(AVCDecObject *decvid) { AVCDec_Status status; AVCCommonObj *video = decvid->common; AVCDecBitstream *stream = decvid->bitstream; AVCMacroblock *currMB = video->currMB; uint mb_type; int slice_type = video->slice_type; int temp; currMB->QPy = video->QPy; currMB->QPc = video->QPc; if (slice_type == AVC_P_SLICE) { if (video->mb_skip_run < 0) { ue_v(stream, (uint *)&(video->mb_skip_run)); } if (video->mb_skip_run == 0) { /* this will not handle the case where the slice ends with a mb_skip_run == 0 and no following MB data */ ue_v(stream, &mb_type); if (mb_type > 30) { return AVCDEC_FAIL; } InterpretMBModeP(currMB, mb_type); video->mb_skip_run = -1; } else { /* see subclause 7.4.4 for more details on how mb_field_decoding_flag is derived in case of skipped MB */ currMB->mb_intra = FALSE; currMB->mbMode = AVC_SKIP; currMB->MbPartWidth = currMB->MbPartHeight = 16; currMB->NumMbPart = 1; currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] = currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1; // currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] = currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth; currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] = currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight; oscl_memset(currMB->nz_coeff, 0, sizeof(uint8)*NUM_BLKS_IN_MB); currMB->CBP = 0; video->cbp4x4 = 0; /* for skipped MB, always look at the first entry in RefPicList */ currMB->RefIdx[0] = currMB->RefIdx[1] = currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx; InterMBPrediction(video); video->mb_skip_run--; return AVCDEC_SUCCESS; } } else { /* Then decode mode and MV */ ue_v(stream, &mb_type); if (mb_type > 25) { return AVCDEC_FAIL; } InterpretMBModeI(currMB, mb_type); } if (currMB->mbMode != AVC_I_PCM) { if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0) { status = sub_mb_pred(video, currMB, stream); } else { status = mb_pred(video, currMB, stream) ; } if (status != AVCDEC_SUCCESS) { return status; } if (currMB->mbMode != AVC_I16) { /* decode coded_block_pattern */ status = DecodeCBP(currMB, stream); if (status != AVCDEC_SUCCESS) { return status; } } if (currMB->CBP > 0 || currMB->mbMode == AVC_I16) { se_v(stream, &temp); if (temp) { temp += (video->QPy + 52); currMB->QPy = video->QPy = temp - 52 * (temp * 79 >> 12); if (currMB->QPy > 51 || currMB->QPy < 0) { video->QPy = AVC_CLIP3(0, 51, video->QPy); // return AVCDEC_FAIL; } video->QPy_div_6 = (video->QPy * 43) >> 8; video->QPy_mod_6 = video->QPy - 6 * video->QPy_div_6; currMB->QPc = video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, video->QPy + video->currPicParams->chroma_qp_index_offset)]; video->QPc_div_6 = (video->QPc * 43) >> 8; video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6; } } /* decode residue and inverse transform */ status = residual(decvid, currMB); if (status != AVCDEC_SUCCESS) { return status; } }
/*! ************************************************************************ * \brief * read the weighted prediction tables ************************************************************************ */ static void pred_weight_table(Slice *currSlice) { VideoParameters *p_Vid = currSlice->p_Vid; 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 luma_weight_flag_l0, luma_weight_flag_l1, chroma_weight_flag_l0, chroma_weight_flag_l1; int i,j; currSlice->luma_log2_weight_denom = (unsigned short) ue_v ("SH: luma_log2_weight_denom", currStream); currSlice->wp_round_luma = currSlice->luma_log2_weight_denom ? 1<<(currSlice->luma_log2_weight_denom - 1): 0; if ( 0 != active_sps->chroma_format_idc) { currSlice->chroma_log2_weight_denom = (unsigned short) ue_v ("SH: chroma_log2_weight_denom", currStream); currSlice->wp_round_chroma = currSlice->chroma_log2_weight_denom ? 1<<(currSlice->chroma_log2_weight_denom - 1): 0; } reset_wp_params(currSlice); for (i=0; i<currSlice->num_ref_idx_active[LIST_0]; i++) { luma_weight_flag_l0 = u_1("SH: luma_weight_flag_l0", currStream); if (luma_weight_flag_l0) { currSlice->wp_weight[0][i][0] = se_v ("SH: luma_weight_l0", currStream); currSlice->wp_offset[0][i][0] = se_v ("SH: luma_offset_l0", currStream); currSlice->wp_offset[0][i][0] = currSlice->wp_offset[0][i][0]<<(p_Vid->bitdepth_luma - 8); } else { currSlice->wp_weight[0][i][0] = 1 << currSlice->luma_log2_weight_denom; currSlice->wp_offset[0][i][0] = 0; } if (active_sps->chroma_format_idc != 0) { chroma_weight_flag_l0 = u_1 ("SH: chroma_weight_flag_l0", currStream); for (j=1; j<3; j++) { if (chroma_weight_flag_l0) { currSlice->wp_weight[0][i][j] = se_v("SH: chroma_weight_l0", currStream); currSlice->wp_offset[0][i][j] = se_v("SH: chroma_offset_l0", currStream); currSlice->wp_offset[0][i][j] = currSlice->wp_offset[0][i][j]<<(p_Vid->bitdepth_chroma-8); } else { currSlice->wp_weight[0][i][j] = 1<<currSlice->chroma_log2_weight_denom; currSlice->wp_offset[0][i][j] = 0; } } } } if ((p_Vid->type == B_SLICE) && p_Vid->active_pps->weighted_bipred_idc == 1) { for (i=0; i<currSlice->num_ref_idx_active[LIST_1]; i++) { luma_weight_flag_l1 = u_1("SH: luma_weight_flag_l1", currStream); if (luma_weight_flag_l1) { currSlice->wp_weight[1][i][0] = se_v ("SH: luma_weight_l1", currStream); currSlice->wp_offset[1][i][0] = se_v ("SH: luma_offset_l1", currStream); currSlice->wp_offset[1][i][0] = currSlice->wp_offset[1][i][0]<<(p_Vid->bitdepth_luma-8); } else { currSlice->wp_weight[1][i][0] = 1<<currSlice->luma_log2_weight_denom; currSlice->wp_offset[1][i][0] = 0; } if (active_sps->chroma_format_idc != 0) { chroma_weight_flag_l1 = u_1 ("SH: chroma_weight_flag_l1", currStream); for (j=1; j<3; j++) { if (chroma_weight_flag_l1) { currSlice->wp_weight[1][i][j] = se_v("SH: chroma_weight_l1", currStream); currSlice->wp_offset[1][i][j] = se_v("SH: chroma_offset_l1", currStream); currSlice->wp_offset[1][i][j] = currSlice->wp_offset[1][i][j]<<(p_Vid->bitdepth_chroma-8); } else { currSlice->wp_weight[1][i][j] = 1<<currSlice->chroma_log2_weight_denom; currSlice->wp_offset[1][i][j] = 0; } } } } } }
/*! ************************************************************************ * \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; }
/* ************************************************************************* * 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; }
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; }
static void pred_weight_table( h264_decoder* dec_params) { Slice *currSlice = dec_params->img->currentSlice; DataPartition *partition = &(currSlice->partArr[0]); Bitstream *currStream = partition->bitstream; int luma_weight_flag_l0, luma_weight_flag_l1, chroma_weight_flag_l0, chroma_weight_flag_l1; int i,j; dec_params->img->luma_log2_weight_denom = ue_v ("SH: luma_log2_weight_denom", currStream,dec_params); dec_params->img->wp_round_luma = dec_params->img->luma_log2_weight_denom ? 1<<(dec_params->img->luma_log2_weight_denom - 1): 0; dec_params->img->chroma_log2_weight_denom = ue_v ("SH: chroma_log2_weight_denom", currStream,dec_params); dec_params->img->wp_round_chroma = dec_params->img->chroma_log2_weight_denom ? 1<<(dec_params->img->chroma_log2_weight_denom - 1): 0; reset_wp_params(dec_params->img); for (i=0; i<dec_params->img->num_ref_idx_l0_active; i++) { luma_weight_flag_l0 = u_1("SH: luma_weight_flag_l0", currStream,dec_params); if (luma_weight_flag_l0) { dec_params->img->apply_weights_luma = 1; dec_params->img->wp_weight[0][i][0] = se_v ("SH: luma_weight_l0", currStream,dec_params); dec_params->img->wp_offset[0][i][0] = se_v ("SH: luma_offset_l0", currStream,dec_params); } else { dec_params->img->wp_weight[0][i][0] = 1<<dec_params->img->luma_log2_weight_denom; dec_params->img->wp_offset[0][i][0] = 0; } //if (dec_params->active_sps->chroma_format_idc != 0) { chroma_weight_flag_l0 = u_1 ("SH: chroma_weight_flag_l0", currStream,dec_params); for (j=1; j<3; j++) { if (chroma_weight_flag_l0) { dec_params->img->wp_weight[0][i][j] = se_v("SH: chroma_weight_l0", currStream,dec_params); dec_params->img->wp_offset[0][i][j] = se_v("SH: chroma_offset_l0", currStream,dec_params); dec_params->img->apply_weights_chr = 1; } else { dec_params->img->wp_weight[0][i][j] = 1<<dec_params->img->chroma_log2_weight_denom; dec_params->img->wp_offset[0][i][j] = 0; } } } } if ((dec_params->img->type == B_SLICE) && dec_params->active_pps->weighted_bipred_idc == 1) { for (i=0; i<dec_params->img->num_ref_idx_l1_active; i++) { luma_weight_flag_l1 = u_1("SH: luma_weight_flag_l1", currStream,dec_params); if (luma_weight_flag_l1) { dec_params->img->wp_weight[1][i][0] = se_v ("SH: luma_weight_l1", currStream,dec_params); dec_params->img->wp_offset[1][i][0] = se_v ("SH: luma_offset_l1", currStream,dec_params); dec_params->img->apply_weights_luma =1; } else { dec_params->img->wp_weight[1][i][0] = 1<<dec_params->img->luma_log2_weight_denom; dec_params->img->wp_offset[1][i][0] = 0; } //if (dec_params->active_sps->chroma_format_idc != 0) { chroma_weight_flag_l1 = u_1 ("SH: chroma_weight_flag_l1", currStream,dec_params); for (j=1; j<3; j++) { if (chroma_weight_flag_l1) { dec_params->img->wp_weight[1][i][j] = se_v("SH: chroma_weight_l1", currStream,dec_params); dec_params->img->wp_offset[1][i][j] = se_v("SH: chroma_offset_l1", currStream,dec_params); dec_params->img->apply_weights_chr = 1; } else { dec_params->img->wp_weight[1][i][j] = 1<<dec_params->img->chroma_log2_weight_denom; dec_params->img->wp_offset[1][i][j] = 0; } } } } } }
/*********************************************************************** *\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 * read the weighted prediction tables ************************************************************************ */ static void pred_weight_table() { Slice *currSlice = img->currentSlice; int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; DataPartition *partition = &(currSlice->partArr[dP_nr]); Bitstream *currStream = partition->bitstream; int luma_weight_flag_l0, luma_weight_flag_l1, chroma_weight_flag_l0, chroma_weight_flag_l1; int i,j; img->luma_log2_weight_denom = ue_v ("SH: luma_log2_weight_denom", currStream); img->wp_round_luma = img->luma_log2_weight_denom ? 1<<(img->luma_log2_weight_denom - 1): 0; if ( 0 != active_sps->chroma_format_idc) { img->chroma_log2_weight_denom = ue_v ("SH: chroma_log2_weight_denom", currStream); img->wp_round_chroma = img->chroma_log2_weight_denom ? 1<<(img->chroma_log2_weight_denom - 1): 0; } reset_wp_params(img); for (i=0; i<img->num_ref_idx_l0_active; i++) { luma_weight_flag_l0 = u_1("SH: luma_weight_flag_l0", currStream); if (luma_weight_flag_l0) { img->wp_weight[0][i][0] = se_v ("SH: luma_weight_l0", currStream); img->wp_offset[0][i][0] = se_v ("SH: luma_offset_l0", currStream); } else { img->wp_weight[0][i][0] = 1<<img->luma_log2_weight_denom; img->wp_offset[0][i][0] = 0; } if (active_sps->chroma_format_idc != 0) { chroma_weight_flag_l0 = u_1 ("SH: chroma_weight_flag_l0", currStream); for (j=1; j<3; j++) { if (chroma_weight_flag_l0) { img->wp_weight[0][i][j] = se_v("SH: chroma_weight_l0", currStream); img->wp_offset[0][i][j] = se_v("SH: chroma_offset_l0", currStream); } else { img->wp_weight[0][i][j] = 1<<img->chroma_log2_weight_denom; img->wp_offset[0][i][j] = 0; } } } } if ((img->type == B_SLICE) && active_pps->weighted_bipred_idc == 1) { for (i=0; i<img->num_ref_idx_l1_active; i++) { luma_weight_flag_l1 = u_1("SH: luma_weight_flag_l1", currStream); if (luma_weight_flag_l1) { img->wp_weight[1][i][0] = se_v ("SH: luma_weight_l1", currStream); img->wp_offset[1][i][0] = se_v ("SH: luma_offset_l1", currStream); } else { img->wp_weight[1][i][0] = 1<<img->luma_log2_weight_denom; img->wp_offset[1][i][0] = 0; } if (active_sps->chroma_format_idc != 0) { chroma_weight_flag_l1 = u_1 ("SH: chroma_weight_flag_l1", currStream); for (j=1; j<3; j++) { if (chroma_weight_flag_l1) { img->wp_weight[1][i][j] = se_v("SH: chroma_weight_l1", currStream); img->wp_offset[1][i][j] = se_v("SH: chroma_offset_l1", currStream); } else { img->wp_weight[1][i][j] = 1<<img->chroma_log2_weight_denom; img->wp_offset[1][i][j] = 0; } } } } } }
/*! ************************************************************************ * \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; }