image.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:32k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  *************************************************************************************
  34.  * file image.c
  35.  *
  36.  * brief
  37.  *    Code one image/slice
  38.  *
  39.  * author
  40.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  41.  *     - Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com>
  42.  *     - Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
  43.  *     - Jani Lainema                    <jani.lainema@nokia.com>
  44.  *     - Sebastian Purreiter             <sebastian.purreiter@mch.siemens.de>
  45.  *     - Byeong-Moon Jeon                <jeonbm@lge.com>
  46.  *     - Yoon-Seong Soh                  <yunsung@lge.com>
  47.  *     - Thomas Stockhammer              <stockhammer@ei.tum.de>
  48.  *     - Detlev Marpe                    <marpe@hhi.de>
  49.  *     - Guido Heising                   <heising@hhi.de>
  50.  *     - Thomas Wedi                     <wedi@tnt.uni-hannover.de>
  51.  *     - Ragip Kurceren                  <ragip.kurceren@nokia.com>
  52.  *     - Antti Hallapuro                 <antti.hallapuro@nokia.com>
  53.  *************************************************************************************
  54.  */
  55. #include "contributors.h"
  56. #include <stdlib.h>
  57. #include <math.h>
  58. #include <time.h>
  59. #include <sys/time.h>
  60. #include <unistd.h>
  61. #include <string.h>
  62. #include <memory.h>
  63. #include <assert.h>
  64. #include "global.h"
  65. #include "image.h"
  66. #include "refbuf.h"
  67. #ifdef _ADAPT_LAST_GROUP_
  68. int *last_P_no;
  69. #endif
  70. //! The followibng two variables are used for debug purposes.  They store
  71. //! the status of the currStream data structure elements after the header
  72. //! writing, and are used whether any MB bits were written during the
  73. //! macroblock coding stage.  We need to worry about empty slices!
  74. static int Byte_Pos_After_Header;
  75. static int Bits_To_Go_After_Header;
  76. static void UnifiedOneForthPix (pel_t **imgY, pel_t** imgU, pel_t **imgV,
  77.         pel_t **out4Y, pel_t **outU, pel_t **outV, pel_t *ref11);
  78. /*!
  79.  ************************************************************************
  80.  * brief
  81.  *    Encodes one frame
  82.  ************************************************************************
  83.  */
  84. int encode_one_frame()
  85. {
  86. #ifdef _LEAKYBUCKET_
  87.   extern long Bit_Buffer[10000];
  88.   extern unsigned long total_frame_buffer;
  89. #endif
  90.   Boolean end_of_frame = FALSE;
  91.   SyntaxElement sym;
  92.   time_t ltime1;   // for time measurement
  93.   time_t ltime2;
  94. #ifdef WIN32
  95.   struct _timeb tstruct1;
  96.   struct _timeb tstruct2;
  97. #else
  98.   struct timeval tstruct1;
  99.   struct timeval tstruct2;
  100. #endif
  101.   int tmp_time;
  102. #ifdef WIN32
  103.   _ftime( &tstruct1 );    // start time ms
  104. #else
  105.   gettimeofday(&tstruct1, NULL);
  106. #endif
  107.   time( &ltime1 );        // start time s
  108.   // Initialize frame with all stat and img variables
  109.   img->total_number_mb = (img->width * img->height)/(MB_BLOCK_SIZE*MB_BLOCK_SIZE);
  110.   init_frame();
  111.   // Read one new frame
  112. #ifndef H26L_LIB
  113.   read_one_new_frame();
  114. #endif
  115.   if (img->type == B_IMG)
  116.     Bframe_ctr++;
  117.   while (end_of_frame == FALSE) // loop over slices
  118.   {
  119.     // Encode the current slice
  120.     encode_one_slice(&sym);
  121.     // Proceed to next slice
  122.     img->current_slice_nr++;
  123.     stat->bit_slice = 0;
  124.     if (img->current_mb_nr == img->total_number_mb) // end of frame reached?
  125.       end_of_frame = TRUE;
  126.   }
  127.   // in future only one call of oneforthpix() for all frame tyoes will be necessary, because
  128.   // mref buffer will be increased by one frame to store also the next P-frame. Then mref_P
  129.   // will not be used any more
  130.   if (img->type != B_IMG) //all I- and P-frames
  131.   {
  132.     if (input->successive_Bframe == 0 || img->number == 0)
  133.       interpolate_frame(); // I- and P-frames:loop-filtered imgY, imgUV -> mref[][][], mcef[][][][]
  134.     else
  135.       interpolate_frame_2();    // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
  136.                                  // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
  137.   }
  138.   else
  139.     if (img->b_frame_to_code == input->successive_Bframe)
  140.       copy2mref(img);          // last successive B-frame: mref_P[][][], mcef_P[][][][] (loop-filtered imgY, imgUV)-> mref[][][], mcef[][][][]
  141.   if (input->rdopt==2)
  142.     UpdateDecoders(); // simulate packet losses and move decoded image to reference buffers
  143.   find_snr(snr,img);
  144.   time(&ltime2);       // end time sec
  145. #ifdef WIN32
  146.   _ftime(&tstruct2);   // end time ms
  147.   tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);
  148. #else
  149.   gettimeofday(&tstruct2, NULL);    // end time ms
  150.   tmp_time=(ltime2*1000+tstruct2.tv_usec/1000) - (ltime1*1000+(tstruct1.tv_usec / 1000));
  151. #endif
  152.   tot_time=tot_time + tmp_time;
  153. #ifndef H26L_LIB
  154.   // Write reconstructed images
  155.   write_reconstructed_image();
  156. #endif
  157. #ifdef _LEAKYBUCKET_
  158.   // Store bits used for this frame and increment counter of no. of coded frames
  159.   Bit_Buffer[total_frame_buffer] = stat->bit_ctr - stat->bit_ctr_n;
  160.   total_frame_buffer++;
  161. #endif
  162.   if(img->number == 0)
  163.   {
  164.     printf("%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d n",
  165.         frame_no, stat->bit_ctr-stat->bit_ctr_n,
  166.         img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
  167.     stat->bitr0=stat->bitr;
  168.     stat->bit_ctr_0=stat->bit_ctr;
  169.     stat->bit_ctr=0;
  170.   }
  171.   else
  172.   {
  173.     if (img->type == INTRA_IMG)
  174.     {
  175.       stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;
  176.       printf("%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d n",
  177.         frame_no, stat->bit_ctr-stat->bit_ctr_n,
  178.         img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
  179.     }
  180.     else if (img->type != B_IMG)
  181.     {
  182.       stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;
  183.       if(img->types == SP_IMG)
  184.         printf("%3d(SP) %8d %4d %7.4f %7.4f %7.4f  %5d    %3dn",
  185.           frame_no, stat->bit_ctr-stat->bit_ctr_n,
  186.           img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, intras);
  187.       else
  188.         printf("%3d(P)  %8d %4d %7.4f %7.4f %7.4f  %5d    %3dn",
  189.           frame_no, stat->bit_ctr-stat->bit_ctr_n,
  190.           img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, intras);
  191.     }
  192.     else
  193.     {
  194.       stat->bit_ctr_B += stat->bit_ctr-stat->bit_ctr_n;
  195.       printf("%3d(B)  %8d %4d %7.4f %7.4f %7.4f  %5d n",
  196.         frame_no, stat->bit_ctr-stat->bit_ctr_n, img->qp,
  197.         snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
  198.     }
  199.   }
  200.   stat->bit_ctr_n=stat->bit_ctr;
  201.   if(img->number == 0)
  202.     return 0;
  203.   else
  204.     return 1;
  205. }
  206. /*!
  207.  ************************************************************************
  208.  * brief
  209.  *    Encodes one slice
  210.  ************************************************************************
  211.  */
  212. void encode_one_slice(SyntaxElement *sym)
  213. {
  214.   Boolean end_of_slice = FALSE;
  215.   Boolean recode_macroblock;
  216.   int len;
  217.   img->cod_counter=0;
  218.   // Initializes the parameters of the current slice
  219.   init_slice();
  220.   // Write slice or picture header
  221.   len = start_slice(sym);
  222.   Byte_Pos_After_Header = img->currentSlice->partArr[0].bitstream->byte_pos;
  223.   Bits_To_Go_After_Header = img->currentSlice->partArr[0].bitstream->bits_to_go;
  224.   if (input->of_mode==PAR_OF_RTP)
  225.   {
  226.     assert (Byte_Pos_After_Header > 0);     // there must be a header
  227.     assert (Bits_To_Go_After_Header == 8);  // byte alignment must have been established
  228.   }
  229.   // Update statistics
  230.   stat->bit_slice += len;
  231.   stat->bit_use_header[img->type] += len;
  232.   while (end_of_slice == FALSE) // loop over macroblocks
  233.   {
  234.     // recode_macroblock is used in slice mode two and three where
  235.     // backing of one macroblock in the bitstream is possible
  236.     recode_macroblock = FALSE;
  237.     // Initializes the current macroblock
  238.     start_macroblock();
  239.     // Encode one macroblock
  240.     encode_one_macroblock();
  241.     // Pass the generated syntax elements to the NAL
  242.     write_one_macroblock();
  243.     // Terminate processing of the current macroblock
  244.     terminate_macroblock(&end_of_slice, &recode_macroblock);
  245.     if (recode_macroblock == FALSE)         // The final processing of the macroblock has been done
  246.       proceed2nextMacroblock(); // Go to next macroblock
  247.   }
  248.   terminate_slice();
  249. }
  250. /*!
  251.  ************************************************************************
  252.  * brief
  253.  *    Initializes the parameters for a new frame
  254.  ************************************************************************
  255.  */
  256. void init_frame()
  257. {
  258.   int i,j,k;
  259.   int prevP_no, nextP_no;
  260.   img->current_mb_nr=0;
  261.   img->current_slice_nr=0;
  262.   stat->bit_slice = 0;
  263.   if(input->UseConstrainedIntraPred)
  264.   {
  265.     for (i=0; i<img->total_number_mb; i++)
  266.       img->intra_mb[i] = 1; // default 1 = intra mb
  267.   }
  268.   img->mhor  = img->width *4-1;
  269.   img->mvert = img->height*4-1;
  270.   img->mb_y = img->mb_x = 0;
  271.   img->block_y = img->pix_y = img->pix_c_y = 0;   // define vertical positions
  272.   img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; // define horizontal positions
  273.   if (input->intra_upd > 0 && img->mb_y <= img->mb_y_intra)
  274.     img->height_err=(img->mb_y_intra*16)+15;     // for extra intra MB
  275.   else
  276.     img->height_err=img->height-1;
  277.   if(img->type != B_IMG)
  278.   {
  279.     img->refPicID ++;
  280.     img->tr=img->number*(input->jumpd+1);
  281. #ifdef _ADAPT_LAST_GROUP_
  282.     if (input->last_frame && img->number+1 == input->no_frames)
  283.       img->tr=input->last_frame;
  284. #endif
  285.     if(img->number!=0 && input->successive_Bframe != 0)   // B pictures to encode
  286.       nextP_tr=img->tr;
  287.     if (img->type == INTRA_IMG)
  288.       img->qp = input->qp0;         // set quant. parameter for I-frame
  289.     else
  290.     {
  291. #ifdef _CHANGE_QP_
  292.         if (input->qp2start > 0 && img->tr >= input->qp2start)
  293.           img->qp = input->qpN2;
  294.         else
  295. #endif
  296.           img->qp = input->qpN;
  297.       if (img->types==SP_IMG)
  298.       {
  299.         img->qp = input->qpsp;
  300.         img->qpsp = input->qpsp_pred;
  301.       }
  302.     }
  303.     img->mb_y_intra=img->mb_y_upd;   //  img->mb_y_intra indicates which GOB to intra code for this frame
  304.     if (input->intra_upd > 0)          // if error robustness, find next GOB to update
  305.     {
  306.       img->mb_y_upd=(img->number/input->intra_upd) % (img->height/MB_BLOCK_SIZE);
  307.     }
  308.   }
  309.   else
  310.   {
  311.     img->p_interval = input->jumpd+1;
  312.     prevP_no = (img->number-1)*img->p_interval;
  313.     nextP_no = img->number*img->p_interval;
  314. #ifdef _ADAPT_LAST_GROUP_
  315.     last_P_no[0] = prevP_no; for (i=1; i<img->buf_cycle; i++) last_P_no[i] = last_P_no[i-1]-img->p_interval;
  316.     if (input->last_frame && img->number+1 == input->no_frames)
  317.       {
  318.         nextP_no        =input->last_frame;
  319.         img->p_interval =nextP_no - prevP_no;
  320.       }
  321. #endif
  322.     img->b_interval = (int)((float)(input->jumpd+1)/(input->successive_Bframe+1.0)+0.49999);
  323.     img->tr= prevP_no+img->b_interval*img->b_frame_to_code; // from prev_P
  324.     if(img->tr >= nextP_no)
  325.       img->tr=nextP_no-1; // ?????
  326. #ifdef _CHANGE_QP_
  327.     if (input->qp2start > 0 && img->tr >= input->qp2start)
  328.       img->qp = input->qpB2;
  329.     else
  330. #endif
  331.       img->qp = input->qpB;
  332.     // initialize arrays
  333.     for(k=0; k<2; k++)
  334.       for(i=0; i<img->height/BLOCK_SIZE; i++)
  335.         for(j=0; j<img->width/BLOCK_SIZE+4; j++)
  336.         {
  337.           tmp_fwMV[k][i][j]=0;
  338.           tmp_bwMV[k][i][j]=0;
  339.           dfMV[k][i][j]=0;
  340.           dbMV[k][i][j]=0;
  341.         }
  342.     for(i=0; i<img->height/BLOCK_SIZE; i++)
  343.       for(j=0; j<img->width/BLOCK_SIZE; j++)
  344.       {
  345.         fw_refFrArr[i][j]=bw_refFrArr[i][j]=-1;
  346.       }
  347.   }
  348. }
  349. /*!
  350.  ************************************************************************
  351.  * brief
  352.  *    Initializes the parameters for a new slice
  353.  ************************************************************************
  354.  */
  355. void init_slice()
  356. {
  357.   int i;
  358.   Slice *curr_slice = img->currentSlice;
  359.   DataPartition *dataPart;
  360.   Bitstream *currStream;
  361.   curr_slice->picture_id = img->tr%256;
  362.   curr_slice->slice_nr = img->current_slice_nr;
  363.   curr_slice->qp = img->qp;
  364.   curr_slice->start_mb_nr = img->current_mb_nr;
  365.   curr_slice->dp_mode = input->partition_mode;
  366.   curr_slice->slice_too_big = dummy_slice_too_big;
  367.   for (i=0; i<curr_slice->max_part_nr; i++)
  368.   {
  369.     dataPart = &(curr_slice->partArr[i]);
  370.     // in priciple it is possible to assign to each partition
  371.     // a different entropy coding method
  372.     if (input->symbol_mode == UVLC)
  373.       dataPart->writeSyntaxElement = writeSyntaxElement_UVLC;
  374.     else
  375.       dataPart->writeSyntaxElement = writeSyntaxElement_CABAC;
  376.     // A little hack until CABAC can handle non-byte aligned start positions   StW!
  377.     // For UVLC, the stored_ positions in the bit buffer are necessary.  For CABAC,
  378.     // the buffer is initialized to start at zero.
  379.     if (input->symbol_mode == UVLC && input->of_mode == PAR_OF_26L)    // Stw: added PAR_OF_26L check
  380.     {
  381.       currStream = dataPart->bitstream;
  382.       currStream->bits_to_go  = currStream->stored_bits_to_go;
  383.       currStream->byte_pos    = currStream->stored_byte_pos;
  384.       currStream->byte_buf    = currStream->stored_byte_buf;
  385.     } 
  386.     else // anything but UVLC and PAR_OF_26L
  387.     {   
  388.       currStream = dataPart->bitstream;
  389.       currStream->bits_to_go  = 8;
  390.       currStream->byte_pos    = 0;
  391.       currStream->byte_buf    = 0;
  392.     }
  393.   }
  394. }
  395. /*!
  396.  ************************************************************************
  397.  * brief
  398.  *    Reads new frame from file and sets frame_no
  399.  ************************************************************************
  400.  */
  401. void read_one_new_frame()
  402. {
  403.   int i, j, uv;
  404.   int status; // frame_no;
  405.   int frame_size = img->height*img->width*3/2;
  406.   if(img->type == B_IMG)
  407.     frame_no = (img->number-1)*(input->jumpd+1)+img->b_interval*img->b_frame_to_code;
  408.   else
  409.   {
  410.     frame_no = img->number*(input->jumpd+1);
  411. #ifdef _ADAPT_LAST_GROUP_
  412.       if (input->last_frame && img->number+1 == input->no_frames)
  413.         frame_no=input->last_frame;
  414. #endif
  415.   }
  416.   rewind (p_in);
  417.   status  = fseek (p_in, frame_no * frame_size + input->infile_header, 0);
  418.   if (status != 0)
  419.   {
  420.     snprintf(errortext, ET_SIZE, "Error in seeking frame no: %dn", frame_no);
  421.     error(errortext,1);
  422.   }
  423.   for (j=0; j < img->height; j++)
  424.     for (i=0; i < img->width; i++)
  425.       imgY_org[j][i]=fgetc(p_in);
  426.   for (uv=0; uv < 2; uv++)
  427.     for (j=0; j < img->height_cr ; j++)
  428.       for (i=0; i < img->width_cr; i++)
  429.         imgUV_org[uv][j][i]=fgetc(p_in);
  430. }
  431. /*!
  432.  ************************************************************************
  433.  * brief
  434.  *     Writes reconstructed image(s) to file
  435.  *     This can be done more elegant!
  436.  ************************************************************************
  437.  */
  438. void write_reconstructed_image()
  439. {
  440.   int i, j, k;
  441.   if (p_dec != NULL)
  442.   {
  443.     if(img->type != B_IMG)
  444.     {
  445.       // write reconstructed image (IPPP)
  446.       if(input->successive_Bframe==0)
  447.       {
  448.         for (i=0; i < img->height; i++)
  449.           for (j=0; j < img->width; j++)
  450.             fputc(min(imgY[i][j],255),p_dec);
  451.         for (k=0; k < 2; ++k)
  452.           for (i=0; i < img->height/2; i++)
  453.             for (j=0; j < img->width/2; j++)
  454.               fputc(min(imgUV[k][i][j],255),p_dec);
  455.       }
  456.       // write reconstructed image (IBPBP) : only intra written
  457.       else if (img->number==0 && input->successive_Bframe!=0)
  458.       {
  459.         for (i=0; i < img->height; i++)
  460.           for (j=0; j < img->width; j++)
  461.             fputc(min(imgY[i][j],255),p_dec);
  462.         for (k=0; k < 2; ++k)
  463.           for (i=0; i < img->height/2; i++)
  464.             for (j=0; j < img->width/2; j++)
  465.               fputc(min(imgUV[k][i][j],255),p_dec);
  466.       }
  467.       // next P picture. This is saved with recon B picture after B picture coding
  468.       if (img->number!=0 && input->successive_Bframe!=0)
  469.       {
  470.         for (i=0; i < img->height; i++)
  471.           for (j=0; j < img->width; j++)
  472.             nextP_imgY[i][j]=imgY[i][j];
  473.         for (k=0; k < 2; ++k)
  474.           for (i=0; i < img->height/2; i++)
  475.             for (j=0; j < img->width/2; j++)
  476.               nextP_imgUV[k][i][j]=imgUV[k][i][j];
  477.       }
  478.     }
  479.     else
  480.     {
  481.       for (i=0; i < img->height; i++)
  482.         for (j=0; j < img->width; j++)
  483.           fputc(min(imgY[i][j],255),p_dec);
  484.       for (k=0; k < 2; ++k)
  485.         for (i=0; i < img->height/2; i++)
  486.           for (j=0; j < img->width/2; j++)
  487.             fputc(min(imgUV[k][i][j],255),p_dec);
  488.       // If this is last B frame also store P frame
  489.       if(img->b_frame_to_code == input->successive_Bframe)
  490.       {
  491.         // save P picture
  492.         for (i=0; i < img->height; i++)
  493.           for (j=0; j < img->width; j++)
  494.             fputc(min(nextP_imgY[i][j],255),p_dec);
  495.         for (k=0; k < 2; ++k)
  496.           for (i=0; i < img->height/2; i++)
  497.             for (j=0; j < img->width/2; j++)
  498.               fputc(min(nextP_imgUV[k][i][j],255),p_dec);
  499.       }
  500.     }
  501.   }
  502. }
  503. /*!
  504.  ************************************************************************
  505.  * brief
  506.  *    Choose interpolation method depending on MV-resolution
  507.  ************************************************************************
  508.  */
  509. void interpolate_frame()
  510. {                 // write to mref[]
  511.   int rpic;
  512.   rpic = img->frame_cycle = img->number % img->buf_cycle;
  513.   if(input->mv_res)
  514.     oneeighthpix(0);
  515.   else
  516.     UnifiedOneForthPix(imgY, imgUV[0], imgUV[1],
  517.                mref[rpic], mcef[rpic][0], mcef[rpic][1],
  518.                Refbuf11[rpic]);
  519. }
  520. /*!
  521.  ************************************************************************
  522.  * brief
  523.  *    Choose interpolation method depending on MV-resolution
  524.  ************************************************************************
  525.  */
  526. void interpolate_frame_2()      // write to mref_P
  527. {
  528.   if(input->mv_res)
  529.     oneeighthpix(1);
  530.   else
  531.     UnifiedOneForthPix(imgY, imgUV[0], imgUV[1], mref_P, mcef_P[0], mcef_P[1], Refbuf11_P);
  532. }
  533. static void GenerateFullPelRepresentation (pel_t **Fourthpel, pel_t *Fullpel, int xsize, int ysize)
  534. {
  535.   int x, y;
  536.   for (y=0; y<ysize; y++)
  537.     for (x=0; x<xsize; x++)
  538.       PutPel_11 (Fullpel, y, x, FastPelY_14 (Fourthpel, y*4, x*4));
  539. }
  540. /*!
  541.  ************************************************************************
  542.  * brief
  543.  *    Upsample 4 times, store them in out4x.  Color is simply copied
  544.  *
  545.  * par Input:
  546.  *    srcy, srcu, srcv, out4y, out4u, out4v
  547.  *
  548.  * par Side Effects_
  549.  *    Uses (writes) img4Y_tmp.  This should be moved to a static variable
  550.  *    in this module
  551.  ************************************************************************/
  552. void UnifiedOneForthPix (pel_t **imgY, pel_t** imgU, pel_t **imgV,
  553.                          pel_t **out4Y, pel_t **outU, pel_t **outV,
  554.                          pel_t *ref11)
  555. {
  556.   int is;
  557.   int i,j,j4;
  558.   int ie2,je2,jj,maxy;
  559.   for (j=-IMG_PAD_SIZE; j < img->height+IMG_PAD_SIZE; j++)
  560.   {
  561.     for (i=-IMG_PAD_SIZE; i < img->width+IMG_PAD_SIZE; i++)
  562.     {
  563.       jj = max(0,min(img->height-1,j));
  564.       is=(ONE_FOURTH_TAP[0][0]*(imgY[jj][max(0,min(img->width-1,i  ))]+imgY[jj][max(0,min(img->width-1,i+1))])+
  565.           ONE_FOURTH_TAP[1][0]*(imgY[jj][max(0,min(img->width-1,i-1))]+imgY[jj][max(0,min(img->width-1,i+2))])+
  566.           ONE_FOURTH_TAP[2][0]*(imgY[jj][max(0,min(img->width-1,i-2))]+imgY[jj][max(0,min(img->width-1,i+3))]));
  567.       img4Y_tmp[j+IMG_PAD_SIZE][(i+IMG_PAD_SIZE)*2  ]=imgY[jj][max(0,min(img->width-1,i))]*1024;    // 1/1 pix pos
  568.       img4Y_tmp[j+IMG_PAD_SIZE][(i+IMG_PAD_SIZE)*2+1]=is*32;              // 1/2 pix pos
  569.     }
  570.   }
  571.   
  572.   for (i=0; i < (img->width+2*IMG_PAD_SIZE)*2; i++)
  573.   {
  574.     for (j=0; j < img->height+2*IMG_PAD_SIZE; j++)
  575.     {
  576.       j4=j*4;
  577.       maxy = img->height+2*IMG_PAD_SIZE-1;
  578.       // change for TML4, use 6 TAP vertical filter
  579.       is=(ONE_FOURTH_TAP[0][0]*(img4Y_tmp[j         ][i]+img4Y_tmp[min(maxy,j+1)][i])+
  580.           ONE_FOURTH_TAP[1][0]*(img4Y_tmp[max(0,j-1)][i]+img4Y_tmp[min(maxy,j+2)][i])+
  581.           ONE_FOURTH_TAP[2][0]*(img4Y_tmp[max(0,j-2)][i]+img4Y_tmp[min(maxy,j+3)][i]))/32;
  582.       PutPel_14 (out4Y, (j-IMG_PAD_SIZE)*4,   (i-IMG_PAD_SIZE*2)*2,(pel_t) max(0,min(255,(int)((img4Y_tmp[j][i]+512)/1024))));     // 1/2 pix
  583.       PutPel_14 (out4Y, (j-IMG_PAD_SIZE)*4+2, (i-IMG_PAD_SIZE*2)*2,(pel_t) max(0,min(255,(int)((is+512)/1024)))); // 1/2 pix
  584.     }
  585.   }
  586.   /* 1/4 pix */
  587.   /* luma */
  588.   ie2=(img->width+2*IMG_PAD_SIZE-1)*4;
  589.   je2=(img->height+2*IMG_PAD_SIZE-1)*4;
  590.   for (j=0;j<je2+4;j+=2)
  591.     for (i=0;i<ie2+3;i+=2) {
  592.       /*  '-'  */
  593.       PutPel_14 (out4Y, j-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4+1, (pel_t) (max(0,min(255,(int)(FastPelY_14(out4Y, j-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4)+FastPelY_14(out4Y, j-IMG_PAD_SIZE*4, min(ie2+2,i+2)-IMG_PAD_SIZE*4))/2))));
  594.     }
  595.   for (i=0;i<ie2+4;i++)
  596.   {
  597.     for (j=0;j<je2+3;j+=2)
  598.     {
  599.       if( i%2 == 0 ) {
  600.         /*  '|'  */
  601.         PutPel_14 (out4Y, j-IMG_PAD_SIZE*4+1, i-IMG_PAD_SIZE*4, (pel_t)(max(0,min(255,(int)(FastPelY_14(out4Y, j-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4)+FastPelY_14(out4Y, min(je2+2,j+2)-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4))/2))));
  602.       }
  603.       else if( ((i&3) == 3)&&(((j+1)&3) == 3))
  604.       {
  605.         /* "funny posision" */
  606.         PutPel_14 (out4Y, j-IMG_PAD_SIZE*4+1, i-IMG_PAD_SIZE*4, (pel_t) ((
  607.           FastPelY_14 (out4Y, j-IMG_PAD_SIZE*4-2, i-IMG_PAD_SIZE*4-3) +
  608.           FastPelY_14 (out4Y, min(je2,j+2)-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4-3) +
  609.           FastPelY_14 (out4Y, j-IMG_PAD_SIZE*4-2, min(ie2,i+1)-IMG_PAD_SIZE*4) +
  610.           FastPelY_14 (out4Y, min(je2,j+2)-IMG_PAD_SIZE*4, min(ie2,i+1)-IMG_PAD_SIZE*4)
  611.           + 2 )/4));
  612.       }
  613.       else if ((j%4 == 0 && i%4 == 1) || (j%4 == 2 && i%4 == 3)) {
  614.         /*  '/'  */
  615.         PutPel_14 (out4Y, j-IMG_PAD_SIZE*4+1, i-IMG_PAD_SIZE*4, (pel_t)(max(0,min(255,(int)(
  616.                    FastPelY_14 (out4Y, j-IMG_PAD_SIZE*4, min(ie2+2,i+1)-IMG_PAD_SIZE*4) +
  617.                    FastPelY_14(out4Y, min(je2+2,j+2)-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4-1))/2))));
  618.       }
  619.       else {
  620.         /*  ''  */
  621.         PutPel_14 (out4Y, j-IMG_PAD_SIZE*4+1, i-IMG_PAD_SIZE*4, (pel_t)(max(0,min(255,(int)(
  622.           FastPelY_14 (out4Y, j-IMG_PAD_SIZE*4, i-IMG_PAD_SIZE*4-1) +
  623.           FastPelY_14(out4Y, min(je2+2,j+2)-IMG_PAD_SIZE*4, min(ie2+2,i+1)-IMG_PAD_SIZE*4))/2))));
  624.       }
  625.     }
  626.   }
  627.   /*  Chroma: */
  628.   for (j=0; j < img->height_cr; j++) {
  629.     memcpy(outU[j],imgUV[0][j],img->width_cr); // just copy 1/1 pix, interpolate "online" 
  630.     memcpy(outV[j],imgUV[1][j],img->width_cr);
  631.   }
  632.   // Generate 1/1th pel representation (used for integer pel MV search)
  633.   GenerateFullPelRepresentation (out4Y, ref11, img->width, img->height);
  634. }
  635. /*!
  636.  ************************************************************************
  637.  * brief
  638.  *    Upsample 4 times for 1/8-pel estimation and store in buffer
  639.  *    for multiple reference frames. 1/8-pel resolution is calculated
  640.  *    during the motion estimation on the fly with bilinear interpolation.
  641.  *
  642.  ************************************************************************
  643.  */
  644. void oneeighthpix(int prior_B_frame)
  645. {
  646.   static int h1[8] = {  -3, 12, -37, 229,  71, -21,  6, -1 };  
  647.   static int h2[8] = {  -3, 12, -39, 158, 158, -39, 12, -3 };  
  648.   static int h3[8] = {  -1,  6, -21,  71, 229, -37, 12, -3 };  
  649.   int uv,x,y,y1,x4,y4,x4p;
  650.   int nx_out, ny_out, nx_1, ny_1, maxy;
  651.   int i0,i1,i2,i3;
  652.   img->frame_cycle=img->number % img->buf_cycle;  /*GH input->no_multpred used insteadof MAX_MULT_PRED
  653.                                                   frame buffer size = input->no_multpred+1*/
  654.   nx_out = 4*img->width;
  655.   ny_out = 4*img->height;
  656.   nx_1   = img->width-1;
  657.   ny_1   = img->height-1;
  658.   //horizontal filtering filtering
  659.   for(y=-IMG_PAD_SIZE;y<img->height+IMG_PAD_SIZE;y++)
  660.   {
  661.     for(x=-IMG_PAD_SIZE;x<img->width+IMG_PAD_SIZE;x++)
  662.     {
  663.       y1 = max(0,min(ny_1,y));
  664.       i0=(256*imgY[y1][max(0,min(nx_1,x))]);
  665.       
  666.       i1=(
  667.         h1[0]* imgY[y1][max(0,min(nx_1,x-3))]  +
  668.         h1[1]* imgY[y1][max(0,min(nx_1,x-2))]  +
  669.         h1[2]* imgY[y1][max(0,min(nx_1,x-1))]  +
  670.         h1[3]* imgY[y1][max(0,min(nx_1,x  ))]  +
  671.         h1[4]* imgY[y1][max(0,min(nx_1,x+1))]  +
  672.         h1[5]* imgY[y1][max(0,min(nx_1,x+2))]  +
  673.         h1[6]* imgY[y1][max(0,min(nx_1,x+3))]  +                         
  674.         h1[7]* imgY[y1][max(0,min(nx_1,x+4))] );
  675.       
  676.       
  677.       i2=(
  678.         h2[0]* imgY[y1][max(0,min(nx_1,x-3))]  +
  679.         h2[1]* imgY[y1][max(0,min(nx_1,x-2))]  +
  680.         h2[2]* imgY[y1][max(0,min(nx_1,x-1))]  +
  681.         h2[3]* imgY[y1][max(0,min(nx_1,x  ))]  +
  682.         h2[4]* imgY[y1][max(0,min(nx_1,x+1))]  +
  683.         h2[5]* imgY[y1][max(0,min(nx_1,x+2))]  +
  684.         h2[6]* imgY[y1][max(0,min(nx_1,x+3))]  +                         
  685.         h2[7]* imgY[y1][max(0,min(nx_1,x+4))] );
  686.       
  687.       
  688.       i3=(
  689.         h3[0]* imgY[y1][max(0,min(nx_1,x-3))]  +
  690.         h3[1]* imgY[y1][max(0,min(nx_1,x-2))]  +
  691.         h3[2]* imgY[y1][max(0,min(nx_1,x-1))]  +
  692.         h3[3]* imgY[y1][max(0,min(nx_1,x  ))]  +
  693.         h3[4]* imgY[y1][max(0,min(nx_1,x+1))]  +
  694.         h3[5]* imgY[y1][max(0,min(nx_1,x+2))]  +
  695.         h3[6]* imgY[y1][max(0,min(nx_1,x+3))]  +                         
  696.         h3[7]* imgY[y1][max(0,min(nx_1,x+4))] );
  697.       
  698.       x4=(x+IMG_PAD_SIZE)*4;
  699.       img4Y_tmp[y+IMG_PAD_SIZE][x4  ] = i0;
  700.       img4Y_tmp[y+IMG_PAD_SIZE][x4+1] = i1;
  701.       img4Y_tmp[y+IMG_PAD_SIZE][x4+2] = i2;
  702.       img4Y_tmp[y+IMG_PAD_SIZE][x4+3] = i3;
  703.     }
  704.   }
  705.   maxy = img->height+2*IMG_PAD_SIZE-1;
  706.   for(x4=0;x4<nx_out+2*IMG_PAD_SIZE*4;x4++)
  707.   {
  708.     for(y=0;y<=maxy;y++)
  709.     {
  710.       i0=(long int)(img4Y_tmp[y][x4]+256/2)/256;
  711.       
  712.       i1=(long int)( 
  713.         h1[0]* img4Y_tmp[max(0   ,y-3)][x4]+
  714.         h1[1]* img4Y_tmp[max(0   ,y-2)][x4]+
  715.         h1[2]* img4Y_tmp[max(0   ,y-1)][x4]+
  716.         h1[3]* img4Y_tmp[y][x4]            +
  717.         h1[4]* img4Y_tmp[min(maxy,y+1)][x4]+
  718.         h1[5]* img4Y_tmp[min(maxy,y+2)][x4]+
  719.         h1[6]* img4Y_tmp[min(maxy,y+3)][x4]+ 
  720.         h1[7]* img4Y_tmp[min(maxy,y+4)][x4]+ 256*256/2 ) / (256*256);
  721.       
  722.       i2=(long int)( 
  723.         h2[0]* img4Y_tmp[max(0   ,y-3)][x4]+
  724.         h2[1]* img4Y_tmp[max(0   ,y-2)][x4]+
  725.         h2[2]* img4Y_tmp[max(0   ,y-1)][x4]+
  726.         h2[3]* img4Y_tmp[y][x4]            +
  727.         h2[4]* img4Y_tmp[min(maxy,y+1)][x4]+
  728.         h2[5]* img4Y_tmp[min(maxy,y+2)][x4]+
  729.         h2[6]* img4Y_tmp[min(maxy,y+3)][x4]+ 
  730.         h2[7]* img4Y_tmp[min(maxy,y+4)][x4]+ 256*256/2 ) / (256*256);
  731.       
  732.       i3=(long int)( 
  733.         h3[0]* img4Y_tmp[max(0   ,y-3)][x4]+
  734.         h3[1]* img4Y_tmp[max(0   ,y-2)][x4]+
  735.         h3[2]* img4Y_tmp[max(0   ,y-1)][x4]+
  736.         h3[3]* img4Y_tmp[y][x4]            +
  737.         h3[4]* img4Y_tmp[min(maxy,y+1)][x4]+
  738.         h3[5]* img4Y_tmp[min(maxy,y+2)][x4]+
  739.         h3[6]* img4Y_tmp[min(maxy,y+3)][x4]+ 
  740.         h3[7]* img4Y_tmp[min(maxy,y+4)][x4]+ 256*256/2 ) / (256*256);
  741.       
  742.       y4  = (y-IMG_PAD_SIZE)*4;
  743.       x4p = x4-IMG_PAD_SIZE*4;
  744.   
  745.       if(prior_B_frame)
  746.       {
  747.         PutPel_14 (mref_P, y4,   x4p, (pel_t) max(0,min(255,i0)));   
  748.         PutPel_14 (mref_P, y4+1, x4p, (pel_t) max(0,min(255,i1)));   
  749.         PutPel_14 (mref_P, y4+2, x4p, (pel_t) max(0,min(255,i2)));   
  750.         PutPel_14 (mref_P, y4+3, x4p, (pel_t) max(0,min(255,i3)));   
  751.       }
  752.       else
  753.       {
  754.         PutPel_14 (mref[img->frame_cycle], y4,   x4p, (pel_t) max(0,min(255,i0)));   
  755.         PutPel_14 (mref[img->frame_cycle], y4+1, x4p, (pel_t) max(0,min(255,i1)));   
  756.         PutPel_14 (mref[img->frame_cycle], y4+2, x4p, (pel_t) max(0,min(255,i2)));
  757.         PutPel_14 (mref[img->frame_cycle], y4+3, x4p, (pel_t) max(0,min(255,i3)));   
  758.       }
  759.     }
  760.   }
  761.   if(!prior_B_frame)
  762.   {
  763.     for(y=0;y<img->height;y++)
  764.       for(x=0;x<img->width;x++)
  765.         PutPel_11 (Refbuf11[img->frame_cycle], y, x, FastPelY_14 (mref[img->frame_cycle], y*4, x*4));
  766.   }
  767.   // Chroma and full pel representation:
  768.   if(prior_B_frame)
  769.   {
  770.     for (uv=0; uv < 2; uv++)
  771.       for (y=0; y < img->height_cr; y++)
  772.         memcpy(mcef_P[uv][y],imgUV[uv][y],img->width_cr); // just copy 1/1 pix, interpolate "online"
  773.     GenerateFullPelRepresentation (mref_P, Refbuf11_P, img->width, img->height);
  774.   }
  775.   else
  776.   {
  777.     for (uv=0; uv < 2; uv++)
  778.       for (y=0; y < img->height_cr; y++)
  779.         memcpy(mcef[img->frame_cycle][uv][y],imgUV[uv][y],img->width_cr); // just copy 1/1 pix, interpolate "online"
  780.     GenerateFullPelRepresentation (mref[img->frame_cycle], Refbuf11[img->frame_cycle], img->width, img->height);
  781.   }
  782.     // Generate 1/1th pel representation (used for integer pel MV search)
  783. }
  784. /*!
  785.  ************************************************************************
  786.  * brief
  787.  *    Find SNR for all three components
  788.  ************************************************************************
  789.  */
  790. void find_snr()
  791. {
  792.   int i,j;
  793.   int diff_y,diff_u,diff_v;
  794.   int impix;
  795.   //  Calculate  PSNR for Y, U and V.
  796.   //     Luma.
  797.   impix = img->height*img->width;
  798.   diff_y=0;
  799.   for (i=0; i < img->width; ++i)
  800.   {
  801.     for (j=0; j < img->height; ++j)
  802.     {
  803.       diff_y += img->quad[abs(imgY_org[j][i]-imgY[j][i])];
  804.     }
  805.   }
  806.   //     Chroma.
  807.   diff_u=0;
  808.   diff_v=0;
  809.   for (i=0; i < img->width_cr; i++)
  810.   {
  811.     for (j=0; j < img->height_cr; j++)
  812.     {
  813.       diff_u += img->quad[abs(imgUV_org[0][j][i]-imgUV[0][j][i])];
  814.       diff_v += img->quad[abs(imgUV_org[1][j][i]-imgUV[1][j][i])];
  815.     }
  816.   }
  817.   //  Collecting SNR statistics
  818.   if (diff_y != 0)
  819.   {
  820.     snr->snr_y=(float)(10*log10(65025*(float)impix/(float)diff_y));        // luma snr for current frame
  821.     snr->snr_u=(float)(10*log10(65025*(float)impix/(float)(4*diff_u)));    // u croma snr for current frame, 1/4 of luma samples
  822.     snr->snr_v=(float)(10*log10(65025*(float)impix/(float)(4*diff_v)));    // v croma snr for current frame, 1/4 of luma samples
  823.   }
  824.   if (img->number == 0)
  825.   {
  826.     snr->snr_y1=(float)(10*log10(65025*(float)impix/(float)diff_y));       // keep luma snr for first frame
  827.     snr->snr_u1=(float)(10*log10(65025*(float)impix/(float)(4*diff_u)));   // keep croma u snr for first frame
  828.     snr->snr_v1=(float)(10*log10(65025*(float)impix/(float)(4*diff_v)));   // keep croma v snr for first frame
  829.     snr->snr_ya=snr->snr_y1;
  830.     snr->snr_ua=snr->snr_u1;
  831.     snr->snr_va=snr->snr_v1;
  832.   }
  833.   // B pictures
  834.   else
  835.   {
  836.     snr->snr_ya=(float)(snr->snr_ya*(img->number+Bframe_ctr)+snr->snr_y)/(img->number+Bframe_ctr+1);   // average snr lume for all frames inc. first
  837.     snr->snr_ua=(float)(snr->snr_ua*(img->number+Bframe_ctr)+snr->snr_u)/(img->number+Bframe_ctr+1);   // average snr u croma for all frames inc. first
  838.     snr->snr_va=(float)(snr->snr_va*(img->number+Bframe_ctr)+snr->snr_v)/(img->number+Bframe_ctr+1);   // average snr v croma for all frames inc. first
  839.   }
  840. }
  841. /*!
  842.  ************************************************************************
  843.  * brief
  844.  *    Just a placebo
  845.  ************************************************************************
  846.  */
  847. Boolean dummy_slice_too_big(int bits_slice)
  848. {
  849.   return FALSE;
  850. }