annotate rpl.c @ 5910:536e5527c1e0 libavformat

Define AVMediaType enum, and use it instead of enum CodecType, which is deprecated and will be dropped at the next major bump.
author stefano
date Tue, 30 Mar 2010 23:30:55 +0000
parents 8c9ba1c9bcbc
children 11bb10c37225
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
1 /*
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
2 * ARMovie/RPL demuxer
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
3 * Copyright (c) 2007 Christian Ohm, 2008 Eli Friedman
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
4 *
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
5 * This file is part of FFmpeg.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
6 *
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
11 *
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
15 * Lesser General Public License for more details.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
16 *
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
20 */
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
21
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3197
diff changeset
22 #include "libavutil/avstring.h"
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
23 #include "avformat.h"
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
24 #include <stdlib.h>
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
25
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
26 #define RPL_SIGNATURE "ARMovie\x0A"
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
27 #define RPL_SIGNATURE_SIZE 8
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
28
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
29 /** 256 is arbitrary, but should be big enough for any reasonable file. */
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
30 #define RPL_LINE_LENGTH 256
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
31
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
32 static int rpl_probe(AVProbeData *p)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
33 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
34 if (memcmp(p->buf, RPL_SIGNATURE, RPL_SIGNATURE_SIZE))
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
35 return 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
36
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
37 return AVPROBE_SCORE_MAX;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
38 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
39
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
40 typedef struct RPLContext {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
41 // RPL header data
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
42 int32_t frames_per_chunk;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
43
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
44 // Stream position data
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
45 uint32_t chunk_number;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
46 uint32_t chunk_part;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
47 uint32_t frame_in_part;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
48 } RPLContext;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
49
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
50 static int read_line(ByteIOContext * pb, char* line, int bufsize)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
51 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
52 int i;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
53 for (i = 0; i < bufsize - 1; i++) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
54 int b = get_byte(pb);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
55 if (b == 0)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
56 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
57 if (b == '\n') {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
58 line[i] = '\0';
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
59 return 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
60 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
61 line[i] = b;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
62 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
63 line[i] = '\0';
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
64 return -1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
65 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
66
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
67 static int32_t read_int(const char* line, const char** endptr, int* error)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
68 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
69 unsigned long result = 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
70 for (; *line>='0' && *line<='9'; line++) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
71 if (result > (0x7FFFFFFF - 9) / 10)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
72 *error = -1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
73 result = 10 * result + *line - '0';
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
74 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
75 *endptr = line;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
76 return result;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
77 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
78
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
79 static int32_t read_line_and_int(ByteIOContext * pb, int* error)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
80 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
81 char line[RPL_LINE_LENGTH];
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
82 const char *endptr;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
83 *error |= read_line(pb, line, sizeof(line));
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
84 return read_int(line, &endptr, error);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
85 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
86
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
87 /** Parsing for fps, which can be a fraction. Unfortunately,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
88 * the spec for the header leaves out a lot of details,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
89 * so this is mostly guessing.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
90 */
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
91 static AVRational read_fps(const char* line, int* error)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
92 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
93 int64_t num, den = 1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
94 AVRational result;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
95 num = read_int(line, &line, error);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
96 if (*line == '.')
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
97 line++;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
98 for (; *line>='0' && *line<='9'; line++) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
99 // Truncate any numerator too large to fit into an int64_t
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
100 if (num > (INT64_MAX - 9) / 10 || den > INT64_MAX / 10)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
101 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
102 num = 10 * num + *line - '0';
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
103 den *= 10;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
104 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
105 if (!num)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
106 *error = -1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
107 av_reduce(&result.num, &result.den, num, den, 0x7FFFFFFF);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
108 return result;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
109 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
110
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
111 static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
112 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
113 ByteIOContext *pb = s->pb;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
114 RPLContext *rpl = s->priv_data;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
115 AVStream *vst = NULL, *ast = NULL;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
116 int total_audio_size;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
117 int error = 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
118
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
119 uint32_t i;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
120
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
121 int32_t audio_format, chunk_catalog_offset, number_of_chunks;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
122 AVRational fps;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
123
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
124 char line[RPL_LINE_LENGTH];
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
125
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
126 // The header for RPL/ARMovie files is 21 lines of text
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
127 // containing the various header fields. The fields are always
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
128 // in the same order, and other text besides the first
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
129 // number usually isn't important.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
130 // (The spec says that there exists some significance
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
131 // for the text in a few cases; samples needed.)
4598
8c9ba1c9bcbc cosmetics: vertical alignment
aurel
parents: 4597
diff changeset
132 error |= read_line(pb, line, sizeof(line)); // ARMovie
4597
ff780d8f1bbc use new metadata API in rpl demuxer
aurel
parents: 3908
diff changeset
133 error |= read_line(pb, line, sizeof(line)); // movie name
ff780d8f1bbc use new metadata API in rpl demuxer
aurel
parents: 3908
diff changeset
134 av_metadata_set(&s->metadata, "title" , line);
ff780d8f1bbc use new metadata API in rpl demuxer
aurel
parents: 3908
diff changeset
135 error |= read_line(pb, line, sizeof(line)); // date/copyright
ff780d8f1bbc use new metadata API in rpl demuxer
aurel
parents: 3908
diff changeset
136 av_metadata_set(&s->metadata, "copyright", line);
ff780d8f1bbc use new metadata API in rpl demuxer
aurel
parents: 3908
diff changeset
137 error |= read_line(pb, line, sizeof(line)); // author and other
ff780d8f1bbc use new metadata API in rpl demuxer
aurel
parents: 3908
diff changeset
138 av_metadata_set(&s->metadata, "author" , line);
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
139
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
140 // video headers
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
141 vst = av_new_stream(s, 0);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
142 if (!vst)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
143 return AVERROR(ENOMEM);
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4598
diff changeset
144 vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
145 vst->codec->codec_tag = read_line_and_int(pb, &error); // video format
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
146 vst->codec->width = read_line_and_int(pb, &error); // video width
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
147 vst->codec->height = read_line_and_int(pb, &error); // video height
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
148 vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
149 error |= read_line(pb, line, sizeof(line)); // video frames per second
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
150 fps = read_fps(line, &error);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
151 av_set_pts_info(vst, 32, fps.den, fps.num);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
152
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
153 // Figure out the video codec
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
154 switch (vst->codec->codec_tag) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
155 #if 0
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
156 case 122:
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
157 vst->codec->codec_id = CODEC_ID_ESCAPE122;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
158 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
159 #endif
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
160 case 124:
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
161 vst->codec->codec_id = CODEC_ID_ESCAPE124;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
162 // The header is wrong here, at least sometimes
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
163 vst->codec->bits_per_coded_sample = 16;
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
164 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
165 #if 0
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
166 case 130:
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
167 vst->codec->codec_id = CODEC_ID_ESCAPE130;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
168 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
169 #endif
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
170 default:
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
171 av_log(s, AV_LOG_WARNING,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
172 "RPL video format %i not supported yet!\n",
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
173 vst->codec->codec_tag);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
174 vst->codec->codec_id = CODEC_ID_NONE;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
175 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
176
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
177 // Audio headers
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
178
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
179 // ARMovie supports multiple audio tracks; I don't have any
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
180 // samples, though. This code will ignore additional tracks.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
181 audio_format = read_line_and_int(pb, &error); // audio format ID
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
182 if (audio_format) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
183 ast = av_new_stream(s, 0);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
184 if (!ast)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
185 return AVERROR(ENOMEM);
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4598
diff changeset
186 ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
187 ast->codec->codec_tag = audio_format;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
188 ast->codec->sample_rate = read_line_and_int(pb, &error); // audio bitrate
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
189 ast->codec->channels = read_line_and_int(pb, &error); // number of audio channels
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
190 ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // audio bits per sample
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
191 // At least one sample uses 0 for ADPCM, which is really 4 bits
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
192 // per sample.
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
193 if (ast->codec->bits_per_coded_sample == 0)
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
194 ast->codec->bits_per_coded_sample = 4;
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
195
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
196 ast->codec->bit_rate = ast->codec->sample_rate *
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
197 ast->codec->bits_per_coded_sample *
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
198 ast->codec->channels;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
199
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
200 ast->codec->codec_id = CODEC_ID_NONE;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
201 switch (audio_format) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
202 case 1:
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
203 if (ast->codec->bits_per_coded_sample == 16) {
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
204 // 16-bit audio is always signed
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
205 ast->codec->codec_id = CODEC_ID_PCM_S16LE;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
206 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
207 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
208 // There are some other formats listed as legal per the spec;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
209 // samples needed.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
210 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
211 case 101:
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
212 if (ast->codec->bits_per_coded_sample == 8) {
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
213 // The samples with this kind of audio that I have
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
214 // are all unsigned.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
215 ast->codec->codec_id = CODEC_ID_PCM_U8;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
216 break;
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
217 } else if (ast->codec->bits_per_coded_sample == 4) {
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
218 ast->codec->codec_id = CODEC_ID_ADPCM_IMA_EA_SEAD;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
219 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
220 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
221 break;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
222 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
223 if (ast->codec->codec_id == CODEC_ID_NONE) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
224 av_log(s, AV_LOG_WARNING,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
225 "RPL audio format %i not supported yet!\n",
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
226 audio_format);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
227 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
228 av_set_pts_info(ast, 32, 1, ast->codec->bit_rate);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
229 } else {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
230 for (i = 0; i < 3; i++)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
231 error |= read_line(pb, line, sizeof(line));
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
232 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
233
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
234 rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
235 if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
236 av_log(s, AV_LOG_WARNING,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
237 "Don't know how to split frames for video format %i. "
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
238 "Video stream will be broken!\n", vst->codec->codec_tag);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
239
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
240 number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
241 // The number in the header is actually the index of the last chunk.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
242 number_of_chunks++;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
243
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
244 error |= read_line(pb, line, sizeof(line)); // "even" chunk size in bytes
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
245 error |= read_line(pb, line, sizeof(line)); // "odd" chunk size in bytes
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
246 chunk_catalog_offset = // offset of the "chunk catalog"
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
247 read_line_and_int(pb, &error); // (file index)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
248 error |= read_line(pb, line, sizeof(line)); // offset to "helpful" sprite
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
249 error |= read_line(pb, line, sizeof(line)); // size of "helpful" sprite
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
250 error |= read_line(pb, line, sizeof(line)); // offset to key frame list
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
251
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
252 // Read the index
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
253 url_fseek(pb, chunk_catalog_offset, SEEK_SET);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
254 total_audio_size = 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
255 for (i = 0; i < number_of_chunks; i++) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
256 int64_t offset, video_size, audio_size;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
257 error |= read_line(pb, line, sizeof(line));
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
258 if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
259 &offset, &video_size, &audio_size))
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
260 error = -1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
261 av_add_index_entry(vst, offset, i * rpl->frames_per_chunk,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
262 video_size, rpl->frames_per_chunk, 0);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
263 if (ast)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
264 av_add_index_entry(ast, offset + video_size, total_audio_size,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
265 audio_size, audio_size * 8, 0);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
266 total_audio_size += audio_size * 8;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
267 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
268
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
269 if (error) return AVERROR(EIO);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
270
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
271 return 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
272 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
273
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
274 static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
275 {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
276 RPLContext *rpl = s->priv_data;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
277 ByteIOContext *pb = s->pb;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
278 AVStream* stream;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
279 AVIndexEntry* index_entry;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
280 uint32_t ret;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
281
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
282 if (rpl->chunk_part == s->nb_streams) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
283 rpl->chunk_number++;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
284 rpl->chunk_part = 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
285 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
286
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
287 stream = s->streams[rpl->chunk_part];
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
288
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
289 if (rpl->chunk_number >= stream->nb_index_entries)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
290 return -1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
291
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
292 index_entry = &stream->index_entries[rpl->chunk_number];
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
293
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
294 if (rpl->frame_in_part == 0)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
295 if (url_fseek(pb, index_entry->pos, SEEK_SET) < 0)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
296 return AVERROR(EIO);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
297
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4598
diff changeset
298 if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
299 stream->codec->codec_tag == 124) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
300 // We have to split Escape 124 frames because there are
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
301 // multiple frames per chunk in Escape 124 samples.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
302 uint32_t frame_size, frame_flags;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
303
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
304 frame_flags = get_le32(pb);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
305 frame_size = get_le32(pb);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
306 if (url_fseek(pb, -8, SEEK_CUR) < 0)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
307 return AVERROR(EIO);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
308
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
309 ret = av_get_packet(pb, pkt, frame_size);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
310 if (ret != frame_size) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
311 av_free_packet(pkt);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
312 return AVERROR(EIO);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
313 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
314 pkt->duration = 1;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
315 pkt->pts = index_entry->timestamp + rpl->frame_in_part;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
316 pkt->stream_index = rpl->chunk_part;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
317
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
318 rpl->frame_in_part++;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
319 if (rpl->frame_in_part == rpl->frames_per_chunk) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
320 rpl->frame_in_part = 0;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
321 rpl->chunk_part++;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
322 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
323 } else {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
324 ret = av_get_packet(pb, pkt, index_entry->size);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
325 if (ret != index_entry->size) {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
326 av_free_packet(pkt);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
327 return AVERROR(EIO);
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
328 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
329
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4598
diff changeset
330 if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
331 // frames_per_chunk should always be one here; the header
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
332 // parsing will warn if it isn't.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
333 pkt->duration = rpl->frames_per_chunk;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
334 } else {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
335 // All the audio codecs supported in this container
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
336 // (at least so far) are constant-bitrate.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
337 pkt->duration = ret * 8;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
338 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
339 pkt->pts = index_entry->timestamp;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
340 pkt->stream_index = rpl->chunk_part;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
341 rpl->chunk_part++;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
342 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
343
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
344 // None of the Escape formats have keyframes, and the ADPCM
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
345 // format used doesn't have keyframes.
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
346 if (rpl->chunk_number == 0 && rpl->frame_in_part == 0)
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
347 pkt->flags |= PKT_FLAG_KEY;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
348
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
349 return ret;
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
350 }
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
351
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
352 AVInputFormat rpl_demuxer = {
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
353 "rpl",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 3286
diff changeset
354 NULL_IF_CONFIG_SMALL("RPL/ARMovie format"),
3197
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
355 sizeof(RPLContext),
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
356 rpl_probe,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
357 rpl_read_header,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
358 rpl_read_packet,
e56c575b6717 ARMovie/RPL demuxer
superdump
parents:
diff changeset
359 };