2 #include "mpeg3protos.h"
10 static uint32_t read_int32(unsigned char *buffer
, int *position
)
14 if(MPEG3_LITTLE_ENDIAN
)
16 ((unsigned char*)&temp
)[3] = buffer
[(*position
)++];
17 ((unsigned char*)&temp
)[2] = buffer
[(*position
)++];
18 ((unsigned char*)&temp
)[1] = buffer
[(*position
)++];
19 ((unsigned char*)&temp
)[0] = buffer
[(*position
)++];
23 ((unsigned char*)&temp
)[0] = buffer
[(*position
)++];
24 ((unsigned char*)&temp
)[1] = buffer
[(*position
)++];
25 ((unsigned char*)&temp
)[2] = buffer
[(*position
)++];
26 ((unsigned char*)&temp
)[3] = buffer
[(*position
)++];
32 static uint64_t read_int64(unsigned char *buffer
, int *position
)
36 if(MPEG3_LITTLE_ENDIAN
)
38 ((unsigned char*)&temp
)[7] = buffer
[(*position
)++];
39 ((unsigned char*)&temp
)[6] = buffer
[(*position
)++];
40 ((unsigned char*)&temp
)[5] = buffer
[(*position
)++];
41 ((unsigned char*)&temp
)[4] = buffer
[(*position
)++];
42 ((unsigned char*)&temp
)[3] = buffer
[(*position
)++];
43 ((unsigned char*)&temp
)[2] = buffer
[(*position
)++];
44 ((unsigned char*)&temp
)[1] = buffer
[(*position
)++];
45 ((unsigned char*)&temp
)[0] = buffer
[(*position
)++];
49 ((unsigned char*)&temp
)[0] = buffer
[(*position
)++];
50 ((unsigned char*)&temp
)[1] = buffer
[(*position
)++];
51 ((unsigned char*)&temp
)[2] = buffer
[(*position
)++];
52 ((unsigned char*)&temp
)[3] = buffer
[(*position
)++];
53 ((unsigned char*)&temp
)[4] = buffer
[(*position
)++];
54 ((unsigned char*)&temp
)[5] = buffer
[(*position
)++];
55 ((unsigned char*)&temp
)[6] = buffer
[(*position
)++];
56 ((unsigned char*)&temp
)[7] = buffer
[(*position
)++];
62 static int read_data(unsigned char *buffer
,
64 unsigned char *output
,
67 memcpy(output
, buffer
+ *position
, bytes
);
71 int mpeg3_read_toc(mpeg3_t
*file
, int *atracks_return
, int *vtracks_return
)
73 unsigned char *buffer
;
79 int vfs_len
= strlen(RENDERFARM_FS_PREFIX
);
81 int64_t current_byte
= 0;
83 //printf("read_toc 1\n");
84 // Fix title paths for Cinelerra VFS
85 if(!strncmp(file
->fs
->path
, RENDERFARM_FS_PREFIX
, vfs_len
))
88 buffer
= malloc(mpeg3io_total_bytes(file
->fs
));
89 mpeg3io_seek(file
->fs
, 0);
90 mpeg3io_read_data(buffer
, mpeg3io_total_bytes(file
->fs
), file
->fs
);
93 if((toc_version
= buffer
[position
++]) != MPEG3_TOC_VERSION
)
96 "read_toc: invalid TOC version %x\n",
101 //printf("read_toc %lld\n", mpeg3io_total_bytes(file->fs));
104 file_type
= buffer
[position
++];
107 case FILE_TYPE_PROGRAM
:
108 file
->is_program_stream
= 1;
110 case FILE_TYPE_TRANSPORT
:
111 file
->is_transport_stream
= 1;
113 case FILE_TYPE_AUDIO
:
114 file
->is_audio_stream
= 1;
116 case FILE_TYPE_VIDEO
:
117 file
->is_video_stream
= 1;
121 //printf("read_toc 10\n");
124 while((stream_type
= buffer
[position
]) != TITLE_PATH
)
129 //printf("read_toc %d %x\n", position, buffer[position]);
131 offset
= read_int32(buffer
, &position
);
132 stream_id
= read_int32(buffer
, &position
);
134 if(stream_type
== STREAM_AUDIO
)
136 file
->demuxer
->astream_table
[offset
] = stream_id
;
139 if(stream_type
== STREAM_VIDEO
)
141 file
->demuxer
->vstream_table
[offset
] = stream_id
;
147 //printf("read_toc 10\n");
151 while(buffer
[position
] == TITLE_PATH
)
153 char string
[MPEG3_STRLEN
];
155 mpeg3_title_t
*title
;
158 // Construct title path from VFS prefix and path.
162 strcpy(string
, RENDERFARM_FS_PREFIX
);
163 string_len
= vfs_len
;
165 while(buffer
[position
] != 0) string
[string_len
++] = buffer
[position
++];
166 string
[string_len
++] = 0;
169 // Test title availability
170 test_fd
= fopen(string
, "r");
177 // Try concatenating title and toc directory if title is not absolute and
178 // toc path has a directory section.
179 if((!is_vfs
&& string
[0] != '/') ||
180 (is_vfs
&& string
[vfs_len
] != '/'))
182 // Get toc filename without path
183 char *ptr
= strrchr(file
->fs
->path
, '/');
186 char string2
[MPEG3_STRLEN
];
188 // Stack filename on toc path
189 strcpy(string2
, file
->fs
->path
);
191 strcpy(&string2
[ptr
- file
->fs
->path
+ 1], string
);
193 strcpy(&string2
[ptr
- file
->fs
->path
+ 1], string
+ vfs_len
);
195 test_fd
= fopen(string2
, "r");
199 strcpy(string
, string2
);
204 "read_toc: failed to open %s or %s\n",
213 "read_toc: failed to open %s\n",
221 "read_toc: failed to open %s\n",
228 file
->demuxer
->titles
[file
->demuxer
->total_titles
++] =
229 mpeg3_new_title(file
, string
);
231 title
->total_bytes
= read_int64(buffer
, &position
);
232 title
->start_byte
= current_byte
;
233 title
->end_byte
= title
->start_byte
+ title
->total_bytes
;
234 current_byte
= title
->end_byte
;
237 title
->cell_table_size
=
238 title
->cell_table_allocation
=
239 read_int32(buffer
, &position
);
240 title
->cell_table
= calloc(title
->cell_table_size
, sizeof(mpeg3_cell_t
));
241 for(i
= 0; i
< title
->cell_table_size
; i
++)
243 mpeg3_cell_t
*cell
= &title
->cell_table
[i
];
244 cell
->title_start
= read_int64(buffer
, &position
);
245 cell
->title_end
= read_int64(buffer
, &position
);
246 cell
->program_start
= read_int64(buffer
, &position
);
247 cell
->program_end
= read_int64(buffer
, &position
);
248 cell
->program
= read_int32(buffer
, &position
);
251 //printf("read_toc 10\n");
258 *atracks_return
= read_int32(buffer
, &position
);
259 //printf("read_toc 1 %d\n", *atracks_return);
263 *vtracks_return
= read_int32(buffer
, &position
);
264 //printf("read_toc 2 %d\n", *vtracks_return);
269 file
->channel_counts
= calloc(sizeof(int), *atracks_return
);
270 file
->sample_offsets
= calloc(sizeof(int64_t*), *atracks_return
);
271 file
->total_sample_offsets
= calloc(sizeof(int*), *atracks_return
);
272 file
->audio_eof
= calloc(sizeof(int64_t), *atracks_return
);
274 for(i
= 0; i
< *atracks_return
; i
++)
276 file
->audio_eof
[i
] = read_int64(buffer
, &position
);
277 file
->channel_counts
[i
] = read_int32(buffer
, &position
);
278 file
->total_sample_offsets
[i
] = read_int32(buffer
, &position
);
279 file
->sample_offsets
[i
] = malloc(file
->total_sample_offsets
[i
] * sizeof(int64_t));
280 for(j
= 0; j
< file
->total_sample_offsets
[i
]; j
++)
282 file
->sample_offsets
[i
][j
] = read_int64(buffer
, &position
);
284 //printf("samples %d %x %llx\n", i, file->sample_offsets[i][0]);
287 //printf("read_toc 10\n");
291 file
->frame_offsets
= calloc(sizeof(int64_t*), *vtracks_return
);
292 file
->total_frame_offsets
= calloc(sizeof(int*), *vtracks_return
);
293 file
->keyframe_numbers
= calloc(sizeof(int64_t*), *vtracks_return
);
294 file
->total_keyframe_numbers
= calloc(sizeof(int*), *vtracks_return
);
295 file
->video_eof
= calloc(sizeof(int64_t), *vtracks_return
);
297 for(i
= 0; i
< *vtracks_return
; i
++)
299 file
->video_eof
[i
] = read_int64(buffer
, &position
);
300 file
->total_frame_offsets
[i
] = read_int32(buffer
, &position
);
301 file
->frame_offsets
[i
] = malloc(file
->total_frame_offsets
[i
] * sizeof(int64_t));
302 for(j
= 0; j
< file
->total_frame_offsets
[i
]; j
++)
304 file
->frame_offsets
[i
][j
] = read_int64(buffer
, &position
);
305 //printf("frame %llx\n", file->frame_offsets[i][j]);
309 file
->total_keyframe_numbers
[i
] = read_int32(buffer
, &position
);
310 file
->keyframe_numbers
[i
] = malloc(file
->total_keyframe_numbers
[i
] * sizeof(int64_t));
311 for(j
= 0; j
< file
->total_keyframe_numbers
[i
]; j
++)
313 file
->keyframe_numbers
[i
][j
] = read_int64(buffer
, &position
);
320 // Indexes. ATracks aren't created yet so we need to put the indexes somewhere
322 file
->indexes
= calloc(sizeof(mpeg3_index_t
*), *atracks_return
);
323 file
->total_indexes
= *atracks_return
;
324 for(i
= 0; i
< *atracks_return
; i
++)
326 mpeg3_index_t
*index
= file
->indexes
[i
] = mpeg3_new_index();
328 index
->index_size
= read_int32(buffer
, &position
);
329 index
->index_zoom
= read_int32(buffer
, &position
);
330 //printf("mpeg3_read_toc %d %d %d\n", i, index->index_size, index->index_zoom);
331 int channels
= index
->index_channels
= file
->channel_counts
[i
];
334 index
->index_data
= calloc(sizeof(float*), channels
);
335 for(j
= 0; j
< channels
; j
++)
337 index
->index_data
[j
] = calloc(sizeof(float),
338 index
->index_size
* 2);
341 (unsigned char*)index
->index_data
[j
],
342 sizeof(float) * index
->index_size
* 2);
352 //printf("read_toc 10\n");
356 //printf("read_toc 1\n");
357 mpeg3demux_open_title(file
->demuxer
, 0);
358 //printf("read_toc 10\n");
364 mpeg3_t
* mpeg3_start_toc(char *path
, char *toc_path
, int64_t *total_bytes
)
367 mpeg3_t
*file
= mpeg3_new(path
);
369 file
->toc_fd
= fopen(toc_path
, "w");
372 printf("mpeg3_start_toc: can't open \"%s\". %s\n",
383 /* Authenticate encryption before reading a single byte */
384 if(mpeg3io_open_file(file
->fs
))
390 // Determine file type
391 int toc_atracks
= 0, toc_vtracks
= 0;
392 if(mpeg3_get_file_type(file
, 0, 0, 0)) return 0;
396 // Create title without scanning for tracks
397 if(!file
->demuxer
->total_titles
)
399 mpeg3_title_t
*title
;
400 title
= file
->demuxer
->titles
[0] = mpeg3_new_title(file
, file
->fs
->path
);
401 file
->demuxer
->total_titles
= 1;
402 mpeg3demux_open_title(file
->demuxer
, 0);
403 title
->total_bytes
= mpeg3io_total_bytes(title
->fs
);
404 title
->start_byte
= 0;
405 title
->end_byte
= title
->total_bytes
;
406 mpeg3_new_cell(title
,
414 // mpeg3demux_seek_byte(file->demuxer, 0x1734e4800LL);
415 mpeg3demux_seek_byte(file
->demuxer
, 0);
416 file
->demuxer
->read_all
= 1;
417 *total_bytes
= mpeg3demux_movie_size(file
->demuxer
);
422 void mpeg3_set_index_bytes(mpeg3_t
*file
, int64_t bytes
)
424 file
->index_bytes
= bytes
;
431 static void divide_index(mpeg3_t
*file
, int track_number
)
433 if(file
->total_indexes
<= track_number
) return;
437 mpeg3_atrack_t
*atrack
= file
->atrack
[track_number
];
438 mpeg3_index_t
*index
= file
->indexes
[track_number
];
441 index
->index_size
/= 2;
442 index
->index_zoom
*= 2;
443 for(i
= 0; i
< index
->index_channels
; i
++)
445 float *current_channel
= index
->index_data
[i
];
446 float *out
= current_channel
;
447 float *in
= current_channel
;
449 for(j
= 0; j
< index
->index_size
; j
++)
451 float max
= MAX(in
[0], in
[2]);
452 float min
= MIN(in
[1], in
[3]);
464 int mpeg3_update_index(mpeg3_t
*file
,
469 mpeg3_atrack_t
*atrack
= file
->atrack
[track_number
];
470 mpeg3_index_t
*index
= file
->indexes
[track_number
];
473 while((flush
&& atrack
->audio
->output_size
) ||
474 (!flush
&& atrack
->audio
->output_size
> MPEG3_AUDIO_CHUNKSIZE
))
476 int fragment
= MPEG3_AUDIO_CHUNKSIZE
;
477 if(atrack
->audio
->output_size
< fragment
)
478 fragment
= atrack
->audio
->output_size
;
480 int index_fragments
= fragment
/
482 if(flush
) index_fragments
++;
484 int new_index_samples
;
485 new_index_samples
= index_fragments
+
488 // Update number of channels
489 if(index
->index_allocated
&&
490 index
->index_channels
< atrack
->channels
)
492 float **new_index_data
= calloc(sizeof(float*), atrack
->channels
);
493 for(i
= 0; i
< index
->index_channels
; i
++)
495 new_index_data
[i
] = index
->index_data
[i
];
497 for(i
= index
->index_channels
; i
< atrack
->channels
; i
++)
499 new_index_data
[i
] = calloc(sizeof(float),
500 index
->index_allocated
* 2);
502 index
->index_channels
= atrack
->channels
;
503 free(index
->index_data
);
504 index
->index_data
= new_index_data
;
507 // Allocate index buffer
508 if(new_index_samples
> index
->index_allocated
)
510 // Double current number of samples
511 index
->index_allocated
= new_index_samples
* 2;
512 if(!index
->index_data
)
514 index
->index_data
= calloc(sizeof(float*), atrack
->channels
);
517 // Allocate new size in high and low pairs
518 for(i
= 0; i
< atrack
->channels
; i
++)
519 index
->index_data
[i
] = realloc(index
->index_data
[i
],
520 index
->index_allocated
* sizeof(float) * 2);
521 index
->index_channels
= atrack
->channels
;
526 // Calculate new index chunk
527 for(i
= 0; i
< atrack
->channels
; i
++)
529 float *in_channel
= atrack
->audio
->output
[i
];
530 float *out_channel
= index
->index_data
[i
] +
531 index
->index_size
* 2;
535 // Calculate index frames
536 for(j
= 0; j
< index_fragments
; j
++)
538 int remaining_fragment
= fragment
- j
* index
->index_zoom
;
539 // Incomplete index frame
540 if(remaining_fragment
< index
->index_zoom
)
542 for(k
= 0; k
< remaining_fragment
; k
++)
546 min
= max
= *in_channel
++;
550 if(*in_channel
> max
) max
= *in_channel
;
552 if(*in_channel
< min
) min
= *in_channel
;
559 min
= max
= *in_channel
++;
560 for(k
= 1; k
< index
->index_zoom
; k
++)
562 if(*in_channel
> max
) max
= *in_channel
;
564 if(*in_channel
< min
) min
= *in_channel
;
568 *out_channel
++ = max
;
569 *out_channel
++ = min
;
573 index
->index_size
= new_index_samples
;
575 // Shift audio buffer
576 mpeg3_shift_audio(atrack
->audio
, fragment
);
579 // Create new toc entry
580 mpeg3_append_samples(atrack
, atrack
->prev_offset
);
583 atrack
->current_position
+= fragment
;
586 // Divide index by 2 and increase zoom
587 if(index
->index_size
* atrack
->channels
* sizeof(float) * 2 >
589 !(index
->index_size
% 2))
591 divide_index(file
, track_number
);
597 int mpeg3_toc_audio(mpeg3_t
*file
,
601 mpeg3_atrack_t
*atrack
= file
->atrack
[track_number
];
603 // Assume last packet of stream
604 atrack
->audio_eof
= mpeg3demux_tell_byte(file
->demuxer
);
606 // Append demuxed data to track buffer
607 mpeg3demux_append_data(atrack
->demuxer
,
608 file
->demuxer
->audio_buffer
,
609 file
->demuxer
->audio_size
);
613 mpeg3audio_decode_audio(atrack
->audio
,
617 MPEG3_AUDIO_HISTORY
);
619 // When a chunk is available,
620 // add downsampled samples to the index buffer and create toc entry.
621 mpeg3_update_index(file
, track_number
, 0);
626 int mpeg3_toc_video(mpeg3_t
*file
,
627 mpeg3_vtrack_t
*vtrack
)
629 mpeg3video_t
*video
= vtrack
->video
;
632 * static FILE *test = 0;
633 * if(!test) test = fopen("test.m2v", "w");
634 * fwrite(file->demuxer->data_buffer, 1, file->demuxer->data_size, test);
635 * static int counter = 0;
636 * printf("%x %d\n", vtrack->pid, counter++);
638 // Assume last packet of stream
639 vtrack
->video_eof
= mpeg3demux_tell_byte(file
->demuxer
);
641 // Append demuxed data to track buffer
642 mpeg3demux_append_data(vtrack
->demuxer
,
643 file
->demuxer
->video_buffer
,
644 file
->demuxer
->video_size
);
647 if(vtrack
->demuxer
->data_size
- vtrack
->demuxer
->data_position
<
648 MPEG3_VIDEO_STREAM_SIZE
) return 0;
650 // Scan for a start code a certain number of bytes from the end of the
651 // buffer. Then scan the header using the video decoder to get the
653 unsigned char *ptr
= &vtrack
->demuxer
->data_buffer
[
654 vtrack
->demuxer
->data_position
];
655 uint32_t code
= (ptr
[0] << 24) | (ptr
[1] << 16) | (ptr
[2] << 8) | (ptr
[3]);
657 while(vtrack
->demuxer
->data_size
- vtrack
->demuxer
->data_position
>
658 MPEG3_VIDEO_STREAM_SIZE
)
660 if(code
== MPEG3_SEQUENCE_START_CODE
||
661 code
== MPEG3_GOP_START_CODE
||
662 code
== MPEG3_PICTURE_START_CODE
)
665 // Use video decoder to get repeat count and field type. Should never hit EOF in here.
666 // This rereads up to the current ptr since data_position isn't updated by
668 if(!mpeg3video_get_header(video
, 0))
670 if(video
->pict_struct
== BOTTOM_FIELD
||
671 video
->pict_struct
== FRAME_PICTURE
||
674 int is_keyframe
= (video
->pict_type
== I_TYPE
);
676 // Add entry for every repeat count.
677 mpeg3_append_frame(vtrack
, vtrack
->prev_offset
, is_keyframe
);
678 video
->current_repeat
+= 100;
679 while(video
->repeat_count
- video
->current_repeat
>= 100)
681 mpeg3_append_frame(vtrack
, vtrack
->prev_offset
, is_keyframe
);
682 video
->current_repeat
+= 100;
685 ptr
= &vtrack
->demuxer
->data_buffer
[
686 vtrack
->demuxer
->data_position
];
687 code
= (ptr
[0] << 24) | (ptr
[1] << 16) | (ptr
[2] << 8) | (ptr
[3]);
690 // Shift out data from before frame
691 mpeg3demux_shift_data(vtrack
->demuxer
, vtrack
->demuxer
->data_position
);
696 // Try this offset again with more data
702 vtrack
->demuxer
->data_position
++;
707 vtrack
->demuxer
->data_position
-= 4;
713 int mpeg3_do_toc(mpeg3_t
*file
, int64_t *bytes_processed
)
716 // Starting byte before our packet read
719 start_byte
= mpeg3demux_tell_byte(file
->demuxer
);
721 int result
= mpeg3_read_next_packet(file
->demuxer
);
723 // Determine program and stream id for current packet. Should be only one.
724 int program
= mpeg3demux_tell_program(file
->demuxer
);
728 * if(start_byte > 0x1b0000 &&
729 * start_byte < 0x1c0000)
730 * 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",
732 * file->demuxer->custom_id,
733 * file->demuxer->got_audio,
734 * file->demuxer->got_video,
735 * file->demuxer->audio_size,
736 * file->demuxer->video_size,
737 * file->demuxer->data_size);
740 // Only handle program 0
743 // Find current PID in tracks.
744 int custom_id
= file
->demuxer
->custom_id
;
748 // In a transport stream the PID's are unique for all audio and video but in
749 // other streams the PID's are shared.
750 if(file
->demuxer
->got_audio
||
751 file
->is_transport_stream
||
752 file
->is_audio_stream
)
754 for(i
= 0; i
< file
->total_astreams
&& !got_it
; i
++)
756 mpeg3_atrack_t
*atrack
= file
->atrack
[i
];
757 if(custom_id
== atrack
->pid
)
759 //printf("mpeg3_do_toc 2 %x\n", atrack->pid);
760 // Update an audio track
761 mpeg3_toc_audio(file
, i
);
762 atrack
->prev_offset
= start_byte
;
768 if(!got_it
&& ((file
->demuxer
->got_audio
&&
769 file
->demuxer
->astream_table
[custom_id
]) ||
770 file
->is_audio_stream
))
772 mpeg3_atrack_t
*atrack
=
773 file
->atrack
[file
->total_astreams
] =
774 mpeg3_new_atrack(file
,
776 file
->demuxer
->astream_table
[custom_id
],
778 file
->total_astreams
);
782 // Create index table
783 file
->total_indexes
++;
784 file
->indexes
= realloc(file
->indexes
,
785 file
->total_indexes
* sizeof(mpeg3_index_t
*));
786 file
->indexes
[file
->total_indexes
- 1] =
790 file
->total_astreams
++;
791 // Make the first offset correspond to the start of the first packet.
792 mpeg3_append_samples(atrack
, start_byte
);
793 mpeg3_toc_audio(file
, file
->total_astreams
- 1);
794 atrack
->prev_offset
= start_byte
;
801 if(file
->demuxer
->got_video
||
802 file
->is_transport_stream
||
803 file
->is_video_stream
)
806 for(i
= 0; i
< file
->total_vstreams
&& !got_it
; i
++)
808 mpeg3_vtrack_t
*vtrack
= file
->vtrack
[i
];
809 if(vtrack
->pid
== custom_id
)
811 // Update a video track
812 mpeg3_toc_video(file
, vtrack
);
813 vtrack
->prev_offset
= start_byte
;
821 if(!got_it
&& ((file
->demuxer
->got_video
&&
822 file
->demuxer
->vstream_table
[custom_id
]) ||
823 file
->is_video_stream
))
825 mpeg3_vtrack_t
*vtrack
=
826 file
->vtrack
[file
->total_vstreams
] =
827 mpeg3_new_vtrack(file
,
830 file
->total_vstreams
);
832 // Make the first offset correspond to the start of the first packet.
835 file
->total_vstreams
++;
836 // Create table entry for frame 0
837 mpeg3_append_frame(vtrack
, start_byte
, 1);
838 mpeg3_toc_video(file
, vtrack
);
839 vtrack
->prev_offset
= start_byte
;
846 // Make user value independant of data type in packet
847 *bytes_processed
= mpeg3demux_tell_byte(file
->demuxer
);
848 //printf("mpeg3_do_toc 1000 %llx\n", *bytes_processed);
855 #define PUT_INT32(x) \
857 if(MPEG3_LITTLE_ENDIAN) \
859 fputc(((unsigned char*)&x)[3], file->toc_fd); \
860 fputc(((unsigned char*)&x)[2], file->toc_fd); \
861 fputc(((unsigned char*)&x)[1], file->toc_fd); \
862 fputc(((unsigned char*)&x)[0], file->toc_fd); \
866 fputc(((unsigned char*)&x)[0], file->toc_fd); \
867 fputc(((unsigned char*)&x)[1], file->toc_fd); \
868 fputc(((unsigned char*)&x)[2], file->toc_fd); \
869 fputc(((unsigned char*)&x)[3], file->toc_fd); \
876 #define PUT_INT64(x) \
878 if(MPEG3_LITTLE_ENDIAN) \
880 fputc(((unsigned char*)&x)[7], file->toc_fd); \
881 fputc(((unsigned char*)&x)[6], file->toc_fd); \
882 fputc(((unsigned char*)&x)[5], file->toc_fd); \
883 fputc(((unsigned char*)&x)[4], file->toc_fd); \
884 fputc(((unsigned char*)&x)[3], file->toc_fd); \
885 fputc(((unsigned char*)&x)[2], file->toc_fd); \
886 fputc(((unsigned char*)&x)[1], file->toc_fd); \
887 fputc(((unsigned char*)&x)[0], file->toc_fd); \
891 fwrite(&x, 1, 8, file->toc_fd); \
899 void mpeg3_stop_toc(mpeg3_t
*file
)
901 // Create final chunk for audio tracks to count the last samples.
903 for(i
= 0; i
< file
->total_astreams
; i
++)
905 mpeg3_atrack_t
*atrack
= file
->atrack
[i
];
906 mpeg3_append_samples(atrack
, atrack
->prev_offset
);
909 // Flush audio indexes
910 for(i
= 0; i
< file
->total_astreams
; i
++)
911 mpeg3_update_index(file
, i
, 1);
913 // Make all indexes the same scale
915 for(i
= 0; i
< file
->total_astreams
; i
++)
917 mpeg3_atrack_t
*atrack
= file
->atrack
[i
];
918 mpeg3_index_t
*index
= file
->indexes
[i
];
919 if(index
->index_data
&& index
->index_zoom
> max_scale
)
920 max_scale
= index
->index_zoom
;
923 for(i
= 0; i
< file
->total_astreams
; i
++)
925 mpeg3_atrack_t
*atrack
= file
->atrack
[i
];
926 mpeg3_index_t
*index
= file
->indexes
[i
];
927 if(index
->index_data
&& index
->index_zoom
< max_scale
)
929 while(index
->index_zoom
< max_scale
)
930 divide_index(file
, i
);
937 // Sort tracks by PID
942 for(i
= 0; i
< file
->total_astreams
- 1; i
++)
944 mpeg3_atrack_t
*atrack1
= file
->atrack
[i
];
945 mpeg3_atrack_t
*atrack2
= file
->atrack
[i
+ 1];
946 if(atrack1
->pid
> atrack2
->pid
)
949 file
->atrack
[i
+ 1] = atrack1
;
950 file
->atrack
[i
] = atrack2
;
951 mpeg3_index_t
*index1
= file
->indexes
[i
];
952 mpeg3_index_t
*index2
= file
->indexes
[i
+ 1];
953 file
->indexes
[i
] = index2
;
954 file
->indexes
[i
+ 1] = index1
;
964 for(i
= 0; i
< file
->total_vstreams
- 1; i
++)
966 mpeg3_vtrack_t
*vtrack1
= file
->vtrack
[i
];
967 mpeg3_vtrack_t
*vtrack2
= file
->vtrack
[i
+ 1];
968 if(vtrack1
->pid
> vtrack2
->pid
)
971 file
->vtrack
[i
+ 1] = vtrack1
;
972 file
->vtrack
[i
] = vtrack2
;
979 // Output toc to file
981 fputc('T', file
->toc_fd
);
982 fputc('O', file
->toc_fd
);
983 fputc('C', file
->toc_fd
);
984 fputc(' ', file
->toc_fd
);
987 fputc(MPEG3_TOC_VERSION
, file
->toc_fd
);
990 if(file
->is_program_stream
)
992 fputc(FILE_TYPE_PROGRAM
, file
->toc_fd
);
995 if(file
->is_transport_stream
)
997 fputc(FILE_TYPE_TRANSPORT
, file
->toc_fd
);
1000 if(file
->is_audio_stream
)
1002 fputc(FILE_TYPE_AUDIO
, file
->toc_fd
);
1005 if(file
->is_video_stream
)
1007 fputc(FILE_TYPE_VIDEO
, file
->toc_fd
);
1010 // Write stream ID's
1011 // Only program and transport streams have these
1012 for(i
= 0; i
< MPEG3_MAX_STREAMS
; i
++)
1014 if(file
->demuxer
->astream_table
[i
])
1016 fputc(STREAM_AUDIO
, file
->toc_fd
);
1018 PUT_INT32(file
->demuxer
->astream_table
[i
]);
1021 if(file
->demuxer
->vstream_table
[i
])
1023 fputc(STREAM_VIDEO
, file
->toc_fd
);
1025 PUT_INT32(file
->demuxer
->vstream_table
[i
]);
1030 for(i
= 0; i
< file
->demuxer
->total_titles
; i
++)
1032 mpeg3_title_t
*title
= file
->demuxer
->titles
[i
];
1034 fputc(TITLE_PATH
, file
->toc_fd
);
1035 fprintf(file
->toc_fd
, title
->fs
->path
);
1036 fputc(0, file
->toc_fd
);
1038 PUT_INT64(title
->total_bytes
);
1039 // Byte offsets of cells
1040 PUT_INT32(file
->demuxer
->titles
[i
]->cell_table_size
);
1041 for(j
= 0; j
< title
->cell_table_size
; j
++)
1043 mpeg3_cell_t
*cell
= &title
->cell_table
[j
];
1044 PUT_INT64(cell
->title_start
);
1045 PUT_INT64(cell
->title_end
);
1046 PUT_INT64(cell
->program_start
);
1047 PUT_INT64(cell
->program_end
);
1048 PUT_INT32(cell
->program
);
1054 fputc(ATRACK_COUNT
, file
->toc_fd
);
1055 PUT_INT32(file
->total_astreams
);
1057 fputc(VTRACK_COUNT
, file
->toc_fd
);
1058 PUT_INT32(file
->total_vstreams
);
1061 for(j
= 0; j
< file
->total_astreams
; j
++)
1063 mpeg3_atrack_t
*atrack
= file
->atrack
[j
];
1064 PUT_INT64(atrack
->audio_eof
);
1065 PUT_INT32(atrack
->channels
);
1066 PUT_INT32(atrack
->total_sample_offsets
);
1067 for(i
= 0; i
< atrack
->total_sample_offsets
; i
++)
1069 PUT_INT64(atrack
->sample_offsets
[i
]);
1078 for(j
= 0; j
< file
->total_vstreams
; j
++)
1080 mpeg3_vtrack_t
*vtrack
= file
->vtrack
[j
];
1081 PUT_INT64(vtrack
->video_eof
);
1082 PUT_INT32(vtrack
->total_frame_offsets
);
1083 for(i
= 0; i
< vtrack
->total_frame_offsets
; i
++)
1085 PUT_INT64(vtrack
->frame_offsets
[i
]);
1088 PUT_INT32(vtrack
->total_keyframe_numbers
);
1089 for(i
= 0; i
< vtrack
->total_keyframe_numbers
; i
++)
1091 PUT_INT64(vtrack
->keyframe_numbers
[i
]);
1098 for(i
= 0; i
< file
->total_astreams
; i
++)
1100 mpeg3_atrack_t
*atrack
= file
->atrack
[i
];
1101 mpeg3_index_t
*index
= file
->indexes
[i
];
1102 if(index
->index_data
)
1104 PUT_INT32(index
->index_size
);
1105 PUT_INT32(index
->index_zoom
);
1106 for(j
= 0; j
< atrack
->channels
; j
++)
1108 fwrite(index
->index_data
[j
],
1119 fclose(file
->toc_fd
);
1133 int mpeg3_index_tracks(mpeg3_t
*file
)
1135 return file
->total_indexes
;
1138 int mpeg3_index_channels(mpeg3_t
*file
, int track
)
1140 if(!file
->total_indexes
) return 0;
1141 return file
->indexes
[track
]->index_channels
;
1144 int mpeg3_index_zoom(mpeg3_t
*file
)
1146 if(!file
->total_indexes
) return 0;
1148 return file
->indexes
[0]->index_zoom
;
1151 int mpeg3_index_size(mpeg3_t
*file
, int track
)
1153 if(!file
->total_indexes
) return 0;
1154 return file
->indexes
[track
]->index_size
;
1157 float* mpeg3_index_data(mpeg3_t
*file
, int track
, int channel
)
1159 if(!file
->total_indexes
) return 0;
1160 return file
->indexes
[track
]->index_data
[channel
];
1164 int mpeg3_has_toc(mpeg3_t
*file
)
1166 if(file
->frame_offsets
|| file
->sample_offsets
) return 1;