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) {
199 if (!ast)
202 ast->codecpar->codec_tag = audio_format;
206 ast->codecpar->bits_per_coded_sample =
read_int(
line, &endptr, &
error);
// audio bits per sample
208 ast->codecpar->ch_layout.nb_channels =
channels;
209 // At least one sample uses 0 for ADPCM, which is really 4 bits
210 // per sample.
211 if (ast->codecpar->bits_per_coded_sample == 0)
212 ast->codecpar->bits_per_coded_sample = 4;
213
214 ast->codecpar->bit_rate = ast->codecpar->sample_rate *
215 (int64_t)ast->codecpar->ch_layout.nb_channels;
216 if (ast->codecpar->bit_rate > INT64_MAX / ast->codecpar->bits_per_coded_sample)
218 ast->codecpar->bit_rate *= ast->codecpar->bits_per_coded_sample;
219
221 switch (audio_format) {
222 case 1:
223 if (ast->codecpar->bits_per_coded_sample == 16) {
224 // 16-bit audio is always signed
226 } else if (ast->codecpar->bits_per_coded_sample == 8) {
231 else
233 }
234 // There are some other formats listed as legal per the spec;
235 // samples needed.
236 break;
237 case 2:
240 }
241 break;
242 case 101:
243 if (ast->codecpar->bits_per_coded_sample == 8) {
244 // The samples with this kind of audio that I have
245 // are all unsigned.
247 } else if (ast->codecpar->bits_per_coded_sample == 4) {
249 }
250 break;
251 }
254 audio_format, audio_codec);
256 } else {
257 for (
i = 0;
i < 3;
i++)
259 }
260
261 if (
s->nb_streams == 0)
263
267 "Don't know how to split frames for video format %s. "
269
271 // The number in the header is actually the index of the last chunk.
272 number_of_chunks++;
273
276 chunk_catalog_offset = // offset of the "chunk catalog"
280 if (vst) {
283 }
284
285 // Read the index
286 avio_seek(pb, chunk_catalog_offset, SEEK_SET);
287 total_audio_size = 0;
288 for (
i = 0; !
error &&
i < number_of_chunks;
i++) {
289 int64_t
offset, video_size, audio_size;
291 if (3 != sscanf(
line,
"%"SCNd64
" , %"SCNd64
" ; %"SCNd64,
292 &
offset, &video_size, &audio_size)) {
294 continue;
295 }
296 if (vst)
299 if (ast)
301 audio_size, audio_size * 8, 0);
302 total_audio_size += audio_size * 8;
303 }
304
307
308 return 0;
309 }
310
312 {
319
323 }
324
327
330
332
336 }
337
340 // We have to split Escape 124 frames because there are
341 // multiple frames per chunk in Escape 124 samples.
343
348
354
358
363 }
364 } else {
370
372 // frames_per_chunk should always be one here; the header
373 // parsing will warn if it isn't.
375 } else {
376 // All the audio codecs supported in this container
377 // (at least so far) are constant-bitrate.
379 }
383 }
384
385 // None of the Escape formats have keyframes, and the ADPCM
386 // format used doesn't have keyframes.
389
391 }
392
400 };