1 /*
2 * Smacker demuxer
3 * Copyright (c) 2006 Konstantin Shishkov
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 * Based on http://wiki.multimedia.cx/index.php?title=Smacker
24 */
25
26 #include <inttypes.h>
27
33
34 #define SMACKER_PAL 0x01
35 #define SMACKER_FLAG_RING_FRAME 0x01
36
43 };
44
46 /* Smacker file header */
58 /* frame info */
61 /* internal variables */
65 /* current frame for demuxing */
76
81
82 /* palette used in Smacker */
84 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
85 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
86 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D,
87 0x61, 0x65, 0x69, 0x6D, 0x71, 0x75, 0x79, 0x7D,
88 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9A, 0x9E,
89 0xA2, 0xA6, 0xAA, 0xAE, 0xB2, 0xB6, 0xBA, 0xBE,
90 0xC3, 0xC7, 0xCB, 0xCF, 0xD3, 0xD7, 0xDB, 0xDF,
91 0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF
92 };
93
94
96 {
99 return 0;
100
103
105 }
106
108 {
112 int i, ret;
113 int tbase;
114
115 /* read and check header */
123 if (smk->
pts_inc > INT_MAX / 100) {
126 }
127
131 for(i = 0; i < 7; i++)
134
135 if(smk->
treesize >= UINT_MAX/4){
// smk->treesize + 16 must not overflow (this check is probably redundant)
138 }
139
140 //FIXME remove extradata "rebuilding"
145 for(i = 0; i < 7; i++) {
148 }
150 /* setup data */
151 if(smk->
frames > 0xFFFFFF) {
154 }
161 }
162
164
165 /* read frame info */
166 for(i = 0; i < smk->
frames; i++) {
168 }
169 for(i = 0; i < smk->
frames; i++) {
171 }
172
173 /* init video codec */
175 if (!st)
184 /* Smacker uses 100000 as internal timebase */
187 else
189 tbase = 100000;
193 /* handle possible audio streams */
194 for(i = 0; i < 7; i++) {
198 if (!ast[i])
209 } else {
211 }
215 } else {
218 }
225 }
226 }
227
228
229 /* load trees to extradata, they will be unpacked by decoder */
232 "Cannot allocate %"PRIu32" bytes of extradata\n",
237 }
243 }
248
251
252 return 0;
253 }
254
255
257 {
260 int ret;
261 int i;
263 int palchange = 0;
264
267
268 /* if we demuxed all streams, pass another frame */
273 /* handle palette change event */
275 int size, sz, t, off, j, pos;
278
279 memcpy(oldpal, pal, 768);
281 size = size * 4 - 1;
282 if(size + 1 > frame_size)
285 frame_size--;
286 sz = 0;
288 while(sz < 256){
290 if(t & 0x80){ /* skip palette entries */
291 sz += (t & 0x7F) + 1;
292 pal += ((t & 0x7F) + 1) * 3;
293 } else if(t & 0x40){ /* copy with offset */
295 j = (t & 0x3F) + 1;
296 if (off + j > 0x100) {
298 "Invalid palette update, offset=%d length=%d extends beyond palette size\n",
299 off, j);
301 }
302 off *= 3;
303 while(j-- && sz < 256) {
304 *pal++ = oldpal[off + 0];
305 *pal++ = oldpal[off + 1];
306 *pal++ = oldpal[off + 2];
307 sz++;
308 off += 3;
309 }
310 } else { /* new entries */
314 sz++;
315 }
316 }
318 palchange |= 1;
319 }
320 flags >>= 1;
322 /* if audio chunks are present, put them to stack and retrieve later */
323 for(i = 0; i < 7; i++) {
324 if(flags & 1) {
326 int err;
327
329 if (!size || size + 4LL > frame_size) {
332 }
334 frame_size -= 4;
338 return err;
339 }
342 if(ret != size)
345 }
346 flags >>= 1;
347 }
348 if (frame_size < 0 || frame_size >= INT_MAX/2)
353 palchange |= 2;
354 pkt->
data[0] = palchange;
355 memcpy(pkt->
data + 1, smk->
pal, 768);
357 if(ret != frame_size)
361 pkt->
size = ret + 769;
364 } else {
375 }
376
377 return 0;
378 }
379
381 {
383 int i;
384
385 for(i = 0; i < 7; i++)
389
390 return 0;
391 }
392
401 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
int index
stream index in AVFormatContext
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define AV_CH_LAYOUT_STEREO
8 bit with AV_PIX_FMT_RGB32 palette
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
#define AVERROR_EOF
End of file.
static av_cold int read_close(AVFormatContext *ctx)
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
unsigned int avio_rl32(AVIOContext *s)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
uint64_t channel_layout
Audio channel layout.
int avio_r8(AVIOContext *s)
AVCodecContext * codec
Codec context associated with this stream.
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
audio channel layout utility functions
int width
picture width / height.
static int read_header(FFV1Context *f)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
enum AVMediaType codec_type
int sample_rate
samples per second
AVIOContext * pb
I/O context.
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
This structure contains the data a format has to probe a file.
int64_t duration
Decoding: duration of the stream, in stream time base.
int av_reallocp(void *ptr, size_t size)
Allocate or reallocate a block of memory.
int channels
number of audio channels
void * priv_data
Format private data.
#define av_malloc_array(a, b)
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
unsigned int avio_rl24(AVIOContext *s)
#define AV_CH_LAYOUT_MONO
#define MKTAG(a, b, c, d)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...