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

📄 encode.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************** *                                                                  * * 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: encode.c 11442 2006-05-27 17:28:08Z giles $ ********************************************************************/#include <stdlib.h>#include <string.h>#include "codec_internal.h"#include "encoder_lookup.h"#include "block_inline.h"#define PUR 8#define PU 4#define PUL 2#define PL 1#define HIGHBITDUPPED(X) (((ogg_int16_t) X)  >> 15)static ogg_uint32_t QuadCodeComponent ( CP_INSTANCE *cpi,                                 ogg_uint32_t FirstSB,                                 ogg_uint32_t SBRows,                                 ogg_uint32_t SBCols,                                 ogg_uint32_t PixelsPerLine ){  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=FirstSB;     /* Super-Block index, initialised to first                                   of this component */  ogg_uint32_t  coded_pixels=0; /* Number of pixels coded */  int           MBCodedFlag;  /* actually transform and quantize the image now that we've decided     on the modes Parse in quad-tree ordering */  SB=FirstSB;  for ( SBrow=0; SBrow<SBRows; SBrow++ ) {    for ( SBcol=0; SBcol<SBCols; SBcol++ ) {      /* Check its four Macro-Blocks  */      for ( MB=0; MB<4; MB++ ) {        if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {          MBCodedFlag = 0;          /*  Now actually code the blocks */          for ( B=0; B<4; B++ ) {            FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );            /* Does Block lie in frame: */            if ( FragIndex >= 0 ) {              /* In Frame: Is it coded: */              if ( cpi->pb.display_fragments[FragIndex] ) {                /* transform and quantize block */                TransformQuantizeBlock( cpi, FragIndex, PixelsPerLine );                /* Has the block got struck off (no MV and no data                   generated after DCT) If not then mark it and the                   assosciated MB as coded. */                if ( cpi->pb.display_fragments[FragIndex] ) {                  /* Create linear list of coded block indices */                  cpi->pb.CodedBlockList[cpi->pb.CodedBlockIndex] = FragIndex;                  cpi->pb.CodedBlockIndex++;                  /* MB is still coded */                  MBCodedFlag = 1;                  cpi->MBCodingMode = cpi->pb.FragCodingMethod[FragIndex];                }              }            }          }          /* If the MB is marked as coded and we are in the Y plane then */          /* the mode list needs to be updated. */          if ( MBCodedFlag && (FirstSB == 0) ){            /* Make a note of the selected mode in the mode list */            cpi->ModeList[cpi->ModeListCount] = cpi->MBCodingMode;            cpi->ModeListCount++;          }        }      }      SB++;    }  }  /* Return number of pixels coded */  return coded_pixels;}static void EncodeDcTokenList (CP_INSTANCE *cpi) {  ogg_int32_t   i,j;  ogg_uint32_t  Token;  ogg_uint32_t  ExtraBitsToken;  ogg_uint32_t  HuffIndex;  ogg_uint32_t  BestDcBits;  ogg_uint32_t  DcHuffChoice[2];  ogg_uint32_t  EntropyTableBits[2][DC_HUFF_CHOICES];  oggpack_buffer *opb=cpi->oggbuffer;  /* Clear table data structure */  memset ( EntropyTableBits, 0, sizeof(ogg_uint32_t)*DC_HUFF_CHOICES*2 );  /* Analyse token list to see which is the best entropy table to use */  for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {    /* Count number of bits for each table option */    Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];    for ( j = 0; j < DC_HUFF_CHOICES; j++ ){      EntropyTableBits[cpi->OptimisedTokenListPl[i]][j] +=        cpi->pb.HuffCodeLengthArray_VP3x[DC_HUFF_OFFSET + j][Token];    }  }  /* Work out which table option is best for Y */  BestDcBits = EntropyTableBits[0][0];  DcHuffChoice[0] = 0;  for ( j = 1; j < DC_HUFF_CHOICES; j++ ) {    if ( EntropyTableBits[0][j] < BestDcBits ) {      BestDcBits = EntropyTableBits[0][j];      DcHuffChoice[0] = j;    }  }  /* Add the DC huffman table choice to the bitstream */  oggpackB_write( opb, DcHuffChoice[0], DC_HUFF_CHOICE_BITS );  /* Work out which table option is best for UV */  BestDcBits = EntropyTableBits[1][0];  DcHuffChoice[1] = 0;  for ( j = 1; j < DC_HUFF_CHOICES; j++ ) {    if ( EntropyTableBits[1][j] < BestDcBits ) {      BestDcBits = EntropyTableBits[1][j];      DcHuffChoice[1] = j;    }  }  /* Add the DC huffman table choice to the bitstream */  oggpackB_write( opb, DcHuffChoice[1], DC_HUFF_CHOICE_BITS );  /* Encode the token list */  for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {    /* Get the token and extra bits */    Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];    ExtraBitsToken = (ogg_uint32_t)cpi->OptimisedTokenListEb[i];    /* Select the huffman table */    if ( cpi->OptimisedTokenListPl[i] == 0)      HuffIndex = (ogg_uint32_t)DC_HUFF_OFFSET + (ogg_uint32_t)DcHuffChoice[0];    else      HuffIndex = (ogg_uint32_t)DC_HUFF_OFFSET + (ogg_uint32_t)DcHuffChoice[1];    /* Add the bits to the encode holding buffer. */    cpi->FrameBitCount += cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex][Token];    oggpackB_write( opb, cpi->pb.HuffCodeArray_VP3x[HuffIndex][Token],                     (ogg_uint32_t)cpi->                     pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );    /* If the token is followed by an extra bits token then code it */    if ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ) {      /* Add the bits to the encode holding buffer.  */      cpi->FrameBitCount += cpi->pb.ExtraBitLengths_VP3x[Token];      oggpackB_write( opb, ExtraBitsToken,                       (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );    }  }  /* Reset the count of second order optimised tokens */  cpi->OptimisedTokenCount = 0;}static void EncodeAcTokenList (CP_INSTANCE *cpi) {  ogg_int32_t   i,j;  ogg_uint32_t  Token;  ogg_uint32_t  ExtraBitsToken;  ogg_uint32_t  HuffIndex;  ogg_uint32_t  BestAcBits;  ogg_uint32_t  AcHuffChoice[2];  ogg_uint32_t  EntropyTableBits[2][AC_HUFF_CHOICES];  oggpack_buffer *opb=cpi->oggbuffer;  memset ( EntropyTableBits, 0, sizeof(ogg_uint32_t)*AC_HUFF_CHOICES*2 );  /* Analyse token list to see which is the best entropy table to use */  for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {    /* Count number of bits for each table option */    Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];    HuffIndex = cpi->OptimisedTokenListHi[i];    for ( j = 0; j < AC_HUFF_CHOICES; j++ ) {      EntropyTableBits[cpi->OptimisedTokenListPl[i]][j] +=        cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex + j][Token];    }  }  /* Select the best set of AC tables for Y */  BestAcBits = EntropyTableBits[0][0];  AcHuffChoice[0] = 0;  for ( j = 1; j < AC_HUFF_CHOICES; j++ ) {    if ( EntropyTableBits[0][j] < BestAcBits ) {      BestAcBits = EntropyTableBits[0][j];      AcHuffChoice[0] = j;    }  }  /* Add the AC-Y huffman table choice to the bitstream */  oggpackB_write( opb, AcHuffChoice[0], AC_HUFF_CHOICE_BITS );  /* Select the best set of AC tables for UV */  BestAcBits = EntropyTableBits[1][0];  AcHuffChoice[1] = 0;  for ( j = 1; j < AC_HUFF_CHOICES; j++ ) {    if ( EntropyTableBits[1][j] < BestAcBits ) {      BestAcBits = EntropyTableBits[1][j];      AcHuffChoice[1] = j;    }  }  /* Add the AC-UV huffman table choice to the bitstream */  oggpackB_write( opb, AcHuffChoice[1], AC_HUFF_CHOICE_BITS );  /* Encode the token list */  for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {    /* Get the token and extra bits */    Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];    ExtraBitsToken = (ogg_uint32_t)cpi->OptimisedTokenListEb[i];    /* Select the huffman table */    HuffIndex = (ogg_uint32_t)cpi->OptimisedTokenListHi[i] +      AcHuffChoice[cpi->OptimisedTokenListPl[i]];    /* Add the bits to the encode holding buffer. */    cpi->FrameBitCount += cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex][Token];    oggpackB_write( opb, cpi->pb.HuffCodeArray_VP3x[HuffIndex][Token],                     (ogg_uint32_t)cpi->                     pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );    /* If the token is followed by an extra bits token then code it */    if ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ) {      /* Add the bits to the encode holding buffer. */      cpi->FrameBitCount += cpi->pb.ExtraBitLengths_VP3x[Token];      oggpackB_write( opb, ExtraBitsToken,                       (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );    }  }  /* Reset the count of second order optimised tokens */  cpi->OptimisedTokenCount = 0;}static void PackModes (CP_INSTANCE *cpi) {  ogg_uint32_t    i,j;  unsigned char   ModeIndex;  unsigned char  *SchemeList;  unsigned char   BestModeSchemes[MAX_MODES];  ogg_int32_t     ModeCount[MAX_MODES];  ogg_int32_t     TmpFreq = -1;  ogg_int32_t     TmpIndex = -1;  ogg_uint32_t    BestScheme;  ogg_uint32_t    BestSchemeScore;  ogg_uint32_t    SchemeScore;  oggpack_buffer *opb=cpi->oggbuffer;  /* Build a frequency map for the modes in this frame */  memset( ModeCount, 0, MAX_MODES*sizeof(ogg_int32_t) );  for ( i = 0; i < cpi->ModeListCount; i++ )    ModeCount[cpi->ModeList[i]] ++;  /* Order the modes from most to least frequent.  Store result as     scheme 0 */  for ( j = 0; j < MAX_MODES; j++ ) {    TmpFreq = -1;  /* need to re-initialize for each loop */    /* Find the most frequent */    for ( i = 0; i < MAX_MODES; i++ ) {      /* Is this the best scheme so far ??? */      if ( ModeCount[i] > TmpFreq ) {        TmpFreq = ModeCount[i];        TmpIndex = i;      }    }    /* I don't know if the above loop ever fails to match, but it's       better safe than sorry.  Plus this takes care of gcc warning */    if ( TmpIndex != -1 ) {      ModeCount[TmpIndex] = -1;      BestModeSchemes[TmpIndex] = (unsigned char)j;    }  }  /* Default/ fallback scheme uses MODE_BITS bits per mode entry */  BestScheme = (MODE_METHODS - 1);  BestSchemeScore = cpi->ModeListCount * 3;  /* Get a bit score for the available schemes. */  for (  j = 0; j < (MODE_METHODS - 1); j++ ) {    /* Reset the scheme score */    if ( j == 0 ){      /* Scheme 0 additional cost of sending frequency order */      SchemeScore = 24;      SchemeList = BestModeSchemes;    } else {      SchemeScore = 0;      SchemeList = ModeSchemes[j-1];    }    /* Find the total bits to code using each avaialable scheme */    for ( i = 0; i < cpi->ModeListCount; i++ )      SchemeScore += ModeBitLengths[SchemeList[cpi->ModeList[i]]];    /* Is this the best scheme so far ??? */    if ( SchemeScore < BestSchemeScore ) {      BestSchemeScore = SchemeScore;      BestScheme = j;    }  }  /* Encode the best scheme. */  oggpackB_write( opb, BestScheme, (ogg_uint32_t)MODE_METHOD_BITS );  /* If the chosen schems is scheme 0 send details of the mode     frequency order */  if ( BestScheme == 0 ) {    for ( j = 0; j < MAX_MODES; j++ )      /* Note that the last two entries are implicit */      oggpackB_write( opb, BestModeSchemes[j], (ogg_uint32_t)MODE_BITS );    SchemeList = BestModeSchemes;  }  else {    SchemeList = ModeSchemes[BestScheme-1];  }  /* Are we using one of the alphabet based schemes or the fallback scheme */  if ( BestScheme < (MODE_METHODS - 1)) {    /* Pack and encode the Mode list */    for ( i = 0; i < cpi->ModeListCount; i++ ) {      /* Add the appropriate mode entropy token. */      ModeIndex = SchemeList[cpi->ModeList[i]];      oggpackB_write( opb, ModeBitPatterns[ModeIndex],                       (ogg_uint32_t)ModeBitLengths[ModeIndex] );    }  }else{    /* Fall back to MODE_BITS per entry */    for ( i = 0; i < cpi->ModeListCount; i++ ) {      /* Add the appropriate mode entropy token. */      oggpackB_write( opb, cpi->ModeList[i], MODE_BITS  );    }  }}static void PackMotionVectors (CP_INSTANCE *cpi) {  ogg_int32_t  i;  ogg_uint32_t MethodBits[2] = {0,0};

⌨️ 快捷键说明

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