/* If toc is 0 just read the first and last timecode. */ int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc) { int result = 0, done = 0, counter_start, counter; mpeg3_t *file = demuxer->file; long next_byte, prev_byte; double next_time, prev_time, absolute_time; long i; mpeg3_title_t *title; u_int32_t test_header = 0; mpeg3demux_timecode_t *timecode = 0; demuxer->error_flag = 0; demuxer->read_all = 1; /* Create a single title */ if(!demuxer->total_titles) { demuxer->titles[0] = mpeg3_new_title(file, file->fs->path); demuxer->total_titles = 1; mpeg3demux_open_title(demuxer, 0); } title = demuxer->titles[0]; title->total_bytes = mpeg3io_total_bytes(title->fs); /* Get the packet size from the file */ if(file->is_program_stream) { mpeg3io_seek(title->fs, 4); for(i = 0; i < MPEG3_MAX_PACKSIZE && test_header != MPEG3_PACK_START_CODE; i++) { test_header <<= 8; test_header |= mpeg3io_read_char(title->fs); } if(i < MPEG3_MAX_PACKSIZE) demuxer->packet_size = i; if(i < MPEG3_DVD_PACKET_SIZE) demuxer->packet_size = 4096; mpeg3io_seek(title->fs, 0); } else demuxer->packet_size = file->packet_size; /* Get timecodes for the title */ if(file->is_transport_stream || file->is_program_stream) { mpeg3io_seek(title->fs, 0); while(!done && !result && !mpeg3io_eof(title->fs)) { next_byte = mpeg3io_tell(title->fs); result = mpeg3_read_next_packet(demuxer); if(!result) { next_time = demuxer->time; //printf("%f %f\n", next_time, prev_time); if(next_time < prev_time || next_time - prev_time > MPEG3_CONTIGUOUS_THRESHOLD || !title->timecode_table_size) { /* Discontinuous */ timecode = mpeg3_append_timecode(demuxer, title, prev_byte, prev_time, next_byte, next_time, 0, 0); /* * printf("timecode: %ld %ld %f %f\n", * timecode->start_byte, * timecode->end_byte, * timecode->start_time, * timecode->end_time); */ counter_start = next_time; } prev_time = next_time; prev_byte = next_byte; counter = next_time; } /* Just get the first bytes if not building a toc to get the stream ID's. */ if(next_byte > 0x100000 && (!timecode_search || !toc)) done = 1; } /* Get the last timecode */ if(!toc || !timecode_search) { demuxer->read_all = 0; result = mpeg3io_seek(title->fs, title->total_bytes); if(!result) result = mpeg3_read_prev_packet(demuxer); } if(title->timecode_table && timecode) { timecode->end_byte = title->total_bytes; // timecode->end_byte = mpeg3io_tell(title->fs)/* + demuxer->packet_size */; timecode->end_time = demuxer->time; timecode->absolute_end_time = timecode->end_time - timecode->start_time; } } mpeg3io_seek(title->fs, 0); demuxer->read_all = 0; return 0; }
/* Read the title information from a toc */ static int read_titles(mpeg3_demuxer_t *demuxer, int version) { char string1[MPEG3_STRLEN], string2[MPEG3_STRLEN]; long start_byte, end_byte; double start_time, end_time; float program; mpeg3_title_t *title = 0; mpeg3_t *file = demuxer->file; // Eventually use IFO file to generate titles while(!feof(file->fs->fd)) { char string[1024]; int i = 0, byte; // Scanf is broken for single word lines do{ byte = fgetc(file->fs->fd); if(byte != 0 && byte != 0xd && byte != 0xa) string[i++] = byte; }while(byte != 0xd && byte != 0xa && !feof(file->fs->fd) && i < 1023); string[i] = 0; if(strlen(string)) { sscanf(string, "%s %s %ld %lf %lf %f", string1, string2, &end_byte, &start_time, &end_time, &program); //printf("read_titles 2 %d %s %s %ld %f %f %f\n", strlen(string), string1, string2, end_byte, start_time, end_time, program); if(!strncasecmp(string1, "PATH:", 5)) { //printf("read_titles 2\n"); title = demuxer->titles[demuxer->total_titles++] = mpeg3_new_title(file, string2); } else if(!strcasecmp(string1, "PROGRAM_STREAM")) { //printf("read_titles 3\n"); file->is_program_stream = 1; } else if(!strcasecmp(string1, "TRANSPORT_STREAM")) { //printf("read_titles 4\n"); file->is_transport_stream = 1; } else if(title) { mpeg3demux_cell_t *timecode; start_byte = atol(string2); //printf("read_titles 5\n"); if(!strcasecmp(string1, "REGION:")) { timecode = mpeg3_append_timecode(demuxer, title, 0, 0, 0, 0, 1, 0); //printf("mpeg3toc2 3\n"); timecode->start_byte = start_byte; //printf("mpeg3toc2 4\n"); timecode->end_byte = end_byte; timecode->start_time = start_time; timecode->end_time = end_time; timecode->program = program; /* * printf("read_title %p end: %f start: %f\n", * timecode, * timecode->end_time, * timecode->start_time); */ } else if(!strcasecmp(string1, "ASTREAM:")) demuxer->astream_table[start_byte] = end_byte; else if(!strcasecmp(string1, "VSTREAM:")) demuxer->vstream_table[start_byte] = end_byte; else if(!strcasecmp(string1, "SIZE:")) title->total_bytes = start_byte; else if(!strcasecmp(string1, "PACKETSIZE:")) file->packet_size = start_byte; //printf("read_titles 3\n"); } } } mpeg3demux_assign_programs(demuxer); mpeg3demux_open_title(demuxer, 0); return 0; }