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

📄 frarray.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 2 页
字号:
     10x                    2-3
     110x                   4-5
     1110xx                 6-9
     11110xxx              10-17
     111110xxxx            18-33
     111111xxxxxxxxxxxx    34-4129
  */

  switch ( pbi->bits_so_far ){
  case 1:
    if ( pbi->bit_pattern == 0 ){
      ret_val = 1;
      *run_value = 1;
    }
    break;

  case 3:
    /* Bit 1 clear */
    if ( !(pbi->bit_pattern & 0x0002) ){
      ret_val = 1;
      *run_value = (pbi->bit_pattern & 0x0001) + 2;
    }
    break;

  case 4:
    /* Bit 1 clear */
    if ( !(pbi->bit_pattern & 0x0002) ){
      ret_val = 1;
      *run_value = (pbi->bit_pattern & 0x0001) + 4;
    }
    break;

  case 6:
    /* Bit 2 clear */
    if ( !(pbi->bit_pattern & 0x0004) ){
      ret_val = 1;
      *run_value = (pbi->bit_pattern & 0x0003) + 6;
    }
    break;

  case 8:
    /* Bit 3 clear */
    if ( !(pbi->bit_pattern & 0x0008) ){
      ret_val = 1;
      *run_value = (pbi->bit_pattern & 0x0007) + 10;
    }
    break;

  case 10:
    /* Bit 4 clear */
    if ( !(pbi->bit_pattern & 0x0010) ){
      ret_val = 1;
      *run_value = (pbi->bit_pattern & 0x000F) + 18;
    }
    break;

  case 18:
    ret_val = 1;
    *run_value = (pbi->bit_pattern & 0x0FFF) + 34;
    break;

  default:
    ret_val = 0;
    break;
  }

  /* todo: handle additional bits for values over 4129 */

  return ret_val;
}

static void GetNextBInit(PB_INSTANCE *pbi){
  long ret;

  theora_read(pbi->opb,1,&ret);
  pbi->NextBit = (unsigned char)ret;

  /* Read run length */
  FrArrayDeCodeInit(pbi);
  do theora_read(pbi->opb,1,&ret);
  while (FrArrayDeCodeBlockRun(pbi,ret,&pbi->BitsLeft)==0);

}

static unsigned char GetNextBBit (PB_INSTANCE *pbi){
  long ret;
  if ( !pbi->BitsLeft ){
    /* Toggle the value.   */
    pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;

    /* Read next run */
    FrArrayDeCodeInit(pbi);
    do theora_read(pbi->opb,1,&ret);
    while (FrArrayDeCodeBlockRun(pbi,ret,&pbi->BitsLeft)==0);

  }

  /* Have  read a bit */
  pbi->BitsLeft--;

  /* Return next bit value */
  return pbi->NextBit;
}

static void GetNextSbInit(PB_INSTANCE *pbi){
  long ret;

  theora_read(pbi->opb,1,&ret);
  pbi->NextBit = (unsigned char)ret;

  /* Read run length */
  FrArrayDeCodeInit(pbi);
  do theora_read(pbi->opb,1,&ret);
  while (FrArrayDeCodeSBRun(pbi,ret,&pbi->BitsLeft)==0);

}

static unsigned char GetNextSbBit (PB_INSTANCE *pbi){
  long ret;

  if ( !pbi->BitsLeft ){
    /* Toggle the value.   */
    pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;

    /* Read next run */
    FrArrayDeCodeInit(pbi);
    do theora_read(pbi->opb,1,&ret);
    while (FrArrayDeCodeSBRun(pbi,ret,&pbi->BitsLeft)==0);

  }

  /* Have  read a bit */
  pbi->BitsLeft--;

  /* Return next bit value */
  return pbi->NextBit;
}

void QuadDecodeDisplayFragments ( PB_INSTANCE *pbi ){
  ogg_uint32_t  SB, MB, B;
  int    DataToDecode;

  ogg_int32_t   dfIndex;
  ogg_uint32_t  MBIndex = 0;

  /* Reset various data structures common to key frames and inter frames. */
  pbi->CodedBlockIndex = 0;
  memset ( pbi->display_fragments, 0, pbi->UnitFragments );

  /* For "Key frames" mark all blocks as coded and return. */
  /* Else initialise the ArrayPtr array to 0 (all blocks uncoded by default) */
  if ( GetFrameType(pbi) == KEY_FRAME ) {
    memset( pbi->SBFullyFlags, 1, pbi->SuperBlocks );
    memset( pbi->SBCodedFlags, 1, pbi->SuperBlocks );
        memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );
  }else{
    memset( pbi->SBFullyFlags, 0, pbi->SuperBlocks );
    memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );

    /* Un-pack the list of partially coded Super-Blocks */
    GetNextSbInit(pbi);
    for( SB = 0; SB < pbi->SuperBlocks; SB++){
      pbi->SBCodedFlags[SB] = GetNextSbBit (pbi);
    }

    /* Scan through the list of super blocks.  Unless all are marked
       as partially coded we have more to do. */
    DataToDecode = 0;
    for ( SB=0; SB<pbi->SuperBlocks; SB++ ) {
      if ( !pbi->SBCodedFlags[SB] ) {
	DataToDecode = 1;
	break;
      }
    }

    /* Are there further block map bits to decode ? */
    if ( DataToDecode ) {
      /* Un-pack the Super-Block fully coded flags. */
      GetNextSbInit(pbi);
      for( SB = 0; SB < pbi->SuperBlocks; SB++) {
	/* Skip blocks already marked as partially coded */
	while( (SB < pbi->SuperBlocks) && pbi->SBCodedFlags[SB] )
	  SB++;

	if ( SB < pbi->SuperBlocks ) {
	  pbi->SBFullyFlags[SB] = GetNextSbBit (pbi);

	  if ( pbi->SBFullyFlags[SB] )       /* If SB is fully coded. */
	    pbi->SBCodedFlags[SB] = 1;       /* Mark the SB as coded */
	}
      }
    }

    /* Scan through the list of coded super blocks.  If at least one
       is marked as partially coded then we have a block list to
       decode. */
    for ( SB=0; SB<pbi->SuperBlocks; SB++ ) {
      if ( pbi->SBCodedFlags[SB] && !pbi->SBFullyFlags[SB] ) {
	/* Initialise the block list decoder. */
	GetNextBInit(pbi);
	break;
      }
    }
  }

  /* Decode the block data from the bit stream. */
  for ( SB=0; SB<pbi->SuperBlocks; SB++ ){
    for ( MB=0; MB<4; MB++ ){
      /* If MB is in the frame */
      if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 ){
	/* Only read block level data if SB was fully or partially coded */
	if ( pbi->SBCodedFlags[SB] ) {
	  for ( B=0; B<4; B++ ){
	    /* If block is valid (in frame)... */
	    dfIndex = QuadMapToIndex1( pbi->BlockMap, SB, MB, B );
	    if ( dfIndex >= 0 ){
	      if ( pbi->SBFullyFlags[SB] )
		pbi->display_fragments[dfIndex] = 1;
	      else
		pbi->display_fragments[dfIndex] = GetNextBBit(pbi);

	      /* Create linear list of coded block indices */
	      if ( pbi->display_fragments[dfIndex] ) {
		pbi->MBCodedFlags[MBIndex] = 1;
		pbi->CodedBlockList[pbi->CodedBlockIndex] = dfIndex;
		pbi->CodedBlockIndex++;
	      }
	    }
	  }
	}
	MBIndex++;

      }
    }
  }
}

CODING_MODE FrArrayUnpackMode(PB_INSTANCE *pbi){
  long ret;
  /* Coding scheme:
     Token                      Codeword           Bits
     Entry   0 (most frequent)  0                   1
     Entry   1       	        10 	            2
     Entry   2       	        110 		    3
     Entry   3       	        1110 		    4
     Entry   4       	        11110 		    5
     Entry   5       	        111110 	            6
     Entry   6       	        1111110 	    7
     Entry   7       	        1111111 	    7
  */

  /* Initialise the decoding. */
  pbi->bits_so_far = 0;

  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = ret;

  /* Do we have a match */
  if ( pbi->bit_pattern == 0 )
    return (CODING_MODE)0;

  /* Get the next bit */
  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = (pbi->bit_pattern << 1) | ret;

  /* Do we have a match */
  if ( pbi->bit_pattern == 0x0002 )
    return (CODING_MODE)1;

  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = (pbi->bit_pattern << 1) | ret;

  /* Do we have a match  */
  if ( pbi->bit_pattern == 0x0006 )
    return (CODING_MODE)2;

  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = (pbi->bit_pattern << 1) | ret;

  /* Do we have a match */
  if ( pbi->bit_pattern == 0x000E )
    return (CODING_MODE)3;

  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = (pbi->bit_pattern << 1) | ret;

  /* Do we have a match */
  if ( pbi->bit_pattern == 0x001E )
    return (CODING_MODE)4;

  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = (pbi->bit_pattern << 1) | ret;

  /* Do we have a match */
  if ( pbi->bit_pattern == 0x003E )
    return (CODING_MODE)5;

  theora_read(pbi->opb,1,&ret);
  pbi->bit_pattern = (pbi->bit_pattern << 1) | ret;

  /* Do we have a match */
  if ( pbi->bit_pattern == 0x007E )
    return (CODING_MODE)6;
  else
    return (CODING_MODE)7;
}





⌨️ 快捷键说明

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