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

📄 decode.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
                MVect[4].y = (MVect[4].y - 2) / 4;              MVect[5].y = MVect[4].y;            }            /* Keep track of last and prior last inter motion vectors. */            if ( CodingMethod == CODE_INTER_PLUS_MV ){              PriorLastInterMV.x = LastInterMV.x;              PriorLastInterMV.y = LastInterMV.y;              LastInterMV.x = MVect[0].x;              LastInterMV.y = MVect[0].y;            }else if ( CodingMethod == CODE_INTER_LAST_MV ){              /* Use the last coded Inter motion vector. */              MVect[0].x = LastInterMV.x;              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 = LastInterMV.y;              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_PRIOR_LAST ){              /* Use the next-to-last coded Inter motion vector. */              MVect[0].x = PriorLastInterMV.x;              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 = PriorLastInterMV.y;              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;              /* Swap the prior and last MV cases over */              TmpMVect.x = PriorLastInterMV.x;              TmpMVect.y = PriorLastInterMV.y;              PriorLastInterMV.x = LastInterMV.x;              PriorLastInterMV.y = LastInterMV.y;              LastInterMV.x = TmpMVect.x;              LastInterMV.y = TmpMVect.y;            }else if ( CodingMethod == CODE_INTER_FOURMV ){              /* Update last MV and prior last mv */              PriorLastInterMV.x = LastInterMV.x;              PriorLastInterMV.y = LastInterMV.y;              LastInterMV.x = MVect[3].x;              LastInterMV.y = MVect[3].y;            }            /* Note the coding mode and vector for each block in the               current macro block. */            pbi->FragMVect[FragIndex].x = MVect[0].x;            pbi->FragMVect[FragIndex].y = MVect[0].y;            pbi->FragMVect[FragIndex + 1].x = MVect[1].x;            pbi->FragMVect[FragIndex + 1].y = MVect[1].y;            pbi->FragMVect[FragIndex + pbi->HFragments].x = MVect[2].x;            pbi->FragMVect[FragIndex + pbi->HFragments].y = MVect[2].y;            pbi->FragMVect[FragIndex + pbi->HFragments + 1].x = MVect[3].x;            pbi->FragMVect[FragIndex + pbi->HFragments + 1].y = MVect[3].y;            /* 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->FragMVect[pbi->YPlaneFragments + UVFragOffset].x = MVect[4].x;            pbi->FragMVect[pbi->YPlaneFragments + UVFragOffset].y = MVect[4].y;            pbi->FragMVect[pbi->YPlaneFragments + pbi->UVPlaneFragments +                          UVFragOffset].x = MVect[5].x;            pbi->FragMVect[pbi->YPlaneFragments + pbi->UVPlaneFragments +                          UVFragOffset].y = MVect[5].y;          }        }      }      /* Next Super-Block */      SB++;    }  }}static ogg_uint32_t ExtractToken(oggpack_buffer *opb,                                 HUFF_ENTRY * CurrentRoot){  long ret;  ogg_uint32_t Token;  /* Loop searches down through tree based upon bits read from the     bitstream */  /* until it hits a leaf at which point we have decoded a token */  while ( CurrentRoot->Value < 0 ){    theora_read(opb, 1, &ret);    if (ret < 0) break; /* out of packet data! */    if (ret)      CurrentRoot = CurrentRoot->OneChild;    else      CurrentRoot = CurrentRoot->ZeroChild;  }  Token = CurrentRoot->Value;  return Token;}static void UnpackAndExpandDcToken( PB_INSTANCE *pbi,                                    Q_LIST_ENTRY *ExpandedBlock,                                    unsigned char * CoeffIndex ){  long                  ret;  ogg_int32_t           ExtraBits = 0;  ogg_uint32_t          Token;  Token = ExtractToken(pbi->opb, pbi->HuffRoot_VP3x[pbi->DcHuffChoice]);  /* Now.. if we are using the DCT optimised coding system, extract any   *  assosciated additional bits token.   */  if ( pbi->ExtraBitLengths_VP3x[Token] > 0 ){    /* Extract the appropriate number of extra bits. */    theora_read(pbi->opb,pbi->ExtraBitLengths_VP3x[Token], &ret);    ExtraBits = ret;  }  /* Take token dependant action */  if ( Token >= DCT_SHORT_ZRL_TOKEN ) {    /* "Value", "zero run" and "zero run value" tokens */    ExpandToken(ExpandedBlock, CoeffIndex, Token, ExtraBits );    if ( *CoeffIndex >= BLOCK_SIZE )      pbi->BlocksToDecode --;  } else if ( Token == DCT_EOB_TOKEN ){    *CoeffIndex = BLOCK_SIZE;    pbi->BlocksToDecode --;  }else{    /* Special action and EOB tokens */    switch ( Token ){    case DCT_EOB_PAIR_TOKEN:      pbi->EOB_Run = 1;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_EOB_TRIPLE_TOKEN:      pbi->EOB_Run = 2;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN_TOKEN:      pbi->EOB_Run = ExtraBits + 3;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN2_TOKEN:      pbi->EOB_Run = ExtraBits + 7;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN3_TOKEN:      pbi->EOB_Run = ExtraBits + 15;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN4_TOKEN:      pbi->EOB_Run = ExtraBits - 1;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    }  }}static void UnpackAndExpandAcToken( PB_INSTANCE *pbi,                                    Q_LIST_ENTRY * ExpandedBlock,                                    unsigned char * CoeffIndex  ) {  long                  ret;  ogg_int32_t           ExtraBits = 0;  ogg_uint32_t          Token;  Token = ExtractToken(pbi->opb, pbi->HuffRoot_VP3x[pbi->ACHuffChoice]);  /* Now.. if we are using the DCT optimised coding system, extract any   *  assosciated additional bits token.   */  if ( pbi->ExtraBitLengths_VP3x[Token] > 0 ){    /* Extract the appropriate number of extra bits. */    theora_read(pbi->opb,pbi->ExtraBitLengths_VP3x[Token], &ret);    ExtraBits = ret;  }  /* Take token dependant action */  if ( Token >= DCT_SHORT_ZRL_TOKEN ){    /* "Value", "zero run" and "zero run value" tokens */    ExpandToken(ExpandedBlock, CoeffIndex, Token, ExtraBits );    if ( *CoeffIndex >= BLOCK_SIZE )      pbi->BlocksToDecode --;  } else if ( Token == DCT_EOB_TOKEN ) {    *CoeffIndex = BLOCK_SIZE;    pbi->BlocksToDecode --;  } else {    /* Special action and EOB tokens */    switch ( Token ) {    case DCT_EOB_PAIR_TOKEN:      pbi->EOB_Run = 1;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_EOB_TRIPLE_TOKEN:      pbi->EOB_Run = 2;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN_TOKEN:      pbi->EOB_Run = ExtraBits + 3;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN2_TOKEN:      pbi->EOB_Run = ExtraBits + 7;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN3_TOKEN:      pbi->EOB_Run = ExtraBits + 15;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    case DCT_REPEAT_RUN4_TOKEN:      pbi->EOB_Run = ExtraBits - 1;      *CoeffIndex = BLOCK_SIZE;      pbi->BlocksToDecode --;      break;    }  }}static void UnPackVideo (PB_INSTANCE *pbi){  long ret;  ogg_int32_t       EncodedCoeffs = 1;  ogg_int32_t       FragIndex;  ogg_int32_t *     CodedBlockListPtr;  ogg_int32_t *     CodedBlockListEnd;  unsigned char     AcHuffIndex1;  unsigned char     AcHuffIndex2;  unsigned char     AcHuffChoice1;  unsigned char     AcHuffChoice2;  unsigned char     DcHuffChoice1;  unsigned char     DcHuffChoice2;  /* Bail out immediately if a decode error has already been reported. */  if ( pbi->DecoderErrorCode ) return;  /* Clear down the array that indicates the current coefficient index     for each block. */  memset(pbi->FragCoeffs, 0, pbi->UnitFragments);  memset(pbi->FragCoefEOB, 0, pbi->UnitFragments);  /* Clear down the pbi->QFragData structure for all coded blocks. */  ClearDownQFragData(pbi);  /* Note the number of blocks to decode */  pbi->BlocksToDecode = pbi->CodedBlockIndex;  /* Get the DC huffman table choice for Y and then UV */  theora_read(pbi->opb,DC_HUFF_CHOICE_BITS,&ret);   DcHuffChoice1 = ret + DC_HUFF_OFFSET;  if (ret < 0 || DcHuffChoice1 >= NUM_HUFF_TABLES) {    DcHuffChoice1 = DC_HUFF_OFFSET;    pbi->DecoderErrorCode = 1;  }  theora_read(pbi->opb,DC_HUFF_CHOICE_BITS,&ret);   DcHuffChoice2 = ret + DC_HUFF_OFFSET;  if (ret < 0 || DcHuffChoice2 >= NUM_HUFF_TABLES) {    DcHuffChoice2 = DC_HUFF_OFFSET;    pbi->DecoderErrorCode = 1;  }  /* UnPack DC coefficients / tokens */  CodedBlockListPtr = pbi->CodedBlockList;  CodedBlockListEnd = &pbi->CodedBlockList[pbi->CodedBlockIndex];  while ( CodedBlockListPtr < CodedBlockListEnd  ) {    /* Get the block data index */    FragIndex = *CodedBlockListPtr;    pbi->FragCoefEOB[FragIndex] = pbi->FragCoeffs[FragIndex];    /* Select the appropriate huffman table offset according to       whether the token is from a Y or UV block */    if ( FragIndex < (ogg_int32_t)pbi->YPlaneFragments )      pbi->DcHuffChoice = DcHuffChoice1;    else      pbi->DcHuffChoice = DcHuffChoice2;    /* If we are in the middle of an EOB run */    if ( pbi->EOB_Run ){      /* Mark the current block as fully expanded and decrement         EOB_RUN count */      pbi->FragCoeffs[FragIndex] = BLOCK_SIZE;      pbi->EOB_Run --;      pbi->BlocksToDecode --;    }else{      /* Else unpack a DC token */      UnpackAndExpandDcToken( pbi,                              pbi->QFragData[FragIndex],                              &pbi->FragCoeffs[FragIndex] );    }    CodedBlockListPtr++;  }  /* Get the AC huffman table choice for Y and then for UV. */  theora_read(pbi->opb,AC_HUFF_CHOICE_BITS,&ret);   AcHuffIndex1 = ret + AC_HUFF_OFFSET;  if (ret < 0 || AcHuffIndex1 >= NUM_HUFF_TABLES) {    AcHuffIndex1 = AC_HUFF_OFFSET;    pbi->DecoderErrorCode = 1;  }  theora_read(pbi->opb,AC_HUFF_CHOICE_BITS,&ret);   AcHuffIndex2 = ret + AC_HUFF_OFFSET;  if (ret < 0 || AcHuffIndex2 >= NUM_HUFF_TABLES) {    AcHuffIndex2 = AC_HUFF_OFFSET;    pbi->DecoderErrorCode = 1;  }  /* Unpack Lower AC coefficients. */  while ( EncodedCoeffs < 64 ) {    /* Repeatedly scan through the list of blocks. */    CodedBlockListPtr = pbi->CodedBlockList;    CodedBlockListEnd = &pbi->CodedBlockList[pbi->CodedBlockIndex];    /* Huffman table selection based upon which AC coefficient we are on */    if ( EncodedCoeffs <= AC_TABLE_2_THRESH ){      AcHuffChoice1 = AcHuffIndex1;      AcHuffChoice2 = AcHuffIndex2;    }else if ( EncodedCoeffs <= AC_TABLE_3_THRESH ){      AcHuffChoice1 = AcHuffIndex1 + AC_HUFF_CHOICES;      AcHuffChoice2 = AcHuffIndex2 + AC_HUFF_CHOICES;    } else if ( EncodedCoeffs <= AC_TABLE_4_THRESH ){      AcHuffChoice1 = AcHuffIndex1 + (AC_HUFF_CHOICES * 2);      AcHuffChoice2 = AcHuffIndex2 + (AC_HUFF_CHOICES * 2);    } else {      AcHuffChoice1 = AcHuffIndex1 + (AC_HUFF_CHOICES * 3);      AcHuffChoice2 = AcHuffIndex2 + (AC_HUFF_CHOICES * 3);    }    while( CodedBlockListPtr < CodedBlockListEnd ) {      /* Get the linear index for the current fragment. */      FragIndex = *CodedBlockListPtr;      /* Should we decode a token for this block on this pass. */      if ( pbi->FragCoeffs[FragIndex] <= EncodedCoeffs ) {        pbi->FragCoefEOB[FragIndex] = pbi->FragCoeffs[FragIndex];        /* If we are in the middle of an EOB run */        if ( pbi->EOB_Run ) {          /* Mark the current block as fully expanded and decrement             EOB_RUN count */          pbi->FragCoeffs[FragIndex] = BLOCK_SIZE;          pbi->EOB_Run --;          pbi->BlocksToDecode --;        }else{          /* Else unpack an AC token */          /* Work out which huffman table to use, then decode a token */          if ( FragIndex < (ogg_int32_t)pbi->YPlaneFragments )            pbi->ACHuffChoice = AcHuffChoice1;          else            pbi->ACHuffChoice = AcHuffChoice2;          UnpackAndExpandAcToken( pbi, pbi->QFragData[FragIndex],                                  &pbi->FragCoeffs[FragIndex] );        }      }      CodedBlockListPtr++;    }    /* Test for condition where there are no blocks left with any       tokesn to decode */    if ( !pbi->BlocksToDecode )      break;    EncodedCoeffs ++;  }}static void DecodeData(PB_INSTANCE *pbi){  ogg_uint32_t i;  /* Bail out immediately if a decode error has already been reported. */  if ( pbi->DecoderErrorCode ) return;  /* Clear down the macro block level mode and MV arrays. */  for ( i = 0; i < pbi->UnitFragments; i++ ){    pbi->FragCodingMethod[i] = CODE_INTER_NO_MV; /* Default coding mode */    pbi->FragMVect[i].x = 0;    pbi->FragMVect[i].y = 0;  }  /* Zero Decoder EOB run count */  pbi->EOB_Run = 0;  /* Make a note of the number of coded blocks this frame */  pbi->CodedBlocksThisFrame = pbi->CodedBlockIndex;  /* Decode the modes data */  DecodeModes( pbi, pbi->YSBRows, pbi->YSBCols);  if (pbi->DecoderErrorCode) return;  /* Unpack and decode the motion vectors. */  DecodeMVectors ( pbi, pbi->YSBRows, pbi->YSBCols);  if (pbi->DecoderErrorCode) return;  /* Unpack and decode the actual video data. */  UnPackVideo(pbi);  if (pbi->DecoderErrorCode) return;  /* Reconstruct and display the frame */  dsp_save_fpu (pbi->dsp);  ReconRefFrames(pbi);  dsp_restore_fpu (pbi->dsp);}int LoadAndDecode(PB_INSTANCE *pbi){  /* Reset the DC predictors. */  pbi->InvLastIntraDC = 0;  pbi->InvLastInterDC = 0;  if ( LoadFrame(pbi) == 0 ){    pbi->LastFrameQualityValue = pbi->ThisFrameQualityValue;    /* Decode the data into the fragment buffer. */    DecodeData(pbi);    if (pbi->DecoderErrorCode == 0) return 0;  }  return OC_BADPACKET;}

⌨️ 快捷键说明

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