1 /*
2 * RL2 Format Demuxer
3 * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de)
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 /**
23 * RL2 file demuxer
24 * @file
25 * @author Sascha Sommer (saschasommer@freenet.de)
26 * @see http://wiki.multimedia.cx/index.php?title=RL2
27 *
28 * extradata:
29 * 2 byte le initial drawing offset within 320x200 viewport
30 * 4 byte le number of used colors
31 * 256 * 3 bytes rgb palette
32 * optional background_frame
33 */
34
39
40 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette
41
42 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
43 #define RLV2_TAG MKBETAG('R', 'L', 'V', '2')
44 #define RLV3_TAG MKBETAG('R', 'L', 'V', '3')
45
47 unsigned int index_pos[2];
///< indexes in the sample tables
49
50
51 /**
52 * check if the file is in rl2 format
53 * @param p probe buffer
54 * @return 0 when the probe buffer does not contain rl2 data, > 0 otherwise
55 */
57 {
58
60 return 0;
61
64 return 0;
65
67 }
68
69 /**
70 * read rl2 header data and setup the avstreams
71 * @param s demuxer context
72 * @return 0 on success, AVERROR otherwise
73 */
75 {
79 unsigned int audio_frame_counter = 0;
80 unsigned int video_frame_counter = 0;
81 unsigned int back_size;
82 unsigned short sound_rate;
83 unsigned short rate;
84 unsigned short channels;
85 unsigned short def_sound_size;
87 unsigned int pts_den = 11025; /* video only case */
88 unsigned int pts_num = 1103;
89 unsigned int* chunk_offset =
NULL;
90 int* chunk_size =
NULL;
92 int i;
93 int ret = 0;
94
96 back_size =
avio_rl32(pb);
/**< get size of the background frame */
100
101 /* disallow back_sizes and frame_counts that may lead to overflows later */
102 if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t))
104
110
111 /** setup video stream */
113 if(!st)
115
121
122 /** allocate and fill extradata */
124
125 if(signature ==
RLV3_TAG && back_size > 0)
127
132
136
137 /** setup audio stream if present */
138 if(sound_rate){
139 if(channels <= 0)
141
142 pts_num = def_sound_size;
143 pts_den = rate;
144
146 if (!st)
159 }
160
162
163 chunk_size =
av_malloc(frame_count *
sizeof(uint32_t));
164 audio_size =
av_malloc(frame_count *
sizeof(uint32_t));
165 chunk_offset =
av_malloc(frame_count *
sizeof(uint32_t));
166
167 if(!chunk_size || !audio_size || !chunk_offset){
172 }
173
174 /** read offset and size tables */
181
182 /** build the sample index */
184 if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){
186 break;
187 }
188
189 if(sound_rate && audio_size[i]){
192 audio_frame_counter += audio_size[i] / channels;
193 }
196 ++video_frame_counter;
197 }
198
199
203
204 return ret;
205 }
206
207 /**
208 * read a single audio or video packet
209 * @param s demuxer context
210 * @param pkt the packet to be filled
211 * @return 0 on success, AVERROR otherwise
212 */
215 {
219 int i;
220 int ret = 0;
221 int stream_id = -1;
222 int64_t pos = INT64_MAX;
223
224 /** check if there is a valid video or audio entry that can be used */
230 stream_id= i;
231 }
232 }
233
234 if(stream_id == -1)
236
238
239 /** position the stream (will probably be there anyway) */
241
242 /** fill the packet */
244 if(ret != sample->
size){
247 }
248
251
252 return ret;
253 }
254
255 /**
256 * seek to a new timestamp
257 * @param s demuxer context
258 * @param stream_index index of the stream that should be seeked
259 * @param timestamp wanted timestamp
260 * @param flags direction and seeking mode
261 * @return 0 on success, -1 otherwise
262 */
264 {
267 int i;
269 if(index < 0)
270 return -1;
271
274
280
281 if(index < 0)
282 index = 0;
283
285 }
286
287 return 0;
288 }
289
298 };