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

📄 macroblock.c

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

#define MACROBLOCK_C
#include "macroblock.h"

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

int get_macroblock_address_increment(VIDEO_STREAM *in);
int read_macroblock(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
int macroblock_to_read_block_option(MACROBLOCK *in, READ_BLOCK_OPTION *opt);
int macroblock_to_mc_parameter(MACROBLOCK *in, MC_PARAMETER *out);	
int reset_motion_vector_predictor(MACROBLOCK *p);
int read_macroblock_type_snr_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_b_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_p_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_i_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_b(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_p(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_i(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_d(VIDEO_STREAM *in, MACROBLOCK *out);

static int read_macroblock_mode(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
static int get_motion_code(VIDEO_STREAM *in);
static int get_dmvector(VIDEO_STREAM *in);
static void read_dual_prime_motion_vector(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
static void read_motion_vector(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s);
static void read_dmv(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s, int t);
static int get_motion_vector_predictor(VIDEO_STREAM *in, int predictor, int f_code, int half);
static void read_coded_block_mpeg2_420_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg1_420_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_422_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_444_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg1_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_422_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_444_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_420_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_422_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_444_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out);
static int get_coded_block_pattern(VIDEO_STREAM *in);
static void read_spatial_temporal_weight(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);

typedef void (* READ_CODED_BLOCK)(VIDEO_STREAM *, MACROBLOCK *);

int read_macroblock(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt)
{
	static const READ_CODED_BLOCK rcb[2][3][2][2] = {
		{    /* mpeg-2 */
			{    /* 420 */
				{   /* nonintra */
					read_coded_block_420_nonintra_nopattern,
					read_coded_block_mpeg2_420_nonintra_pattern,
				},{ /* intra */
					read_coded_block_mpeg2_420_intra,
					read_coded_block_mpeg2_420_intra,
				},
			}, { /* 422 */
				{   /* nonintra */
					read_coded_block_422_nonintra_nopattern,
					read_coded_block_mpeg2_422_nonintra_pattern,
				},{ /* intra */
					read_coded_block_mpeg2_422_intra,
					read_coded_block_mpeg2_422_intra,
				},
			}, { /* 444 */
				{   /* nonintra */
					read_coded_block_444_nonintra_nopattern,
					read_coded_block_mpeg2_444_nonintra_pattern,
				},{ /* intra */
					read_coded_block_mpeg2_444_intra,
					read_coded_block_mpeg2_444_intra,
				},
			},
		},{ /* mpeg-1 */
			{   /* 420 */
				{   /* nonintra */
					read_coded_block_420_nonintra_nopattern,
					read_coded_block_mpeg1_420_nonintra_pattern,
				},{ /* intra */
					read_coded_block_mpeg1_420_intra,
					read_coded_block_mpeg1_420_intra,
				},
			},{ /* 422 - dummy */
				{   /* nonintra */
					read_coded_block_420_nonintra_nopattern,
					read_coded_block_mpeg1_420_nonintra_pattern,
				},{ /* intra */
					read_coded_block_mpeg1_420_intra,
					read_coded_block_mpeg1_420_intra,
				},
			},{ /* 444 - dummy */
				{   /* nonintra */
					read_coded_block_420_nonintra_nopattern,
					read_coded_block_mpeg1_420_nonintra_pattern,
				},{ /* intra */
					read_coded_block_mpeg1_420_intra,
					read_coded_block_mpeg1_420_intra,
				},
			},
		},
	};
	
	if(!read_macroblock_mode(in, out, opt)){
		return 0;
	}

	if(out->macroblock_quant){
		out->quantizer_scale_code = vs_get_bits(in, 5);
	}

	if(out->macroblock_motion_forward || (out->macroblock_intra && opt->concealment_motion_vectors)){
		read_motion_vector(in, out, opt, 0);
	}

	if(out->macroblock_motion_backward){
		read_motion_vector(in, out, opt, 1);
	}

	if(out->macroblock_intra && opt->concealment_motion_vectors){
		vs_get_bits(in, 1); /* marker bit */
	}

	rcb[opt->mpeg1][opt->chroma_format-1][out->macroblock_intra][out->macroblock_pattern](in, out);

	return 1;
}

int macroblock_to_read_block_option(MACROBLOCK *in, READ_BLOCK_OPTION *out)
{
	out->macroblock_intra = in->macroblock_intra;
	out->dct_type = in->dct_type;

	if(in->macroblock_quant){
		out->qw[0] = out->qw_table[in->quantizer_scale_code][0];
		out->qw[1] = out->qw_table[in->quantizer_scale_code][1];
		out->qw[2] = out->qw_table[in->quantizer_scale_code][2];
		out->qw[3] = out->qw_table[in->quantizer_scale_code][3];
	}

	if(! in->macroblock_intra){
		reset_dc_dct_predictor(out);
	}
	
	return 1;
}

int get_macroblock_address_increment(VIDEO_STREAM *in)
{
	int r;
	int code;

	static const BASIC_VLC_ELEMENT table_a[] = {
		{9,7},{8,7},
		{7,5},{7,5},{7,5},{7,5},{6,5},{6,5},{6,5},{6,5},
		{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
		{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
		{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},
		{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},
		{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,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},{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,1},{1,1},{1,1},{1,1},{1,1},{1,1},
	};

	static const BASIC_VLC_ELEMENT table_b[] = {
		{33,11},{32,11},{31,11},{30,11},{29,11},{28,11},{27,11},{26,11},
		{25,11},{24,11},{23,11},{22,11},{21,10},{21,10},{20,10},{20,10},
		{19,10},{19,10},{18,10},{18,10},{17,10},{17,10},{16,10},{16,10},
		{15,8},{15,8},{15,8},{15,8},{15,8},{15,8},{15,8},{15,8},
		{14,8},{14,8},{14,8},{14,8},{14,8},{14,8},{14,8},{14,8},
		{13,8},{13,8},{13,8},{13,8},{13,8},{13,8},{13,8},{13,8},
		{12,8},{12,8},{12,8},{12,8},{12,8},{12,8},{12,8},{12,8},
		{11,8},{11,8},{11,8},{11,8},{11,8},{11,8},{11,8},{11,8},
		{10,8},{10,8},{10,8},{10,8},{10,8},{10,8},{10,8},{10,8},
	};

	r = 0;

	code = vs_read_bits(in, 11);

	while( (code = vs_read_bits(in, 11)) == 8 ){
		r += 33;
		vs_erase_bits(in, 11);
	}

	if(code > 95){
		code = (code >> 4) - 6;
		r += table_a[code].value;
		vs_erase_bits(in, table_a[code].length);
	}else if(code > 23){
		code -= 24;
		r += table_b[code].value;
		vs_erase_bits(in, table_b[code].length);
	}else{
		r = 0;
	}

	return r;
}

int macroblock_to_mc_parameter(MACROBLOCK *in, MC_PARAMETER *out)
{
	int r,s,t;

	out->macroblock_motion_forward = in->macroblock_motion_forward;
	out->macroblock_motion_backward = in->macroblock_motion_backward;

	out->prediction_type = in->prediction_type;

	for(r=0;r<2;r++){
		for(s=0;s<2;s++){
			for(t=0;t<2;t++){
				out->PMV[r][s][t] = in->PMV[r][s][t];
			}
			out->DMV[r][s] = in->DMV[r][s];
			out->motion_vertical_field_select[r][s] = in->motion_vertical_field_select[r][s];
		}
	}

	return 1;
}

int macroblock_to_error_concealment_mc_parameter(MACROBLOCK *in, MC_PARAMETER *out)
{
	int r,s,t;

	out->macroblock_motion_forward = in->macroblock_motion_forward;
	out->macroblock_motion_backward = in->macroblock_motion_backward;

	out->prediction_type = in->prediction_type;

	for(r=0;r<2;r++){
		for(s=0;s<2;s++){
			for(t=0;t<2;t++){
				out->PMV[r][s][t] = in->PMV[r][s][t];
			}
			out->DMV[r][s] = in->DMV[r][s];
			out->motion_vertical_field_select[r][s] = in->motion_vertical_field_select[r][s];
		}
	}

	if(in->macroblock_intra){
		out->macroblock_motion_forward = 1;
		out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
		memset(out->PMV, 0, sizeof(out->PMV));
		if(out->picture_structure == 2){
			out->motion_vertical_field_select[0][0] = 1;
		}else{
			out->motion_vertical_field_select[0][0] = 0;
		}
	}

	return 1;
}

int reset_motion_vector_predictor(MACROBLOCK *p)
{
	int r,s,t;

	for(r=0;r<2;r++){
		for(s=0;s<2;s++){
			for(t=0;t<2;t++){
				p->PMV[r][s][t] = 0;
			}
		}
	}

	return 1;
}

static int read_macroblock_mode(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt)
{
	int code;

	if(!opt->read_macroblock_type(in, out)){
		return 0;
	}

	if(out->spatial_temporal_weight_code_flag){
		read_spatial_temporal_weight(in, out, opt);
	}

	if(out->macroblock_motion_forward || out->macroblock_motion_backward){
		if(opt->picture_structure == 3){
			if(! opt->frame_predictive_frame_dct){
				code = vs_get_bits(in, 2);
				switch(code){
				case 0:
					return 0;
				case 1:
					out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
					if( (out->spatial_temporal_weight_class == 0) || (out->spatial_temporal_weight_class == 1) ){
						out->motion_vector_count = 2;
					}else{
						out->motion_vector_count = 1;
					}
					out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
					out->dual_prime_motion_vector = 0;
					break;
				case 2:
					out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
					out->motion_vector_count = 1;
					out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
					out->dual_prime_motion_vector = 0;
					break;
				case 3:
					out->prediction_type = PREDICTION_TYPE_DUAL_PRIME;
					out->motion_vector_count = 1;
					out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
					out->dual_prime_motion_vector = 1;
				}
			}else{
				out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
				out->motion_vector_count = 1;
				out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
				out->dual_prime_motion_vector = 0;
			}
		}else{
			code = vs_get_bits(in, 2);
			switch(code){
			case 0:
				return 0;
			case 1:
				out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
				out->motion_vector_count = 1;
				out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
				out->dual_prime_motion_vector = 0;
				break;
			case 2:
				out->prediction_type = PREDICTION_TYPE_16x8_MC;
				out->motion_vector_count = 2;
				out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
				out->dual_prime_motion_vector = 0;
				break;
			case 3:
				out->prediction_type = PREDICTION_TYPE_DUAL_PRIME;
				out->motion_vector_count = 1;
				out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
				out->dual_prime_motion_vector = 1;
				break;
			}
		}
	}else if(out->macroblock_intra && opt->concealment_motion_vectors){
		out->motion_vector_count = 1;
		out->dual_prime_motion_vector = 0;
		if(opt->picture_structure == 3){
			out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
			out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
		}else{
			out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
			out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
		}
	}else{
		out->motion_vector_count = 1;
		out->dual_prime_motion_vector = 0;

		reset_motion_vector_predictor(out);
		
		switch(opt->picture_structure){
		case 1:
			out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
			out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
			out->motion_vertical_field_select[0][0] = 0;
			break;
		case 2:
			out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
			out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
			out->motion_vertical_field_select[0][0] = 1;
			break;
		case 3:
			out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
			out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
			break;
		}
	}

	if(opt->frame_predictive_frame_dct){
		out->dct_type = 0;
	}else if( opt->picture_structure == 3 && (out->macroblock_intra || out->macroblock_pattern) ){
		out->dct_type = vs_get_bits(in, 1);
	}else{
		out->dct_type = 0;
	}

	return 1;
}

int read_macroblock_type_snr_scalability(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int code;
	
	code = vs_read_bits(in, 3);
	if( (code >> 2) == 1 ){
		out->macroblock_quant = 0;
		out->macroblock_motion_forward = 0;
		out->macroblock_motion_backward = 0;
		out->macroblock_pattern = 1;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;
		out->spatial_temporal_weight_class = 0;
		vs_erase_bits(in, 1);
	}else if( (code >> 1) == 1){
		out->macroblock_quant = 1;
		out->macroblock_motion_forward = 0;
		out->macroblock_motion_backward = 0;
		out->macroblock_pattern = 1;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;
		out->spatial_temporal_weight_class = 0;
		vs_erase_bits(in, 2);
	}else if(code == 1){
		out->macroblock_quant = 0;
		out->macroblock_motion_forward = 0;
		out->macroblock_motion_backward = 0;
		out->macroblock_pattern = 0;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;
		out->spatial_temporal_weight_class = 0;
		vs_erase_bits(in, 3);
	}else{
		return 0;
	}

	return 1;
}

int read_macroblock_type_b_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out)
{
	int code;

	code = vs_read_bits(in, 9);
	
	if( (code >> 7) == 2 ){
		out->macroblock_quant = 0;
		out->macroblock_motion_forward = 1;
		out->macroblock_motion_backward = 1;
		out->macroblock_pattern = 0;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;
		out->spatial_temporal_weight_class = 0;
		vs_erase_bits(in, 2);
	}else if( (code >> 7) == 3 ){
		out->macroblock_quant = 0;
		out->macroblock_motion_forward = 1;
		out->macroblock_motion_backward = 1;
		out->macroblock_pattern = 1;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;
		out->spatial_temporal_weight_class = 0;
		vs_erase_bits(in, 2);
	}else if( (code >> 6) == 2 ){
		out->macroblock_quant = 0;
		out->macroblock_motion_forward = 0;
		out->macroblock_motion_backward = 1;
		out->macroblock_pattern = 0;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;
		out->spatial_temporal_weight_class = 0;
		vs_erase_bits(in, 3);
	}else if( (code >> 6) == 3 ){
		out->macroblock_quant = 0;
		out->macroblock_motion_forward = 0;
		out->macroblock_motion_backward = 1;
		out->macroblock_pattern = 1;
		out->macroblock_intra = 0;
		out->spatial_temporal_weight_code_flag = 0;

⌨️ 快捷键说明

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