www.pudn.com > rm52h.rar > ldecod.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2003, Advanced Audio Video Coding Standard, Part II * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ /*! *********************************************************************** * \mainpage * This is the AVS decoder reference software. For detailed documentation * see the comments in each file. * * \author * The main contributors are listed in contributors.h * * \version * JM 6.1e * * \note * tags are used for document system "doxygen" * available at http://www.doxygen.org * * \par Limitations: * Using different NAL's the assignment of partition-id to containing * syntax elements may got lost, if this information is not transmitted. * The same has to be stated for the partitionlength if partitions are * merged by the NAL. * \par * The presented solution in Q15-K-16 solves both of this problems as the * departitioner parses the bitstream before decoding. Due to syntax element * dependencies both, partition bounds and partitionlength information can * be parsed by the departitioner. * * \par Handling partition information in external file: * As the TML is still a work in progress, it makes sense to handle this * information for simplification in an external file, here called partition * information file, which can be found by the extension .dp extending the * original encoded AVS bitstream. In this file partition-ids followed by its * partitionlength is written. Instead of parsing the bitstream we get the * partition information now out of this file. * This information is assumed to be never sent over transmission channels * (simulation scenarios) as it's information we allways get using a * "real" departitioner before decoding * * \par Extension of Interim File Format: * Therefore a convention has to be made within the interim file format. * The underlying NAL has to take care of fulfilling these conventions. * All partitions have to be bytealigned to be readable by the decoder, * So if the NAL-encoder merges partitions, >>this is only possible to use the * VLC structure of the AVS bitstream<<, this bitaligned structure has to be * broken up by the NAL-decoder. In this case the NAL-decoder is responsable to * read the partitionlength information from the partition information file. * Partitionlosses are signaled with a partition of zero length containing no * syntax elements. * */ /* ************************************************************************************* * File name: ldecod.c * Function: TML decoder project main() * ************************************************************************************* */ #include "contributors.h" #include#include #include #include #include #include #if defined WIN32 #include #endif #include "global.h" #include "memalloc.h" #include "mbuffer.h" #include "annexb.h" #define RM "5" #define VERSION "5.2g" #define LOGFILE "log.dec" #define DATADECFILE "dataDec.txt" #define TRACEFILE "trace_dec.txt" // I have started to move the inp and img structures into global variables. // They are declared in the following lines. Since inp is defined in conio.h // and cannot be overridden globally, it is defined here as input // Everywhere, input-> and img-> can now be used either globally or with // the local override through the formal parameter mechanism extern FILE* bits; struct inp_par *input; //!< input parameters from input configuration file struct snr_par *snr; //!< statistics struct img_par *img; //!< image parameters Bitstream *currStream; FILE *reffile,*reffile2; /* ************************************************************************* * Function:main function for TML decoder * Input: * Output: * Return: * Attention: ************************************************************************* */ int main(int argc, char **argv) { // allocate memory for the structures if ((input = (struct inp_par *)calloc(1, sizeof(struct inp_par)))==NULL) no_mem_exit("main: input"); if ((snr = (struct snr_par *)calloc(1, sizeof(struct snr_par)))==NULL) no_mem_exit("main: snr"); if ((img = (struct img_par *)calloc(1, sizeof(struct img_par)))==NULL) no_mem_exit("main: img"); currStream = AllocBitstream(); // Read Configuration File if (argc != 2) { snprintf(errortext, ET_SIZE, "Usage: %s \n\t defines decoder parameters",argv[0]); error(errortext, 300); } init_conf(input, argv[1]); OpenBitstreamFile (input->infile); // Allocate Slice data struct init(img); img->number=0; img->type = I_IMG; img->imgtr_last_P = 0; img->imgtr_next_P = 0; // B pictures Bframe_ctr=0; // time for total decoding session tot_time = 0; while (decode_one_frame(img, input, snr) != EOS); // B PICTURE : save the last P picture write_prev_Pframe(img, p_out); report(input, img, snr); FreeBitstream(); free_global_buffers(input, img); CloseBitstreamFile(); fclose(p_out); if (p_ref) fclose(p_ref); #if TRACE fclose(p_trace); #endif free (input); free (snr); free (img); return 0; } /* ************************************************************************* * Function:Initilize some arrays * Input: * Output: * Return: * Attention: ************************************************************************* */ void init(struct img_par *img) //!< image parameters { int i; // initilize quad mat`rix used in snr routine for (i=0; i < 256; i++) { img->quad[i]=i*i; } } /* ************************************************************************* * Function:Read input from configuration file * Input:Name of configuration filename * Output: * Return: * Attention: ************************************************************************* */ void init_conf(struct inp_par *inp, char *config_filename) { FILE *fd; // read the decoder configuration file if((fd=fopen(config_filename,"r")) == NULL) { snprintf(errortext, ET_SIZE, "Error: Control file %s not found\n",config_filename); error(errortext, 300); } fscanf(fd,"%s",inp->infile); // AVS compressed input bitsream fscanf(fd,"%*[^\n]"); fscanf(fd,"%s",inp->outfile); // YUV 4:2:2 input format fscanf(fd,"%*[^\n]"); fscanf(fd,"%s",inp->reffile); // reference file fscanf(fd,"%*[^\n]"); // Frame buffer size fscanf(fd,"%d,",&inp->buf_cycle); // may be overwritten in case of RTP NAL fscanf(fd,"%*[^\n]"); if (inp->buf_cycle < 1) { snprintf(errortext, ET_SIZE, "Frame Buffer Size is %d. It has to be at least 1",inp->buf_cycle); error(errortext,1); } fscanf(fd,"%d,",&inp->LFParametersFlag); fscanf(fd,"%*[^\n]"); #if TRACE if ((p_trace=fopen(TRACEFILE,"w"))==0) // append new statistic at the end { snprintf(errortext, ET_SIZE, "Error open file %s!",TRACEFILE); error(errortext,500); } #endif if ((p_out=fopen(inp->outfile,"wb"))==0) { snprintf(errortext, ET_SIZE, "Error open file %s ",inp->outfile); error(errortext,500); } fprintf(stdout,"--------------------------------------------------------------------------\n"); fprintf(stdout," Decoder config file : %s \n",config_filename); fprintf(stdout,"--------------------------------------------------------------------------\n"); fprintf(stdout," Input AVS bitstream : %s \n",inp->infile); fprintf(stdout," Output decoded YUV 4:2:0 : %s \n",inp->outfile); fprintf(stdout," Output status file : %s \n",LOGFILE); if ((p_ref=fopen(inp->reffile,"rb"))==0) { fprintf(stdout," Input reference file : %s does not exist \n",inp->reffile); fprintf(stdout," SNR values are not available\n"); } else fprintf(stdout," Input reference file : %s \n",inp->reffile); fprintf(stdout,"--------------------------------------------------------------------------\n"); fprintf(stdout,"Frame TR QP SnrY SnrU SnrV Time(ms)\n"); } /* ************************************************************************* * Function:Reports the gathered information to appropriate outputs * Input: struct inp_par *inp, struct img_par *img, struct snr_par *stat * Output: * Return: * Attention: ************************************************************************* */ void report(struct inp_par *inp, struct img_par *img, struct snr_par *snr) { #define OUTSTRING_SIZE 255 char string[OUTSTRING_SIZE]; FILE *p_log; #ifndef WIN32 time_t now; struct tm *l_time; #else char timebuf[128]; #endif fprintf(stdout,"-------------------- Average SNR all frames ------------------------------\n"); fprintf(stdout," SNR Y(dB) : %5.2f\n",snr->snr_ya); fprintf(stdout," SNR U(dB) : %5.2f\n",snr->snr_ua); fprintf(stdout," SNR V(dB) : %5.2f\n",snr->snr_va); fprintf(stdout," Total decoding time : %.3f sec \n",tot_time*0.001); fprintf(stdout,"--------------------------------------------------------------------------\n"); fprintf(stdout," Exit RM %s decoder, ver %s ",RM,VERSION); fprintf(stdout,"\n"); // write to log file snprintf(string, OUTSTRING_SIZE, "%s", LOGFILE); if ((p_log=fopen(string,"r"))==0) // check if file exist { if ((p_log=fopen(string,"a"))==0) { snprintf(errortext, ET_SIZE, "Error open file %s for appending",string); error(errortext, 500); } else // Create header to new file { fprintf(p_log," ------------------------------------------------------------------------------------------\n"); fprintf(p_log,"| Decoder statistics. This file is made first time, later runs are appended |\n"); fprintf(p_log," ------------------------------------------------------------------------------------------ \n"); fprintf(p_log,"| Date | Time | Sequence |#Img|Format|SNRY 1|SNRU 1|SNRV 1|SNRY N|SNRU N|SNRV N|\n"); fprintf(p_log," ------------------------------------------------------------------------------------------\n"); } } else { fclose(p_log); p_log=fopen(string,"a"); // File exist,just open for appending } #ifdef WIN32 _strdate( timebuf ); fprintf(p_log,"| %1.5s |",timebuf ); _strtime( timebuf); fprintf(p_log," % 1.5s |",timebuf); #else now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time' time (&now); l_time = localtime (&now); strftime (string, sizeof string, "%d-%b-%Y", l_time); fprintf(p_log,"| %1.5s |",string ); strftime (string, sizeof string, "%H:%M:%S", l_time); fprintf(p_log,"| %1.5s |",string ); #endif fprintf(p_log,"%20.20s|",inp->infile); fprintf(p_log,"%3d |",img->number); fprintf(p_log,"%6.3f|",snr->snr_y1); fprintf(p_log,"%6.3f|",snr->snr_u1); fprintf(p_log,"%6.3f|",snr->snr_v1); fprintf(p_log,"%6.3f|",snr->snr_ya); fprintf(p_log,"%6.3f|",snr->snr_ua); fprintf(p_log,"%6.3f|\n",snr->snr_va); fclose(p_log); snprintf(string, OUTSTRING_SIZE,"%s", DATADECFILE); p_log=fopen(string,"a"); if(Bframe_ctr != 0) // B picture used { fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5d " "%2.2f %2.2f %2.2f %5d " "%2.2f %2.2f %2.2f %5d %.3f\n", img->number, 0, img->qp, snr->snr_y1, snr->snr_u1, snr->snr_v1, 0, 0.0, 0.0, 0.0, 0, snr->snr_ya, snr->snr_ua, snr->snr_va, 0, (double)0.001*tot_time/(img->number+Bframe_ctr-1)); } else { fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5d " "%2.2f %2.2f %2.2f %5d " "%2.2f %2.2f %2.2f %5d %.3f\n", img->number, 0, img->qp, snr->snr_y1, snr->snr_u1, snr->snr_v1, 0, 0.0, 0.0, 0.0, 0, snr->snr_ya, snr->snr_ua, snr->snr_va, 0, (double)0.001*tot_time/img->number); } fclose(p_log); } /* ************************************************************************* * Function:Allocates a Bitstream * Input: * Output:allocated Bitstream point * Return: * Attention: ************************************************************************* */ Bitstream *AllocBitstream() { Bitstream *bitstream; bitstream = (Bitstream *) calloc(1, sizeof(Bitstream)); if (bitstream == NULL) { snprintf(errortext, ET_SIZE, "AllocBitstream: Memory allocation for Bitstream failed"); error(errortext, 100); } bitstream->streamBuffer = (byte *) calloc(MAX_CODED_FRAME_SIZE, sizeof(byte)); if (bitstream->streamBuffer == NULL) { snprintf(errortext, ET_SIZE, "AllocBitstream: Memory allocation for streamBuffer failed"); error(errortext, 100); } return bitstream; } /* ************************************************************************* * Function:Frees a partition structure (array). * Input:Partition to be freed, size of partition Array (Number of Partitions) * Output: * Return: * Attention:n must be the same as for the corresponding call of AllocPartition ************************************************************************* */ void FreeBitstream () { assert (currStream!= NULL); assert (currStream->streamBuffer != NULL); free (currStream->streamBuffer); free (currStream); } /* ************************************************************************* * Function:Dynamic memory allocation of frame size related global buffers buffers are defined in global.h, allocated memory must be freed in void free_global_buffers() * Input:Input Parameters struct inp_par *inp, Image Parameters struct img_par *img * Output:Number of allocated bytes * Return: * Attention: ************************************************************************* */ int init_global_buffers(struct inp_par *inp, struct img_par *img) { int i,j; int refnum; int memory_size=0; img->buf_cycle = inp->buf_cycle+1; img->buf_cycle *= 2; if(!progressive_sequence) { memory_size += get_mem2Dint(&refFrArr_top, vertical_size/(2*B8_SIZE), img->width/B8_SIZE); memory_size += get_mem2Dint(&refFrArr_bot, vertical_size/(2*B8_SIZE), img->width/B8_SIZE); memory_size += get_mem3Dint(&(img->mv_top),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->mv_bot),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); // int fw_refFrArr[72][88]; memory_size += get_mem2Dint(&(img->fw_refFrArr_top),vertical_size/(2*B8_SIZE),img->width/B8_SIZE); // int bw_refFrArr[72][88]; memory_size += get_mem2Dint(&(img->bw_refFrArr_top),vertical_size/(2*B8_SIZE),img->width/B8_SIZE); memory_size += get_mem2Dint(&(img->fw_refFrArr_bot),vertical_size/(2*B8_SIZE),img->width/B8_SIZE); // int bw_refFrArr[72][88]; memory_size += get_mem2Dint(&(img->bw_refFrArr_bot),vertical_size/(2*B8_SIZE),img->width/B8_SIZE); memory_size += get_mem3Dint(&(img->fw_mv_top),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->fw_mv_bot),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->bw_mv_top),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->bw_mv_bot),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->dfMV_top),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->dbMV_top),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->dfMV_bot),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); memory_size += get_mem3Dint(&(img->dbMV_bot),img->width/B8_SIZE +4, vertical_size/(2*B8_SIZE),3); } // allocate memory for imgY_prev memory_size += get_mem2D(&imgY_prev, vertical_size, img->width); memory_size += get_mem3D(&imgUV_prev, 2, vertical_size/2, img->width_cr); // allocate memory for reference frames of each block: refFrArr memory_size += get_mem2Dint(&refFrArr_frm, vertical_size/B8_SIZE, img->width/B8_SIZE); // allocate memory for reference frame in find_snr memory_size += get_mem2D(&imgY_ref, vertical_size, img->width); memory_size += get_mem3D(&imgUV_ref, 2, vertical_size/2, img->width_cr); // allocate memory in structure img if(((mb_data) = (Macroblock *) calloc((img->width/MB_BLOCK_SIZE) * (vertical_size/MB_BLOCK_SIZE),sizeof(Macroblock))) == NULL) no_mem_exit("init_global_buffers: mb_data"); if(((img->intra_block) = (int**)calloc((j=(img->width/MB_BLOCK_SIZE) * (vertical_size/MB_BLOCK_SIZE)),sizeof(int))) == NULL) no_mem_exit("init_global_buffers: img->intra_block"); for (i=0; i intra_block[i] = (int*)calloc(4, sizeof(int))) == NULL) no_mem_exit ("init_global_buffers: img->intra_block"); } memory_size += get_mem3Dint(&(img->mv_frm),img->width/B8_SIZE +4, vertical_size/B8_SIZE,3); memory_size += get_mem2Dint(&(img->ipredmode),img->width/B8_SIZE +2 , vertical_size/B8_SIZE +2); memory_size += get_mem3Dint(&(img->dfMV),img->width/B8_SIZE +4, vertical_size/B8_SIZE,3); memory_size += get_mem3Dint(&(img->dbMV),img->width/B8_SIZE +4, vertical_size/B8_SIZE,3); memory_size += get_mem2Dint(&(img->fw_refFrArr_frm),vertical_size/B8_SIZE,img->width/B8_SIZE); memory_size += get_mem2Dint(&(img->bw_refFrArr_frm),vertical_size/B8_SIZE,img->width/B8_SIZE); memory_size += get_mem3Dint(&(img->fw_mv),img->width/B8_SIZE +4, vertical_size/B8_SIZE,3); memory_size += get_mem3Dint(&(img->bw_mv),img->width/B8_SIZE +4, vertical_size/B8_SIZE,3); // Prediction mode is set to -1 outside the frame, indicating that no prediction can be made from this part for (i=0; i < img->width/(B8_SIZE)+2; i++) { for (j=0; j < vertical_size/(B8_SIZE)+2; j++) { img->ipredmode[i][j]=-1; } } //by oliver 0512 img->buf_cycle = inp->buf_cycle+1; // allocate frame buffer for(refnum=0; refnum<3; refnum++) for (i=0; i<3; i++) { if (i==0) { get_mem2D(&reference_frame[refnum][i],vertical_size,img->width); }else { get_mem2D(&reference_frame[refnum][i],vertical_size/2,img->width_cr); } } //allocate field buffer if(!progressive_sequence) { for(refnum=0; refnum<6; refnum++) for (i=0; i<3; i++) { if (i==0) { get_mem2D(&reference_field[refnum][i],vertical_size/2,img->width); }else { get_mem2D(&reference_field[refnum][i],vertical_size/4,img->width_cr); } } } //forward reference frame buffer ref_frm[0] = reference_frame[0]; //reference_frame[ref_index][yuv][height][width],ref_frm[ref_index][yuv][height][width] ref_frm[1] = reference_frame[1]; current_frame = reference_frame[2]; //luma for forward for (j=0;j<2;j++)//ref_index = 0 { mref_frm[j] = ref_frm[j][0]; } //chroma for forward for (j=0;j<2;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_frm[j][i] = ref_frm[j][i+1]; } //luma for backward //forward/backward reference buffer f_ref_frm[0] = ref_frm[1]; //f_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field b_ref_frm[0] = ref_frm[0]; //b_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field for (j=0;j<1;j++)//ref_index = 0 luma = 0 { mref_fref_frm[j] = f_ref_frm[j][0]; mref_bref_frm[j] = b_ref_frm[j][0]; } //chroma for backward for (j=0;j<1;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fref_frm[j][i] = f_ref_frm[j][i+1]; mcef_bref_frm[j][i] = b_ref_frm[j][i+1]; } if(!progressive_sequence) { //forward reference frame buffer for (i=0; i<4; i++) ref_fld[i] = reference_field[i]; ref_fld[4] = reference_field[5]; current_field = reference_field[4]; //luma for forward for (j=0;j<4;j++)//ref_index = 0 { mref_fld[j] = ref_fld[j][0]; } //chroma for forward for (j=0;j<4;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fld[j][i] = ref_fld[j][i+1]; } //luma for backward //forward/backward reference buffer for (i=0; i<2; i++) { f_ref_fld[i] = ref_fld[i+2]; //f_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field b_ref_fld[i] = ref_fld[1-i]; //b_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field } for (j=0;j<2;j++)//ref_index = 0 luma = 0 { mref_fref_fld[j] = f_ref_fld[j][0]; mref_bref_fld[j] = b_ref_fld[j][0]; } //chroma for backward for (j=0;j<2;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fref_fld[j][i] = f_ref_fld[j][i+1]; mcef_bref_fld[j][i] = b_ref_fld[j][i+1]; } } if((mref = (byte***)calloc(4,sizeof(byte**))) == NULL) no_mem_exit("alloc_mref: mcef"); if((mcef = (byte****)calloc(4,sizeof(byte***))) == NULL) no_mem_exit("alloc_mref: mcef"); for (i=0; i<4; i++) if((mcef[i] = (byte***)calloc(2,sizeof(byte**))) == NULL) no_mem_exit("alloc_mref: mcef"); return (memory_size); } /* ************************************************************************* * Function:Free allocated memory of frame size related global buffers buffers are defined in global.h, allocated memory is allocated in int init_global_buffers() * Input:Input Parameters struct inp_par *inp, Image Parameters struct img_par *img * Output: * Return: * Attention: ************************************************************************* */ void free_global_buffers(struct inp_par *inp, struct img_par *img) { int i,j; free_mem2D(imgY_prev); free_mem3D(imgUV_prev,2); if(!progressive_sequence) { free (parity_fld); for (i=0; i<6; i++) for(j=0;j<3; j++) { free_mem2D(reference_field[i][j]); } } free (mref); for (i=0; i<2; i++) free (mcef[i]); free (mcef); free_mem2D (imgY_ref); free_mem3D (imgUV_ref,2); // free mem, allocated for structure img if (mb_data != NULL) free(mb_data); j = (img->width/16)*(img->height/16); for (i=0; i intra_block[i]); } free (img->intra_block); free_mem3Dint(img->mv_frm,img->width/B8_SIZE + 4); free_mem2Dint (img->ipredmode); free_mem3Dint(img->dfMV,img->width/B8_SIZE + 4); free_mem3Dint(img->dbMV,img->width/B8_SIZE + 4); free_mem2Dint(img->fw_refFrArr_frm); free_mem2Dint(img->bw_refFrArr_frm); free_mem3Dint(img->fw_mv,img->width/B8_SIZE + 4); free_mem3Dint(img->bw_mv,img->width/B8_SIZE + 4); for (i=0; i<3; i++) for(j=0;j<3; j++) { free_mem2D(reference_frame[i][j]); } } int get_direct_mv (int****** mv,int mb_x,int mb_y) { int i, j, k, l; if ((*mv = (int*****)calloc(mb_y,sizeof(int****))) == NULL) no_mem_exit ("get_mem_mv: mv"); for (i=0; i 0; i--) ref_fld[i] = ref_fld[i-1]; ref_fld[0] = current_field; current_field = tmp; //forward/backward reference buffer for (i=0; i<2; i++) { f_ref_fld[i] = ref_fld[i+2]; //f_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field b_ref_fld[i] = ref_fld[1-i]; //b_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field } //luma for forward for (j=0;j<4;j++)//ref_index = 0 { mref_fld[j] = ref_fld[j][0]; } //chroma for forward for (j=0;j<4;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fld[j][i] = ref_fld[j][i+1]; } //luma for backward for (j=0;j<2;j++)//ref_index = 0 luma = 0 { mref_fref_fld[j] = f_ref_fld[j][0]; mref_bref_fld[j] = b_ref_fld[j][0]; } //chroma for backward for (j=0;j<2;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fref_fld[j][i] = f_ref_fld[j][i+1]; mcef_bref_fld[j][i] = b_ref_fld[j][i+1]; } } void Update_Picture_bot_field() { unsigned char ***tmp; int i,j; //forward reference frame buffer tmp = ref_fld[4]; for (i=4; i>0; i--) ref_fld[i] = ref_fld[i-1]; ref_fld[0] = current_field; current_field = tmp; //forward/backward reference buffer for (i=0; i<2; i++) { f_ref_fld[i] = ref_fld[i+2]; //f_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field b_ref_fld[i] = ref_fld[1-i]; //b_ref_frm[ref_index][yuv][height(height/2)][width] ref_index=0 for B frame, ref_index = 0,1 for B field } //luma for forward for (j=0;j<4;j++)//ref_index = 0 { mref_fld[j] = ref_fld[j][0]; } //chroma for forward for (j=0;j<4;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fld[j][i] = ref_fld[j][i+1]; } //luma for backward for (j=0;j<2;j++)//ref_index = 0 luma = 0 { mref_fref_fld[j] = f_ref_fld[j][0]; mref_bref_fld[j] = b_ref_fld[j][0]; } //chroma for backward for (j=0;j<2;j++)//ref_index = 0 for (i=0;i<2;i++) // chroma uv =0,1; 1,2 for reference_frame { mcef_fref_fld[j][i] = f_ref_fld[j][i+1]; mcef_bref_fld[j][i] = b_ref_fld[j][i+1]; } }