annotate smacker.c @ 5330:936a03bbd757 libavformat

Suppress ?params in the rtsp uri Right now rtsp demuxer receives it's ffmpeg specific params encoded in the url That made the server receiving requests with the url ending with "?udp", "?multicast" and "?tcp". That may or may not cause problems to servers with overly strict or overly simple uri parsers Patch from Armand Bendanan (name.surnameATfreeDOTfr)
author lu_zero
date Sat, 24 Oct 2009 15:18:21 +0000
parents 2da42f33de42
children 942ca859a587
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
1 /*
1415
3b00fb8ef8e4 replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents: 1358
diff changeset
2 * Smacker demuxer
4251
77e0c7511d41 cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 4201
diff changeset
3 * Copyright (c) 2006 Konstantin Shishkov
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
4 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
5 * This file is part of FFmpeg.
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
6 *
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
11 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
15 * Lesser General Public License for more details.
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
16 *
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
20 */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
21
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
22 /*
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
23 * Based on http://wiki.multimedia.cx/index.php?title=Smacker
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
24 */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
25
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 2771
diff changeset
26 #include "libavutil/bswap.h"
4201
7d2f3f1b68d8 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 3973
diff changeset
27 #include "libavutil/intreadwrite.h"
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
28 #include "avformat.h"
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
29
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
30 #define SMACKER_PAL 0x01
2404
2ca025105808 Take ring frame into account when demuxing.
kostya
parents: 2274
diff changeset
31 #define SMACKER_FLAG_RING_FRAME 0x01
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
32
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
33 enum SAudFlags {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
34 SMK_AUD_PACKED = 0x80000000,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
35 SMK_AUD_16BITS = 0x20000000,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
36 SMK_AUD_STEREO = 0x10000000,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
37 SMK_AUD_BINKAUD = 0x08000000,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
38 SMK_AUD_USEDCT = 0x04000000
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
39 };
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
40
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
41 typedef struct SmackerContext {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
42 /* Smacker file header */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
43 uint32_t magic;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
44 uint32_t width, height;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
45 uint32_t frames;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
46 int pts_inc;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
47 uint32_t flags;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
48 uint32_t audio[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
49 uint32_t treesize;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
50 uint32_t mmap_size, mclr_size, full_size, type_size;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
51 uint32_t rates[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
52 uint32_t pad;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
53 /* frame info */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
54 uint32_t *frm_size;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
55 uint8_t *frm_flags;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
56 /* internal variables */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
57 int cur_frame;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
58 int is_ver4;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
59 int64_t cur_pts;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
60 /* current frame for demuxing */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
61 uint8_t pal[768];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
62 int indexes[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
63 int videoindex;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
64 uint8_t *bufs[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
65 int buf_sizes[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
66 int stream_id[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
67 int curstream;
3973
549a09cf23fe Remove offset_t typedef and use int64_t directly instead.
diego
parents: 3908
diff changeset
68 int64_t nextpos;
1090
80b1e60a735e Proper PTS generation for Smacker audio
kostya
parents: 1089
diff changeset
69 int64_t aud_pts[7];
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
70 } SmackerContext;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
71
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
72 typedef struct SmackerFrame {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
73 int64_t pts;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
74 int stream;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
75 } SmackerFrame;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
76
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
77 /* palette used in Smacker */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
78 static const uint8_t smk_pal[64] = {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
79 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
80 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
81 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
82 0x61, 0x65, 0x69, 0x6D, 0x71, 0x75, 0x79, 0x7D,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
83 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9A, 0x9E,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
84 0xA2, 0xA6, 0xAA, 0xAE, 0xB2, 0xB6, 0xBA, 0xBE,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
85 0xC3, 0xC7, 0xCB, 0xCF, 0xD3, 0xD7, 0xDB, 0xDF,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
86 0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
87 };
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
88
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
89
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
90 static int smacker_probe(AVProbeData *p)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
91 {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
92 if(p->buf[0] == 'S' && p->buf[1] == 'M' && p->buf[2] == 'K'
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
93 && (p->buf[3] == '2' || p->buf[3] == '4'))
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
94 return AVPROBE_SCORE_MAX;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
95 else
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
96 return 0;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
97 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
98
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
99 static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
100 {
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
101 ByteIOContext *pb = s->pb;
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
102 SmackerContext *smk = s->priv_data;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
103 AVStream *st, *ast[7];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
104 int i, ret;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
105 int tbase;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
106
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
107 /* read and check header */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
108 smk->magic = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
109 if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4'))
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
110 return -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
111 smk->width = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
112 smk->height = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
113 smk->frames = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
114 smk->pts_inc = (int32_t)get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
115 smk->flags = get_le32(pb);
2404
2ca025105808 Take ring frame into account when demuxing.
kostya
parents: 2274
diff changeset
116 if(smk->flags & SMACKER_FLAG_RING_FRAME)
2ca025105808 Take ring frame into account when demuxing.
kostya
parents: 2274
diff changeset
117 smk->frames++;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
118 for(i = 0; i < 7; i++)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
119 smk->audio[i] = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
120 smk->treesize = get_le32(pb);
1079
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
121
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
122 if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant)
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
123 av_log(s, AV_LOG_ERROR, "treesize too large\n");
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
124 return -1;
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
125 }
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
126
40e81416015d sanity checks some might have been exploitable
michael
parents: 1019
diff changeset
127 //FIXME remove extradata "rebuilding"
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
128 smk->mmap_size = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
129 smk->mclr_size = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
130 smk->full_size = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
131 smk->type_size = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
132 for(i = 0; i < 7; i++)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
133 smk->rates[i] = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
134 smk->pad = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
135 /* setup data */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
136 if(smk->frames > 0xFFFFFF) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
137 av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
138 return -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
139 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
140 smk->frm_size = av_malloc(smk->frames * 4);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
141 smk->frm_flags = av_malloc(smk->frames);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
142
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
143 smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2'));
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
144
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
145 /* read frame info */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
146 for(i = 0; i < smk->frames; i++) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
147 smk->frm_size[i] = get_le32(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
148 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
149 for(i = 0; i < smk->frames; i++) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
150 smk->frm_flags[i] = get_byte(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
151 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
152
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
153 /* init video codec */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
154 st = av_new_stream(s, 0);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
155 if (!st)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
156 return -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
157 smk->videoindex = st->index;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
158 st->codec->width = smk->width;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
159 st->codec->height = smk->height;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
160 st->codec->pix_fmt = PIX_FMT_PAL8;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
161 st->codec->codec_type = CODEC_TYPE_VIDEO;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
162 st->codec->codec_id = CODEC_ID_SMACKVIDEO;
1089
0319672689ef Now MPlayer should understand Smacker audio and video codecs.
kostya
parents: 1079
diff changeset
163 st->codec->codec_tag = smk->magic;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
164 /* Smacker uses 100000 as internal timebase */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
165 if(smk->pts_inc < 0)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
166 smk->pts_inc = -smk->pts_inc;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
167 else
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
168 smk->pts_inc *= 100;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
169 tbase = 100000;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
170 av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
171 av_set_pts_info(st, 33, smk->pts_inc, tbase);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
172 /* handle possible audio streams */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
173 for(i = 0; i < 7; i++) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
174 smk->indexes[i] = -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
175 if((smk->rates[i] & 0xFFFFFF) && !(smk->rates[i] & SMK_AUD_BINKAUD)){
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
176 ast[i] = av_new_stream(s, 0);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
177 smk->indexes[i] = ast[i]->index;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
178 ast[i]->codec->codec_type = CODEC_TYPE_AUDIO;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
179 ast[i]->codec->codec_id = (smk->rates[i] & SMK_AUD_PACKED) ? CODEC_ID_SMACKAUDIO : CODEC_ID_PCM_U8;
1089
0319672689ef Now MPlayer should understand Smacker audio and video codecs.
kostya
parents: 1079
diff changeset
180 ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A');
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
181 ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
182 ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF;
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
183 ast[i]->codec->bits_per_coded_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8;
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
184 if(ast[i]->codec->bits_per_coded_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8)
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
185 ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
4767
2da42f33de42 Make Smacker audio decoder output audio in original bit depth
kostya
parents: 4251
diff changeset
186 ast[i]->codec->sample_fmt = ast[i]->codec->bits_per_coded_sample == 8 ? SAMPLE_FMT_U8 : SAMPLE_FMT_S16;
1090
80b1e60a735e Proper PTS generation for Smacker audio
kostya
parents: 1089
diff changeset
187 av_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
188 * ast[i]->codec->channels * ast[i]->codec->bits_per_coded_sample / 8);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
189 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
190 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
191
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
192
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
193 /* load trees to extradata, they will be unpacked by decoder */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
194 st->codec->extradata = av_malloc(smk->treesize + 16);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
195 st->codec->extradata_size = smk->treesize + 16;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
196 if(!st->codec->extradata){
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
197 av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
198 av_free(smk->frm_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
199 av_free(smk->frm_flags);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
200 return -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
201 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
202 ret = get_buffer(pb, st->codec->extradata + 16, st->codec->extradata_size - 16);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
203 if(ret != st->codec->extradata_size - 16){
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
204 av_free(smk->frm_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
205 av_free(smk->frm_flags);
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
206 return AVERROR(EIO);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
207 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
208 ((int32_t*)st->codec->extradata)[0] = le2me_32(smk->mmap_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
209 ((int32_t*)st->codec->extradata)[1] = le2me_32(smk->mclr_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
210 ((int32_t*)st->codec->extradata)[2] = le2me_32(smk->full_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
211 ((int32_t*)st->codec->extradata)[3] = le2me_32(smk->type_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
212
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
213 smk->curstream = -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
214 smk->nextpos = url_ftell(pb);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
215
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
216 return 0;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
217 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
218
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
219
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
220 static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
221 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
222 SmackerContext *smk = s->priv_data;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
223 int flags;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
224 int ret;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
225 int i;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
226 int frame_size = 0;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
227 int palchange = 0;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
228 int pos;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
229
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
230 if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
1787
eb16c64144ee This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents: 1673
diff changeset
231 return AVERROR(EIO);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
232
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
233 /* if we demuxed all streams, pass another frame */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
234 if(smk->curstream < 0) {
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
235 url_fseek(s->pb, smk->nextpos, 0);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
236 frame_size = smk->frm_size[smk->cur_frame] & (~3);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
237 flags = smk->frm_flags[smk->cur_frame];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
238 /* handle palette change event */
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
239 pos = url_ftell(s->pb);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
240 if(flags & SMACKER_PAL){
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
241 int size, sz, t, off, j, pos;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
242 uint8_t *pal = smk->pal;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
243 uint8_t oldpal[768];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
244
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
245 memcpy(oldpal, pal, 768);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
246 size = get_byte(s->pb);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
247 size = size * 4 - 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
248 frame_size -= size;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
249 frame_size--;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
250 sz = 0;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
251 pos = url_ftell(s->pb) + size;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
252 while(sz < 256){
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
253 t = get_byte(s->pb);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
254 if(t & 0x80){ /* skip palette entries */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
255 sz += (t & 0x7F) + 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
256 pal += ((t & 0x7F) + 1) * 3;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
257 } else if(t & 0x40){ /* copy with offset */
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
258 off = get_byte(s->pb) * 3;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
259 j = (t & 0x3F) + 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
260 while(j-- && sz < 256) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
261 *pal++ = oldpal[off + 0];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
262 *pal++ = oldpal[off + 1];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
263 *pal++ = oldpal[off + 2];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
264 sz++;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
265 off += 3;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
266 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
267 } else { /* new entries */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
268 *pal++ = smk_pal[t];
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
269 *pal++ = smk_pal[get_byte(s->pb) & 0x3F];
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
270 *pal++ = smk_pal[get_byte(s->pb) & 0x3F];
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
271 sz++;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
272 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
273 }
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
274 url_fseek(s->pb, pos, 0);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
275 palchange |= 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
276 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
277 flags >>= 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
278 smk->curstream = -1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
279 /* if audio chunks are present, put them to stack and retrieve later */
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
280 for(i = 0; i < 7; i++) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
281 if(flags & 1) {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
282 int size;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
283 size = get_le32(s->pb) - 4;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
284 frame_size -= size;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
285 frame_size -= 4;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
286 smk->curstream++;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
287 smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
288 smk->buf_sizes[smk->curstream] = size;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
289 ret = get_buffer(s->pb, smk->bufs[smk->curstream], size);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
290 if(ret != size)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
291 return AVERROR(EIO);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
292 smk->stream_id[smk->curstream] = smk->indexes[i];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
293 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
294 flags >>= 1;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
295 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
296 if (av_new_packet(pkt, frame_size + 768))
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
297 return AVERROR(ENOMEM);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
298 if(smk->frm_size[smk->cur_frame] & 1)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
299 palchange |= 2;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
300 pkt->data[0] = palchange;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
301 memcpy(pkt->data + 1, smk->pal, 768);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
302 ret = get_buffer(s->pb, pkt->data + 769, frame_size);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
303 if(ret != frame_size)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
304 return AVERROR(EIO);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
305 pkt->stream_index = smk->videoindex;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
306 pkt->size = ret + 769;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
307 smk->cur_frame++;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2404
diff changeset
308 smk->nextpos = url_ftell(s->pb);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
309 } else {
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
310 if (av_new_packet(pkt, smk->buf_sizes[smk->curstream]))
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
311 return AVERROR(ENOMEM);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
312 memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
313 pkt->size = smk->buf_sizes[smk->curstream];
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
314 pkt->stream_index = smk->stream_id[smk->curstream];
1090
80b1e60a735e Proper PTS generation for Smacker audio
kostya
parents: 1089
diff changeset
315 pkt->pts = smk->aud_pts[smk->curstream];
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1415
diff changeset
316 smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
317 smk->curstream--;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
318 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
319
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
320 return 0;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
321 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
322
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
323 static int smacker_read_close(AVFormatContext *s)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
324 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
325 SmackerContext *smk = s->priv_data;
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
326 int i;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
327
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
328 for(i = 0; i < 7; i++)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
329 if(smk->bufs[i])
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
330 av_free(smk->bufs[i]);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
331 if(smk->frm_size)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
332 av_free(smk->frm_size);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
333 if(smk->frm_flags)
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
334 av_free(smk->frm_flags);
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
335
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
336 return 0;
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
337 }
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
338
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
339 AVInputFormat smacker_demuxer = {
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
340 "smk",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 3399
diff changeset
341 NULL_IF_CONFIG_SMALL("Smacker video"),
1019
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
342 sizeof(SmackerContext),
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
343 smacker_probe,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
344 smacker_read_header,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
345 smacker_read_packet,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
346 smacker_read_close,
a9d8381ff40d Smacker demuxer and decoder.
kostya
parents:
diff changeset
347 };