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

流媒体/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 decoder.c
  35.  *
  36.  * brief
  37.  *    Contains functions that implement the "decoders in the encoder" concept for the
  38.  *    rate-distortion optimization with losses.
  39.  * date
  40.  *    October 22nd, 2001
  41.  *
  42.  * author
  43.  *    Main contributors (see contributors.h for copyright, address and 
  44.  *    affiliation details)
  45.  *    - Dimitrios Kontopodis                    <dkonto@eikon.tum.de>
  46.  *************************************************************************************
  47.  */
  48. #include <stdlib.h>
  49. #include <memory.h>
  50. #include "global.h"
  51. #include "refbuf.h"
  52. #include "rdopt.h"
  53. /*! 
  54.  *************************************************************************************
  55.  * brief
  56.  *    decodes one macroblock at one simulated decoder 
  57.  *
  58.  * param decoder
  59.  *    The id of the decoder
  60.  *
  61.  * param mode
  62.  *    encoding mode of the MB
  63.  *
  64.  * param ref
  65.  *    reference frame index
  66.  *
  67.  * note
  68.  *    Gives the expected value in the decoder of one MB. This is done based on the 
  69.  *    stored reconstructed residue resY[][], the reconstructed values imgY[][]
  70.  *    and the motion vectors. The decoded MB is moved to decY[][].
  71.  *************************************************************************************
  72.  */
  73. void decode_one_macroblock(int decoder, int mode, int ref)
  74. {
  75.   int i,j,block_y,block_x;
  76.   int ref_inx;
  77.   int mv[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE];
  78.   int resY_tmp[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
  79.   int inter = (mode >= MBMODE_INTER16x16    && mode <= MBMODE_INTER4x4    && img->type!=B_IMG);
  80.   if (img->number==0)
  81.   {
  82.     for(i=0;i<MB_BLOCK_SIZE;i++)
  83.       for(j=0;j<MB_BLOCK_SIZE;j++)
  84.         decY[decoder][img->pix_y+j][img->pix_x+i]=imgY[img->pix_y+j][img->pix_x+i];
  85.   }
  86.   else
  87.   {
  88.     if (mode==MBMODE_COPY)
  89.     {
  90.       for(i=0;i<MB_BLOCK_SIZE;i++)
  91.         for(j=0;j<MB_BLOCK_SIZE;j++)
  92.           resY_tmp[j][i]=0;
  93.       /* Set motion vectors to zero */
  94.       for (block_y=0; block_y<BLOCK_MULTIPLE; block_y++)
  95.         for (block_x=0; block_x<BLOCK_MULTIPLE; block_x++)
  96.           for (i=0;i<2;i++)
  97.             mv[i][block_y][block_x]=0;
  98.     }
  99.     else
  100.     {
  101.     /* Copy motion vectors and residues to local arrays mv, resY_tmp, resUV_tmp */
  102.       for (block_y=0; block_y<BLOCK_MULTIPLE; block_y++)
  103.         for (block_x=0; block_x<BLOCK_MULTIPLE; block_x++)
  104.           for (i=0;i<2;i++)
  105.             mv[i][block_y][block_x]=tmp_mv[i][img->block_y+block_y][img->block_x+block_x+4];
  106.           
  107.       for(i=0;i<MB_BLOCK_SIZE;i++)
  108.         for(j=0;j<MB_BLOCK_SIZE;j++)
  109.           resY_tmp[j][i]=resY[j][i];
  110.     }
  111.   
  112.     
  113.     /* Decode Luminance */
  114.     if (inter || mode==MBMODE_COPY)  
  115.     {
  116.       for (block_y=img->block_y ; block_y < img->block_y+BLOCK_MULTIPLE ; block_y++)
  117.         for (block_x=img->block_x ; block_x < img->block_x+BLOCK_MULTIPLE ; block_x++)
  118.         {
  119.           ref_inx = (img->number-ref-1)%img->no_multpred;
  120.           
  121.           Get_Reference_Block(decref[decoder][ref_inx],
  122.                                 block_y, block_x,
  123.                                 mv[0][block_y-img->block_y][block_x-img->block_x],
  124.                                 mv[1][block_y-img->block_y][block_x-img->block_x], 
  125.                                 RefBlock);
  126.           for (j=0;j<BLOCK_SIZE;j++)
  127.             for (i=0;i<BLOCK_SIZE;i++)
  128.             {
  129.               if (RefBlock[j][i] != UMVPelY_14 (mref[ref_inx],
  130.                                                 (block_y*4+j)*4+mv[1][block_y-img->block_y][block_x-img->block_x],
  131.                                                 (block_x*4+i)*4+mv[0][block_y-img->block_y][block_x-img->block_x]))
  132.               ref_inx = (img->number-ref-1)%img->no_multpred;
  133.               decY[decoder][block_y*BLOCK_SIZE + j][block_x*BLOCK_SIZE + i] = 
  134.                                   resY_tmp[(block_y-img->block_y)*BLOCK_SIZE + j]
  135.                                           [(block_x-img->block_x)*BLOCK_SIZE + i]
  136.                                   + RefBlock[j][i];
  137.             }
  138.         }
  139.     }
  140.     else 
  141.     {
  142.       /* Intra Refresh - Assume no spatial prediction */
  143.       for (j=0;j<MB_BLOCK_SIZE;j++)
  144.         for (i=0;i<MB_BLOCK_SIZE;i++)
  145.           decY[decoder][img->pix_y + j][img->pix_x + i] = imgY[img->pix_y + j][img->pix_x + i];
  146.     }
  147.   }
  148. }
  149. /*! 
  150.  *************************************************************************************
  151.  * brief
  152.  *    Finds the reference MB given the decoded reference frame
  153.  * note
  154.  *    This is based on the function UnifiedOneForthPix, only it is modified to
  155.  *    be used at the "many decoders in the encoder" RD optimization. In this case
  156.  *    we dont want to keep full upsampled reference frames for all decoders, so
  157.  *    we just upsample when it is necessary.
  158.  * param imY
  159.  *    The frame to be upsampled
  160.  * param block_y
  161.  *    The row of the block, whose prediction we want to find
  162.  * param block_x
  163.  *    The column of the block, whose prediction we want to track
  164.  * param mvhor
  165.  *    Motion vector, horizontal part
  166.  * param mvver
  167.  *    Motion vector, vertical part
  168.  * param out
  169.  *    Output: The prediction for the block (block_y, block_x)
  170.  *************************************************************************************
  171.  */
  172. void Get_Reference_Block(byte **imY, 
  173.                          int block_y, 
  174.                          int block_x, 
  175.                          int mvhor, 
  176.                          int mvver, 
  177.                          byte **out)
  178. {
  179.   int i,j,y,x;
  180.   y = block_y * BLOCK_SIZE * 4 + mvver;
  181.   x = block_x * BLOCK_SIZE * 4 + mvhor;
  182.   for (j=0; j<BLOCK_SIZE; j++)
  183.     for (i=0; i<BLOCK_SIZE; i++)
  184.       out[j][i] = Get_Reference_Pixel(imY, 
  185.                   max(0,min(img->mvert, y+j*4)), 
  186.                   max(0,min(img->mhor, x+i*4)));
  187. }
  188. /*! 
  189.  *************************************************************************************
  190.  * brief
  191.  *    Finds a pixel (y,x) of the upsampled reference frame
  192.  * note
  193.  *    This is based on the function UnifiedOneForthPix, only it is modified to
  194.  *    be used at the "many decoders in the encoder" RD optimization. In this case
  195.  *    we dont want to keep full upsampled reference frames for all decoders, so
  196.  *    we just upsample when it is necessary.
  197.  *************************************************************************************
  198.  */
  199. byte Get_Reference_Pixel(byte **imY, int y_pos, int x_pos)
  200. {
  201.   int dx, x;
  202.   int dy, y;
  203.   int maxold_x,maxold_y;
  204.   int result = 0, result1, result2;
  205.   int pres_x;
  206.   int pres_y; 
  207.   int tmp_res[6];
  208.   static const int COEF[6] = {
  209.     1, -5, 20, 20, -5, 1
  210.   };
  211.   dx = x_pos&3;
  212.   dy = y_pos&3;
  213.   x_pos = (x_pos-dx)/4;
  214.   y_pos = (y_pos-dy)/4;
  215.   maxold_x = img->width-1;
  216.   maxold_y = img->height-1;
  217.   if (dx == 0 && dy == 0) { /* fullpel position */
  218.     result = imY[max(0,min(maxold_y,y_pos))][max(0,min(maxold_x,x_pos))];
  219.   }
  220.   else if (dx == 3 && dy == 3) { /* funny position */
  221.     result = (imY[max(0,min(maxold_y,y_pos))  ][max(0,min(maxold_x,x_pos))  ]+
  222.               imY[max(0,min(maxold_y,y_pos))  ][max(0,min(maxold_x,x_pos+1))]+
  223.               imY[max(0,min(maxold_y,y_pos+1))][max(0,min(maxold_x,x_pos+1))]+
  224.               imY[max(0,min(maxold_y,y_pos+1))][max(0,min(maxold_x,x_pos))  ]+2)/4;
  225.   }
  226.   else { /* other positions */
  227.     if (dy == 0) {
  228.       pres_y = max(0,min(maxold_y,y_pos));
  229.       for(x=-2;x<4;x++) {
  230.         pres_x = max(0,min(maxold_x,x_pos+x));
  231.         result += imY[pres_y][pres_x]*COEF[x+2];
  232.       }
  233.       result = max(0, min(255, (result+16)/32));
  234.       if (dx == 1) {
  235.         result = (result + imY[pres_y][max(0,min(maxold_x,x_pos))])/2;
  236.       }
  237.       else if (dx == 3) {
  238.         result = (result + imY[pres_y][max(0,min(maxold_x,x_pos+1))])/2;
  239.       }
  240.     }
  241.     else if (dx == 0) {
  242.       pres_x = max(0,min(maxold_x,x_pos));
  243.       for(y=-2;y<4;y++) {
  244.         pres_y = max(0,min(maxold_y,y_pos+y));
  245.         result += imY[pres_y][pres_x]*COEF[y+2];
  246.       }
  247.       result = max(0, min(255, (result+16)/32));
  248.       if (dy == 1) {
  249.         result = (result + imY[max(0,min(maxold_y,y_pos))][pres_x])/2;
  250.       }
  251.       else if (dy == 3) {
  252.         result = (result + imY[max(0,min(maxold_y,y_pos+1))][pres_x])/2;
  253.       }
  254.     }
  255.     else if (dx == 2) {
  256.       for(y=-2;y<4;y++) {
  257.         result = 0;
  258.         pres_y = max(0,min(maxold_y,y_pos+y));
  259.         for(x=-2;x<4;x++) {
  260.           pres_x = max(0,min(maxold_x,x_pos+x));
  261.           result += imY[pres_y][pres_x]*COEF[x+2];
  262.         }
  263.         tmp_res[y+2] = result;
  264.       }
  265.       result = 0;
  266.       for(y=-2;y<4;y++) {
  267.         result += tmp_res[y+2]*COEF[y+2];
  268.       }
  269.       result = max(0, min(255, (result+512)/1024));
  270.       if (dy == 1) {
  271.         result = (result + max(0, min(255, (tmp_res[2]+16)/32)))/2;
  272.       }
  273.       else if (dy == 3) {
  274.         result = (result + max(0, min(255, (tmp_res[3]+16)/32)))/2;
  275.       }
  276.     }
  277.     else if (dy == 2) {
  278.       for(x=-2;x<4;x++) {
  279.         result = 0;
  280.         pres_x = max(0,min(maxold_x,x_pos+x));
  281.         for(y=-2;y<4;y++) {
  282.           pres_y = max(0,min(maxold_y,y_pos+y));
  283.           result += imY[pres_y][pres_x]*COEF[y+2];
  284.         }
  285.         tmp_res[x+2] = result;
  286.       }
  287.       result = 0;
  288.       for(x=-2;x<4;x++) {
  289.         result += tmp_res[x+2]*COEF[x+2];
  290.       }
  291.       result = max(0, min(255, (result+512)/1024));
  292.       if (dx == 1) {
  293.         result = (result + max(0, min(255, (tmp_res[2]+16)/32)))/2;
  294.       }
  295.       else {
  296.         result = (result + max(0, min(255, (tmp_res[3]+16)/32)))/2;
  297.       }
  298.     }
  299.     else {
  300.       result = 0;
  301.       pres_y = dy == 1 ? y_pos : y_pos+1;
  302.       pres_y = max(0,min(maxold_y,pres_y));
  303.       for(x=-2;x<4;x++) {
  304.         pres_x = max(0,min(maxold_x,x_pos+x));
  305.         result += imY[pres_y][pres_x]*COEF[x+2];
  306.       }
  307.       result1 = max(0, min(255, (result+16)/32));
  308.       result = 0;
  309.       pres_x = dx == 1 ? x_pos : x_pos+1;
  310.       pres_x = max(0,min(maxold_x,pres_x));
  311.       for(y=-2;y<4;y++) {
  312.         pres_y = max(0,min(maxold_y,y_pos+y));
  313.         result += imY[pres_y][pres_x]*COEF[y+2];
  314.       }
  315.       result2 = max(0, min(255, (result+16)/32));
  316.       result = (result1+result2)/2;
  317.     }
  318.   }
  319.   return result;
  320. }
  321.   
  322. /*! 
  323.  *************************************************************************************
  324.  * brief
  325.  *    Performs the simulation of the packet losses, calls the error concealment funcs
  326.  *    and copies the decoded images to the reference frame buffers of the decoders 
  327.  *
  328.  *************************************************************************************
  329.  */
  330. void UpdateDecoders()
  331. {
  332.   int k;
  333.   for (k=0; k<input->NoOfDecoders; k++)
  334.   {
  335.     Build_Status_Map(status_map); // simulates the packet losses
  336.     Error_Concealment(decY_best[k], status_map, decref[k]); // for the moment error concealment is just a "copy"
  337.     // Move decoded frames to reference buffers: (at the decoders this is done 
  338.     // without interpolation (upsampling) - upsampling is done while decoding
  339.     DecOneForthPix(decY_best[k], decref[k]); 
  340.   }
  341. }
  342. /*! 
  343.  *************************************************************************************
  344.  * brief
  345.  *    Copies one (reconstructed) image to the respective reference frame buffer
  346.  *
  347.  * note
  348.  *    This is used at the "many decoders in the encoder"
  349.  * param dY
  350.  *    The reconstructed image
  351.  * param dref
  352.  *    The reference buffer
  353.  *************************************************************************************
  354.  */
  355. void DecOneForthPix(byte **dY, byte ***dref)
  356. {
  357.   int j, ref=img->number%img->buf_cycle;
  358.   for (j=0; j<img->height; j++)
  359.     memcpy(dref[ref][j], dY[j], img->width);
  360. }
  361. /*! 
  362.  *************************************************************************************
  363.  * brief
  364.  *    Gives the prediction residue for this MB.
  365.  *
  366.  * param mode
  367.  *    The encoding mode of this MB.
  368.  *************************************************************************************
  369.  */
  370. void compute_residue(int mode)
  371. {
  372.   int i,j;
  373.   if (mode == MBMODE_INTRA16x16)  /* Intra 16 MB*/
  374.     for (i=0; i<MB_BLOCK_SIZE; i++)
  375.       for (j=0; j<MB_BLOCK_SIZE; j++)
  376.         resY[j][i] = imgY[img->pix_y+j][img->pix_x+i]-img->mprr_2[mode][j][i]; /* SOS: Is this correct? or maybe mprr_2[][i][j] ??*/
  377.   else
  378.     for (i=0; i<MB_BLOCK_SIZE; i++)  /* Inter MB */
  379.       for (j=0; j<MB_BLOCK_SIZE; j++)
  380.         resY[j][i] = imgY[img->pix_y+j][img->pix_x+i]-img->mpr[i][j];
  381. }
  382. /*! 
  383.  *************************************************************************************
  384.  * brief
  385.  *    Builds a random status map showing whether each MB is received or lost, based
  386.  *    on the packet loss rate and the slice structure.
  387.  *
  388.  * param s_map
  389.  *    The status map to be filled
  390.  *************************************************************************************
  391.  */
  392. void Build_Status_Map(byte **s_map)
  393. {
  394.   int i,j,slice=-1,mb=0,jj,ii,packet_lost;
  395.   jj = img->height/MB_BLOCK_SIZE;
  396.   ii = img->width/MB_BLOCK_SIZE;
  397.   for (j=0 ; j<jj; j++)
  398.     for (i=0 ; i<ii; i++)
  399.     {
  400.       if (!input->slice_mode || img->mb_data[mb].slice_nr != slice) /* new slice */
  401.       {
  402.         if ((double)rand()/(double)RAND_MAX*100 < input->LossRate)
  403.           packet_lost=1;
  404.         else
  405.           packet_lost=0;
  406.         
  407.         slice++;
  408.       }
  409.       if (packet_lost)
  410.         s_map[j][i]=0;
  411.       else
  412.         s_map[j][i]=1;
  413.       mb++;
  414.     }
  415. }
  416. /*! 
  417.  *************************************************************************************
  418.  * brief
  419.  *    Performs some sort of error concealment for the areas that are lost according
  420.  *    to the status_map
  421.  *    
  422.  * param inY
  423.  *    Error concealment is performed on this frame imY[][]
  424.  * param s_map
  425.  *    The status map shows which areas are lost.
  426.  * param refY
  427.  *    The set of reference frames - may be used for the error concealment.
  428.  *************************************************************************************
  429.  */
  430. void Error_Concealment(byte **inY, byte **s_map, byte ***refY)
  431. {
  432.   int mb_y, mb_x, mb_h, mb_w;
  433.   mb_h = img->height/MB_BLOCK_SIZE;
  434.   mb_w = img->width/MB_BLOCK_SIZE;
  435.   
  436.   for (mb_y=0; mb_y < mb_h; mb_y++)
  437.     for (mb_x=0; mb_x < mb_w; mb_x++)
  438.       if (!s_map[mb_y][mb_x])
  439.         Conceal_Error(inY, mb_y, mb_x, refY);
  440. }
  441. /*! 
  442.  *************************************************************************************
  443.  * brief
  444.  *    Copies a certain MB (mb_y,mb_x) of the frame inY[][] from the previous frame.
  445.  *    For the time there is no better EC...
  446.  *************************************************************************************
  447.  */
  448. void Conceal_Error(byte **inY, int mb_y, int mb_x, byte ***refY)
  449. {
  450.   int i,j;
  451.   int ref_inx = (img->number-1)%img->no_multpred;
  452.   int pos_y = mb_y*MB_BLOCK_SIZE, pos_x = mb_x*MB_BLOCK_SIZE;
  453.   if (img->number)
  454.   {
  455.     for (j=0;j<MB_BLOCK_SIZE;j++)
  456.       for (i=0;i<MB_BLOCK_SIZE;i++)
  457.         inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i];
  458.   }
  459.   else
  460.   {
  461.     for (j=0;j<MB_BLOCK_SIZE;j++)
  462.       for (i=0;i<MB_BLOCK_SIZE;i++)
  463.         inY[pos_y+j][pos_x+i] = 127;
  464.   }
  465. }