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

📄 mpeg2edit.c

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

	scr = ps_get_system_clock_reference(tail->data) + ps_get_pack_scr_length(tail->data);
	if(scr == ps_get_system_clock_reference(next)){
		return 1;
	}

	return 0;
}

static __int64 ps_get_pack_list_scr_length(PS_PACK_LIST_ELEMENT *head)
{
	__int64 r;

	r = 0;
	while(head){
		r += ps_get_pack_scr_length(head->data);
		head = (PS_PACK_LIST_ELEMENT *)head->next;
	}

	return r;
}
	
static void ps_set_pack_list_scr(PS_PACK_LIST_ELEMENT *head, __int64 scr)
{
	while(head){
		ps_set_system_clock_reference(head->data, scr);
		scr += ps_get_pack_scr_length(head->data);
		head = (PS_PACK_LIST_ELEMENT *)head->next;
	}
}

static void ps_set_clock_reference_pes_packet(LIST_ELEMENT *pes_packet, __int64 diff)
{
	static const unsigned char id_table[] = {
		0, 1, 0, 0,             /* 0xbc - 0xbf */
		1, 1, 1, 1, 1, 1, 1, 1, /* 0xc0 - 0xc7 */
		1, 1, 1, 1, 1, 1, 1, 1, /* 0xc8 - 0xcf */
		1, 1, 1, 1, 1, 1, 1, 1, /* 0xd0 - 0xd7 */
		1, 1, 1, 1, 1, 1, 1, 1, /* 0xd8 - 0xdf */
		1, 1, 1, 1, 1, 1, 1, 1, /* 0xe0 - 0xe7 */
		1, 1, 1, 1, 1, 1, 1, 1, /* 0xe8 - 0xef */
		0, 0, 0, 1, 1, 1, 1, 1, /* 0xf0 - 0xf7 */
		0, 1, 0, 0, 0, 0, 0, 0, /* 0xf8 - 0xff */
	};

	int id;
	unsigned char *p;
	
	int offset;
	int pts_dts_flag;
	int escr_flag;

	__int64 base;
	__int64 ext;
	__int64 cr;

	if(pes_packet->length < 9){
		return;
	}

	p = pes_packet->data;

	id = p[3];

	if(id < 0xbc){
		return;
	}

	if(!id_table[id-0xbc]){
		return;
	}

	if( (p[6] & 0xc0) == 0x80 ){ /* MPEG-2 */
		pts_dts_flag = p[7] >> 6;
		escr_flag = (p[7] >> 5) & 1;

		offset = 9;

		if(pts_dts_flag == 2){ /* pts only */
			base = (p[offset+0] >> 1) & 7;
			base <<= 8;
			base += p[offset+1];
			base <<= 7;
			base += p[offset+2] >> 1;
			base <<= 8;
			base += p[offset+3];
			base <<= 7;
			base += p[offset+4] >> 1;
			base += (diff / 300);
			p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + ((base >> 30) << 1) + 1);
			p[offset+1] = (unsigned char)((base >> 22) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) << 1) & 0xfe) + 1);
			p[offset+3] = (unsigned char)((base >> 7) & 0xff);
			p[offset+4] = (unsigned char)(((base << 1) & 0xfe) + 1);
			offset += 5;
		}else if(pts_dts_flag == 3){ /* pts and dts */
			base = (p[offset+0] >> 1) & 7;
			base <<= 8;
			base += p[offset+1];
			base <<= 7;
			base += p[offset+2] >> 1;
			base <<= 8;
			base += p[offset+3];
			base <<= 7;
			base += p[offset+4] >> 1;
			base += (diff / 300);
			p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + ((base >> 30) << 1) + 1);
			p[offset+1] = (unsigned char)((base >> 22) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) << 1) & 0xfe) + 1);
			p[offset+3] = (unsigned char)((base >> 7) & 0xff);
			p[offset+4] = (unsigned char)(((base << 1) & 0xfe) + 1);
			offset += 5; /* pts */
			
			base = (p[offset+0] >> 1) & 7;
			base <<= 8;
			base += p[offset+1];
			base <<= 7;
			base += p[offset+2] >> 1;
			base <<= 8;
			base += p[offset+3];
			base <<= 7;
			base += p[offset+4] >> 1;
			base += (diff / 300);
			p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + ((base >> 30) << 1) + 1);
			p[offset+1] = (unsigned char)((base >> 22) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) << 1) & 0xfe) + 1);
			p[offset+3] = (unsigned char)((base >> 7) & 0xff);
			p[offset+4] = (unsigned char)(((base << 1) & 0xfe) + 1);
			offset += 5; /* dts */
		}

		if(escr_flag){
			base = (p[offset+0] >> 3) & 7;
			base <<= 2;
			base += p[offset+0] & 3;
			base <<= 8;
			base += p[offset+1];
			base <<= 5;
			base += (p[offset+2] >> 3) & 0x1f;
			base <<= 2;
			base += p[offset+2] & 3;
			base <<= 8;
			base += p[offset+3];
			base <<= 5;
			base += (p[offset+4] >> 3) & 0x1f;

			ext = p[offset+4] & 3;
			ext <<= 7;
			ext += p[offset+5] >> 1;

			cr = base * 300 + ext;
			cr += diff;

			base = cr / 300;
			ext = cr % 300;
			
			p[offset+0] = (unsigned char)((p[offset+0] & 0xc0) + (((base >> 30) & 7) << 3) + 4 + ((base >> 28) & 3));
			p[offset+1] = (unsigned char)((base >> 20) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) & 0x1f) << 3) + 4 + ((base >> 13) & 3));
			p[offset+3] = (unsigned char)((base >> 5) & 0xff);
			p[offset+4] = (unsigned char)(((base & 0x1f) << 3) + 4 + ((ext >> 7) & 3));
			p[offset+5] = (unsigned char)(((ext & 0x7f) << 1) + 1);
		}
	}else{ /* MPEG-1 */
		offset = 6;
		while(p[offset] == 0xff){
			offset += 1;
		}
		if( (p[offset] & 0xc0) == 0x40 ){
			offset += 2;
		}
		if( (p[offset] & 0xf0) == 0x20 ){
			base = (p[offset+0] >> 1) & 7;
			base <<= 8;
			base += p[offset+1];
			base <<= 7;
			base += (p[offset+2] >> 1) & 0x7f;
			base <<= 8;
			base += p[offset+3];
			base <<= 7;
			base += (p[offset+4] >> 1) & 0x7f;
			cr = base * 300;
			cr += diff;

			base = cr / 300;

			p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + (((base >> 30) & 7) << 1) + 1);
			p[offset+1] = (unsigned char)((base >> 22) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) & 0x7f) << 1) + 1);
			p[offset+3] = (unsigned char)((base >> 7) & 0xff);
			p[offset+2] = (unsigned char)(((base & 0x7f) << 1) + 1);
		}else if( (p[offset] & 0xf0) == 0x30 ){
			base = (p[offset+0] >> 1) & 7;
			base <<= 8;
			base += p[offset+1];
			base <<= 7;
			base += (p[offset+2] >> 1) & 0x7f;
			base <<= 8;
			base += p[offset+3];
			base <<= 7;
			base += (p[offset+4] >> 1) & 0x7f;
			cr = base * 300;
			cr += diff;

			base = cr / 300;

			p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + (((base >> 30) & 7) << 1) + 1);
			p[offset+1] = (unsigned char)((base >> 22) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) & 0x7f) << 1) + 1);
			p[offset+3] = (unsigned char)((base >> 7) & 0xff);
			p[offset+2] = (unsigned char)(((base & 0x7f) << 1) + 1);

			offset += 5;
			
			base = (p[offset+0] >> 1) & 7;
			base <<= 8;
			base += p[offset+1];
			base <<= 7;
			base += (p[offset+2] >> 1) & 0x7f;
			base <<= 8;
			base += p[offset+3];
			base <<= 7;
			base += (p[offset+4] >> 1) & 0x7f;
			cr = base * 300;
			cr += diff;

			base = cr / 300;

			p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + (((base >> 30) & 7) << 1) + 1);
			p[offset+1] = (unsigned char)((base >> 22) & 0xff);
			p[offset+2] = (unsigned char)((((base >> 15) & 0x7f) << 1) + 1);
			p[offset+3] = (unsigned char)((base >> 7) & 0xff);
			p[offset+2] = (unsigned char)(((base & 0x7f) << 1) + 1);
		}
	}
}

static BLOCK *ps_join_stream(PS_PACK *pack, int stream_id)
{
	BLOCK *r;
	BLOCK *p;
	LIST_ELEMENT *packet;

	int space;
	
	if(pack == NULL){
		return NULL;
	}

	r = (BLOCK *)malloc(sizeof(BLOCK));
	if(r == NULL){
		return NULL;
	}

	r->data = NULL;
	r->length = 0;

	space = 0;
	packet = pack->pes_packet;

	while(packet){
		if(packet->data[3] == stream_id){
			space += packet->length;
		}
		packet = (LIST_ELEMENT *)packet->next;
	}

	r->data = (unsigned char *)calloc(space, 1);
	if(r->data == NULL){
		free(r);
		return NULL;
	}

	packet = pack->pes_packet;

	while(packet){
		if(packet->data[3] == stream_id){
			p = ps_get_pes_packet_data(packet);
			if(p == NULL){
				delete_block(r);
				return NULL;
			}
			memcpy(r->data+r->length, p->data, p->length);
			r->length += p->length;
			delete_block(p);
		}
		packet = (LIST_ELEMENT *)packet->next;
	}

	return r;
}

static void ps_update_stream(PS_PACK *pack, int stream_id, BLOCK *data)
{
	LIST_ELEMENT *packet;
	
	if( (pack == NULL) || (data == NULL) ){
		return;
	}

	packet = pack->pes_packet;

	while(packet){
		if(packet->data[3] == stream_id){
			ps_set_pes_packet_data(packet, data);
		}
		packet = (LIST_ELEMENT *)packet->next;
	}
}

static BLOCK *ps_get_pes_packet_data(LIST_ELEMENT *pes_packet)
{
	BLOCK *r;
	int offset;
	int length;
	unsigned char *p;

	if(pes_packet == NULL){
		return NULL;
	}

	if(pes_packet->length < 9){
		return NULL;
	}

	p = pes_packet->data;

	offset = ps_get_pes_packet_header_length(pes_packet);
	length = ps_get_pes_packet_data_length(pes_packet);

	r = new_block(p+offset, length);
	
	return r;
}

static void ps_set_pes_packet_data(LIST_ELEMENT *pes_packet, BLOCK *data)
{
	int length;
	int offset;

	unsigned char *p;

	if(pes_packet == NULL){
		return;
	}

	if(pes_packet->length < 9){
		return;
	}
	p = pes_packet->data;
	
	offset = ps_get_pes_packet_header_length(pes_packet);
	length = ps_get_pes_packet_data_length(pes_packet);

	memcpy(p+offset, data->data, length);

	if(data->length - length){
		memmove(data->data, data->data+length, data->length-length);
		data->length -= length;
	}else{
		free(data->data);
		data->data = NULL;
		data->length = 0;
	}
}

static int ps_get_pes_packet_data_length(LIST_ELEMENT *pes_packet)
{
	if(pes_packet == NULL){
		return 0;
	}

	if(pes_packet->length < 9){
		return 0;
	}

	if(pes_packet->data[3] == 0xbe){ /* padding stream */
		return 0;
	}

	return pes_packet->length - ps_get_pes_packet_header_length(pes_packet);
}

static int ps_get_pes_packet_header_length(LIST_ELEMENT *pes_packet)
{
	int r;
	
	if(pes_packet == NULL){
		return 0;
	}

	if(pes_packet->length < 9){
		return 6;
	}

	if(pes_packet->data[3] == 0xbe){ /* padding stream */
		return 6;
	}

	if( (pes_packet->data[6] & 0xc0) == 0x80 ){ /* MPEG-2 */
		r = 9+pes_packet->data[8];
	}else{ /* MPEG-1 */
		r = 6;
		while(pes_packet->data[r] == 0xff){
			r += 1;
		}
		if( (pes_packet->data[r] & 0xc0) == 0x40 ){
			r += 2;
		}
		if( (pes_packet->data[r] & 0xf0) == 0x20 ) {
			r += 5;
		}else if( (pes_packet->data[r] & 0xf0) == 0x30 ){
			r += 10;
		}else{
			r += 1;
		}
	}
		
	return r;
}

static int ps_proc_video_picture(BLOCK *b1, BLOCK *b2, int old_offset, int new_offset, PS_PROC_VIDEO_OPTION *opt)
{
	int code,n;
	
	if(ps_check_fill_zero_video(opt)){
		ps_fill_zero_video(b1, b2, old_offset, new_offset);
	}

	if(opt->level == PS_LEVEL_FIELD){
		return new_offset+2;
	}else{
		opt->level = PS_LEVEL_PICTURE;
		code = (get_byte_block(b1, b2, new_offset+5) >> 3) & 3;

		opt->picture = code;
		opt->padding = 0;
		if(code == 1){ /* I picture */
			if(opt->step == PS_STEP_START){
				opt->step = PS_STEP_SEEK;
				opt->input_field = 2;
				code = get_byte_block(b1, b2, new_offset+4) << 2;
				code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
				opt->temporal_reference = code;
				if(opt->closed_gop == 0){
					opt->broken_link = 1;
				}else{
					opt->closed_gop = 2;
				}
				n = subtract_temporal_reference(opt->temporal_reference, 0);
				if( opt->in <= n ){
					opt->step = PS_STEP_OUTPUT;
					opt->output = PS_OUTPUT_PACK;
					opt->output_field = 2;
					if(opt->closed_gop){
						opt->temporal_reference -= (n-opt->in);
					}		
					code -= opt->temporal_reference;
					set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
					code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
					set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
					return new_offset+6;
				}
				return new_offset+2;
			}else if(opt->step == PS_STEP_SEEK){
				if(opt->broken_link == 1){
					opt->broken_link = 2;
				}else{
					opt->broken_link = 0;
				}
				if(opt->closed_gop == 1){
					opt->closed_gop = 2;
				}else{
					opt->closed_gop = 0;
				}
				code = get_byte_block(b1, b2, new_offset+4) << 2;
				code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
				n = (opt->input_field+subtract_temporal_reference(code, opt->temporal_reference)*2+1)/2;
				opt->input_field +=2;
				if( opt->in <= n ){
					opt->output = PS_OUTPUT_PACK;
					opt->output_field = 2;
					opt->step = PS_STEP_OUTPUT;
					if(opt->closed_gop){
						opt->temporal_reference = code - (n-opt->in);
					}else{
						opt->temporal_reference = code;
					}
					code -= opt->temporal_reference;
					set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
					code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
					set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
					return new_offset+6;
				}
				opt->temporal_reference = code;
				return new_offset+2;
			}else if(opt->step == PS_STEP_OUTPUT){
				if( (opt->input_field+1)/2 >= opt->out ){
					opt->step = PS_STEP_END;
					set_byte_block(b1, b2, new_offset+3, 0xb7);
					return new_offset+4;
				}
				code = get_byte_block(b1, b2, new_offset+4) << 2;
				code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
				if(opt->broken_link == 1){
					opt->broken_link = 2;
					opt->temporal_reference = code;
				}else{
					opt->broken_link = 0;
				}

				code -= opt->temporal_reference;
				set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
				code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
				set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
				opt->input_field += 2;
				opt->output_field += 2;
				return new_offset+6;
			}else{
				return new_offset+2;
			}
		}else if(code == 2){/* P picture */
			if(opt->step == PS_STEP_SEEK){
				opt->broken_link = 0;
				opt->closed_gop = 0;
				code = get_byte_block(b1, b2, new_offset+4) << 2;
				code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
				opt->temporal_reference = code;
				opt->input_field += 2;
				return new_offset+2;
			}else if(opt->step == PS_STEP_OUTPUT){
				if( (opt->input_field+1)/2 >= opt->out ){
					opt->step = PS_STEP_END;
					set_byte_block(b1, b2, new_offset+3, 0xb7);
					return new_offset+4;
				}
				opt->broken_link = 0;
				opt->closed_gop = 0;
				code = get_byte_block(b1, b2, new_offset+4) << 2;
				code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
				code -= opt->temporal_reference;
				set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
				code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
				set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
				opt->input_field += 2;
				opt->output_field += 2;
				return new_offset+6;
			}else{
				

⌨️ 快捷键说明

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