1 #include "libmpeg3.h"
2 #include "mpeg3protos.h"
3 
4 #define TOCVERSION 3
5 #define TOCVIDEO 4
6 
mpeg3_generate_toc(FILE * output,char * path,int timecode_search,int print_streams)7 int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams)
8 {
9 	mpeg3_t *file = mpeg3_open(path);
10 	mpeg3_demuxer_t *demuxer;
11 	int i;
12 
13 	if(file)
14 	{
15 		demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
16 		if(file->is_ifo_file)
17 		{
18 			int i;
19 			mpeg3io_open_file(file->fs);
20 			mpeg3demux_read_ifo(file, demuxer, 1);
21 			mpeg3io_close_file(file->fs);
22 
23 			for(i = 0; i < demuxer->total_titles; i++)
24 			{
25 				fprintf(output, "TOCVERSION %d\n", TOCVERSION);
26 
27 				if(file->is_program_stream)
28 					fprintf(output, "PROGRAM_STREAM\n");
29 				else
30 					fprintf(output, "TRANSPORT_STREAM\n");
31 
32 				fprintf(output, "PATH: %s\n"
33 					"SIZE: %ld\n"
34 					"PACKETSIZE: %ld\n",
35 					demuxer->titles[i]->fs->path,
36 					demuxer->titles[i]->total_bytes,
37 					file->packet_size);
38 
39 /* Just print the first title's streams */
40 				if(i == 0)
41 					mpeg3demux_print_streams(demuxer, output);
42 
43 				mpeg3demux_print_timecodes(demuxer->titles[i], output);
44 			}
45 
46 			return 0;
47 		}
48 		else
49 		{
50 			char complete_path[MPEG3_STRLEN];
51 			mpeg3io_complete_path(complete_path, path);
52 
53 			fprintf(output, "TOCVERSION %d\n"
54 				"PATH: %s\n", TOCVERSION, complete_path);
55 			if(file->is_program_stream)
56 				fprintf(output, "PROGRAM_STREAM\n");
57 			else
58 				fprintf(output, "TRANSPORT_STREAM\n");
59 
60 			mpeg3demux_create_title(demuxer, timecode_search, output);
61 /* Just print the first title's streams */
62 			if(print_streams) mpeg3demux_print_streams(demuxer, output);
63 
64 			if(file->is_transport_stream || file->is_program_stream)
65 			{
66 				fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes);
67 				fprintf(output, "PACKETSIZE: %ld\n", file->packet_size);
68 			}
69 
70 			mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output);
71 			return 0;
72 		}
73 
74 		mpeg3_delete_demuxer(demuxer);
75 		mpeg3_close(file);
76 	}
77 	return 1;
78 }
79 
80 /* Read the title information from a toc */
read_titles(mpeg3_demuxer_t * demuxer,int version)81 static int read_titles(mpeg3_demuxer_t *demuxer, int version)
82 {
83 	char string1[MPEG3_STRLEN], string2[MPEG3_STRLEN];
84 	long start_byte, end_byte;
85 	double start_time, end_time;
86 	float program;
87 	mpeg3_title_t *title = 0;
88 	mpeg3_t *file = demuxer->file;
89 
90 // Eventually use IFO file to generate titles
91 	while(!feof(file->fs->fd))
92 	{
93 		char string[1024];
94 		int i = 0, byte;
95 
96 // Scanf is broken for single word lines
97 		do{
98 			byte = fgetc(file->fs->fd);
99 			if(byte != 0 &&
100 				byte != 0xd &&
101 				byte != 0xa) string[i++] = byte;
102 		}while(byte != 0xd &&
103 			byte != 0xa &&
104 			!feof(file->fs->fd) &&
105 			i < 1023);
106 		string[i] = 0;
107 
108 		if(strlen(string))
109 		{
110 			sscanf(string, "%s %s %ld %lf %lf %f",
111 				string1,
112 				string2,
113 				&end_byte,
114 				&start_time,
115 				&end_time,
116 				&program);
117 
118 //printf("read_titles 2 %d %s %s %ld %f %f %f\n", strlen(string),  string1, string2, end_byte, start_time, end_time, program);
119 			if(!strncasecmp(string1, "PATH:", 5))
120 			{
121 	//printf("read_titles 2\n");
122 				title = demuxer->titles[demuxer->total_titles++] = mpeg3_new_title(file, string2);
123 			}
124 			else
125 			if(!strcasecmp(string1, "PROGRAM_STREAM"))
126 			{
127 	//printf("read_titles 3\n");
128 				file->is_program_stream = 1;
129 			}
130 			else
131 			if(!strcasecmp(string1, "TRANSPORT_STREAM"))
132 			{
133 	//printf("read_titles 4\n");
134 				file->is_transport_stream = 1;
135 			}
136 			else
137 			if(title)
138 			{
139 				mpeg3demux_cell_t *timecode;
140 				start_byte = atol(string2);
141 	//printf("read_titles 5\n");
142 				if(!strcasecmp(string1, "REGION:"))
143 				{
144 					timecode = mpeg3_append_timecode(demuxer,
145 						title,
146 						0,
147 						0,
148 						0,
149 						0,
150 						1,
151 						0);
152 
153 
154 	//printf("mpeg3toc2 3\n");
155 					timecode->start_byte = start_byte;
156 	//printf("mpeg3toc2 4\n");
157 					timecode->end_byte = end_byte;
158 					timecode->start_time = start_time;
159 					timecode->end_time = end_time;
160 					timecode->program = program;
161 /*
162  * printf("read_title %p end: %f start: %f\n",
163  * 	timecode,
164  * 	timecode->end_time,
165  * 	timecode->start_time);
166  */
167 				}
168 				else
169 				if(!strcasecmp(string1, "ASTREAM:"))
170 					demuxer->astream_table[start_byte] = end_byte;
171 				else
172 				if(!strcasecmp(string1, "VSTREAM:"))
173 					demuxer->vstream_table[start_byte] = end_byte;
174 				else
175 				if(!strcasecmp(string1, "SIZE:"))
176 					title->total_bytes = start_byte;
177 				else
178 				if(!strcasecmp(string1, "PACKETSIZE:"))
179 					file->packet_size = start_byte;
180 //printf("read_titles 3\n");
181 			}
182 		}
183 	}
184 
185 	mpeg3demux_assign_programs(demuxer);
186 	mpeg3demux_open_title(demuxer, 0);
187 	return 0;
188 }
189 
mpeg3_read_toc(mpeg3_t * file)190 int mpeg3_read_toc(mpeg3_t *file)
191 {
192 	char string[MPEG3_STRLEN];
193 	int version;
194 
195 /* Test version number */
196 	mpeg3io_seek(file->fs, 0);
197 	fscanf(file->fs->fd, "%s %d", string, &version);
198 	if(version != TOCVERSION && version != TOCVIDEO) return 1;
199 	switch(version)
200 	{
201 		case TOCVIDEO:
202 			file->is_video_stream = 1;
203 			break;
204 	}
205 
206 /* Read titles */
207 	read_titles(file->demuxer, version);
208 	return 0;
209 }
210