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

📄 mpeg3demux.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 4 页
字号:

			if(demuxer->current_timecode >= title->timecode_table_size)
			{
				demuxer->current_timecode = 0;
				if(demuxer->current_title + 1 < demuxer->total_titles)
				{
					mpeg3demux_open_title(demuxer, ++demuxer->current_title);
					do_seek = 1;
				}
				else
				{
					mpeg3io_seek(title->fs, mpeg3io_total_bytes(title->fs));
			 		result = 1;
				}
			}


			title = demuxer->titles[demuxer->current_title];
		}





//if(last_timecode != demuxer->current_timecode && demuxer->do_video)
//	printf("using title %d cell %x-%x\n", demuxer->current_title, title->timecode_table[demuxer->current_timecode].start_byte, title->timecode_table[demuxer->current_timecode].end_byte);

//printf("2 %d\n", title->timecode_table[demuxer->current_timecode].program);





		if(!result && do_seek)
		{
//printf("current_cell=%d\n", demuxer->current_timecode);
			mpeg3io_seek(title->fs, 
				title->timecode_table[demuxer->current_timecode].start_byte);
		}
	}
	else
	{










/* Get the previous timecode */
		while(!result && 
			(mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte ||
				demuxer->current_program != title->timecode_table[demuxer->current_timecode].program))
		{
/*
 * printf("mpeg3_reverse_timecode %d %d %d %d\n", 
 * 	mpeg3io_tell(title->fs), 
 * 	demuxer->current_timecode,
 * 	title->timecode_table[demuxer->current_timecode].start_byte,
 *  title->timecode_table[demuxer->current_timecode].end_byte);
 */

			demuxer->current_timecode--;
			if(demuxer->current_timecode < 0)
			{
				if(demuxer->current_title > 0)
				{
//printf("advance_timecode 2 %d\n", demuxer->current_title);
					mpeg3demux_open_title(demuxer, --demuxer->current_title);
					title = demuxer->titles[demuxer->current_title];
// Seek to end since we opened at the beginning of the next title
					mpeg3io_seek(title->fs, title->total_bytes);
//printf("advance_timecode 3 %d %d\n", demuxer->current_title, mpeg3io_tell(title->fs));
					demuxer->current_timecode = title->timecode_table_size - 1;
					do_seek = 1;
				}
				else
				{
					mpeg3io_seek(title->fs, 0);
					demuxer->current_timecode = 0;
					result = 1;
				}
			}
		}







		if(!result && do_seek)
		{
			mpeg3io_seek(title->fs, 
				title->timecode_table[demuxer->current_timecode].start_byte);
		}




	}

//printf("mpeg3_advance_timecode 2 %d\n", demuxer->current_title);fflush(stdout);
	return result;
}














/* Read packet in the forward direction */
int mpeg3_read_next_packet(mpeg3_demuxer_t *demuxer)
{
	int result = 0;
	long current_position;
	mpeg3_t *file = demuxer->file;
	mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
	demuxer->data_size = 0;
	demuxer->data_position = 0;

//printf("mpeg3_read_next_packet 1 %d %llx\n", demuxer->current_title, mpeg3io_tell(title->fs));
/* Switch to forward direction. */
	if(demuxer->reverse)
	{
		if(file->packet_size > 0)
		{
			if(!result) result = mpeg3io_seek_relative(title->fs, file->packet_size);
		}
		else
		{
			if(!result) result = mpeg3io_next_code(title->fs, MPEG3_PACK_START_CODE, MPEG3_RAW_SIZE);
			if(!result) result = mpeg3io_next_code(title->fs, MPEG3_PACK_START_CODE, MPEG3_RAW_SIZE);
		}

		demuxer->reverse = 0;
	}
//printf("mpeg3_read_next_packet 4 %d\n", result);








/* Read packets until the output buffer is full */
	if(!result)
	{
		do
		{
			result = mpeg3_advance_timecode(demuxer);

			if(!result)
			{
				demuxer->time_offset = lookup_time_offset(demuxer, mpeg3io_tell(title->fs));

				if(file->is_transport_stream)
				{
//printf("mpeg3_read_next_packet: 1 %f\n", demuxer->time);
					result = read_transport(demuxer);
//printf("mpeg3_read_next_packet: 2 %f\n", demuxer->time);
				}
				else
				if(file->is_program_stream)
				{
					result = mpeg3demux_read_program(demuxer);
				}
				else
				{
/* Read elementary stream. */
//printf("mpeg3_read_next_packet: 3\n");
					result = mpeg3io_read_data(demuxer->data_buffer, 
						file->packet_size, title->fs);
					if(!result) demuxer->data_size = file->packet_size;
				}
			}
//printf("mpeg3_read_next_packet 2 %x %lx\n", demuxer->data_size, mpeg3io_tell(title->fs));
		}while(!result && 
			demuxer->data_size == 0 && 
			(demuxer->do_audio || demuxer->do_video));
	}

//printf("mpeg3_read_next_packet 4 %d\n", result);
	return result;
}
















/* Read the packet right before the packet we're currently on. */
int mpeg3_read_prev_packet(mpeg3_demuxer_t *demuxer)
{
	int result = 0;
	mpeg3_t *file = demuxer->file;
	long current_position;
	mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
	demuxer->data_size = 0;
	demuxer->data_position = 0;







//printf("mpeg3_read_prev_packet 1 %x %x\n", title->fs->current_byte, title->fs->buffer_position);
/* Switch to reverse direction */
	if(!demuxer->reverse)
	{
		if(file->packet_size > 0)
		{
			result = mpeg3io_seek_relative(title->fs, -file->packet_size);
		}
		else
		{
			result = mpeg3io_prev_code(title->fs, MPEG3_PACK_START_CODE, MPEG3_RAW_SIZE);
		}

		demuxer->reverse = 1;
	}





//printf("mpeg3_read_prev_packet 2 %x %x\n", title->fs->current_byte, title->fs->buffer_position);


	do
	{
// Go to beginning of previous packet

		if(file->packet_size > 0)
		{
			if(!result) result = mpeg3io_seek_relative(title->fs, -file->packet_size);
		}
		else
		{
			if(!result) result = mpeg3io_prev_code(title->fs, MPEG3_PACK_START_CODE, MPEG3_RAW_SIZE);
		}

//printf("mpeg3_read_prev_packet 3 %x %x\n", title->fs->current_byte, title->fs->buffer_position);
		if(!result) result = mpeg3_advance_timecode(demuxer);

//printf("mpeg3_read_prev_packet 2 %p->%p->%p\n", title, title->fs, title->fs->fd);
		if(!result) demuxer->time_offset = lookup_time_offset(demuxer, mpeg3io_tell(title->fs));

// Read packet and then rewind it
		if(file->is_transport_stream && !result)
		{
			result = read_transport(demuxer);

			if(!mpeg3io_bof(title->fs))
			{
				result = mpeg3io_seek_relative(title->fs, -file->packet_size);
			}
//printf("mpeg3_read_prev_packet 4 %x %x\n", title->fs->current_byte, title->fs->buffer_position);
		}
		else
		if(file->is_program_stream && !result)
		{
			result = mpeg3demux_read_program(demuxer);
//printf("mpeg3_read_prev_packet 4 %x %x\n", title->fs->current_byte);
			if(!mpeg3io_bof(title->fs))
				result = mpeg3io_prev_code(title->fs, MPEG3_PACK_START_CODE, MPEG3_RAW_SIZE);
//printf("mpeg3_read_prev_packet 5 %x %x\n", title->fs->current_byte);
		}
		else
		if(!result)
		{
/* Elementary stream */
/* Read the packet forwards and seek back to the start */
			result = mpeg3io_read_data(demuxer->data_buffer, 
				file->packet_size, 
				title->fs);

			if(!result) 
			{
				demuxer->data_size = file->packet_size;
				result = mpeg3io_seek_relative(title->fs, -file->packet_size);
			}
		}
	}while(!result && 
		demuxer->data_size == 0 && 
		(demuxer->do_audio || demuxer->do_video));


//printf("mpeg3_read_prev_packet 4 %x %x\n", title->fs->current_byte, title->fs->buffer_position);
	return result;
}


/* For audio */
int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer, 
		unsigned char *output, 
		long size)
{
	long i;
	int result = 0;
	mpeg3_t *file = demuxer->file;
	demuxer->error_flag = 0;
	
	if(demuxer->data_position >= 0)
	{
/* Read forwards */
		for(i = 0; i < size && !result; )
		{
			int fragment_size = size - i;
			if(fragment_size > demuxer->data_size - demuxer->data_position)
				fragment_size = demuxer->data_size - demuxer->data_position;
			memcpy(output + i, demuxer->data_buffer + demuxer->data_position, fragment_size);
			demuxer->data_position += fragment_size;
			i += fragment_size;

			if(i < size)
			{
				result = mpeg3_read_next_packet(demuxer);
			}
		}
		return i;
	}
	else
	{
/* Read backwards a full packet. */
/* Only good for reading less than the size of a full packet, but */
/* this routine should only be used for searching for previous markers. */
		long current_position = demuxer->data_position;
		result = mpeg3_read_prev_packet(demuxer);
		if(!result) demuxer->data_position = demuxer->data_size + current_position;
		memcpy(output, demuxer->data_buffer + demuxer->data_position, size);
		demuxer->data_position += size;
	}

	demuxer->error_flag = result;
	return result;
}

unsigned char mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer)
{
	demuxer->error_flag = 0;

	if(demuxer->data_position >= demuxer->data_size)
		demuxer->error_flag = mpeg3_read_next_packet(demuxer);
	demuxer->next_char = demuxer->data_buffer[demuxer->data_position++];

	return demuxer->next_char;
}

unsigned char mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer)
{
	demuxer->error_flag = 0;
	demuxer->data_position--;
	if(demuxer->data_position < 0)
	{
//printf("mpeg3demux_read_prev_char_packet 1\n");
		demuxer->error_flag = mpeg3_read_prev_packet(demuxer);
//printf("mpeg3demux_read_prev_char_packet 2\n");
		if(!demuxer->error_flag) demuxer->data_position = demuxer->data_size - 1;
	}
	demuxer->next_char = demuxer->data_buffer[demuxer->data_position];
	return demuxer->next_char;
}

static mpeg3demux_timecode_t* next_timecode(mpeg3_demuxer_t *demuxer, 
		int *current_title, 
		int *current_timecode,
		int current_program)
{
	int done = 0;
	while(!done)
	{
/* Increase timecode number */
		if(*current_timecode < demuxer->titles[*current_title]->timecode_table_size - 1) 
		{
			(*current_timecode)++;
			if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
				return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
		}
		else
/* Increase title number */
		if(*current_title < demuxer->total_titles - 1)
		{
			(*current_title)++;
			(*current_timecode) = 0;
			if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
				return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
		}
		else
/* End of disk */
			done = 1;
	}
	return 0;
}

static mpeg3demux_timecode_t* prev_timecode(mpeg3_demuxer_t *demuxer, 
		int *current_title, 
		int *current_timecode,
		int current_program)
{
	int done = 0;
	while(!done)
	{
/* Increase timecode number */
		if(*current_timecode > 0)
		{
			(*current_timecode)--;
			if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
				return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
		}
		else
/* Increase title number */
		if(*current_title > 0)
		{
			(*current_title)--;
			(*current_timecode) = demuxer->titles[*current_title]->timecode_table_size - 1;
			if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
				return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
		}
		else
/* End of disk */
			done = 1;
		
	}
	return 0;
}

int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number)
{
	mpeg3_title_t *title;

//printf("mpeg3demux_open_title 1\n");
	if(title_number < demuxer->total_titles)
	{
		if(demuxer->current_title >= 0)
		{
			mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs);
			demuxer->current_title = -1;
		}

//printf("mpeg3demux_open_title %p %p %d\n", demuxer, demuxer->titles, title_number);
		title = demuxer->titles[title_number];

		if(mpeg3io_open_file(title->fs))
		{
			demuxer->error_flag = 1;
			fprintf(stderr, "mpeg3demux_open_title %s: %s", title->fs->path, strerror(errno));
		}
		else
		{
			demuxer->current_title = title_number;
		}
	}

//printf("mpeg3demux_open_title 2\n");
//	demuxer->current_timecode = 0;

	return demuxer->error_flag;
}

/* Assign program numbers to interleaved programs */
int mpeg3demux_assign_programs(mpeg3_demuxer_t *demuxer)
{
	int current_program = 0;
	int current_title = 0;
	int current_timecode = 0;
	double current_time;
	mpeg3demux_timecode_t *timecode;
	int total_programs = 1;
	int i, j;
	int program_exists, last_program_assigned = 0;
	int total_timecodes;
	mpeg3_title_t **titles = demuxer->titles;

	for(i = 0, total_timecodes = 0; i < demuxer->total_titles; i++)
	{
		total_timecodes += demuxer->titles[i]->timecode_table_size;
		for(j = 0; j < demuxer->titles[i]->timecode_table_size; j++)
		{
			timecode = &demuxer->titles[i]->timecode_table[j];
			if(timecode->program > total_programs - 1)
				total_programs = timecode->program + 1;
		}
	}

/* Assign absolute timecodes in each program. */
	for(current_program = 0; 
		current_program < total_programs; 
		current_program++)
	{
		current_time = 0;
		current_title = 0;

⌨️ 快捷键说明

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