📄 mpeg3demux.c
字号:
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 + -