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

📄 scan.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************** *                                                                  * * 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: scan.c 11442 2006-05-27 17:28:08Z giles $ ********************************************************************/#include <stdlib.h>#include <math.h>#include <string.h>#include "codec_internal.h"#include "dsp.h"#define MAX_SEARCH_LINE_LEN                   7#define SET8_0(ptr) \  ((ogg_uint32_t *)ptr)[0] = 0x00000000; \  ((ogg_uint32_t *)ptr)[1] = 0x00000000;#define SET8_1(ptr) \  ((ogg_uint32_t *)ptr)[0] = 0x01010101; \  ((ogg_uint32_t *)ptr)[1] = 0x01010101;#define SET8_8(ptr) \  ((ogg_uint32_t *)ptr)[0] = 0x08080808; \  ((ogg_uint32_t *)ptr)[1] = 0x08080808;static ogg_uint32_t LineLengthScores[ MAX_SEARCH_LINE_LEN + 1 ] = {  0, 0, 0, 0, 2, 4, 12, 24};static ogg_uint32_t BodyNeighbourScore = 8;static double DiffDevisor = 0.0625;#define HISTORY_BLOCK_FACTOR    2#define MIN_STEP_THRESH 6#define SCORE_MULT_LOW    0.5#define SCORE_MULT_HIGH   4#define UP      0#define DOWN    1#define LEFT    2#define RIGHT   3#define INTERNAL_BLOCK_HEIGHT   8#define INTERNAL_BLOCK_WIDTH    8#define BLOCK_NOT_CODED                       0#define BLOCK_CODED_BAR                       3#define BLOCK_CODED_SGC                       4#define BLOCK_CODED_LOW                       4#define BLOCK_CODED                           5#define CANDIDATE_BLOCK_LOW                  -2#define CANDIDATE_BLOCK                      -1#define FIRST_ROW           0#define NOT_EDGE_ROW        1#define LAST_ROW            2#define YDIFF_CB_ROWS                   (INTERNAL_BLOCK_HEIGHT * 3)#define CHLOCALS_CB_ROWS                (INTERNAL_BLOCK_HEIGHT * 3)#define PMAP_CB_ROWS                    (INTERNAL_BLOCK_HEIGHT * 3)void ConfigurePP( PP_INSTANCE *ppi, int Level ) {  switch ( Level ){  case 0:    ppi->SRFGreyThresh = 1;    ppi->SRFColThresh = 1;    ppi->NoiseSupLevel = 2;    ppi->SgcLevelThresh = 1;    ppi->SuvcLevelThresh = 1;    ppi->GrpLowSadThresh = 6;    ppi->GrpHighSadThresh = 24;    ppi->PrimaryBlockThreshold = 2;    ppi->SgcThresh = 10;    ppi->PAKEnabled = 0;    break;  case 1:    ppi->SRFGreyThresh = 2;    ppi->SRFColThresh = 2;    ppi->NoiseSupLevel = 2;    ppi->SgcLevelThresh = 2;    ppi->SuvcLevelThresh = 2;    ppi->GrpLowSadThresh = 8;    ppi->GrpHighSadThresh = 32;    ppi->PrimaryBlockThreshold = 5;    ppi->SgcThresh = 12;    ppi->PAKEnabled = 1;    break;  case 2: /* Default VP3 settings */    ppi->SRFGreyThresh = 3;    ppi->SRFColThresh = 3;    ppi->NoiseSupLevel = 2;    ppi->SgcLevelThresh = 2;    ppi->SuvcLevelThresh = 2;    ppi->GrpLowSadThresh = 8;    ppi->GrpHighSadThresh = 32;    ppi->PrimaryBlockThreshold = 5;    ppi->SgcThresh = 16;    ppi->PAKEnabled = 1;    break;  case 3:    ppi->SRFGreyThresh = 4;    ppi->SRFColThresh = 4;    ppi->NoiseSupLevel = 3;    ppi->SgcLevelThresh = 3;    ppi->SuvcLevelThresh = 3;    ppi->GrpLowSadThresh = 10;    ppi->GrpHighSadThresh = 48;    ppi->PrimaryBlockThreshold = 5;    ppi->SgcThresh = 18;    ppi->PAKEnabled = 1;    break;  case 4:    ppi->SRFGreyThresh = 5;    ppi->SRFColThresh = 5;    ppi->NoiseSupLevel = 3;    ppi->SgcLevelThresh = 4;    ppi->SuvcLevelThresh = 4;    ppi->GrpLowSadThresh = 12;    ppi->GrpHighSadThresh = 48;    ppi->PrimaryBlockThreshold = 5;    ppi->SgcThresh = 20;    ppi->PAKEnabled = 1;    break;  case 5:    ppi->SRFGreyThresh = 6;    ppi->SRFColThresh = 6;    ppi->NoiseSupLevel = 3;    ppi->SgcLevelThresh = 4;    ppi->SuvcLevelThresh = 4;    ppi->GrpLowSadThresh = 12;    ppi->GrpHighSadThresh = 64;    ppi->PrimaryBlockThreshold = 10;    ppi->SgcThresh = 24;    ppi->PAKEnabled = 1;    break;  case 6:    ppi->SRFGreyThresh = 6;    ppi->SRFColThresh = 7;    ppi->NoiseSupLevel = 3;    ppi->SgcLevelThresh = 4;    ppi->SuvcLevelThresh = 4;    ppi->GrpLowSadThresh = 12;    ppi->GrpHighSadThresh = 64;    ppi->PrimaryBlockThreshold = 10;    ppi->SgcThresh = 24;    ppi->PAKEnabled = 1;    break;  default:    ppi->SRFGreyThresh = 3;    ppi->SRFColThresh = 3;    ppi->NoiseSupLevel = 2;    ppi->SgcLevelThresh = 2;    ppi->SuvcLevelThresh = 2;    ppi->GrpLowSadThresh = 10;    ppi->GrpHighSadThresh = 32;    ppi->PrimaryBlockThreshold = 5;    ppi->SgcThresh = 16;    ppi->PAKEnabled = 1;    break;  }}static void ScanCalcPixelIndexTable(PP_INSTANCE *ppi){  ogg_uint32_t i;  ogg_uint32_t * PixelIndexTablePtr = ppi->ScanPixelIndexTable;  /* If appropriate add on extra inices for U and V planes. */  for ( i = 0; i < (ppi->ScanYPlaneFragments); i++ ) {    PixelIndexTablePtr[ i ] =      ((i / ppi->ScanHFragments) *       VFRAGPIXELS * ppi->ScanConfig.VideoFrameWidth);    PixelIndexTablePtr[ i ] +=      ((i % ppi->ScanHFragments) * HFRAGPIXELS);  }  PixelIndexTablePtr = &ppi->ScanPixelIndexTable[ppi->ScanYPlaneFragments];  for ( i = 0; i < (ppi->ScanUVPlaneFragments * 2); i++ ){    PixelIndexTablePtr[ i ] =      ((i / (ppi->ScanHFragments >> 1) ) *       (VFRAGPIXELS * (ppi->ScanConfig.VideoFrameWidth >> 1)) );    PixelIndexTablePtr[ i ] +=      ((i % (ppi->ScanHFragments >> 1) ) *       HFRAGPIXELS) + ppi->YFramePixels;    }}static void InitScanMapArrays(PP_INSTANCE *ppi){  int i;  unsigned char StepThresh;  /* Clear down the fragment level map arrays for the current frame. */  memset( ppi->FragScores, 0,          ppi->ScanFrameFragments * sizeof(*ppi->FragScores) );  memset( ppi->SameGreyDirPixels, 0,          ppi->ScanFrameFragments );  memset( ppi->FragDiffPixels, 0,          ppi->ScanFrameFragments );  memset( ppi->RowChangedPixels, 0,          3* ppi->ScanConfig.VideoFrameHeight*sizeof(*ppi->RowChangedPixels));  memset( ppi->ScanDisplayFragments, BLOCK_NOT_CODED, ppi->ScanFrameFragments);  /* Threshold used in setting up ppi->NoiseScoreBoostTable[] */  StepThresh = (unsigned int)(ppi->SRFGreyThresh >> 1);  if ( StepThresh < MIN_STEP_THRESH )    StepThresh = MIN_STEP_THRESH;  ppi->SrfThresh = (int)ppi->SRFGreyThresh;  /* Set up various tables used to tweak pixel score values and     scoring rules based upon absolute value of a pixel change */  for ( i = 0; i < 256; i++ ){    /* Score multiplier table indexed by absolute difference. */    ppi->AbsDiff_ScoreMultiplierTable[i] = (double)i * DiffDevisor;    if ( ppi->AbsDiff_ScoreMultiplierTable[i] < SCORE_MULT_LOW )      ppi->AbsDiff_ScoreMultiplierTable[i] = SCORE_MULT_LOW;    else if ( ppi->AbsDiff_ScoreMultiplierTable[i] > SCORE_MULT_HIGH)      ppi->AbsDiff_ScoreMultiplierTable[i] = SCORE_MULT_HIGH;    /* Table that facilitates a relaxation of the changed locals rules       in NoiseScoreRow() for pixels that have changed by a large       amount. */    if ( i < (ppi->SrfThresh + StepThresh) )      ppi->NoiseScoreBoostTable[i] = 0;    else if ( i < (ppi->SrfThresh + (StepThresh * 4)) )      ppi->NoiseScoreBoostTable[i] = 1;    else if ( i < (ppi->SrfThresh + (StepThresh * 6)) )      ppi->NoiseScoreBoostTable[i] = 2;    else      ppi->NoiseScoreBoostTable[i] = 3;  }  /* Set various other threshold parameters. */  /* Set variables that control access to the line search algorithms. */  ppi->LineSearchTripTresh = 16;  if ( ppi->LineSearchTripTresh > ppi->PrimaryBlockThreshold )    ppi->LineSearchTripTresh = (unsigned int)(ppi->PrimaryBlockThreshold + 1);  /* Adjust line search length if block threshold low */  ppi->MaxLineSearchLen = MAX_SEARCH_LINE_LEN;  while ( (ppi->MaxLineSearchLen > 0) &&          (LineLengthScores[ppi->MaxLineSearchLen-1] >           ppi->PrimaryBlockThreshold) )    ppi->MaxLineSearchLen -= 1;}void ScanYUVInit( PP_INSTANCE *  ppi, SCAN_CONFIG_DATA * ScanConfigPtr){  int i;  /* Set up the various imported data structure pointers. */  ppi->ScanConfig.Yuv0ptr = ScanConfigPtr->Yuv0ptr;  ppi->ScanConfig.Yuv1ptr = ScanConfigPtr->Yuv1ptr;  ppi->ScanConfig.SrfWorkSpcPtr = ScanConfigPtr->SrfWorkSpcPtr;  ppi->ScanConfig.disp_fragments = ScanConfigPtr->disp_fragments;  ppi->ScanConfig.RegionIndex = ScanConfigPtr->RegionIndex;  ppi->ScanConfig.VideoFrameWidth = ScanConfigPtr->VideoFrameWidth;  ppi->ScanConfig.VideoFrameHeight = ScanConfigPtr->VideoFrameHeight;  /* UV plane sizes. */  ppi->VideoUVPlaneWidth = ScanConfigPtr->VideoFrameWidth / 2;  ppi->VideoUVPlaneHeight = ScanConfigPtr->VideoFrameHeight / 2;  /* Note the size of each plane in pixels. */  ppi->YFramePixels = ppi->ScanConfig.VideoFrameWidth *    ppi->ScanConfig.VideoFrameHeight;  ppi->UVFramePixels = ppi->VideoUVPlaneWidth * ppi->VideoUVPlaneHeight;  /* Work out various fragment related values. */  ppi->ScanYPlaneFragments = ppi->YFramePixels /    (HFRAGPIXELS * VFRAGPIXELS);  ppi->ScanUVPlaneFragments = ppi->UVFramePixels /    (HFRAGPIXELS * VFRAGPIXELS);;  ppi->ScanHFragments = ppi->ScanConfig.VideoFrameWidth / HFRAGPIXELS;  ppi->ScanVFragments = ppi->ScanConfig.VideoFrameHeight / VFRAGPIXELS;  ppi->ScanFrameFragments = ppi->ScanYPlaneFragments +    (2 * ppi->ScanUVPlaneFragments);  PInitFrameInfo(ppi);  /* Set up the scan pixel index table. */  ScanCalcPixelIndexTable(ppi);  /* Initialise the previous frame block history lists */  for ( i = 0; i < MAX_PREV_FRAMES; i++ )    memset( ppi->PrevFragments[i], BLOCK_NOT_CODED, ppi->ScanFrameFragments);  /* YUVAnalyseFrame() is not called for the first frame in a sequence     (a key frame obviously).  This memset insures that for the second     frame all blocks are marked for coding in line with the behaviour     for other key frames. */  memset( ppi->PrevFragments[ppi->PrevFrameLimit-1],          BLOCK_CODED, ppi->ScanFrameFragments );  /* Initialise scan arrays */  InitScanMapArrays(ppi);}static void SetFromPrevious(PP_INSTANCE *ppi) {  unsigned int  i,j;  /* We buld up the list of previously updated blocks in the zero     index list of PrevFragments[] so we must start by reseting its     contents */  memset( ppi->PrevFragments[0], BLOCK_NOT_CODED, ppi->ScanFrameFragments );  if ( ppi->PrevFrameLimit > 1 ){    /* Now build up PrevFragments[0] from PrevFragments[1 to PrevFrameLimit] */    for ( i = 0; i < ppi->ScanFrameFragments; i++ ){      for ( j = 1; j < ppi->PrevFrameLimit; j++ ){        if ( ppi->PrevFragments[j][i] > BLOCK_CODED_BAR ){          ppi->PrevFragments[0][i] = BLOCK_CODED;          break;        }      }    }  }}static void UpdatePreviousBlockLists(PP_INSTANCE *ppi) {  int  i;  /* Shift previous frame block lists along. */  for ( i = ppi->PrevFrameLimit; i > 1; i-- ){    memcpy( ppi->PrevFragments[i], ppi->PrevFragments[i-1],            ppi->ScanFrameFragments );  }  /* Now copy in this frames block list */  memcpy( ppi->PrevFragments[1], ppi->ScanDisplayFragments,          ppi->ScanFrameFragments );}static void CreateOutputDisplayMap( PP_INSTANCE *ppi,                                    signed char *InternalFragmentsPtr,                                    signed char *RecentHistoryPtr,                                    unsigned char *ExternalFragmentsPtr ) {  ogg_uint32_t i;  ogg_uint32_t HistoryBlocksAdded = 0;  ogg_uint32_t YBand =  (ppi->ScanYPlaneFragments/8);   /* 1/8th of Y image. */  ppi->OutputBlocksUpdated = 0;  for ( i = 0; i < ppi->ScanFrameFragments; i++ ) {    if ( InternalFragmentsPtr[i] > BLOCK_NOT_CODED ) {      ppi->OutputBlocksUpdated ++;      ExternalFragmentsPtr[i] = 1;    }else if ( RecentHistoryPtr[i] == BLOCK_CODED ){

⌨️ 快捷键说明

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