Mercurial > libavcodec.hg
annotate cscd.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 | 8a4984c5cacc |
children | ca1896830b44 |
rev | line source |
---|---|
3030 | 1 /* |
2 * CamStudio decoder | |
3 * Copyright (c) 2006 Reimar Doeffinger | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
3030 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
3030 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
3030 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
3034
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3030 | 20 */ |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 | |
24 #include "avcodec.h" | |
25 | |
8590 | 26 #if CONFIG_ZLIB |
3030 | 27 #include <zlib.h> |
28 #endif | |
6763 | 29 #include "libavutil/lzo.h" |
3030 | 30 |
31 typedef struct { | |
32 AVFrame pic; | |
33 int linelen, height, bpp; | |
34 unsigned int decomp_size; | |
35 unsigned char* decomp_buf; | |
36 } CamStudioContext; | |
37 | |
6312 | 38 static void copy_frame_default(AVFrame *f, const uint8_t *src, |
3030 | 39 int linelen, int height) { |
40 int i; | |
41 uint8_t *dst = f->data[0]; | |
42 dst += (height - 1) * f->linesize[0]; | |
43 for (i = height; i; i--) { | |
44 memcpy(dst, src, linelen); | |
45 src += linelen; | |
46 dst -= f->linesize[0]; | |
47 } | |
48 } | |
49 | |
6312 | 50 static void add_frame_default(AVFrame *f, const uint8_t *src, |
3030 | 51 int linelen, int height) { |
52 int i, j; | |
53 uint8_t *dst = f->data[0]; | |
54 dst += (height - 1) * f->linesize[0]; | |
55 for (i = height; i; i--) { | |
56 for (j = linelen; j; j--) | |
57 *dst++ += *src++; | |
58 dst -= f->linesize[0] + linelen; | |
59 } | |
60 } | |
61 | |
9985 | 62 #if !HAVE_BIGENDIAN |
3030 | 63 #define copy_frame_16 copy_frame_default |
64 #define copy_frame_32 copy_frame_default | |
65 #define add_frame_16 add_frame_default | |
66 #define add_frame_32 add_frame_default | |
67 #else | |
6312 | 68 static void copy_frame_16(AVFrame *f, const uint8_t *src, |
3030 | 69 int linelen, int height) { |
70 int i, j; | |
71 uint8_t *dst = f->data[0]; | |
72 dst += (height - 1) * f->linesize[0]; | |
73 for (i = height; i; i--) { | |
74 for (j = linelen / 2; j; j--) { | |
75 dst[0] = src[1]; | |
76 dst[1] = src[0]; | |
77 src += 2; | |
78 dst += 2; | |
79 } | |
80 dst -= f->linesize[0] + linelen; | |
81 } | |
82 } | |
83 | |
6312 | 84 static void copy_frame_32(AVFrame *f, const uint8_t *src, |
3030 | 85 int linelen, int height) { |
86 int i, j; | |
87 uint8_t *dst = f->data[0]; | |
88 dst += (height - 1) * f->linesize[0]; | |
89 for (i = height; i; i--) { | |
90 for (j = linelen / 4; j; j--) { | |
91 dst[0] = src[3]; | |
92 dst[1] = src[2]; | |
93 dst[2] = src[1]; | |
94 dst[3] = src[0]; | |
95 src += 4; | |
96 dst += 4; | |
97 } | |
98 dst -= f->linesize[0] + linelen; | |
99 } | |
100 } | |
101 | |
6312 | 102 static void add_frame_16(AVFrame *f, const uint8_t *src, |
3030 | 103 int linelen, int height) { |
104 int i, j; | |
105 uint8_t *dst = f->data[0]; | |
106 dst += (height - 1) * f->linesize[0]; | |
107 for (i = height; i; i--) { | |
108 for (j = linelen / 2; j; j--) { | |
109 dst[0] += src[1]; | |
110 dst[1] += src[0]; | |
111 src += 2; | |
112 dst += 2; | |
113 } | |
114 dst -= f->linesize[0] + linelen; | |
115 } | |
116 } | |
117 | |
6312 | 118 static void add_frame_32(AVFrame *f, const uint8_t *src, |
3030 | 119 int linelen, int height) { |
120 int i, j; | |
121 uint8_t *dst = f->data[0]; | |
122 dst += (height - 1) * f->linesize[0]; | |
123 for (i = height; i; i--) { | |
124 for (j = linelen / 4; j; j--) { | |
125 dst[0] += src[3]; | |
126 dst[1] += src[2]; | |
127 dst[2] += src[1]; | |
128 dst[3] += src[0]; | |
129 src += 4; | |
130 dst += 4; | |
131 } | |
132 dst -= f->linesize[0] + linelen; | |
133 } | |
134 } | |
135 #endif | |
136 | |
137 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8732
diff
changeset
|
138 AVPacket *avpkt) { |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8732
diff
changeset
|
139 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8732
diff
changeset
|
140 int buf_size = avpkt->size; |
4827 | 141 CamStudioContext *c = avctx->priv_data; |
3030 | 142 AVFrame *picture = data; |
143 | |
144 if (buf_size < 2) { | |
145 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); | |
146 return -1; | |
147 } | |
148 | |
149 if (c->pic.data[0]) | |
150 avctx->release_buffer(avctx, &c->pic); | |
151 c->pic.reference = 1; | |
152 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | | |
153 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | |
154 if (avctx->get_buffer(avctx, &c->pic) < 0) { | |
155 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
156 return -1; | |
157 } | |
158 | |
159 // decompress data | |
160 switch ((buf[0] >> 1) & 7) { | |
161 case 0: { // lzo compression | |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
3030
diff
changeset
|
162 int outlen = c->decomp_size, inlen = buf_size - 2; |
8732
967c0a1a60a0
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
8590
diff
changeset
|
163 if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen)) |
3030 | 164 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); |
165 break; | |
166 } | |
167 case 1: { // zlib compression | |
8590 | 168 #if CONFIG_ZLIB |
3030 | 169 unsigned long dlen = c->decomp_size; |
170 if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) | |
171 av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); | |
172 break; | |
173 #else | |
174 av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n"); | |
175 return -1; | |
176 #endif | |
177 } | |
178 default: | |
179 av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); | |
180 return -1; | |
181 } | |
182 | |
183 // flip upside down, add difference frame | |
184 if (buf[0] & 1) { // keyframe | |
185 c->pic.pict_type = FF_I_TYPE; | |
186 c->pic.key_frame = 1; | |
187 switch (c->bpp) { | |
188 case 16: | |
189 copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); | |
190 break; | |
191 case 32: | |
192 copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); | |
193 break; | |
194 default: | |
195 copy_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); | |
196 } | |
197 } else { | |
198 c->pic.pict_type = FF_P_TYPE; | |
199 c->pic.key_frame = 0; | |
200 switch (c->bpp) { | |
201 case 16: | |
202 add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); | |
203 break; | |
204 case 32: | |
205 add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); | |
206 break; | |
207 default: | |
208 add_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); | |
209 } | |
210 } | |
211 | |
212 *picture = c->pic; | |
213 *data_size = sizeof(AVFrame); | |
214 return buf_size; | |
215 } | |
216 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6312
diff
changeset
|
217 static av_cold int decode_init(AVCodecContext *avctx) { |
4827 | 218 CamStudioContext *c = avctx->priv_data; |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
219 switch (avctx->bits_per_coded_sample) { |
4290
e7dfc2743e26
Fix 16 bit cscd samples, 16 bit raw means RGB555 on Windows, and the original
reimar
parents:
4289
diff
changeset
|
220 case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; |
3030 | 221 case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4290
diff
changeset
|
222 case 32: avctx->pix_fmt = PIX_FMT_RGB32; break; |
3030 | 223 default: |
224 av_log(avctx, AV_LOG_ERROR, | |
4289 | 225 "CamStudio codec error: invalid depth %i bpp\n", |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
226 avctx->bits_per_coded_sample); |
3030 | 227 return 1; |
228 } | |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
229 c->bpp = avctx->bits_per_coded_sample; |
3030 | 230 c->pic.data[0] = NULL; |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
231 c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; |
3030 | 232 c->height = avctx->height; |
233 c->decomp_size = c->height * c->linelen; | |
8732
967c0a1a60a0
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
8590
diff
changeset
|
234 c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); |
3030 | 235 if (!c->decomp_buf) { |
236 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); | |
237 return 1; | |
238 } | |
239 return 0; | |
240 } | |
241 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6312
diff
changeset
|
242 static av_cold int decode_end(AVCodecContext *avctx) { |
4827 | 243 CamStudioContext *c = avctx->priv_data; |
3030 | 244 av_freep(&c->decomp_buf); |
245 if (c->pic.data[0]) | |
246 avctx->release_buffer(avctx, &c->pic); | |
247 return 0; | |
248 } | |
249 | |
250 AVCodec cscd_decoder = { | |
251 "camstudio", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10397
diff
changeset
|
252 AVMEDIA_TYPE_VIDEO, |
3030 | 253 CODEC_ID_CSCD, |
254 sizeof(CamStudioContext), | |
255 decode_init, | |
256 NULL, | |
257 decode_end, | |
258 decode_frame, | |
259 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6763
diff
changeset
|
260 .long_name = NULL_IF_CONFIG_SMALL("CamStudio"), |
3030 | 261 }; |
262 |