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

📄 mpeg2edit.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
📖 第 1 页 / 共 5 页
字号:
	return 0;
}

static int es_judge_read_gop_header_end(int code)
{
	if(code == 0x00000100){ /* picture_start_code */
		return 1;
	}

	return 0;
}

static int es_judge_read_picture_end(int code)
{
	if(code == 0x00000100){ /* picture_start_code */
		return 1;
	}else if(code == 0x000001b3){ /* sequence_start_code */
		return 1;
	}else if(code == 0x000001b8){ /* gop_start_code */
		return 1;
	}else if(code == 0x000001b7){ /* sequence_end_code */
		return 1;
	}

	return 0;
}

static void es_write_sequence_header(ES_SEQUENCE_HEADER *in, FILE *out)
{
	fwrite_list(in->head, out);
}

static void es_write_gop_header(ES_GOP_HEADER *in, FILE *out)
{
	fwrite_list(in->head, out);
}

static void es_write_picture(ES_PICTURE *in, FILE *out)
{
	fwrite_list(in->head, out);
}

static void es_write_frame(ES_FRAME *in, FILE *out)
{
	es_write_picture(&(in->fst), out);
	es_write_picture(&(in->snd), out);
}

static void es_write_sequence_end_code(FILE *out)
{
	unsigned char sequence_end_code[4] = {
		0, 0, 1, 0xb7,
	};

	fwrite(sequence_end_code, 1, 4, out);
}

static void es_clear_sequence_header(ES_SEQUENCE_HEADER *seq)
{
	clear_list(seq->head);
	seq->head = NULL;
	seq->length = 0;
}

static void es_clear_gop_header(ES_GOP_HEADER *gop)
{
	clear_list(gop->head);
	gop->head = NULL;
	gop->length = 0;
}

static void es_clear_picture(ES_PICTURE *pic)
{
	clear_list(pic->head);
	pic->head = NULL;
	pic->length = 0;
}

static void es_clear_frame(ES_FRAME *frm)
{
	es_clear_picture(&(frm->fst));
	es_clear_picture(&(frm->snd));
}

static void es_padding_picture(ES_PICTURE *pic)
{
	padding_list(pic->head, 0);
}

static void es_padding_frame(ES_FRAME *frm)
{
	es_padding_picture(&(frm->fst));

	if(frm->snd.length){
		es_padding_picture(&(frm->snd));
	}
}

static int es_get_fps(ES_SEQUENCE_HEADER *seq)
{
	int r;
	int rate;
	int scale;
	int offset;
	unsigned char code;
	unsigned char pattern[4] = { 0, 0, 1, 0xb5 };

	static const int rate_table[16] = {
		 0, 23976, 24, 25, 2997, 30, 50, 5994,
		60,     0,  0,  0,    0,  0,  0,    0,
	};

	static const int scale_table[16] = {
		 1, 1000, 1, 1, 100, 1, 1, 100,
		 1,    1, 1, 1,   1, 1, 1,   1,
	};

	code = get_byte_list(seq->head, 7);
	rate = rate_table[code & 0xf];
	scale = scale_table[code & 0xf];
	
	offset = find_list(seq->head, 12, pattern, 4);
	
	while(offset > 0){
		if( (get_byte_list(seq->head, offset+4) & 0xf0) == 0x10){
			code = get_byte_list(seq->head, offset+9);
			rate *= (((code >> 5) & 0x3) + 1);
			scale *= (((code >> 3) & 0x3) + 1);
			break;
		}else{
			offset = find_list(seq->head, offset+4, pattern, 4);
		}
	}

	r = (rate+(scale-1))/scale;
	
	return r;
}

static void es_set_timecode(ES_GOP_HEADER *gop, __int64 frame, int fps)
{
	int hh;
	int mm;
	int ss;
	int ff;

	unsigned char c0,c1,c2,c3;

	ff = (int)(frame % fps);
	frame /= fps;
	ss = (int)(frame % 60);
	frame /= 60;
	mm = (int)(frame % 60);
	frame /= 60;
	hh = (int)(frame % 24);

	c0 = (unsigned char)( (hh << 2) + (mm >> 4) );
	c1 = (unsigned char)( ((mm & 0x0f) << 4) + 0x08 + (ss >> 3) );
	c2 = (unsigned char)( ((ss & 7) << 5) + (ff >> 1) );
	c3 = (unsigned char)( (get_byte_list(gop->head, 7) & 0x7f) + ((ff & 1) << 7) );

	set_byte_list(gop->head, 4, c0);
	set_byte_list(gop->head, 5, c1);
	set_byte_list(gop->head, 6, c2);
	set_byte_list(gop->head, 7, c3);
}

static int es_get_closed_gop(ES_GOP_HEADER *gop)
{
	int r;

	r = (get_byte_list(gop->head, 7) & 0x40) >> 6;

	return r;
}

static int es_get_broken_link(ES_GOP_HEADER *gop)
{
	int r;

	r = (get_byte_list(gop->head, 7) & 0x20) >> 5;

	return r;
}

static void es_set_broken_link(ES_GOP_HEADER *gop, int broken_link)
{
	unsigned char c;

	c = (unsigned char)(get_byte_list(gop->head, 7) & 0xdf);

	if(broken_link){
		c |= 0x20;
	}

	set_byte_list(gop->head, 7, c);
}

static int  es_get_picture_temporal_reference(ES_PICTURE *pic)
{
	int r;

	r = get_byte_list(pic->head, 4) << 2;
	r += (get_byte_list(pic->head, 5) >> 6);

	return r;
}

static void es_set_picture_temporal_reference(ES_PICTURE *pic, int temporal_reference)
{
	unsigned char c0;
	unsigned char c1;

	temporal_reference &= 0x000003ff;

	c0 = (unsigned char)(temporal_reference >> 2);
	c1 = (unsigned char)( (get_byte_list(pic->head, 5) & 0x3f) + ((temporal_reference & 3) << 6) );

	set_byte_list(pic->head, 4, c0);
	set_byte_list(pic->head, 5, c1);
}

static int es_get_picture_coding_type(ES_PICTURE *pic)
{
	int r;

	r = (get_byte_list(pic->head, 5) >> 3) & 3;
	
	return r;
}

static int es_get_picture_field_count(ES_PICTURE *pic)
{
	int r;
	int offset;
	int code;

	unsigned char pattern[4] = { 0, 0, 1, 0xb5 };

	r = 2;
	
	offset = find_list(pic->head, 8, pattern, 4);
	
	while(offset > 0){
		if( (get_byte_list(pic->head, offset+4) & 0xf0) == 0x80){
			code = get_byte_list(pic->head, offset+6);
			if( (code & 0x03) != 0x03 ){
				return 1;
			}
			code = get_byte_list(pic->head, offset+7);
			if( (code & 0x02) == 0x02 ){
				return 3;
			}
			break;
		}else{
			offset = find_list(pic->head, offset+4, pattern, 4);
		}
	}

	return r;
}

static int es_get_temporal_reference(ES_FRAME *frm)
{
	return es_get_picture_temporal_reference(&(frm->fst));
}

static void es_set_temporal_reference(ES_FRAME *frm, int temporal_reference)
{
	es_set_picture_temporal_reference(&(frm->fst), temporal_reference);

	if(frm->snd.length){
		es_set_picture_temporal_reference(&(frm->snd), temporal_reference);
	}
}

static int es_get_coding_type(ES_FRAME *frm)
{
	return es_get_picture_coding_type(&(frm->fst));
}

static int es_get_field_count(ES_FRAME *frm)
{
	int r;

	r = es_get_picture_field_count(&(frm->fst));

	if(frm->snd.length){
		r += es_get_picture_field_count(&(frm->snd));
	}

	return r;
}

/*-----------------------------------------------------------------*/
static int ps_open(const char *path, MPEG2EDIT *mpeg2edit)
{
	BITSTREAM *bs;

	bs = bs_open(path);
	if(bs == NULL){
		return 0;
	}

	bs_seek(bs, 0, SEEK_SET);

	mpeg2edit->stream = bs;
	mpeg2edit->edit = ps_edit;
	mpeg2edit->close = ps_close;

	return 1;
}

static void ps_edit(void *mpeg2edit, char *out_path, __int64 in, __int64 out)
{
	BITSTREAM *bs;
	FILE *file;
	
	PS_PACK_LIST_ELEMENT *header;
	PS_PACK_LIST_ELEMENT *header_tail;
	
	PS_PACK_LIST_ELEMENT *other;
	PS_PACK_LIST_ELEMENT *other_tail;

	PS_PACK *system;
	
	PS_PACK *video1;
	PS_PACK *video2;

	PS_PACK *previous;
	PS_PACK *current;

	PS_PROC_VIDEO_OPTION opt;

	STREAM_ID_LIST audio_stream;
	
	int status;

	int stream_id;

	ps_init_proc_video_option(&opt, in, out);
	ps_init_stream_id_list(&audio_stream);
	
	header = NULL;
	header_tail = NULL;
	other = NULL;
	other_tail = NULL;

	system = NULL;
	
	video1 = NULL;
	video2 = NULL;

	stream_id = 0;

	status = PS_WASTE_PACK;
	
	bs = ((MPEG2EDIT *)mpeg2edit)->stream;
	
	bs_seek(bs, 0, SEEK_SET);
	bs_next_packet_prefix(bs);

	current = (PS_PACK *)calloc(1, sizeof(PS_PACK));
	previous = NULL;

	while(current){
		if(((MPEG2EDIT *)mpeg2edit)->callback(out_path, ps_get_current_percent(&opt)) != VF_OK){
			break;
		}
		
		ps_read_pack(bs, current);
		
		ps_set_pack_scr_length(previous, ps_get_system_clock_reference(current)-ps_get_system_clock_reference(previous));
		previous = current;
		
		if( (stream_id & 0xf0) != 0xe0 ){
			stream_id = ps_get_video_stream_id(current);
			ps_set_stream_id_proc_video_option(&opt, stream_id);
		}

		if( ps_find_system_header(current) ){
			if(system){
				ps_clear_pack(system);
				free(system);
			}
			system = current;
		}

		if( ((stream_id & 0xf0) == 0xe0) && ps_find_stream(current, stream_id) ){
			video2 = current;
			if(video1){
				status = ps_proc_video(video1, video2, &opt);
				if(status & PS_OUTPUT_PACK){
					if(system == video2){
						system = (PS_PACK *)calloc(1, sizeof(PS_PACK));
						ps_copy_system_header_pack(video2, system);
					}
					goto PS_EDIT_2ND_STEP;
				}else if(status & PS_HEADER_PACK){
					ps_clear_pack_list(header);
					header = ps_add_pack_list(NULL, video1);
					header_tail = header;
				}else if(status & PS_HEADER_CHAIN_PACK){
					header_tail = ps_add_pack_list(header_tail, video1);
				}else{
					ps_clear_pack(video1);
					free(video1);
				}
			}
			video1 = video2;
			if(system == video1){
				system = (PS_PACK *)calloc(1, sizeof(PS_PACK));
				ps_copy_system_header_pack(video1, system);
			}
		}else if(! ps_find_system_header(current)){
			if(ps_check_pack_chain(other_tail, current)){
				other_tail = ps_add_pack_list(other_tail, current);
			}else{
				ps_clear_pack_list(other);
				other = ps_add_pack_list(NULL, current);
				other_tail = other;
			}
		}
		
		if(! bs_next_packet_prefix(bs) ){
			break;
		}
		
		if( bs_read_bits(bs, 32) == 0x000001ba ){
			current = (PS_PACK *)calloc(1, sizeof(PS_PACK));
		}else{
			current = NULL;
		}
	}

	ps_clear_pack_list(header);
	ps_clear_pack_list(other);

	ps_clear_pack(system);
	free(system);
	
	ps_clear_pack(video1);
	free(video1);

	return;

PS_EDIT_2ND_STEP:

	file = fopen(out_path, "wb");
	if(file == NULL){
		ps_clear_pack_list(header);
		ps_clear_pack_list(other);

		ps_clear_pack(system);
		free(system);
	
		ps_clear_pack(video1);
		free(video1);

		return;
	}

	if(status & PS_HEADER_PACK){
		ps_clear_pack_list(header);
		header = NULL;
		header_tail = NULL;
	}

	current = video1;

	if(header){
		ps_set_pack_list_scr(header, ps_get_system_clock_reference(current)-ps_get_pack_list_scr_length(header));
		current = header->data;
	}

	if( ps_find_system_header(current) ){
		if(system){
			ps_clear_pack(system);
			free(system);
			system = NULL;
		}
	}
	
	if(system){
		ps_set_system_clock_reference(system, ps_get_system_clock_reference(current)-ps_get_pack_scr_length(system));
		ps_write_pack(system, file, &audio_stream);
		ps_clear_pack(system);
		free(system);
	}

	ps_initialize_video_packet(current, stream_id);
	
	ps_write_pack_list(header, file, &audio_stream);
	ps_clear_pack_list(header);

	ps_write_pack(video1, file, &audio_stream);
	ps_clear_pack(video1);
	free(video1);
	video1 = video2;

	ps_write_pack_list(other, file, &audio_stream);

	if(! bs_next_packet_prefix(bs) ){
		ps_clear_pack_list(other);
		ps_write_pack(video1, file, &audio_stream);
		ps_clear_pack(video1);
		free(video1);
		fclose(file);
		return;
	}
		
	if( bs_read_bits(bs, 32) == 0x000001ba ){
		current = (PS_PACK *)calloc(1, sizeof(PS_PACK));
	}else{
		current = NULL;
	}

	while(current){
		if(((MPEG2EDIT *)mpeg2edit)->callback(out_path, ps_get_current_percent(&opt)) != VF_OK){
			ps_clear_pack_list(other);
			ps_clear_pack(video1);
			free(video1);
			fclose(file);
			return;
		}

		ps_read_pack(bs, current);

		ps_set_pack_scr_length(previous, ps_get_system_clock_reference(current)-ps_get_system_clock_reference(previous));
		previous = current;

		if(ps_find_stream(current, stream_id)){
			video2 = current;
			status = ps_proc_video(video1, video2, &opt);
			if(status & PS_OUTPUT_PACK){
				ps_write_pack(video1, file, &audio_stream);
				ps_clear_pack(video1);
				free(video1);
				ps_write_pack_list(other, file, &audio_stream);
				ps_clear_pack_list(other);
				other = NULL;
				other_tail = NULL;
			}else{
				goto PS_EDIT_3RD_STEP;
			}
			video1 = video2;
		}else{
			if(ps_check_pack_chain(other_tail, current)){
				other_tail = ps_add_pack_list(other_tail, current);
			}else{
				ps_clear_pack_list(other);
				other = ps_add_pack_list(NULL, current);
				other_tail = other;

⌨️ 快捷键说明

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