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

📄 libmpeg3.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "libmpeg3.h"
#include "mpeg3protos.h"

#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif

mpeg3_t* mpeg3_new(const char *path)
{
	int i;
	mpeg3_t *file = calloc(1, sizeof(mpeg3_t));
	file->cpus = 1;
	file->fs = mpeg3_new_fs(path);
	file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
	file->seekable = 1;
	return file;
}

int mpeg3_delete(mpeg3_t *file)
{
	int i;

	for(i = 0; i < file->total_vstreams; i++)
		mpeg3_delete_vtrack(file, file->vtrack[i]);

	for(i = 0; i < file->total_astreams; i++)
		mpeg3_delete_atrack(file, file->atrack[i]);

	mpeg3_delete_fs(file->fs);
	mpeg3_delete_demuxer(file->demuxer);

	if(file->frame_offsets)
	{
		for(i = 0; i < file->total_vstreams; i++)
		{
			free(file->frame_offsets[i]);
			free(file->keyframe_numbers[i]);
		}

		free(file->frame_offsets);
		free(file->keyframe_numbers);
		free(file->total_frame_offsets);
		free(file->total_keyframe_numbers);
	}

	if(file->sample_offsets)
	{
		for(i = 0; i < file->total_astreams; i++)
			free(file->sample_offsets[i]);

		free(file->sample_offsets);
		free(file->total_sample_offsets);
	}

	free(file);
	return 0;
}

int mpeg3_check_sig(const char *path)
{
	mpeg3_fs_t *fs;
	u_int32_t bits;
	char *ext;
	int result = 0;

	fs = mpeg3_new_fs(path);
	if(mpeg3io_open_file(fs))
	{
/* File not found */
		return 0;
	}

	bits = mpeg3io_read_int32(fs);
/* Test header */
	if(bits == MPEG3_TOC_PREFIX)
	{
		result = 1;
	}
	else
	if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
		(bits == MPEG3_PACK_START_CODE) ||
		((bits & 0xfff00000) == 0xfff00000) ||
		((bits & 0xffff0000) == 0xffe30000) ||
		(bits == MPEG3_SEQUENCE_START_CODE) ||
		(bits == MPEG3_PICTURE_START_CODE) ||
		(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
		((bits >> 8) == MPEG3_ID3_PREFIX) ||
		(bits == MPEG3_RIFF_CODE) ||
        (bits == MPEG3_IFO_PREFIX))
	{
		result = 1;

		ext = strrchr(path, '.');
		if(ext)
		{
/* Test file extension. */
			if(strncasecmp(ext, ".ifo", 4) && 
            	strncasecmp(ext, ".mp2", 4) && 
				strncasecmp(ext, ".mp3", 4) &&
				strncasecmp(ext, ".m1v", 4) &&
				strncasecmp(ext, ".m2v", 4) &&
				strncasecmp(ext, ".m2s", 4) &&
				strncasecmp(ext, ".mpg", 4) &&
				strncasecmp(ext, ".vob", 4) &&
				strncasecmp(ext, ".mpeg", 4) &&
				strncasecmp(ext, ".ac3", 4))
				result = 0;
		}
	}

	mpeg3io_close_file(fs);
	mpeg3_delete_fs(fs);
	return result;
}


static uint32_t read_int32(unsigned char *buffer, int *position)
{
	uint32_t temp;

	if(MPEG3_LITTLE_ENDIAN)
	{
		((unsigned char*)&temp)[3] = buffer[(*position)++];
		((unsigned char*)&temp)[2] = buffer[(*position)++];
		((unsigned char*)&temp)[1] = buffer[(*position)++];
		((unsigned char*)&temp)[0] = buffer[(*position)++];
	}
	else
	{
		((unsigned char*)&temp)[0] = buffer[(*position)++];
		((unsigned char*)&temp)[1] = buffer[(*position)++];
		((unsigned char*)&temp)[2] = buffer[(*position)++];
		((unsigned char*)&temp)[3] = buffer[(*position)++];
	}
	
	return temp;
}

static uint64_t read_int64(unsigned char *buffer, int *position)
{
	uint64_t temp;

	if(MPEG3_LITTLE_ENDIAN)
	{
		((unsigned char*)&temp)[7] = buffer[(*position)++];
		((unsigned char*)&temp)[6] = buffer[(*position)++];
		((unsigned char*)&temp)[5] = buffer[(*position)++];
		((unsigned char*)&temp)[4] = buffer[(*position)++];
		((unsigned char*)&temp)[3] = buffer[(*position)++];
		((unsigned char*)&temp)[2] = buffer[(*position)++];
		((unsigned char*)&temp)[1] = buffer[(*position)++];
		((unsigned char*)&temp)[0] = buffer[(*position)++];
	}
	else
	{
		((unsigned char*)&temp)[0] = buffer[(*position)++];
		((unsigned char*)&temp)[1] = buffer[(*position)++];
		((unsigned char*)&temp)[2] = buffer[(*position)++];
		((unsigned char*)&temp)[3] = buffer[(*position)++];
		((unsigned char*)&temp)[4] = buffer[(*position)++];
		((unsigned char*)&temp)[5] = buffer[(*position)++];
		((unsigned char*)&temp)[6] = buffer[(*position)++];
		((unsigned char*)&temp)[7] = buffer[(*position)++];
	}

	return temp;
}






static int read_toc(mpeg3_t *file)
{
	unsigned char *buffer;
	int file_type;
	int position = 4;
	int stream_type;
	int atracks;
	int vtracks;
	int i, j;

	buffer = malloc(mpeg3io_total_bytes(file->fs));
	mpeg3io_seek(file->fs, 0);
	mpeg3io_read_data(buffer, mpeg3io_total_bytes(file->fs), file->fs);


//printf("read_toc %lld\n", mpeg3io_total_bytes(file->fs));

// File type
	file_type = buffer[position++];
	switch(file_type)
	{
		case FILE_TYPE_PROGRAM:
			file->is_program_stream = 1;
			break;
		case FILE_TYPE_TRANSPORT:
			file->is_transport_stream = 1;
			break;
		case FILE_TYPE_AUDIO:
			file->is_audio_stream = 1;
			break;
		case FILE_TYPE_VIDEO:
			file->is_video_stream = 1;
			break;
	}


// Stream ID's
	while((stream_type = buffer[position]) != TITLE_PATH)
	{
		int offset;
		int stream_id;

//printf("read_toc %d %x\n", position, buffer[position]);
		position++;
		offset = read_int32(buffer, &position);
		stream_id = read_int32(buffer, &position);

		if(stream_type == STREAM_AUDIO)
		{
			file->demuxer->astream_table[offset] = stream_id;
		}

		if(stream_type == STREAM_VIDEO)
		{
			file->demuxer->vstream_table[offset] = stream_id;
		}
	}





// Titles
	while(buffer[position] == TITLE_PATH)
	{
		char string[MPEG3_STRLEN];
		int string_len = 0;
		mpeg3_title_t *title;

		position++;
		while(buffer[position] != 0) string[string_len++] = buffer[position++];
		string[string_len++] = 0;
		position++;

		title = 
			file->demuxer->titles[file->demuxer->total_titles++] = 
			mpeg3_new_title(file, string);

		title->total_bytes = read_int64(buffer, &position);

// Cells
		title->timecode_table_size = 
			title->timecode_table_allocation = 
			read_int32(buffer, &position);
		title->timecode_table = calloc(title->timecode_table_size, sizeof(mpeg3demux_timecode_t));
		for(i = 0; i < title->timecode_table_size; i++)
		{
			title->timecode_table[i].start_byte = read_int64(buffer, &position);
			title->timecode_table[i].end_byte = read_int64(buffer, &position);
			title->timecode_table[i].program = read_int32(buffer, &position);
		}
	}



// Audio streams
// Skip ATRACK_COUNT
	position++;
	atracks = read_int32(buffer, &position);

// Skip VTRACK_COUNT
	position++;
	vtracks = read_int32(buffer, &position);


	if(atracks)
	{
		file->sample_offsets = malloc(sizeof(int64_t*) * atracks);
		file->total_sample_offsets = malloc(sizeof(int*) * atracks);

		for(i = 0; i < atracks; i++)
		{
			file->total_sample_offsets[i] = read_int32(buffer, &position);
			file->sample_offsets[i] = malloc(file->total_sample_offsets[i] * sizeof(int64_t));
			for(j = 0; j < file->total_sample_offsets[i]; j++)
			{
				file->sample_offsets[i][j] = read_int64(buffer, &position);
//printf("samples %llx\n", file->sample_offsets[i][j]);
			}
		}
	}

	if(vtracks)
	{
		file->frame_offsets = malloc(sizeof(int64_t*) * vtracks);
		file->total_frame_offsets = malloc(sizeof(int*) * vtracks);
		file->keyframe_numbers = malloc(sizeof(int64_t*) * vtracks);
		file->total_keyframe_numbers = malloc(sizeof(int*) * vtracks);

		for(i = 0; i < vtracks; i++)
		{
			file->total_frame_offsets[i] = read_int32(buffer, &position);
			file->frame_offsets[i] = malloc(file->total_frame_offsets[i] * sizeof(int64_t));
			for(j = 0; j < file->total_frame_offsets[i]; j++)
			{
				file->frame_offsets[i][j] = read_int64(buffer, &position);
//printf("frame %llx\n", file->frame_offsets[i][j]);
			}


			file->total_keyframe_numbers[i] = read_int32(buffer, &position);
			file->keyframe_numbers[i] = malloc(file->total_keyframe_numbers[i] * sizeof(int64_t));
			for(j = 0; j < file->total_keyframe_numbers[i]; j++)
			{
				file->keyframe_numbers[i][j] = read_int64(buffer, &position);
			}
		}
	}

	free(buffer);



//printf("read_toc 1\n");
	mpeg3demux_open_title(file->demuxer, 0);

//printf("read_toc 2 %llx\n", mpeg3demux_tell(file->demuxer));
	return 0;
}




mpeg3_t* mpeg3_open_copy(const char *path, mpeg3_t *old_file)
{
	mpeg3_t *file = 0;
	unsigned int bits;
	int i, done;

/* Initialize the file structure */
	file = mpeg3_new(path);







//printf("mpeg3_open_copy %s\n", path);

/* Need to perform authentication before reading a single byte. */
	if(mpeg3io_open_file(file->fs))
	{
		mpeg3_delete(file);
		return 0;
	}













/* =============================== Create the title objects ========================= */
	bits = mpeg3io_read_int32(file->fs);
//printf("mpeg3_open 1 %p %d %d %d %d\n", old_file, file->is_transport_stream, file->is_program_stream, file->is_video_stream, file->is_audio_stream);

	if(bits == MPEG3_TOC_PREFIX)   /* TOC  */
	{
/* Table of contents for another title set */
		if(!old_file)
		{
//printf("libmpeg3 1\n");
			if(read_toc(file))
			{
//printf("libmpeg3 1\n");
				mpeg3io_close_file(file->fs);
				mpeg3_delete(file);
				return 0;
			}
//printf("libmpeg3 1\n");
		}
		mpeg3io_close_file(file->fs);
	}
	else
// IFO file
#ifndef _WIN32
    if(bits == MPEG3_IFO_PREFIX)
    {
//printf("libmpeg3 1\n");
    	if(!old_file)
		{
//printf("libmpeg3 2\n");
			if(mpeg3_read_ifo(file, 0))
        	{
				mpeg3_delete(file);
				mpeg3io_close_file(file->fs);
				return 0;
        	}
//printf("libmpeg3 3\n");
		}
		file->is_ifo_file = 1;
		mpeg3io_close_file(file->fs);
    }
    else
#endif
	if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
	{
/* Transport stream */
//printf("libmpeg3 2\n");
		file->is_transport_stream = 1;
	}
	else
	if(bits == MPEG3_PACK_START_CODE)
	{
/* Program stream */
/* Determine packet size empirically */
//printf("libmpeg3 3\n");
		file->is_program_stream = 1;
	}
	else
	if((bits & 0xfff00000) == 0xfff00000 ||
		(bits & 0xffff0000) == 0xffe30000 ||
		((bits >> 8) == MPEG3_ID3_PREFIX) ||
		(bits == MPEG3_RIFF_CODE))
	{
/* MPEG Audio only */
//printf("libmpeg3 4\n");
		file->is_audio_stream = 1;
	}
	else
	if(bits == MPEG3_SEQUENCE_START_CODE ||
		bits == MPEG3_PICTURE_START_CODE)

⌨️ 快捷键说明

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