Mercurial > libavcodec.hg
annotate dxa.c @ 12043:f9a0bd0888a4 libavcodec
mpegaudio: call ff_mpegaudiodec_init_mmx() only from float decoder
The mmx code is floating-point only, and this function does not know
from which decoder it is called. Without this change, the integer
decoder only "works" because the size of the context struct is smaller
in this case, and the mmx init function writes the function pointer
outside the allocated context.
author | mru |
---|---|
date | Thu, 01 Jul 2010 23:21:17 +0000 |
parents | 7dd2a45249a9 |
children |
rev | line source |
---|---|
4671 | 1 /* |
2 * Feeble Files/ScummVM DXA decoder | |
3 * Copyright (c) 2007 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 /** | |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11560
diff
changeset
|
23 * @file |
4671 | 24 * DXA Video decoder |
25 */ | |
26 | |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
29 | |
8573
2acf0ae7b041
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
7040
diff
changeset
|
30 #include "libavutil/intreadwrite.h" |
4671 | 31 #include "avcodec.h" |
32 | |
33 #include <zlib.h> | |
34 | |
35 /* | |
36 * Decoder context | |
37 */ | |
38 typedef struct DxaDecContext { | |
39 AVCodecContext *avctx; | |
40 AVFrame pic, prev; | |
41 | |
42 int dsize; | |
43 uint8_t *decomp_buf; | |
44 uint32_t pal[256]; | |
45 } DxaDecContext; | |
46 | |
47 static const int shift1[6] = { 0, 8, 8, 8, 4, 4 }; | |
48 static const int shift2[6] = { 0, 0, 8, 4, 0, 4 }; | |
49 | |
50 static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref) | |
51 { | |
52 uint8_t *code, *data, *mv, *msk, *tmp, *tmp2; | |
53 int i, j, k; | |
54 int type, x, y, d, d2; | |
55 int stride = c->pic.linesize[0]; | |
56 uint32_t mask; | |
57 | |
58 code = src + 12; | |
59 data = code + ((avctx->width * avctx->height) >> 4); | |
60 mv = data + AV_RB32(src + 0); | |
61 msk = mv + AV_RB32(src + 4); | |
62 | |
63 for(j = 0; j < avctx->height; j += 4){ | |
64 for(i = 0; i < avctx->width; i += 4){ | |
65 tmp = dst + i; | |
66 tmp2 = ref + i; | |
67 type = *code++; | |
68 switch(type){ | |
69 case 4: // motion compensation | |
70 x = (*mv) >> 4; if(x & 8) x = 8 - x; | |
71 y = (*mv++) & 0xF; if(y & 8) y = 8 - y; | |
72 tmp2 += x + y*stride; | |
73 case 0: // skip | |
74 case 5: // skip in method 12 | |
75 for(y = 0; y < 4; y++){ | |
76 memcpy(tmp, tmp2, 4); | |
77 tmp += stride; | |
78 tmp2 += stride; | |
79 } | |
80 break; | |
81 case 1: // masked change | |
82 case 10: // masked change with only half of pixels changed | |
83 case 11: // cases 10-15 are for method 12 only | |
84 case 12: | |
85 case 13: | |
86 case 14: | |
87 case 15: | |
88 if(type == 1){ | |
89 mask = AV_RB16(msk); | |
90 msk += 2; | |
91 }else{ | |
92 type -= 10; | |
93 mask = ((msk[0] & 0xF0) << shift1[type]) | ((msk[0] & 0xF) << shift2[type]); | |
94 msk++; | |
95 } | |
96 for(y = 0; y < 4; y++){ | |
97 for(x = 0; x < 4; x++){ | |
98 tmp[x] = (mask & 0x8000) ? *data++ : tmp2[x]; | |
99 mask <<= 1; | |
100 } | |
101 tmp += stride; | |
102 tmp2 += stride; | |
103 } | |
104 break; | |
105 case 2: // fill block | |
106 for(y = 0; y < 4; y++){ | |
107 memset(tmp, data[0], 4); | |
108 tmp += stride; | |
109 } | |
110 data++; | |
111 break; | |
112 case 3: // raw block | |
113 for(y = 0; y < 4; y++){ | |
114 memcpy(tmp, data, 4); | |
115 data += 4; | |
116 tmp += stride; | |
117 } | |
118 break; | |
119 case 8: // subblocks - method 13 only | |
120 mask = *msk++; | |
121 for(k = 0; k < 4; k++){ | |
122 d = ((k & 1) << 1) + ((k & 2) * stride); | |
123 d2 = ((k & 1) << 1) + ((k & 2) * stride); | |
124 tmp2 = ref + i + d2; | |
125 switch(mask & 0xC0){ | |
126 case 0x80: // motion compensation | |
127 x = (*mv) >> 4; if(x & 8) x = 8 - x; | |
128 y = (*mv++) & 0xF; if(y & 8) y = 8 - y; | |
129 tmp2 += x + y*stride; | |
130 case 0x00: // skip | |
131 tmp[d + 0 ] = tmp2[0]; | |
132 tmp[d + 1 ] = tmp2[1]; | |
133 tmp[d + 0 + stride] = tmp2[0 + stride]; | |
134 tmp[d + 1 + stride] = tmp2[1 + stride]; | |
135 break; | |
136 case 0x40: // fill | |
137 tmp[d + 0 ] = data[0]; | |
138 tmp[d + 1 ] = data[0]; | |
139 tmp[d + 0 + stride] = data[0]; | |
140 tmp[d + 1 + stride] = data[0]; | |
141 data++; | |
142 break; | |
143 case 0xC0: // raw | |
144 tmp[d + 0 ] = *data++; | |
145 tmp[d + 1 ] = *data++; | |
146 tmp[d + 0 + stride] = *data++; | |
147 tmp[d + 1 + stride] = *data++; | |
148 break; | |
149 } | |
150 mask <<= 2; | |
151 } | |
152 break; | |
153 case 32: // vector quantization - 2 colors | |
154 mask = AV_RB16(msk); | |
155 msk += 2; | |
156 for(y = 0; y < 4; y++){ | |
157 for(x = 0; x < 4; x++){ | |
158 tmp[x] = data[mask & 1]; | |
159 mask >>= 1; | |
160 } | |
161 tmp += stride; | |
162 tmp2 += stride; | |
163 } | |
164 data += 2; | |
165 break; | |
166 case 33: // vector quantization - 3 or 4 colors | |
167 case 34: | |
168 mask = AV_RB32(msk); | |
169 msk += 4; | |
170 for(y = 0; y < 4; y++){ | |
171 for(x = 0; x < 4; x++){ | |
172 tmp[x] = data[mask & 3]; | |
173 mask >>= 2; | |
174 } | |
175 tmp += stride; | |
176 tmp2 += stride; | |
177 } | |
178 data += type - 30; | |
179 break; | |
180 default: | |
181 av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type); | |
182 return -1; | |
183 } | |
184 } | |
185 dst += stride * 4; | |
186 ref += stride * 4; | |
187 } | |
188 return 0; | |
189 } | |
190 | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
191 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) |
4671 | 192 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
193 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
194 int buf_size = avpkt->size; |
4827 | 195 DxaDecContext * const c = avctx->priv_data; |
4671 | 196 uint8_t *outptr, *srcptr, *tmpptr; |
197 unsigned long dsize; | |
198 int i, j, compr; | |
199 int stride; | |
200 int orig_buf_size = buf_size; | |
201 int pc = 0; | |
202 | |
203 /* make the palette available on the way out */ | |
204 if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){ | |
205 int r, g, b; | |
206 | |
207 buf += 4; | |
208 for(i = 0; i < 256; i++){ | |
209 r = *buf++; | |
210 g = *buf++; | |
211 b = *buf++; | |
212 c->pal[i] = (r << 16) | (g << 8) | b; | |
213 } | |
214 pc = 1; | |
215 buf_size -= 768+4; | |
216 } | |
217 | |
218 if(avctx->get_buffer(avctx, &c->pic) < 0){ | |
219 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
220 return -1; | |
221 } | |
222 memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); | |
223 c->pic.palette_has_changed = pc; | |
224 | |
225 outptr = c->pic.data[0]; | |
226 srcptr = c->decomp_buf; | |
227 tmpptr = c->prev.data[0]; | |
228 stride = c->pic.linesize[0]; | |
229 | |
230 if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L') | |
231 compr = -1; | |
232 else | |
233 compr = buf[4]; | |
234 | |
235 dsize = c->dsize; | |
236 if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){ | |
237 av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n"); | |
238 return -1; | |
239 } | |
240 switch(compr){ | |
241 case -1: | |
242 c->pic.key_frame = 0; | |
243 c->pic.pict_type = FF_P_TYPE; | |
244 if(c->prev.data[0]) | |
245 memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height); | |
246 else{ // Should happen only when first frame is 'NULL' | |
247 memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height); | |
248 c->pic.key_frame = 1; | |
249 c->pic.pict_type = FF_I_TYPE; | |
250 } | |
251 break; | |
252 case 2: | |
253 case 3: | |
254 case 4: | |
255 case 5: | |
256 c->pic.key_frame = !(compr & 1); | |
257 c->pic.pict_type = (compr & 1) ? FF_P_TYPE : FF_I_TYPE; | |
258 for(j = 0; j < avctx->height; j++){ | |
259 if(compr & 1){ | |
260 for(i = 0; i < avctx->width; i++) | |
261 outptr[i] = srcptr[i] ^ tmpptr[i]; | |
262 tmpptr += stride; | |
263 }else | |
264 memcpy(outptr, srcptr, avctx->width); | |
265 outptr += stride; | |
266 srcptr += avctx->width; | |
267 } | |
268 break; | |
269 case 12: // ScummVM coding | |
270 case 13: | |
271 c->pic.key_frame = 0; | |
272 c->pic.pict_type = FF_P_TYPE; | |
273 decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]); | |
274 break; | |
275 default: | |
276 av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]); | |
277 return -1; | |
278 } | |
279 | |
280 FFSWAP(AVFrame, c->pic, c->prev); | |
281 if(c->pic.data[0]) | |
282 avctx->release_buffer(avctx, &c->pic); | |
283 | |
284 *data_size = sizeof(AVFrame); | |
285 *(AVFrame*)data = c->prev; | |
286 | |
287 /* always report that the buffer was completely consumed */ | |
288 return orig_buf_size; | |
289 } | |
290 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6267
diff
changeset
|
291 static av_cold int decode_init(AVCodecContext *avctx) |
4671 | 292 { |
4827 | 293 DxaDecContext * const c = avctx->priv_data; |
4671 | 294 |
295 c->avctx = avctx; | |
296 avctx->pix_fmt = PIX_FMT_PAL8; | |
297 | |
298 c->dsize = avctx->width * avctx->height * 2; | |
299 if((c->decomp_buf = av_malloc(c->dsize)) == NULL) { | |
300 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); | |
301 return -1; | |
302 } | |
303 | |
304 return 0; | |
305 } | |
306 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6267
diff
changeset
|
307 static av_cold int decode_end(AVCodecContext *avctx) |
4671 | 308 { |
4827 | 309 DxaDecContext * const c = avctx->priv_data; |
4671 | 310 |
311 av_freep(&c->decomp_buf); | |
312 if(c->prev.data[0]) | |
313 avctx->release_buffer(avctx, &c->prev); | |
314 if(c->pic.data[0]) | |
315 avctx->release_buffer(avctx, &c->pic); | |
316 | |
317 return 0; | |
318 } | |
319 | |
320 AVCodec dxa_decoder = { | |
321 "dxa", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10397
diff
changeset
|
322 AVMEDIA_TYPE_VIDEO, |
4671 | 323 CODEC_ID_DXA, |
324 sizeof(DxaDecContext), | |
325 decode_init, | |
326 NULL, | |
327 decode_end, | |
6712 | 328 decode_frame, |
9800 | 329 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
330 .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), |
4671 | 331 }; |
332 |