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

📄 block.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************
                      block layer interface
 *******************************************************************/

#include "scan.h"
#include "dct_coefficient.h"

#define BLOCK_C
#include "block.h"

typedef struct {
	short value;
	short length;
} BASIC_VLC_ELEMENT;

int read_block_null(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg2_intra_luminance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg2_intra_cb(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg2_intra_cr(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg2_nonintra_luminance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg2_nonintra_chrominance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg1_intra_luminance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg1_intra_cb(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg1_intra_cr(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int read_block_mpeg1_nonintra(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt);
int reset_dc_dct_predictor(READ_BLOCK_OPTION *p);
void __stdcall setup_qw_nosimd(unsigned short *qw, unsigned short *qm, int q);

static int get_dct_dc_size_luminance(VIDEO_STREAM *in);
static int get_dct_dc_size_chrominance(VIDEO_STREAM *in);

__inline static int get_dct_dc_diff_luminance(VIDEO_STREAM *in)
{
	int size;
	int diff;

	size = get_dct_dc_size_luminance(in);
	if(size){
		diff = vs_get_bits(in, size);
		if(diff < (1 << (size-1))){
			diff -= (1<<size)-1;
		}
		return diff;
	}else{
		return 0;
	}
}

__inline static int get_dct_dc_diff_chrominance(VIDEO_STREAM *in)
{
	int size;
	int diff;

	size = get_dct_dc_size_chrominance(in);
	if(size){
		diff = vs_get_bits(in, size);
		if(diff < (1 << (size-1))){
			diff -= (1<<size)-1;
		}
		return diff;
	}else{
		return 0;
	}
}

__inline static short limit_dct_coefficient(int w)
{
	if(w >= -2048){
		if(w < 2047){
			return (short)w;
		}else{
			return 2047;
		}
	}
	return -2048;
}

static const int color_component[12] = {
	0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2,
};

int read_block_null(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	return 0;
}

static const short missmatch_control[2][2] = {
	{1, -1}, {0, 0},
};

static const READ_DCT_COEFFICIENT rdc_table[2] = {
	read_dct_ac_coefficient_b14,
	read_dct_ac_coefficient_b15,
};

int read_block_mpeg2_intra_luminance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;

	int run;
	int level;

	READ_DCT_COEFFICIENT rdc;
	
	short *qw;
	
	qw = opt->qw[0];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	opt->dc_dct_predictor[0] += get_dct_dc_diff_luminance(in);
	out[0] = limit_dct_coefficient(opt->dc_dct_predictor[0] * (1 << (3-opt->intra_dc_precision)));
	sum = out[0];

	rdc = rdc_table[opt->intra_vlc_format];	
	
	n = 1;
	while(rdc(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[opt->alternate_scan][n];

		out[i] = limit_dct_coefficient( (level * qw[i]) / 16 );
		sum += out[i];
		n += 1;
	}

	out[63] += missmatch_control[sum&1][out[63]&1];
	
	return 1;
}

int read_block_mpeg2_intra_cb(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;

	int run;
	int level;

	READ_DCT_COEFFICIENT rdc;
	
	short *qw;
	
	qw = opt->qw[2];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	opt->dc_dct_predictor[1] += get_dct_dc_diff_chrominance(in);
	out[0] = limit_dct_coefficient(opt->dc_dct_predictor[1] * (1 << (3-opt->intra_dc_precision)));
	sum = out[0];

	rdc = rdc_table[opt->intra_vlc_format];
	
	n = 1;
	while(rdc(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[opt->alternate_scan][n];

		out[i] = limit_dct_coefficient( (level * qw[i]) / 16 );
		sum += out[i];
		n += 1;
	}

	out[63] += missmatch_control[sum&1][out[63]&1];
	
	return 1;
}

int read_block_mpeg2_intra_cr(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;

	int run;
	int level;

	READ_DCT_COEFFICIENT rdc;
	
	short *qw;
	
	qw = opt->qw[2];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	opt->dc_dct_predictor[2] += get_dct_dc_diff_chrominance(in);
	out[0] = limit_dct_coefficient(opt->dc_dct_predictor[2] * (1 << (3-opt->intra_dc_precision)));
	sum = out[0];

	rdc = rdc_table[opt->intra_vlc_format];
	
	n = 1;
	while(rdc(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[opt->alternate_scan][n];

		out[i] = limit_dct_coefficient( (level * qw[i]) / 16 );
		sum += out[i];
		n += 1;
	}

	out[63] += missmatch_control[sum&1][out[63]&1];
	
	return 1;
}

int read_block_mpeg2_nonintra_luminance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;

	int run;
	int level;

	short *qw;
	
	qw = opt->qw[1];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	/* read first coefficient */
	read_dct_dc_coefficient_b14(in, &run, &level);
	n = run;
	i = scan_table[opt->alternate_scan][n];
	out[i] = limit_dct_coefficient( ( ((level * 2) + ( (level > 0) ? 1 : -1)) * qw[i]) / 32 );
	sum = out[i];
	n += 1;

	while(read_dct_ac_coefficient_b14(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[opt->alternate_scan][n];
		out[i] = limit_dct_coefficient( ( ((level * 2) + ( (level > 0) ? 1 : -1)) * qw[i]) / 32 );
		sum += out[i];
		n += 1;
	}

	out[63] += missmatch_control[sum&1][out[63]&1];

	return 1;
}

int read_block_mpeg2_nonintra_chrominance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n,sum;

	int run;
	int level;

	short *qw;
	
	qw = opt->qw[3];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	/* read first coefficient */
	read_dct_dc_coefficient_b14(in, &run, &level);
	n = run;
	i = scan_table[opt->alternate_scan][n];
	out[i] = limit_dct_coefficient( ( ((level * 2) + ( (level > 0) ? 1 : -1)) * qw[i]) / 32 );
	sum = out[i];
	n += 1;

	while(read_dct_ac_coefficient_b14(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[opt->alternate_scan][n];
		out[i] = limit_dct_coefficient( ( ((level * 2) + ( (level > 0) ? 1 : -1)) * qw[i] ) / 32 );
		sum += out[i];
		n += 1;
	}

	out[63] += missmatch_control[sum&1][out[63]&1];

	return 1;
}

int read_block_mpeg1_intra_luminance(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n;

	int run;
	int level;

	short *qw;
	
	qw = opt->qw[0];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	opt->dc_dct_predictor[0] += get_dct_dc_diff_luminance(in);
	out[0] = limit_dct_coefficient(opt->dc_dct_predictor[0] << 3);

	n = 1;
	while(read_dct_ac_coefficient_mpeg1(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[0][n];

		out[i] = limit_dct_coefficient( (((level * qw[i]) / 16)-1) | 1);
		n += 1;
	}

	return 1;
}

int read_block_mpeg1_intra_cb(VIDEO_STREAM *in, short *out, READ_BLOCK_OPTION *opt)
{
	int i,n;

	int run;
	int level;

	short *qw;
	
	qw = opt->qw[0];
	
	/* initialize output block */
	memset(out, 0, sizeof(short)*64);

	opt->dc_dct_predictor[1] += get_dct_dc_diff_chrominance(in);
	out[0] = limit_dct_coefficient(opt->dc_dct_predictor[1] << 3);

	n = 1;
	while(read_dct_ac_coefficient_mpeg1(in, &run, &level) > 0){
		n += run;
		if(n >= 64){
			return 0;
		}
		i = scan_table[0][n];

		out[i] = limit_dct_coefficient( (((level * qw[i]) / 16)-1) | 1);
		n += 1;
	}

	return 1;
}

⌨️ 快捷键说明

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