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

📄 dct_decode.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
    (HFRAGPIXELS - 1);
  SrcPtr2 = &DestReconPtr[ PixelIndex ];
  DestPtr2 = &DestReconPtr[ PixelIndex + 1 ];

  /* Now copy the top and bottom source lines into each line of the
     respective borders */
  for ( i = 0; i < PlaneHeight; i++ ) {
    memset( DestPtr1, SrcPtr1[0], PlaneBorderWidth );
    memset( DestPtr2, SrcPtr2[0], PlaneBorderWidth );
    SrcPtr1 += PlaneStride;
    SrcPtr2 += PlaneStride;
    DestPtr1 += PlaneStride;
    DestPtr2 += PlaneStride;
  }
}

void UpdateUMVBorder( PB_INSTANCE *pbi,
		      unsigned char * DestReconPtr ) {
  ogg_uint32_t  PlaneFragOffset;

  /* Y plane */
  PlaneFragOffset = 0;
  UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
  UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );

  /* Then the U and V Planes */
  PlaneFragOffset = pbi->YPlaneFragments;
  UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
  UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );

  PlaneFragOffset = pbi->YPlaneFragments + pbi->UVPlaneFragments;
  UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
  UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
}

static void CopyRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr,
		unsigned char * SrcReconPtr ) {
  ogg_uint32_t  i;
  ogg_uint32_t	PlaneLineStep; /* Pixels per line */
  ogg_uint32_t  PixelIndex;

  unsigned char  *SrcPtr;      /* Pointer to line of source image data */
  unsigned char  *DestPtr;     /* Pointer to line of destination image data */

  /* Copy over only updated blocks.*/

  /* First Y plane */
  PlaneLineStep = pbi->YStride;
  for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
    if ( pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];

      dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
    }
  }

  /* Then U and V */
  PlaneLineStep = pbi->UVStride;
  for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
    if ( pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];

      dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);

    }
  }
}

static void CopyNotRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr,
		   unsigned char * SrcReconPtr ) {
  ogg_uint32_t  i;
  ogg_uint32_t	PlaneLineStep; /* Pixels per line */
  ogg_uint32_t  PixelIndex;

  unsigned char  *SrcPtr;      /* Pointer to line of source image data */
  unsigned char  *DestPtr;     /* Pointer to line of destination image data*/

  /* Copy over only updated blocks. */

  /* First Y plane */
  PlaneLineStep = pbi->YStride;
  for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
    if ( !pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];

      dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
    }
  }

  /* Then U and V */
  PlaneLineStep = pbi->UVStride;
  for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
    if ( !pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];

      dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);

    }
  }
}

void ExpandToken( Q_LIST_ENTRY * ExpandedBlock,
		  unsigned char * CoeffIndex, ogg_uint32_t Token,
		  ogg_int32_t ExtraBits ){
  /* Is the token is a combination run and value token. */
  if ( Token >= DCT_RUN_CATEGORY1 ){
    /* Expand the token and additional bits to a zero run length and
       data value.  */
    if ( Token < DCT_RUN_CATEGORY2 ) {
      /* Decoding method depends on token */
      if ( Token < DCT_RUN_CATEGORY1B ) {
	/* Step on by the zero run length */
	*CoeffIndex += (unsigned char)((Token - DCT_RUN_CATEGORY1) + 1);

	/* The extra bit determines the sign. */
	if ( ExtraBits & 0x01 )
	  ExpandedBlock[*CoeffIndex] = -1;
	else
	  ExpandedBlock[*CoeffIndex] = 1;
      } else if ( Token == DCT_RUN_CATEGORY1B ) {
	/* Bits 0-1 determines the zero run length */
	*CoeffIndex += (6 + (ExtraBits & 0x03));

	/* Bit 2 determines the sign */
	if ( ExtraBits & 0x04 )
	  ExpandedBlock[*CoeffIndex] = -1;
	else
	  ExpandedBlock[*CoeffIndex] = 1;
      }else{
	/* Bits 0-2 determines the zero run length */
	*CoeffIndex += (10 + (ExtraBits & 0x07));

	/* Bit 3 determines the sign */
	if ( ExtraBits & 0x08 )
	  ExpandedBlock[*CoeffIndex] = -1;
	else
	  ExpandedBlock[*CoeffIndex] = 1;
      }
    }else{
      /* If token == DCT_RUN_CATEGORY2 we have a single 0 followed by
         a value */
      if ( Token == DCT_RUN_CATEGORY2 ){
	/* Step on by the zero run length */
	*CoeffIndex += 1;

	/* Bit 1 determines sign, bit 0 the value */
	if ( ExtraBits & 0x02 )
	  ExpandedBlock[*CoeffIndex] = -(2 + (ExtraBits & 0x01));
	else
	  ExpandedBlock[*CoeffIndex] = 2 + (ExtraBits & 0x01);
      }else{
	/* else we have 2->3 zeros followed by a value */
	/* Bit 0 determines the zero run length */
	*CoeffIndex += 2 + (ExtraBits & 0x01);

	/* Bit 2 determines the sign, bit 1 the value */
	if ( ExtraBits & 0x04 )
	  ExpandedBlock[*CoeffIndex] = -(2 + ((ExtraBits & 0x02) >> 1));
	else
	  ExpandedBlock[*CoeffIndex] = 2 + ((ExtraBits & 0x02) >> 1);
      }
    }

    /* Step on over value */
    *CoeffIndex += 1;

  } else if ( Token == DCT_SHORT_ZRL_TOKEN ) {
    /* Token is a ZRL token so step on by the appropriate number of zeros */
    *CoeffIndex += ExtraBits + 1;
  } else if ( Token == DCT_ZRL_TOKEN ) {
    /* Token is a ZRL token so step on by the appropriate number of zeros */
    *CoeffIndex += ExtraBits + 1;
  } else if ( Token < LOW_VAL_TOKENS ) {
    /* Token is a small single value token. */
    switch ( Token ) {
    case ONE_TOKEN:
      ExpandedBlock[*CoeffIndex] = 1;
      break;
    case MINUS_ONE_TOKEN:
      ExpandedBlock[*CoeffIndex] = -1;
      break;
    case TWO_TOKEN:
      ExpandedBlock[*CoeffIndex] = 2;
      break;
    case MINUS_TWO_TOKEN:
      ExpandedBlock[*CoeffIndex] = -2;
      break;
    }

    /* Step on the coefficient index. */
    *CoeffIndex += 1;
  }else{
    /* Token is a larger single value token */
    /* Expand the token and additional bits to a data value. */
    if ( Token < DCT_VAL_CATEGORY3 ) {
      /* Offset from LOW_VAL_TOKENS determines value */
      Token = Token - LOW_VAL_TOKENS;

      /* Extra bit determines sign */
      if ( ExtraBits )
	ExpandedBlock[*CoeffIndex] =
	  -((Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN));
      else
	ExpandedBlock[*CoeffIndex] =
	  (Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN);
    } else if ( Token == DCT_VAL_CATEGORY3 ) {
      /* Bit 1 determines sign, Bit 0 the value */
      if ( ExtraBits & 0x02 )
	ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT3_MIN + (ExtraBits & 0x01));
      else
	ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT3_MIN + (ExtraBits & 0x01);
    } else if ( Token == DCT_VAL_CATEGORY4 ) {
      /* Bit 2 determines sign, Bit 0-1 the value */
      if ( ExtraBits & 0x04 )
	ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT4_MIN + (ExtraBits & 0x03));
      else
	ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT4_MIN + (ExtraBits & 0x03);
    } else if ( Token == DCT_VAL_CATEGORY5 ) {
      /* Bit 3 determines sign, Bit 0-2 the value */
      if ( ExtraBits & 0x08 )
	ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT5_MIN + (ExtraBits & 0x07));
      else
	ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT5_MIN + (ExtraBits & 0x07);
    } else if ( Token == DCT_VAL_CATEGORY6 ) {
      /* Bit 4 determines sign, Bit 0-3 the value */
      if ( ExtraBits & 0x10 )
	ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F));
      else
	ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F);
    } else if ( Token == DCT_VAL_CATEGORY7 ) {
      /* Bit 5 determines sign, Bit 0-4 the value */
      if ( ExtraBits & 0x20 )
	ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F));
      else
	ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F);
    } else if ( Token == DCT_VAL_CATEGORY8 ) {
      /* Bit 9 determines sign, Bit 0-8 the value */
      if ( ExtraBits & 0x200 )
	ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF));
      else
	ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF);
    }

    /* Step on the coefficient index. */
    *CoeffIndex += 1;
  }
}

void ClearDownQFragData(PB_INSTANCE *pbi){
  ogg_int32_t       i,j;
  Q_LIST_ENTRY *    QFragPtr;

  for ( i = 0; i < pbi->CodedBlockIndex; i++ ) {
    /* Get the linear index for the current fragment. */
    QFragPtr = pbi->QFragData[pbi->CodedBlockList[i]];
    memset(QFragPtr, 0, 64*sizeof(Q_LIST_ENTRY));
  }
}

void FilterHoriz(unsigned char * PixelPtr,
			ogg_int32_t LineLength,
			ogg_int32_t *BoundingValuePtr){
  ogg_int32_t j;
  ogg_int32_t FiltVal;

  for ( j = 0; j < 8; j++ ){
    FiltVal =
      ( PixelPtr[0] ) -
      ( PixelPtr[1] * 3 ) +
      ( PixelPtr[2] * 3 ) -
      ( PixelPtr[3] );

    FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3));

    PixelPtr[1] = clamp255(PixelPtr[1] + FiltVal);
    PixelPtr[2] = clamp255(PixelPtr[2] - FiltVal);

    PixelPtr += LineLength;
  }
}

void FilterVert(unsigned char * PixelPtr,
		ogg_int32_t LineLength,
		ogg_int32_t *BoundingValuePtr){
  ogg_int32_t j;
  ogg_int32_t FiltVal;

  /* the math was correct, but negative array indicies are forbidden
     by ANSI/C99 and will break optimization on several modern
     compilers */

  PixelPtr -= 2*LineLength;

  for ( j = 0; j < 8; j++ ) {
    FiltVal = ( (ogg_int32_t)PixelPtr[0] ) -
      ( (ogg_int32_t)PixelPtr[LineLength] * 3 ) +
      ( (ogg_int32_t)PixelPtr[2 * LineLength] * 3 ) -
      ( (ogg_int32_t)PixelPtr[3 * LineLength] );

    FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3));

    PixelPtr[LineLength] = clamp255(PixelPtr[LineLength] + FiltVal);
    PixelPtr[2 * LineLength] = clamp255(PixelPtr[2*LineLength] - FiltVal);

    PixelPtr ++;
  }
}

void LoopFilter(PB_INSTANCE *pbi){
  ogg_int32_t i;

  ogg_int32_t * BoundingValuePtr=pbi->BoundingValuePtr;//pbi->FiltBoundingValue+256;
  int FragsAcross=pbi->HFragments;
  int FromFragment,ToFragment;
  int FragsDown = pbi->VFragments;
  ogg_int32_t LineFragments;
  ogg_int32_t LineLength;
  ogg_int32_t FLimit;
  int QIndex;
  int j,m,n;

  /* Set the limit value for the loop filter based upon the current
     quantizer. */
  QIndex = Q_TABLE_SIZE - 1;
  while ( QIndex >= 0 ) {
    if ( (QIndex == 0) ||
	 ( pbi->QThreshTable[QIndex] >= pbi->ThisFrameQualityValue) )
      break;
    QIndex --;
  }

  FLimit = pbi->LoopFilterLimits[QIndex];
  if ( FLimit == 0 ) return;
  dsp_funcs.SetupBoundingValueArray(pbi, FLimit);

  for ( j = 0; j < 3 ; j++){
    switch(j) {
    case 0: /* y */
      FromFragment = 0;
      ToFragment = pbi->YPlaneFragments;
      FragsAcross = pbi->HFragments;
      FragsDown = pbi->VFragments;
      LineLength = pbi->YStride;
      LineFragments = pbi->HFragments;
      break;
    case 1: /* u */
      FromFragment = pbi->YPlaneFragments;
      ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      LineLength = pbi->UVStride;
      LineFragments = pbi->HFragments / 2;
      break;
    /*case 2:  v */
    default:
      FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
      ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      LineLength = pbi->UVStride;
      LineFragments = pbi->HFragments / 2;
      break;
    }

    i=FromFragment;

    /**************************************************************
     First 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]){
      /* 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);

	/* Filter right hand border only if the block to the right is
           not coded */

⌨️ 快捷键说明

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