summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libmpeg3/mpeg3cat.c') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3cat.c225
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
12int 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}