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
35 #include <stdint.h>
36
41
42 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette
43
44 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
45 #define RLV2_TAG MKBETAG('R', 'L', 'V', '2')
46 #define RLV3_TAG MKBETAG('R', 'L', 'V', '3')
47
49 unsigned int index_pos[2];
///< indexes in the sample tables
51
52
53 /**
54 * check if the file is in rl2 format
55 * @param p probe buffer
56 * @return 0 when the probe buffer does not contain rl2 data, > 0 otherwise
57 */
59 {
60
62 return 0;
63
66 return 0;
67
69 }
70
71 /**
72 * read rl2 header data and setup the avstreams
73 * @param s demuxer context
74 * @return 0 on success, AVERROR otherwise
75 */
77 {
80 unsigned int frame_count;
81 unsigned int audio_frame_counter = 0;
82 unsigned int video_frame_counter = 0;
83 unsigned int back_size;
84 unsigned short sound_rate;
85 unsigned short rate;
86 unsigned short channels;
87 unsigned short def_sound_size;
89 unsigned int pts_den = 11025; /* video only case */
90 unsigned int pts_num = 1103;
91 unsigned int* chunk_offset =
NULL;
92 int* chunk_size =
NULL;
93 int* audio_size =
NULL;
94 int i;
96
98 back_size =
avio_rl32(pb);
/**< get size of the background frame */
102
103 /* disallow back_sizes and frame_counts that may lead to overflows later */
104 if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t))
106
112
113 /** setup video stream */
115 if(!st)
117
123
124 /** allocate and fill extradata */
126
127 if(signature ==
RLV3_TAG && back_size > 0)
129
132
133 /** setup audio stream if present */
134 if(sound_rate){
135 if (!channels || channels > 42) {
138 }
139
140 pts_num = def_sound_size;
141 pts_den = rate;
142
144 if (!st)
157 }
158
160
161 chunk_size =
av_malloc(frame_count *
sizeof(uint32_t));
162 audio_size =
av_malloc(frame_count *
sizeof(uint32_t));
163 chunk_offset =
av_malloc(frame_count *
sizeof(uint32_t));
164
165 if(!chunk_size || !audio_size || !chunk_offset){
170 }
171
172 /** read offset and size tables */
173 for(i=0; i < frame_count;i++)
175 for(i=0; i < frame_count;i++)
177 for(i=0; i < frame_count;i++)
179
180 /** build the sample index */
181 for(i=0;i<frame_count;i++){
182 if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){
184 break;
185 }
186
187 if(sound_rate && audio_size[i]){
190 audio_frame_counter += audio_size[i] / channels;
191 }
194 ++video_frame_counter;
195 }
196
197
201
203 }
204
205 /**
206 * read a single audio or video packet
207 * @param s demuxer context
208 * @param pkt the packet to be filled
209 * @return 0 on success, AVERROR otherwise
210 */
213 {
217 int i;
219 int stream_id = -1;
220 int64_t pos = INT64_MAX;
221
222 /** check if there is a valid video or audio entry that can be used */
228 stream_id= i;
229 }
230 }
231
232 if(stream_id == -1)
234
236
237 /** position the stream (will probably be there anyway) */
239
240 /** fill the packet */
242 if(ret != sample->
size){
245 }
246
249
251 }
252
253 /**
254 * seek to a new timestamp
255 * @param s demuxer context
256 * @param stream_index index of the stream that should be seeked
257 * @param timestamp wanted timestamp
258 * @param flags direction and seeking mode
259 * @return 0 on success, -1 otherwise
260 */
262 {
265 int i;
267 if(index < 0)
268 return -1;
269
272
278
279 if(index < 0)
280 index = 0;
281
283 }
284
285 return 0;
286 }
287
296 };