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

📄 mpeg_video.c

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

	in->dec_buf.current = new_frame(in->seq.h_size, in->seq.v_size);
	in->cur_prm.index = in->bwd_prm.index;

	picture_header_to_output_parameter(&(in->pic), &(in->cur_prm));
	
	if(in->pic.picture_coding_type != 3){
		r = rotate_reference_frame(in, frame);
	}
	in->cur_prm.closed_gop = in->closed_gop;

	if( in->pic.picture_coding_type == 3 ){
		if( in->dec_buf.backward == NULL) {
			delete_frame(in->dec_buf.current);
			in->dec_prm->mc_parameter.first_field = 0;
			return r;
		}else if( in->dec_buf.forward == NULL ){
			if(in->closed_gop){
				/* closed_gop error concealment */
				in->dec_buf.forward = in->dec_buf.backward;
			}else{
				delete_frame(in->dec_buf.current);
				in->dec_prm->mc_parameter.first_field = 0;
				return r;
			}
		}
	}else if((in->pic.picture_coding_type == 2) && (in->dec_buf.forward == NULL)){
		delete_frame(in->dec_buf.current);
		in->dec_prm->mc_parameter.first_field = 0;
		return r;
	}

	decode_picture(&(in->bitstream), &(in->dec_buf), in->dec_prm);

	if(in->pic.has_picture_coding_extension && in->pic.pc.picture_structure != 3){
		decode_2nd_field(in);
	}

	if(in->dec_buf.forward == in->dec_buf.backward){
		/* teardown closed_gop error concealment */
		in->dec_buf.forward = NULL;
	}

	if(in->pic.picture_coding_type == 3){
		r = store_current_decoding_frame(in, frame);
	}

	return r;
}

static OUT_BUFFER_ELEMENT *store_forward_reference_frame(MPEG_VIDEO *in, __int64 frame)
{
	delete_frame(in->dec_buf.forward);
	in->dec_buf.forward = NULL;

	return NULL;
}

static OUT_BUFFER_ELEMENT *store_backward_reference_frame(MPEG_VIDEO *in, __int64 frame)
{
	OUT_BUFFER_ELEMENT *w;
	OUT_BUFFER_ELEMENT *r;

	FRAME *rff_buf;

	r = NULL;
	
	if(in->bwd_prm.repeat_first_field && (in->bwd_prm.top_field_first == in->disp_field_order)){
		rff_buf = copy_frame(in->dec_buf.backward);
		w = add_frame_out_buffer_with_resize(in, rff_buf, &(in->bwd_prm));
		delete_frame(rff_buf);
		if(in->bwd_prm.index == frame){
			r = w;
		}
		in->bwd_prm.index += 1;
		in->bwd_prm.top_field_first = !(in->disp_field_order);
		in->bwd_prm.repeat_first_field = 0;
		in->bwd_prm.picture_coding_type = 3;
	}
	
	if((in->bwd_prm.picture_coding_type == 1) && (in->bwd_prm.index != in->current.start_frame) ){
		in->current.frame_count = in->bwd_prm.index - in->current.start_frame;
		in->current.start_frame = in->bwd_prm.index;
	}

	w = add_frame_out_buffer_with_resize(in, in->dec_buf.backward, &(in->bwd_prm));
	if(in->bwd_prm.index == frame){
		r = w;
	}
	delete_frame(in->dec_buf.backward);
	in->dec_buf.backward = NULL;

	return r;
}

static OUT_BUFFER_ELEMENT *store_current_decoding_frame(MPEG_VIDEO *in, __int64 frame)
{
	OUT_BUFFER_ELEMENT *w;
	OUT_BUFFER_ELEMENT *r;

	FRAME *rff_buf;

	r = NULL;
	
	if(in->cur_prm.repeat_first_field && (in->cur_prm.top_field_first == in->disp_field_order)){
		rff_buf = copy_frame(in->dec_buf.current);
		
		w = add_frame_out_buffer_with_resize(in, rff_buf, &(in->cur_prm));
		delete_frame(rff_buf);
		
		if(in->cur_prm.index == frame){
			r = w;
		}

		in->cur_prm.index += 1;
		in->cur_prm.top_field_first = !(in->disp_field_order);
		in->cur_prm.repeat_first_field = 0;
		in->cur_prm.picture_coding_type = 3;

		in->bwd_prm.index += 1;
	}

	w = add_frame_out_buffer_with_resize(in, in->dec_buf.current, &(in->cur_prm));
	delete_frame(in->dec_buf.current);
	
	if(in->cur_prm.index == frame){
		r = w;
	}
	
	in->bwd_prm.index += 1;

	return r;
}

static OUT_BUFFER_ELEMENT *rotate_reference_frame(MPEG_VIDEO *in, __int64 frame)
{
	OUT_BUFFER_ELEMENT *w;
	OUT_BUFFER_ELEMENT *r;
	
	FRAME *rff_buf;
	OUTPUT_PARAMETER rff_prm;

	r = NULL;
	
	if(in->dec_buf.forward){
		delete_frame(in->dec_buf.forward);
	}
	
	in->dec_buf.forward = in->dec_buf.backward;
	in->dec_buf.backward = in->dec_buf.current;
	in->fwd_prm = in->bwd_prm;
	in->bwd_prm = in->cur_prm;
	in->bwd_prm.index += 1;

	if((in->fwd_prm.picture_coding_type == 1) && (in->fwd_prm.index != in->current.start_frame) ){
		in->current.frame_count = in->fwd_prm.index - in->current.start_frame;
		in->current.start_frame = in->fwd_prm.index;
	}

	if(in->fwd_prm.repeat_first_field && (in->fwd_prm.top_field_first == in->disp_field_order) ){
		rff_buf = copy_frame(in->dec_buf.forward);

		rff_prm = in->fwd_prm;
		rff_prm.index += 1;
		rff_prm.picture_coding_type = 3;
		rff_prm.top_field_first = !(in->disp_field_order);
		rff_prm.repeat_first_field = 0;
		
		w = add_frame_out_buffer_with_resize(in, rff_buf, &rff_prm);
		delete_frame(rff_buf);
		if(rff_prm.index == frame){
			r = w;
		}

		in->bwd_prm.index += 1;
	}

	if(in->dec_buf.forward){
		w = add_frame_out_buffer_with_resize(in, in->dec_buf.forward, &(in->fwd_prm));
		if(in->fwd_prm.index == frame){
			r = w;
		}
	}

	if(in->closed_gop == 1){
		in->closed_gop = 2;
	}else{
		in->closed_gop = 0;
	}

	return r;
}

static int is_seek_required(MPEG_VIDEO *p, __int64 frame)
{
	__int64 n,m;
	
	if(p->dec_buf.backward){
		if(p->bwd_prm.index == frame){
			return 0;
		}
	}
	
	n = p->current.start_frame + p->current.frame_count;
	m = p->bwd_prm.index + 10;
	if(n<m){
		n = m;
	}
	
	if( (p->bwd_prm.index > 0) && (frame > p->bwd_prm.index) && (frame < n) ){
		return 0;
	}

	return 1;
}

static void sequence_header_to_decode_picture_parameter(SEQUENCE_HEADER *in, DECODE_PICTURE_PARAMETER *out)
{
	sequence_header_to_read_slice_header_option(in, &(out->slice_option));
	sequence_header_to_read_macroblock_option(in, &(out->macroblock_option));
	sequence_header_to_read_block_option(in, &(out->block_option));
	sequence_header_to_mc_parameter(in, &(out->mc_parameter));
}

static void picture_header_to_decode_picture_parameter(PICTURE_HEADER *in, DECODE_PICTURE_PARAMETER *out)
{
	picture_header_to_read_macroblock_option(in, &(out->macroblock_option));
	picture_header_to_read_block_option(in, &(out->block_option));
	picture_header_to_mc_parameter(in, &(out->mc_parameter));
}

static void decode_2nd_field(MPEG_VIDEO *p)
{
	int code;

	__int64 offset;
	
	while(vs_next_start_code(&(p->bitstream))){
		code = vs_read_bits(&(p->bitstream), 32);
		if(code == 0x100){
			offset = video_stream_tell(&(p->bitstream));
			vs_erase_bits(&(p->bitstream), 32);
			
			read_picture_header(&(p->bitstream), &(p->pic), &(p->pic_opt));
			
			if(p->pic.has_picture_coding_extension && (p->pic.pc.picture_structure !=3) ){
				picture_header_to_decode_picture_parameter(&(p->pic), p->dec_prm);
				
				decode_picture(&(p->bitstream), &(p->dec_buf), p->dec_prm);

			}else{
				video_stream_seek(&(p->bitstream), offset, SEEK_SET);
			}

			return;
		}else{
			return;
		}
	}
}

static OUT_BUFFER_ELEMENT *add_frame_out_buffer_with_resize(MPEG_VIDEO *p, FRAME *data, OUTPUT_PARAMETER *frame_prm)
{
	OUT_BUFFER_ELEMENT *r;
	FRAME *rsz;
	
	p->upsmp_c[frame_prm->progressive_frame](data);
	rsz = resize(data, p->rsz_prm);
	r = add_frame_out_buffer(&(p->out_buf), rsz, frame_prm);
	if(rsz != data){
		delete_frame(rsz);
	}
	return r;
}

static int is_registered_suffix(char *filepath)
{
	int i;
	
	static char *registered_suffix[] = {
		".mpeg",
		".mpg",
		".m2p",
		".mp2",
		".vob",
		".vro",
		".m2v",
		".m1v",
		".mpv",
		".ves",
		".m2t",
		".ssg",
		".ts",
		".bs",
		"", /* sentinel */
	};

	i = 0;
	while(registered_suffix[i][0]){
		if(check_suffix(filepath, registered_suffix[i])){
			return 1;
		}
		i += 1;
	}

	return 0;
}

static void setup_chroma_upsampling_function(MPEG_VIDEO *p, int chroma_format, int simd)
{
	if(chroma_format == 1){
		if(simd & M2V_CONFIG_USE_SSE2){
			p->upsmp_c[0] = upsample_chroma_420i_sse2;
			p->upsmp_c[1] = upsample_chroma_420p_sse2;
		}else if(simd & M2V_CONFIG_USE_MMX){
			p->upsmp_c[0] = upsample_chroma_420i_mmx;
			p->upsmp_c[1] = upsample_chroma_420p_mmx;
		}else{
			p->upsmp_c[0] = upsample_chroma_420i;
			p->upsmp_c[1] = upsample_chroma_420p;
		}
	}else{
		p->upsmp_c[0] = upsample_chroma_none;
		p->upsmp_c[1] = upsample_chroma_none;
	}
}

static void setup_convert_function(MPEG_VIDEO *p, int chroma_format, int simd)
{
	if(chroma_format == 3){
		p->to_bgr = yuv444_to_bgr;
		p->to_yuy2 = yuv444_to_yuy2;
	}else{
		if(simd & M2V_CONFIG_USE_SSE2){
			p->to_bgr = yuv422_to_bgr_sse2;
			p->to_yuy2 = yuv422_to_yuy2_sse2;
		}else if(simd & M2V_CONFIG_USE_MMX){
			p->to_bgr = yuv422_to_bgr_mmx;
			p->to_yuy2 = yuv422_to_yuy2_mmx;
		}else{
			p->to_bgr = yuv422_to_bgr;
			p->to_yuy2 = yuv422_to_yuy2;
		}
	}
}

static void setup_qw_function(DECODE_PICTURE_PARAMETER *p, int simd)
{
	if(simd & M2V_CONFIG_USE_SSE2){
		p->block_option.setup_qw = setup_qw_sse2;
	}else if(simd & M2V_CONFIG_USE_MMX){
		p->block_option.setup_qw = setup_qw_mmx;
	}else{
		p->block_option.setup_qw = setup_qw_nosimd;
	}
}

static void setup_idct_function(DECODE_PICTURE_PARAMETER *p, M2V_CONFIG *prm)
{
	if(prm->idct_type == M2V_CONFIG_IDCT_REFERENCE){
		if(prm->simd & M2V_CONFIG_USE_SSE){
			p->idct_func = idct_reference_sse;
		}else{
			p->idct_func = idct_reference;
		}
	}else if (prm->idct_type == M2V_CONFIG_IDCT_LLM_INT){
		if(prm->simd & M2V_CONFIG_USE_MMX){
			p->idct_func = idct_llm_mmx;
		}else{
			p->idct_func = idct_llm_int;
		}
	}else{
		if(prm->simd & M2V_CONFIG_USE_SSE2){
			p->idct_func = idct_ap922_sse2;
		}else if(prm->simd & M2V_CONFIG_USE_SSE){
			p->idct_func = idct_ap922_sse;
		}else if(prm->simd & M2V_CONFIG_USE_MMX){
			p->idct_func = idct_ap922_mmx;
		}else{
			p->idct_func = idct_ap922_int;
		}
	}
}

static void setup_mc_function(DECODE_PICTURE_PARAMETER *p, M2V_CONFIG *prm)
{
	if(prm->simd & M2V_CONFIG_USE_SSE2){
		p->mc_parameter.prediction_func = prediction_sse2;
	}else if(prm->simd & M2V_CONFIG_USE_SSE){
		p->mc_parameter.prediction_func = prediction_sse;
	}else if(prm->simd & M2V_CONFIG_USE_MMX){
		p->mc_parameter.prediction_func = prediction_mmx;
	}else{
		p->mc_parameter.prediction_func = prediction;
	}
}

static void setup_add_block_function(DECODE_PICTURE_PARAMETER *p, M2V_CONFIG *prm)
{
	if(prm->simd & M2V_CONFIG_USE_MMX){
		p->add_block_func = add_block_data_to_frame_mmx;
	}else{
		p->add_block_func = add_block_data_to_frame;
	}
}

static void clear_output_parameters(MPEG_VIDEO *p)
{
	memset(&(p->fwd_prm), 0, sizeof(OUTPUT_PARAMETER));
	memset(&(p->cur_prm), 0, sizeof(OUTPUT_PARAMETER));
	memset(&(p->bwd_prm), 0, sizeof(OUTPUT_PARAMETER));
		
	p->fwd_prm.index = p->current.start_frame - 1;
	p->bwd_prm.index = p->current.start_frame - 1;
}

static void setup_m2v_config(M2V_CONFIG *p)
{
	p->simd = get_simd_mode();
	p->bt601 = get_color_conversion_type();
	p->yuy2 = get_yuy2_mode();
	p->aspect_ratio = get_resize_mode();
	p->field_mode = get_field_mode();
	p->idct_type = get_idct_type();
	p->color_matrix = get_color_matrix();
	p->gl = get_gl_mode();
}

static void setup_field_order(MPEG_VIDEO *p, M2V_CONFIG *prm)
{
	switch(prm->field_mode){
	case M2V_CONFIG_FRAME_KEEP_ORIGINAL:
		p->disp_field_order = p->orig_field_order;
		break;
	case M2V_CONFIG_FRAME_TOP_FIRST:
		p->disp_field_order = TOP_FIELD_FIRST;
		break;
	case M2V_CONFIG_FRAME_BOTTOM_FIRST:
		p->disp_field_order = BOTTOM_FIELD_FIRST;
		break;
	default:
		p->disp_field_order = p->orig_field_order;
	}

	if(p->disp_field_order != p->orig_field_order){
		p->total -= 1;
	}
}

static void resize_parameter_to_bgr_conversion_parameter(RESIZE_PARAMETER *in, BGR_CONVERSION_PARAMETER *out)
{
	if(in == NULL){
		return;
	}

	out->prm.width = in->l.width;
	out->prm.height = in->l.height;

	out->prm.in_step = in->l.out_step;

	out->prm.c_offset = in->c.out_offset;
}

static YUY2_CONVERT select_yuy2_convert_function(int simd)
{
	YUY2_CONVERT r;

	r = yuy2_convert;
	
	if(simd & M2V_CONFIG_USE_SSE2){
		r = yuy2_convert_sse2;
	}else if(simd & M2V_CONFIG_USE_SSE){
		r = yuy2_convert_mmx;
	}else if(simd & M2V_CONFIG_USE_MMX){
		r = yuy2_convert_mmx;
	}
	
	return r;
}

⌨️ 快捷键说明

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