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

📄 putvlc.c

📁 经典的MP4编解码核心库
💻 C
📖 第 1 页 / 共 2 页
字号:
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream, 
					coeff_tab3[run - 2].code,
					coeff_tab3[run - 2].len);
		    }
		}
    }

    return length;
}





__inline static int PutLevelCoeff4intra(BitWriter * bitstream, int run, int level, int last)
{
    int length = 0;

    assert(run >= 0 && run < 64);
    assert(level > 0 && level < 128);

    if (!last)
    {
		if (run == 0 && level < 28)
		{
		    length = coeff_tab4[level - 1].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /*  boon */
				BitstreamPutBits(bitstream, 
					coeff_tab4[level - 1].code,
					coeff_tab4[level - 1].len);
		    }
		}
		else if (run == 1 && level < 11)
		{
		    length = coeff_tab5[level - 1].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream, 
					coeff_tab5[level - 1].code,
					coeff_tab5[level - 1].len);
		    }
		}
		else if (run > 1 && run < 10 && level < 6)
		{
		    length = coeff_tab6[run - 2][level - 1].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream, 
					coeff_tab6[run - 2][level - 1].code,
					coeff_tab6[run - 2][level - 1].len);
		    }
		}
		else if (run > 9 && run < 15 && level == 1)
		{
		    length = coeff_tab7[run - 10].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream, 
					coeff_tab7[run - 10].code,
					coeff_tab7[run - 10].len);
		    }
		}
    }
    else // last == 1
    {
		if (run == 0 && level < 9)
		{
		    length = coeff_tab8[level - 1].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream, 
					coeff_tab8[level - 1].code,
					coeff_tab8[level - 1].len);
		    }
		}
		else if (run > 0 && run < 7 && level < 4)
		{
		    length = coeff_tab9[run - 1][level - 1].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream,
					coeff_tab9[run - 1][level - 1].code,
					coeff_tab9[run - 1][level - 1].len);
		    }
		}
		else if (run > 6 && run < 21 && level == 1)
		{
		    length = coeff_tab10[run - 7].len;
		    if (length != 0)
		    {
				BitstreamPutBits(bitstream, 3L, 7L);
				/* boon19970701 */
				BitstreamPutBits(bitstream, 0L, 1L);
				length += 8;			 /* boon */
				BitstreamPutBits(bitstream, 
					coeff_tab10[run - 7].code,
					coeff_tab10[run - 7].len);
		    }
		}
    }

    return length;
}



/***********************************************************CommentBegin******
 *
 * -- PutIntraDC -- DPCM Encoding of INTRADC in case of Intra macroblocks
 *
 * Purpose :
 *	DPCM Encoding of INTRADC in case of Intra macroblocks
 *
 * Arguments in :
 *	int val : the difference value with respect to the previous
 *		INTRADC value
 * 	int lum : indicates whether the block is a luminance block (lum=1) or
 * 		a chrominance block ( lum = 0)
 *
 * Arguments out :
 *	BitWriter* bitstream  : a pointer to the output bitstream
 *
 ***********************************************************CommentEnd********/


int PutIntraDC(BitWriter * bitstream, int val, bool lum)
{
    int n_bits;
    int absval, size = 0;

    absval = (val < 0) ? -val : val;		  

    // dct_dc_size 
    size = 0;
    while (absval)
    {
		absval >>= 1;
		size++;
    }

    if (lum)
		n_bits = PutDCsize4lum(bitstream, size);
    else
		n_bits = PutDCsize4chrom(bitstream, size);

    if (size != 0)
    {
		if (val < 0)
		{
		    absval = -val;	
		    val = absval ^ ((1 << size) - 1);
		}
		BitstreamPutBits(bitstream, (long) (val), (long) (size));
		n_bits += size;

		if (size > 8)
		    BitstreamPutBits(bitstream, (long) 1, (long) 1);
    }

    return n_bits;			// bits for intra_dc dpcm 
}


static int intra_max_run0[28] = {

    0, 14, 9, 7, 3, 2, 1,

    1, 1, 1, 1, 0, 0, 0,

    0, 0, 0, 0, 0, 0, 0,

    0, 0, 0, 0, 0, 0, 0

};

static int intra_max_run1[9] = {

    0, 20, 6,

    1, 0, 0,

    0, 0, 0

};

static int inter_max_run0[13] = {

    0,

    26, 10, 6, 2, 1, 1,

    0, 0, 0, 0, 0, 0

};

static int inter_max_run1[4] = {

    0, 40, 1, 0

};

static __declspec(align(16)) int intra_max_level[2][64] = {

    {

     27, 10, 5, 4, 3, 3, 3, 3,

     2, 2, 1, 1, 1, 1, 1, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0
     },



    {

     8, 3, 2, 2, 2, 2, 2, 1,

     1, 1, 1, 1, 1, 1, 1, 1,

     1, 1, 1, 1, 1, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0}

};


static __declspec(align(16)) int inter_max_level[2][64] = {

    {

     12, 6, 4, 3, 3, 3, 3, 2,

     2, 2, 2, 1, 1, 1, 1, 1,

     1, 1, 1, 1, 1, 1, 1, 1,

     1, 1, 1, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0
	},



    {

     3, 2, 1, 1, 1, 1, 1, 1,

     1, 1, 1, 1, 1, 1, 1, 1,

     1, 1, 1, 1, 1, 1, 1, 1,

     1, 1, 1, 1, 1, 1, 1, 1,

     1, 1, 1, 1, 1, 1, 1, 1,

     1, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0,

     0, 0, 0, 0, 0, 0, 0, 0}

};


__inline static int PutCoeff_Last(BitWriter * bitstream, int run, int level, int Mode)
{
    int s = 0;
    bool intra = 0;
    int length = 0;

    assert(level != 0);
    assert(bitstream);
    assert(run < 64);
    assert(run >= 0);

    if (level < 0)
    {
		s = 1;
		level = -level;
    }

    if ((Mode == MODE_INTRA) || (Mode == MODE_INTRA_Q))
		intra = 1;

    if ((run < 64) && (((level < 4) && !intra) || ((level < 9) && intra)))
    {
		// Separate tables for Intra luminance blocks 

		if (intra)
		    length = PutCoeff4intra(bitstream, run, level, 1);
		else
		    length = PutCoeff4inter(bitstream, run, level, 1);

    }


    //  First escape mode. Level offset 

    if (length == 0)
    {
		/* subtraction of Max level, last = 0 */
		int level_minus_max;
	
		if (intra)
		    level_minus_max = level - intra_max_level[1][run];
		else
		    level_minus_max = level - inter_max_level[1][run];

		if (((level_minus_max < 4) && (!intra)) ||
		    ((level_minus_max < 9) && intra))
		{
		    /* Separate tables for Intra luminance blocks */

			if (intra)
				length = PutLevelCoeff4intra(bitstream, run, level_minus_max, 1);
		    else
				length = PutLevelCoeff4inter(bitstream, run, level_minus_max, 1);

		}
    }

    // Second escape mode. Run offset 

    if (length == 0)
    {
		if (((level < 4) && (!intra)) || ((level < 9) && intra))
		{
		    /* subtraction of Max Run, last = 1 */
		    int run_minus_max;
	
			assert(level);

			if (intra)
				run_minus_max = run - (intra_max_run1[level] + 1);
		    else
				run_minus_max = run - (inter_max_run1[level] + 1);

		    /*  Separate tables for Intra luminance blocks */

			if (intra)
				length = PutRunCoeff4intra(bitstream, run_minus_max, level, 1);
		    else
				length = PutRunCoeff4inter(bitstream, run_minus_max, level, 1);

		}
    }


    // Third escape mode.

    if (length == 0)
    {						 /*  Escape coding */
		if (s == 1)
		    level = (level ^ 0xfff) + 1;
	
		BitstreamPutBits(bitstream, 3, 7);
		BitstreamPutBits(bitstream, 3, 2);
		BitstreamPutBits(bitstream, 1, 1);
		BitstreamPutBits(bitstream, run, 6);

		BitstreamPutBits(bitstream, MARKER_BIT, 1);
		BitstreamPutBits(bitstream, level, 12);
	
		BitstreamPutBits(bitstream, MARKER_BIT, 1);

		return 30;

    }
    else
    {
		BitstreamPutBits(bitstream, s, 1);
		return length + 1;
    }
}



__inline static int PutCoeff_NotLast(BitWriter * bitstream, int run, int level,
			    int Mode)
{
    int s = 0;
    bool intra = 0;
    int length = 0;

    if (level < 0)
    {
		s = 1;
		level = -level;
    }

    if ((Mode == MODE_INTRA) || (Mode == MODE_INTRA_Q))
		intra = 1;

    if ((run < 64) &&
		((((level < 13) && (!intra))) || ((level < 28) && intra)))
    {
		if (intra)
		    length = PutCoeff4intra(bitstream, run, level, 0);
		else
		    length = PutCoeff4inter(bitstream, run, level, 0);
    }


    /* First escape mode. Level offset */

    if (length == 0)
    {
		if (run < 64)
		{
		    /* subtraction of Max level, last = 0 */
		    int level_minus_max;

		    if (intra)
				level_minus_max = level - intra_max_level[0][run];
		    else
				level_minus_max = level - inter_max_level[0][run];
	
			if (((level_minus_max < 13) && (!intra)) ||
				((level_minus_max < 28) && intra))
		    {
				/*  Separate tables for Intra luminance blocks */

				if (intra)
				    length = PutLevelCoeff4intra(bitstream, run, level_minus_max, 0);
				else
				    length = PutLevelCoeff4inter(bitstream, run, level_minus_max, 0);
			}

		}
    }

    //  Second escape mode. 

    if (length == 0)
    {
		if (((level < 13) && (!intra)) || ((level < 28) && intra))
		{
			/* subtraction of Max Run, last = 0 */
	
			int run_minus_max;

		    assert(level);
	
			if (intra)
				run_minus_max = run - (intra_max_run0[level] + 1);
			else
				run_minus_max = run - (inter_max_run0[level] + 1);

			/* Separate tables for Intra luminance blocks */
			if (intra)
			    length = PutRunCoeff4intra(bitstream, run_minus_max, level, 0);
			else
				length = PutRunCoeff4inter(bitstream, run_minus_max, level, 0);
		}
    }


    // Third escape mode 

    if (length == 0)
    {						 

		if (s)
		    level = (level ^ 0xfff) + 1;

		BitstreamPutBits(bitstream, 3, 7);
		BitstreamPutBits(bitstream, 3, 2);
		BitstreamPutBits(bitstream, 0, 1);
		BitstreamPutBits(bitstream, run, 6);
		BitstreamPutBits(bitstream, MARKER_BIT, 1);
		BitstreamPutBits(bitstream, level, 12);
		BitstreamPutBits(bitstream, MARKER_BIT, 1);
		return 30;
	}
	else
    {
		BitstreamPutBits(bitstream, s, 1);
		return length + 1;
    }
}



int PutCoeff(BitWriter * bitstream, int run, int level, int last, int Mode)
{
    if (last)
		return PutCoeff_Last(bitstream, run, level, Mode);
    else
		return PutCoeff_NotLast(bitstream, run, level, Mode);
}

⌨️ 快捷键说明

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