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

📄 program_stream.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
字号:
/*******************************************************************
                 Program Stream treating module
 *******************************************************************/

#include <stdlib.h>
#include <string.h>
#include "pes.h"
#include "bitstream.h"
#include "registry.h"

#define PROGRAM_STREAM_C
#include "program_stream.h"

#define MAX_PACKET_DATA_LENGTH 65536

typedef struct {
	
	BITSTREAM      *bs;
	PES_STREAM_TYPE type;

	unsigned char   buffer[MAX_PACKET_DATA_LENGTH];
	unsigned char  *current;

	unsigned int    data_rest;
	int             packet_start_code;

	PTS_DTS         current_pts_dts;
} PROGRAM_STREAM;

int ps_open(const char *filename, int stream_type);
int ps_close(int in);
int ps_read(int in, void *data, unsigned int count);
__int64 ps_seek(int in, __int64 offset, int origin);
__int64 ps_tell(int in);

static int read_pes_packet(BITSTREAM *in, PES_PACKET *out);
static int check_ps(BITSTREAM *in);

int ps_open(const char *filename, int stream_type)
{
	PROGRAM_STREAM *ps;
	PES_PACKET packet;
	PES_STREAM_TYPE type;

	init_pes_packet(&packet);

	ps = (PROGRAM_STREAM *)calloc(1, sizeof(PROGRAM_STREAM));
	if(ps == NULL){
		return -1;
	}
	
	ps->bs = bs_open(filename);
	if(ps->bs == NULL){
		free(ps);
		return -1;
	}

	if(!check_ps(ps->bs)){
		bs_close(ps->bs);
		return -1;
	}

	ps->type.type = stream_type;

	while(read_pes_packet(ps->bs, &packet)){
		if(extract_pes_stream_type(&packet, &type)){
			if(type.type == ps->type.type){
				ps->type.id = type.id;
				bs_seek(ps->bs, 0, SEEK_SET);
				ps->packet_start_code = 0x100 + packet.stream_id;
				release_pes_packet(&packet);
				return (int)ps;
			}
		}
	}

	bs_close(ps->bs);
	free(ps);
	release_pes_packet(&packet);
	
	return -1;
}

int  ps_close(int in)
{
	PROGRAM_STREAM *ps;

	ps = (PROGRAM_STREAM *)in;

	if(ps){
		if(ps->bs){
			bs_close(ps->bs);
		}
		free(ps);
	}

	return 1;
}

int  ps_read(int in, void *data, unsigned int count)
{
	int r;
	
	PROGRAM_STREAM *ps;
	PES_PACKET packet;
	PES_STREAM_TYPE type;

	ps = (PROGRAM_STREAM *)in;
	init_pes_packet(&packet);
	
	if(ps->data_rest){
		if(ps->data_rest <= count){
			memcpy(data, ps->current, ps->data_rest);
			r = ps->data_rest;
			ps->data_rest = 0;
			
			release_pes_packet(&packet);
			return r;
		}else{
			memcpy(data, ps->current, count);
			ps->data_rest -= count;
			ps->current += count;
			
			release_pes_packet(&packet);
			return count;
		}
	}

	while(read_pes_packet(ps->bs, &packet) ){
		if( extract_pes_stream_type(&packet, &type) ){
			if( (type.type == ps->type.type) && (type.id == ps->type.id) ){
				extract_pes_packet_data(&packet, ps->buffer, &(ps->data_rest) );
				if(ps->data_rest == 0){
					continue;
				}else if(ps->data_rest <= count){
					memcpy(data, ps->buffer, ps->data_rest);
					r = ps->data_rest;
					ps->data_rest = 0;
					
					release_pes_packet(&packet);
					return r;
				}else{
					memcpy(data, ps->buffer, count);
					ps->data_rest -= count;
					ps->current = ps->buffer + count;
					
					release_pes_packet(&packet);
					return count;
				}
			}
		}
	}
	
					
	release_pes_packet(&packet);
	return 0;
}

__int64  ps_seek(int in, __int64 offset, int origin)
{
	__int64 n,m;
	PROGRAM_STREAM *ps;
	PES_PACKET      packet;
	PES_STREAM_TYPE type;
	
	ps = (PROGRAM_STREAM *)in;
	init_pes_packet(&packet);

	n = bs_seek(ps->bs, offset, origin);

	while(bs_prev_packet_prefix(ps->bs)){
		if( bs_read_bits(ps->bs, 32) == ps->packet_start_code ){
			read_pes_packet(ps->bs, &packet);
			extract_pes_stream_type(&packet, &type);
			if(! ( type.type == ps->type.type && type.id == ps->type.id) ){
				break;
			}
			m = bs_tell(ps->bs);
			if( m < n ){
				break;
			}
				
			extract_pes_packet_data(&packet, ps->buffer, &(ps->data_rest));
			ps->current = ps->buffer + (ps->data_rest - (m - n));
			ps->data_rest = (unsigned int) (m - n);
			
			release_pes_packet(&packet);
			return ps_tell(in);
		}else{
			ps->bs->current -= 4;
		}
	}

	while( read_pes_packet(ps->bs, &packet) ){
		if( extract_pes_stream_type(&packet, &type) ){
			if( (type.type == ps->type.type) && (type.id == ps->type.id) ){
				extract_pes_packet_data(&packet, ps->buffer, &(ps->data_rest));
				ps->current = ps->buffer;
				break;
			}
		}
	}

	release_pes_packet(&packet);
	return ps_tell(in);
}

__int64  ps_tell(int in)
{
	__int64 r;

	PROGRAM_STREAM *ps;

	
	ps = (PROGRAM_STREAM *)in;

	r = bs_tell(ps->bs);
	r -= ps->data_rest;

	return r;
}

static int read_pes_packet(BITSTREAM *in, PES_PACKET *out)
{
	int code, n, m;
	unsigned char buf[6];
	
	do{
		if(! bs_next_packet_prefix(in)){
			return 0;
		}

		code = bs_get_bits(in, 32);
		
	}while(code < 0x1bc);

	release_pes_packet(out);
	buf[0] = 0;
	buf[1] = 0;
	buf[2] = 1;
	buf[3] = (unsigned char)( code & 0xff );

	n = bs_get_bits(in, 16);
	buf[4] = (unsigned char)( (n >> 8) & 0xff );
	buf[5] = (unsigned char)( n & 0xff );
	
	append_pes_packet_data(out, buf, sizeof(buf));
	while(n){
		m = bs_read(in, out->data+out->size, n);
		n -= m;
		out->size += m;
		if(m == 0){
			return 0;
		}
	}
	return out->size;
}

static int check_ps(BITSTREAM *in)
{
	int limit;

	limit = get_filecheck_limit();
	while(bs_next_packet_prefix(in)){
		if(bs_get_bits(in, 32) > 0x1b8){
			bs_seek(in, 0, SEEK_SET);
			return 1;
		}
		if(limit < bs_tell(in)){
			break;
		}
	}

	return 0;
}

⌨️ 快捷键说明

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