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

📄 encode.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 4 页
字号:
  QIndex = Q_TABLE_SIZE - 1;
  while ( QIndex >= 0 ) {
    if ( (QIndex == 0) ||
	 ( cpi->pb.QThreshTable[QIndex] >= cpi->pb.ThisFrameQualityValue) )
      break;
    QIndex --;
  }


  /* Encode and tokenise the Y, U and V components */
  coded_pixels = QuadCodeComponent(cpi, 0, cpi->pb.YSBRows, cpi->pb.YSBCols,
				   cpi->pb.info.width );
  coded_pixels += QuadCodeComponent(cpi, cpi->pb.YSuperBlocks,
				    cpi->pb.UVSBRows,
				    cpi->pb.UVSBCols,
				    cpi->pb.info.width>>1 );
  coded_pixels += QuadCodeComponent(cpi,
				    cpi->pb.YSuperBlocks+cpi->pb.UVSuperBlocks,
				    cpi->pb.UVSBRows, cpi->pb.UVSBCols,
				    cpi->pb.info.width>>1 );

  /* 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 = cpi->pb.YPlaneFragments;
      FragsAcross = cpi->pb.HFragments;
      FragsDown = cpi->pb.VFragments;
      break;
    case 1: /* u */
      FromFragment = cpi->pb.YPlaneFragments;
      ToFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments ;
      FragsAcross = cpi->pb.HFragments >> 1;
      FragsDown = cpi->pb.VFragments >> 1;
      break;
    /*case 2:  v */
    default:
      FromFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments;
      ToFragment = cpi->pb.YPlaneFragments + (2 * cpi->pb.UVPlaneFragments) ;
      FragsAcross = cpi->pb.HFragments >> 1;
      FragsDown = cpi->pb.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++) {
	cpi->OriginalDC[i] = cpi->pb.QFragData[i][0];

	/* only do 2 prediction if fragment coded and on non intra or
           if all fragments are intra */
	if( cpi->pb.display_fragments[i] ||
            (GetFrameType(&cpi->pb) == KEY_FRAME) ) {
	  /* Type of Fragment */
	  WhichFrame = Mode2Frame[cpi->pb.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) &&
               cpi->pb.display_fragments[fn[k]] &&
               (Mode2Frame[cpi->pb.FragCodingMethod[fn[k]]] == WhichFrame)){
              v[pcount]=cpi->OriginalDC[fn[k]];
              wpc|=pflag;
              pcount++;
            }
	  }

	  if(wpc==0) {

            /* fall back to the last coded fragment */
            cpi->pb.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];
              }
	    }

	    cpi->pb.QFragData[i][0] -= PredictedDC;
	  }

	  /* Save the last fragment coded for whatever frame we are
             predicting from */

	  Last[WhichFrame] = cpi->OriginalDC[i];

	}
      }
    }
  }

  /* Pack DC tokens and adjust the ones we couldn't predict 2d */
  for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
    /* Get the linear index for the current coded fragment. */
    FragIndex = cpi->pb.CodedBlockList[i];
    coded_pixels += DPCMTokenizeBlock ( cpi, FragIndex);

  }


  /* Bit pack the video data data */
  PackCodedVideo(cpi);

  /* End the bit packing run. */
  /* EndAddBitsToBuffer(cpi); */

  /* Reconstruct the reference frames */
  ReconRefFrames(&cpi->pb);

  UpdateFragQIndex(&cpi->pb);

  /* Measure the inter reconstruction error for all the blocks that
     were coded */
  /* for use as part of the recovery monitoring process in subsequent frames. */
  for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
    cpi->LastCodedErrorScore[ cpi->pb.CodedBlockList[i] ] =
      GetBlockReconErrorSlow( cpi, cpi->pb.CodedBlockList[i] );

  }

  /* Return total number of coded pixels */
  return coded_pixels;
}

ogg_uint32_t EncodeData(CP_INSTANCE *cpi){
    ogg_uint32_t coded_pixels = 0;

    /* Zero the count of tokens so far this frame. */
    cpi->TotTokenCount = 0;

    /* Zero the mode and MV list indices. */
    cpi->ModeListCount = 0;

    /* Zero Decoder EOB run count */
    cpi->pb.EOB_Run = 0;

    dsp_static_save_fpu ();

    /* Encode any fragments coded using DCT. */
    coded_pixels += QuadCodeDisplayFragments (cpi);

    dsp_static_restore_fpu ();

    return coded_pixels;

}

ogg_uint32_t PickIntra( CP_INSTANCE *cpi,
			ogg_uint32_t SBRows,
			ogg_uint32_t SBCols){

  ogg_int32_t	FragIndex;  /* Fragment number */
  ogg_uint32_t	MB, B;	    /* Macro-Block, Block indices */
  ogg_uint32_t	SBrow;	    /* Super-Block row number */
  ogg_uint32_t	SBcol;	    /* Super-Block row number */
  ogg_uint32_t	SB=0;	    /* Super-Block index, initialised to first of
			       this component */

  ogg_uint32_t UVRow;
  ogg_uint32_t UVColumn;
  ogg_uint32_t UVFragOffset;

  /* decide what block type and motion vectors to use on all of the frames */
  for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
    for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
      /* Check its four Macro-Blocks */
      for ( MB=0; MB<4; MB++ ) {
	/* There may be MB's lying out of frame which must be
	   ignored. For these MB's Top left block will have a negative
	   Fragment Index. */
	if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {

	  cpi->MBCodingMode = CODE_INTRA;

	  /* Now actually code the blocks. */
	  for ( B=0; B<4; B++ ) {
	    FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
	    cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
	  }

	  /* Matching fragments in the U and V planes */
	  UVRow = (FragIndex / (cpi->pb.HFragments * 2));
	  UVColumn = (FragIndex % cpi->pb.HFragments) / 2;
	  UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;

	  cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments + UVFragOffset] =
	    cpi->MBCodingMode;
	  cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments +
				  cpi->pb.UVPlaneFragments + UVFragOffset] =
	    cpi->MBCodingMode;

	}
      }

      /* Next Super-Block */
      SB++;
    }
  }
  return 0;
}

static void AddMotionVector(CP_INSTANCE *cpi,
		     MOTION_VECTOR *ThisMotionVector) {
  cpi->MVList[cpi->MvListCount].x = ThisMotionVector->x;
  cpi->MVList[cpi->MvListCount].y = ThisMotionVector->y;
  cpi->MvListCount++;
}

static void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
				ogg_int32_t FragIndex,
				MOTION_VECTOR *ThisMotionVector){
  /* Note the coding mode and vector for each block */
  cpi->pb.FragMVect[FragIndex].x = ThisMotionVector->x;
  cpi->pb.FragMVect[FragIndex].y = ThisMotionVector->y;
  cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
}

static void SetMBMotionVectorsAndMode(CP_INSTANCE *cpi,
			       ogg_int32_t YFragIndex,
			       ogg_int32_t UFragIndex,
			       ogg_int32_t VFragIndex,
			       MOTION_VECTOR *ThisMotionVector){
  SetFragMotionVectorAndMode(cpi, YFragIndex, ThisMotionVector);
  SetFragMotionVectorAndMode(cpi, YFragIndex + 1, ThisMotionVector);
  SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,
			     ThisMotionVector);
  SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,
			     ThisMotionVector);
  SetFragMotionVectorAndMode(cpi, UFragIndex, ThisMotionVector);
  SetFragMotionVectorAndMode(cpi, VFragIndex, ThisMotionVector);
}

ogg_uint32_t PickModes(CP_INSTANCE *cpi,
		       ogg_uint32_t SBRows, ogg_uint32_t SBCols,
		       ogg_uint32_t PixelsPerLine,
		       ogg_uint32_t *InterError, ogg_uint32_t *IntraError) {
  ogg_int32_t	YFragIndex;
  ogg_int32_t	UFragIndex;
  ogg_int32_t	VFragIndex;
  ogg_uint32_t	MB, B;	    /* Macro-Block, Block indices */
  ogg_uint32_t	SBrow;	    /* Super-Block row number */
  ogg_uint32_t	SBcol;	    /* Super-Block row number */
  ogg_uint32_t	SB=0;	    /* Super-Block index, initialised to first
                               of this component */

  ogg_uint32_t  MBIntraError;           /* Intra error for macro block */
  ogg_uint32_t  MBGFError;              /* Golden frame macro block error */
  ogg_uint32_t  MBGF_MVError;           /* Golden frame plus MV error */
  ogg_uint32_t  LastMBGF_MVError;       /* Golden frame error with
                                           last used GF motion
                                           vector. */
  ogg_uint32_t  MBInterError;           /* Inter no MV macro block error */
  ogg_uint32_t  MBLastInterError;       /* Inter with last used MV */
  ogg_uint32_t  MBPriorLastInterError;  /* Inter with prior last MV */
  ogg_uint32_t  MBInterMVError;         /* Inter MV macro block error */
  ogg_uint32_t  MBInterMVExError;       /* Inter MV (exhaustive
                                           search) macro block error */
  ogg_uint32_t  MBInterFOURMVError;     /* Inter MV error when using 4
                                           motion vectors per macro
                                           block */
  ogg_uint32_t  BestError;              /* Best error so far. */

  MOTION_VECTOR FourMVect[6];     /* storage for last used vectors (one
				     entry for each block in MB) */
  MOTION_VECTOR LastInterMVect;   /* storage for last used Inter frame
                                     MB motion vector */
  MOTION_VECTOR PriorLastInterMVect;  /* storage for prior last used
                                         Inter frame MB motion vector */
  MOTION_VECTOR TmpMVect;         /* Temporary MV storage */
  MOTION_VECTOR LastGFMVect;      /* storage for last used Golden
                                     Frame MB motion vector */
  MOTION_VECTOR InterMVect;       /* storage for motion vector */
  MOTION_VECTOR InterMVectEx;     /* storage for motion vector result
                                     from exhaustive search */
  MOTION_VECTOR GFMVect;          /* storage for motion vector */
  MOTION_VECTOR ZeroVect;

  ogg_uint32_t UVRow;
  ogg_uint32_t UVColumn;
  ogg_uint32_t UVFragOffset;

  int          MBCodedFlag;
  unsigned char QIndex;

  /* initialize error scores */
  *InterError = 0;
  *IntraError = 0;

  /* clear down the default motion vector. */
  cpi->MvListCount = 0;
  FourMVect[0].x = 0;
  FourMVect[0].y = 0;
  FourMVect[1].x = 0;
  FourMVect[1].y = 0;
  FourMVect[2].x = 0;
  FourMVect[2].y = 0;
  FourMVect[3].x = 0;
  FourMVect[3].y = 0;
  FourMVect[4].x = 0;
  FourMVect[4].y = 0;
  FourMVect[5].x = 0;
  FourMVect[5].y = 0;
  LastInterMVect.x = 0;
  LastInterMVect.y = 0;
  PriorLastInterMVect.x = 0;
  PriorLastInterMVect.y = 0;
  LastGFMVect.x = 0;
  LastGFMVect.y = 0;
  InterMVect.x = 0;
  InterMVect.y = 0;
  GFMVect.x = 0;
  GFMVect.y = 0;

  ZeroVect.x = 0;
  ZeroVect.y = 0;

  QIndex = (unsigned char)cpi->pb.FrameQIndex;



  /* change the quatization matrix to the one at best Q to compute the
     new error score */
  cpi->MinImprovementForNewMV = (MvThreshTable[QIndex] << 12);
  cpi->InterTripOutThresh = (5000<<12);
  cpi->MVChangeFactor = MVChangeFactorTable[QIndex]; /* 0.9 */

  if ( cpi->pb.info.quick_p ) {
    cpi->ExhaustiveSearchThresh = (1000<<12);
    cpi->FourMVThreshold = (2500<<12);
  } else {
    cpi->ExhaustiveSearchThresh = (250<<12);
    cpi->FourMVThreshold = (500<<12);

⌨️ 快捷键说明

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