/******************** class scalarsettypedecl ********************/ scalarsettypedecl::scalarsettypedecl(expr * l, int lb) :typedecl(), named(FALSE), lexname(NULL), useless(TRUE) { if (Error.CondError(!type_equal(l->gettype(), inttype), "Only scalarsets of integer size allowed.") || Error.CondError(!l->hasvalue(), "Scalarset size must be constants.") ) { left = lb; right = lb; numbits = 1; if (!args->no_compression) { bitsalloc = numbits; } else { bitsalloc = BYTES(numbits); if (left < 0 || right > 254 || numbits > 8) bitsalloc = 32; } mu_type = (left < 0 || right > 254 || numbits > 8 ? "mu__long" : "mu__byte"); idvalues = symtab->declare(new lexid(tsprintf("scalarset_%u_v_error", scalarset_type_int++), 0), new constdecl(lb++, this)); // it is not set as scalarset variable because it is of size 1. // structure = typedecl::ScalarsetVariable; scalarsetlist = NULL; // to be set when declaring ID : typeExpr } else { // setting size, numbits, left and right // const 0 is used for undefined value --> 0. lb, ... . ub int size = l->getvalue(); if (size < 1) Error.Error("Scalarset size must be greater than zero."); numbits = CeilLog2(l->getvalue() + 1); left = lb; right = left + size - 1; if (!args->no_compression) { bitsalloc = numbits; } else { if (numbits > 31) Error.Error("Internal error, range is too large"); bitsalloc = BYTES(numbits); if (left < 0 || right > 254 || numbits > 8) bitsalloc = 32; } mu_type = (left < 0 || right > 254 || numbits > 8 ? "mu__long" : "mu__byte"); // set id strings // name may be changed if it is later explicitly given a type name int value = left; for (int i = 1; i <= size; i++) { symtab->declare(new lexid(tsprintf("scalarset_%u_v%u", scalarset_type_int, i), 0), new constdecl(value++, this)); } idvalues = symtab->getscope(); if (size > 1) // scalarset of size 1 is treated as normal enum structure = typedecl::ScalarsetVariable; scalarsetlist = NULL; // to be set when declaring ID : typeExpr } }
/******************** class subrangetypedecl ********************/ subrangetypedecl::subrangetypedecl(int left, int right, typedecl * parent) :typedecl(), left(left), right(right), parent(parent) { // 0 is used for undefined value --> 0. lb, ... . ub numbits = CeilLog2(right - left + 2); if (!args->no_compression) { bitsalloc = numbits; } else { if (numbits > 31) Error.Error("Internal error, range is too large"); bitsalloc = BYTES(numbits); if (left < 0 || right > 254 || numbits > 8) bitsalloc = 32; } mu_type = (left < 0 || right > 254 || numbits > 8 ? "mu__long" : "mu__byte"); }
subrangetypedecl::subrangetypedecl(expr * left, expr * right) : typedecl() { if (Error.CondError(!type_equal(left->gettype(), inttype), "Only integer subranges allowed.") || Error.CondError(!type_equal(right->gettype(), inttype), "Only integer subranges allowed.") || Error.CondError(!left->hasvalue(), "Subrange bounds must be constants.") || Error.CondError(!right->hasvalue(), "Subrange bounds must be constants.") || Error.CondError(right->getvalue() < left->getvalue(), "Upper bound of subrange less than lower bound.") ) { this->left = 0; this->right = 1; this->numbits = 1; if (!args->no_compression) { this->bitsalloc = this->numbits; } else { this->bitsalloc = BYTES(this->numbits); } this->parent = inttype; } else { this->left = left->getvalue(); this->right = right->getvalue(); // 0 is used for undefined value --> 0. lb, ... . ub this->numbits = CeilLog2(right->getvalue() - left->getvalue() + 2); if (this->numbits > 31) Error.Error("Internal error, range is too large"); if (!args->no_compression) { this->bitsalloc = this->numbits; } else { this->bitsalloc = BYTES(this->numbits); if (this->left < 0 || this->right > 254 || numbits > 8) this->bitsalloc = 32; } this->parent = left->gettype(); // more general than inttype, though not yet necessary. } mu_type = (left->getvalue() < 0 || right->getvalue() > 254 || numbits > 8 ? "mu__long" : "mu__byte"); }
/******************** class enumtypedecl ********************/ enumtypedecl::enumtypedecl(int l, int r) :typedecl(), left(l), right(r) { // shift = (left > 1 ? left-1 : 0); // this->left -= shift; // this->right -= shift; // 0 is used for undefined value --> 0. lb, ... . ub numbits = CeilLog2(right - left + 2); if (!args->no_compression) { bitsalloc = numbits; } else { if (numbits > 31) Error.Error("Internal error, range is too large"); bitsalloc = BYTES(numbits); if (left < 0 || right > 254 || numbits > 8) bitsalloc = 32; } mu_type = (left < 0 || right > 254 || numbits > 8 ? "mu__long" : "mu__byte"); }
/******************** class uniontypedecl ********************/ uniontypedecl::uniontypedecl(stelist * unionmembers) : typedecl(), unionmembers(unionmembers), useless(TRUE) { stelist *s; typedecl *d; int sumsize = 0; // get total size for (s = unionmembers; s != NULL; s = s->next) { sumsize += ((scalarsettypedecl *) (s->s->getvalue()))->getsize(); } size = sumsize; // 0 is used for undefined value --> 0. lb, ... . ub numbits = CeilLog2(size + 1); if (!args->no_compression) { bitsalloc = numbits; } else { bitsalloc = MULTIPL8(numbits); if (size > 254 || numbits > 8) bitsalloc = MULTIPL32(numbits); } mu_type = (size > 254 || numbits > 8 ? "mu__long" : "mu__byte"); // check the existance of scalarset member with size > 1 for (s = unionmembers; s != NULL; s = s->next) { d = (typedecl *) s->s->getvalue(); if (d->gettypeclass() == typedecl::Scalarset && d->getsize() > 1) structure = typedecl::ScalarsetVariable; } scalarsetlist = unionmembers; unionwithscalarset = FALSE; for (stelist * member = unionmembers; member != NULL; member = member->next) if (((typedecl *) member->s->getvalue())->gettypeclass() == typedecl::Scalarset) unionwithscalarset = TRUE; }
/*! *********************************************************************** * \brief * Checks the input parameters for consistency. *********************************************************************** */ static void PatchInp () { int bitdepth_qp_scale = 6*(input->BitDepthLuma - 8); // These variables are added for FMO FILE * sgfile=NULL; int i,j; int frame_mb_only; int mb_width, mb_height, mapunit_height; int storedBplus1; TestEncoderParams(bitdepth_qp_scale); if (input->FrameRate == 0.0) input->FrameRate = INIT_FRAME_RATE; // Set block sizes // Skip/Direct16x16 input->part_size[0][0] = 4; input->part_size[0][1] = 4; // 16x16 input->part_size[1][0] = 4; input->part_size[1][1] = 4; // 16x8 input->part_size[2][0] = 4; input->part_size[2][1] = 2; // 8x16 input->part_size[3][0] = 2; input->part_size[3][1] = 4; // 8x8 input->part_size[4][0] = 2; input->part_size[4][1] = 2; // 8x4 input->part_size[5][0] = 2; input->part_size[5][1] = 1; // 4x8 input->part_size[6][0] = 1; input->part_size[6][1] = 2; // 4x4 input->part_size[7][0] = 1; input->part_size[7][1] = 1; for (j = 0; j<8;j++) { for (i = 0; i<2; i++) { input->blc_size[j][i] = input->part_size[j][i] * BLOCK_SIZE; } } // set proper log2_max_frame_num_minus4. storedBplus1 = (input->BRefPictures ) ? input->successive_Bframe + 1: 1; if (input->Log2MaxFNumMinus4 == -1) log2_max_frame_num_minus4 = Clip3(0,12, (int) (CeilLog2(input->no_frames * storedBplus1) - 4)); else log2_max_frame_num_minus4 = input->Log2MaxFNumMinus4; if (log2_max_frame_num_minus4 == 0 && input->num_ref_frames == 16) { snprintf(errortext, ET_SIZE, " NumberReferenceFrames=%d and Log2MaxFNumMinus4=%d may lead to an invalid value of frame_num.", input->num_ref_frames, input-> Log2MaxFNumMinus4); error (errortext, 500); } // set proper log2_max_pic_order_cnt_lsb_minus4. if (input->Log2MaxPOCLsbMinus4 == - 1) log2_max_pic_order_cnt_lsb_minus4 = Clip3(0,12, (int) (CeilLog2( 2*input->no_frames * (input->jumpd + 1)) - 4)); else log2_max_pic_order_cnt_lsb_minus4 = input->Log2MaxPOCLsbMinus4; if (((1<<(log2_max_pic_order_cnt_lsb_minus4 + 3)) < input->jumpd * 4) && input->Log2MaxPOCLsbMinus4 != -1) error("log2_max_pic_order_cnt_lsb_minus4 might not be sufficient for encoding. Increase value.",400); // B picture consistency check if(input->successive_Bframe > input->jumpd) { snprintf(errortext, ET_SIZE, "Number of B-frames %d can not exceed the number of frames skipped", input->successive_Bframe); error (errortext, 400); } // Direct Mode consistency check if(input->successive_Bframe && input->direct_spatial_mv_pred_flag != DIR_SPATIAL && input->direct_spatial_mv_pred_flag != DIR_TEMPORAL) { snprintf(errortext, ET_SIZE, "Unsupported direct mode=%d, use TEMPORAL=0 or SPATIAL=1", input->direct_spatial_mv_pred_flag); error (errortext, 400); } if (input->PicInterlace>0 || input->MbInterlace>0) { if (input->directInferenceFlag==0) printf("\nDirectInferenceFlag set to 1 due to interlace coding."); input->directInferenceFlag=1; } if (input->PicInterlace>0) { if (input->IntraBottom!=0 && input->IntraBottom!=1) { snprintf(errortext, ET_SIZE, "Incorrect value %d for IntraBottom. Use 0 (disable) or 1 (enable).", input->IntraBottom); error (errortext, 400); } } // Cabac/UVLC consistency check if (input->symbol_mode != UVLC && input->symbol_mode != CABAC) { snprintf (errortext, ET_SIZE, "Unsupported symbol mode=%d, use UVLC=0 or CABAC=1",input->symbol_mode); error (errortext, 400); } // Open Files if ((p_in=open(input->infile, OPENFLAGS_READ))==-1) { snprintf(errortext, ET_SIZE, "Input file %s does not exist",input->infile); error (errortext, 500); } if (strlen (input->ReconFile) > 0 && (p_dec=open(input->ReconFile, OPENFLAGS_WRITE, OPEN_PERMISSIONS))==-1) { snprintf(errortext, ET_SIZE, "Error open file %s", input->ReconFile); error (errortext, 500); } #if TRACE if (strlen (input->TraceFile) > 0 && (p_trace=fopen(input->TraceFile,"w"))==NULL) { snprintf(errortext, ET_SIZE, "Error open file %s", input->TraceFile); error (errortext, 500); } #endif if (input->img_width % 16 != 0) { img->auto_crop_right = 16-(input->img_width % 16); } else { img->auto_crop_right=0; } if (input->PicInterlace || input->MbInterlace) { if (input->img_height % 2 != 0) { error ("even number of lines required for interlaced coding", 500); } if (input->img_height % 32 != 0) { img->auto_crop_bottom = 32-(input->img_height % 32); } else { img->auto_crop_bottom=0; } } else { if (input->img_height % 16 != 0) { img->auto_crop_bottom = 16-(input->img_height % 16); } else { img->auto_crop_bottom=0; } } if (img->auto_crop_bottom || img->auto_crop_right) { printf ("Warning: Automatical cropping activated: Coded frame Size: %dx%d\n", input->img_width+img->auto_crop_right, input->img_height+img->auto_crop_bottom); } /* // add check for MAXSLICEGROUPIDS if(input->num_slice_groups_minus1>=MAXSLICEGROUPIDS) { snprintf(errortext, ET_SIZE, "num_slice_groups_minus1 exceeds MAXSLICEGROUPIDS"); error (errortext, 500); } */ // Following codes are to read slice group configuration from SliceGroupConfigFileName for slice group type 0,2 or 6 if( (input->num_slice_groups_minus1!=0)&& ((input->slice_group_map_type == 0) || (input->slice_group_map_type == 2) || (input->slice_group_map_type == 6)) ) { if (strlen (input->SliceGroupConfigFileName) > 0 && (sgfile=fopen(input->SliceGroupConfigFileName,"r"))==NULL) { snprintf(errortext, ET_SIZE, "Error open file %s", input->SliceGroupConfigFileName); error (errortext, 500); } else { if (input->slice_group_map_type == 0) { input->run_length_minus1=(int *)malloc(sizeof(int)*(input->num_slice_groups_minus1+1)); if (NULL==input->run_length_minus1) no_mem_exit("PatchInp: input->run_length_minus1"); // each line contains one 'run_length_minus1' value for(i=0;i<=input->num_slice_groups_minus1;i++) { fscanf(sgfile,"%d",(input->run_length_minus1+i)); fscanf(sgfile,"%*[^\n]"); } } else if (input->slice_group_map_type == 2) { input->top_left=(int *)malloc(sizeof(int)*input->num_slice_groups_minus1); input->bottom_right=(int *)malloc(sizeof(int)*input->num_slice_groups_minus1); if (NULL==input->top_left) no_mem_exit("PatchInp: input->top_left"); if (NULL==input->bottom_right) no_mem_exit("PatchInp: input->bottom_right"); // every two lines contain 'top_left' and 'bottom_right' value for(i=0;i<input->num_slice_groups_minus1;i++) { fscanf(sgfile,"%d",(input->top_left+i)); fscanf(sgfile,"%*[^\n]"); fscanf(sgfile,"%d",(input->bottom_right+i)); fscanf(sgfile,"%*[^\n]"); } } else if (input->slice_group_map_type == 6) { int tmp; frame_mb_only = !(input->PicInterlace || input->MbInterlace); mb_width= (input->img_width+img->auto_crop_right)/16; mb_height= (input->img_height+img->auto_crop_bottom)/16; mapunit_height=mb_height/(2-frame_mb_only); input->slice_group_id=(byte * ) malloc(sizeof(byte)*mapunit_height*mb_width); if (NULL==input->slice_group_id) no_mem_exit("PatchInp: input->slice_group_id"); // each line contains slice_group_id for one Macroblock for (i=0;i<mapunit_height*mb_width;i++) { fscanf(sgfile,"%d", &tmp); input->slice_group_id[i]= (byte) tmp; if ( *(input->slice_group_id+i) > input->num_slice_groups_minus1 ) { snprintf(errortext, ET_SIZE, "Error read slice group information from file %s", input->SliceGroupConfigFileName); error (errortext, 500); } fscanf(sgfile,"%*[^\n]"); } } fclose(sgfile); } } if (input->PyramidRefReorder && input->PyramidCoding && (input->PicInterlace || input->MbInterlace)) { snprintf(errortext, ET_SIZE, "PyramidRefReorder Not supported with Interlace encoding methods\n"); error (errortext, 400); } if (input->PocMemoryManagement && input->PyramidCoding && (input->PicInterlace || input->MbInterlace)) { snprintf(errortext, ET_SIZE, "PocMemoryManagement not supported with Interlace encoding methods\n"); error (errortext, 400); } // frame/field consistency check if (input->PicInterlace != FRAME_CODING && input->PicInterlace != ADAPTIVE_CODING && input->PicInterlace != FIELD_CODING) { snprintf (errortext, ET_SIZE, "Unsupported PicInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",input->PicInterlace); error (errortext, 400); } // frame/field consistency check if (input->MbInterlace != FRAME_CODING && input->MbInterlace != ADAPTIVE_CODING && input->MbInterlace != FIELD_CODING) { snprintf (errortext, ET_SIZE, "Unsupported MbInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",input->MbInterlace); error (errortext, 400); } if ((!input->rdopt)&&(input->MbInterlace)) { snprintf(errortext, ET_SIZE, "MB AFF is not compatible with non-rd-optimized coding."); error (errortext, 500); } if (input->rdopt>2) { snprintf(errortext, ET_SIZE, "RDOptimization=3 mode has been deactivated do to diverging of real and simulated decoders."); error (errortext, 500); } // check RDoptimization mode and profile. FMD does not support Frex Profiles. if (input->rdopt==2 && input->ProfileIDC>=FREXT_HP) { snprintf(errortext, ET_SIZE, "Fast Mode Decision methods does not support FREX Profiles"); error (errortext, 500); } // the two HEX FME schemes support FAST Subpel ME. EPZS does not but works fine with // Hadamard reduction with similar speed up. Subpel FME may be added at a later stage // for this scheme for further speed increase. if (input->hadamard == 2 && input->FMEnable != 0 && input->FMEnable != 3) { snprintf(errortext, ET_SIZE, "UseHadamard=2 is not allowed when UseFME is set to 1 or 2."); error (errortext, 500); } // Tian Dong: May 31, 2002 // The number of frames in one sub-seq in enhanced layer should not exceed // the number of reference frame number. if ( input->NumFramesInELSubSeq >= input->num_ref_frames || input->NumFramesInELSubSeq < 0 ) { snprintf(errortext, ET_SIZE, "NumFramesInELSubSeq (%d) is out of range [0,%d).", input->NumFramesInELSubSeq, input->num_ref_frames); error (errortext, 500); } // Tian Dong: Enhanced GOP is not supported in bitstream mode. September, 2002 if ( input->NumFramesInELSubSeq > 0 && input->of_mode == PAR_OF_ANNEXB ) { snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in bitstream mode and RTP mode yet."); error (errortext, 500); } // Tian Dong (Sept 2002) // The AFF is not compatible with spare picture for the time being. if ((input->PicInterlace || input->MbInterlace) && input->SparePictureOption == TRUE) { snprintf(errortext, ET_SIZE, "AFF is not compatible with spare picture."); error (errortext, 500); } // Only the RTP mode is compatible with spare picture for the time being. if (input->of_mode != PAR_OF_RTP && input->SparePictureOption == TRUE) { snprintf(errortext, ET_SIZE, "Only RTP output mode is compatible with spare picture features."); error (errortext, 500); } if( (input->WeightedPrediction > 0 || input->WeightedBiprediction > 0) && (input->MbInterlace)) { printf("Weighted prediction coding is not supported for MB AFF currently."); error (errortext, 500); } if ( input->NumFramesInELSubSeq > 0 && input->WeightedPrediction > 0) { snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in weighted prediction coding mode yet."); error (errortext, 500); } //! the number of slice groups is forced to be 1 for slice group type 3-5 if(input->num_slice_groups_minus1 > 0) { if( (input->slice_group_map_type >= 3) && (input->slice_group_map_type<=5) ) input->num_slice_groups_minus1 = 1; } // Rate control if(input->RCEnable) { if ( ((input->img_height+img->auto_crop_bottom)*(input->img_width+img->auto_crop_right)/256)%input->basicunit!=0) { snprintf(errortext, ET_SIZE, "Frame size in macroblocks must be a multiple of BasicUnit."); error (errortext, 500); } } if ((input->successive_Bframe)&&(input->BRefPictures)&&(input->idr_enable)&&(input->intra_period)&&(input->pic_order_cnt_type!=0)) { error("Stored B pictures combined with IDR pictures only supported in Picture Order Count type 0\n",-1000); } if( !input->direct_spatial_mv_pred_flag && input->num_ref_frames<2 && input->successive_Bframe >0) error("temporal direct needs at least 2 ref frames\n",-1000); // frext if(input->Transform8x8Mode && input->sp_periodicity /*SP-frames*/) { snprintf(errortext, ET_SIZE, "\nThe new 8x8 mode is not implemented for sp-frames."); error (errortext, 500); } if(input->Transform8x8Mode && (input->ProfileIDC<FREXT_HP || input->ProfileIDC>FREXT_Hi444)) { snprintf(errortext, ET_SIZE, "\nTransform8x8Mode may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444); error (errortext, 500); } if(input->ScalingMatrixPresentFlag && (input->ProfileIDC<FREXT_HP || input->ProfileIDC>FREXT_Hi444)) { snprintf(errortext, ET_SIZE, "\nScalingMatrixPresentFlag may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444); error (errortext, 500); } if(input->yuv_format==YUV422 && input->ProfileIDC < FREXT_Hi422) { snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV422 can be used only with ProfileIDC %d or %d\n",FREXT_Hi422, FREXT_Hi444); error (errortext, 500); } if(input->yuv_format==YUV444 && input->ProfileIDC < FREXT_Hi444) { snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV444 can be used only with ProfileIDC %d.\n",FREXT_Hi444); error (errortext, 500); } // Residue Color Transform if(input->yuv_format!=YUV444 && input->residue_transform_flag) { snprintf(errortext, ET_SIZE, "\nResidue color transform is supported only in YUV444."); error (errortext, 500); } if ((input->BiPredMotionEstimation) && (input->search_range < input->BiPredMESearchRange)) { snprintf(errortext, ET_SIZE, "\nBiPredMESearchRange must be smaller or equal SearchRange."); error (errortext, 500); } if (input->EnableOpenGOP) input->PyramidRefReorder = 1; if (input->EnableOpenGOP && input->PicInterlace) { snprintf(errortext, ET_SIZE, "Open Gop currently not supported for Field coded pictures."); error (errortext, 500); } ProfileCheck(); LevelCheck(); }
/*! ************************************************************************ * \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; }
/*********************************************************************** *\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 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 = read_u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream, &p_Dec->UsedBits); /* 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 = read_u_1("SH: field_pic_flag", currStream, &p_Dec->UsedBits); if (currSlice->field_pic_flag) { // bottom_field_flag u(1) currSlice->bottom_field_flag = (byte) read_u_1("SH: bottom_field_flag", currStream, &p_Dec->UsedBits); 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 (currSlice->structure == FRAME ) assert (currSlice->field_pic_flag == 0); if (currSlice->structure == TOP_FIELD ) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == FALSE)); if (currSlice->structure == BOTTOM_FIELD) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == TRUE )); if (currSlice->idr_flag) { currSlice->idr_pic_id = read_ue_v("SH: idr_pic_id", currStream, &p_Dec->UsedBits); } #if (MVC_EXTENSION_ENABLE) else if ( currSlice->svc_extension_flag == 0 && currSlice->NaluHeaderMVCExt.non_idr_flag == 0 ) { currSlice->idr_pic_id = read_ue_v("SH: idr_pic_id", currStream, &p_Dec->UsedBits); } #endif if (active_sps->pic_order_cnt_type == 0) { currSlice->pic_order_cnt_lsb = read_u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream, &p_Dec->UsedBits); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt_bottom = read_se_v("SH: delta_pic_order_cnt_bottom", currStream, &p_Dec->UsedBits); 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 ] = read_se_v("SH: delta_pic_order_cnt[0]", currStream, &p_Dec->UsedBits); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt[ 1 ] = read_se_v("SH: delta_pic_order_cnt[1]", currStream, &p_Dec->UsedBits); 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 = read_ue_v ("SH: redundant_pic_cnt", currStream, &p_Dec->UsedBits); } if(currSlice->slice_type == B_SLICE) { currSlice->direct_spatial_mv_pred_flag = read_u_1 ("SH: direct_spatial_mv_pred_flag", currStream, &p_Dec->UsedBits); } currSlice->num_ref_idx_active[LIST_0] = p_Vid->active_pps->num_ref_idx_l0_default_active_minus1 + 1; currSlice->num_ref_idx_active[LIST_1] = p_Vid->active_pps->num_ref_idx_l1_default_active_minus1 + 1; if(currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE || currSlice->slice_type == B_SLICE) { val = read_u_1 ("SH: num_ref_idx_override_flag", currStream, &p_Dec->UsedBits); if (val) { currSlice->num_ref_idx_active[LIST_0] = 1 + read_ue_v ("SH: num_ref_idx_l0_active_minus1", currStream, &p_Dec->UsedBits); if(currSlice->slice_type == B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 1 + read_ue_v ("SH: num_ref_idx_l1_active_minus1", currStream, &p_Dec->UsedBits); } } } 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&&(currSlice->slice_type == P_SLICE|| currSlice->slice_type == SP_SLICE))|| (p_Vid->active_pps->weighted_bipred_idc==1 && (currSlice->slice_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 && currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE) { currSlice->model_number = read_ue_v("SH: cabac_init_idc", currStream, &p_Dec->UsedBits); } else { currSlice->model_number = 0; } currSlice->slice_qp_delta = val = read_se_v("SH: slice_qp_delta", currStream, &p_Dec->UsedBits); //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(currSlice->slice_type == SP_SLICE || currSlice->slice_type == SI_SLICE) { if(currSlice->slice_type==SP_SLICE) { currSlice->sp_switch = read_u_1 ("SH: sp_for_switch_flag", currStream, &p_Dec->UsedBits); } currSlice->slice_qs_delta = val = read_se_v("SH: slice_qs_delta", currStream, &p_Dec->UsedBits); 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 DPF_PARAM_DISP printf("deblocking_filter_control_present_flag:%d\n", p_Vid->active_pps->deblocking_filter_control_present_flag); #endif if (p_Vid->active_pps->deblocking_filter_control_present_flag) { currSlice->DFDisableIdc = (short) read_ue_v ("SH: disable_deblocking_filter_idc", currStream, &p_Dec->UsedBits); if (currSlice->DFDisableIdc!=1) { currSlice->DFAlphaC0Offset = (short) (2 * read_se_v("SH: slice_alpha_c0_offset_div2", currStream, &p_Dec->UsedBits)); currSlice->DFBetaOffset = (short) (2 * read_se_v("SH: slice_beta_offset_div2", currStream, &p_Dec->UsedBits)); } else { currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } } else { currSlice->DFDisableIdc = currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } #if DPF_PARAM_DISP printf("Slice:%d, DFParameters:(%d,%d,%d)\n\n", currSlice->current_slice_nr, currSlice->DFDisableIdc, currSlice->DFAlphaC0Offset, currSlice->DFBetaOffset); #endif // The conformance point for intra profiles is without deblocking, but decoders are still recommended to filter the output. // We allow in the decoder config to skip the loop filtering. This is achieved by modifying the parameters here. if ( is_HI_intra_only_profile(active_sps->profile_idc, active_sps->constrained_set3_flag) && (p_Inp->intra_profile_deblocking == 0) ) { 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 = read_u_v (len, "SH: slice_group_change_cycle", currStream, &p_Dec->UsedBits); } 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; }
/*! ************************************************************************ * \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; }