Mercurial > libavcodec.hg
annotate cscd.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | 8cafb4db28cb |
children |
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 | |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
38 static void copy_frame_default(AVFrame *f, const uint8_t *src, int src_stride, |
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); | |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
45 src += src_stride; |
3030 | 46 dst -= f->linesize[0]; |
47 } | |
48 } | |
49 | |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
50 static void add_frame_default(AVFrame *f, const uint8_t *src, int src_stride, |
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++; | |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
58 src += src_stride - linelen; |
3030 | 59 dst -= f->linesize[0] + linelen; |
60 } | |
61 } | |
62 | |
9985 | 63 #if !HAVE_BIGENDIAN |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
64 #define copy_frame_16(f, s, l, h) copy_frame_default(f, s, l, l, h) |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
65 #define copy_frame_32(f, s, l, h) copy_frame_default(f, s, l, l, h) |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
66 #define add_frame_16(f, s, l, h) add_frame_default(f, s, l, l, h) |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
67 #define add_frame_32(f, s, l, h) add_frame_default(f, s, l, l, h) |
3030 | 68 #else |
6312 | 69 static void copy_frame_16(AVFrame *f, const uint8_t *src, |
3030 | 70 int linelen, int height) { |
71 int i, j; | |
72 uint8_t *dst = f->data[0]; | |
73 dst += (height - 1) * f->linesize[0]; | |
74 for (i = height; i; i--) { | |
75 for (j = linelen / 2; j; j--) { | |
76 dst[0] = src[1]; | |
77 dst[1] = src[0]; | |
78 src += 2; | |
79 dst += 2; | |
80 } | |
81 dst -= f->linesize[0] + linelen; | |
82 } | |
83 } | |
84 | |
6312 | 85 static void copy_frame_32(AVFrame *f, const uint8_t *src, |
3030 | 86 int linelen, int height) { |
87 int i, j; | |
88 uint8_t *dst = f->data[0]; | |
89 dst += (height - 1) * f->linesize[0]; | |
90 for (i = height; i; i--) { | |
91 for (j = linelen / 4; j; j--) { | |
92 dst[0] = src[3]; | |
93 dst[1] = src[2]; | |
94 dst[2] = src[1]; | |
95 dst[3] = src[0]; | |
96 src += 4; | |
97 dst += 4; | |
98 } | |
99 dst -= f->linesize[0] + linelen; | |
100 } | |
101 } | |
102 | |
6312 | 103 static void add_frame_16(AVFrame *f, const uint8_t *src, |
3030 | 104 int linelen, int height) { |
105 int i, j; | |
106 uint8_t *dst = f->data[0]; | |
107 dst += (height - 1) * f->linesize[0]; | |
108 for (i = height; i; i--) { | |
109 for (j = linelen / 2; j; j--) { | |
110 dst[0] += src[1]; | |
111 dst[1] += src[0]; | |
112 src += 2; | |
113 dst += 2; | |
114 } | |
115 dst -= f->linesize[0] + linelen; | |
116 } | |
117 } | |
118 | |
6312 | 119 static void add_frame_32(AVFrame *f, const uint8_t *src, |
3030 | 120 int linelen, int height) { |
121 int i, j; | |
122 uint8_t *dst = f->data[0]; | |
123 dst += (height - 1) * f->linesize[0]; | |
124 for (i = height; i; i--) { | |
125 for (j = linelen / 4; j; j--) { | |
126 dst[0] += src[3]; | |
127 dst[1] += src[2]; | |
128 dst[2] += src[1]; | |
129 dst[3] += src[0]; | |
130 src += 4; | |
131 dst += 4; | |
132 } | |
133 dst -= f->linesize[0] + linelen; | |
134 } | |
135 } | |
136 #endif | |
137 | |
138 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
|
139 AVPacket *avpkt) { |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8732
diff
changeset
|
140 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8732
diff
changeset
|
141 int buf_size = avpkt->size; |
4827 | 142 CamStudioContext *c = avctx->priv_data; |
3030 | 143 AVFrame *picture = data; |
144 | |
145 if (buf_size < 2) { | |
146 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); | |
147 return -1; | |
148 } | |
149 | |
150 if (c->pic.data[0]) | |
151 avctx->release_buffer(avctx, &c->pic); | |
152 c->pic.reference = 1; | |
153 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | | |
154 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | |
155 if (avctx->get_buffer(avctx, &c->pic) < 0) { | |
156 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
157 return -1; | |
158 } | |
159 | |
160 // decompress data | |
161 switch ((buf[0] >> 1) & 7) { | |
162 case 0: { // lzo compression | |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
3030
diff
changeset
|
163 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
|
164 if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen)) |
3030 | 165 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); |
166 break; | |
167 } | |
168 case 1: { // zlib compression | |
8590 | 169 #if CONFIG_ZLIB |
3030 | 170 unsigned long dlen = c->decomp_size; |
171 if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) | |
172 av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); | |
173 break; | |
174 #else | |
175 av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n"); | |
176 return -1; | |
177 #endif | |
178 } | |
179 default: | |
180 av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); | |
181 return -1; | |
182 } | |
183 | |
184 // flip upside down, add difference frame | |
185 if (buf[0] & 1) { // keyframe | |
186 c->pic.pict_type = FF_I_TYPE; | |
187 c->pic.key_frame = 1; | |
188 switch (c->bpp) { | |
189 case 16: | |
190 copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); | |
191 break; | |
192 case 32: | |
193 copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); | |
194 break; | |
195 default: | |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
196 copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4), |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
197 c->linelen, c->height); |
3030 | 198 } |
199 } else { | |
200 c->pic.pict_type = FF_P_TYPE; | |
201 c->pic.key_frame = 0; | |
202 switch (c->bpp) { | |
203 case 16: | |
204 add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); | |
205 break; | |
206 case 32: | |
207 add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); | |
208 break; | |
209 default: | |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
210 add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4), |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
211 c->linelen, c->height); |
3030 | 212 } |
213 } | |
214 | |
215 *picture = c->pic; | |
216 *data_size = sizeof(AVFrame); | |
217 return buf_size; | |
218 } | |
219 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6312
diff
changeset
|
220 static av_cold int decode_init(AVCodecContext *avctx) { |
4827 | 221 CamStudioContext *c = avctx->priv_data; |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
222 int stride; |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
223 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
|
224 case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; |
3030 | 225 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
|
226 case 32: avctx->pix_fmt = PIX_FMT_RGB32; break; |
3030 | 227 default: |
228 av_log(avctx, AV_LOG_ERROR, | |
4289 | 229 "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
|
230 avctx->bits_per_coded_sample); |
12479 | 231 return 1; |
3030 | 232 } |
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
233 c->bpp = avctx->bits_per_coded_sample; |
3030 | 234 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
|
235 c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; |
3030 | 236 c->height = avctx->height; |
12482
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
237 stride = c->linelen; |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
238 if (avctx->bits_per_coded_sample == 24) |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
239 stride = FFALIGN(stride, 4); |
8cafb4db28cb
Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this)
reimar
parents:
12479
diff
changeset
|
240 c->decomp_size = c->height * stride; |
8732
967c0a1a60a0
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
8590
diff
changeset
|
241 c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); |
3030 | 242 if (!c->decomp_buf) { |
243 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); | |
244 return 1; | |
245 } | |
246 return 0; | |
247 } | |
248 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6312
diff
changeset
|
249 static av_cold int decode_end(AVCodecContext *avctx) { |
4827 | 250 CamStudioContext *c = avctx->priv_data; |
3030 | 251 av_freep(&c->decomp_buf); |
252 if (c->pic.data[0]) | |
253 avctx->release_buffer(avctx, &c->pic); | |
254 return 0; | |
255 } | |
256 | |
257 AVCodec cscd_decoder = { | |
258 "camstudio", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10397
diff
changeset
|
259 AVMEDIA_TYPE_VIDEO, |
3030 | 260 CODEC_ID_CSCD, |
261 sizeof(CamStudioContext), | |
262 decode_init, | |
263 NULL, | |
264 decode_end, | |
265 decode_frame, | |
266 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6763
diff
changeset
|
267 .long_name = NULL_IF_CONFIG_SMALL("CamStudio"), |
3030 | 268 }; |
269 |