www.pudn.com > avs-m3.rar > header.c
/*! ************************************************************************************* * \file * header.c * \brief * seq header/ picture header handling ************************************************************************************* */ #include#include #include "memalloc.h" #include "vlc.h" #include "header.h" #include "annexb.h" #include "parset.h" #include "sei.h" extern FILE *bits; /*! ************************************************************************************* * \brief : * Processing NAl unit to RBSP function ************************************************************************************* */ void NALU2RBSP(NALU_t *nalu,byte *Buf,int *Buf_cur_pos) { memcpy (Buf + *Buf_cur_pos, nalu->buf+1, nalu->len-1); *Buf_cur_pos += (nalu->len-1); } /*! ************************************************************************************* * \brief : * picture header handling including IDR/I/P picture header according to AVS-M FCD * \author * zhan ma EI Depart. of HUST ************************************************************************************* */ void DecodePictureHeader(NALU_t *nalu) { seq_parameter_set *sps_t = NULL; pic_parameter_set *pps_t = NULL; picture_header *p; sps_t = AllocSPS(); pgImage->sps = sps_t; pps_t = AllocPPS(); pgImage->pps = pps_t; p = AllocPicHeader(); picture_header_rbsp = p; /* need to be simplified -- zhan ma */ memcpy (currStream->streamBuffer, nalu->buf+1, nalu->len-1);//WJP FOR NAL currStream->code_len = currStream->bitstream_length = nalu->len-1;//WJP FOR NAL currStream->read_len = currStream->frame_bitoffset = 0;//WJP FOR NAL #if TRACE fprintf(p_trace,"\n"); tracebits2("start_code_prefix",24,0x01); fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n", nalu->len,nalu->forbidden_bit,nalu->nal_reference_idc,nalu->nal_unit_type); tracebits2("PictureHeader: NALU Header",8,nalu->buf[0]); fprintf(p_trace,"\nDecoding picture_header_rbsp\n\n"); #endif picture_header_rbsp->picture_coding_type = u_v(2 , "PictureHeader: picture_coding_type"); // picture_header_rbsp->picture_distance = u_v(8 , "PictureHeader: picture_distance"); picture_header_rbsp->pic_parameter_set_id = ue_v("PictureHeader: pic_parameter_set_id"); pgImage->pps = pps_buf[picture_header_rbsp->pic_parameter_set_id]; pgImage->sps = sps_buf[pgImage->pps->seq_parameter_set_id]; if(picture_header_rbsp->picture_distance == 0) //add by JX 050406 picture_header_rbsp->picture_distance_gap_minus1 = ue_v("PictureHeader: picture_distance_gap_minus1"); picture_header_rbsp->frame_num = u_v (5 , "PictureHeader: frame_num"); picture_header_rbsp->picture_qp = u_v(6 , "PictureHeader: picture_qp"); #ifdef _HRD_ pgImage->picture_distance = picture_header_rbsp->picture_distance; pgImage->picture_distance_gap_minus1 = picture_header_rbsp->picture_distance_gap_minus1; #endif // _HRD_ if(pgImage->pps->loop_filter_parameter_flag) { picture_header_rbsp->alpha_ci_offset = se_v("PictureHeader: alpha_ci_offset"); picture_header_rbsp->cp_offset = se_v("PictureHeader: cp_offset"); picture_header_rbsp->loopfilter_qp_offset = se_v("PictureHeader: qp_offset"); pgImage->loop_filter_alpha_ci_offset = picture_header_rbsp->alpha_ci_offset; pgImage->loop_filter_cp_offset = picture_header_rbsp->cp_offset; pgImage->loop_filter_qp_offset = picture_header_rbsp->loopfilter_qp_offset; } else { pgImage->loop_filter_alpha_ci_offset = 0; pgImage->loop_filter_cp_offset = 0; pgImage->loop_filter_qp_offset = 0; } if(pps->sliding_window_size_flag) /* see FCD 9.3.3 -- zhan ma */ { picture_header_rbsp->sliding_window_size_minus1 = u_v(1 , "PictureHeader: sliding window size minus 1"); pgImage->ssw = 1+picture_header_rbsp->sliding_window_size_minus1; } else pgImage->ssw = 2; /* global decoding indicator definitions */ if(picture_header_rbsp->picture_coding_type == 0) { pgImage->type = I_IMG; if (nalu->nal_unit_type == 2) pgImage->idr_flag = 1; else pgImage->idr_flag = 0; } else { pgImage->type = P_IMG; pgImage->idr_flag = 0; } if(pgImage->idr_flag == 1) /* IDR frame */ { pgImage->active_num_ref_frames = 0; } //!< optional mode - simulate a lower-end decoder that can only decode video with low frame rate //!< if you just want to decode the reference frames, plz active following skip_img_flag! //!< zhan ma -- Sept 1st 2005 //if (!nalu->nal_reference_idc) // pgImage->skip_img_flag = 1; //else // pgImage->skip_img_flag = 0; DecodeTrailingBits(currStream); /* decoding trailing aligned bits in byte format stream */ CheckPictureHeaderValid(picture_header_rbsp,nalu); /* picture header conformance check */ pgImage->delta_time_picture_distance_1 = pgImage->sps->delta_time_picture_distance_1; horizontal_size = (pgImage->sps->horizontal_size_minus1+1)*MB_BLOCK_SIZE; vertical_size = (pgImage->sps->vertical_size_minus1+1)*MB_BLOCK_SIZE; pgImage->width = horizontal_size; pgImage->height = vertical_size; pgImage->width_cr = (pgImage->width>>1); pgImage->height_cr = (pgImage->height>>1); pgImage->PicWidthInMbs = pgImage->width/MB_BLOCK_SIZE; pgImage->PicHeightInMbs = pgImage->height/MB_BLOCK_SIZE; pgImage->PicSizeInMbs = pgImage->PicWidthInMbs * pgImage->PicHeightInMbs; pgImage->max_mb_nr = (pgImage->width * pgImage->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE); pgImage->num_ref_frames = pgImage->sps->num_ref_frames; pgImage->skip_mode_flag = pgImage->pps->skip_mode_flag; pgImage->constrained_intra_pred_flag = pgImage->pps->constrained_intra_pred_flag; pgImage->picture_reference_flag = pgImage->pps->picture_reference_flag; pgImage->half_pixel_mv_flag = pgImage->pps->half_pixel_mv_flag; pgImage->loop_filter_disable_flag = pgImage->pps->loop_filter_disable_flag; pgImage->loop_filter_parameter_flag = pgImage->pps->loop_filter_parameter_flag; fixed_picture_qp_flag = pgImage->pps->fixed_picture_qp_flag; /* bitstream conformance statisitics -- zhan ma */ stat_parameter->constrained_intra_pred_flag = pgImage->constrained_intra_pred_flag; stat_parameter->half_pixel_mv_flag = pgImage->half_pixel_mv_flag; stat_parameter->loop_filter_disable_flag = pgImage->loop_filter_disable_flag; stat_parameter->loop_filter_parameter_flag = pgImage->loop_filter_parameter_flag; stat_parameter->picture_reference_flag = pgImage->picture_reference_flag; stat_parameter->skip_mode_flag = pgImage->skip_mode_flag; /* bistream conformance stat -- zhan ma */ stat_parameter->img_width = pgImage->width; stat_parameter->img_height = pgImage->height; stat_parameter->frame_cropping_flag = pgImage->sps->frame_cropping_flag; stat_parameter->delta_time_picture_distance_1 = pgImage->delta_time_picture_distance_1; stat_parameter->frame_skip = (pgImage->delta_time_picture_distance_1/3000 -1); stat_parameter->ref_frame_number = pgImage->num_ref_frames; pgImage->pic_ref_flag = (!nalu->nal_reference_idc); //!< frames/picture reference flag indicator picture_qp = picture_header_rbsp->picture_qp; pgImage->qp = picture_header_rbsp->picture_qp; previous_qp = pgImage->qp; /* picture qp initialization */ /* bistream conformance check -- zhan ma*/ stat_parameter->alpha_ci_offset = pgImage->loop_filter_alpha_ci_offset; stat_parameter->cp_offset = pgImage->loop_filter_cp_offset; stat_parameter->loop_fiter_qp_offset = pgImage->loop_filter_qp_offset; FreePicHeader(picture_header_rbsp); } /*! ************************************************************************************* * \brief : * picture Header handling * \author * zhan ma ************************************************************************************* */ /* void DecodeSliceHeader(Bitstream *stream) { int first_mb_nr_in_slice,slice_delta_qp; first_mb_nr_in_slice = ue_v("SliceHeader: first_mb_nr_in_slice"); if(!fixed_picture_qp_flag) { fixed_slice_qp_flag = u_v(1,"SliceHeader: fixed_slice_qp"); slice_delta_qp = se_v("SliceHeader: slice_delta_qp"); previous_qp = pgImage->qp + slice_delta_qp; // zhan ma 0714 } else fixed_slice_qp_flag = 1; // zhan ma 0714 if(!pgImage->loop_filter_disable_flag) { pgImage->disable_loop_filter_slice_flag = u_v(1,"SliceHeader: disable_loop_filter_slice_flag"); } } void DecodeSliceData(Bitstream *stream) { while (pgImage->current_mb_nr PicSizeInMbs) { #if TRACE // Here was the slice nr from the mb_data used. This slice number is only set after // the reconstruction of an MB and hence here not yet valid fprintf(p_trace,"\n*********** Pic: %i (I/P) MB: %i Slice: %i Type %d **********\n", pgImage->number, pgImage->current_mb_nr, pgImage->current_slice_nr, pgImage->type); fflush(p_trace); #endif // Initializes the current macroblock start_macroblock(); // Get the syntax elements from the NAL read_one_macroblock(); // decode one macroblock decode_one_macroblock(); mb_data[pgImage->current_mb_nr].lf_alpha_c0_offset=-2; mb_data[pgImage->current_mb_nr].lf_beta_offset=-1; mb_data[pgImage->current_mb_nr].cbp_blk=0; pgImage->current_mb_nr++; previous_qp = pgcurrMB->qp; } } void DecodeSlice(NALU_t *nalu) { memcpy (currStream->streamBuffer, nalu->buf+1, nalu->len-1);//WJP FOR NAL currStream->code_len = currStream->bitstream_length = nalu->len-1;//WJP FOR NAL currStream->read_len = currStream->frame_bitoffset = 0;//WJP FOR NAL pgImage->current_slice_nr = 0; DecodeSliceHeader(currStream); DecodeSliceData(currStream); } */ /*! ************************************************************************************* * \brief : * Reads new slice from bit_stream ************************************************************************************* */ int read_new_byte_stream() { byte *Buf; int Buf_cur_pos=0; int next_nalu_type; int i,slice_num=0; Slice_Enable=1; for(i=0;i<176;i++) { Position_of_Slice_in_Picbuff[i]=0; } nalu = AllocNALU(MAX_CODED_FRAME_SIZE);//pgImage->width * pgImage->height * 4 if ((Buf = (char*)calloc (MAX_CODED_FRAME_SIZE , sizeof(byte))) == NULL) no_mem_exit("GetAnnexbNALU: Buf"); while (1) { GetOneUnit(nalu,&next_nalu_type); //! nal_unit_type) { case NALU_TYPE_SPS: SequenceParameterSet(nalu); break; case NALU_TYPE_PPS: PictureParameterSet(nalu); break; case NALU_TYPE_IDR: DecodePictureHeader(nalu); break; case NALU_TYPE_P_HEADER: DecodePictureHeader(nalu); break; case NALU_TYPE_SLICE: Position_of_Slice_in_Picbuff[slice_num++]=Buf_cur_pos; NALU2RBSP(nalu,Buf,&Buf_cur_pos); if(next_nalu_type == NALU_TYPE_SLICE) break; else { memcpy (currStream->streamBuffer, Buf, Buf_cur_pos); currStream->code_len = currStream->bitstream_length = Buf_cur_pos; currStream->read_len = currStream->frame_bitoffset = 0; //decode_picture_header(Buf,Buf_cur_pos); FreeNALU(nalu); free(Buf); if(next_nalu_type== -1)//end of bitstream return LPOS; else return SOP; } case NALU_TYPE_SEI: InterpretSEIMessage(nalu->buf, nalu->len, pgImage); break; case NALU_TYPE_RAPI: //JX 050406 printf("random acess point indicator unit detected\n"); break; default: printf("Can't find start code\n"); FreeNALU(nalu); free(Buf); return EOS; } } } #ifdef _HRD_ /*! ************************************************************************************* * \brief : * hrd_parameters ************************************************************************************* */ void hrd_parameters(seq_parameter_set *sps) { sps->initial_cpb_removal_delay_length = u_v(5, "SPS: initial_cpb_removal_delay_length"); sps->initial_dpb_output_delay_length = u_v(5, "SPS: initial_dpb_output_delay_length"); sps->bit_rate_scale = u_v(4, "SPS: bit_rate_scale"); sps->cpb_size_scale = u_v(4, "SPS: cpb_size_scale"); sps->dpb_size_scale = u_v(4, "SPS: dpb_size_scale"); } #endif // _HRD_ /*! ************************************************************************************* * \brief : * sequence header parseting according AVS-M FCD * \notes: * Add SPS indicator to trace file by Zhan MA ************************************************************************************* */ void SequenceParameterSet (NALU_t *nalu) { int profile_idc,level_idc,seq_parameter_set_id; seq_parameter_set *p = NULL; p = AllocSPS(); sps = p; #if TRACE fprintf(p_trace,"\n"); tracebits2("start_code_prefix",24,0x01); fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n", nalu->len,nalu->forbidden_bit,nalu->nal_reference_idc,nalu->nal_unit_type); tracebits2("SPS: NALU Header",8,nalu->buf[0]); fprintf(p_trace,"\nDecoding seq_parameter_set_rbsp\n\n"); #endif /* NALU to RBSP */ memcpy (currStream->streamBuffer, nalu->buf+1, nalu->len-1);//WJP FOR NAL currStream->code_len = currStream->bitstream_length = nalu->len-1;//WJP FOR NAL currStream->read_len = currStream->frame_bitoffset = 0;//WJP FOR NAL profile_idc = u_v(8, "SPS: Profile_idc"); level_idc = u_v(8, "SPS: Level_idc"); seq_parameter_set_id = ue_v("SPS: seq_parameter_set_id"); sps = sps_buf[seq_parameter_set_id]; sps->profile_idc = profile_idc; sps->level_idc = level_idc; sps->seq_parameter_set_id = seq_parameter_set_id; sps->delta_time_picture_distance_1 = u_v(16 , "SPS: delta_time_picture_distance_1"); sps->num_ref_frames = ue_v("SPS: num_ref_frames"); sps->horizontal_size_minus1 = ue_v("SPS: horizontal_size_minus1"); sps->vertical_size_minus1 = ue_v("SPS: vertical_size_minus1"); sps->aspect_ratio = u_v(4, "SPS: aspect_ratio"); sps->frame_cropping_flag = u_v(1, "SPS: frame_cropping_flag"); if(sps->frame_cropping_flag ) { sps->frame_cropping_left_offset = ue_v("SPS: frame_cropping_left_offset"); sps->frame_crop_right_offset = ue_v("SPS: frame_cropping_right_offset"); sps->frame_crop_top_offset = ue_v("SPS: frame_cropping_top_offset"); sps->frame_crop_bottom_offset = ue_v("SPS: frame_cropping_bottom_offset"); } sps->hrd_parameters_present_flag = u_v(1,"SPS: hrd_par_present_flag"); //may be bugs here #ifdef _HRD_ sps->bit_rate_scale = 4; sps->cpb_size_scale = 6; sps->dpb_size_scale = 6; sps->initial_cpb_removal_delay_length = 24; sps->initial_dpb_output_delay_length = 24; if (sps->hrd_parameters_present_flag) { hrd_parameters(sps); } #endif // _HRD_ DecodeTrailingBits(currStream); CheckSPSValid(sps); /* error report for bistream conformance*/ } /*! ************************************************************************************* * \brief : * PictureParameterSet ************************************************************************************* */ void PictureParameterSet(NALU_t *nalu) { int pic_parameter_set_id; pic_parameter_set *p = NULL; p = AllocPPS(); pps = p; #if TRACE fprintf(p_trace,"\n"); tracebits2("start_code_prefix",24,0x01); fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n", nalu->len,nalu->forbidden_bit,nalu->nal_reference_idc,nalu->nal_unit_type); tracebits2("PPS: NALU Header",8,nalu->buf[0]); fprintf(p_trace,"\nDecoding pic_parameter_set_rbsp\n\n"); #endif memcpy (currStream->streamBuffer, nalu->buf+1, nalu->len-1);//WJP FOR NAL currStream->code_len = currStream->bitstream_length = nalu->len-1;//WJP FOR NAL currStream->read_len = currStream->frame_bitoffset = 0;//WJP FOR NAL pic_parameter_set_id = ue_v("PPS: pic_parameter_set_id"); pps = pps_buf[pic_parameter_set_id]; pps->pic_parameter_set_id = pic_parameter_set_id; pps->seq_parameter_set_id = ue_v("PPS: seq_parameter_set_id"); pps->fixed_picture_qp_flag = u_v(1,"PPS: fixed_picture_qp_flag"); pps->picture_reference_flag = u_v(1,"PPS: picture_reference_flag"); if(!pps->picture_reference_flag) /* if 0 : mb adaptive reference picture selection */ { pps->sliding_window_size_flag = u_v(1,"PPS: sliding window size flag"); } pps->skip_mode_flag = u_v(1,"PPS: skip mode flag"); pps->loop_filter_disable_flag = u_v(1,"PPS: loop filter disable flag"); if(!pps->loop_filter_disable_flag) /* 0 Enable Filter, 1 Diable Filter */ pps->loop_filter_parameter_flag = u_v(1,"PPS: loop filter parameter flag"); else pps->loop_filter_parameter_flag = 0; pps->constrained_intra_pred_flag = u_v(1,"PPS: Constrained Intra Prediction Flag"); pps->half_pixel_mv_flag = u_v(1,"PPS: half_pix_mv_flag"); DecodeTrailingBits(currStream); CheckPPSValid(pps); } /*! ************************************************************************************* * \brief : * ************************************************************************************* */ /* int sign(int a , int b) { int x; x=abs(a); if (b>0) return(x); else return(-x); } */