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
30
31 #define RPL_SIGNATURE "ARMovie\x0A"
32 #define RPL_SIGNATURE_SIZE 8
33
34 /** 256 is arbitrary, but should be big enough for any reasonable file. */
35 #define RPL_LINE_LENGTH 256
36
38 {
40 return 0;
41
43 }
44
46 // RPL header data
48
49 // Stream position data
54
56 {
58 for (
i = 0;
i < bufsize - 1;
i++) {
61 break;
65 }
67 }
69 return -1;
70 }
71
73 {
76 if (
result > (0x7FFFFFFF - 9) / 10)
79 }
82 }
83
85 {
87 const char *endptr;
90 }
91
92 /** Parsing for fps, which can be a fraction. Unfortunately,
93 * the spec for the header leaves out a lot of details,
94 * so this is mostly guessing.
95 */
97 {
104 // Truncate any numerator too large to fit into an int64_t
105 if (num > (INT64_MAX - 9) / 10ULL || den > INT64_MAX / 10ULL)
106 break;
107 num = 10 * num + (*
line -
'0');
108 den *= 10;
109 }
110 if (!num)
114 }
115
117 {
123 const char *endptr;
126
128
129 int32_t video_format, audio_format, chunk_catalog_offset, number_of_chunks;
131
133
134 // The header for RPL/ARMovie files is 21 lines of text
135 // containing the various header fields. The fields are always
136 // in the same order, and other text besides the first
137 // number usually isn't important.
138 // (The spec says that there exists some significance
139 // for the text in a few cases; samples needed.)
147
148 // video headers
150 if (video_format) {
152 if (!vst)
159
160 // Figure out the video codec
162 #if 0
163 case 122:
165 break;
166 #endif
167 case 124:
169 // The header is wrong here, at least sometimes
171 break;
172 case 130:
174 break;
175 default:
179 }
180 } else {
181 for (
i = 0;
i < 3;
i++)
183 }
184
187 if (vst)
189
190 // Audio headers
191
192 // ARMovie supports multiple audio tracks; I don't have any
193 // samples, though. This code will ignore additional tracks.
197 if (audio_format) {
200 if (!ast)
203 ast->codecpar->codec_tag = audio_format;
205 if (ast->codecpar->sample_rate < 0)
211 ast->codecpar->bits_per_coded_sample =
read_int(
line, &endptr, &
error);
// audio bits per sample
213 ast->codecpar->ch_layout.nb_channels =
channels;
214 // At least one sample uses 0 for ADPCM, which is really 4 bits
215 // per sample.
216 if (ast->codecpar->bits_per_coded_sample == 0)
217 ast->codecpar->bits_per_coded_sample = 4;
218
219 ast->codecpar->bit_rate = ast->codecpar->sample_rate *
220 (
int64_t)ast->codecpar->ch_layout.nb_channels;
221 if (ast->codecpar->bit_rate > INT64_MAX / ast->codecpar->bits_per_coded_sample)
223 ast->codecpar->bit_rate *= ast->codecpar->bits_per_coded_sample;
224
226 switch (audio_format) {
227 case 1:
228 if (ast->codecpar->bits_per_coded_sample == 16) {
229 // 16-bit audio is always signed
231 } else if (ast->codecpar->bits_per_coded_sample == 8) {
236 else
238 }
239 // There are some other formats listed as legal per the spec;
240 // samples needed.
241 break;
242 case 2:
245 }
246 break;
247 case 101:
248 if (ast->codecpar->bits_per_coded_sample == 8) {
249 // The samples with this kind of audio that I have
250 // are all unsigned.
252 } else if (ast->codecpar->bits_per_coded_sample == 4) {
254 }
255 break;
256 }
259 audio_format, audio_codec);
261 } else {
262 for (
i = 0;
i < 3;
i++)
264 }
265
266 if (
s->nb_streams == 0)
268
272 "Don't know how to split frames for video format %s. "
274
276 if (number_of_chunks == INT_MAX)
278
279 // The number in the header is actually the index of the last chunk.
280 number_of_chunks++;
281
284 chunk_catalog_offset = // offset of the "chunk catalog"
288 if (vst) {
291 }
292
293 // Read the index
294 avio_seek(pb, chunk_catalog_offset, SEEK_SET);
295 total_audio_size = 0;
296 for (
i = 0; !
error &&
i < number_of_chunks;
i++) {
299 if (3 != sscanf(
line,
"%"SCNd64
" , %"SCNd64
" ; %"SCNd64,
300 &
offset, &video_size, &audio_size)) {
302 continue;
303 }
304 if (vst)
307 if (ast)
309 audio_size, audio_size * 8, 0);
310 if (total_audio_size/8 + (uint64_t)audio_size >= INT64_MAX/8)
312 total_audio_size += audio_size * 8;
313 }
314
317
318 return 0;
319 }
320
322 {
329
333 }
334
337
340
342
346 }
347
350 // We have to split Escape 124 frames because there are
351 // multiple frames per chunk in Escape 124 samples.
353
358
364
368
373 }
374 } else {
380
382 // frames_per_chunk should always be one here; the header
383 // parsing will warn if it isn't.
385 } else {
386 // All the audio codecs supported in this container
387 // (at least so far) are constant-bitrate.
389 }
393 }
394
395 // None of the Escape formats have keyframes, and the ADPCM
396 // format used doesn't have keyframes.
399
401 }
402
410 };