www.pudn.com > avs-m3.rar > image.c
/*! ************************************************************************************* * \file * image.c * \brief * Decoding a slice * \notes: * upadated @ June 14th 2005 according to the FCD ************************************************************************************* */ #include#include #include //#include #include "header.h" #include "global.h" #include "vlc.h" #include "memalloc.h" extern FILE *bits; extern unsigned int seq_parameter_set_id; extern unsigned int cpb_dpb_cnt_minus1; extern unsigned int *cpb_underflow_allowable_flag; extern unsigned int *bit_rate_value_minus1_lsb; extern unsigned int *bit_rate_value_minus1_msb; extern unsigned int *cpb_size_value_minus1_lsb; extern unsigned int *cpb_size_value_minus1_msb; extern unsigned int *dpb_size_value_minus1_lsb; extern unsigned int *dpb_size_value_minus1_msb; extern unsigned int *initial_cpb_removal_delay_lsb; extern unsigned int *initial_cpb_removal_delay_msb; extern unsigned int *initial_cpb_removal_delay; extern unsigned int *initial_dpb_output_delay_lsb; extern unsigned int *initial_dpb_output_delay_msb; extern unsigned int *initial_dpb_output_delay; extern unsigned int *Bit_Buffer; extern unsigned int *ROT; extern struct DecodedPictureBuffer dpb; extern struct FrameBuffer outframe; extern struct FrameBuffer decframe; extern unsigned int outputtimer; extern int pre_picture_distance; #ifdef _HRD_ #include "HRD.h" #endif // _HRD_ extern void UpdateiREG(); /*! ************************************************************************ * \brief * decodes one I- or P-frame ************************************************************************ */ int decode_one_picture(struct snr_par *snr) { time_t ltime1; // for time measurement time_t ltime2; #ifdef _HRD_ int j, i; int framenum=0; #endif // _HRD_ /* #ifdef WIN32 struct _timeb tstruct1; struct _timeb tstruct2; #else struct timeb tstruct1; struct timeb tstruct2; #endif */ int tmp_time; // time used by decoding the last frame /* #ifdef WIN32 _ftime (&tstruct1); // start time ms #else ftime (&tstruct1); // start time ms #endif time( <ime1 ); // start time s */ init_frame(); //cbzhu 0412 #ifdef _ISOLATED_REGION_ if(iREGenable) { UpdateiREG(); } #endif //_ISOLATED_REGION_ //!< 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 (pgImage->skip_img_flag) // return (SOP); decode_picture_data(); // decoding process DeblockFrame(imgY , imgUV); #ifdef _HRD_ { for (j = 0; j < pgImage->height; j++) for (i = 0; i < pgImage->width; i++) decframe.imgY[j][i] = imgY[j][i]; for (j = 0; j < pgImage->height / 2; j++) for (i = 0; i < pgImage->width / 2; i++) { decframe.imgUV[0][j][i] = imgUV[0][j][i]; decframe.imgUV[1][j][i] = imgUV[1][j][i]; } decframe.frmnum = pgImage->number; decframe.outputted = 0; if (pgImage->type == I_IMG) decframe.used_for_ref = 1; else { if (!pgImage->pic_ref_flag) decframe.used_for_ref = 1; else decframe.used_for_ref = 0; } if (pgImage->number == 0) { decframe.rotvalue = 0; ROT[0] = 0; } else { if (pgImage->type == I_IMG) ROT[pgImage->number] = ROT[pgImage->number - 1] + (pgImage->picture_distance_gap_minus1 + 1) * sps->delta_time_picture_distance_1; else { ROT[pgImage->number] = ROT[pgImage->number - 1] + ((pgImage->picture_distance - pre_picture_distance) % 256) * sps->delta_time_picture_distance_1; // added by yiwang, 2005.7.2 framenum = pgImage->picture_distance - pre_picture_distance; } decframe.rotvalue = ROT[pgImage->number]; pre_picture_distance = pgImage->picture_distance; } outputtimer += pgImage->delta_time_picture_distance_1 * framenum; Store_OneFrame_Into_DPB(&decframe); UpdateRefFrameBufFlag(); } #endif // _HRD_ #if TRACE trace_frame(p_trace,pgImage->width,pgImage->height,imgY,imgUV); #endif /* #ifdef WIN32 _ftime (&tstruct2); //!< end time ms #else ftime (&tstruct2); //!< end time ms #endif */ if (p_ref) find_snr(snr,p_ref); //!< if ref sequence exist time( <ime2 ); // end time sec //tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm); tot_time=tot_time + tmp_time; report_picture(tmp_time); write_frame(p_out); Update_Picture_Buffers(); pgImage->number++; return (SOP); } /*! ************************************************************************ * \brief * ************************************************************************ */ void report_picture(int time_pic) { #ifndef _PSNR_YUV_ if(pgImage->type == I_IMG) // I picture // fprintf(stdout,"%3d(I) %5d %7.4f %7.4f %7.4f %5d\n", pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,time_pic); // else if(pgImage->type == P_IMG) // P pictures fprintf(stdout,"%3d(P) %5d %7.4f %7.4f %7.4f %5d\n", pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,time_pic); #else if(pgImage->type == I_IMG) // I picture // fprintf(stdout,"%3d(I) %5d %7.4f %7.4f %7.4f %7.4f %5d\n", pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,snr->snr_yuv,time_pic); // else if(pgImage->type == P_IMG) // P pictures // fprintf(stdout,"%3d(P) %5d %7.4f %7.4f %7.4f %7.4f %5d\n", pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,snr->snr_yuv, time_pic); // #endif // _PSNR_YUV_ fflush(stdout); } /*! ************************************************************************ * \brief * Find PSNR for all three components.Compare decoded frame with * the original sequence. Read input->jumpd frames to reflect frame skipping. ************************************************************************ */ void find_snr(struct snr_par *snr, //!< pointer to snr parameters FILE *p_ref) //!< filestream to reference YUV file { int i,j; int diff_y,diff_u,diff_v; int uv; int status; #ifdef _PSNR_YUV_ float tmpy, tmpu, tmpv; #endif // _PSNR_YUV_ if(!p_ref) { printf("no ref file!\n"); snr->snr_u = -1; snr->snr_u1 = -1; snr->snr_ua = -1; snr->snr_v = -1; snr->snr_v1 = -1; snr->snr_va = -1; snr->snr_y = -1; snr->snr_y1 = -1; snr->snr_ya = -1; return ; } rewind(p_ref); status = fseek (p_ref, pgImage->number*pgImage->height*pgImage->width*3/2, 0); for (j=0; j < pgImage->height; j++) for (i=0; i < pgImage->width; i++) { imgY_ref[j][i]=fgetc(p_ref); } for (uv=0; uv < 2; uv++) for (j=0; j < pgImage->height_cr ; j++) for (i=0; i < pgImage->width_cr; i++) imgUV_ref[uv][j][i]=fgetc(p_ref); pgImage->quad[0]=0; diff_y=0; for (j=0; j < pgImage->height; ++j) { for (i=0; i < pgImage->width; ++i) { diff_y += pgImage->quad[abs(imgY[j][i]-imgY_ref[j][i])]; } } // Chroma diff_u=0; diff_v=0; for (j=0; j < pgImage->height_cr; ++j) { for (i=0; i < pgImage->width_cr; ++i) { diff_u += pgImage->quad[abs(imgUV_ref[0][j][i]-imgUV[0][j][i])]; diff_v += pgImage->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])]; /* if(pgImage->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])]!=0)//²âÊÔ { printf("x=%d,y=%d\n",i,j); getch(); } */ } } // Collecting SNR statistics if (diff_y != 0) snr->snr_y=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)diff_y)); // luma snr for current frame if (diff_u != 0) snr->snr_u=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_u))); // chroma snr for current frame if (diff_v != 0) snr->snr_v=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_v))); // chroma snr for current frame #ifdef _PSNR_YUV_ tmpy = (float)(4.0 / pow(10, snr->snr_y / 10)); tmpu = (float)(1.0 / pow(10, snr->snr_u / 10)); tmpv = (float)(1.0 / pow(10, snr->snr_v / 10)); snr->snr_yuv = (float)(10 * log10(6 / ( tmpy + tmpu + tmpv ) )); #endif // _PSNR_YUV_ if (pgImage->number == 0) // first { snr->snr_y1=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)diff_y)); // keep luma snr for first frame snr->snr_u1=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_u))); // keep chroma snr for first frame snr->snr_v1=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_v))); // keep chroma snr for first frame snr->snr_ya=snr->snr_y1; snr->snr_ua=snr->snr_u1; snr->snr_va=snr->snr_v1; if (diff_y == 0) snr->snr_ya=50; // need to assign a reasonable large number so avg snr of entire sequece isn't infinite if (diff_u == 0) snr->snr_ua=50; if (diff_v == 0) snr->snr_va=50; #ifdef _PSNR_YUV_ if ( diff_y == 0 && diff_u == 0 && diff_v == 0 ) { snr->snr_yuva = 50; } else { tmpy = (float)(4.0 / pow(10, snr->snr_y1 / 10)); tmpu = (float)(1.0 / pow(10, snr->snr_u1 / 10)); tmpv = (float)(1.0 / pow(10, snr->snr_v1 / 10)); snr->snr_yuva = (float)(10 * log10(6 / ( tmpy + tmpu + tmpv ) )); } #endif // _PSNR_YUV_ } else { snr->snr_ya=(float)(snr->snr_ya*(pgImage->number/*+Bframe_ctr*/)+snr->snr_y)/(pgImage->number/*+Bframe_ctr*/+1); // average snr chroma for all frames snr->snr_ua=(float)(snr->snr_ua*(pgImage->number/*+Bframe_ctr*/)+snr->snr_u)/(pgImage->number/*+Bframe_ctr*/+1); // average snr luma for all frames snr->snr_va=(float)(snr->snr_va*(pgImage->number/*+Bframe_ctr*/)+snr->snr_v)/(pgImage->number/*+Bframe_ctr*/+1); // average snr luma for all frames #ifdef _PSNR_YUV_ snr->snr_yuva = (float)(snr->snr_yuva*(pgImage->number)+snr->snr_yuv)/(pgImage->number + 1); #endif // _PSNR_YUV_ } } /*! ************************************************************************ * \brief * Interpolation of 1/4 subpixel ************************************************************************ */ void get_block(int x_pos, int y_pos, int block[4][4], unsigned char **ref_pic)//mark1 { int dx, dy; int x, y; int i, j; int maxold_x,maxold_y; int result; int tmp_res[26][26]; int tmp_res_2[26][26]; int tmp_res_3[26][26]; static const int COEF_HALF_h[8] = {-1,4,-12,41,41,-12,4,-1}; static const int COEF_HALF_v[8] = {0,0,-1,5,5,-1,0,0}; const int iWeight1_2_h = 64; const int iWeight1_2_v = 8; static const int COEF_QUART[4] = {0, 1, 1, 0}; const int iWeight1_4 = 2; // A a 1 b B // c d e f // 2 h 3 i // j k l m // C D dx = x_pos & 3; dy = y_pos & 3; x_pos = ( x_pos - dx ) / 4; y_pos = ( y_pos - dy ) / 4; maxold_x = pgImage->width - 1; maxold_y = pgImage->height - 1; if (dx == 0 && dy == 0) { //fullpel position: A for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { block[i][j] = ref_pic[max(0, min(maxold_y, y_pos + j))][max(0, min(maxold_x, x_pos + i))]; } } } else { if ( (dx == 2) && (dy == 0)) {//horizonal 1/2 position: 1 for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, x = -3; x < 5; x++) { result += ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + x))] * COEF_HALF_h[x + 3]; } //block[i][j] = max(0, min(255, (result + 1) / 2)); //block[i][j] = max(0, min(255, (result + iWeight1_2_h / 2) / iWeight1_2_h)); block[i][j] = max(0, min(255, (result + iWeight1_2_h / 2)>>6)); } } } else if ( ( (dx == 1) || (dx == 3) ) && (dy == 0) ) {//horizonal 1/4 position: a and b for (j = 0; j < BLOCK_SIZE; j++) { for (i = -1; i < BLOCK_SIZE + 1; i++) { for (result = 0, x = -3; x < 5; x++) { result += ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + x))] * COEF_HALF_h[x + 3]; } //tmp_res[j][2 * (i + 1)] = max(0, min(255, (result + 4) / 8)); tmp_res[j][2 * (i + 1)] = max(0, min(255, (result + iWeight1_2_h / 2 ) >> 6)); tmp_res[j][2 * (i + 1) + 1] = ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + 1))]; } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, x = -1; x < 3; x++) { if (dx == 1)//a { result += tmp_res[j][2 * i + x + 1] * COEF_QUART[x + 1]; } else//b { result += tmp_res[j][2 * i + x + 2] * COEF_QUART[3-(x + 1)]; } } //block[i][j] = max(0, min(255, (result + 8) / 16)); block[i][j] = max(0, min(255, (result + iWeight1_4 / 2 ) >>1)); } } }//else if ( ( (dx == 1) || (dx == 3) ) && (dy == 0) ) else if ( (dy == 2) && (dx == 0) ) {//vertical 1/2 position: 2 for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -3; y < 5; y++) { result += ref_pic[max(0, min(maxold_y, y_pos + j + y))] [max(0, min(maxold_x, x_pos + i))] * COEF_HALF_v[y + 3]; } //block[i][j] = max(0, min(255, (result + 1) / 2)); block[i][j] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); } } }//else if ( (dy == 2) && (dx == 0) ) else if( ( (dy == 1) || (dy == 3)) && (dx == 0) ) {//vertical 1/4 position: c and j for (j = -1; j < BLOCK_SIZE + 1; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -3; y < 5; y++) { result += ref_pic[max(0, min(maxold_y, y_pos + j + y))] [max(0, min(maxold_x, x_pos + i))] * COEF_HALF_v[y + 3]; } //tmp_res[2 * ( j + 1 )][i] = max(0, min(255, (result + 4) / 8)); tmp_res[2 * ( j + 1 )][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); tmp_res[2 * ( j + 1 ) + 1][i] = ref_pic[max(0, min(maxold_y, y_pos + j + 1))] [max(0, min(maxold_x, x_pos + i))]; } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -1; y < 3; y++) { if (dy == 1)//c { result += tmp_res[2 * j + y + 1][i] * COEF_QUART[y + 1]; } else//j { result += tmp_res[2 * j + y + 2][i] * COEF_QUART[3-(y + 1)]; } } //block[i][j] = max(0, min(255, (result + 8) / 16)); block[i][j] = max(0, min(255, (result + iWeight1_4 / 2) >>1)); } } }//else if( ( (dy == 1) || (dy == 3)) && (dx == 0) ) else if ( (dx == 2) && (dy == 2) ) {//horizonal and vertical 1/2 position: 3 for (j = -3; j < BLOCK_SIZE + 4; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, x = -3; x < 5; x++) { result += ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + x))] * COEF_HALF_h[x + 3]; } tmp_res[j + 3][i] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));//max(0, min(255, (result+4)/8)); } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -3; y < 5; y++) { result += tmp_res[j + y + 3][i] * COEF_HALF_v[y + 3]; } block[i][j] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); } } } else if( ( (dx == 1) || (dx == 3) ) && (dy == 2) ) {//horizonal and vertical 1/4 position: h and i /////////////////////////////////////////////// for (j = -3; j < BLOCK_SIZE + 4; j++) { for (i = -1; i < BLOCK_SIZE+1; i++) { for (result = 0, x = -3; x < 5; x++) { result += ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + x))] * COEF_HALF_h[x + 3]; } tmp_res[j + 3][i+1] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));//max(0, min(255, (result+4)/8)); } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = -1; i < BLOCK_SIZE+1; i++) { for (result = 0, y = -3; y < 5; y++) { result += tmp_res[j + y + 3][i+1] * COEF_HALF_v[y + 3]; } tmp_res_3[j][i+1] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); } } /////////////////////////////////////////////// for (j = 0; j < BLOCK_SIZE; j++) { //for (i = -4; i < BLOCK_SIZE + 5; i++) for (i = 0; i < BLOCK_SIZE + 2; i++) { for (result = 0, y = -3; y < 5; y++) { result += ref_pic[max(0, min(maxold_y, y_pos + j + y))] [max(0, min(maxold_x, x_pos + i))] * COEF_HALF_v[y + 3]; } tmp_res[j][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3));//max(0, min(255, (result+4)/8)); } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE + 2; i++) { tmp_res_2[j][2 * i] = tmp_res_3[j][i]; tmp_res_2[j][2 * i + 1] = tmp_res[j][i]; } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, x = -1; x < 3; x++) { if (dx == 1)//h { result += tmp_res_2[j][2 * i + x + 1] * COEF_QUART[x + 1]; } else { result += tmp_res_2[j][2 * i + x + 2] * COEF_QUART[3-(x + 1)]; } } //block[i][j] = max(0, min(255, (result + 8) / 16)); block[i][j] = max(0, min(255, (result + iWeight1_4 / 2) >>1)); } } } else if( ( (dy == 1) || (dy == 3) ) && (dx == 2) ) {//vertical and horizonal 1/4 position: e and l for (j = -4; j < BLOCK_SIZE+5; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, x = -3; x < 5; x++) { result += ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + x))] * COEF_HALF_h[x + 3]; } tmp_res[j + 4][i] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));// max(0, min(255, (result+4)/8)); //tmp_res[j + 2][i] = max(0, min(255, (result + iWeight1_2 / 2) / iWeight1_2)); } } for (j = 0; j < BLOCK_SIZE + 2; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -3; y < 5; y++) { result += tmp_res[j + y + 3][i] * COEF_HALF_v[y + 3]; } //tmp_res_2[2 * j][i] = max(0, min(255, (result + 32) / 64)); tmp_res_2[2 * j][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); //tmp_res_2[2 * j + 1][i] = max(0, min(255, (tmp_res[j + 2][i] + 4) / 8)); tmp_res_2[2 * j + 1][i] = tmp_res[j + 4][i]; } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -1; y < 3; y++) { if(dy == 1)//e { result += tmp_res_2[2 * j + y + 1][i] * COEF_QUART[y + 1]; } else//l { result += tmp_res_2[2 * j + y + 2][i] * COEF_QUART[3-(y + 1)]; } } //block[i][j] = max(0, min(255, (result + 8) / 16)); block[i][j] = max(0, min(255, (result + iWeight1_4 / 2) >>1)); } } } else {//Diagonal 1/4 position : d, f, k and m for (j = -3; j < BLOCK_SIZE + 5; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, x = -3; x < 5; x++) { result += ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + x))] * COEF_HALF_h[x + 3]; } tmp_res[j + 3][i] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));//max(0, min(255, (result+4)/8)); //tmp_res[j + 1][i] = max(0, min(255, (result + iWeight1_2 / 2) / iWeight1_2)); } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { for (result = 0, y = -3; y < 5; y++) { result += tmp_res[j + y + 3][i] * COEF_HALF_v[y + 3]; } //tmp_res_2[j][i] = max(0, min(255, (result + 32) / 64)); tmp_res_2[j][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); } } for (j = 0; j < BLOCK_SIZE; j++) { for (i = 0; i < BLOCK_SIZE; i++) { if( (dx == 1) && (dy == 1) )//d { result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i))]; } else if( (dx == 3) && (dy == 1) )//f { result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j))] [max(0, min(maxold_x, x_pos + i + 1))]; } else if ((dx == 1) && (dy == 3))//k { result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j + 1))] [max(0, min(maxold_x, x_pos + i))]; } else if((dx == 3) && (dy == 3))//m { result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j + 1))] [max(0, min(maxold_x, x_pos + i + 1))]; } block[i][j] = max(0, min(255, (result + 1) / 2)); } } } }//if (dx == 0 && dy == 0) else } /*! ************************************************************************ * \brief * Initializes the parameters for a new frame ************************************************************************ */ void init_frame() //qwang 2004-3-10 { int i,j; for(i=0;i<(pgImage->width/BLOCK_SIZE+2);i++) // set edge to -1, indicate nothing to predict from for(j=0;j<(pgImage->height/BLOCK_SIZE+2);j++) { pgImage->ipredmode[i][j]=-1; } for(i=0; i max_mb_nr; i++) { mb_data[i].slice_nr = -1; } pgImage->current_mb_nr = 0; imgY = current_frame[0]; imgUV = ¤t_frame[1]; pgImage->current_slice_nr=-1;//WJP FOR SLICE_HEADER 050320 } /*! ************************************************************************ * \brief * decodes one picture ************************************************************************ */ void decode_picture_data() { //WJP FOR SLICE //int tmp; int pos_of_NSLE_SC = 1; int next_slice_start_pos=0;//WJP FOR SLICE_HEADER 050320 int slice_delta_qp;//WJP FOR SLICE_HEADER 050320 int first_mb_nr_in_slice;//WJP FOR SLICE_HEADER 050320 pgImage->cod_counter=-1; while (pgImage->current_mb_nr PicSizeInMbs) // loop over macroblocks { //decode_slice_header(); if(pos_of_NSLE_SC!=0) { if(pgImage->current_mb_nr == next_slice_start_pos) { #if TRACE fprintf(p_trace,"\n"); tracebits2("start_code_prefix",24,0x01); #endif pgImage->current_slice_nr++; //slice_nr=pgImage->current_slice_nr; pgImage->cod_counter=-1; pos_of_NSLE_SC = Position_of_Slice_in_Picbuff[pgImage->current_slice_nr + 1]; #if TRACE // fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n", // (pos_of_NSLE_SC+1),0,1,3); /* temporary */ #endif next_slice_start_pos = search_ue_code(pos_of_NSLE_SC*8); currStream->frame_bitoffset = Position_of_Slice_in_Picbuff[pgImage->current_slice_nr]*8; 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 slice_delta_qp = 0; } if(!pgImage->loop_filter_disable_flag) { pgImage->disable_loop_filter_slice_flag = u_v(1,"SliceHeader: disable_loop_filter_slice_flag"); pgImage->SliceLFDisbaleFlag[pgImage->current_slice_nr] = pgImage->disable_loop_filter_slice_flag; } //fprintf(stdout,"%2d",pgImage->SliceLFDisbaleFlag[pgImage->current_slice_nr]); CheckSliceHeaderValid(first_mb_nr_in_slice,slice_delta_qp); /* check slice header conformance*/ } } /* slice data decoding */ decode_slice_data(); //if (pgImage->current_mb_nr == (next_slice_start_pos)) // DecodeTrailingBits1(currStream,pos_of_NSLE_SC+1); #ifdef _ISOLATED_REGION_ if(iREGenable) { if (pgImage->type == P_IMG) { int j, i; if (iREGmap[pgImage->mb_y][pgImage->mb_x] != 2) for (j = 0; j < 4; j++) for (i = 0; i < 4; i++) pgImage->ipredmode[pgImage->mb_x * 4 + i + 1][pgImage->mb_y * 4 + j + 1] = -1; } } #endif // _ISOLATED_REGION_ //fprintf(stdout,"%2d",pgImage->disable_loop_filter_slice_flag); } //end of MB-loop } /*! ************************************************************************************* * \brief : * decoding slice header including first_mb_in_slice etc. * \author : * Ma Zhan ************************************************************************************* */ void decode_slice_header() { } /*! ************************************************************************************* * \brief : * decoding slice header including first_mb_in_slice etc. * \author : * Ma Zhan ************************************************************************************* */ void decode_slice_data() { #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(); pgImage->current_mb_nr++; previous_qp = pgcurrMB->qp; } /*! ************************************************************************************* * \brief : * Write decoded frame to output file ************************************************************************************* */ void write_frame( FILE *p_out) //!< filestream to output file { int i,j; for(i=0;i height;i++) for(j=0;j width;j++) { fputc(imgY[i][j],p_out); } for(i=0;i height_cr;i++) for(j=0;j width_cr;j++) { fputc(imgUV[0][i][j],p_out); } for(i=0;i height_cr;i++) for(j=0;j width_cr;j++) { fputc(imgUV[1][i][j],p_out); } fflush(p_out); }