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

📄 l3bitstream.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
	    {
		for ( region = 0; region < 3; region++ )
		    *pph = CRC_BF_addEntry( *pph, gi->table_select[region], 5 );

		*pph = CRC_BF_addEntry( *pph, gi->region0_count, 4 );
		*pph = CRC_BF_addEntry( *pph, gi->region1_count, 3 );
	    }

	    *pph = CRC_BF_addEntry( *pph, gi->scalefac_scale,     1 );
	    *pph = CRC_BF_addEntry( *pph, gi->count1table_select, 1 );
	}
	if ( gfp->stereo == 2 )
	    bits_sent += 136;
	else
	    bits_sent += 72;
    }

    if ( gfp->error_protection )
    {   /* (jo) error_protection: add crc16 information to header */
	headerPH = BF_addEntry( headerPH, crc, 16 );
	bits_sent += 16;
    }

    return bits_sent;
}

/*
  Some combinations of bitrate, Fs, and stereo make it impossible to stuff
  out a frame using just main_data, due to the limited number of bits to
  indicate main_data_length. In these situations, we put stuffing bits into
  the ancillary data...
*/
static void
drain_into_ancillary_data( int lengthInBits )
{
    /*
     */
    int wordsToSend   = lengthInBits / 32;
    int remainingBits = lengthInBits % 32;
    int i;

    /*
      userFrameDataPH->part->nrEntries set by call to write_ancillary_data()
    */
    
    userFrameDataPH->part->nrEntries = 0;
    for ( i = 0; i < wordsToSend; i++ )
	userFrameDataPH = BF_addEntry( userFrameDataPH, 0, 32 );
    if ( remainingBits )
	userFrameDataPH = BF_addEntry( userFrameDataPH, 0, remainingBits );
}

/*
  Note the discussion of huffmancodebits() on pages 28
  and 29 of the IS, as well as the definitions of the side
  information on pages 26 and 27.
  */
static void
Huffmancodebits( BF_PartHolder **pph, int *ix, gr_info *gi )
{
    int L3_huffman_coder_count1( BF_PartHolder **pph, struct huffcodetab *h, int v, int w, int x, int y );

    int region1Start;
    int region2Start;
    int i, bigvalues, count1End;
    int v, w, x, y, bits, cbits, xbits, stuffingBits;
    unsigned int code, ext;
#ifdef DEBUG
    int bvbits, c1bits;
#endif
    int bitsWritten = 0;

    
    /* 1: Write the bigvalues */
    bigvalues = gi->big_values * 2;
    if ( bigvalues )
    {
	if ( !(gi->mixed_block_flag) && (gi->block_type == SHORT_TYPE) )
	{ /* Three short blocks */
	    /*
	      Within each scalefactor band, data is given for successive
	      time windows, beginning with window 0 and ending with window 2.
	      Within each window, the quantized values are then arranged in
	      order of increasing frequency...
	      */
	    int sfb, window, line, start, end;

	    I192_3 *ix_s;
	    
	    ix_s = (I192_3 *) ix;
	    region1Start = 12;
	    region2Start = 576;

	    for ( sfb = 0; sfb < 13; sfb++ )
	    {
		unsigned tableindex = 100;
		start = scalefac_band.s[ sfb ];
		end   = scalefac_band.s[ sfb+1 ];

		if ( start < region1Start )
		    tableindex = gi->table_select[ 0 ];
		else
		    tableindex = gi->table_select[ 1 ];
		assert( tableindex < 32 );

		for ( window = 0; window < 3; window++ )
		    for ( line = start; line < end; line += 2 )
		    {
			x = (*ix_s)[line][window];
			y = (*ix_s)[line + 1][window];
			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );
			*pph = BF_addEntry( *pph,  code, cbits );
			*pph = BF_addEntry( *pph,  ext, xbits );
			bitsWritten += bits;
		    }
		
	    }
	}
	else
#ifdef ALLOW_MIXED
	    if ( gi->mixed_block_flag && gi->block_type == SHORT_TYPE )
	    {  /* Mixed blocks long, short */
		int sfb, window, line, start, end;
		unsigned tableindex;
		I192_3 *ix_s;
		
		ix_s = (I192_3 *) ix;

		/* Write the long block region */
		tableindex = gi->table_select[0];
		if ( tableindex )
		    for ( i = 0; i < 36; i += 2 )
		    {
			x = ix[i];
			y = ix[i + 1];
			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );
			*pph = BF_addEntry( *pph,  code, cbits );
			*pph = BF_addEntry( *pph,  ext, xbits );
			bitsWritten += bits;
			
		    }
		/* Write the short block region */
		tableindex = gi->table_select[ 1 ];
		assert( tableindex < 32 );

		for ( sfb = 3; sfb < 13; sfb++ )
		{
		    start = scalefac_band.s[ sfb ];
		    end   = scalefac_band.s[ sfb+1 ];           
		    
		    for ( window = 0; window < 3; window++ )
			for ( line = start; line < end; line += 2 )
			{
			    x = (*ix_s)[line][window];
			    y = (*ix_s)[line + 1][window];
			    bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );
			    *pph = BF_addEntry( *pph,  code, cbits );
			    *pph = BF_addEntry( *pph,  ext, xbits );
			    bitsWritten += bits;
			}
		}

	    }
	    else
#endif
	    { /* Long blocks */
		unsigned scalefac_index = 100;
		
		if ( gi->mixed_block_flag )
		{
		    region1Start = 36;
		    region2Start = 576;
		}
		else
		{
		    scalefac_index = gi->region0_count + 1;
		    assert( scalefac_index < 23 );
		    region1Start = scalefac_band.l[ scalefac_index ];
		    scalefac_index += gi->region1_count + 1;
		    assert( scalefac_index < 23 );    
		    region2Start = scalefac_band.l[ scalefac_index ];
		}

		for ( i = 0; i < bigvalues; i += 2 )
		{
		    unsigned tableindex = 100;
		    /* get table pointer */
		    if ( i < region1Start )
		    {
			tableindex = gi->table_select[0];
		    }
		    else
			if ( i < region2Start )
			{
			    tableindex = gi->table_select[1];
			}
			else
			{
			    tableindex = gi->table_select[2];
			}
		    assert( tableindex < 32 );
		    /* get huffman code */
		    x = ix[i];
		    y = ix[i + 1];

		    if ( tableindex )
		    {
			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );
			*pph = BF_addEntry( *pph,  code, cbits );
			*pph = BF_addEntry( *pph,  ext, xbits );
			bitsWritten += bits;
		    }
		}
	    }
    }
#ifdef DEBUG
    bvbits = bitsWritten; 
#endif

    /* 2: Write count1 area */
    assert( (gi->count1table_select < 2) );
    count1End = bigvalues + (gi->count1 * 4);

    assert( count1End <= 576 );

    for ( i = bigvalues; i < count1End; i += 4 )
    {
	v = ix[i];
	w = ix[i+1];
	x = ix[i+2];
	y = ix[i+3];
	bitsWritten += L3_huffman_coder_count1( pph, &ht[gi->count1table_select + 32], v, w, x, y );
    }
#ifdef DEBUG
    c1bits = bitsWritten - bvbits;
#endif
    if ( (stuffingBits = gi->part2_3_length - gi->part2_length - bitsWritten) )
    {
	int stuffingWords = stuffingBits / 32;
	int remainingBits = stuffingBits % 32;

        fprintf(stderr,"opps - adding stuffing bits = %i.\n",stuffingBits);
        fprintf(stderr,"this should not happen...\n");

	/*
	  Due to the nature of the Huffman code
	  tables, we will pad with ones
	*/
	while ( stuffingWords-- )
	    *pph = BF_addEntry( *pph, ~(u_int)0, 32 );
	if ( remainingBits )
	    *pph = BF_addEntry( *pph, ~(u_int)0, remainingBits );
	bitsWritten += stuffingBits;
    }
    assert( bitsWritten == (int)(gi->part2_3_length - gi->part2_length) );
#ifdef DEBUG
    fprintf(stderr, "## %d Huffman bits written (%02d + %02d), part2_length = %d, part2_3_length = %d, %d stuffing ##\n",
	    bitsWritten, bvbits, c1bits, gi->part2_length, gi->part2_3_length, stuffingBits );
#endif
}

int
abs_and_sign( int *x )
{
    if ( *x > 0 )
	return 0;
    *x *= -1;
    return 1;
}

int
L3_huffman_coder_count1( BF_PartHolder **pph, struct huffcodetab *h, int v, int w, int x, int y )
{
    HUFFBITS huffbits;
    unsigned int signv, signw, signx, signy, p;
    int len;
    int totalBits = 0;
    
    signv = abs_and_sign( &v );
    signw = abs_and_sign( &w );
    signx = abs_and_sign( &x );
    signy = abs_and_sign( &y );
    
    /* bug fix from Leonid A. Kulakov 9/1999:*/
    p = (v << 3) + (w << 2) + (x << 1) + y;  

    huffbits = h->table[p];
    len = h->hlen[ p ];
    *pph = BF_addEntry(*pph, huffbits, len);
    totalBits= 0;
#if 0
    if ( v )
    {
	*pph = BF_addEntry( *pph,  signv, 1 );
	totalBits += 1;
    }
    if ( w )
    {
	*pph = BF_addEntry( *pph,  signw, 1 );
	totalBits += 1;
    }

    if ( x )
    {
	*pph = BF_addEntry( *pph,  signx, 1 );
	totalBits += 1;
    }
    if ( y )
    {
	*pph = BF_addEntry( *pph,  signy, 1 );
	totalBits += 1;
    }
#endif   

    p=0;
    if ( v ) {
	p = signv;
	++totalBits;
    }

    if ( w ){
	p = 2*p + signw;
	++totalBits;
    }

    if ( x ) {
	p = 2*p + signx;
	++totalBits;
    }

    if ( y ) {
	p = 2*p + signy;
	++totalBits;
    }

    *pph = BF_addEntry(*pph, p, totalBits);

    return totalBits+len;  
}

/*
  Implements the pseudocode of page 98 of the IS
  */
int
HuffmanCode( int table_select, int x, int y, unsigned int *code, unsigned int *ext, int *cbits, int *xbits )
{
    unsigned signx, signy, linbitsx, linbitsy, linbits, idx;
    struct huffcodetab *h;

    *cbits = 0;
    *xbits = 0;
    *code  = 0;
    *ext   = 0;
    
    if ( table_select == 0 )
	return 0;
    
    signx = abs_and_sign( &x );
    signy = abs_and_sign( &y );
    h = &(ht[table_select]);

    if ( table_select > 15 )
    { /* ESC-table is used */
      linbits = h->xlen;
      linbitsx = linbitsy = 0;
	if ( x > 14 )
	{
	    linbitsx = x - 15;
	    assert( linbitsx <= h->linmax );
	    x = 15;
	}
	if ( y > 14 )
	{
	    linbitsy = y - 15;
	    assert( linbitsy <= h->linmax );
	    y = 15;
	}
	idx = x * 16 + y;
	*code = h->table[idx];
        *cbits = h->hlen[ idx ];
	if ( x > 14 )
	{
	    *ext |= linbitsx;
	    *xbits += linbits;
	}
	if ( x != 0 )
	{
	    *ext <<= 1;
	    *ext |= signx;
	    *xbits += 1;
	}
	if ( y > 14 )
	{
	    *ext <<= linbits;
	    *ext |= linbitsy;
	    *xbits += linbits;
	}
	if ( y != 0 )
	{
	    *ext <<= 1;
	    *ext |= signy;
	    *xbits += 1;
	}
    }
    else
    { /* No ESC-words */
	idx = x * 16 + y;
	*code = h->table[idx];
	*cbits += h->hlen[ idx ];
	if ( x != 0 )
	{
	    *code <<= 1;
	    *code |= signx;
	    *cbits += 1;
	}
	if ( y != 0 )
	{
	    *code <<= 1;
	    *code |= signy;
            *cbits += 1;
	}
    }
    assert( *cbits <= 32 );
    assert( *xbits <= 32 );
    return *cbits + *xbits;
}

⌨️ 快捷键说明

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