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

📄 dct_decode.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ( !pbi->display_fragments[ i + 1 ] ){
	  dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		      pbi->recon_pixel_index_table[i]+6,
		      LineLength, BoundingValuePtr);
	}

	/* Bottom done if next row set */
	if( !pbi->display_fragments[ i + LineFragments] ){
	  dsp_funcs.FilterVert(pbi->LastFrameRecon+
		     pbi->recon_pixel_index_table[i + LineFragments],
		     LineLength, BoundingValuePtr);
	}

      }
    }

    /***************************************************************/
    /* Last Column */
    if( pbi->display_fragments[i]){
      /* Filter Left edge always */
      dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		  pbi->recon_pixel_index_table[i] - 2 ,
		  LineLength, BoundingValuePtr);

      /* Bottom done if next row set */
      if( !pbi->display_fragments[ i + LineFragments] ){
	dsp_funcs.FilterVert(pbi->LastFrameRecon+
		   pbi->recon_pixel_index_table[i + LineFragments],
		   LineLength, BoundingValuePtr);
      }
    }
    i++;

    /***************************************************************/
    /* Middle Rows */
    /***************************************************************/
    for ( m = 1 ; m < FragsDown-1 ; m++) {

      /*****************************************************************/
      /* first column conditions */
      /* only do 2 prediction if fragment coded and on non intra or if
         all fragments are intra */
      if( pbi->display_fragments[i]){
	/* TopRow is always done */
	dsp_funcs.FilterVert(pbi->LastFrameRecon+
		   pbi->recon_pixel_index_table[i],
		   LineLength, BoundingValuePtr);

	/* Filter right hand border only if the block to the right is
           not coded */
	if ( !pbi->display_fragments[ i + 1 ] ){
	  dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		      pbi->recon_pixel_index_table[i] + 6,
		      LineLength, BoundingValuePtr);
	}

	/* Bottom done if next row set */
	if( !pbi->display_fragments[ i + LineFragments] ){
	  dsp_funcs.FilterVert(pbi->LastFrameRecon+
		     pbi->recon_pixel_index_table[i + LineFragments],
		     LineLength, BoundingValuePtr);
	}
      }
      i++;

      /*****************************************************************/
      /* middle columns  */
      for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){
	if( pbi->display_fragments[i]){
	  /* Filter Left edge always */
	  dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		      pbi->recon_pixel_index_table[i] - 2,
		      LineLength, BoundingValuePtr);

	  /* TopRow is always done */
	  dsp_funcs.FilterVert(pbi->LastFrameRecon+
		     pbi->recon_pixel_index_table[i],
		     LineLength, BoundingValuePtr);

	  /* Filter right hand border only if the block to the right
             is not coded */
	  if ( !pbi->display_fragments[ i + 1 ] ){
	    dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
			pbi->recon_pixel_index_table[i] + 6,
			LineLength, BoundingValuePtr);
	  }

	  /* Bottom done if next row set */
	  if( !pbi->display_fragments[ i + LineFragments] ){
	    dsp_funcs.FilterVert(pbi->LastFrameRecon+
		       pbi->recon_pixel_index_table[i + LineFragments],
		       LineLength, BoundingValuePtr);
	  }
	}
      }

      /******************************************************************/
      /* Last Column */
      if( pbi->display_fragments[i]){
	/* Filter Left edge always*/
	dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		    pbi->recon_pixel_index_table[i] - 2,
		    LineLength, BoundingValuePtr);

	/* TopRow is always done */
	dsp_funcs.FilterVert(pbi->LastFrameRecon+
		   pbi->recon_pixel_index_table[i],
		   LineLength, BoundingValuePtr);

	/* Bottom done if next row set */
	if( !pbi->display_fragments[ i + LineFragments] ){
	  dsp_funcs.FilterVert(pbi->LastFrameRecon+
		     pbi->recon_pixel_index_table[i + LineFragments],
		     LineLength, BoundingValuePtr);
	}
      }
      i++;

    }

    /*******************************************************************/
    /* Last Row  */

    /* first column conditions */
    /* only do 2 prediction if fragment coded and on non intra or if
       all fragments are intra */
    if( pbi->display_fragments[i]){

      /* TopRow is always done */
      dsp_funcs.FilterVert(pbi->LastFrameRecon+
		 pbi->recon_pixel_index_table[i],
		 LineLength, BoundingValuePtr);

      /* Filter right hand border only if the block to the right is
         not coded */
      if ( !pbi->display_fragments[ i + 1 ] ){
	dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		    pbi->recon_pixel_index_table[i] + 6,
		    LineLength, BoundingValuePtr);
      }
    }
    i++;

    /******************************************************************/
    /* middle columns  */
    for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){
      if( pbi->display_fragments[i]){
	/* Filter Left edge always */
	dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		    pbi->recon_pixel_index_table[i] - 2,
		    LineLength, BoundingValuePtr);

	/* TopRow is always done */
	dsp_funcs.FilterVert(pbi->LastFrameRecon+
		   pbi->recon_pixel_index_table[i],
		   LineLength, BoundingValuePtr);

	/* Filter right hand border only if the block to the right is
           not coded */
	if ( !pbi->display_fragments[ i + 1 ] ){
	  dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		      pbi->recon_pixel_index_table[i] + 6,
		      LineLength, BoundingValuePtr);
	}
      }
    }

    /******************************************************************/
    /* Last Column */
    if( pbi->display_fragments[i]){
      /* Filter Left edge always */
      dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
		  pbi->recon_pixel_index_table[i] - 2,
		  LineLength, BoundingValuePtr);

      /* TopRow is always done */
      dsp_funcs.FilterVert(pbi->LastFrameRecon+
		 pbi->recon_pixel_index_table[i],
		 LineLength, BoundingValuePtr);

    }
    i++;
  }
 _mm_empty();
}

void ReconRefFrames (PB_INSTANCE *pbi){
  ogg_int32_t i;
  unsigned char *SwapReconBuffersTemp;

  /* predictor multiplier up-left, up, up-right,left, shift
     Entries are packed in the order L, UL, U, UR, with missing entries
      moved to the end (before the shift parameters). */
  static const ogg_int16_t pc[16][6]={
    {0,0,0,0,0,0},
    {1,0,0,0,0,0},      /* PL */
    {1,0,0,0,0,0},      /* PUL */
    {1,0,0,0,0,0},      /* PUL|PL */
    {1,0,0,0,0,0},      /* PU */
    {1,1,0,0,1,1},      /* PU|PL */
    {0,1,0,0,0,0},      /* PU|PUL */
    {29,-26,29,0,5,31}, /* PU|PUL|PL */
    {1,0,0,0,0,0},      /* PUR */
    {75,53,0,0,7,127},  /* PUR|PL */
    {1,1,0,0,1,1},      /* PUR|PUL */
    {75,0,53,0,7,127},  /* PUR|PUL|PL */
    {1,0,0,0,0,0},      /* PUR|PU */
    {75,0,53,0,7,127},  /* PUR|PU|PL */
    {3,10,3,0,4,15},    /* PUR|PU|PUL */
    {29,-26,29,0,5,31}  /* PUR|PU|PUL|PL */
  };

  /* boundary case bit masks. */
  static const int bc_mask[8]={
    /* normal case no boundary condition */
    PUR|PU|PUL|PL,
    /* left column */
    PUR|PU,
    /* top row */
    PL,
    /* top row, left column */
    0,
    /* right column */
    PU|PUL|PL,
    /* right and left column */
    PU,
    /* top row, right column */
    PL,
    /* top row, right and left column */
    0
  };

  /* value left value up-left, value up, value up-right, missing
      values skipped. */
  int v[4];

  /* fragment number left, up-left, up, up-right */
  int fn[4];

  /* predictor count. */
  int pcount;

  short wpc;
  static const short Mode2Frame[] = {
    1,  /* CODE_INTER_NO_MV     0 => Encoded diff from same MB last frame  */
    0,  /* CODE_INTRA           1 => DCT Encoded Block */
    1,  /* CODE_INTER_PLUS_MV   2 => Encoded diff from included MV MB last frame */
    1,  /* CODE_INTER_LAST_MV   3 => Encoded diff from MRU MV MB last frame */
    1,  /* CODE_INTER_PRIOR_MV  4 => Encoded diff from included 4 separate MV blocks */
    2,  /* CODE_USING_GOLDEN    5 => Encoded diff from same MB golden frame */
    2,  /* CODE_GOLDEN_MV       6 => Encoded diff from included MV MB golden frame */
    1   /* CODE_INTER_FOUR_MV   7 => Encoded diff from included 4 separate MV blocks */
  };
  short Last[3];
  short PredictedDC;
  int FragsAcross=pbi->HFragments;
  int FromFragment,ToFragment;
  int FragsDown = pbi->VFragments;

  int WhichFrame;
  int WhichCase;
  int j,k,m,n;

  void (*ExpandBlockA) ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber );

  if ( GetFrameType(pbi) == KEY_FRAME )
    ExpandBlockA=ExpandKFBlock;
  else
    ExpandBlockA=ExpandBlock;

  SetupLoopFilter(pbi);

  /* for y,u,v */
  for ( j = 0; j < 3 ; j++) {
    /* pick which fragments based on Y, U, V */
    switch(j){
    case 0: /* y */
      FromFragment = 0;
      ToFragment = pbi->YPlaneFragments;
      FragsAcross = pbi->HFragments;
      FragsDown = pbi->VFragments;
      break;
    case 1: /* u */
      FromFragment = pbi->YPlaneFragments;
      ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      break;
    /*case 2:  v */
    default:
      FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
      ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      break;
    }

    /* initialize our array of last used DC Components */
    for(k=0;k<3;k++)
      Last[k]=0;

    i=FromFragment;

    /* do prediction on all of Y, U or V */
    for ( m = 0 ; m < FragsDown ; m++) {
      for ( n = 0 ; n < FragsAcross ; n++, i++){

	/* only do 2 prediction if fragment coded and on non intra or
           if all fragments are intra */
        if( pbi->display_fragments[i] || (GetFrameType(pbi) == KEY_FRAME) ){
	  /* Type of Fragment */
	  WhichFrame = Mode2Frame[pbi->FragCodingMethod[i]];

	  /* Check Borderline Cases */
	  WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);

          fn[0]=i-1;
          fn[1]=i-FragsAcross-1;
          fn[2]=i-FragsAcross;
          fn[3]=i-FragsAcross+1;

	    /* fragment valid for prediction use if coded and it comes
               from same frame as the one we are predicting */
          for(k=pcount=wpc=0; k<4; k++) {
            int pflag;
            pflag=1<<k;
            if((bc_mask[WhichCase]&pflag) &&
               pbi->display_fragments[fn[k]] &&
               (Mode2Frame[pbi->FragCodingMethod[fn[k]]] == WhichFrame)){
              v[pcount]=pbi->QFragData[fn[k]][0];
              wpc|=pflag;
              pcount++;
            }
	  }

	  if(wpc==0){
            /* fall back to the last coded fragment */
	      pbi->QFragData[i][0] += Last[WhichFrame];

	  }else{

	    /* don't do divide if divisor is 1 or 0 */
            PredictedDC = pc[wpc][0]*v[0];
            for(k=1; k<pcount; k++){
              PredictedDC += pc[wpc][k]*v[k];
            }

	    /* if we need to do a shift */
	    if(pc[wpc][4] != 0 ){

	      /* If negative add in the negative correction factor */
	      PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);

	      /* Shift in lieu of a divide */
	      PredictedDC >>= pc[wpc][4];
	    }

	    /* check for outranging on the two predictors that can outrange */
            if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){
              if( abs(PredictedDC - v[2]) > 128) {
                PredictedDC = v[2];
              } else if( abs(PredictedDC - v[0]) > 128) {
                PredictedDC = v[0];
              } else if( abs(PredictedDC - v[1]) > 128) {
                PredictedDC = v[1];
              }
	    }

	    pbi->QFragData[i][0] += PredictedDC;

	  }

	  /* Save the last fragment coded for whatever frame we are
             predicting from */
	  Last[WhichFrame] = pbi->QFragData[i][0];

	  /* Inverse DCT and reconstitute buffer in thisframe */
	  ExpandBlockA( pbi, i );

	}
      }
    }
  }
  _mm_empty();
  /* Copy the current reconstruction back to the last frame recon buffer. */
  if(pbi->CodedBlockIndex > (ogg_int32_t) (pbi->UnitFragments >> 1)){
    SwapReconBuffersTemp = pbi->ThisFrameRecon;
    pbi->ThisFrameRecon = pbi->LastFrameRecon;
    pbi->LastFrameRecon = SwapReconBuffersTemp;
    CopyNotRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );
  }else{
    CopyRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );
  }

  /* Apply a loop filter to edge pixels of updated blocks */
  LoopFilter(pbi);

  /* We may need to update the UMV border */
  UpdateUMVBorder(pbi, pbi->LastFrameRecon);

  /* Reconstruct the golden frame if necessary.
     For VFW codec only on key frames */
  if ( GetFrameType(pbi) == KEY_FRAME ){
    CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon );
    /* We may need to update the UMV border */
    UpdateUMVBorder(pbi, pbi->GoldenFrame);
  }
}

⌨️ 快捷键说明

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