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

📄 dct_decode.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************** *                                                                  * * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       * *                                                                  * * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003                * * by the Xiph.Org Foundation http://www.xiph.org/                  * *                                                                  * ********************************************************************  function:  last mod: $Id: dct_decode.c 11442 2006-05-27 17:28:08Z giles $ ********************************************************************/#include <stdlib.h>#include <string.h>#include "codec_internal.h"#include "dsp.h"#define GOLDEN_FRAME_THRESH_Q   50#define PUR 8#define PU 4#define PUL 2#define PL 1#define HIGHBITDUPPED(X) (((signed short) X)  >> 15)/* in-loop filter tables. one of these is used in dct_decode.c */static const unsigned char LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {  30, 25, 20, 20, 15, 15, 14, 14,  13, 13, 12, 12, 11, 11, 10, 10,  9,  9,  8,  8,  7,  7,  7,  7,  6,  6,  6,  6,  5,  5,  5,  5,  4,  4,  4,  4,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};static const unsigned char LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {  30, 25, 20, 20, 15, 15, 14, 14,  13, 13, 12, 12, 11, 11, 10, 10,  9,  9,  8,  8,  7,  7,  7,  7,  6,  6,  6,  6,  5,  5,  5,  5,  4,  4,  4,  4,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1};static const int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };static void SetupBoundingValueArray_Generic(PB_INSTANCE *pbi,                                            ogg_int32_t FLimit){  ogg_int32_t * BoundingValuePtr = pbi->FiltBoundingValue+256;  ogg_int32_t i;  /* Set up the bounding value array. */  memset ( pbi->FiltBoundingValue, 0, (512*sizeof(*pbi->FiltBoundingValue)) );  for ( i = 0; i < FLimit; i++ ){    BoundingValuePtr[-i-FLimit] = (-FLimit+i);    BoundingValuePtr[-i] = -i;    BoundingValuePtr[i] = i;    BoundingValuePtr[i+FLimit] = FLimit-i;  }}/* handle the in-loop filter limit value table */void WriteFilterTables(PB_INSTANCE *pbi, oggpack_buffer *opb){  int i;  int bits=5;  oggpackB_write(opb, bits, 3);  for(i=0;i<Q_TABLE_SIZE;i++)    oggpackB_write(opb, pbi->LoopFilterLimits[i],bits);}int ReadFilterTables(codec_setup_info *ci, oggpack_buffer *opb){  int i;  int bits, value;  theora_read(opb, 3, &bits);  for(i=0;i<Q_TABLE_SIZE;i++){    theora_read(opb,bits,&value);    ci->LoopFilterLimitValues[i]=value;  }  if(bits<0)return OC_BADHEADER;  return 0;}/* copy in-loop filter limits from the bitstream header into our instance */void CopyFilterTables(PB_INSTANCE *pbi, codec_setup_info *ci){  memcpy(pbi->LoopFilterLimits, ci->LoopFilterLimitValues, Q_TABLE_SIZE);}/* initialize the filter limits from our static table */void InitFilterTables(PB_INSTANCE *pbi){  memcpy(pbi->LoopFilterLimits, LoopFilterLimitValuesV1, Q_TABLE_SIZE);}void SetupLoopFilter(PB_INSTANCE *pbi){  ogg_int32_t FLimit;  /* nb: this was using the V2 values rather than V1     we think is was a mistake; the results were not used */  FLimit = pbi->LoopFilterLimits[pbi->FrameQIndex];  SetupBoundingValueArray_Generic(pbi, FLimit);}static void ExpandKFBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){  ogg_uint32_t ReconPixelsPerLine;  ogg_int32_t     ReconPixelIndex;  /* Select the appropriate inverse Q matrix and line stride */  if ( FragmentNumber<(ogg_int32_t)pbi->YPlaneFragments ){    ReconPixelsPerLine = pbi->YStride;    pbi->dequant_coeffs = pbi->dequant_Y_coeffs;  }else if ( FragmentNumber<(ogg_int32_t)(pbi->YPlaneFragments + pbi->UVPlaneFragments) ){    ReconPixelsPerLine = pbi->UVStride;    pbi->dequant_coeffs = pbi->dequant_U_coeffs;  }else{    ReconPixelsPerLine = pbi->UVStride;    pbi->dequant_coeffs = pbi->dequant_V_coeffs;  }  /* Set up pointer into the quantisation buffer. */  pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];  /* Invert quantisation and DCT to get pixel data. */  switch(pbi->FragCoefEOB[FragmentNumber]){  case 0:case 1:    IDct1( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );    break;  case 2: case 3:case 4:case 5:case 6:case 7:case 8: case 9:case 10:    IDct10( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );    break;  default:    IDctSlow( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );  }  /* Convert fragment number to a pixel offset in a reconstruction buffer. */  ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];  /* Get the pixel index for the first pixel in the fragment. */  dsp_recon_intra8x8 (pbi->dsp, (unsigned char *)(&pbi->ThisFrameRecon[ReconPixelIndex]),              (ogg_int16_t *)pbi->ReconDataBuffer, ReconPixelsPerLine);}static void ExpandBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){  unsigned char *LastFrameRecPtr;   /* Pointer into previous frame                                       reconstruction. */  unsigned char *LastFrameRecPtr2;  /* Pointer into previous frame                                       reconstruction for 1/2 pixel MC. */  ogg_uint32_t   ReconPixelsPerLine; /* Pixels per line */  ogg_int32_t    ReconPixelIndex;    /* Offset for block into a                                        reconstruction buffer */  ogg_int32_t    ReconPtr2Offset;    /* Offset for second                                        reconstruction in half pixel                                        MC */  ogg_int32_t    MVOffset;           /* Baseline motion vector offset */  ogg_int32_t    MvShift  ;          /* Shift to correct to 1/2 or 1/4 pixel */  ogg_int32_t    MvModMask;          /* Mask to determine whether 1/2                                        pixel is used */  /* Get coding mode for this block */  if ( GetFrameType(pbi) == KEY_FRAME ){    pbi->CodingMode = CODE_INTRA;  }else{    /* Get Motion vector and mode for this block. */    pbi->CodingMode = pbi->FragCodingMethod[FragmentNumber];  }  /* Select the appropriate inverse Q matrix and line stride */  if ( FragmentNumber<(ogg_int32_t)pbi->YPlaneFragments ) {    ReconPixelsPerLine = pbi->YStride;    MvShift = 1;    MvModMask = 0x00000001;    /* Select appropriate dequantiser matrix. */    if ( pbi->CodingMode == CODE_INTRA )      pbi->dequant_coeffs = pbi->dequant_Y_coeffs;    else      pbi->dequant_coeffs = pbi->dequant_InterY_coeffs;  }else{    ReconPixelsPerLine = pbi->UVStride;    MvShift = 2;    MvModMask = 0x00000003;    /* Select appropriate dequantiser matrix. */    if ( pbi->CodingMode == CODE_INTRA )      if ( FragmentNumber <                 (ogg_int32_t)(pbi->YPlaneFragments + pbi->UVPlaneFragments) )        pbi->dequant_coeffs = pbi->dequant_U_coeffs;      else        pbi->dequant_coeffs = pbi->dequant_V_coeffs;    else      if ( FragmentNumber <                 (ogg_int32_t)(pbi->YPlaneFragments + pbi->UVPlaneFragments) )        pbi->dequant_coeffs = pbi->dequant_InterU_coeffs;      else        pbi->dequant_coeffs = pbi->dequant_InterV_coeffs;  }  /* Set up pointer into the quantisation buffer. */  pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];  /* Invert quantisation and DCT to get pixel data. */  switch(pbi->FragCoefEOB[FragmentNumber]){  case 0:case 1:    IDct1( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );    break;  case 2: case 3:case 4:case 5:case 6:case 7:case 8: case 9:case 10:    IDct10( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );    break;  default:    IDctSlow( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );  }  /* Convert fragment number to a pixel offset in a reconstruction buffer. */  ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];  /* Action depends on decode mode. */  if ( pbi->CodingMode == CODE_INTER_NO_MV ){    /* Inter with no motion vector */    /* Reconstruct the pixel data using the last frame reconstruction       and change data when the motion vector is (0,0), the recon is       based on the lastframe without loop filtering---- for testing */    dsp_recon_inter8x8 (pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],                &pbi->LastFrameRecon[ReconPixelIndex],                  pbi->ReconDataBuffer, ReconPixelsPerLine);  }else if ( ModeUsesMC[pbi->CodingMode] ) {    /* The mode uses a motion vector. */    /* Get vector from list */    pbi->MVector.x = pbi->FragMVect[FragmentNumber].x;    pbi->MVector.y = pbi->FragMVect[FragmentNumber].y;    /* Work out the base motion vector offset and the 1/2 pixel offset       if any.  For the U and V planes the MV specifies 1/4 pixel       accuracy. This is adjusted to 1/2 pixel as follows ( 0->0,       1/4->1/2, 1/2->1/2, 3/4->1/2 ). */    MVOffset = 0;    ReconPtr2Offset = 0;    if ( pbi->MVector.x > 0 ){      MVOffset = pbi->MVector.x >> MvShift;      if ( pbi->MVector.x & MvModMask )        ReconPtr2Offset += 1;    } else if ( pbi->MVector.x < 0 ) {      MVOffset -= (-pbi->MVector.x) >> MvShift;      if ( (-pbi->MVector.x) & MvModMask )        ReconPtr2Offset -= 1;    }    if ( pbi->MVector.y > 0 ){      MVOffset += (pbi->MVector.y >>  MvShift) * ReconPixelsPerLine;      if ( pbi->MVector.y & MvModMask )        ReconPtr2Offset += ReconPixelsPerLine;    } else if ( pbi->MVector.y < 0 ){      MVOffset -= ((-pbi->MVector.y) >> MvShift) * ReconPixelsPerLine;      if ( (-pbi->MVector.y) & MvModMask )        ReconPtr2Offset -= ReconPixelsPerLine;    }    /* Set up the first of the two reconstruction buffer pointers. */    if ( pbi->CodingMode==CODE_GOLDEN_MV ) {      LastFrameRecPtr = &pbi->GoldenFrame[ReconPixelIndex] + MVOffset;    }else{      LastFrameRecPtr = &pbi->LastFrameRecon[ReconPixelIndex] + MVOffset;    }    /* Set up the second of the two reconstruction pointers. */    LastFrameRecPtr2 = LastFrameRecPtr + ReconPtr2Offset;    /* Select the appropriate reconstruction function */    if ( (int)(LastFrameRecPtr - LastFrameRecPtr2) == 0 ) {      /* Reconstruct the pixel dats from the reference frame and change data         (no half pixel in this case as the two references were the same. */      dsp_recon_inter8x8 (pbi->dsp,		  &pbi->ThisFrameRecon[ReconPixelIndex],                  LastFrameRecPtr, pbi->ReconDataBuffer,                  ReconPixelsPerLine);    }else{      /* Fractional pixel reconstruction. */      /* Note that we only use two pixels per reconstruction even for         the diagonal. */      dsp_recon_inter8x8_half(pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],                            LastFrameRecPtr, LastFrameRecPtr2,                            pbi->ReconDataBuffer, ReconPixelsPerLine);    }  } else if ( pbi->CodingMode == CODE_USING_GOLDEN ){    /* Golden frame with motion vector */    /* Reconstruct the pixel data using the golden frame       reconstruction and change data */    dsp_recon_inter8x8 (pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],                &pbi->GoldenFrame[ ReconPixelIndex ],                  pbi->ReconDataBuffer, ReconPixelsPerLine);  } else {    /* Simple Intra coding */    /* Get the pixel index for the first pixel in the fragment. */    dsp_recon_intra8x8 (pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],              pbi->ReconDataBuffer, ReconPixelsPerLine);  }}static void UpdateUMV_HBorders( PB_INSTANCE *pbi,                                unsigned char * DestReconPtr,                                ogg_uint32_t  PlaneFragOffset ) {  ogg_uint32_t  i;  ogg_uint32_t  PixelIndex;  ogg_uint32_t  PlaneStride;  ogg_uint32_t  BlockVStep;  ogg_uint32_t  PlaneFragments;  ogg_uint32_t  LineFragments;  ogg_uint32_t  PlaneBorderWidth;  unsigned char   *SrcPtr1;  unsigned char   *SrcPtr2;  unsigned char   *DestPtr1;  unsigned char   *DestPtr2;  /* Work out various plane specific values */  if ( PlaneFragOffset == 0 ) {    /* Y Plane */    BlockVStep = (pbi->YStride *                  (VFRAGPIXELS - 1));    PlaneStride = pbi->YStride;    PlaneBorderWidth = UMV_BORDER;    PlaneFragments = pbi->YPlaneFragments;    LineFragments = pbi->HFragments;  }else{    /* U or V plane. */    BlockVStep = (pbi->UVStride *                  (VFRAGPIXELS - 1));    PlaneStride = pbi->UVStride;    PlaneBorderWidth = UMV_BORDER / 2;    PlaneFragments = pbi->UVPlaneFragments;    LineFragments = pbi->HFragments / 2;  }  /* Setup the source and destination pointers for the top and bottom     borders */  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset];  SrcPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ];  DestPtr1 = SrcPtr1 - (PlaneBorderWidth * PlaneStride);  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset +                                           PlaneFragments - LineFragments] +    BlockVStep;  SrcPtr2 = &DestReconPtr[ PixelIndex - PlaneBorderWidth];  DestPtr2 = SrcPtr2 + PlaneStride;  /* Now copy the top and bottom source lines into each line of the     respective borders */  for ( i = 0; i < PlaneBorderWidth; i++ ) {    memcpy( DestPtr1, SrcPtr1, PlaneStride );    memcpy( DestPtr2, SrcPtr2, PlaneStride );    DestPtr1 += PlaneStride;    DestPtr2 += PlaneStride;  }}static void UpdateUMV_VBorders( PB_INSTANCE *pbi,                                unsigned char * DestReconPtr,                                ogg_uint32_t  PlaneFragOffset ){  ogg_uint32_t  i;  ogg_uint32_t  PixelIndex;  ogg_uint32_t  PlaneStride;  ogg_uint32_t  LineFragments;  ogg_uint32_t  PlaneBorderWidth;  ogg_uint32_t   PlaneHeight;  unsigned char   *SrcPtr1;  unsigned char   *SrcPtr2;  unsigned char   *DestPtr1;  unsigned char   *DestPtr2;  /* Work out various plane specific values */  if ( PlaneFragOffset == 0 ) {    /* Y Plane */    PlaneStride = pbi->YStride;    PlaneBorderWidth = UMV_BORDER;    LineFragments = pbi->HFragments;    PlaneHeight = pbi->info.height;  }else{    /* U or V plane. */    PlaneStride = pbi->UVStride;    PlaneBorderWidth = UMV_BORDER / 2;    LineFragments = pbi->HFragments / 2;    PlaneHeight = pbi->info.height / 2;  }  /* Setup the source data values and destination pointers for the     left and right edge borders */  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset];  SrcPtr1 = &DestReconPtr[ PixelIndex ];  DestPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ];  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset +                                           LineFragments - 1] +    (HFRAGPIXELS - 1);

⌨️ 快捷键说明

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