r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / libmpeg3 / libmpeg3.c
blob681bc46dc4a809143b27b7a2bb31b834416e034b
1 #include "libmpeg3.h"
2 #include "mpeg3private.h"
3 #include "mpeg3protos.h"
5 #include <fcntl.h>
6 #include <stdlib.h>
7 #include <string.h>
9 #define MAX(a, b) ((a) > (b) ? (a) : (b))
11 int mpeg3_major()
13 return MPEG3_MAJOR;
16 int mpeg3_minor()
18 return MPEG3_MINOR;
21 int mpeg3_release()
23 return MPEG3_RELEASE;
28 mpeg3_t* mpeg3_new(char *path)
30 int i;
31 mpeg3_t *file = calloc(1, sizeof(mpeg3_t));
32 file->cpus = 1;
33 file->fs = mpeg3_new_fs(path);
34 // file->have_mmx = mpeg3_mmx_test();
35 // Late compilers don't produce usable code.
36 file->have_mmx = 0;
37 file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
38 file->seekable = 1;
39 return file;
42 int mpeg3_delete(mpeg3_t *file)
44 int i;
46 for(i = 0; i < file->total_vstreams; i++)
47 mpeg3_delete_vtrack(file, file->vtrack[i]);
49 for(i = 0; i < file->total_astreams; i++)
50 mpeg3_delete_atrack(file, file->atrack[i]);
52 mpeg3_delete_fs(file->fs);
53 mpeg3_delete_demuxer(file->demuxer);
55 if(file->frame_offsets)
57 for(i = 0; i < file->total_vstreams; i++)
59 free(file->frame_offsets[i]);
60 free(file->keyframe_numbers[i]);
63 free(file->frame_offsets);
64 free(file->keyframe_numbers);
65 free(file->total_frame_offsets);
66 free(file->total_keyframe_numbers);
69 if(file->sample_offsets)
71 for(i = 0; i < file->total_astreams; i++)
72 free(file->sample_offsets[i]);
74 free(file->sample_offsets);
75 free(file->total_sample_offsets);
77 if(file->channel_counts)
78 free(file->channel_counts);
80 free(file);
81 return 0;
84 int mpeg3_check_sig(char *path)
86 mpeg3_fs_t *fs;
87 u_int32_t bits;
88 char *ext;
89 int result = 0;
91 fs = mpeg3_new_fs(path);
92 if(mpeg3io_open_file(fs))
94 /* File not found */
95 return 0;
98 bits = mpeg3io_read_int32(fs);
99 /* Test header */
100 if(bits == MPEG3_TOC_PREFIX)
102 result = 1;
104 else
105 if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
106 (bits == MPEG3_PACK_START_CODE) ||
107 ((bits & 0xfff00000) == 0xfff00000) ||
108 ((bits & 0xffff0000) == 0xffe30000) ||
109 (bits == MPEG3_SEQUENCE_START_CODE) ||
110 (bits == MPEG3_PICTURE_START_CODE) ||
111 (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
112 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
113 (bits == MPEG3_RIFF_CODE) ||
114 (bits == MPEG3_IFO_PREFIX))
116 result = 1;
118 ext = strrchr(path, '.');
119 if(ext)
121 /* Test file extension. */
122 if(strncasecmp(ext, ".ifo", 4) &&
123 strncasecmp(ext, ".mp2", 4) &&
124 strncasecmp(ext, ".mp3", 4) &&
125 strncasecmp(ext, ".m1v", 4) &&
126 strncasecmp(ext, ".m2v", 4) &&
127 strncasecmp(ext, ".m2s", 4) &&
128 strncasecmp(ext, ".mpg", 4) &&
129 strncasecmp(ext, ".vob", 4) &&
130 strncasecmp(ext, ".mpeg", 4) &&
131 strncasecmp(ext, ".ac3", 4))
132 result = 0;
136 mpeg3io_close_file(fs);
137 mpeg3_delete_fs(fs);
138 return result;
142 static uint32_t read_int32(unsigned char *buffer, int *position)
144 uint32_t temp;
146 if(MPEG3_LITTLE_ENDIAN)
148 ((unsigned char*)&temp)[3] = buffer[(*position)++];
149 ((unsigned char*)&temp)[2] = buffer[(*position)++];
150 ((unsigned char*)&temp)[1] = buffer[(*position)++];
151 ((unsigned char*)&temp)[0] = buffer[(*position)++];
153 else
155 ((unsigned char*)&temp)[0] = buffer[(*position)++];
156 ((unsigned char*)&temp)[1] = buffer[(*position)++];
157 ((unsigned char*)&temp)[2] = buffer[(*position)++];
158 ((unsigned char*)&temp)[3] = buffer[(*position)++];
161 return temp;
164 static uint64_t read_int64(unsigned char *buffer, int *position)
166 uint64_t temp;
168 if(MPEG3_LITTLE_ENDIAN)
170 ((unsigned char*)&temp)[7] = buffer[(*position)++];
171 ((unsigned char*)&temp)[6] = buffer[(*position)++];
172 ((unsigned char*)&temp)[5] = buffer[(*position)++];
173 ((unsigned char*)&temp)[4] = buffer[(*position)++];
174 ((unsigned char*)&temp)[3] = buffer[(*position)++];
175 ((unsigned char*)&temp)[2] = buffer[(*position)++];
176 ((unsigned char*)&temp)[1] = buffer[(*position)++];
177 ((unsigned char*)&temp)[0] = buffer[(*position)++];
179 else
181 ((unsigned char*)&temp)[0] = buffer[(*position)++];
182 ((unsigned char*)&temp)[1] = buffer[(*position)++];
183 ((unsigned char*)&temp)[2] = buffer[(*position)++];
184 ((unsigned char*)&temp)[3] = buffer[(*position)++];
185 ((unsigned char*)&temp)[4] = buffer[(*position)++];
186 ((unsigned char*)&temp)[5] = buffer[(*position)++];
187 ((unsigned char*)&temp)[6] = buffer[(*position)++];
188 ((unsigned char*)&temp)[7] = buffer[(*position)++];
191 return temp;
199 static int read_toc(mpeg3_t *file, int *atracks_return, int *vtracks_return)
201 unsigned char *buffer;
202 int file_type;
203 int position = 4;
204 int stream_type;
205 int i, j;
206 int is_vfs = 0;
207 int vfs_len = strlen(RENDERFARM_FS_PREFIX);
208 int toc_version;
209 int64_t current_byte = 0;
211 // Fix title paths for Cinelerra VFS
212 if(!strncmp(file->fs->path, RENDERFARM_FS_PREFIX, vfs_len))
213 is_vfs = 1;
215 buffer = malloc(mpeg3io_total_bytes(file->fs));
216 mpeg3io_seek(file->fs, 0);
217 mpeg3io_read_data(buffer, mpeg3io_total_bytes(file->fs), file->fs);
219 // Test version
220 if((toc_version = buffer[position++]) != MPEG3_TOC_VERSION)
222 fprintf(stderr,
223 "read_toc: invalid TOC version %x\n",
224 toc_version);
225 return 1;
228 //printf("read_toc %lld\n", mpeg3io_total_bytes(file->fs));
230 // File type
231 file_type = buffer[position++];
232 switch(file_type)
234 case FILE_TYPE_PROGRAM:
235 file->is_program_stream = 1;
236 break;
237 case FILE_TYPE_TRANSPORT:
238 file->is_transport_stream = 1;
239 break;
240 case FILE_TYPE_AUDIO:
241 file->is_audio_stream = 1;
242 break;
243 case FILE_TYPE_VIDEO:
244 file->is_video_stream = 1;
245 break;
248 //printf("read_toc 10\n");
250 // Stream ID's
251 while((stream_type = buffer[position]) != TITLE_PATH)
253 int offset;
254 int stream_id;
256 //printf("read_toc %d %x\n", position, buffer[position]);
257 position++;
258 offset = read_int32(buffer, &position);
259 stream_id = read_int32(buffer, &position);
261 if(stream_type == STREAM_AUDIO)
263 file->demuxer->astream_table[offset] = stream_id;
266 if(stream_type == STREAM_VIDEO)
268 file->demuxer->vstream_table[offset] = stream_id;
274 //printf("read_toc 10\n");
277 // Titles
278 while(buffer[position] == TITLE_PATH)
280 char string[MPEG3_STRLEN];
281 int string_len = 0;
282 mpeg3_title_t *title;
283 FILE *test_fd;
285 // Construct title path from VFS prefix and path.
286 position++;
287 if(is_vfs)
289 strcpy(string, RENDERFARM_FS_PREFIX);
290 string_len = vfs_len;
292 while(buffer[position] != 0) string[string_len++] = buffer[position++];
293 string[string_len++] = 0;
294 position++;
296 // Test title availability
297 test_fd = fopen(string, "r");
298 if(test_fd)
300 fclose(test_fd);
302 else
304 // Try concatenating title and toc directory if title is not absolute and
305 // toc path has a directory section.
306 if((!is_vfs && string[0] != '/') ||
307 (is_vfs && string[vfs_len] != '/'))
309 // Get toc filename without path
310 char *ptr = strrchr(file->fs->path, '/');
311 if(ptr)
313 char string2[MPEG3_STRLEN];
315 // Stack filename on toc path
316 strcpy(string2, file->fs->path);
317 if(!is_vfs)
318 strcpy(&string2[ptr - file->fs->path + 1], string);
319 else
320 strcpy(&string2[ptr - file->fs->path + 1], string + vfs_len);
322 test_fd = fopen(string2, "r");
323 if(test_fd)
325 fclose(test_fd);
326 strcpy(string, string2);
328 else
330 fprintf(stderr,
331 "read_toc: failed to open %s or %s\n",
332 string,
333 string2);
334 return 1;
337 else
339 fprintf(stderr,
340 "read_toc: failed to open %s\n",
341 string);
342 return 1;
345 else
347 fprintf(stderr,
348 "read_toc: failed to open %s\n",
349 string);
350 return 1;
354 title =
355 file->demuxer->titles[file->demuxer->total_titles++] =
356 mpeg3_new_title(file, string);
358 title->total_bytes = read_int64(buffer, &position);
359 title->start_byte = current_byte;
360 title->end_byte = title->start_byte + title->total_bytes;
361 current_byte = title->end_byte;
363 // Cells
364 title->cell_table_size =
365 title->cell_table_allocation =
366 read_int32(buffer, &position);
367 title->cell_table = calloc(title->cell_table_size, sizeof(mpeg3demux_cell_t));
368 for(i = 0; i < title->cell_table_size; i++)
370 title->cell_table[i].start_byte = read_int64(buffer, &position);
371 title->cell_table[i].end_byte = read_int64(buffer, &position);
372 title->cell_table[i].program = read_int32(buffer, &position);
375 //printf("read_toc 10\n");
379 // Audio streams
380 // Skip ATRACK_COUNT
381 position++;
382 *atracks_return = read_int32(buffer, &position);
383 //printf("read_toc 10\n");
385 // Skip VTRACK_COUNT
386 position++;
387 *vtracks_return = read_int32(buffer, &position);
388 //printf("read_toc 10\n");
391 if(*atracks_return)
393 file->channel_counts = calloc(sizeof(int), *atracks_return);
394 file->sample_offsets = malloc(sizeof(int64_t*) * *atracks_return);
395 file->total_sample_offsets = malloc(sizeof(int*) * *atracks_return);
397 for(i = 0; i < *atracks_return; i++)
399 file->channel_counts[i] = read_int32(buffer, &position);
400 file->total_sample_offsets[i] = read_int32(buffer, &position);
401 file->sample_offsets[i] = malloc(file->total_sample_offsets[i] * sizeof(int64_t));
402 for(j = 0; j < file->total_sample_offsets[i]; j++)
404 file->sample_offsets[i][j] = read_int64(buffer, &position);
405 //printf("samples %llx\n", file->sample_offsets[i][j]);
409 //printf("read_toc 10\n");
411 if(*vtracks_return)
413 file->frame_offsets = malloc(sizeof(int64_t*) * *vtracks_return);
414 file->total_frame_offsets = malloc(sizeof(int*) * *vtracks_return);
415 file->keyframe_numbers = malloc(sizeof(int64_t*) * *vtracks_return);
416 file->total_keyframe_numbers = malloc(sizeof(int*) * *vtracks_return);
418 for(i = 0; i < *vtracks_return; i++)
420 file->total_frame_offsets[i] = read_int32(buffer, &position);
421 file->frame_offsets[i] = malloc(file->total_frame_offsets[i] * sizeof(int64_t));
422 for(j = 0; j < file->total_frame_offsets[i]; j++)
424 file->frame_offsets[i][j] = read_int64(buffer, &position);
425 //printf("frame %llx\n", file->frame_offsets[i][j]);
429 file->total_keyframe_numbers[i] = read_int32(buffer, &position);
430 file->keyframe_numbers[i] = malloc(file->total_keyframe_numbers[i] * sizeof(int64_t));
431 for(j = 0; j < file->total_keyframe_numbers[i]; j++)
433 file->keyframe_numbers[i][j] = read_int64(buffer, &position);
437 //printf("read_toc 10\n");
439 free(buffer);
440 //printf("read_toc 10\n");
444 //printf("read_toc 1\n");
445 mpeg3demux_open_title(file->demuxer, 0);
446 //printf("read_toc 10\n");
448 //printf("read_toc 2 %llx\n", mpeg3demux_tell(file->demuxer));
449 return 0;
455 mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file)
457 mpeg3_t *file = 0;
458 unsigned int bits;
459 int i, done;
460 /* The table of contents may have fewer tracks than are in the demuxer */
461 /* This limits the track count */
462 int toc_atracks = 0x7fffffff;
463 int toc_vtracks = 0x7fffffff;
465 /* Initialize the file structure */
466 file = mpeg3_new(path);
474 //printf("mpeg3_open_copy 1 %s\n", path);
476 /* Need to perform authentication before reading a single byte. */
477 if(mpeg3io_open_file(file->fs))
479 mpeg3_delete(file);
480 return 0;
495 /* =============================== Create the title objects ========================= */
496 bits = mpeg3io_read_int32(file->fs);
497 //printf("mpeg3_open 1 %p %d %d %d %d\n", old_file, file->is_transport_stream, file->is_program_stream, file->is_video_stream, file->is_audio_stream);
499 if(bits == MPEG3_TOC_PREFIX) /* TOC */
501 /* Table of contents for another title set */
502 if(!old_file)
504 if(read_toc(file, &toc_atracks, &toc_vtracks))
506 mpeg3io_close_file(file->fs);
507 mpeg3_delete(file);
508 return 0;
511 mpeg3io_close_file(file->fs);
513 else
514 // IFO file
515 if(bits == MPEG3_IFO_PREFIX)
517 if(!old_file)
519 if(mpeg3_read_ifo(file, 0))
521 mpeg3_delete(file);
522 mpeg3io_close_file(file->fs);
523 return 0;
526 file->is_ifo_file = 1;
527 mpeg3io_close_file(file->fs);
529 else
530 if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
532 /* Transport stream */
533 file->is_transport_stream = 1;
535 else
536 if(bits == MPEG3_PACK_START_CODE)
538 /* Program stream */
539 /* Determine packet size empirically */
540 file->is_program_stream = 1;
542 else
543 if((bits & 0xfff00000) == 0xfff00000 ||
544 (bits & 0xffff0000) == 0xffe30000 ||
545 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
546 (bits == MPEG3_RIFF_CODE))
548 /* MPEG Audio only */
549 file->is_audio_stream = 1;
551 else
552 if(bits == MPEG3_SEQUENCE_START_CODE ||
553 bits == MPEG3_PICTURE_START_CODE)
555 /* Video only */
556 file->is_video_stream = 1;
558 else
559 if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
561 /* AC3 Audio only */
562 file->is_audio_stream = 1;
564 else
566 mpeg3_delete(file);
567 fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n");
568 return 0;
572 * printf("mpeg3_open 2 %p %d %d %d %d\n",
573 * old_file,
574 * file->is_transport_stream,
575 * file->is_program_stream,
576 * file->is_video_stream,
577 * file->is_audio_stream);
591 // Configure packet size
592 if(file->is_transport_stream)
593 file->packet_size = MPEG3_TS_PACKET_SIZE;
594 else
595 if(file->is_program_stream)
596 file->packet_size = 0;
597 else
598 if(file->is_audio_stream)
599 file->packet_size = MPEG3_DVD_PACKET_SIZE;
600 else
601 if(file->is_video_stream)
602 file->packet_size = MPEG3_DVD_PACKET_SIZE;
616 //printf("mpeg3_open 1 %d\n", file->demuxer->total_titles);
618 /* Create titles */
619 /* Copy timecodes from an old demuxer */
620 if(old_file && mpeg3_get_demuxer(old_file))
622 mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file));
623 file->is_transport_stream = old_file->is_transport_stream;
624 file->is_program_stream = old_file->is_program_stream;
626 else
627 /* Start from scratch */
628 if(!file->demuxer->total_titles)
630 mpeg3demux_create_title(file->demuxer, 0, 0);
635 //printf("mpeg3_open 50\n");
647 /* Generate tracks */
648 if(file->is_transport_stream || file->is_program_stream)
650 /* Create video tracks */
651 for(i = 0;
652 i < MPEG3_MAX_STREAMS && file->total_vstreams < toc_vtracks;
653 i++)
655 if(file->demuxer->vstream_table[i])
657 file->vtrack[file->total_vstreams] =
658 mpeg3_new_vtrack(file,
660 file->demuxer,
661 file->total_vstreams);
662 if(file->vtrack[file->total_vstreams])
663 file->total_vstreams++;
668 /* Create audio tracks */
669 for(i = 0; i < MPEG3_MAX_STREAMS && file->total_astreams < toc_atracks; i++)
671 if(file->demuxer->astream_table[i])
673 file->atrack[file->total_astreams] = mpeg3_new_atrack(file,
675 file->demuxer->astream_table[i],
676 file->demuxer,
677 file->total_astreams);
678 if(file->atrack[file->total_astreams]) file->total_astreams++;
682 else
683 if(file->is_video_stream)
685 /* Create video tracks */
686 file->vtrack[0] = mpeg3_new_vtrack(file,
687 -1,
688 file->demuxer,
690 if(file->vtrack[0]) file->total_vstreams++;
692 else
693 if(file->is_audio_stream)
695 /* Create audio tracks */
697 file->atrack[0] = mpeg3_new_atrack(file,
698 -1,
699 AUDIO_UNKNOWN,
700 file->demuxer,
702 if(file->atrack[0]) file->total_astreams++;
708 mpeg3io_close_file(file->fs);
709 return file;
712 mpeg3_t* mpeg3_open(char *path)
714 return mpeg3_open_copy(path, 0);
717 int mpeg3_close(mpeg3_t *file)
719 /* File is closed in the same procedure it is opened in. */
720 mpeg3_delete(file);
721 return 0;
724 int mpeg3_set_cpus(mpeg3_t *file, int cpus)
726 int i;
727 file->cpus = cpus;
728 for(i = 0; i < file->total_vstreams; i++)
729 mpeg3video_set_cpus(file->vtrack[i]->video, cpus);
730 return 0;
733 int mpeg3_set_mmx(mpeg3_t *file, int use_mmx)
735 int i;
736 file->have_mmx = use_mmx;
737 for(i = 0; i < file->total_vstreams; i++)
738 mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx);
739 return 0;
742 int mpeg3_has_audio(mpeg3_t *file)
744 return file->total_astreams > 0;
747 int mpeg3_total_astreams(mpeg3_t *file)
749 return file->total_astreams;
752 int mpeg3_audio_channels(mpeg3_t *file,
753 int stream)
755 if(file->total_astreams)
756 return file->atrack[stream]->channels;
757 return -1;
760 int mpeg3_sample_rate(mpeg3_t *file,
761 int stream)
763 if(file->total_astreams)
764 return file->atrack[stream]->sample_rate;
765 return -1;
768 long mpeg3_get_sample(mpeg3_t *file,
769 int stream)
771 if(file->total_astreams)
772 return file->atrack[stream]->current_position;
773 return -1;
776 int mpeg3_set_sample(mpeg3_t *file,
777 long sample,
778 int stream)
780 if(file->total_astreams)
782 //printf(__FUNCTION__ " 1 %d %d\n", file->atrack[stream]->current_position, sample);
783 file->atrack[stream]->current_position = sample;
784 mpeg3audio_seek_sample(file->atrack[stream]->audio, sample);
785 return 0;
787 return -1;
790 long mpeg3_audio_samples(mpeg3_t *file,
791 int stream)
793 if(file->total_astreams)
794 return file->atrack[stream]->total_samples;
795 return -1;
798 char* mpeg3_audio_format(mpeg3_t *file, int stream)
800 if(stream < file->total_astreams)
802 switch(file->atrack[stream]->format)
804 case AUDIO_UNKNOWN: return "Unknown"; break;
805 case AUDIO_MPEG: return "MPEG"; break;
806 case AUDIO_AC3: return "AC3"; break;
807 case AUDIO_PCM: return "PCM"; break;
808 case AUDIO_AAC: return "AAC"; break;
809 case AUDIO_JESUS: return "Vorbis"; break;
812 return "";
815 int mpeg3_has_video(mpeg3_t *file)
817 return file->total_vstreams > 0;
820 int mpeg3_total_vstreams(mpeg3_t *file)
822 return file->total_vstreams;
825 int mpeg3_video_width(mpeg3_t *file,
826 int stream)
828 if(file->total_vstreams)
829 return file->vtrack[stream]->width;
830 return -1;
833 int mpeg3_video_height(mpeg3_t *file,
834 int stream)
836 if(file->total_vstreams)
837 return file->vtrack[stream]->height;
838 return -1;
841 float mpeg3_aspect_ratio(mpeg3_t *file, int stream)
843 if(file->total_vstreams)
844 return file->vtrack[stream]->aspect_ratio;
845 return 0;
848 double mpeg3_frame_rate(mpeg3_t *file,
849 int stream)
851 if(file->total_vstreams)
852 return file->vtrack[stream]->frame_rate;
853 return -1;
856 long mpeg3_video_frames(mpeg3_t *file,
857 int stream)
859 if(file->total_vstreams)
860 return file->vtrack[stream]->total_frames;
861 return -1;
864 long mpeg3_get_frame(mpeg3_t *file,
865 int stream)
867 if(file->total_vstreams)
868 return file->vtrack[stream]->current_position;
869 return -1;
872 int mpeg3_set_frame(mpeg3_t *file,
873 long frame,
874 int stream)
876 if(file->total_vstreams)
878 file->vtrack[stream]->current_position = frame;
879 mpeg3video_seek_frame(file->vtrack[stream]->video, frame);
880 return 0;
882 return -1;
885 int mpeg3_seek_byte(mpeg3_t *file, int64_t byte)
887 int i;
889 // file->percentage_pts = -1;
890 for(i = 0; i < file->total_vstreams; i++)
892 file->vtrack[i]->current_position = 0;
893 mpeg3video_seek_byte(file->vtrack[i]->video, byte);
896 for(i = 0; i < file->total_astreams; i++)
898 file->atrack[i]->current_position = 0;
899 mpeg3audio_seek_byte(file->atrack[i]->audio, byte);
902 return 0;
906 * double mpeg3_get_percentage_pts(mpeg3_t *file)
908 * return file->percentage_pts;
911 * void mpeg3_set_percentage_pts(mpeg3_t *file, double pts)
917 int mpeg3_previous_frame(mpeg3_t *file, int stream)
919 file->last_type_read = 2;
920 file->last_stream_read = stream;
922 if(file->total_vstreams)
923 return mpeg3video_previous_frame(file->vtrack[stream]->video);
925 return 0;
928 int64_t mpeg3_tell_byte(mpeg3_t *file)
930 int64_t result = 0;
931 if(file->last_type_read == 1)
933 result = mpeg3demux_tell_byte(file->atrack[file->last_stream_read]->demuxer);
936 if(file->last_type_read == 2)
938 result = mpeg3demux_tell_byte(file->vtrack[file->last_stream_read]->demuxer);
940 return result;
943 int64_t mpeg3_get_bytes(mpeg3_t *file)
945 return mpeg3demux_movie_size(file->demuxer);
948 double mpeg3_get_time(mpeg3_t *file)
950 double atime = 0, vtime = 0;
952 if(file->is_transport_stream || file->is_program_stream)
954 /* Timecode only available in transport stream */
955 if(file->last_type_read == 1)
957 atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer);
959 else
960 if(file->last_type_read == 2)
962 vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer);
965 else
967 /* Use percentage and total time */
968 if(file->total_astreams)
970 atime = mpeg3demux_tell_byte(file->atrack[0]->demuxer) *
971 mpeg3_audio_samples(file, 0) /
972 mpeg3_sample_rate(file, 0) /
973 mpeg3_get_bytes(file);
976 if(file->total_vstreams)
978 vtime = mpeg3demux_tell_byte(file->vtrack[0]->demuxer) *
979 mpeg3_video_frames(file, 0) /
980 mpeg3_frame_rate(file, 0) /
981 mpeg3_get_bytes(file);
985 return MAX(atime, vtime);
988 int mpeg3_end_of_audio(mpeg3_t *file, int stream)
990 int result = 0;
991 if(!file->atrack[stream]->channels) return 1;
992 result = mpeg3demux_eof(file->atrack[stream]->demuxer);
993 return result;
996 int mpeg3_end_of_video(mpeg3_t *file, int stream)
998 int result = 0;
999 result = mpeg3demux_eof(file->vtrack[stream]->demuxer);
1000 return result;
1004 int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream)
1006 int result = -1;
1008 if(file->total_vstreams)
1010 result = mpeg3video_drop_frames(file->vtrack[stream]->video,
1011 frames);
1012 if(frames > 0) file->vtrack[stream]->current_position += frames;
1013 file->last_type_read = 2;
1014 file->last_stream_read = stream;
1016 return result;
1019 int mpeg3_colormodel(mpeg3_t *file, int stream)
1021 if(file->total_vstreams)
1023 return mpeg3video_colormodel(file->vtrack[stream]->video);
1025 return 0;
1028 int mpeg3_set_rowspan(mpeg3_t *file, int bytes, int stream)
1030 if(file->total_vstreams)
1032 file->vtrack[stream]->video->row_span = bytes;
1034 return 0;
1038 int mpeg3_read_frame(mpeg3_t *file,
1039 unsigned char **output_rows,
1040 int in_x,
1041 int in_y,
1042 int in_w,
1043 int in_h,
1044 int out_w,
1045 int out_h,
1046 int color_model,
1047 int stream)
1049 int result = -1;
1050 //printf("mpeg3_read_frame 1 %d\n", file->vtrack[stream]->current_position);
1052 if(file->total_vstreams)
1054 result = mpeg3video_read_frame(file->vtrack[stream]->video,
1055 file->vtrack[stream]->current_position,
1056 output_rows,
1057 in_x,
1058 in_y,
1059 in_w,
1060 in_h,
1061 out_w,
1062 out_h,
1063 color_model);
1064 //printf(__FUNCTION__ " 2\n");
1065 file->last_type_read = 2;
1066 file->last_stream_read = stream;
1067 file->vtrack[stream]->current_position++;
1070 //printf("mpeg3_read_frame 2 %d\n", file->vtrack[stream]->current_position);
1071 return result;
1074 int mpeg3_read_yuvframe(mpeg3_t *file,
1075 char *y_output,
1076 char *u_output,
1077 char *v_output,
1078 int in_x,
1079 int in_y,
1080 int in_w,
1081 int in_h,
1082 int stream)
1084 int result = -1;
1086 //printf("mpeg3_read_yuvframe 1\n");
1087 if(file->total_vstreams)
1089 result = mpeg3video_read_yuvframe(file->vtrack[stream]->video,
1090 file->vtrack[stream]->current_position,
1091 y_output,
1092 u_output,
1093 v_output,
1094 in_x,
1095 in_y,
1096 in_w,
1097 in_h);
1098 file->last_type_read = 2;
1099 file->last_stream_read = stream;
1100 file->vtrack[stream]->current_position++;
1102 //printf("mpeg3_read_yuvframe 100\n");
1103 return result;
1106 int mpeg3_read_yuvframe_ptr(mpeg3_t *file,
1107 char **y_output,
1108 char **u_output,
1109 char **v_output,
1110 int stream)
1112 int result = -1;
1114 if(file->total_vstreams)
1116 result = mpeg3video_read_yuvframe_ptr(file->vtrack[stream]->video,
1117 file->vtrack[stream]->current_position,
1118 y_output,
1119 u_output,
1120 v_output);
1121 file->last_type_read = 2;
1122 file->last_stream_read = stream;
1123 file->vtrack[stream]->current_position++;
1125 return result;
1128 int mpeg3_read_audio(mpeg3_t *file,
1129 float *output_f,
1130 short *output_i,
1131 int channel,
1132 long samples,
1133 int stream)
1135 int result = -1;
1137 if(file->total_astreams)
1139 result = mpeg3audio_decode_audio(file->atrack[stream]->audio,
1140 output_f,
1141 output_i,
1142 channel,
1143 samples);
1144 file->last_type_read = 1;
1145 file->last_stream_read = stream;
1146 file->atrack[stream]->current_position += samples;
1149 return result;
1152 int mpeg3_reread_audio(mpeg3_t *file,
1153 float *output_f,
1154 short *output_i,
1155 int channel,
1156 long samples,
1157 int stream)
1159 if(file->total_astreams)
1161 mpeg3_set_sample(file,
1162 file->atrack[stream]->current_position - samples,
1163 stream);
1164 file->last_type_read = 1;
1165 file->last_stream_read = stream;
1166 return mpeg3_read_audio(file,
1167 output_f,
1168 output_i,
1169 channel,
1170 samples,
1171 stream);
1173 return -1;
1176 int mpeg3_read_audio_chunk(mpeg3_t *file,
1177 unsigned char *output,
1178 long *size,
1179 long max_size,
1180 int stream)
1182 int result = 0;
1183 if(file->total_astreams)
1185 result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size);
1186 file->last_type_read = 1;
1187 file->last_stream_read = stream;
1189 return result;
1192 int mpeg3_read_video_chunk(mpeg3_t *file,
1193 unsigned char *output,
1194 long *size,
1195 long max_size,
1196 int stream)
1198 int result = 0;
1199 if(file->total_vstreams)
1201 result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size);
1202 file->last_type_read = 2;
1203 file->last_stream_read = stream;
1205 return result;