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

📄 macroblock.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
📖 第 1 页 / 共 3 页
字号:
		vs_erase_bits(in, 2);
		return 1;
	}

	return 0;
}

static int get_motion_code(VIDEO_STREAM *in)
{
	int r;
	int code;
	
	static const BASIC_VLC_ELEMENT table_a[] = {
		{ 2, 4}, {-2, 4},
		{ 1, 3}, { 1, 3}, {-1,3}, {-1, 3},
		{ 0, 1}, { 0, 1}, { 0,1}, { 0, 1},
		{ 0, 1}, { 0, 1}, { 0,1}, { 0, 1},
	};
	
	static const BASIC_VLC_ELEMENT table_b[] = {
		{ 7, 8}, {-7, 8}, { 6, 8}, {-6, 8}, { 5, 8}, {-5, 8},
		{ 4, 7}, { 4, 7}, {-4, 7}, {-4, 7},
		{ 3, 5}, { 3, 5}, { 3, 5}, { 3, 5},
		{ 3, 5}, { 3, 5}, { 3, 5}, { 3, 5},
		{-3, 5}, {-3, 5}, {-3, 5}, {-3, 5},
		{-3, 5}, {-3, 5}, {-3, 5}, {-3, 5},
	};
	
	static const BASIC_VLC_ELEMENT table_c[] = {
		{16,11}, {-16,11}, {15,11}, {-15,11},
		{14,11}, {-14,11}, {13,11}, {-13,11},
		{12,11}, {-12,11}, {11,11}, {-11,11},
		{10,10}, {10,10}, {-10,10}, {-10,10},
		{ 9,10}, { 9,10}, { -9,10}, { -9,10},
		{ 8,10}, { 8,10}, { -8,10}, { -8,10},
	};

	code = vs_read_bits(in, 11);

	if(code > 255){
		code = (code >> 7) - 2;
		r = table_a[code].value;
		vs_erase_bits(in, table_a[code].length);
	}else if(code > 47){
		code = (code >> 3) - 6;
		r = table_b[code].value;
		vs_erase_bits(in, table_b[code].length);
	}else{
		code -= 24;
		r = table_c[code].value;
		vs_erase_bits(in, table_c[code].length);
	}

	return r;
}

static int get_dmvector(VIDEO_STREAM *in)
{
	int code;
	
	static const BASIC_VLC_ELEMENT table[] = {
		{ 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
	};

	code = vs_read_bits(in, 2);

	vs_erase_bits(in, table[code].length);

	return table[code].value;
}

static void read_motion_vector(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s)
{
	int r,t;
	int half;

	if( (out->motion_vector_format == MOTION_VECTOR_FORMAT_FIELD) && (opt->picture_structure == 3) ){
		half = 2;
	}else if( opt->full_pel_vector[s] ){
		half = 3;
	}else{
		half = 0;
	}
	
	if(out->motion_vector_count == 1){
		if( (out->motion_vector_format == MOTION_VECTOR_FORMAT_FIELD) && (out->dual_prime_motion_vector != 1) ){
			out->motion_vertical_field_select[0][s] = vs_get_bits(in, 1);
		}
		for(t=0;t<2;t++){
			out->PMV[0][s][t] = get_motion_vector_predictor(in, out->PMV[0][s][t], opt->f_code[s][t], (half & (t+1)) );
			if(out->dual_prime_motion_vector == 1){
				read_dmv(in, out, opt, s, t);
			}
			out->PMV[1][s][t] = out->PMV[0][s][t];
		}
	}else{
		for(r=0;r<2;r++){
			out->motion_vertical_field_select[r][s] = vs_get_bits(in, 1);
			for(t=0;t<2;t++){
				out->PMV[r][s][t] = get_motion_vector_predictor(in, out->PMV[r][s][t], opt->f_code[s][t], (half && t));
			}
		}
	}
}

static void read_dmv(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s, int t)
{
	int v;
	int dmvector;

	dmvector = get_dmvector(in);
	
	if(opt->picture_structure == 3){
		if(t){
			v = out->PMV[0][s][t] >> 1;
		}else{
			v = out->PMV[0][s][t];
		}
		if(opt->top_field_first){
			out->DMV[0][t] = ( ( v   + (v>0) )>>1 ) + dmvector - t;
			out->DMV[1][t] = ( ( v*3 + (v>0) )>>1 ) + dmvector + t;
		}else{
			out->DMV[0][t] = ( ( v*3 + (v>0) )>>1 ) + dmvector - t;
			out->DMV[1][t] = ( ( v   + (v>0) )>>1 ) + dmvector + t;
		}
	}else{
		v = out->PMV[0][s][t];
		out->DMV[0][t] = ( ( v + (v>0) )>>1) + dmvector;
		if(opt->picture_structure == 1){
			out->DMV[0][t] -= t;
		}else{
			out->DMV[0][t] += t;
		}
	}
}

static int get_motion_vector_predictor(VIDEO_STREAM *in, int prediction, int f_code, int half)
{
	int r;
	
	int f;
	int r_size;
	int high;
	int low;
	int range;

	int delta;
	
	int motion_code;
	int motion_residual;

	r_size = f_code - 1;
	f = 1 << r_size;

	high = 16 * f - 1;
	low = -16 * f;
	range = 32 * f;

	motion_code = get_motion_code(in);
	if( (!r_size) || (motion_code == 0) ){
		delta = motion_code;
	}else{
		motion_residual = vs_get_bits(in, r_size);
		delta = (abs(motion_code) - 1) * f + motion_residual + 1;
		if(motion_code < 0){
			delta = 0 - delta;
		}
	}

	if(half){
		prediction >>= 1;
	}

	r = prediction + delta;

	if(r < low){
		r += range;
	}else if(r > high){
		r -= range;
	}

	if(half){
		r <<= 1;
	}

	return r;
}

static void read_coded_block_mpeg2_420_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;

	out->block_count = 6;

	for(i=0;i<4;i++){
		out->read_block[i] = read_block_mpeg2_intra_luminance;
	}
	out->read_block[4] = read_block_mpeg2_intra_cb;
	out->read_block[5] = read_block_mpeg2_intra_cr;
}

static void read_coded_block_mpeg1_420_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;

	out->block_count = 6;

	for(i=0;i<4;i++){
		out->read_block[i] = read_block_mpeg1_intra_luminance;
	}
	out->read_block[4] = read_block_mpeg1_intra_cb;
	out->read_block[5] = read_block_mpeg1_intra_cr;
}

static void read_coded_block_mpeg2_422_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	out->block_count = 8;

	for(i=0;i<4;i++){
		out->read_block[i] = read_block_mpeg2_intra_luminance;
	}
	out->read_block[4] = read_block_mpeg2_intra_cb;
	out->read_block[5] = read_block_mpeg2_intra_cr;
	out->read_block[6] = read_block_mpeg2_intra_cb;
	out->read_block[7] = read_block_mpeg2_intra_cr;
}

static void read_coded_block_mpeg2_444_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	out->block_count = 12;

	for(i=0;i<4;i++){
		out->read_block[i] = read_block_mpeg2_intra_luminance;
	}
	for(i=4;i<12;i+=2){
		out->read_block[i] = read_block_mpeg2_intra_cb;
		out->read_block[i+1] = read_block_mpeg2_intra_cr;
	}
}

static void read_coded_block_mpeg2_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	int coded_block_pattern;

	static const READ_BLOCK rb_y_table[2] = {
		read_block_null,
		read_block_mpeg2_nonintra_luminance,
	};

	static const READ_BLOCK rb_c_table[2] = {
		read_block_null,
		read_block_mpeg2_nonintra_chrominance,
	};

	out->block_count = 6;

	coded_block_pattern = get_coded_block_pattern(in);
	
	for(i=0;i<4;i++){
		out->read_block[i] = rb_y_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
	for(i=4;i<6;i++){
		out->read_block[i] = rb_c_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
}

static void read_coded_block_mpeg1_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	int coded_block_pattern;

	static const READ_BLOCK rb_table[2] = {
		read_block_null,
		read_block_mpeg1_nonintra,
	};

	out->block_count = 6;

	coded_block_pattern = get_coded_block_pattern(in);
	
	for(i=0;i<6;i++){
		out->read_block[i] = rb_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
}

static void read_coded_block_mpeg2_422_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	int coded_block_pattern;

	static const READ_BLOCK rb_y_table[2] = {
		read_block_null,
		read_block_mpeg2_nonintra_luminance,
	};

	static const READ_BLOCK rb_c_table[2] = {
		read_block_null,
		read_block_mpeg2_nonintra_chrominance,
	};

	out->block_count = 8;

	coded_block_pattern = get_coded_block_pattern(in);
	coded_block_pattern <<= 2;
	coded_block_pattern += vs_get_bits(in, 2);
	
	for(i=0;i<4;i++){
		out->read_block[i] = rb_y_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
	for(i=4;i<8;i++){
		out->read_block[i] = rb_c_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
}

static void read_coded_block_mpeg2_444_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	int coded_block_pattern;

	static const READ_BLOCK rb_y_table[2] = {
		read_block_null,
		read_block_mpeg2_nonintra_luminance,
	};

	static const READ_BLOCK rb_c_table[2] = {
		read_block_null,
		read_block_mpeg2_nonintra_chrominance,
	};

	out->block_count = 12;

	coded_block_pattern = get_coded_block_pattern(in);
	coded_block_pattern <<= 6;
	coded_block_pattern += vs_get_bits(in, 6);
	
	for(i=0;i<4;i++){
		out->read_block[i] = rb_y_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
	for(i=4;i<12;i++){
		out->read_block[i] = rb_c_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
	}
}

static void read_coded_block_420_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	
	out->block_count = 6;
	
	for(i=0;i<6;i++){
		out->read_block[i] = read_block_null;
	}
}

static void read_coded_block_422_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	
	out->block_count = 8;
	
	for(i=0;i<8;i++){
		out->read_block[i] = read_block_null;
	}
}

static void read_coded_block_444_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int i;
	
	out->block_count = 12;
	
	for(i=0;i<12;i++){
		out->read_block[i] = read_block_null;
	}
}

static int get_coded_block_pattern(VIDEO_STREAM *in)
{
	int r;
	int code;
	
	static const BASIC_VLC_ELEMENT table_a[] = {
		{63,6},{ 3,6},{36,6},{24,6},{62,5},{62,5},{ 2,5},{ 2,5},
		{61,5},{61,5},{ 1,5},{ 1,5},{56,5},{56,5},{52,5},{52,5},
		{44,5},{44,5},{28,5},{28,5},{40,5},{40,5},{20,5},{20,5},
		{48,5},{48,5},{12,5},{12,5},{32,4},{32,4},{32,4},{32,4},
		{16,4},{16,4},{16,4},{16,4},{ 8,4},{ 8,4},{ 8,4},{ 8,4},
		{ 4,4},{ 4,4},{ 4,4},{ 4,4},{60,3},{60,3},{60,3},{60,3},
		{60,3},{60,3},{60,3},{60,3},
	};
	
	static const BASIC_VLC_ELEMENT table_b[] = {
		{ 0,0},{ 0,9},{39,9},{27,9},{59,9},{55,9},{47,9},{31,9},
		{58,8},{58,8},{54,8},{54,8},{46,8},{46,8},{30,8},{30,8},
		{57,8},{57,8},{53,8},{53,8},{45,8},{45,8},{29,8},{29,8},
		{38,8},{38,8},{26,8},{26,8},{37,8},{37,8},{25,8},{25,8},
		{43,8},{43,8},{23,8},{23,8},{51,8},{51,8},{15,8},{15,8},
		{42,8},{42,8},{22,8},{22,8},{50,8},{50,8},{14,8},{14,8},
		{41,8},{41,8},{21,8},{21,8},{49,8},{49,8},{13,8},{13,8},
		{35,8},{35,8},{19,8},{19,8},{11,8},{11,8},{ 7,8},{ 7,8},
		{34,7},{34,7},{34,7},{34,7},{18,7},{18,7},{18,7},{18,7},
		{10,7},{10,7},{10,7},{10,7},{ 6,7},{ 6,7},{ 6,7},{ 6,7},
		{33,7},{33,7},{33,7},{33,7},{17,7},{17,7},{17,7},{17,7},
		{ 9,7},{ 9,7},{ 9,7},{ 9,7},{ 5,7},{ 5,7},{ 5,7},{ 5,7},
	};

	code = vs_read_bits(in, 9);

	if(code > 95){
		code = (code >> 3) - 12;
		r = table_a[code].value;
		vs_erase_bits(in, table_a[code].length);
	}else{
		r = table_b[code].value;
		vs_erase_bits(in, table_b[code].length);
	}

	return r;
}

typedef struct {
	int weight_top;
	int weight_bottom;
	int class;
	int integer_weight;
} SPATIAL_TEMPORAL_WEIGHT_TABLE_ELEMENT;

static void read_spatial_temporal_weight(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt)
{
	int code;
	
	static const SPATIAL_TEMPORAL_WEIGHT_TABLE_ELEMENT table[4][4] = {
		{
			{1, 1, 1, 0},
			{1, 1, 1, 0},
			{1, 1, 1, 0},
			{1, 1, 1, 0},
		}, /* table_index_0 */

		{
			{0, 2, 3, 1},
			{0, 1, 1, 0},
			{1, 2, 3, 0},
			{1, 1, 1, 0},
		}, /* table_index_1 */

		{
			{2, 0, 2, 1},
			{1, 0, 1, 0},
			{2, 1, 2, 0},
			{1, 1, 1, 0},
		}, /* table_index_2 */

		{
			{2, 0, 2, 1},
			{2, 1, 2, 0},
			{1, 2, 3, 0},
			{1, 1, 1, 0},
		}, /* table_index_4 */
	};
	
	if(opt->spatial_temporal_weight_code_table_index){
		code = vs_get_bits(in, 2);
		out->spatial_temporal_weight[0] = table[opt->spatial_temporal_weight_code_table_index][code].weight_top;
		out->spatial_temporal_weight[1] = table[opt->spatial_temporal_weight_code_table_index][code].weight_bottom;
		out->spatial_temporal_weight_class = table[opt->spatial_temporal_weight_code_table_index][code].class;
		out->spatial_temporal_integer_weight = table[opt->spatial_temporal_weight_code_table_index][code].integer_weight;
	}else{
		out->spatial_temporal_weight[0] = 1;
		out->spatial_temporal_weight[1] = 1;
		out->spatial_temporal_weight_class = 1;
		out->spatial_temporal_integer_weight = 0;
	}
}

⌨️ 快捷键说明

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