fix GPL license information and dates
[goodguy/cinelerra.git] / cinelerra-5.1 / libzmpeg3 / mpeg3dump.C
1 #include <stdlib.h>
2 #include <string.h>
3 #include "libzmpeg3.h"
4
5 #define BUFSIZE 65536
6
7 void test_32bit_overflow(char *outfile, int (*out_counter), FILE *(*out))
8 {
9   if( ftell(*out) > 0x7f000000 ) {
10     char string[1024];
11     fclose(*out);
12     sprintf(string, "%s%03d", outfile, ++(*out_counter));
13     (*out) = fopen(string, "wb");
14   }
15 }
16
17 int main(int argc, char *argv[])
18 {
19   zmpeg3_t *file;
20   int i, j, len, result = 0;
21   int out_counter = 0;
22   float *audio_output_f;
23   unsigned char *audio_output_i;
24   FILE *out;
25   char outfile[1024];
26   int decompress_audio = 0;
27   int audio_track = 0;
28 /* Print cell offsets */
29   int print_offsets = 0;
30   int print_pids = 1;
31
32   outfile[0] = 0;
33   if( argc < 2 ) {
34     printf( "Dump information or extract audio to a 24 bit pcm file.\n"
35             "Example: dump -a0 outputfile.pcm take1.vob\n");
36     exit(1);
37   }
38
39   for( i=1; i < argc; ++i ) {
40     if( !strncmp(argv[i], "-a", 2) ) {
41 // Check for track number
42       if( strlen(argv[i]) > 2 ) {
43         audio_track = atol(argv[i] + 2);
44       }
45
46 // Check for filename
47       if( i + 1 < argc ) {
48         strcpy(outfile, argv[++i]);
49         decompress_audio = 1;
50       }
51       else {
52         fprintf(stderr, "-a must be paired with a filename.\n");
53         exit(1);
54       }
55
56 // Check if file exists
57       if( (out = fopen(outfile, "r")) ) {
58         fprintf(stderr, "%s exists.\n", outfile);
59         exit(1);
60       }
61     }
62   }
63
64   int error = 0;
65   file = mpeg3_open(argv[argc - 1], &error);
66   if( outfile[0] ) {
67     out = fopen(outfile, "wb");
68   }
69
70
71   if( file ) {
72 // Audio streams
73     fprintf(stderr, "total_astreams=%d\n", mpeg3_total_astreams(file));
74
75     for( i=0; i < mpeg3_total_astreams(file); ++i ) {
76       fprintf(stderr, "  Stream 0x%04x: channels=%d rate=%d samples=%ld format=%s\n", 
77         file->atrack[i]->demuxer->astream, 
78         mpeg3_audio_channels(file, i), 
79         mpeg3_sample_rate(file, i),
80         mpeg3_audio_samples(file, i),
81         mpeg3_audio_format(file, i));
82       
83       if( print_offsets ) {
84         fprintf(stderr, "total_sample_offsets=%d\n", file->atrack[i]->total_sample_offsets);
85         for( j=0; j < file->atrack[i]->total_sample_offsets; ++j ) {
86           fprintf(stderr, "%jx ", file->atrack[i]->sample_offsets[j]);
87           if( j > 0 && !(j % 8)) fprintf(stderr, "\n" );
88         }
89         fprintf(stderr, "\n");
90       }
91     }
92
93 // Video streams
94     fprintf(stderr, "total_vstreams=%d\n", mpeg3_total_vstreams(file));
95
96     for( i=0; i < mpeg3_total_vstreams(file); ++i ) {
97       fprintf(stderr, "  Stream 0x%04x: w=%d h=%d framerate=%0.3f frames=%ld coding=%s\n", 
98         file->vtrack[i]->demuxer->vstream, 
99         mpeg3_video_width(file, i), 
100         mpeg3_video_height(file, i), 
101         mpeg3_frame_rate(file, i),
102         mpeg3_video_frames(file, i),
103         mpeg3_colormodel(file, i) == zmpeg3_t::cmdl_YUV420P ? "420" : "422");
104       
105       if( print_offsets ) {
106         fprintf(stderr, "total_frame_offsets=%d\n", file->vtrack[i]->total_frame_offsets);
107         for( j=0; j < file->vtrack[i]->total_frame_offsets; ++j ) {
108           fprintf(stderr, "%d=%jx ", j, file->vtrack[i]->frame_offsets[j]);
109           if( j > 0 && !(j % 8)) fprintf(stderr, "\n" );
110         }
111         fprintf(stderr, "\n");
112
113         fprintf(stderr, "total_keyframe_numbers=%d\n", file->vtrack[i]->total_keyframe_numbers);
114         for( j=0; j < file->vtrack[i]->total_keyframe_numbers; ++j ) {
115           fprintf(stderr, "%d ", file->vtrack[i]->keyframe_numbers[j]);
116           if( j > 0 && !(j % 8)) fprintf(stderr, "\n" );
117         }
118         fprintf(stderr, "\n");
119       }
120     }
121
122 // Subtitle tracks
123     printf("total subtitle tracks: %d\n", mpeg3_subtitle_tracks(file));
124     for( i=0; i < mpeg3_subtitle_tracks(file); ++i ) {
125       zstrack_t *strack = file->strack[i];
126       printf("  stream: 0x%02x total_offsets: %d\n", 
127         strack->id, strack->total_offsets);
128       if( print_offsets ) {
129         for( j=0; j < strack->total_offsets; ++j ) {
130           printf("%jx ", strack->offsets[j]);
131         }
132         printf("\n");
133       }
134     }
135
136 // Titles
137     fprintf(stderr, "total_titles=%d\n", file->demuxer->total_titles);
138     for( i=0; i < file->demuxer->total_titles; ++i ) {
139       fprintf(stderr, "  Title path=%s total_bytes=%jx cell_table_size=%d\n", 
140         file->demuxer->titles[i]->fs->path,
141         file->demuxer->titles[i]->total_bytes, 
142         file->demuxer->titles[i]->cell_table_size);
143       
144       if( print_offsets ) {
145         for( j=0; j < file->demuxer->titles[i]->cell_table_size; ++j )
146           fprintf(stderr, "    Cell: %jx-%jx %jx-%jx\n", 
147             file->demuxer->titles[i]->cell_table[j].program_start, 
148             file->demuxer->titles[i]->cell_table[j].program_end,
149             file->demuxer->titles[i]->cell_table[j].title_start, 
150             file->demuxer->titles[i]->cell_table[j].title_end);
151       }
152     }
153
154 // Pids
155     if( print_pids ) {
156       zdemuxer_t *demuxer = file->demuxer;
157       printf("Total PIDs=%d\n", demuxer->total_pids);
158       for( i=0; i < demuxer->total_pids; ++i ) {
159         printf("0x%04x ", demuxer->pid_table[i]);
160       }
161       printf("\n");
162     }
163
164 // Write audio
165     if( decompress_audio ) {
166       mpeg3_set_cpus(file, 2);
167       audio_output_f = new float[BUFSIZE];
168       len = BUFSIZE * 3 * mpeg3_audio_channels(file, audio_track);
169       audio_output_i = new unsigned char[len];
170
171 //printf("%d\n", mpeg3_end_of_audio(file, audio_track));
172       while( !mpeg3_end_of_audio(file, audio_track) && !result ) {
173         test_32bit_overflow(outfile, &out_counter, &out);
174         
175         for( i=0; i < mpeg3_audio_channels(file, audio_track); ++i ) {
176           if( i == 0 )
177               result = mpeg3_read_audio(file, audio_output_f, 
178                           0, i, BUFSIZE, audio_track);
179           else /* Pointer to pre-allocated buffer of floats */
180             result = mpeg3_reread_audio(file, audio_output_f,
181                           0, i, BUFSIZE, audio_track);
182           for( j=0; j < BUFSIZE; ++j ) {
183             int sample = audio_output_f[j] * 0x7fffff;
184             unsigned char * output_i = audio_output_i + j * 3 *
185               mpeg3_audio_channels(file, audio_track) + i * 3;
186             if( sample > 0x7fffff ) 
187               sample = 0x7fffff;
188             else if( sample < -0x7fffff )
189               sample = -0x7fffff;
190             *output_i++ = (sample & 0xff0000) >> 16;
191             *output_i++ = (sample & 0xff00) >> 8;
192             *output_i = sample & 0xff;
193           }
194         }
195
196         len = BUFSIZE * 3 * mpeg3_audio_channels(file, audio_track);
197         result = !fwrite(audio_output_i, len, 1, out);
198       }
199     }
200
201 /*
202  *     len = BUFSIZE * 2 * mpeg3_audio_channels(file, 0);
203  *     audio_output_i = unsigned char[len];
204  *     mpeg3_seek_percentage(file, 0.1);
205  *     result = mpeg3_read_audio(file, 0, audio_output_i, 1, BUFSIZE, 0);
206  */
207
208 /*
209  *       len = mpeg3_video_width(file, 0) * mpeg3_video_height(file, 0) * 3 + 4;
210  *       output = unsigned char[len];
211  *       len = sizeof(unsigned char*) * mpeg3_video_height(file, 0);
212  *       output_rows = unsigned char *[len];
213  *       for( i=0; i < mpeg3_video_height(file, 0); ++i )
214  *         output_rows[i] = &output[i * mpeg3_video_width(file, 0) * 3];
215  * printf("dump 1\n");
216  *      mpeg3_seek_percentage(file, 0.375);
217  *      result = mpeg3_read_frame(file, 
218  *            output_rows, 
219  *            0, 
220  *            0, 
221  *            mpeg3_video_width(file, 0), 
222  *           mpeg3_video_height(file, 0), 
223  *            mpeg3_video_width(file, 0), 
224  *            mpeg3_video_height(file, 0), 
225  *           MPEG3_RGB888, 
226  *            0);
227  * printf("dump 2\n");
228  */
229
230     mpeg3_close(file);
231   }
232   return 0;
233 }