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

📄 l3bitstream.c

📁 MPEG 2的音频编码软件。喜欢多媒体的开发人员可以看看。
💻 C
📖 第 1 页 / 共 2 页
字号:

		for ( region = 0; region < 2; region++ )
		    *pph = BF_addEntry( *pph, gi->table_select[region],  5 );
		for ( window = 0; window < 3; window++ )
		    *pph = BF_addEntry( *pph, gi->subblock_gain[window], 3 );
	    }
	    else
	    {
		for ( region = 0; region < 3; region++ )
		    *pph = BF_addEntry( *pph, gi->table_select[region], 5 );

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

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

static void
write_ancillary_data( char *theData, int lengthInBits )
{
    /*
     */
    int bytesToSend = lengthInBits / 8;
    int remainingBits = lengthInBits % 8;
    unsigned wrd;
    int i;

    userFrameDataPH->part->nrEntries = 0;

    for ( i = 0; i < bytesToSend; i++ )
    {
	wrd = theData[i];
	userFrameDataPH = BF_addEntry( userFrameDataPH, wrd, 8 );
    }
    if ( remainingBits )
    {
	/* right-justify remaining bits */
	wrd = theData[bytesToSend] >> (8 - remainingBits);
	userFrameDataPH = BF_addEntry( userFrameDataPH, wrd, remainingBits );
    }
    
}

/*
  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()
    */

    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 bigv_bitcount( int ix[576], gr_info *cod_info );

    int region1Start;
    int region2Start;
    int i, bigvalues, count1End;
    int v, w, x, y, bits, cbits, xbits, stuffingBits;
    unsigned int code, ext;
    struct huffcodetab *h;
    int bvbits, c1bits, tablezeros, r0, r1, r2, rt, *pr;
    int bitsWritten = 0;
    int idx = 0;
    tablezeros = 0;
    r0 = r1 = r2 = 0;
    
    /* 1: Write the bigvalues */
    bigvalues = gi->big_values * 2;
    if ( bigvalues )
    {
	if ( !(gi->mixed_block_flag) && gi->window_switching_flag && (gi->block_type == 2) )
	{ /* 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;
	    int *scalefac = &sfBandIndex[fr_ps->header->sampling_frequency + (fr_ps->header->version * 3)].s[0];
	    
	    ix_s = (I192_3 *) ix;
	    region1Start = 12;
	    region2Start = 576;

	    for ( sfb = 0; sfb < 13; sfb++ )
	    {
		unsigned tableindex = 100;
		start = scalefac[ sfb ];
		end   = scalefac[ 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];
			assert( idx < 576 );
			assert( idx >= 0 );
			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );
			*pph = BF_addEntry( *pph,  code, cbits );
			*pph = BF_addEntry( *pph,  ext, xbits );
			bitsWritten += bits;
		    }
		
	    }
	}
	else
	    if ( gi->mixed_block_flag && gi->block_type == 2 )
	    {  /* Mixed blocks long, short */
		int sfb, window, line, start, end;
		unsigned tableindex;
		I192_3 *ix_s;
		int *scalefac = &sfBandIndex[fr_ps->header->sampling_frequency + (fr_ps->header->version * 3)].s[0];
		
		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[ sfb ];
		    end   = scalefac[ 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
	    { /* Long blocks */
		int *scalefac = &sfBandIndex[fr_ps->header->sampling_frequency + (fr_ps->header->version * 3)].l[0];
		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[ scalefac_index ];
		    scalefac_index += gi->region1_count + 1;
		    assert( scalefac_index < 23 );    
		    region2Start = scalefac[ scalefac_index ];
		    assert( region1Start == gi->address1 );
		}
		for ( i = 0; i < bigvalues; i += 2 )
		{
		    unsigned tableindex = 100;
		    /* get table pointer */
		    if ( i < region1Start )
		    {
			tableindex = gi->table_select[0];
			pr = &r0;
		    }
		    else
			if ( i < region2Start )
			{
			    tableindex = gi->table_select[1];
			    pr = &r1;
			}
			else
			{
			    tableindex = gi->table_select[2];
			    pr = &r2;
			}
		    assert( tableindex < 32 );
		    h = &ht[ tableindex ];
		    /* 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 += rt = bits;
			*pr += rt;
		    }
		    else
		    {
			tablezeros += 1;
			*pr = 0;
		    }
		}
	    }
    }
    bvbits = bitsWritten; 

    /* 2: Write count1 area */
    assert( (gi->count1table_select < 2) );
    h = &ht[gi->count1table_select + 32];
    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, h, v, w, x, y );
    }
    c1bits = bitsWritten - bvbits;
    if ( (stuffingBits = gi->part2_3_length - gi->part2_length - bitsWritten) )
    {
	int stuffingWords = stuffingBits / 32;
	int remainingBits = stuffingBits % 32;
	assert( stuffingBits > 0 );

	/*
	  Due to the nature of the Huffman code
	  tables, we will pad with ones
	*/
	while ( stuffingWords-- )
	    *pph = BF_addEntry( *pph, ~0, 32 );
	if ( remainingBits )
	    *pph = BF_addEntry( *pph, ~0, remainingBits );
	bitsWritten += stuffingBits;
    }
    assert( bitsWritten == gi->part2_3_length - gi->part2_length );
#ifdef DEBUG
    printf( "#### %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 );
    
    p = v + (w << 1) + (x << 2) + (y << 3);
    huffbits = h->table[p];
    len = h->hlen[ p ];
    *pph = BF_addEntry( *pph,  huffbits, len );
    totalBits += len;
    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;
    }
    return totalBits;
}

/*
  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, xlen, ylen, 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]);
    xlen = h->xlen;
    ylen = h->ylen;
    linbits = h->linbits;
    linbitsx = linbitsy = 0;

    if ( table_select > 15 )
    { /* ESC-table is used */
	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 * ylen) + 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 * ylen) + 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 + -