1 /*
2 * ARMovie/RPL demuxer
3 * Copyright (c) 2007 Christian Ohm, 2008 Eli Friedman
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <inttypes.h>
23 #include <stdlib.h>
24
29
30 #define RPL_SIGNATURE "ARMovie\x0A"
31 #define RPL_SIGNATURE_SIZE 8
32
33 /** 256 is arbitrary, but should be big enough for any reasonable file. */
34 #define RPL_LINE_LENGTH 256
35
37 {
39 return 0;
40
42 }
43
45 // RPL header data
47
48 // Stream position data
53
55 {
57 for (
i = 0;
i < bufsize - 1;
i++) {
60 break;
64 }
66 }
68 return -1;
69 }
70
72 {
75 if (
result > (0x7FFFFFFF - 9) / 10)
78 }
81 }
82
84 {
86 const char *endptr;
89 }
90
91 /** Parsing for fps, which can be a fraction. Unfortunately,
92 * the spec for the header leaves out a lot of details,
93 * so this is mostly guessing.
94 */
96 {
97 int64_t num, den = 1;
103 // Truncate any numerator too large to fit into an int64_t
104 if (num > (INT64_MAX - 9) / 10 || den > INT64_MAX / 10)
105 break;
106 num = 10 * num + (*
line -
'0');
107 den *= 10;
108 }
109 if (!num)
113 }
114
116 {
120 int total_audio_size;
122 const char *endptr;
125
127
128 int32_t video_format, audio_format, chunk_catalog_offset, number_of_chunks;
130
132
133 // The header for RPL/ARMovie files is 21 lines of text
134 // containing the various header fields. The fields are always
135 // in the same order, and other text besides the first
136 // number usually isn't important.
137 // (The spec says that there exists some significance
138 // for the text in a few cases; samples needed.)
146
147 // video headers
149 if (video_format) {
151 if (!vst)
158
159 // Figure out the video codec
161 #if 0
162 case 122:
164 break;
165 #endif
166 case 124:
168 // The header is wrong here, at least sometimes
170 break;
171 case 130:
173 break;
174 default:
178 }
179 } else {
180 for (
i = 0;
i < 3;
i++)
182 }
183
186 if (vst)
188
189 // Audio headers
190
191 // ARMovie supports multiple audio tracks; I don't have any
192 // samples, though. This code will ignore additional tracks.
196 if (audio_format) {
198 if (!ast)
201 ast->codecpar->codec_tag = audio_format;
205 ast->codecpar->bits_per_coded_sample =
read_int(
line, &endptr, &
error);
// audio bits per sample
207 // At least one sample uses 0 for ADPCM, which is really 4 bits
208 // per sample.
209 if (ast->codecpar->bits_per_coded_sample == 0)
210 ast->codecpar->bits_per_coded_sample = 4;
211
212 ast->codecpar->bit_rate = ast->codecpar->sample_rate *
213 (int64_t)ast->codecpar->channels;
214 if (ast->codecpar->bit_rate > INT64_MAX / ast->codecpar->bits_per_coded_sample)
216 ast->codecpar->bit_rate *= ast->codecpar->bits_per_coded_sample;
217
219 switch (audio_format) {
220 case 1:
221 if (ast->codecpar->bits_per_coded_sample == 16) {
222 // 16-bit audio is always signed
224 } else if (ast->codecpar->bits_per_coded_sample == 8) {
229 else
231 }
232 // There are some other formats listed as legal per the spec;
233 // samples needed.
234 break;
235 case 2:
238 }
239 break;
240 case 101:
241 if (ast->codecpar->bits_per_coded_sample == 8) {
242 // The samples with this kind of audio that I have
243 // are all unsigned.
245 } else if (ast->codecpar->bits_per_coded_sample == 4) {
247 }
248 break;
249 }
252 audio_format, audio_codec);
254 } else {
255 for (
i = 0;
i < 3;
i++)
257 }
258
259 if (
s->nb_streams == 0)
261
265 "Don't know how to split frames for video format %s. "
267
269 // The number in the header is actually the index of the last chunk.
270 number_of_chunks++;
271
274 chunk_catalog_offset = // offset of the "chunk catalog"
278 if (vst) {
281 }
282
283 // Read the index
284 avio_seek(pb, chunk_catalog_offset, SEEK_SET);
285 total_audio_size = 0;
286 for (
i = 0; !
error &&
i < number_of_chunks;
i++) {
287 int64_t
offset, video_size, audio_size;
289 if (3 != sscanf(
line,
"%"SCNd64
" , %"SCNd64
" ; %"SCNd64,
290 &
offset, &video_size, &audio_size)) {
292 continue;
293 }
294 if (vst)
297 if (ast)
299 audio_size, audio_size * 8, 0);
300 total_audio_size += audio_size * 8;
301 }
302
305
306 return 0;
307 }
308
310 {
317
321 }
322
325
328
330
334 }
335
338 // We have to split Escape 124 frames because there are
339 // multiple frames per chunk in Escape 124 samples.
341
346
352
356
361 }
362 } else {
368
370 // frames_per_chunk should always be one here; the header
371 // parsing will warn if it isn't.
373 } else {
374 // All the audio codecs supported in this container
375 // (at least so far) are constant-bitrate.
377 }
381 }
382
383 // None of the Escape formats have keyframes, and the ADPCM
384 // format used doesn't have keyframes.
387
389 }
390
398 };