3 * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de)
5 * This file is part of FFmpeg.
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.
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.
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
25 * @author Sascha Sommer (saschasommer@freenet.de)
26 * @see http://wiki.multimedia.cx/index.php?title=RL2
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
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/mathematics.h"
42 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette
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')
48 typedef struct Rl2DemuxContext
{
49 unsigned int index_pos
[2]; ///< indexes in the sample tables
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
58 static int rl2_probe(AVProbeData
*p
)
61 if(AV_RB32(&p
->buf
[0]) != FORM_TAG
)
64 if(AV_RB32(&p
->buf
[8]) != RLV2_TAG
&&
65 AV_RB32(&p
->buf
[8]) != RLV3_TAG
)
68 return AVPROBE_SCORE_MAX
;
72 * read rl2 header data and setup the avstreams
73 * @param s demuxer context
74 * @return 0 on success, AVERROR otherwise
76 static av_cold
int rl2_read_header(AVFormatContext
*s
)
78 AVIOContext
*pb
= s
->pb
;
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
;
86 unsigned short channels
;
87 unsigned short def_sound_size
;
88 unsigned int signature
;
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
;
97 avio_skip(pb
,4); /* skip FORM tag */
98 back_size
= avio_rl32(pb
); /**< get size of the background frame */
99 signature
= avio_rb32(pb
);
100 avio_skip(pb
, 4); /* data size */
101 frame_count
= avio_rl32(pb
);
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))
105 return AVERROR_INVALIDDATA
;
107 avio_skip(pb
, 2); /* encoding mentod */
108 sound_rate
= avio_rl16(pb
);
109 rate
= avio_rl16(pb
);
110 channels
= avio_rl16(pb
);
111 def_sound_size
= avio_rl16(pb
);
113 /** setup video stream */
114 st
= avformat_new_stream(s
, NULL
);
116 return AVERROR(ENOMEM
);
118 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
119 st
->codec
->codec_id
= AV_CODEC_ID_RL2
;
120 st
->codec
->codec_tag
= 0; /* no fourcc */
121 st
->codec
->width
= 320;
122 st
->codec
->height
= 200;
124 /** allocate and fill extradata */
125 st
->codec
->extradata_size
= EXTRADATA1_SIZE
;
127 if(signature
== RLV3_TAG
&& back_size
> 0)
128 st
->codec
->extradata_size
+= back_size
;
130 if(ff_get_extradata(st
->codec
, pb
, st
->codec
->extradata_size
) < 0)
131 return AVERROR(ENOMEM
);
133 /** setup audio stream if present */
135 if (!channels
|| channels
> 42) {
136 av_log(s
, AV_LOG_ERROR
, "Invalid number of channels: %d\n", channels
);
137 return AVERROR_INVALIDDATA
;
140 pts_num
= def_sound_size
;
143 st
= avformat_new_stream(s
, NULL
);
145 return AVERROR(ENOMEM
);
146 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
147 st
->codec
->codec_id
= AV_CODEC_ID_PCM_U8
;
148 st
->codec
->codec_tag
= 1;
149 st
->codec
->channels
= channels
;
150 st
->codec
->bits_per_coded_sample
= 8;
151 st
->codec
->sample_rate
= rate
;
152 st
->codec
->bit_rate
= st
->codec
->channels
* st
->codec
->sample_rate
*
153 st
->codec
->bits_per_coded_sample
;
154 st
->codec
->block_align
= st
->codec
->channels
*
155 st
->codec
->bits_per_coded_sample
/ 8;
156 avpriv_set_pts_info(st
,32,1,rate
);
159 avpriv_set_pts_info(s
->streams
[0], 32, pts_num
, pts_den
);
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));
165 if(!chunk_size
|| !audio_size
|| !chunk_offset
){
168 av_free(chunk_offset
);
169 return AVERROR(ENOMEM
);
172 /** read offset and size tables */
173 for(i
=0; i
< frame_count
;i
++)
174 chunk_size
[i
] = avio_rl32(pb
);
175 for(i
=0; i
< frame_count
;i
++)
176 chunk_offset
[i
] = avio_rl32(pb
);
177 for(i
=0; i
< frame_count
;i
++)
178 audio_size
[i
] = avio_rl32(pb
) & 0xFFFF;
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
]){
183 ret
= AVERROR_INVALIDDATA
;
187 if(sound_rate
&& audio_size
[i
]){
188 av_add_index_entry(s
->streams
[1], chunk_offset
[i
],
189 audio_frame_counter
,audio_size
[i
], 0, AVINDEX_KEYFRAME
);
190 audio_frame_counter
+= audio_size
[i
] / channels
;
192 av_add_index_entry(s
->streams
[0], chunk_offset
[i
] + audio_size
[i
],
193 video_frame_counter
,chunk_size
[i
]-audio_size
[i
],0,AVINDEX_KEYFRAME
);
194 ++video_frame_counter
;
200 av_free(chunk_offset
);
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
211 static int rl2_read_packet(AVFormatContext
*s
,
214 Rl2DemuxContext
*rl2
= s
->priv_data
;
215 AVIOContext
*pb
= s
->pb
;
216 AVIndexEntry
*sample
= NULL
;
220 int64_t pos
= INT64_MAX
;
222 /** check if there is a valid video or audio entry that can be used */
223 for(i
=0; i
<s
->nb_streams
; i
++){
224 if(rl2
->index_pos
[i
] < s
->streams
[i
]->nb_index_entries
225 && s
->streams
[i
]->index_entries
[ rl2
->index_pos
[i
] ].pos
< pos
){
226 sample
= &s
->streams
[i
]->index_entries
[ rl2
->index_pos
[i
] ];
235 ++rl2
->index_pos
[stream_id
];
237 /** position the stream (will probably be there anyway) */
238 avio_seek(pb
, sample
->pos
, SEEK_SET
);
240 /** fill the packet */
241 ret
= av_get_packet(pb
, pkt
, sample
->size
);
242 if(ret
!= sample
->size
){
247 pkt
->stream_index
= stream_id
;
248 pkt
->pts
= sample
->timestamp
;
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
261 static int rl2_read_seek(AVFormatContext
*s
, int stream_index
, int64_t timestamp
, int flags
)
263 AVStream
*st
= s
->streams
[stream_index
];
264 Rl2DemuxContext
*rl2
= s
->priv_data
;
266 int index
= av_index_search_timestamp(st
, timestamp
, flags
);
270 rl2
->index_pos
[stream_index
] = index
;
271 timestamp
= st
->index_entries
[index
].timestamp
;
273 for(i
=0; i
< s
->nb_streams
; i
++){
274 AVStream
*st2
= s
->streams
[i
];
275 index
= av_index_search_timestamp(st2
,
276 av_rescale_q(timestamp
, st
->time_base
, st2
->time_base
),
277 flags
| AVSEEK_FLAG_BACKWARD
);
282 rl2
->index_pos
[i
] = index
;
288 AVInputFormat ff_rl2_demuxer
= {
290 .long_name
= NULL_IF_CONFIG_SMALL("RL2"),
291 .priv_data_size
= sizeof(Rl2DemuxContext
),
292 .read_probe
= rl2_probe
,
293 .read_header
= rl2_read_header
,
294 .read_packet
= rl2_read_packet
,
295 .read_seek
= rl2_read_seek
,