author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/multimedia/opieplayer/libmpeg3/mpeg3cat.c | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/mpeg3cat.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/mpeg3cat.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c b/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c new file mode 100644 index 0000000..20f7660 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* Concatenate elementary streams */ | ||
2 | |||
3 | #include "libmpeg3.h" | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #define MPEG3_SEQUENCE_START_CODE 0x000001b3 | ||
10 | #define BUFFER_SIZE 1000000 | ||
11 | |||
12 | int main(int argc, char *argv[]) | ||
13 | { | ||
14 | char inpath[1024]; | ||
15 | mpeg3_t *in; | ||
16 | int current_file, current_output_file = 0, i; | ||
17 | unsigned int bits; | ||
18 | unsigned char *buffer; | ||
19 | long output_size; | ||
20 | int result = 0; | ||
21 | long total_frames = 0; | ||
22 | int do_audio = 0, do_video = 0; | ||
23 | int stream = 0; | ||
24 | |||
25 | if(argc < 2) | ||
26 | { | ||
27 | fprintf(stderr, "Concatenate elementary streams or demultiplex a program stream.\n" | ||
28 | "Usage: mpeg3cat -[av0123456789] <infile> [infile...] > <outfile>\n\n" | ||
29 | "Example: Concatenate 2 video files: mpeg3cat xena1.m2v xena2.m2v > xena.m2v\n" | ||
30 | " Extract audio stream 0: mpeg3cat -a0 xena.vob > war_cry.ac3\n"); | ||
31 | exit(1); | ||
32 | } | ||
33 | |||
34 | for(i = 1; i < argc; i++) | ||
35 | { | ||
36 | if(argv[i][0] == '-') | ||
37 | { | ||
38 | if(argv[i][1] != 'a' && argv[i][1] != 'v') | ||
39 | { | ||
40 | fprintf(stderr, "invalid option %s\n", argv[i]); | ||
41 | } | ||
42 | else | ||
43 | { | ||
44 | if(argv[i][1] == 'a') do_audio = 1; | ||
45 | else | ||
46 | if(argv[i][1] == 'v') do_video = 1; | ||
47 | |||
48 | if(argv[i][2] != 0) | ||
49 | { | ||
50 | stream = argv[i][2] - 48; | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
56 | buffer = (unsigned char*)malloc(BUFFER_SIZE); | ||
57 | |||
58 | for(current_file = 1; current_file < argc; current_file++) | ||
59 | { | ||
60 | if(argv[current_file][0] == '-') continue; | ||
61 | |||
62 | strcpy(inpath, argv[current_file]); | ||
63 | if(!(in = mpeg3_open(inpath))) | ||
64 | { | ||
65 | fprintf(stderr, "Skipping %s\n", inpath); | ||
66 | continue; | ||
67 | } | ||
68 | |||
69 | if((mpeg3_has_audio(in) && in->is_audio_stream) || | ||
70 | (do_audio && !in->is_audio_stream && !in->is_video_stream)) | ||
71 | { | ||
72 | do_audio = 1; | ||
73 | /* Add audio stream to end */ | ||
74 | while(!mpeg3_read_audio_chunk(in, buffer, | ||
75 | &output_size, | ||
76 | BUFFER_SIZE, | ||
77 | stream)) | ||
78 | { | ||
79 | result = !fwrite(buffer, output_size, 1, stdout); | ||
80 | if(result) | ||
81 | { | ||
82 | perror("fwrite audio chunk"); | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | else | ||
88 | if((mpeg3_has_video(in) && in->is_video_stream) || | ||
89 | (do_video && !in->is_video_stream && !in->is_audio_stream)) | ||
90 | { | ||
91 | /* Add video stream to end */ | ||
92 | int hour, minute, second, frame; | ||
93 | long gop_frame; | ||
94 | unsigned long code; | ||
95 | float carry; | ||
96 | int i, offset; | ||
97 | |||
98 | do_video = 1; | ||
99 | while(!mpeg3_read_video_chunk(in, | ||
100 | buffer, | ||
101 | &output_size, | ||
102 | BUFFER_SIZE, | ||
103 | stream) && | ||
104 | output_size >= 4) | ||
105 | { | ||
106 | code = (unsigned long)buffer[output_size - 4] << 24; | ||
107 | code |= (unsigned long)buffer[output_size - 3] << 16; | ||
108 | code |= (unsigned long)buffer[output_size - 2] << 8; | ||
109 | code |= (unsigned long)buffer[output_size - 1]; | ||
110 | |||
111 | /* Got a frame at the end of this buffer. */ | ||
112 | if(code == MPEG3_PICTURE_START_CODE) | ||
113 | { | ||
114 | total_frames++; | ||
115 | } | ||
116 | else | ||
117 | if(code == MPEG3_SEQUENCE_END_CODE) | ||
118 | { | ||
119 | /* Got a sequence end code at the end of this buffer. */ | ||
120 | output_size -= 4; | ||
121 | } | ||
122 | |||
123 | code = (unsigned long)buffer[0] << 24; | ||
124 | code |= (unsigned long)buffer[1] << 16; | ||
125 | code |= (unsigned long)buffer[2] << 8; | ||
126 | code |= buffer[3]; | ||
127 | |||
128 | i = 0; | ||
129 | offset = 0; | ||
130 | if(code == MPEG3_SEQUENCE_START_CODE && current_output_file > 0) | ||
131 | { | ||
132 | /* Skip the sequence start code */ | ||
133 | i += 4; | ||
134 | while(i < output_size && | ||
135 | code != MPEG3_GOP_START_CODE) | ||
136 | { | ||
137 | code <<= 8; | ||
138 | code |= buffer[i++]; | ||
139 | } | ||
140 | i -= 4; | ||
141 | offset = i; | ||
142 | } | ||
143 | |||
144 | /* Search for GOP header to fix */ | ||
145 | code = (unsigned long)buffer[i++] << 24; | ||
146 | code |= (unsigned long)buffer[i++] << 16; | ||
147 | code |= (unsigned long)buffer[i++] << 8; | ||
148 | code |= buffer[i++]; | ||
149 | while(i < output_size && | ||
150 | code != MPEG3_GOP_START_CODE) | ||
151 | { | ||
152 | code <<= 8; | ||
153 | code |= buffer[i++]; | ||
154 | } | ||
155 | |||
156 | if(code == MPEG3_GOP_START_CODE) | ||
157 | { | ||
158 | /* Get the time code */ | ||
159 | code = (unsigned long)buffer[i] << 24; | ||
160 | code |= (unsigned long)buffer[i + 1] << 16; | ||
161 | code |= (unsigned long)buffer[i + 2] << 8; | ||
162 | code |= (unsigned long)buffer[i + 3]; | ||
163 | |||
164 | hour = code >> 26 & 0x1f; | ||
165 | minute = code >> 20 & 0x3f; | ||
166 | second = code >> 13 & 0x3f; | ||
167 | frame = code >> 7 & 0x3f; | ||
168 | |||
169 | gop_frame = (long)(hour * 3600 * mpeg3_frame_rate(in, stream) + | ||
170 | minute * 60 * mpeg3_frame_rate(in, stream) + | ||
171 | second * mpeg3_frame_rate(in, stream) + | ||
172 | frame); | ||
173 | /* fprintf(stderr, "old: %02d:%02d:%02d:%02d ", hour, minute, second, frame); */ | ||
174 | /* Write a new time code */ | ||
175 | hour = (long)((float)(total_frames - 1) / mpeg3_frame_rate(in, stream) / 3600); | ||
176 | carry = hour * 3600 * mpeg3_frame_rate(in, stream); | ||
177 | minute = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream) / 60); | ||
178 | carry += minute * 60 * mpeg3_frame_rate(in, stream); | ||
179 | second = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream)); | ||
180 | carry += second * mpeg3_frame_rate(in, stream); | ||
181 | frame = (int)(total_frames - 1 - carry); | ||
182 | |||
183 | buffer[i] = ((code >> 24) & 0x80) | (hour << 2) | (minute >> 4); | ||
184 | buffer[i + 1] = ((code >> 16) & 0x08) | ((minute & 0xf) << 4) | (second >> 3); | ||
185 | buffer[i + 2] = ((second & 0x7) << 5) | (frame >> 1); | ||
186 | buffer[i + 3] = (code & 0x7f) | ((frame & 0x1) << 7); | ||
187 | /* fprintf(stderr, "new: %02d:%02d:%02d:%02d\n", hour, minute, second, frame); */ | ||
188 | } | ||
189 | |||
190 | /* Write the frame */ | ||
191 | result = !fwrite(buffer + offset, output_size - offset, 1, stdout); | ||
192 | if(result) | ||
193 | { | ||
194 | perror("fwrite video chunk"); | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | fprintf(stderr, "Unsupported stream type.\n"); | ||
202 | mpeg3_close(in); | ||
203 | in = 0; | ||
204 | continue; | ||
205 | } | ||
206 | |||
207 | mpeg3_close(in); | ||
208 | in = 0; | ||
209 | current_output_file++; | ||
210 | } | ||
211 | |||
212 | /* Terminate output */ | ||
213 | if(current_output_file > 0 && do_video) | ||
214 | { | ||
215 | /*fprintf(stderr, "\n"); */ | ||
216 | /* Write new end of sequence */ | ||
217 | buffer[0] = MPEG3_SEQUENCE_END_CODE >> 24; | ||
218 | buffer[1] = (MPEG3_SEQUENCE_END_CODE >> 16) & 0xff; | ||
219 | buffer[2] = (MPEG3_SEQUENCE_END_CODE >> 8) & 0xff; | ||
220 | buffer[3] = MPEG3_SEQUENCE_END_CODE & 0xff; | ||
221 | result = !fwrite(buffer, 4, 1, stdout); | ||
222 | } | ||
223 | |||
224 | exit(0); | ||
225 | } | ||