⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 b_frame.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU 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
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/

/*!
 *************************************************************************************
 * \file b_frame.c
 *
 * \brief
 *    B picture coding
 *
 * \author
 *    Main contributors (see contributors.h for copyright, address and affiliation details)
 *    - Byeong-Moon Jeon                <jeonbm@lge.com>
 *    - Yoon-Seong Soh                  <yunsung@lge.com>
 *    - Thomas Stockhammer              <stockhammer@ei.tum.de>
 *    - Detlev Marpe                    <marpe@hhi.de>
 *    - Guido Heising                   <heising@hhi.de>
 *    - Thomas Wedi                     <wedi@tnt.uni-hannover.de>
 *************************************************************************************
 */

#include <stdlib.h>
#include <math.h>
#include <memory.h>

#include "elements.h"
#include "b_frame.h"
#include "refbuf.h"


#ifdef _ADAPT_LAST_GROUP_
extern int *last_P_no;
#endif

/*!
 ************************************************************************
 * \brief
 *    Set reference frame information in global arrays
 *    depending on mode decision. Used for motion vector prediction.
 ************************************************************************
 */
void SetRefFrameInfo_B()
{
  int i,j;
  const int fw_predframe_no = img->mb_data[img->current_mb_nr].ref_frame;

  if(img->imod==B_Direct)
  {
    for (j = 0; j < 4;j++)
    {
      for (i = 0; i < 4;i++)
      {
        fw_refFrArr[img->block_y+j][img->block_x+i] =
            bw_refFrArr[img->block_y+j][img->block_x+i] = -1;
      }
    }
  }
  else
    if (img->imod == B_Forward)
    {
      for (j = 0;j < 4;j++)
      {
        for (i = 0;i < 4;i++)
        {
          fw_refFrArr[img->block_y+j][img->block_x+i] = fw_predframe_no;
          bw_refFrArr[img->block_y+j][img->block_x+i] = -1;
        }
      }
    }
    else
      if(img->imod == B_Backward)
      {
        for (j = 0;j < 4;j++)
        {
          for (i = 0;i < 4;i++)
          {
            fw_refFrArr[img->block_y+j][img->block_x+i] = -1;
            bw_refFrArr[img->block_y+j][img->block_x+i] = 0;
          }
        }
      }
      else
        if(img->imod == B_Bidirect)
        {
          for (j = 0;j < 4;j++)
          {
            for (i = 0;i < 4;i++)
            {
              fw_refFrArr[img->block_y+j][img->block_x+i] = fw_predframe_no;
              bw_refFrArr[img->block_y+j][img->block_x+i] = 0;
            }
          }
        }
        else // 4x4-, 16x16-intra
        {
          for (j = 0;j < 4;j++)
          {
            for (i = 0;i < 4;i++)
            {
              fw_refFrArr[img->block_y+j][img->block_x+i] =
                bw_refFrArr[img->block_y+j][img->block_x+i] = -1;
            }
          }
        }

}


/*!
 ************************************************************************
 * \brief
 *    Performs DCT, quantization, run/level pre-coding and IDCT
 *    for the MC-compensated MB residue of a B-frame;
 *    current cbp (for LUMA only) is affected
 ************************************************************************
 */
void LumaResidualCoding_B()
{
  int cbp_mask, cbp_blk_mask, sum_cnt_nonz, coeff_cost, nonzero;
  int mb_y, mb_x, block_y, block_x, i, j, pic_pix_y, pic_pix_x, pic_block_x, pic_block_y;
  int ii4, jj4, iii4, jjj4, i2, j2, fw_pred, bw_pred, ref_inx, df_pred, db_pred;
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];


  switch(img->imod)
  {
    case B_Forward :
      currMB->cbp     = 0 ;
      currMB->cbp_blk = 0 ;
      sum_cnt_nonz    = 0 ;

      for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2)
      {
        for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2)
        {
          cbp_mask=(int)pow(2,(mb_x/8+mb_y/4));
          coeff_cost=0;
          for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE)
          {
            pic_pix_y=img->pix_y+block_y;
            pic_block_y=pic_pix_y/BLOCK_SIZE;
            for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE)
            {
              cbp_blk_mask = (block_x>>2)+ block_y ;
              pic_pix_x=img->pix_x+block_x;
              pic_block_x=pic_pix_x/BLOCK_SIZE;

              img->ipredmode[pic_block_x+1][pic_block_y+1]=0;

              if(input->mv_res)
              {
                ii4=(img->pix_x+block_x)*8+tmp_fwMV[0][pic_block_y][pic_block_x+4];
                jj4=(img->pix_y+block_y)*8+tmp_fwMV[1][pic_block_y][pic_block_x+4];

                for (j=0;j<4;j++)
                {
                  j2=j*8;
                  for (i=0;i<4;i++)
                  {
                    i2=i*8;
                    img->mpr[i+block_x][j+block_y]=UMVPelY_18 (mref[img->fw_multframe_no], jj4+j2, ii4+i2); // refbuf
                  }
                }
              }
              else
              {
                ii4=(img->pix_x+block_x)*4+tmp_fwMV[0][pic_block_y][pic_block_x+4];
                jj4=(img->pix_y+block_y)*4+tmp_fwMV[1][pic_block_y][pic_block_x+4];

                for (j=0;j<4;j++)
                {
                  j2=j*4;
                  for (i=0;i<4;i++)
                  {
                    i2=i*4;
                    img->mpr[i+block_x][j+block_y]=UMVPelY_14 (mref[img->fw_multframe_no], jj4+j2, ii4+i2); // refbuf
                  }
                }
              }

              for (j=0; j < BLOCK_SIZE; j++)
              {
                for (i=0; i < BLOCK_SIZE; i++)
                {
                  img->m7[i][j]=
                    imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i]-img->mpr[i+block_x][j+block_y];
                }
              }
              nonzero=dct_luma(block_x,block_y,&coeff_cost);
              if (nonzero)
              {
                currMB->cbp_blk |= 1 << cbp_blk_mask ;            // one bit for every 4x4 block
                currMB->cbp     |= cbp_mask;
              }
            } // block_x
          } // block_y

          if (coeff_cost > 3)
          {
            sum_cnt_nonz += coeff_cost;
          }
          else //discard
          {
            currMB->cbp     &=  (63-cbp_mask);
            currMB->cbp_blk &= ~(51 << (mb_y + (mb_x>>2) )) ;
            for (i=mb_x; i < mb_x+BLOCK_SIZE*2; i++)
            {
              for (j=mb_y; j < mb_y+BLOCK_SIZE*2; j++)
              {
                imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];
              }
            }
          }
        } // mb_x
      } // mb_y

      if (sum_cnt_nonz <= 5 )
      {
        currMB->cbp     &= 0xfffff0 ;
        currMB->cbp_blk &= 0xff0000 ;
        for (i=0; i < MB_BLOCK_SIZE; i++)
        {
          for (j=0; j < MB_BLOCK_SIZE; j++)
          {
            imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];
          }
        }
      }
      break;

    case B_Backward :
      currMB->cbp     = 0 ;
      currMB->cbp_blk = 0 ;
      sum_cnt_nonz    = 0 ;

      for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2)
      {
        for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2)
        {
          cbp_mask=(int)pow(2,(mb_x/8+mb_y/4));
          coeff_cost=0;
          for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE)
          {
            pic_pix_y=img->pix_y+block_y;
            pic_block_y=pic_pix_y/BLOCK_SIZE;
            for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE)
            {
              cbp_blk_mask = (block_x>>2)+ block_y ;
              pic_pix_x=img->pix_x+block_x;
              pic_block_x=pic_pix_x/BLOCK_SIZE;

              img->ipredmode[pic_block_x+1][pic_block_y+1]=0;

              if(input->mv_res)
              {
                iii4=(img->pix_x+block_x)*8+tmp_bwMV[0][pic_block_y][pic_block_x+4];
                jjj4=(img->pix_y+block_y)*8+tmp_bwMV[1][pic_block_y][pic_block_x+4];

                for (j=0;j<4;j++)
                {
                  j2=j*8;
                  for (i=0;i<4;i++)
                  {
                    i2=i*8;
                    img->mpr[i+block_x][j+block_y]=UMVPelY_18 (mref_P, jjj4+j2, iii4+i2); // refbuf
                  }
                }
              }
              else
              {
                iii4=(img->pix_x+block_x)*4+tmp_bwMV[0][pic_block_y][pic_block_x+4];
                jjj4=(img->pix_y+block_y)*4+tmp_bwMV[1][pic_block_y][pic_block_x+4];

                for (j=0;j<4;j++)
                {
                  j2=j*4;
                  for (i=0;i<4;i++)
                  {
                    i2=i*4;
                    img->mpr[i+block_x][j+block_y]=UMVPelY_14 (mref_P, jjj4+j2, iii4+i2); // refbuf
                  }
                }
              }

              for (j=0; j < BLOCK_SIZE; j++)
              {
                for (i=0; i < BLOCK_SIZE; i++)
                {
                  img->m7[i][j]=
                    imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i]-img->mpr[i+block_x][j+block_y];
                }
              }
              nonzero=dct_luma(block_x,block_y,&coeff_cost);
              if (nonzero)
              {
                currMB->cbp_blk |= 1 << cbp_blk_mask ;            // one bit for every 4x4 block
                currMB->cbp     |= cbp_mask;
              }
            } // block_x
          } // block_y

          if (coeff_cost > 3)
          {
            sum_cnt_nonz += coeff_cost;
          }
          else //discard
          {
            currMB->cbp     &= (63-cbp_mask);
            currMB->cbp_blk &= ~(51 << (mb_y + (mb_x>>2) )) ;
            for (i=mb_x; i < mb_x+BLOCK_SIZE*2; i++)
            {
              for (j=mb_y; j < mb_y+BLOCK_SIZE*2; j++)
              {
                imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];
              }
            }
          }
        } // mb_x
      } // mb_y

      if (sum_cnt_nonz <= 5 )
      {
        currMB->cbp     &= 0xfffff0 ;
        currMB->cbp_blk &= 0xff0000 ;
        for (i=0; i < MB_BLOCK_SIZE; i++)
        {
          for (j=0; j < MB_BLOCK_SIZE; j++)
          {
            imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];
          }
        }
      }
      break;

    case B_Bidirect :
      currMB->cbp=0;
      currMB->cbp_blk=0;
      sum_cnt_nonz=0;
      for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2)
      {
        for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2)
        {
          cbp_mask=(int)pow(2,(mb_x/8+mb_y/4));
          coeff_cost=0;
          for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE)
          {
            pic_pix_y=img->pix_y+block_y;
            pic_block_y=pic_pix_y/BLOCK_SIZE;
            for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE)
            {
              cbp_blk_mask = (block_x>>2)+ block_y ;
              pic_pix_x=img->pix_x+block_x;
              pic_block_x=pic_pix_x/BLOCK_SIZE;

              img->ipredmode[pic_block_x+1][pic_block_y+1]=0;

              if(input->mv_res)
              {
                ii4=(img->pix_x+block_x)*8+tmp_fwMV[0][pic_block_y][pic_block_x+4];
                jj4=(img->pix_y+block_y)*8+tmp_fwMV[1][pic_block_y][pic_block_x+4];
                iii4=(img->pix_x+block_x)*8+tmp_bwMV[0][pic_block_y][pic_block_x+4];
                jjj4=(img->pix_y+block_y)*8+tmp_bwMV[1][pic_block_y][pic_block_x+4];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -