r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / libmpeg3 / libmpeg3.c
blob7b57cf6e15f8a8a86649f2b6ab598229123d3efb
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 file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
36 file->seekable = 1;
37 return file;
40 int mpeg3_delete(mpeg3_t *file)
42 int i;
44 for(i = 0; i < file->total_vstreams; i++)
45 mpeg3_delete_vtrack(file, file->vtrack[i]);
47 for(i = 0; i < file->total_astreams; i++)
48 mpeg3_delete_atrack(file, file->atrack[i]);
50 mpeg3_delete_fs(file->fs);
51 mpeg3_delete_demuxer(file->demuxer);
53 if(file->frame_offsets)
55 for(i = 0; i < file->total_vstreams; i++)
57 free(file->frame_offsets[i]);
58 free(file->keyframe_numbers[i]);
61 free(file->frame_offsets);
62 free(file->keyframe_numbers);
63 free(file->total_frame_offsets);
64 free(file->total_keyframe_numbers);
67 if(file->sample_offsets)
69 for(i = 0; i < file->total_astreams; i++)
70 free(file->sample_offsets[i]);
72 free(file->sample_offsets);
73 free(file->total_sample_offsets);
75 if(file->channel_counts)
76 free(file->channel_counts);
78 free(file);
79 return 0;
82 int mpeg3_check_sig(char *path)
84 mpeg3_fs_t *fs;
85 u_int32_t bits;
86 char *ext;
87 int result = 0;
89 fs = mpeg3_new_fs(path);
90 if(mpeg3io_open_file(fs))
92 /* File not found */
93 return 0;
96 bits = mpeg3io_read_int32(fs);
97 /* Test header */
98 if(bits == MPEG3_TOC_PREFIX)
100 result = 1;
102 else
103 if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
104 (bits == MPEG3_PACK_START_CODE) ||
105 ((bits & 0xfff00000) == 0xfff00000) ||
106 ((bits & 0xffff0000) == 0xffe30000) ||
107 (bits == MPEG3_SEQUENCE_START_CODE) ||
108 (bits == MPEG3_PICTURE_START_CODE) ||
109 (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
110 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
111 (bits == MPEG3_RIFF_CODE) ||
112 (bits == MPEG3_IFO_PREFIX))
114 result = 1;
116 ext = strrchr(path, '.');
117 if(ext)
119 /* Test file extension. */
120 if(strncasecmp(ext, ".ifo", 4) &&
121 strncasecmp(ext, ".mp2", 4) &&
122 strncasecmp(ext, ".mp3", 4) &&
123 strncasecmp(ext, ".m1v", 4) &&
124 strncasecmp(ext, ".m2v", 4) &&
125 strncasecmp(ext, ".m2s", 4) &&
126 strncasecmp(ext, ".mpg", 4) &&
127 strncasecmp(ext, ".vob", 4) &&
128 strncasecmp(ext, ".mpeg", 4) &&
129 strncasecmp(ext, ".ac3", 4))
130 result = 0;
134 mpeg3io_close_file(fs);
135 mpeg3_delete_fs(fs);
136 return result;
140 static uint32_t read_int32(unsigned char *buffer, int *position)
142 uint32_t temp;
144 if(MPEG3_LITTLE_ENDIAN)
146 ((unsigned char*)&temp)[3] = buffer[(*position)++];
147 ((unsigned char*)&temp)[2] = buffer[(*position)++];
148 ((unsigned char*)&temp)[1] = buffer[(*position)++];
149 ((unsigned char*)&temp)[0] = buffer[(*position)++];
151 else
153 ((unsigned char*)&temp)[0] = buffer[(*position)++];
154 ((unsigned char*)&temp)[1] = buffer[(*position)++];
155 ((unsigned char*)&temp)[2] = buffer[(*position)++];
156 ((unsigned char*)&temp)[3] = buffer[(*position)++];
159 return temp;
162 static uint64_t read_int64(unsigned char *buffer, int *position)
164 uint64_t temp;
166 if(MPEG3_LITTLE_ENDIAN)
168 ((unsigned char*)&temp)[7] = buffer[(*position)++];
169 ((unsigned char*)&temp)[6] = buffer[(*position)++];
170 ((unsigned char*)&temp)[5] = buffer[(*position)++];
171 ((unsigned char*)&temp)[4] = buffer[(*position)++];
172 ((unsigned char*)&temp)[3] = buffer[(*position)++];
173 ((unsigned char*)&temp)[2] = buffer[(*position)++];
174 ((unsigned char*)&temp)[1] = buffer[(*position)++];
175 ((unsigned char*)&temp)[0] = buffer[(*position)++];
177 else
179 ((unsigned char*)&temp)[0] = buffer[(*position)++];
180 ((unsigned char*)&temp)[1] = buffer[(*position)++];
181 ((unsigned char*)&temp)[2] = buffer[(*position)++];
182 ((unsigned char*)&temp)[3] = buffer[(*position)++];
183 ((unsigned char*)&temp)[4] = buffer[(*position)++];
184 ((unsigned char*)&temp)[5] = buffer[(*position)++];
185 ((unsigned char*)&temp)[6] = buffer[(*position)++];
186 ((unsigned char*)&temp)[7] = buffer[(*position)++];
189 return temp;
197 static int read_toc(mpeg3_t *file)
199 unsigned char *buffer;
200 int file_type;
201 int position = 4;
202 int stream_type;
203 int atracks;
204 int vtracks;
205 int i, j;
206 int is_vfs = 0;
207 if(!strncmp(file->fs->path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
208 is_vfs = 1;
209 //printf("read_toc 10\n");
210 buffer = malloc(mpeg3io_total_bytes(file->fs));
211 //printf("read_toc 10\n");
212 mpeg3io_seek(file->fs, 0);
213 //printf("read_toc 10\n");
214 mpeg3io_read_data(buffer, mpeg3io_total_bytes(file->fs), file->fs);
215 //printf("read_toc 10\n");
218 //printf("read_toc %lld\n", mpeg3io_total_bytes(file->fs));
220 // File type
221 file_type = buffer[position++];
222 switch(file_type)
224 case FILE_TYPE_PROGRAM:
225 file->is_program_stream = 1;
226 break;
227 case FILE_TYPE_TRANSPORT:
228 file->is_transport_stream = 1;
229 break;
230 case FILE_TYPE_AUDIO:
231 file->is_audio_stream = 1;
232 break;
233 case FILE_TYPE_VIDEO:
234 file->is_video_stream = 1;
235 break;
238 //printf("read_toc 10\n");
240 // Stream ID's
241 while((stream_type = buffer[position]) != TITLE_PATH)
243 int offset;
244 int stream_id;
246 //printf("read_toc %d %x\n", position, buffer[position]);
247 position++;
248 offset = read_int32(buffer, &position);
249 stream_id = read_int32(buffer, &position);
251 if(stream_type == STREAM_AUDIO)
253 file->demuxer->astream_table[offset] = stream_id;
256 if(stream_type == STREAM_VIDEO)
258 file->demuxer->vstream_table[offset] = stream_id;
264 //printf("read_toc 10\n");
267 // Titles
268 while(buffer[position] == TITLE_PATH)
270 char string[MPEG3_STRLEN];
271 int string_len = 0;
272 mpeg3_title_t *title;
274 position++;
275 if(is_vfs)
277 strcpy(string, RENDERFARM_FS_PREFIX);
278 string_len = strlen(string);
280 while(buffer[position] != 0) string[string_len++] = buffer[position++];
281 string[string_len++] = 0;
282 position++;
284 title =
285 file->demuxer->titles[file->demuxer->total_titles++] =
286 mpeg3_new_title(file, string);
288 title->total_bytes = read_int64(buffer, &position);
290 // Cells
291 title->timecode_table_size =
292 title->timecode_table_allocation =
293 read_int32(buffer, &position);
294 title->timecode_table = calloc(title->timecode_table_size, sizeof(mpeg3demux_timecode_t));
295 for(i = 0; i < title->timecode_table_size; i++)
297 title->timecode_table[i].start_byte = read_int64(buffer, &position);
298 title->timecode_table[i].end_byte = read_int64(buffer, &position);
299 title->timecode_table[i].program = read_int32(buffer, &position);
302 //printf("read_toc 10\n");
306 // Audio streams
307 // Skip ATRACK_COUNT
308 position++;
309 atracks = read_int32(buffer, &position);
310 //printf("read_toc 10\n");
312 // Skip VTRACK_COUNT
313 position++;
314 vtracks = read_int32(buffer, &position);
315 //printf("read_toc 10\n");
318 if(atracks)
320 file->channel_counts = calloc(sizeof(int), atracks);
321 file->sample_offsets = malloc(sizeof(int64_t*) * atracks);
322 file->total_sample_offsets = malloc(sizeof(int*) * atracks);
324 for(i = 0; i < atracks; i++)
326 file->channel_counts[i] = read_int32(buffer, &position);
327 file->total_sample_offsets[i] = read_int32(buffer, &position);
328 file->sample_offsets[i] = malloc(file->total_sample_offsets[i] * sizeof(int64_t));
329 for(j = 0; j < file->total_sample_offsets[i]; j++)
331 file->sample_offsets[i][j] = read_int64(buffer, &position);
332 //printf("samples %llx\n", file->sample_offsets[i][j]);
336 //printf("read_toc 10\n");
338 if(vtracks)
340 file->frame_offsets = malloc(sizeof(int64_t*) * vtracks);
341 file->total_frame_offsets = malloc(sizeof(int*) * vtracks);
342 file->keyframe_numbers = malloc(sizeof(int64_t*) * vtracks);
343 file->total_keyframe_numbers = malloc(sizeof(int*) * vtracks);
345 for(i = 0; i < vtracks; i++)
347 file->total_frame_offsets[i] = read_int32(buffer, &position);
348 file->frame_offsets[i] = malloc(file->total_frame_offsets[i] * sizeof(int64_t));
349 for(j = 0; j < file->total_frame_offsets[i]; j++)
351 file->frame_offsets[i][j] = read_int64(buffer, &position);
352 //printf("frame %llx\n", file->frame_offsets[i][j]);
356 file->total_keyframe_numbers[i] = read_int32(buffer, &position);
357 file->keyframe_numbers[i] = malloc(file->total_keyframe_numbers[i] * sizeof(int64_t));
358 for(j = 0; j < file->total_keyframe_numbers[i]; j++)
360 file->keyframe_numbers[i][j] = read_int64(buffer, &position);
364 //printf("read_toc 10\n");
366 free(buffer);
367 //printf("read_toc 10\n");
371 //printf("read_toc 1\n");
372 mpeg3demux_open_title(file->demuxer, 0);
373 //printf("read_toc 10\n");
375 //printf("read_toc 2 %llx\n", mpeg3demux_tell(file->demuxer));
376 return 0;
382 mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file)
384 mpeg3_t *file = 0;
385 unsigned int bits;
386 int i, done;
388 /* Initialize the file structure */
389 file = mpeg3_new(path);
397 //printf("mpeg3_open_copy 1 %s\n", path);
399 /* Need to perform authentication before reading a single byte. */
400 if(mpeg3io_open_file(file->fs))
402 mpeg3_delete(file);
403 return 0;
418 /* =============================== Create the title objects ========================= */
419 bits = mpeg3io_read_int32(file->fs);
420 //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);
422 if(bits == MPEG3_TOC_PREFIX) /* TOC */
424 /* Table of contents for another title set */
425 if(!old_file)
427 //printf("libmpeg3 10\n");
428 if(read_toc(file))
430 //printf("libmpeg3 20\n");
431 mpeg3io_close_file(file->fs);
432 //printf("libmpeg3 21n");
433 mpeg3_delete(file);
434 //printf("libmpeg3 22\n");
435 return 0;
437 //printf("libmpeg3 30\n");
439 mpeg3io_close_file(file->fs);
440 //printf("libmpeg3 40\n");
442 else
443 // IFO file
444 if(bits == MPEG3_IFO_PREFIX)
446 //printf("libmpeg3 1\n");
447 if(!old_file)
449 //printf("libmpeg3 2\n");
450 if(mpeg3_read_ifo(file, 0))
452 mpeg3_delete(file);
453 mpeg3io_close_file(file->fs);
454 return 0;
456 //printf("libmpeg3 3\n");
458 file->is_ifo_file = 1;
459 mpeg3io_close_file(file->fs);
461 else
462 if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
464 /* Transport stream */
465 //printf("libmpeg3 2\n");
466 file->is_transport_stream = 1;
468 else
469 if(bits == MPEG3_PACK_START_CODE)
471 /* Program stream */
472 /* Determine packet size empirically */
473 //printf("libmpeg3 3\n");
474 file->is_program_stream = 1;
476 else
477 if((bits & 0xfff00000) == 0xfff00000 ||
478 (bits & 0xffff0000) == 0xffe30000 ||
479 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
480 (bits == MPEG3_RIFF_CODE))
482 /* MPEG Audio only */
483 //printf("libmpeg3 4\n");
484 file->is_audio_stream = 1;
486 else
487 if(bits == MPEG3_SEQUENCE_START_CODE ||
488 bits == MPEG3_PICTURE_START_CODE)
490 /* Video only */
491 //printf("libmpeg3 5\n");
492 file->is_video_stream = 1;
494 else
495 if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
497 /* AC3 Audio only */
498 //printf("libmpeg3 6\n");
499 file->is_audio_stream = 1;
501 else
503 //printf("libmpeg3 7\n");
504 mpeg3_delete(file);
505 fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n");
506 return 0;
510 * printf("mpeg3_open 2 %p %d %d %d %d\n",
511 * old_file,
512 * file->is_transport_stream,
513 * file->is_program_stream,
514 * file->is_video_stream,
515 * file->is_audio_stream);
524 //printf("mpeg3_open 20\n");
530 // Configure packet size
531 if(file->is_transport_stream)
532 file->packet_size = MPEG3_TS_PACKET_SIZE;
533 else
534 if(file->is_program_stream)
535 file->packet_size = 0;
536 else
537 if(file->is_audio_stream)
538 file->packet_size = MPEG3_DVD_PACKET_SIZE;
539 else
540 if(file->is_video_stream)
541 file->packet_size = MPEG3_DVD_PACKET_SIZE;
555 //printf("mpeg3_open 1\n");
557 /* Create titles */
558 /* Copy timecodes from an old demuxer */
559 if(old_file && mpeg3_get_demuxer(old_file))
561 mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file));
562 file->is_transport_stream = old_file->is_transport_stream;
563 file->is_program_stream = old_file->is_program_stream;
565 else
566 /* Start from scratch */
567 if(!file->demuxer->total_titles)
569 mpeg3demux_create_title(file->demuxer, 0, 0);
574 //printf("mpeg3_open 50\n");
586 /* Generate tracks */
587 if(file->is_transport_stream || file->is_program_stream)
589 /* Create video tracks */
590 /* Video must be created before audio because audio uses the video timecode */
591 /* to get its length. */
593 * for(i = 0; i < MPEG3_MAX_STREAMS; i++)
595 * if(file->demuxer->vstream_table[i])
596 * printf(__FUNCTION__ " %x %x\n", i, file->demuxer->vstream_table[i]);
598 * for(i = 0; i < MPEG3_MAX_STREAMS; i++)
600 * if(file->demuxer->astream_table[i])
601 * printf(__FUNCTION__ " %x %x\n", i, file->demuxer->astream_table[i]);
606 //printf("mpeg3_open 3\n");
607 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
609 if(file->demuxer->vstream_table[i])
611 file->vtrack[file->total_vstreams] =
612 mpeg3_new_vtrack(file,
614 file->demuxer,
615 file->total_vstreams);
616 if(file->vtrack[file->total_vstreams])
617 file->total_vstreams++;
619 //printf("libmpeg3 %d %d %p %d\n", i, file->demuxer->vstream_table[i], file->vtrack[file->total_vstreams], file->total_vstreams);
623 //printf("mpeg3_open 4\n");
624 /* Create audio tracks */
625 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
627 if(file->demuxer->astream_table[i])
629 file->atrack[file->total_astreams] = mpeg3_new_atrack(file,
631 file->demuxer->astream_table[i],
632 file->demuxer,
633 file->total_astreams);
634 if(file->atrack[file->total_astreams]) file->total_astreams++;
637 //printf("mpeg3_open 5\n");
639 else
640 if(file->is_video_stream)
642 /* Create video tracks */
643 //printf("mpeg3_open 3\n");
644 file->vtrack[0] = mpeg3_new_vtrack(file,
645 -1,
646 file->demuxer,
648 //printf("mpeg3_open 4\n");
649 if(file->vtrack[0]) file->total_vstreams++;
651 else
652 if(file->is_audio_stream)
654 /* Create audio tracks */
656 //printf("mpeg3_open 3\n");
657 file->atrack[0] = mpeg3_new_atrack(file,
658 -1,
659 AUDIO_UNKNOWN,
660 file->demuxer,
662 //printf("mpeg3_open 3\n");
663 if(file->atrack[0]) file->total_astreams++;
666 //printf("mpeg3_open 100\n");
670 mpeg3io_close_file(file->fs);
671 //printf("mpeg3_open 120\n");
672 return file;
675 mpeg3_t* mpeg3_open(char *path)
677 return mpeg3_open_copy(path, 0);
680 int mpeg3_close(mpeg3_t *file)
682 /* File is closed in the same procedure it is opened in. */
683 mpeg3_delete(file);
684 return 0;
687 int mpeg3_set_cpus(mpeg3_t *file, int cpus)
689 int i;
690 file->cpus = cpus;
691 for(i = 0; i < file->total_vstreams; i++)
692 mpeg3video_set_cpus(file->vtrack[i]->video, cpus);
693 return 0;
696 int mpeg3_set_mmx(mpeg3_t *file, int use_mmx)
698 int i;
699 file->have_mmx = use_mmx;
700 for(i = 0; i < file->total_vstreams; i++)
701 mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx);
702 return 0;
705 int mpeg3_has_audio(mpeg3_t *file)
707 return file->total_astreams > 0;
710 int mpeg3_total_astreams(mpeg3_t *file)
712 return file->total_astreams;
715 int mpeg3_audio_channels(mpeg3_t *file,
716 int stream)
718 if(file->total_astreams)
719 return file->atrack[stream]->channels;
720 return -1;
723 int mpeg3_sample_rate(mpeg3_t *file,
724 int stream)
726 if(file->total_astreams)
727 return file->atrack[stream]->sample_rate;
728 return -1;
731 long mpeg3_get_sample(mpeg3_t *file,
732 int stream)
734 if(file->total_astreams)
735 return file->atrack[stream]->current_position;
736 return -1;
739 int mpeg3_set_sample(mpeg3_t *file,
740 long sample,
741 int stream)
743 if(file->total_astreams)
745 //printf(__FUNCTION__ " 1 %d %d\n", file->atrack[stream]->current_position, sample);
746 file->atrack[stream]->current_position = sample;
747 mpeg3audio_seek_sample(file->atrack[stream]->audio, sample);
748 return 0;
750 return -1;
753 long mpeg3_audio_samples(mpeg3_t *file,
754 int stream)
756 if(file->total_astreams)
757 return file->atrack[stream]->total_samples;
758 return -1;
761 char* mpeg3_audio_format(mpeg3_t *file, int stream)
763 if(stream < file->total_astreams)
765 switch(file->atrack[stream]->format)
767 case AUDIO_UNKNOWN: return "Unknown"; break;
768 case AUDIO_MPEG: return "MPEG"; break;
769 case AUDIO_AC3: return "AC3"; break;
770 case AUDIO_PCM: return "PCM"; break;
771 case AUDIO_AAC: return "AAC"; break;
772 case AUDIO_JESUS: return "Vorbis"; break;
775 return "";
778 int mpeg3_has_video(mpeg3_t *file)
780 return file->total_vstreams > 0;
783 int mpeg3_total_vstreams(mpeg3_t *file)
785 return file->total_vstreams;
788 int mpeg3_video_width(mpeg3_t *file,
789 int stream)
791 if(file->total_vstreams)
792 return file->vtrack[stream]->width;
793 return -1;
796 int mpeg3_video_height(mpeg3_t *file,
797 int stream)
799 if(file->total_vstreams)
800 return file->vtrack[stream]->height;
801 return -1;
804 float mpeg3_aspect_ratio(mpeg3_t *file, int stream)
806 if(file->total_vstreams)
807 return file->vtrack[stream]->aspect_ratio;
808 return 0;
811 double mpeg3_frame_rate(mpeg3_t *file,
812 int stream)
814 if(file->total_vstreams)
815 return file->vtrack[stream]->frame_rate;
816 return -1;
819 long mpeg3_video_frames(mpeg3_t *file,
820 int stream)
822 if(file->total_vstreams)
823 return file->vtrack[stream]->total_frames;
824 return -1;
827 long mpeg3_get_frame(mpeg3_t *file,
828 int stream)
830 if(file->total_vstreams)
831 return file->vtrack[stream]->current_position;
832 return -1;
835 int mpeg3_set_frame(mpeg3_t *file,
836 long frame,
837 int stream)
839 if(file->total_vstreams)
841 file->vtrack[stream]->current_position = frame;
842 mpeg3video_seek_frame(file->vtrack[stream]->video, frame);
843 return 0;
845 return -1;
848 int mpeg3_seek_percentage(mpeg3_t *file, double percentage)
850 int i;
852 file->percentage_pts = -1;
853 for(i = 0; i < file->total_vstreams; i++)
855 file->vtrack[i]->current_position = 0;
856 mpeg3video_seek_percentage(file->vtrack[i]->video, percentage);
859 for(i = 0; i < file->total_astreams; i++)
861 file->atrack[i]->current_position = 0;
862 mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage);
865 return 0;
868 double mpeg3_get_percentage_pts(mpeg3_t *file)
870 return file->percentage_pts;
873 void mpeg3_set_percentage_pts(mpeg3_t *file, double pts)
878 int mpeg3_previous_frame(mpeg3_t *file, int stream)
880 file->last_type_read = 2;
881 file->last_stream_read = stream;
883 if(file->total_vstreams)
884 return mpeg3video_previous_frame(file->vtrack[stream]->video);
886 return 0;
889 double mpeg3_tell_percentage(mpeg3_t *file)
891 double percent = 0;
892 if(file->last_type_read == 1)
894 percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer);
897 if(file->last_type_read == 2)
899 percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer);
901 return percent;
904 double mpeg3_get_time(mpeg3_t *file)
906 double atime = 0, vtime = 0;
908 if(file->is_transport_stream || file->is_program_stream)
910 /* Timecode only available in transport stream */
911 if(file->last_type_read == 1)
913 atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer);
915 else
916 if(file->last_type_read == 2)
918 vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer);
921 else
923 /* Use percentage and total time */
924 if(file->total_astreams)
926 atime = mpeg3demux_tell_percentage(file->atrack[0]->demuxer) *
927 mpeg3_audio_samples(file, 0) / mpeg3_sample_rate(file, 0);
930 if(file->total_vstreams)
932 vtime = mpeg3demux_tell_percentage(file->vtrack[0]->demuxer) *
933 mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0);
937 return MAX(atime, vtime);
940 int mpeg3_end_of_audio(mpeg3_t *file, int stream)
942 int result = 0;
943 if(!file->atrack[stream]->channels) return 1;
944 result = mpeg3demux_eof(file->atrack[stream]->demuxer);
945 return result;
948 int mpeg3_end_of_video(mpeg3_t *file, int stream)
950 int result = 0;
951 result = mpeg3demux_eof(file->vtrack[stream]->demuxer);
952 return result;
956 int mpeg3_read_frame(mpeg3_t *file,
957 unsigned char **output_rows,
958 int in_x,
959 int in_y,
960 int in_w,
961 int in_h,
962 int out_w,
963 int out_h,
964 int color_model,
965 int stream)
967 int result = -1;
969 if(file->total_vstreams)
971 //printf(__FUNCTION__ " 1 %d\n", file->vtrack[stream]->current_position);
972 result = mpeg3video_read_frame(file->vtrack[stream]->video,
973 file->vtrack[stream]->current_position,
974 output_rows,
975 in_x,
976 in_y,
977 in_w,
978 in_h,
979 out_w,
980 out_h,
981 color_model);
982 //printf(__FUNCTION__ " 2\n");
983 file->last_type_read = 2;
984 file->last_stream_read = stream;
985 file->vtrack[stream]->current_position++;
987 return result;
990 int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream)
992 int result = -1;
994 if(file->total_vstreams)
996 result = mpeg3video_drop_frames(file->vtrack[stream]->video,
997 frames);
998 if(frames > 0) file->vtrack[stream]->current_position += frames;
999 file->last_type_read = 2;
1000 file->last_stream_read = stream;
1002 return result;
1005 int mpeg3_colormodel(mpeg3_t *file, int stream)
1007 if(file->total_vstreams)
1009 return mpeg3video_colormodel(file->vtrack[stream]->video);
1011 return 0;
1014 int mpeg3_set_rowspan(mpeg3_t *file, int bytes, int stream)
1016 if(file->total_vstreams)
1018 file->vtrack[stream]->video->row_span = bytes;
1020 return 0;
1024 int mpeg3_read_yuvframe(mpeg3_t *file,
1025 char *y_output,
1026 char *u_output,
1027 char *v_output,
1028 int in_x,
1029 int in_y,
1030 int in_w,
1031 int in_h,
1032 int stream)
1034 int result = -1;
1036 //printf("mpeg3_read_yuvframe 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
1037 if(file->total_vstreams)
1039 result = mpeg3video_read_yuvframe(file->vtrack[stream]->video,
1040 file->vtrack[stream]->current_position,
1041 y_output,
1042 u_output,
1043 v_output,
1044 in_x,
1045 in_y,
1046 in_w,
1047 in_h);
1048 file->last_type_read = 2;
1049 file->last_stream_read = stream;
1050 file->vtrack[stream]->current_position++;
1052 //printf("mpeg3_read_yuvframe 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
1053 return result;
1056 int mpeg3_read_yuvframe_ptr(mpeg3_t *file,
1057 char **y_output,
1058 char **u_output,
1059 char **v_output,
1060 int stream)
1062 int result = -1;
1064 //printf("mpeg3_read_yuvframe_ptr 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
1065 if(file->total_vstreams)
1067 result = mpeg3video_read_yuvframe_ptr(file->vtrack[stream]->video,
1068 file->vtrack[stream]->current_position,
1069 y_output,
1070 u_output,
1071 v_output);
1072 file->last_type_read = 2;
1073 file->last_stream_read = stream;
1074 file->vtrack[stream]->current_position++;
1076 //printf("mpeg3_read_yuvframe_ptr 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
1077 return result;
1080 int mpeg3_read_audio(mpeg3_t *file,
1081 float *output_f,
1082 short *output_i,
1083 int channel,
1084 long samples,
1085 int stream)
1087 int result = -1;
1089 if(file->total_astreams)
1091 result = mpeg3audio_decode_audio(file->atrack[stream]->audio,
1092 output_f,
1093 output_i,
1094 channel,
1095 samples);
1096 file->last_type_read = 1;
1097 file->last_stream_read = stream;
1098 file->atrack[stream]->current_position += samples;
1101 return result;
1104 int mpeg3_reread_audio(mpeg3_t *file,
1105 float *output_f,
1106 short *output_i,
1107 int channel,
1108 long samples,
1109 int stream)
1111 if(file->total_astreams)
1113 mpeg3_set_sample(file,
1114 file->atrack[stream]->current_position - samples,
1115 stream);
1116 file->last_type_read = 1;
1117 file->last_stream_read = stream;
1118 return mpeg3_read_audio(file,
1119 output_f,
1120 output_i,
1121 channel,
1122 samples,
1123 stream);
1125 return -1;
1128 int mpeg3_read_audio_chunk(mpeg3_t *file,
1129 unsigned char *output,
1130 long *size,
1131 long max_size,
1132 int stream)
1134 int result = 0;
1135 if(file->total_astreams)
1137 result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size);
1138 file->last_type_read = 1;
1139 file->last_stream_read = stream;
1141 return result;
1144 int mpeg3_read_video_chunk(mpeg3_t *file,
1145 unsigned char *output,
1146 long *size,
1147 long max_size,
1148 int stream)
1150 int result = 0;
1151 if(file->total_vstreams)
1153 result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size);
1154 file->last_type_read = 2;
1155 file->last_stream_read = stream;
1157 return result;