2 #include "mpeg3private.h"
3 #include "mpeg3protos.h"
28 mpeg3_t
* mpeg3_new(char *path
)
31 mpeg3_t
*file
= calloc(1, sizeof(mpeg3_t
));
33 file
->fs
= mpeg3_new_fs(path
);
34 // Late compilers don't produce usable code.
35 file
->demuxer
= mpeg3_new_demuxer(file
, 0, 0, -1);
37 file
->index_bytes
= 0x300000;
38 file
->subtitle_track
= -1;
42 mpeg3_index_t
* mpeg3_new_index()
44 mpeg3_index_t
*index
= calloc(1, sizeof(mpeg3_index_t
));
45 index
->index_zoom
= 1;
49 void mpeg3_delete_index(mpeg3_index_t
*index
)
52 for(i
= 0;i
< index
->index_channels
; i
++)
53 free(index
->index_data
[i
]);
54 free(index
->index_data
);
58 int mpeg3_delete(mpeg3_t
*file
)
63 if(debug
) printf("mpeg3_delete 1\n");
64 for(i
= 0; i
< file
->total_vstreams
; i
++)
65 mpeg3_delete_vtrack(file
, file
->vtrack
[i
]);
66 if(debug
) printf("mpeg3_delete 2\n");
68 for(i
= 0; i
< file
->total_astreams
; i
++)
69 mpeg3_delete_atrack(file
, file
->atrack
[i
]);
71 for(i
= 0; i
< file
->total_sstreams
; i
++)
72 mpeg3_delete_strack(file
->strack
[i
]);
75 if(debug
) printf("mpeg3_delete 3\n");
76 mpeg3_delete_fs(file
->fs
);
77 mpeg3_delete_demuxer(file
->demuxer
);
79 if(debug
) printf("mpeg3_delete 4\n");
80 if(file
->frame_offsets
)
82 for(i
= 0; i
< file
->total_vstreams
; i
++)
84 free(file
->frame_offsets
[i
]);
85 free(file
->keyframe_numbers
[i
]);
88 if(debug
) printf("mpeg3_delete 5\n");
89 free(file
->frame_offsets
);
90 free(file
->keyframe_numbers
);
91 free(file
->total_frame_offsets
);
92 free(file
->total_keyframe_numbers
);
95 if(debug
) printf("mpeg3_delete 6\n");
96 if(file
->sample_offsets
)
98 for(i
= 0; i
< file
->total_astreams
; i
++)
99 free(file
->sample_offsets
[i
]);
101 free(file
->sample_offsets
);
102 free(file
->total_sample_offsets
);
105 if(debug
) printf("mpeg3_delete 7\n");
107 if(file
->channel_counts
)
108 free(file
->channel_counts
);
111 free(file
->audio_eof
);
113 if(debug
) printf("mpeg3_delete 8\n");
116 for(i
= 0; i
< file
->total_indexes
; i
++)
117 mpeg3_delete_index(file
->indexes
[i
]);
118 if(debug
) printf("mpeg3_delete 9\n");
123 if(debug
) printf("mpeg3_delete 10\n");
125 if(debug
) printf("mpeg3_delete 11\n");
129 int mpeg3_check_sig(char *path
)
132 u_int32_t bits
, bits2
;
136 fs
= mpeg3_new_fs(path
);
137 if(mpeg3io_open_file(fs
))
143 bits
= mpeg3io_read_int32(fs
);
144 bits2
= mpeg3io_read_int32(fs
);
145 ext
= strrchr(path
, '.');
147 if(bits
== MPEG3_TOC_PREFIX
)
152 if(((bits2
>> 24) & 0xff) == MPEG3_SYNC_BYTE
&&
154 !strncasecmp(ext
, ".m2ts", 5))
159 if((((bits
>> 24) & 0xff) == MPEG3_SYNC_BYTE
) ||
160 (bits
== MPEG3_PACK_START_CODE
) ||
161 ((bits
& 0xfff00000) == 0xfff00000) ||
162 ((bits
& 0xffff0000) == 0xffe30000) ||
163 (bits
== MPEG3_SEQUENCE_START_CODE
) ||
164 (bits
== MPEG3_PICTURE_START_CODE
) ||
165 (((bits
& 0xffff0000) >> 16) == MPEG3_AC3_START_CODE
) ||
166 ((bits
>> 8) == MPEG3_ID3_PREFIX
) ||
167 (bits
== MPEG3_RIFF_CODE
) ||
168 (bits
== MPEG3_IFO_PREFIX
))
174 /* Test file extension. */
175 if(strncasecmp(ext
, ".ifo", 4) &&
176 strncasecmp(ext
, ".mp2", 4) &&
177 strncasecmp(ext
, ".mp3", 4) &&
178 strncasecmp(ext
, ".m1v", 4) &&
179 strncasecmp(ext
, ".m2v", 4) &&
180 strncasecmp(ext
, ".m2s", 4) &&
181 strncasecmp(ext
, ".mpg", 4) &&
182 strncasecmp(ext
, ".vob", 4) &&
183 strncasecmp(ext
, ".mpeg", 4) &&
184 strncasecmp(ext
, ".ac3", 4))
189 mpeg3io_close_file(fs
);
203 static int is_toc(uint32_t bits
)
205 return (bits
== MPEG3_TOC_PREFIX
);
209 static int is_ifo(uint32_t bits
)
211 return (bits
== MPEG3_IFO_PREFIX
);
214 static int is_transport(uint32_t bits
)
216 return (((bits
>> 24) & 0xff) == MPEG3_SYNC_BYTE
);
219 static int is_bd(uint32_t bits1
, uint32_t bits2
)
221 return (((bits2
>> 24) & 0xff) == MPEG3_SYNC_BYTE
);
224 static int is_program(uint32_t bits
)
226 return (bits
== MPEG3_PACK_START_CODE
);
229 static int is_mpeg_audio(uint32_t bits
)
231 return (bits
& 0xfff00000) == 0xfff00000 ||
232 (bits
& 0xffff0000) == 0xffe30000 ||
233 ((bits
>> 8) == MPEG3_ID3_PREFIX
) ||
234 (bits
== MPEG3_RIFF_CODE
);
237 static int is_mpeg_video(uint32_t bits
)
239 return (bits
== MPEG3_SEQUENCE_START_CODE
||
240 bits
== MPEG3_PICTURE_START_CODE
);
243 static int is_ac3(uint32_t bits
)
245 return (((bits
& 0xffff0000) >> 16) == MPEG3_AC3_START_CODE
);
248 static int calculate_packet_size(int is_transport
,
257 return MPEG3_BD_PACKET_SIZE
;
259 return MPEG3_TS_PACKET_SIZE
;
266 return MPEG3_DVD_PACKET_SIZE
;
269 return MPEG3_DVD_PACKET_SIZE
;
274 int mpeg3_get_file_type(mpeg3_t
*file
,
279 uint32_t bits
= mpeg3io_read_int32(file
->fs
);
280 uint32_t bits2
= mpeg3io_read_int32(file
->fs
);
283 if(old_file
) file
->is_bd
= old_file
->is_bd
;
288 /* Table of contents for another title set */
291 if(toc_atracks
&& toc_vtracks
)
293 if((result
= mpeg3_read_toc(file
, toc_atracks
, toc_vtracks
)))
295 mpeg3io_close_file(file
->fs
);
301 mpeg3io_close_file(file
->fs
);
305 mpeg3io_close_file(file
->fs
);
313 file
->is_program_stream
= 1;
314 if(mpeg3_read_ifo(file
, 0))
316 mpeg3io_close_file(file
->fs
);
320 file
->is_ifo_file
= 1;
321 mpeg3io_close_file(file
->fs
);
324 if(is_bd(bits
, bits2
))
327 file
->is_transport_stream
= 1;
330 if(is_transport(bits
))
332 /* Transport stream */
333 file
->is_transport_stream
= 1;
339 /* Determine packet size empirically */
340 file
->is_program_stream
= 1;
343 if(is_mpeg_audio(bits
))
345 /* MPEG Audio only */
346 file
->is_audio_stream
= 1;
349 if(is_mpeg_video(bits
))
352 file
->is_video_stream
= 1;
358 file
->is_audio_stream
= 1;
362 fprintf(stderr
, "mpeg3_get_file_type: not a readable stream.\n");
367 * printf("mpeg3_get_file_type 2 %p %d %d %d %d\n",
369 * file->is_transport_stream,
370 * file->is_program_stream,
371 * file->is_video_stream,
372 * file->is_audio_stream);
376 file
->packet_size
= calculate_packet_size(file
->is_transport_stream
,
377 file
->is_program_stream
,
378 file
->is_audio_stream
,
379 file
->is_video_stream
,
386 static void copy_subtitles(mpeg3_t
*file
, mpeg3_t
*old_file
)
389 file
->total_sstreams
= old_file
->total_sstreams
;
390 for(i
= 0; i
< file
->total_sstreams
; i
++)
392 file
->strack
[i
] = mpeg3_new_strack(old_file
->strack
[i
]->id
);
393 mpeg3_copy_strack(file
->strack
[i
], old_file
->strack
[i
]);
396 memcpy(file
->palette
, old_file
->palette
, 16 * 4);
397 file
->have_palette
= old_file
->have_palette
;
401 mpeg3_t
* mpeg3_open_copy(char *path
, mpeg3_t
*old_file
, int *error_return
)
406 /* The table of contents may have fewer tracks than are in the demuxer */
407 /* This limits the track count */
408 int toc_atracks
= 0x7fffffff;
409 int toc_vtracks
= 0x7fffffff;
412 /* Initialize the file structure */
413 file
= mpeg3_new(path
);
416 /* Need to perform authentication before reading a single byte. */
417 if(mpeg3io_open_file(file
->fs
))
427 /* =============================== Create the title objects ========================= */
428 if((*error_return
= mpeg3_get_file_type(file
,
448 /* Copy data from an old file */
449 if(old_file
&& mpeg3_get_demuxer(old_file
))
451 mpeg3demux_copy_titles(file
->demuxer
, mpeg3_get_demuxer(old_file
));
452 copy_subtitles(file
, old_file
);
454 file
->is_transport_stream
= old_file
->is_transport_stream
;
455 file
->is_program_stream
= old_file
->is_program_stream
;
456 file
->is_bd
= old_file
->is_bd
;
457 file
->source_date
= old_file
->source_date
;
460 /* Start from scratch */
461 if(!file
->demuxer
->total_titles
)
463 mpeg3_create_title(file
->demuxer
, 0);
478 /* Generate tracks */
479 if(file
->is_transport_stream
|| file
->is_program_stream
)
481 /* Create video tracks */
483 i
< MPEG3_MAX_STREAMS
&& file
->total_vstreams
< toc_vtracks
;
486 if(file
->demuxer
->vstream_table
[i
])
488 file
->vtrack
[file
->total_vstreams
] =
489 mpeg3_new_vtrack(file
,
492 file
->total_vstreams
);
493 if(file
->vtrack
[file
->total_vstreams
])
494 file
->total_vstreams
++;
499 /* Create audio tracks */
500 for(i
= 0; i
< MPEG3_MAX_STREAMS
&& file
->total_astreams
< toc_atracks
; i
++)
502 if(file
->demuxer
->astream_table
[i
])
504 file
->atrack
[file
->total_astreams
] = mpeg3_new_atrack(file
,
506 file
->demuxer
->astream_table
[i
],
508 file
->total_astreams
);
509 if(file
->atrack
[file
->total_astreams
]) file
->total_astreams
++;
514 if(file
->is_video_stream
)
516 /* Create video tracks */
517 file
->vtrack
[0] = mpeg3_new_vtrack(file
,
521 if(file
->vtrack
[0]) file
->total_vstreams
++;
524 if(file
->is_audio_stream
)
526 /* Create audio tracks */
528 file
->atrack
[0] = mpeg3_new_atrack(file
,
533 if(file
->atrack
[0]) file
->total_astreams
++;
540 mpeg3io_close_file(file
->fs
);
545 mpeg3_t
* mpeg3_open(char *path
, int *error_return
)
547 return mpeg3_open_copy(path
, 0, error_return
);
550 int mpeg3_close(mpeg3_t
*file
)
552 /* File is closed in the same procedure it is opened in. */
557 int mpeg3_set_cpus(mpeg3_t
*file
, int cpus
)
561 for(i
= 0; i
< file
->total_vstreams
; i
++)
562 mpeg3video_set_cpus(file
->vtrack
[i
]->video
, cpus
);
566 int mpeg3_has_audio(mpeg3_t
*file
)
568 return file
->total_astreams
> 0;
571 int mpeg3_total_astreams(mpeg3_t
*file
)
573 return file
->total_astreams
;
576 int mpeg3_audio_channels(mpeg3_t
*file
,
579 if(file
->total_astreams
)
580 return file
->atrack
[stream
]->channels
;
584 int mpeg3_sample_rate(mpeg3_t
*file
,
587 if(file
->total_astreams
)
588 return file
->atrack
[stream
]->sample_rate
;
592 long mpeg3_get_sample(mpeg3_t
*file
,
595 if(file
->total_astreams
)
596 return file
->atrack
[stream
]->current_position
;
600 int mpeg3_set_sample(mpeg3_t
*file
,
604 if(file
->total_astreams
)
606 //printf(__FUNCTION__ " 1 %d %d\n", file->atrack[stream]->current_position, sample);
607 file
->atrack
[stream
]->current_position
= sample
;
608 mpeg3audio_seek_sample(file
->atrack
[stream
]->audio
, sample
);
614 long mpeg3_audio_samples(mpeg3_t
*file
,
617 if(file
->total_astreams
)
618 return file
->atrack
[stream
]->total_samples
;
622 char* mpeg3_audio_format(mpeg3_t
*file
, int stream
)
624 if(stream
< file
->total_astreams
)
626 switch(file
->atrack
[stream
]->format
)
628 case AUDIO_UNKNOWN
: return "Unknown"; break;
629 case AUDIO_MPEG
: return "MPEG"; break;
630 case AUDIO_AC3
: return "AC3"; break;
631 case AUDIO_PCM
: return "PCM"; break;
632 case AUDIO_AAC
: return "AAC"; break;
633 case AUDIO_JESUS
: return "Vorbis"; break;
639 int mpeg3_has_video(mpeg3_t
*file
)
641 return file
->total_vstreams
> 0;
644 int mpeg3_total_vstreams(mpeg3_t
*file
)
646 return file
->total_vstreams
;
649 int mpeg3_video_width(mpeg3_t
*file
,
652 if(file
->total_vstreams
)
653 return file
->vtrack
[stream
]->width
;
657 int mpeg3_video_height(mpeg3_t
*file
,
660 if(file
->total_vstreams
)
661 return file
->vtrack
[stream
]->height
;
665 float mpeg3_aspect_ratio(mpeg3_t
*file
, int stream
)
667 if(file
->total_vstreams
)
668 return file
->vtrack
[stream
]->aspect_ratio
;
672 double mpeg3_frame_rate(mpeg3_t
*file
,
675 if(file
->total_vstreams
)
676 return file
->vtrack
[stream
]->frame_rate
;
680 long mpeg3_video_frames(mpeg3_t
*file
,
683 if(file
->total_vstreams
)
684 return file
->vtrack
[stream
]->total_frames
;
688 long mpeg3_get_frame(mpeg3_t
*file
,
691 if(file
->total_vstreams
)
692 return file
->vtrack
[stream
]->current_position
;
696 int mpeg3_set_frame(mpeg3_t
*file
,
700 if(file
->total_vstreams
)
702 file
->vtrack
[stream
]->current_position
= frame
;
703 mpeg3video_seek_frame(file
->vtrack
[stream
]->video
, frame
);
709 int mpeg3_seek_byte(mpeg3_t
*file
, int64_t byte
)
713 // file->percentage_pts = -1;
714 for(i
= 0; i
< file
->total_vstreams
; i
++)
716 file
->vtrack
[i
]->current_position
= 0;
717 mpeg3video_seek_byte(file
->vtrack
[i
]->video
, byte
);
720 for(i
= 0; i
< file
->total_astreams
; i
++)
722 file
->atrack
[i
]->current_position
= 0;
723 mpeg3audio_seek_byte(file
->atrack
[i
]->audio
, byte
);
730 * double mpeg3_get_percentage_pts(mpeg3_t *file)
732 * return file->percentage_pts;
735 * void mpeg3_set_percentage_pts(mpeg3_t *file, double pts)
741 int mpeg3_previous_frame(mpeg3_t
*file
, int stream
)
743 file
->last_type_read
= 2;
744 file
->last_stream_read
= stream
;
746 if(file
->total_vstreams
)
747 return mpeg3video_previous_frame(file
->vtrack
[stream
]->video
);
752 int64_t mpeg3_tell_byte(mpeg3_t
*file
)
755 if(file
->last_type_read
== 1)
757 result
= mpeg3demux_tell_byte(file
->atrack
[file
->last_stream_read
]->demuxer
);
760 if(file
->last_type_read
== 2)
762 result
= mpeg3demux_tell_byte(file
->vtrack
[file
->last_stream_read
]->demuxer
);
767 int64_t mpeg3_get_bytes(mpeg3_t
*file
)
769 return mpeg3demux_movie_size(file
->demuxer
);
772 double mpeg3_get_time(mpeg3_t
*file
)
774 double atime
= 0, vtime
= 0;
776 if(file
->is_transport_stream
|| file
->is_program_stream
)
778 /* Timecode only available in transport stream */
779 if(file
->last_type_read
== 1)
781 atime
= mpeg3demux_get_time(file
->atrack
[file
->last_stream_read
]->demuxer
);
784 if(file
->last_type_read
== 2)
786 vtime
= mpeg3demux_get_time(file
->vtrack
[file
->last_stream_read
]->demuxer
);
791 /* Use percentage and total time */
792 if(file
->total_astreams
)
794 atime
= mpeg3demux_tell_byte(file
->atrack
[0]->demuxer
) *
795 mpeg3_audio_samples(file
, 0) /
796 mpeg3_sample_rate(file
, 0) /
797 mpeg3_get_bytes(file
);
800 if(file
->total_vstreams
)
802 vtime
= mpeg3demux_tell_byte(file
->vtrack
[0]->demuxer
) *
803 mpeg3_video_frames(file
, 0) /
804 mpeg3_frame_rate(file
, 0) /
805 mpeg3_get_bytes(file
);
809 return MAX(atime
, vtime
);
812 int mpeg3_end_of_audio(mpeg3_t
*file
, int stream
)
815 if(!file
->atrack
[stream
]->channels
) return 1;
816 result
= mpeg3demux_eof(file
->atrack
[stream
]->demuxer
);
820 int mpeg3_end_of_video(mpeg3_t
*file
, int stream
)
823 result
= mpeg3demux_eof(file
->vtrack
[stream
]->demuxer
);
828 int mpeg3_drop_frames(mpeg3_t
*file
, long frames
, int stream
)
832 if(file
->total_vstreams
)
834 result
= mpeg3video_drop_frames(file
->vtrack
[stream
]->video
,
837 if(frames
> 0) file
->vtrack
[stream
]->current_position
+= frames
;
838 file
->last_type_read
= 2;
839 file
->last_stream_read
= stream
;
844 int mpeg3_colormodel(mpeg3_t
*file
, int stream
)
846 if(file
->total_vstreams
)
848 return mpeg3video_colormodel(file
->vtrack
[stream
]->video
);
853 int mpeg3_set_rowspan(mpeg3_t
*file
, int bytes
, int stream
)
855 if(file
->total_vstreams
)
857 file
->vtrack
[stream
]->video
->row_span
= bytes
;
863 int mpeg3_read_frame(mpeg3_t
*file
,
864 unsigned char **output_rows
,
875 //printf("mpeg3_read_frame 1 %d\n", file->vtrack[stream]->current_position);
877 if(file
->total_vstreams
)
879 result
= mpeg3video_read_frame(file
->vtrack
[stream
]->video
,
888 //printf(__FUNCTION__ " 2\n");
889 file
->last_type_read
= 2;
890 file
->last_stream_read
= stream
;
891 file
->vtrack
[stream
]->current_position
++;
894 //printf("mpeg3_read_frame 2 %d\n", file->vtrack[stream]->current_position);
898 int mpeg3_read_yuvframe(mpeg3_t
*file
,
910 //printf("mpeg3_read_yuvframe 1\n");
911 if(file
->total_vstreams
)
913 result
= mpeg3video_read_yuvframe(file
->vtrack
[stream
]->video
,
921 file
->last_type_read
= 2;
922 file
->last_stream_read
= stream
;
923 file
->vtrack
[stream
]->current_position
++;
925 //printf("mpeg3_read_yuvframe 100\n");
929 int mpeg3_read_yuvframe_ptr(mpeg3_t
*file
,
937 if(file
->total_vstreams
)
939 result
= mpeg3video_read_yuvframe_ptr(file
->vtrack
[stream
]->video
,
943 file
->last_type_read
= 2;
944 file
->last_stream_read
= stream
;
945 file
->vtrack
[stream
]->current_position
++;
950 int mpeg3_read_audio(mpeg3_t
*file
,
959 if(file
->total_astreams
)
961 result
= mpeg3audio_decode_audio(file
->atrack
[stream
]->audio
,
966 file
->last_type_read
= 1;
967 file
->last_stream_read
= stream
;
968 file
->atrack
[stream
]->current_position
+= samples
;
974 int mpeg3_reread_audio(mpeg3_t
*file
,
981 if(file
->total_astreams
)
983 mpeg3_set_sample(file
,
984 file
->atrack
[stream
]->current_position
- samples
,
986 file
->last_type_read
= 1;
987 file
->last_stream_read
= stream
;
988 return mpeg3_read_audio(file
,
998 int mpeg3_read_audio_chunk(mpeg3_t
*file
,
999 unsigned char *output
,
1005 if(file
->total_astreams
)
1007 result
= mpeg3audio_read_raw(file
->atrack
[stream
]->audio
,
1011 file
->last_type_read
= 1;
1012 file
->last_stream_read
= stream
;
1017 int mpeg3_read_video_chunk(mpeg3_t
*file
,
1018 unsigned char *output
,
1024 if(file
->total_vstreams
)
1026 result
= mpeg3video_read_raw(file
->vtrack
[stream
]->video
,
1030 file
->last_type_read
= 2;
1031 file
->last_stream_read
= stream
;
1038 int64_t mpeg3_memory_usage(mpeg3_t
*file
)
1042 for(i
= 0; i
< file
->total_vstreams
; i
++)
1044 result
+= mpeg3_cache_usage(file
->vtrack
[i
]->frame_cache
);