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

📄 decode.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************** *                                                                  * * 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-2006                * * by the Xiph.Org Foundation http://www.xiph.org/                  * *                                                                  * ********************************************************************  function:  last mod: $Id: decode.c 11442 2006-05-27 17:28:08Z giles $ ********************************************************************/#include <string.h>#include "codec_internal.h"#include "block_inline.h"static const CODING_MODE  ModeAlphabet[MODE_METHODS-2][MAX_MODES] = {  /* Last motion vector dominates */  {    CODE_INTER_LAST_MV,    CODE_INTER_PRIOR_LAST,       CODE_INTER_PLUS_MV,    CODE_INTER_NO_MV,       CODE_INTRA,            CODE_USING_GOLDEN,       CODE_GOLDEN_MV,        CODE_INTER_FOURMV },  {    CODE_INTER_LAST_MV,    CODE_INTER_PRIOR_LAST,       CODE_INTER_NO_MV,      CODE_INTER_PLUS_MV,       CODE_INTRA,            CODE_USING_GOLDEN,       CODE_GOLDEN_MV,        CODE_INTER_FOURMV },  {    CODE_INTER_LAST_MV,    CODE_INTER_PLUS_MV,       CODE_INTER_PRIOR_LAST, CODE_INTER_NO_MV,       CODE_INTRA,            CODE_USING_GOLDEN,       CODE_GOLDEN_MV,        CODE_INTER_FOURMV },  {    CODE_INTER_LAST_MV,    CODE_INTER_PLUS_MV,       CODE_INTER_NO_MV,      CODE_INTER_PRIOR_LAST,       CODE_INTRA,            CODE_USING_GOLDEN,       CODE_GOLDEN_MV,        CODE_INTER_FOURMV },  /* No motion vector dominates */  {    CODE_INTER_NO_MV,      CODE_INTER_LAST_MV,       CODE_INTER_PRIOR_LAST, CODE_INTER_PLUS_MV,       CODE_INTRA,            CODE_USING_GOLDEN,       CODE_GOLDEN_MV,        CODE_INTER_FOURMV },  {    CODE_INTER_NO_MV,      CODE_USING_GOLDEN,       CODE_INTER_LAST_MV,    CODE_INTER_PRIOR_LAST,       CODE_INTER_PLUS_MV,    CODE_INTRA,       CODE_GOLDEN_MV,        CODE_INTER_FOURMV },};int GetFrameType(PB_INSTANCE *pbi){  return pbi->FrameType;}static int LoadFrameHeader(PB_INSTANCE *pbi){  long ret;  int NQIndex;  unsigned char  DctQIndex[3];  unsigned char  SpareBits;       /* Spare cfg bits */  /* Is the frame and inter frame or a key frame */  theora_read(pbi->opb,1,&ret);  pbi->FrameType = (unsigned char)ret;  /* Quality (Q) index */  NQIndex = 0;  theora_read(pbi->opb,6,&ret);  if (ret < 0 || ret >= 64) {   /* range check */    ret = 0;    pbi->DecoderErrorCode = 1;  }  DctQIndex[NQIndex++] = (unsigned char)ret;  theora_read(pbi->opb,1,&ret);  SpareBits = (unsigned char)ret;  if (SpareBits) {    theora_read(pbi->opb,6,&ret);    if (ret < 0 || ret >= 64) { /* range check */      ret = 0;      pbi->DecoderErrorCode = 1;    }    DctQIndex[NQIndex++] = (unsigned char)ret;    theora_read(pbi->opb,1,&ret);    SpareBits = (unsigned char)ret;    if (SpareBits) {      theora_read(pbi->opb,6,&ret);      if (ret < 0 || ret >= 64) {       /* range check */        ret = 0;        pbi->DecoderErrorCode = 1;      }      DctQIndex[NQIndex++] = (unsigned char)ret;    }  }  if (NQIndex != 1) return OC_IMPL;  if ( (pbi->FrameType == KEY_FRAME) ){    /* Read the type / coding method for the key frame. */    theora_read(pbi->opb,1,&ret);    pbi->KeyFrameType = (unsigned char)ret;    theora_read(pbi->opb,2,&ret);    SpareBits = (unsigned char)ret;    if (pbi->KeyFrameType || SpareBits) return OC_BADPACKET;  }  /* Set this frame quality value and tables from the coded Q Index */  UpdateQ(pbi, DctQIndex[0]);  return pbi->DecoderErrorCode;}void SetFrameType( PB_INSTANCE *pbi,unsigned char FrType ){  /* Set the appropriate frame type according to the request. */  switch ( FrType ){  case KEY_FRAME:    pbi->FrameType = FrType;    break;  default:    pbi->FrameType = FrType;    break;  }}static int LoadFrame(PB_INSTANCE *pbi){  /* Load the frame header (including the frame size). */  if ( LoadFrameHeader(pbi) == 0 ){    /* Read in the updated block map */    QuadDecodeDisplayFragments( pbi );    return 0;  }  return pbi->DecoderErrorCode;}static void DecodeModes (PB_INSTANCE *pbi,                         ogg_uint32_t SBRows,                         ogg_uint32_t SBCols){  long ret;  ogg_int32_t   FragIndex;  ogg_uint32_t  MB;  ogg_uint32_t  SBrow;  ogg_uint32_t  SBcol;  ogg_uint32_t  SB=0;  CODING_MODE  CodingMethod;  ogg_uint32_t  UVRow;  ogg_uint32_t  UVColumn;  ogg_uint32_t  UVFragOffset;  ogg_uint32_t  CodingScheme;  ogg_uint32_t  MBListIndex = 0;  ogg_uint32_t  i;  /* If the frame is an intra frame then all blocks have mode intra. */  if ( GetFrameType(pbi) == KEY_FRAME ){    for ( i = 0; i < pbi->UnitFragments; i++ ){      pbi->FragCodingMethod[i] = CODE_INTRA;    }  }else{    ogg_uint32_t        ModeEntry; /* Mode bits read */    CODING_MODE         CustomModeAlphabet[MAX_MODES];    const CODING_MODE  *ModeList;    /* Read the coding method */    theora_read(pbi->opb, MODE_METHOD_BITS, &ret);    CodingScheme=ret;    /* If the coding method is method 0 then we have to read in a       custom coding scheme */    if ( CodingScheme == 0 ){      /* Read the coding scheme. */      for ( i = 0; i < MAX_MODES; i++ ){        theora_read(pbi->opb, MODE_BITS, &ret);        CustomModeAlphabet[ret]=i;      }      ModeList=CustomModeAlphabet;    }    else{      ModeList=ModeAlphabet[CodingScheme-1];    }    /* Unravel the quad-tree */    for ( SBrow=0; SBrow<SBRows; SBrow++ ){      for ( SBcol=0; SBcol<SBCols; SBcol++ ){        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(pbi->BlockMap, SB,MB) >= 0){            /* Is the Macro-Block coded: */            if ( pbi->MBCodedFlags[MBListIndex++] ){              /* Upack the block level modes and motion vectors */              FragIndex = QuadMapToMBTopLeft( pbi->BlockMap, SB, MB );              /* Unpack the mode. */              if ( CodingScheme == (MODE_METHODS-1) ){                /* This is the fall back coding scheme. */                /* Simply MODE_BITS bits per mode entry. */                theora_read(pbi->opb, MODE_BITS, &ret);                CodingMethod = (CODING_MODE)ret;              }else{                ModeEntry = FrArrayUnpackMode(pbi);                CodingMethod = ModeList[ModeEntry];              }              /* Note the coding mode for each block in macro block. */              pbi->FragCodingMethod[FragIndex] = CodingMethod;              pbi->FragCodingMethod[FragIndex + 1] = CodingMethod;              pbi->FragCodingMethod[FragIndex + pbi->HFragments] =                CodingMethod;              pbi->FragCodingMethod[FragIndex + pbi->HFragments + 1] =                CodingMethod;              /* Matching fragments in the U and V planes */              UVRow = (FragIndex / (pbi->HFragments * 2));              UVColumn = (FragIndex % pbi->HFragments) / 2;              UVFragOffset = (UVRow * (pbi->HFragments / 2)) + UVColumn;              pbi->FragCodingMethod[pbi->YPlaneFragments + UVFragOffset] =                CodingMethod;              pbi->FragCodingMethod[pbi->YPlaneFragments +                                   pbi->UVPlaneFragments + UVFragOffset] =                CodingMethod;            }          }        }        /* Next Super-Block */        SB++;      }    }  }}static ogg_int32_t ExtractMVectorComponentA(PB_INSTANCE *pbi){  long ret;  ogg_int32_t   MVectComponent;  ogg_uint32_t  MVCode = 0;  ogg_uint32_t  ExtraBits = 0;  /* Get group to which coded component belongs */  theora_read(pbi->opb, 3, &ret);  MVCode=ret;  /*  Now extract the appropriate number of bits to identify the component */  switch ( MVCode ){  case 0:    MVectComponent = 0;    break;  case 1:    MVectComponent = 1;    break;  case 2:    MVectComponent = -1;    break;  case 3:    theora_read(pbi->opb,1,&ret);    if (ret)      MVectComponent = -2;    else      MVectComponent = 2;    break;  case 4:    theora_read(pbi->opb,1,&ret);    if (ret)      MVectComponent = -3;    else      MVectComponent = 3;    break;  case 5:    theora_read(pbi->opb,2,&ret);    ExtraBits=ret;    MVectComponent = 4 + ExtraBits;    theora_read(pbi->opb,1,&ret);    if (ret)      MVectComponent = -MVectComponent;    break;  case 6:    theora_read(pbi->opb,3,&ret);    ExtraBits=ret;    MVectComponent = 8 + ExtraBits;    theora_read(pbi->opb,1,&ret);    if (ret)      MVectComponent = -MVectComponent;    break;  case 7:    theora_read(pbi->opb,4,&ret);    ExtraBits=ret;    MVectComponent = 16 + ExtraBits;    theora_read(pbi->opb,1,&ret);    if (ret)      MVectComponent = -MVectComponent;    break;  default:    /* occurs if there is a read error */    MVectComponent = 0;  }  return MVectComponent;}static ogg_int32_t ExtractMVectorComponentB(PB_INSTANCE *pbi){  long ret;  ogg_int32_t   MVectComponent;  /* Get group to which coded component belongs */  theora_read(pbi->opb,5,&ret);  MVectComponent=ret;  theora_read(pbi->opb,1,&ret);  if (ret)    MVectComponent = -MVectComponent;  return MVectComponent;}static void DecodeMVectors ( PB_INSTANCE *pbi,                             ogg_uint32_t SBRows,                             ogg_uint32_t SBCols ){  long ret;  ogg_int32_t   FragIndex;  ogg_uint32_t  MB;  ogg_uint32_t  SBrow;  ogg_uint32_t  SBcol;  ogg_uint32_t  SB=0;  ogg_uint32_t  CodingMethod;  MOTION_VECTOR MVect[6];  MOTION_VECTOR TmpMVect;  MOTION_VECTOR LastInterMV;  MOTION_VECTOR PriorLastInterMV;  ogg_int32_t (*ExtractMVectorComponent)(PB_INSTANCE *pbi);  ogg_uint32_t  UVRow;  ogg_uint32_t  UVColumn;  ogg_uint32_t  UVFragOffset;  ogg_uint32_t  MBListIndex = 0;  /* Should not be decoding motion vectors if in INTRA only mode. */  if ( GetFrameType(pbi) == KEY_FRAME ){    return;  }  /* set the default motion vectors to 0,0 */  MVect[0].x = 0;  MVect[0].y = 0;  MVect[1].x = 0;  MVect[1].y = 0;  MVect[2].x = 0;  MVect[2].y = 0;  MVect[3].x = 0;  MVect[3].y = 0;  MVect[4].x = 0;  MVect[4].y = 0;  MVect[5].x = 0;  MVect[5].y = 0;  LastInterMV.x = 0;  LastInterMV.y = 0;  PriorLastInterMV.x = 0;  PriorLastInterMV.y = 0;  /* Read the entropy method used and set up the appropriate decode option */  theora_read(pbi->opb, 1, &ret);    if ( ret == 0 )    ExtractMVectorComponent = ExtractMVectorComponentA;  else    ExtractMVectorComponent = ExtractMVectorComponentB;  /* Unravel the quad-tree */  for ( SBrow=0; SBrow<SBRows; SBrow++ ){    for ( SBcol=0; SBcol<SBCols; SBcol++ ){      for ( MB=0; MB<4; MB++ ){        /* There may be MB's lying out of frame which must be           ignored. For these MB's the top left block will have a           negative Fragment. */        if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 ) {          /* Is the Macro-Block further coded: */          if ( pbi->MBCodedFlags[MBListIndex++] ){            /* Upack the block level modes and motion vectors */            FragIndex = QuadMapToMBTopLeft( pbi->BlockMap, SB, MB );            /* Clear the motion vector before we start. */            MVect[0].x = 0;            MVect[0].y = 0;            /* Unpack the mode (and motion vectors if necessary). */            CodingMethod = pbi->FragCodingMethod[FragIndex];            /* Read the motion vector or vectors if present. */            if ( (CodingMethod == CODE_INTER_PLUS_MV) ||                 (CodingMethod == CODE_GOLDEN_MV) ){              MVect[0].x = ExtractMVectorComponent(pbi);              MVect[1].x = MVect[0].x;              MVect[2].x = MVect[0].x;              MVect[3].x = MVect[0].x;              MVect[4].x = MVect[0].x;              MVect[5].x = MVect[0].x;              MVect[0].y = ExtractMVectorComponent(pbi);              MVect[1].y = MVect[0].y;              MVect[2].y = MVect[0].y;              MVect[3].y = MVect[0].y;              MVect[4].y = MVect[0].y;              MVect[5].y = MVect[0].y;            }else if ( CodingMethod == CODE_INTER_FOURMV ){              /* Extrac the 4 Y MVs */              MVect[0].x = ExtractMVectorComponent(pbi);              MVect[0].y = ExtractMVectorComponent(pbi);              MVect[1].x = ExtractMVectorComponent(pbi);              MVect[1].y = ExtractMVectorComponent(pbi);              MVect[2].x = ExtractMVectorComponent(pbi);              MVect[2].y = ExtractMVectorComponent(pbi);              MVect[3].x = ExtractMVectorComponent(pbi);              MVect[3].y = ExtractMVectorComponent(pbi);              /* Calculate the U and V plane MVs as the average of the                 Y plane MVs. */              /* First .x component */              MVect[4].x = MVect[0].x + MVect[1].x + MVect[2].x + MVect[3].x;              if ( MVect[4].x >= 0 )                MVect[4].x = (MVect[4].x + 2) / 4;              else                MVect[4].x = (MVect[4].x - 2) / 4;              MVect[5].x = MVect[4].x;              /* Then .y component */              MVect[4].y = MVect[0].y + MVect[1].y + MVect[2].y + MVect[3].y;              if ( MVect[4].y >= 0 )                MVect[4].y = (MVect[4].y + 2) / 4;              else

⌨️ 快捷键说明

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