📄 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 + -