r134: Heroine Virtual's release 1.1.8
[cinelerra_cv/mob.git] / hvirtual / libmpeg3 / mpeg3title.c
blob582bba24005010e20da32f5f4f1175b7ee0bd99c
1 #include "mpeg3private.h"
2 #include "mpeg3protos.h"
3 #include "mpeg3title.h"
6 #include <stdlib.h>
9 mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path)
11 mpeg3_title_t *title = calloc(1, sizeof(mpeg3_title_t));
12 title->fs = mpeg3_new_fs(path);
13 title->file = file;
14 return title;
17 int mpeg3_delete_title(mpeg3_title_t *title)
19 mpeg3_delete_fs(title->fs);
20 if(title->timecode_table_size)
22 free(title->timecode_table);
24 free(title);
25 return 0;
29 int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src)
31 int i;
33 mpeg3_copy_fs(dst->fs, src->fs);
34 dst->total_bytes = src->total_bytes;
36 if(src->timecode_table_size)
38 dst->timecode_table_allocation = src->timecode_table_allocation;
39 dst->timecode_table_size = src->timecode_table_size;
40 dst->timecode_table = calloc(1, sizeof(mpeg3demux_timecode_t) * dst->timecode_table_allocation);
42 for(i = 0; i < dst->timecode_table_size; i++)
44 dst->timecode_table[i] = src->timecode_table[i];
47 return 0;
50 int mpeg3_dump_title(mpeg3_title_t *title)
52 int i;
54 printf("mpeg3_dump_title path %s timecode_table_size %d\n", title->fs->path, title->timecode_table_size);
55 for(i = 0; i < title->timecode_table_size; i++)
57 printf("%.02f: %x - %x %.02f %.02f %x\n",
58 title->timecode_table[i].absolute_start_time,
59 title->timecode_table[i].start_byte,
60 title->timecode_table[i].end_byte,
61 title->timecode_table[i].start_time,
62 title->timecode_table[i].end_time,
63 title->timecode_table[i].program);
65 return 0;
69 // Realloc doesn't work for some reason.
70 static void extend_timecode_table(mpeg3_title_t *title)
72 if(!title->timecode_table ||
73 title->timecode_table_allocation <= title->timecode_table_size)
75 long new_allocation;
76 mpeg3demux_timecode_t *new_table;
77 int i;
79 //printf("extend_timecode_table 1\n");
80 new_allocation = title->timecode_table_allocation ?
81 title->timecode_table_size * 2 :
82 64;
83 new_table = calloc(1, sizeof(mpeg3demux_timecode_t) * new_allocation);
84 //printf("extend_timecode_table 1\n");
85 memcpy(new_table,
86 title->timecode_table,
87 sizeof(mpeg3demux_timecode_t) * title->timecode_table_allocation);
88 //printf("extend_timecode_table 1 %p %d %d\n", title->timecode_table, title->timecode_table_allocation,
89 // (new_allocation - title->timecode_table_allocation));
90 free(title->timecode_table);
91 title->timecode_table = new_table;
92 //printf("extend_timecode_table 2\n");
93 title->timecode_table_allocation = new_allocation;
94 //printf("extend_timecode_table 2\n");
98 void mpeg3_new_timecode(mpeg3_title_t *title,
99 long start_byte,
100 double start_time,
101 long end_byte,
102 double end_time,
103 int program)
105 mpeg3demux_timecode_t *new_timecode;
107 extend_timecode_table(title);
108 new_timecode = &title->timecode_table[title->timecode_table_size];
110 new_timecode->start_byte = start_byte;
111 new_timecode->start_time = start_time;
112 new_timecode->end_byte = end_byte;
113 new_timecode->end_time = end_time;
114 new_timecode->absolute_start_time = 0;
115 new_timecode->program = program;
116 title->timecode_table_size++;
119 mpeg3demux_timecode_t* mpeg3_append_timecode(mpeg3_demuxer_t *demuxer,
120 mpeg3_title_t *title,
121 long prev_byte,
122 double prev_time,
123 long start_byte,
124 double start_time,
125 int dont_store,
126 int program)
128 mpeg3demux_timecode_t *new_timecode, *old_timecode;
129 long i;
131 extend_timecode_table(title);
133 * printf("mpeg3_append_timecode 1 %d %f %d %f %d %d\n", prev_byte,
134 * prev_time,
135 * start_byte,
136 * start_time,
137 * dont_store,
138 * program);
141 new_timecode = &title->timecode_table[title->timecode_table_size];
142 if(!dont_store)
144 new_timecode->start_byte = start_byte;
145 new_timecode->start_time = start_time;
146 new_timecode->absolute_start_time = 0;
148 if(title->timecode_table_size > 0)
150 old_timecode = &title->timecode_table[title->timecode_table_size - 1];
151 old_timecode->end_byte = prev_byte;
152 old_timecode->end_time = prev_time;
153 new_timecode->absolute_start_time =
154 prev_time -
155 old_timecode->start_time +
156 old_timecode->absolute_start_time;
157 new_timecode->absolute_end_time = start_time;
161 title->timecode_table_size++;
162 return new_timecode;
165 /* Create a title. */
166 /* Build a table of timecodes contained in the program stream. */
167 /* If toc is 0 just read the first and last timecode. */
168 int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer,
169 int timecode_search,
170 FILE *toc)
172 int result = 0, done = 0, counter_start, counter;
173 mpeg3_t *file = demuxer->file;
174 long next_byte, prev_byte;
175 double next_time, prev_time, absolute_time;
176 long i;
177 mpeg3_title_t *title;
178 u_int32_t test_header = 0;
179 mpeg3demux_timecode_t *timecode = 0;
181 demuxer->error_flag = 0;
182 demuxer->read_all = 1;
184 /* Create a single title */
185 if(!demuxer->total_titles)
187 demuxer->titles[0] = mpeg3_new_title(file, file->fs->path);
188 demuxer->total_titles = 1;
189 mpeg3demux_open_title(demuxer, 0);
192 title = demuxer->titles[0];
193 title->total_bytes = mpeg3io_total_bytes(title->fs);
202 /* Get timecodes for the title */
203 if(file->is_transport_stream || file->is_program_stream)
205 mpeg3io_seek(title->fs, 0);
206 //fprintf(stderr, "mpeg3demux_create_title: 0 %f %d %d\n", demuxer->time, result, mpeg3io_eof(title->fs));
207 while(!done && !result && !mpeg3io_eof(title->fs))
209 next_byte = mpeg3io_tell(title->fs);
210 result = mpeg3_read_next_packet(demuxer);
211 //printf("mpeg3demux_create_title: 1 %f %d\n", demuxer->time, result);
213 if(!result)
215 next_time = demuxer->time;
216 //printf("timecode: %f %f %f\n", (double)next_time, (double)prev_time, (double)demuxer->time);
217 if(next_time < prev_time ||
218 next_time - prev_time > MPEG3_CONTIGUOUS_THRESHOLD ||
219 !title->timecode_table_size)
221 /* Discontinuous */
222 timecode = mpeg3_append_timecode(demuxer,
223 title,
224 prev_byte,
225 prev_time,
226 next_byte,
227 next_time,
231 * printf("timecode: %ld %ld %f %f\n",
232 * timecode->start_byte,
233 * timecode->end_byte,
234 * timecode->start_time,
235 * timecode->end_time);
238 counter_start = next_time;
243 // Breaks transport stream decoding
244 // Kai Strieder
245 // if (prev_time == next_time)
246 // {
247 // done = 1;
248 // }
251 prev_time = next_time;
252 prev_byte = next_byte;
253 counter = next_time;
256 /* Just get the first bytes if not building a toc to get the stream ID's. */
257 if(next_byte > 0x100000 &&
258 (!timecode_search || !toc)) done = 1;
259 //printf("mpeg3demux_create_title 2 next_byte=%d next_time=%f done=%d result=%d %d\n",
260 // next_byte, next_time, done, result, mpeg3io_eof(title->fs));
263 /* Get the last timecode */
264 if(!toc || !timecode_search)
266 demuxer->read_all = 0;
267 result = mpeg3io_seek(title->fs, title->total_bytes);
268 // result = mpeg3io_seek(title->fs, title->total_bytes -
269 // (title->total_bytes % demuxer->packet_size));
270 //printf("mpeg3demux_create_title 3 %d\n", result);
271 if(!result) result = mpeg3_read_prev_packet(demuxer);
274 //fprintf(stderr, "mpeg3demux_create_title 4 %d %f\n", result, demuxer->time);
275 if(title->timecode_table && timecode)
277 timecode->end_byte = title->total_bytes;
278 // timecode->end_byte = mpeg3io_tell(title->fs)/* + demuxer->packet_size */;
279 timecode->end_time = demuxer->time;
280 timecode->absolute_end_time = timecode->end_time - timecode->start_time;
283 //fprintf(stderr, "mpeg3demux_create_title 5 %d\n", result);
285 mpeg3io_seek(title->fs, 0);
286 demuxer->read_all = 0;
287 return 0;
290 int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output)
292 mpeg3demux_timecode_t *timecode;
293 mpeg3_t *file = title->file;
294 int i;
296 if(title->timecode_table)
298 for(i = 0; i < title->timecode_table_size; i++)
300 timecode = &title->timecode_table[i];
302 fprintf(output, "REGION: %ld %ld %f %f %d\n",
303 timecode->start_byte,
304 timecode->end_byte,
305 timecode->start_time,
306 timecode->end_time,
307 timecode->program);
310 return 0;
313 int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc)
315 int i;
316 /* Print the stream information */
317 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
319 if(demuxer->astream_table[i])
320 fprintf(toc, "ASTREAM: %d %d\n", i, demuxer->astream_table[i]);
322 if(demuxer->vstream_table[i])
323 fprintf(toc, "VSTREAM: %d %d\n", i, demuxer->vstream_table[i]);
325 return 0;