Merge commit 'svn/origin' into devel
[cinelerra_cv/ct.git] / libmpeg3 / mpeg3tocutil.c
blob5c245c930c0c1bf6e62aa862b88d9504e9fd3bf4
1 #include "libmpeg3.h"
2 #include "mpeg3protos.h"
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/stat.h>
12 #define PUT_INT32(x) \
13 { \
14 uint32_t temp = x; \
15 if(MPEG3_LITTLE_ENDIAN) \
16 { \
17 fputc(((unsigned char*)&temp)[3], file->toc_fd); \
18 fputc(((unsigned char*)&temp)[2], file->toc_fd); \
19 fputc(((unsigned char*)&temp)[1], file->toc_fd); \
20 fputc(((unsigned char*)&temp)[0], file->toc_fd); \
21 } \
22 else \
23 { \
24 fwrite(&temp, 1, 4, file->toc_fd); \
25 } \
31 #define PUT_INT64(x) \
32 { \
33 uint64_t temp = x; \
34 if(MPEG3_LITTLE_ENDIAN) \
35 { \
36 fputc(((unsigned char*)&temp)[7], file->toc_fd); \
37 fputc(((unsigned char*)&temp)[6], file->toc_fd); \
38 fputc(((unsigned char*)&temp)[5], file->toc_fd); \
39 fputc(((unsigned char*)&temp)[4], file->toc_fd); \
40 fputc(((unsigned char*)&temp)[3], file->toc_fd); \
41 fputc(((unsigned char*)&temp)[2], file->toc_fd); \
42 fputc(((unsigned char*)&temp)[1], file->toc_fd); \
43 fputc(((unsigned char*)&temp)[0], file->toc_fd); \
44 } \
45 else \
46 { \
47 fwrite(&temp, 1, 8, file->toc_fd); \
48 } \
52 static uint32_t read_int32(unsigned char *buffer, int *position)
54 uint32_t temp;
56 if(MPEG3_LITTLE_ENDIAN)
58 ((unsigned char*)&temp)[3] = buffer[(*position)++];
59 ((unsigned char*)&temp)[2] = buffer[(*position)++];
60 ((unsigned char*)&temp)[1] = buffer[(*position)++];
61 ((unsigned char*)&temp)[0] = buffer[(*position)++];
63 else
65 ((unsigned char*)&temp)[0] = buffer[(*position)++];
66 ((unsigned char*)&temp)[1] = buffer[(*position)++];
67 ((unsigned char*)&temp)[2] = buffer[(*position)++];
68 ((unsigned char*)&temp)[3] = buffer[(*position)++];
71 return temp;
75 static uint64_t read_int64(unsigned char *buffer, int *position)
77 uint64_t temp;
79 if(MPEG3_LITTLE_ENDIAN)
81 ((unsigned char*)&temp)[7] = buffer[(*position)++];
82 ((unsigned char*)&temp)[6] = buffer[(*position)++];
83 ((unsigned char*)&temp)[5] = buffer[(*position)++];
84 ((unsigned char*)&temp)[4] = buffer[(*position)++];
85 ((unsigned char*)&temp)[3] = buffer[(*position)++];
86 ((unsigned char*)&temp)[2] = buffer[(*position)++];
87 ((unsigned char*)&temp)[1] = buffer[(*position)++];
88 ((unsigned char*)&temp)[0] = buffer[(*position)++];
90 else
92 ((unsigned char*)&temp)[0] = buffer[(*position)++];
93 ((unsigned char*)&temp)[1] = buffer[(*position)++];
94 ((unsigned char*)&temp)[2] = buffer[(*position)++];
95 ((unsigned char*)&temp)[3] = buffer[(*position)++];
96 ((unsigned char*)&temp)[4] = buffer[(*position)++];
97 ((unsigned char*)&temp)[5] = buffer[(*position)++];
98 ((unsigned char*)&temp)[6] = buffer[(*position)++];
99 ((unsigned char*)&temp)[7] = buffer[(*position)++];
102 return temp;
105 static int read_data(unsigned char *buffer,
106 int *position,
107 unsigned char *output,
108 int bytes)
110 memcpy(output, buffer + *position, bytes);
111 *position += bytes;
114 // Concatenate title and toc directory if title is not absolute and
115 // toc path has a directory section.
116 static void complete_path(char *result, char *toc_path, char *path)
118 strcpy(result, path);
120 if(path[0] != '/')
122 // Get end of toc directory
123 char *ptr = strrchr(toc_path, '/');
125 if(ptr)
127 // Stack filename on toc path
128 strcpy(result, toc_path);
129 strcpy(&result[ptr - toc_path + 1], path);
134 int mpeg3_read_toc(mpeg3_t *file,
135 int *atracks_return,
136 int *vtracks_return)
138 unsigned char *buffer;
139 int buffer_size;
140 int file_type;
141 int position = 4;
142 int stream_type;
143 int i, j;
144 int is_vfs = 0;
145 int vfs_len = strlen(RENDERFARM_FS_PREFIX);
146 int toc_version;
147 int64_t current_byte = 0;
148 char *ext;
149 const int debug = 0;
151 // Fix title paths for Cinelerra VFS
152 if(!strncmp(file->fs->path, RENDERFARM_FS_PREFIX, vfs_len))
153 is_vfs = 1;
155 buffer_size = mpeg3io_total_bytes(file->fs);
156 buffer = malloc(buffer_size);
157 mpeg3io_seek(file->fs, 0);
158 mpeg3io_read_data(buffer, buffer_size, file->fs);
160 // Test version
161 if((toc_version = read_int32(buffer, &position)) != MPEG3_TOC_VERSION)
163 free(buffer);
164 fprintf(stderr,
165 "mpeg3_read_toc: invalid TOC version %x\n",
166 toc_version);
167 return MPEG3_INVALID_TOC_VERSION;
171 // File type
172 int done = 0;
173 while(!done && position <= buffer_size - 4)
175 // Get section type
176 int section_type = read_int32(buffer, &position);
177 //printf("section_type=%d position=%x\n", section_type, position);
178 switch(section_type)
180 case FILE_TYPE_PROGRAM:
181 file->is_program_stream = 1;
182 break;
183 case FILE_TYPE_TRANSPORT:
184 file->is_transport_stream = 1;
185 break;
186 case FILE_TYPE_AUDIO:
187 file->is_audio_stream = 1;
188 break;
189 case FILE_TYPE_VIDEO:
190 file->is_video_stream = 1;
191 break;
193 case FILE_INFO:
195 char string[MPEG3_STRLEN];
196 char string2[MPEG3_STRLEN];
197 memcpy(string, &buffer[position], MPEG3_STRLEN);
198 complete_path(string2, file->fs->path, string);
200 position += MPEG3_STRLEN;
201 file->source_date = read_int64(buffer, &position);
202 int64_t current_date = mpeg3_calculate_source_date(string2);
204 * printf("mpeg3_read_toc file=%s source_date=%lld current_date=%lld\n",
205 * string2,
206 * file->source_date,
207 * current_date);
209 if(current_date != file->source_date)
211 fprintf(stderr, "read_toc: date mismatch\n");
212 free(buffer);
213 return MPEG3_TOC_DATE_MISMATCH;
215 break;
218 case STREAM_AUDIO:
220 int number;
221 int stream_id;
222 number = read_int32(buffer, &position);
223 stream_id = read_int32(buffer, &position);
224 file->demuxer->astream_table[number] = stream_id;
225 break;
228 case STREAM_VIDEO:
230 int number;
231 int stream_id;
233 number = read_int32(buffer, &position);
234 stream_id = read_int32(buffer, &position);
235 file->demuxer->vstream_table[number] = stream_id;
236 break;
240 case ATRACK_COUNT:
241 *atracks_return = read_int32(buffer, &position);
242 file->channel_counts = calloc(sizeof(int), *atracks_return);
243 file->sample_offsets = calloc(sizeof(int64_t*), *atracks_return);
244 file->total_sample_offsets = calloc(sizeof(int), *atracks_return);
245 file->audio_eof = calloc(sizeof(int64_t), *atracks_return);
246 file->total_samples = calloc(sizeof(int64_t), *atracks_return);
247 file->indexes = calloc(sizeof(mpeg3_index_t*), *atracks_return);
248 file->total_indexes = *atracks_return;
249 for(i = 0; i < *atracks_return; i++)
251 file->audio_eof[i] = read_int64(buffer, &position);
252 file->channel_counts[i] = read_int32(buffer, &position);
253 file->total_sample_offsets[i] = read_int32(buffer, &position);
254 file->total_samples[i] = read_int64(buffer, &position);
256 if(file->total_samples[i] < 1) file->total_samples[i] = 1;
257 file->sample_offsets[i] = malloc(file->total_sample_offsets[i] * sizeof(int64_t));
258 for(j = 0; j < file->total_sample_offsets[i]; j++)
260 file->sample_offsets[i][j] = read_int64(buffer, &position);
263 mpeg3_index_t *index = file->indexes[i] = mpeg3_new_index();
264 index->index_size = read_int32(buffer, &position);
265 index->index_zoom = read_int32(buffer, &position);
266 //printf("mpeg3_read_toc %d %d %d\n", i, index->index_size, index->index_zoom);
267 int channels = index->index_channels = file->channel_counts[i];
268 if(channels)
270 index->index_data = calloc(sizeof(float*), channels);
271 for(j = 0; j < channels; j++)
273 index->index_data[j] = calloc(sizeof(float),
274 index->index_size * 2);
275 read_data(buffer,
276 &position,
277 (unsigned char*)index->index_data[j],
278 sizeof(float) * index->index_size * 2);
282 break;
284 case VTRACK_COUNT:
285 *vtracks_return = read_int32(buffer, &position);
286 file->frame_offsets = calloc(sizeof(int64_t*), *vtracks_return);
287 file->total_frame_offsets = calloc(sizeof(int), *vtracks_return);
288 file->keyframe_numbers = calloc(sizeof(int64_t*), *vtracks_return);
289 file->total_keyframe_numbers = calloc(sizeof(int), *vtracks_return);
290 file->video_eof = calloc(sizeof(int64_t), *vtracks_return);
291 for(i = 0; i < *vtracks_return; i++)
293 file->video_eof[i] = read_int64(buffer, &position);
294 file->total_frame_offsets[i] = read_int32(buffer, &position);
295 file->frame_offsets[i] = malloc(file->total_frame_offsets[i] * sizeof(int64_t));
296 if(debug) printf("mpeg3_read_toc 62 %d %d %lld\n",
297 file->total_frame_offsets[i], position, buffer_size);
298 for(j = 0; j < file->total_frame_offsets[i]; j++)
300 file->frame_offsets[i][j] = read_int64(buffer, &position);
301 //printf("frame %llx\n", file->frame_offsets[i][j]);
304 if(debug) printf("mpeg3_read_toc 64\n");
306 file->total_keyframe_numbers[i] = read_int32(buffer, &position);
307 file->keyframe_numbers[i] = malloc(file->total_keyframe_numbers[i] * sizeof(int64_t));
308 for(j = 0; j < file->total_keyframe_numbers[i]; j++)
310 file->keyframe_numbers[i][j] = read_int64(buffer, &position);
313 break;
315 case STRACK_COUNT:
317 file->total_sstreams = read_int32(buffer, &position);
318 for(i = 0; i < file->total_sstreams; i++)
320 int id = read_int32(buffer, &position);
321 mpeg3_strack_t *strack = file->strack[i] = mpeg3_new_strack(id);
322 strack->total_offsets = read_int32(buffer, &position);
323 strack->offsets = malloc(sizeof(int64_t) * strack->total_offsets);
324 strack->allocated_offsets = strack->total_offsets;
325 for(j = 0; j < strack->total_offsets; j++)
327 strack->offsets[j] = read_int64(buffer, &position);
330 break;
333 case TITLE_PATH:
335 char string[MPEG3_STRLEN];
336 int string_len = 0;
337 mpeg3_title_t *title;
338 FILE *test_fd;
339 if(debug) printf("mpeg3_read_toc 11\n");
341 // Construct title path from VFS prefix and path.
342 if(is_vfs)
344 strcpy(string, RENDERFARM_FS_PREFIX);
345 string_len = vfs_len;
347 memcpy(string, buffer + position, MPEG3_STRLEN);
348 position += MPEG3_STRLEN;
350 // Detect Blu-Ray
351 if(debug) printf("mpeg3_read_toc 11 position=%x\n", position);
352 ext = strrchr(string, '.');
353 if(ext && !strncasecmp(ext, ".m2ts", 5))
354 file->is_bd = 1;
355 if(debug) printf("mpeg3_read_toc 12\n");
357 // Test title availability
358 test_fd = fopen(string, "r");
359 if(debug) printf("mpeg3_read_toc 20\n");
360 if(test_fd)
362 fclose(test_fd);
364 else
366 // Concatenate title and toc directory if title is not absolute and
367 // toc path has a directory section.
368 if((!is_vfs && string[0] != '/') ||
369 (is_vfs && string[vfs_len] != '/'))
371 // Get toc filename without path
372 char *ptr = strrchr(file->fs->path, '/');
373 if(ptr)
375 char string2[MPEG3_STRLEN];
377 // Stack filename on toc path
378 strcpy(string2, file->fs->path);
379 if(!is_vfs)
380 strcpy(&string2[ptr - file->fs->path + 1], string);
381 else
382 strcpy(&string2[ptr - file->fs->path + 1], string + vfs_len);
384 test_fd = fopen(string2, "r");
385 if(test_fd)
387 fclose(test_fd);
388 strcpy(string, string2);
390 else
392 fprintf(stderr,
393 "read_toc: failed to open %s or %s\n",
394 string,
395 string2);
396 return 1;
399 else
401 fprintf(stderr,
402 "read_toc: failed to open %s\n",
403 string);
404 return 1;
407 else
409 fprintf(stderr,
410 "read_toc: failed to open %s\n",
411 string);
412 return 1;
416 if(debug) printf("mpeg3_read_toc 30\n");
417 title =
418 file->demuxer->titles[file->demuxer->total_titles++] =
419 mpeg3_new_title(file, string);
421 title->total_bytes = read_int64(buffer, &position);
422 title->start_byte = current_byte;
423 title->end_byte = title->start_byte + title->total_bytes;
424 current_byte = title->end_byte;
426 // Cells
427 title->cell_table_size =
428 title->cell_table_allocation =
429 read_int32(buffer, &position);
430 //printf("mpeg3_read_toc 40 %llx %d\n", title->total_bytes, title->cell_table_size);
431 title->cell_table = calloc(title->cell_table_size, sizeof(mpeg3_cell_t));
432 for(i = 0; i < title->cell_table_size; i++)
434 mpeg3_cell_t *cell = &title->cell_table[i];
435 cell->title_start = read_int64(buffer, &position);
436 cell->title_end = read_int64(buffer, &position);
437 cell->program_start = read_int64(buffer, &position);
438 cell->program_end = read_int64(buffer, &position);
439 cell->program = read_int32(buffer, &position);
441 * printf("mpeg3_read_toc 50 %llx-%llx %llx-%llx %d\n",
442 * cell->title_start,
443 * cell->title_end,
444 * cell->program_start,
445 * cell->program_end,
446 * cell->program);
450 break;
453 case IFO_PALETTE:
454 for(i = 0; i < 16; i++)
456 file->palette[i * 4 + 0] = (unsigned char)buffer[position++];
457 file->palette[i * 4 + 1] = (unsigned char)buffer[position++];
458 file->palette[i * 4 + 2] = (unsigned char)buffer[position++];
459 file->palette[i * 4 + 3] = (unsigned char)buffer[position++];
461 * printf("color %02d: 0x%02x 0x%02x 0x%02x 0x%02x\n",
462 * i,
463 * file->palette[i * 4 + 0],
464 * file->palette[i * 4 + 1],
465 * file->palette[i * 4 + 2],
466 * file->palette[i * 4 + 3]);
469 file->have_palette = 1;
470 break;
484 free(buffer);
485 if(debug) printf("mpeg3_read_toc 90\n");
489 mpeg3demux_open_title(file->demuxer, 0);
490 if(debug) printf("mpeg3_read_toc 100\n");
492 return 0;
496 mpeg3_t* mpeg3_start_toc(char *path, char *toc_path, int64_t *total_bytes)
498 *total_bytes = 0;
499 mpeg3_t *file = mpeg3_new(path);
502 file->toc_fd = fopen(toc_path, "w");
503 if(!file->toc_fd)
505 printf("mpeg3_start_toc: can't open \"%s\". %s\n",
506 toc_path,
507 strerror(errno));
508 mpeg3_delete(file);
509 return 0;
513 file->source_date = mpeg3_calculate_source_date(path);
514 file->seekable = 0;
516 /* Authenticate encryption before reading a single byte */
517 if(mpeg3io_open_file(file->fs))
519 mpeg3_delete(file);
520 return 0;
523 // Determine file type
524 int toc_atracks = 0, toc_vtracks = 0;
525 if(mpeg3_get_file_type(file, 0, 0, 0))
527 mpeg3_delete(file);
528 return 0;
533 // Create title without scanning for tracks
534 if(!file->demuxer->total_titles)
536 mpeg3_title_t *title;
537 title = file->demuxer->titles[0] = mpeg3_new_title(file, file->fs->path);
538 file->demuxer->total_titles = 1;
539 mpeg3demux_open_title(file->demuxer, 0);
540 title->total_bytes = mpeg3io_total_bytes(title->fs);
541 title->start_byte = 0;
542 title->end_byte = title->total_bytes;
543 mpeg3_new_cell(title,
545 title->end_byte,
547 title->end_byte,
551 // mpeg3demux_seek_byte(file->demuxer, 0x1734e4800LL);
552 mpeg3demux_seek_byte(file->demuxer, 0);
553 file->demuxer->read_all = 1;
554 *total_bytes = mpeg3demux_movie_size(file->demuxer);
556 //*total_bytes = 500000000;
557 return file;
560 void mpeg3_set_index_bytes(mpeg3_t *file, int64_t bytes)
562 file->index_bytes = bytes;
569 static void divide_index(mpeg3_t *file, int track_number)
571 if(file->total_indexes <= track_number) return;
574 int i, j;
575 mpeg3_atrack_t *atrack = file->atrack[track_number];
576 mpeg3_index_t *index = file->indexes[track_number];
579 index->index_size /= 2;
580 index->index_zoom *= 2;
581 for(i = 0; i < index->index_channels; i++)
583 float *current_channel = index->index_data[i];
584 float *out = current_channel;
585 float *in = current_channel;
587 for(j = 0; j < index->index_size; j++)
589 float max = MAX(in[0], in[2]);
590 float min = MIN(in[1], in[3]);
591 *out++ = max;
592 *out++ = min;
593 in += 4;
602 int mpeg3_update_index(mpeg3_t *file,
603 int track_number,
604 int flush)
606 int i, j, k;
607 mpeg3_atrack_t *atrack = file->atrack[track_number];
608 mpeg3_index_t *index = file->indexes[track_number];
611 while((flush && atrack->audio->output_size) ||
612 (!flush && atrack->audio->output_size > MPEG3_AUDIO_CHUNKSIZE))
614 int fragment = MPEG3_AUDIO_CHUNKSIZE;
615 if(atrack->audio->output_size < fragment)
616 fragment = atrack->audio->output_size;
618 int index_fragments = fragment /
619 index->index_zoom;
620 if(flush) index_fragments++;
622 int new_index_samples;
623 new_index_samples = index_fragments +
624 index->index_size;
626 // Update number of channels
627 if(index->index_allocated &&
628 index->index_channels < atrack->channels)
630 float **new_index_data = calloc(sizeof(float*), atrack->channels);
631 for(i = 0; i < index->index_channels; i++)
633 new_index_data[i] = index->index_data[i];
635 for(i = index->index_channels; i < atrack->channels; i++)
637 new_index_data[i] = calloc(sizeof(float),
638 index->index_allocated * 2);
640 index->index_channels = atrack->channels;
641 free(index->index_data);
642 index->index_data = new_index_data;
645 // Allocate index buffer
646 if(new_index_samples > index->index_allocated)
648 // Double current number of samples
649 index->index_allocated = new_index_samples * 2;
650 if(!index->index_data)
652 index->index_data = calloc(sizeof(float*), atrack->channels);
655 // Allocate new size in high and low pairs
656 for(i = 0; i < atrack->channels; i++)
657 index->index_data[i] = realloc(index->index_data[i],
658 index->index_allocated * sizeof(float) * 2);
659 index->index_channels = atrack->channels;
664 // Calculate new index chunk
665 for(i = 0; i < atrack->channels; i++)
667 float *in_channel = atrack->audio->output[i];
668 float *out_channel = index->index_data[i] +
669 index->index_size * 2;
670 float min = 0;
671 float max = 0;
673 // Calculate index frames
674 for(j = 0; j < index_fragments; j++)
676 int remaining_fragment = fragment - j * index->index_zoom;
677 // Incomplete index frame
678 if(remaining_fragment < index->index_zoom)
680 for(k = 0; k < remaining_fragment; k++)
682 if(k == 0)
684 min = max = *in_channel++;
686 else
688 if(*in_channel > max) max = *in_channel;
689 else
690 if(*in_channel < min) min = *in_channel;
691 in_channel++;
695 else
697 min = max = *in_channel++;
698 for(k = 1; k < index->index_zoom; k++)
700 if(*in_channel > max) max = *in_channel;
701 else
702 if(*in_channel < min) min = *in_channel;
703 in_channel++;
706 *out_channel++ = max;
707 *out_channel++ = min;
711 index->index_size = new_index_samples;
713 // Shift audio buffer
714 mpeg3_shift_audio(atrack->audio, fragment);
717 // Create new toc entry
718 mpeg3_append_samples(atrack, atrack->prev_offset);
721 atrack->current_position += fragment;
724 // Divide index by 2 and increase zoom
725 if(index->index_size * atrack->channels * sizeof(float) * 2 >
726 file->index_bytes &&
727 !(index->index_size % 2))
729 divide_index(file, track_number);
735 static int handle_audio(mpeg3_t *file,
736 int track_number)
738 int i, j, k;
739 mpeg3_atrack_t *atrack = file->atrack[track_number];
741 // Assume last packet of stream
742 atrack->audio_eof = mpeg3demux_tell_byte(file->demuxer);
744 // Append demuxed data to track buffer
745 if(file->demuxer->audio_size)
746 mpeg3demux_append_data(atrack->demuxer,
747 file->demuxer->audio_buffer,
748 file->demuxer->audio_size);
749 else
750 if(file->demuxer->data_size)
751 mpeg3demux_append_data(atrack->demuxer,
752 file->demuxer->data_buffer,
753 file->demuxer->data_size);
756 * if(file->demuxer->pid == 0x1100) printf("handle_audio %p %d %d\n",
757 * file->demuxer->pid,
758 * file->demuxer->audio_size,
759 * file->demuxer->data_size);
763 * if(atrack->pid == 0x1100)
765 * static FILE *test = 0;
766 * if(!test) test = fopen("/hmov/test.ac3", "w");
767 * fwrite(file->demuxer->audio_buffer,
768 * file->demuxer->audio_size,
769 * 1,
770 * test);
774 // Decode samples
775 mpeg3audio_decode_audio(atrack->audio,
779 MPEG3_AUDIO_HISTORY);
781 // When a chunk is available,
782 // add downsampled samples to the index buffer and create toc entry.
783 mpeg3_update_index(file, track_number, 0);
785 return 0;
789 static int handle_video(mpeg3_t *file,
790 mpeg3_vtrack_t *vtrack)
792 mpeg3video_t *video = vtrack->video;
795 // Assume last packet of stream
796 vtrack->video_eof = mpeg3demux_tell_byte(file->demuxer);
798 // Append demuxed data to track buffer
799 if(file->demuxer->video_size)
800 mpeg3demux_append_data(vtrack->demuxer,
801 file->demuxer->video_buffer,
802 file->demuxer->video_size);
803 else
804 if(file->demuxer->data_size)
805 mpeg3demux_append_data(vtrack->demuxer,
806 file->demuxer->data_buffer,
807 file->demuxer->data_size);
810 if(vtrack->demuxer->data_size - vtrack->demuxer->data_position <
811 MPEG3_VIDEO_STREAM_SIZE) return 0;
813 // Scan for a start code a certain number of bytes from the end of the
814 // buffer. Then scan the header using the video decoder to get the
815 // repeat count.
816 unsigned char *ptr = &vtrack->demuxer->data_buffer[
817 vtrack->demuxer->data_position];
818 uint32_t code = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
819 ptr += 4;
821 while(vtrack->demuxer->data_size - vtrack->demuxer->data_position >
822 MPEG3_VIDEO_STREAM_SIZE)
824 if(code == MPEG3_SEQUENCE_START_CODE ||
825 code == MPEG3_GOP_START_CODE ||
826 code == MPEG3_PICTURE_START_CODE)
828 if(vtrack->prev_frame_offset == -1) vtrack->prev_frame_offset = vtrack->prev_offset;
830 // Use video decoder to get repeat count and field type. Should never hit EOF in here.
831 // This rereads up to the current ptr since data_position isn't updated by
832 // handle_video.
833 if(!mpeg3video_get_header(video, 0))
835 if(video->pict_struct == BOTTOM_FIELD ||
836 video->pict_struct == FRAME_PICTURE ||
837 !video->pict_struct)
839 int is_keyframe = (video->pict_type == I_TYPE);
841 // Add entry for every repeat count.
842 mpeg3_append_frame(vtrack, vtrack->prev_frame_offset, is_keyframe);
843 video->current_repeat += 100;
844 while(video->repeat_count - video->current_repeat >= 100)
846 mpeg3_append_frame(vtrack, vtrack->prev_frame_offset, is_keyframe);
847 video->current_repeat += 100;
850 // Shift out data from before frame
851 mpeg3demux_shift_data(vtrack->demuxer, vtrack->demuxer->data_position);
853 // Reset pointer
854 ptr = &vtrack->demuxer->data_buffer[
855 vtrack->demuxer->data_position];
856 code = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
857 ptr += 4;
859 vtrack->prev_frame_offset = -1;
861 else
864 * // Shift out data from before frame
865 * vtrack->demuxer->data_position++;
866 * mpeg3demux_shift_data(vtrack->demuxer, vtrack->demuxer->data_position);
868 * // Reset pointer
869 * ptr = &vtrack->demuxer->data_buffer[
870 * vtrack->demuxer->data_position];
871 * code = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
872 * ptr += 4;
874 * vtrack->prev_frame_offset = -1;
876 break;
879 else
881 // Try this offset again with more data
882 break;
885 else
887 vtrack->demuxer->data_position++;
888 // code <<= 8;
889 // code |= *ptr++;
890 ptr = &vtrack->demuxer->data_buffer[vtrack->demuxer->data_position];
891 code = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
894 //printf("handle_video 20\n");
895 vtrack->demuxer->data_position -= 4;
896 mpeg3demux_shift_data(vtrack->demuxer, vtrack->demuxer->data_position);
899 return 0;
903 static void handle_subtitle(mpeg3_t *file)
905 int i, j;
906 int got_one = 1;
907 while(got_one)
909 got_one = 0;
911 mpeg3_subtitle_t *subtitle = 0;
912 mpeg3_strack_t *strack = 0;
913 for(i = 0; i < mpeg3_subtitle_tracks(file); i++)
915 strack = mpeg3_get_strack(file, i);
916 if((subtitle = mpeg3_get_subtitle(strack)))
918 got_one = 1;
919 break;
924 if(subtitle)
926 /* Add offset to the subtitle track */
927 mpeg3_append_subtitle_offset(strack, subtitle->offset);
930 /* Remove from buffer */
931 mpeg3_pop_subtitle(strack, 0, 1);
936 int mpeg3_do_toc(mpeg3_t *file, int64_t *bytes_processed)
938 int i, j, k;
939 // Starting byte before our packet read
940 int64_t start_byte;
942 start_byte = mpeg3demux_tell_byte(file->demuxer);
944 //printf("mpeg3_do_toc 1\n");
945 int result = mpeg3_read_next_packet(file->demuxer);
946 //printf("mpeg3_do_toc 10\n");
948 // Determine program interleaving for current packet.
949 int program = mpeg3demux_tell_program(file->demuxer);
953 * if(start_byte > 0x1b0000 &&
954 * start_byte < 0x1c0000)
955 * printf("mpeg3_do_toc 1 start_byte=%llx custum_id=%x got_audio=%d got_video=%d audio_size=%d video_size=%d data_size=%d\n",
956 * start_byte,
957 * file->demuxer->custom_id,
958 * file->demuxer->got_audio,
959 * file->demuxer->got_video,
960 * file->demuxer->audio_size,
961 * file->demuxer->video_size,
962 * file->demuxer->data_size);
965 // Only handle program 0
966 if(program == 0)
968 // Find current PID in tracks.
969 int custom_id = file->demuxer->custom_id;
970 int got_it = 0;
974 // Got subtitle
975 if(file->demuxer->got_subtitle)
977 handle_subtitle(file);
981 // In a transport stream the audio or video is determined by the PID.
982 // In other streams the data type is determined by stream ID.
983 if(file->demuxer->got_audio ||
984 file->is_transport_stream ||
985 file->is_audio_stream)
987 for(i = 0; i < file->total_astreams && !got_it; i++)
989 mpeg3_atrack_t *atrack = file->atrack[i];
990 if(custom_id == atrack->pid)
993 * printf("mpeg3_do_toc 2 offset=0x%llx pid=0x%x\n",
994 * start_byte,
995 * atrack->pid);
997 // Update an audio track
998 handle_audio(file, i);
999 atrack->prev_offset = start_byte;
1000 got_it = 1;
1001 break;
1005 if(!got_it && ((file->demuxer->got_audio &&
1006 file->demuxer->astream_table[custom_id]) ||
1007 file->is_audio_stream))
1009 mpeg3_atrack_t *atrack =
1010 file->atrack[file->total_astreams] =
1011 mpeg3_new_atrack(file,
1012 custom_id,
1013 file->demuxer->astream_table[custom_id],
1014 file->demuxer,
1015 file->total_astreams);
1017 if(atrack)
1019 // Create index table
1020 file->total_indexes++;
1021 file->indexes = realloc(file->indexes,
1022 file->total_indexes * sizeof(mpeg3_index_t*));
1023 file->indexes[file->total_indexes - 1] =
1024 mpeg3_new_index();
1027 file->total_astreams++;
1028 // Make the first offset correspond to the start of the first packet.
1029 mpeg3_append_samples(atrack, start_byte);
1030 handle_audio(file, file->total_astreams - 1);
1031 atrack->prev_offset = start_byte;
1038 if(file->demuxer->got_video ||
1039 file->is_transport_stream ||
1040 file->is_video_stream)
1042 got_it = 0;
1043 for(i = 0; i < file->total_vstreams && !got_it; i++)
1045 mpeg3_vtrack_t *vtrack = file->vtrack[i];
1046 if(vtrack->pid == custom_id)
1048 // Update a video track
1049 handle_video(file, vtrack);
1050 vtrack->prev_offset = start_byte;
1051 got_it = 1;
1052 break;
1058 if(!got_it && ((file->demuxer->got_video &&
1059 file->demuxer->vstream_table[custom_id]) ||
1060 file->is_video_stream))
1062 mpeg3_vtrack_t *vtrack =
1063 file->vtrack[file->total_vstreams] =
1064 mpeg3_new_vtrack(file,
1065 custom_id,
1066 file->demuxer,
1067 file->total_vstreams);
1069 // Make the first offset correspond to the start of the first packet.
1070 if(vtrack)
1072 file->total_vstreams++;
1073 // Create table entry for frame 0
1074 mpeg3_append_frame(vtrack, start_byte, 1);
1075 handle_video(file, vtrack);
1076 vtrack->prev_offset = start_byte;
1083 // Make user value independant of data type in packet
1084 *bytes_processed = mpeg3demux_tell_byte(file->demuxer);
1085 //printf("mpeg3_do_toc 1000 %llx\n", *bytes_processed);
1094 void mpeg3_stop_toc(mpeg3_t *file)
1096 // Create final chunk for audio tracks to count the last samples.
1097 int i, j, k;
1098 for(i = 0; i < file->total_astreams; i++)
1100 mpeg3_atrack_t *atrack = file->atrack[i];
1101 mpeg3_append_samples(atrack, atrack->prev_offset);
1104 // Flush audio indexes
1105 for(i = 0; i < file->total_astreams; i++)
1106 mpeg3_update_index(file, i, 1);
1108 // Make all indexes the same scale
1109 int max_scale = 1;
1110 for(i = 0; i < file->total_astreams; i++)
1112 mpeg3_atrack_t *atrack = file->atrack[i];
1113 mpeg3_index_t *index = file->indexes[i];
1114 if(index->index_data && index->index_zoom > max_scale)
1115 max_scale = index->index_zoom;
1118 for(i = 0; i < file->total_astreams; i++)
1120 mpeg3_atrack_t *atrack = file->atrack[i];
1121 mpeg3_index_t *index = file->indexes[i];
1122 if(index->index_data && index->index_zoom < max_scale)
1124 while(index->index_zoom < max_scale)
1125 divide_index(file, i);
1132 // Sort tracks by PID
1133 int done = 0;
1134 while(!done)
1136 done = 1;
1137 for(i = 0; i < file->total_astreams - 1; i++)
1139 mpeg3_atrack_t *atrack1 = file->atrack[i];
1140 mpeg3_atrack_t *atrack2 = file->atrack[i + 1];
1141 if(atrack1->pid > atrack2->pid)
1143 done = 0;
1144 file->atrack[i + 1] = atrack1;
1145 file->atrack[i] = atrack2;
1146 mpeg3_index_t *index1 = file->indexes[i];
1147 mpeg3_index_t *index2 = file->indexes[i + 1];
1148 file->indexes[i] = index2;
1149 file->indexes[i + 1] = index1;
1155 done = 0;
1156 while(!done)
1158 done = 1;
1159 for(i = 0; i < file->total_vstreams - 1; i++)
1161 mpeg3_vtrack_t *vtrack1 = file->vtrack[i];
1162 mpeg3_vtrack_t *vtrack2 = file->vtrack[i + 1];
1163 if(vtrack1->pid > vtrack2->pid)
1165 done = 0;
1166 file->vtrack[i + 1] = vtrack1;
1167 file->vtrack[i] = vtrack2;
1174 // Output toc to file
1175 // Write file type
1176 fputc('T', file->toc_fd);
1177 fputc('O', file->toc_fd);
1178 fputc('C', file->toc_fd);
1179 fputc(' ', file->toc_fd);
1181 // Write version
1182 PUT_INT32(MPEG3_TOC_VERSION);
1184 // Write stream type
1185 if(file->is_program_stream)
1187 PUT_INT32(FILE_TYPE_PROGRAM);
1189 else
1190 if(file->is_transport_stream)
1192 PUT_INT32(FILE_TYPE_TRANSPORT);
1194 else
1195 if(file->is_audio_stream)
1197 PUT_INT32(FILE_TYPE_AUDIO);
1199 else
1200 if(file->is_video_stream)
1202 PUT_INT32(FILE_TYPE_VIDEO);
1206 // Store file information
1207 PUT_INT32(FILE_INFO);
1208 fprintf(file->toc_fd, file->fs->path);
1209 for(j = strlen(file->fs->path); j < MPEG3_STRLEN; j++)
1210 fputc(0, file->toc_fd);
1211 PUT_INT64(file->source_date);
1213 // Write stream ID's
1214 // Only program and transport streams have these
1215 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
1217 if(file->demuxer->astream_table[i])
1219 PUT_INT32(STREAM_AUDIO);
1220 PUT_INT32(i);
1221 PUT_INT32(file->demuxer->astream_table[i]);
1224 if(file->demuxer->vstream_table[i])
1226 PUT_INT32(STREAM_VIDEO);
1227 PUT_INT32(i);
1228 PUT_INT32(file->demuxer->vstream_table[i]);
1232 // Write titles
1233 for(i = 0; i < file->demuxer->total_titles; i++)
1235 mpeg3_title_t *title = file->demuxer->titles[i];
1236 // Path
1237 PUT_INT32(TITLE_PATH);
1239 fprintf(file->toc_fd, title->fs->path);
1241 // Pad path with 0
1242 for(j = strlen(title->fs->path); j < MPEG3_STRLEN; j++)
1243 fputc(0, file->toc_fd);
1244 // Total bytes
1245 PUT_INT64(title->total_bytes);
1246 // Total cells in title
1247 PUT_INT32(file->demuxer->titles[i]->cell_table_size);
1248 for(j = 0; j < title->cell_table_size; j++)
1250 mpeg3_cell_t *cell = &title->cell_table[j];
1251 //printf("%x: %llx-%llx %llx-%llx %d\n", ftell(file->toc_fd), cell->title_start, cell->title_end, cell->program_start, cell->program_end, cell->program);
1252 PUT_INT64(cell->title_start);
1253 PUT_INT64(cell->title_end);
1254 PUT_INT64(cell->program_start);
1255 PUT_INT64(cell->program_end);
1256 PUT_INT32(cell->program);
1261 PUT_INT32(ATRACK_COUNT);
1262 PUT_INT32(file->total_astreams);
1264 // Audio streams
1265 for(j = 0; j < file->total_astreams; j++)
1267 mpeg3_atrack_t *atrack = file->atrack[j];
1268 PUT_INT64(atrack->audio_eof);
1269 PUT_INT32(atrack->channels);
1270 PUT_INT32(atrack->total_sample_offsets);
1271 // Total samples
1272 PUT_INT64(atrack->current_position);
1273 // Sample offsets
1274 for(i = 0; i < atrack->total_sample_offsets; i++)
1276 PUT_INT64(atrack->sample_offsets[i]);
1279 // Index
1280 mpeg3_index_t *index = file->indexes[j];
1281 if(index->index_data)
1283 PUT_INT32(index->index_size);
1284 PUT_INT32(index->index_zoom);
1285 for(k = 0; k < atrack->channels; k++)
1287 fwrite(index->index_data[k],
1288 sizeof(float) * 2,
1289 index->index_size,
1290 file->toc_fd);
1293 else
1295 PUT_INT32(0);
1296 PUT_INT32(1);
1304 PUT_INT32(VTRACK_COUNT);
1305 PUT_INT32(file->total_vstreams);
1307 // Video streams
1308 for(j = 0; j < file->total_vstreams; j++)
1310 mpeg3_vtrack_t *vtrack = file->vtrack[j];
1311 PUT_INT64(vtrack->video_eof);
1312 PUT_INT32(vtrack->total_frame_offsets);
1313 for(i = 0; i < vtrack->total_frame_offsets; i++)
1315 PUT_INT64(vtrack->frame_offsets[i]);
1318 PUT_INT32(vtrack->total_keyframe_numbers);
1319 for(i = 0; i < vtrack->total_keyframe_numbers; i++)
1321 PUT_INT64(vtrack->keyframe_numbers[i]);
1328 PUT_INT32(STRACK_COUNT);
1329 PUT_INT32(file->total_sstreams);
1331 // Subtitle tracks
1332 for(i = 0; i < file->total_sstreams; i++)
1334 mpeg3_strack_t *strack = file->strack[i];
1335 PUT_INT32(strack->id);
1336 PUT_INT32(strack->total_offsets);
1337 for(j = 0; j < strack->total_offsets; j++)
1339 PUT_INT64(strack->offsets[j]);
1344 PUT_INT32(IFO_PALETTE);
1345 for(i = 0; i < 16 * 4; i++)
1347 fputc(file->palette[i], file->toc_fd);
1351 fclose(file->toc_fd);
1354 mpeg3_delete(file);
1365 int mpeg3_index_tracks(mpeg3_t *file)
1367 return file->total_indexes;
1370 int mpeg3_index_channels(mpeg3_t *file, int track)
1372 if(!file->total_indexes) return 0;
1373 return file->indexes[track]->index_channels;
1376 int mpeg3_index_zoom(mpeg3_t *file)
1378 if(!file->total_indexes) return 0;
1380 return file->indexes[0]->index_zoom;
1383 int mpeg3_index_size(mpeg3_t *file, int track)
1385 if(!file->total_indexes) return 0;
1386 return file->indexes[track]->index_size;
1389 float* mpeg3_index_data(mpeg3_t *file, int track, int channel)
1391 if(!file->total_indexes) return 0;
1392 return file->indexes[track]->index_data[channel];
1396 int mpeg3_has_toc(mpeg3_t *file)
1398 if(file->frame_offsets || file->sample_offsets) return 1;
1399 return 0;
1402 char* mpeg3_title_path(mpeg3_t *file, int number)
1404 if(number < file->demuxer->total_titles)
1406 return file->demuxer->titles[number]->fs->path;
1408 return 0;
1411 int64_t mpeg3_get_source_date(mpeg3_t *file)
1413 return file->source_date;
1416 int64_t mpeg3_calculate_source_date(char *path)
1418 struct stat64 ostat;
1419 bzero(&ostat, sizeof(struct stat64));
1420 stat64(path, &ostat);
1421 return ostat.st_mtime;