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
26 #include <stdlib.h>
27
28 #define RPL_SIGNATURE "ARMovie\x0A"
29 #define RPL_SIGNATURE_SIZE 8
30
31 /** 256 is arbitrary, but should be big enough for any reasonable file. */
32 #define RPL_LINE_LENGTH 256
33
35 {
37 return 0;
38
40 }
41
43 // RPL header data
45
46 // Stream position data
51
53 {
54 int i;
55 for (i = 0; i < bufsize - 1; i++) {
57 if (b == 0)
58 break;
59 if (b == '\n') {
60 line[i] = '0円';
62 }
64 }
65 line[i] = '0円';
66 return -1;
67 }
68
70 {
71 unsigned long result = 0;
72 for (; *line>='0' && *line<='9'; line++) {
73 if (result > (0x7FFFFFFF - 9) / 10)
74 *error = -1;
75 result = 10 * result + *line - '0';
76 }
77 *endptr = line;
78 return result;
79 }
80
82 {
84 const char *endptr;
85 *error |=
read_line(pb, line,
sizeof(line));
86 return read_int(line, &endptr, error);
87 }
88
89 /** Parsing for fps, which can be a fraction. Unfortunately,
90 * the spec for the header leaves out a lot of details,
91 * so this is mostly guessing.
92 */
94 {
95 int64_t num, den = 1;
98 if (*line == '.')
99 line++;
100 for (; *line>='0' && *line<='9'; line++) {
101 // Truncate any numerator too large to fit into an int64_t
102 if (num > (INT64_MAX - 9) / 10 || den > INT64_MAX / 10)
103 break;
104 num = 10 * num + *line - '0';
105 den *= 10;
106 }
107 if (!num)
108 *error = -1;
110 return result;
111 }
112
114 {
118 int total_audio_size;
119 int error = 0;
120
121 uint32_t i;
122
123 int32_t audio_format, chunk_catalog_offset, number_of_chunks;
125
127
128 // The header for RPL/ARMovie files is 21 lines of text
129 // containing the various header fields. The fields are always
130 // in the same order, and other text besides the first
131 // number usually isn't important.
132 // (The spec says that there exists some significance
133 // for the text in a few cases; samples needed.)
134 error |=
read_line(pb, line,
sizeof(line));
// ARMovie
135 error |=
read_line(pb, line,
sizeof(line));
// movie name
137 error |=
read_line(pb, line,
sizeof(line));
// date/copyright
139 error |=
read_line(pb, line,
sizeof(line));
// author and other
141
142 // video headers
144 if (!vst)
151 error |=
read_line(pb, line,
sizeof(line));
// video frames per second
154
155 // Figure out the video codec
157 #if 0
158 case 122:
160 break;
161 #endif
162 case 124:
164 // The header is wrong here, at least sometimes
166 break;
167 case 130:
169 break;
170 default:
174 }
175
176 // Audio headers
177
178 // ARMovie supports multiple audio tracks; I don't have any
179 // samples, though. This code will ignore additional tracks.
181 if (audio_format) {
183 if (!ast)
186 ast->codec->codec_tag = audio_format;
188 ast->codec->channels =
read_line_and_int(pb, &error);
// number of audio channels
189 ast->codec->bits_per_coded_sample =
read_line_and_int(pb, &error);
// audio bits per sample
190 // At least one sample uses 0 for ADPCM, which is really 4 bits
191 // per sample.
192 if (ast->codec->bits_per_coded_sample == 0)
193 ast->codec->bits_per_coded_sample = 4;
194
195 ast->codec->bit_rate = ast->codec->sample_rate *
196 ast->codec->bits_per_coded_sample *
197 ast->codec->channels;
198
200 switch (audio_format) {
201 case 1:
202 if (ast->codec->bits_per_coded_sample == 16) {
203 // 16-bit audio is always signed
205 break;
206 }
207 // There are some other formats listed as legal per the spec;
208 // samples needed.
209 break;
210 case 101:
211 if (ast->codec->bits_per_coded_sample == 8) {
212 // The samples with this kind of audio that I have
213 // are all unsigned.
215 break;
216 } else if (ast->codec->bits_per_coded_sample == 4) {
218 break;
219 }
220 break;
221 }
225 } else {
226 for (i = 0; i < 3; i++)
227 error |=
read_line(pb, line,
sizeof(line));
228 }
229
233 "Don't know how to split frames for video format %i. "
235
236 number_of_chunks =
read_line_and_int(pb, &error);
// number of chunks in the file
237 // The number in the header is actually the index of the last chunk.
238 number_of_chunks++;
239
240 error |=
read_line(pb, line,
sizeof(line));
// "even" chunk size in bytes
241 error |=
read_line(pb, line,
sizeof(line));
// "odd" chunk size in bytes
242 chunk_catalog_offset = // offset of the "chunk catalog"
244 error |=
read_line(pb, line,
sizeof(line));
// offset to "helpful" sprite
245 error |=
read_line(pb, line,
sizeof(line));
// size of "helpful" sprite
246 error |=
read_line(pb, line,
sizeof(line));
// offset to key frame list
247
248 // Read the index
249 avio_seek(pb, chunk_catalog_offset, SEEK_SET);
250 total_audio_size = 0;
251 for (i = 0; !error && i < number_of_chunks; i++) {
253 error |=
read_line(pb, line,
sizeof(line));
254 if (3 != sscanf(line, "%"SCNd64" , %"SCNd64" ; %"SCNd64,
255 &offset, &video_size, &audio_size))
256 error = -1;
259 if (ast)
261 audio_size, audio_size * 8, 0);
262 total_audio_size += audio_size * 8;
263 }
264
265 if (error)
return AVERROR(EIO);
266
267 return 0;
268 }
269
271 {
277
281 }
282
284
287
289
293
296 // We have to split Escape 124 frames because there are
297 // multiple frames per chunk in Escape 124 samples.
299
304
306 if (ret != frame_size) {
309 }
313
318 }
319 } else {
321 if (ret != index_entry->
size) {
324 }
325
327 // frames_per_chunk should always be one here; the header
328 // parsing will warn if it isn't.
330 } else {
331 // All the audio codecs supported in this container
332 // (at least so far) are constant-bitrate.
334 }
338 }
339
340 // None of the Escape formats have keyframes, and the ADPCM
341 // format used doesn't have keyframes.
344
346 }
347
355 };