Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6147 | serge | 1 | /* |
2 | * Copyright (c) 2003 Michael Niedermayer |
||
3 | * |
||
4 | * This file is part of FFmpeg. |
||
5 | * |
||
6 | * FFmpeg is free software; you can redistribute it and/or |
||
7 | * modify it under the terms of the GNU Lesser General Public |
||
8 | * License as published by the Free Software Foundation; either |
||
9 | * version 2.1 of the License, or (at your option) any later version. |
||
10 | * |
||
11 | * FFmpeg is distributed in the hope that it will be useful, |
||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
14 | * Lesser General Public License for more details. |
||
15 | * |
||
16 | * You should have received a copy of the GNU Lesser General Public |
||
17 | * License along with FFmpeg; if not, write to the Free Software |
||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
19 | */ |
||
20 | |||
21 | /** |
||
22 | * @file |
||
23 | * ASUS V1/V2 decoder. |
||
24 | */ |
||
25 | |||
26 | #include "libavutil/attributes.h" |
||
27 | #include "libavutil/mem.h" |
||
28 | |||
29 | #include "asv.h" |
||
30 | #include "avcodec.h" |
||
31 | #include "blockdsp.h" |
||
32 | #include "idctdsp.h" |
||
33 | #include "internal.h" |
||
34 | #include "mathops.h" |
||
35 | #include "mpeg12data.h" |
||
36 | |||
37 | #define VLC_BITS 6 |
||
38 | #define ASV2_LEVEL_VLC_BITS 10 |
||
39 | |||
40 | static VLC ccp_vlc; |
||
41 | static VLC level_vlc; |
||
42 | static VLC dc_ccp_vlc; |
||
43 | static VLC ac_ccp_vlc; |
||
44 | static VLC asv2_level_vlc; |
||
45 | |||
46 | static av_cold void init_vlcs(ASV1Context *a) |
||
47 | { |
||
48 | static int done = 0; |
||
49 | |||
50 | if (!done) { |
||
51 | done = 1; |
||
52 | |||
53 | INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17, |
||
54 | &ff_asv_ccp_tab[0][1], 2, 1, |
||
55 | &ff_asv_ccp_tab[0][0], 2, 1, 64); |
||
56 | INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8, |
||
57 | &ff_asv_dc_ccp_tab[0][1], 2, 1, |
||
58 | &ff_asv_dc_ccp_tab[0][0], 2, 1, 64); |
||
59 | INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16, |
||
60 | &ff_asv_ac_ccp_tab[0][1], 2, 1, |
||
61 | &ff_asv_ac_ccp_tab[0][0], 2, 1, 64); |
||
62 | INIT_VLC_STATIC(&level_vlc, VLC_BITS, 7, |
||
63 | &ff_asv_level_tab[0][1], 2, 1, |
||
64 | &ff_asv_level_tab[0][0], 2, 1, 64); |
||
65 | INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, |
||
66 | &ff_asv2_level_tab[0][1], 2, 1, |
||
67 | &ff_asv2_level_tab[0][0], 2, 1, 1024); |
||
68 | } |
||
69 | } |
||
70 | |||
71 | // FIXME write a reversed bitstream reader to avoid the double reverse |
||
72 | static inline int asv2_get_bits(GetBitContext *gb, int n) |
||
73 | { |
||
74 | return ff_reverse[get_bits(gb, n) << (8 - n)]; |
||
75 | } |
||
76 | |||
77 | static inline int asv1_get_level(GetBitContext *gb) |
||
78 | { |
||
79 | int code = get_vlc2(gb, level_vlc.table, VLC_BITS, 1); |
||
80 | |||
81 | if (code == 3) |
||
82 | return get_sbits(gb, 8); |
||
83 | else |
||
84 | return code - 3; |
||
85 | } |
||
86 | |||
87 | static inline int asv2_get_level(GetBitContext *gb) |
||
88 | { |
||
89 | int code = get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); |
||
90 | |||
91 | if (code == 31) |
||
92 | return (int8_t) asv2_get_bits(gb, 8); |
||
93 | else |
||
94 | return code - 31; |
||
95 | } |
||
96 | |||
97 | static inline int asv1_decode_block(ASV1Context *a, int16_t block[64]) |
||
98 | { |
||
99 | int i; |
||
100 | |||
101 | block[0] = 8 * get_bits(&a->gb, 8); |
||
102 | |||
103 | for (i = 0; i < 11; i++) { |
||
104 | const int ccp = get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); |
||
105 | |||
106 | if (ccp) { |
||
107 | if (ccp == 16) |
||
108 | break; |
||
109 | if (ccp < 0 || i >= 10) { |
||
110 | av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n"); |
||
111 | return AVERROR_INVALIDDATA; |
||
112 | } |
||
113 | |||
114 | if (ccp & 8) |
||
115 | block[a->scantable.permutated[4 * i + 0]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4; |
||
116 | if (ccp & 4) |
||
117 | block[a->scantable.permutated[4 * i + 1]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4; |
||
118 | if (ccp & 2) |
||
119 | block[a->scantable.permutated[4 * i + 2]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4; |
||
120 | if (ccp & 1) |
||
121 | block[a->scantable.permutated[4 * i + 3]] = (asv1_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4; |
||
122 | } |
||
123 | } |
||
124 | |||
125 | return 0; |
||
126 | } |
||
127 | |||
128 | static inline int asv2_decode_block(ASV1Context *a, int16_t block[64]) |
||
129 | { |
||
130 | int i, count, ccp; |
||
131 | |||
132 | count = asv2_get_bits(&a->gb, 4); |
||
133 | |||
134 | block[0] = 8 * asv2_get_bits(&a->gb, 8); |
||
135 | |||
136 | ccp = get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); |
||
137 | if (ccp) { |
||
138 | if (ccp & 4) |
||
139 | block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4; |
||
140 | if (ccp & 2) |
||
141 | block[a->scantable.permutated[2]] = (asv2_get_level(&a->gb) * a->intra_matrix[2]) >> 4; |
||
142 | if (ccp & 1) |
||
143 | block[a->scantable.permutated[3]] = (asv2_get_level(&a->gb) * a->intra_matrix[3]) >> 4; |
||
144 | } |
||
145 | |||
146 | for (i = 1; i < count + 1; i++) { |
||
147 | const int ccp = get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1); |
||
148 | |||
149 | if (ccp) { |
||
150 | if (ccp & 8) |
||
151 | block[a->scantable.permutated[4 * i + 0]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 0]) >> 4; |
||
152 | if (ccp & 4) |
||
153 | block[a->scantable.permutated[4 * i + 1]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 1]) >> 4; |
||
154 | if (ccp & 2) |
||
155 | block[a->scantable.permutated[4 * i + 2]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 2]) >> 4; |
||
156 | if (ccp & 1) |
||
157 | block[a->scantable.permutated[4 * i + 3]] = (asv2_get_level(&a->gb) * a->intra_matrix[4 * i + 3]) >> 4; |
||
158 | } |
||
159 | } |
||
160 | |||
161 | return 0; |
||
162 | } |
||
163 | |||
164 | static inline int decode_mb(ASV1Context *a, int16_t block[6][64]) |
||
165 | { |
||
166 | int i; |
||
167 | |||
168 | a->bdsp.clear_blocks(block[0]); |
||
169 | |||
170 | if (a->avctx->codec_id == AV_CODEC_ID_ASV1) { |
||
171 | for (i = 0; i < 6; i++) { |
||
172 | if (asv1_decode_block(a, block[i]) < 0) |
||
173 | return -1; |
||
174 | } |
||
175 | } else { |
||
176 | for (i = 0; i < 6; i++) { |
||
177 | if (asv2_decode_block(a, block[i]) < 0) |
||
178 | return -1; |
||
179 | } |
||
180 | } |
||
181 | return 0; |
||
182 | } |
||
183 | |||
184 | static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y) |
||
185 | { |
||
186 | int16_t(*block)[64] = a->block; |
||
187 | int linesize = frame->linesize[0]; |
||
188 | |||
189 | uint8_t *dest_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; |
||
190 | uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; |
||
191 | uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; |
||
192 | |||
193 | a->idsp.idct_put(dest_y, linesize, block[0]); |
||
194 | a->idsp.idct_put(dest_y + 8, linesize, block[1]); |
||
195 | a->idsp.idct_put(dest_y + 8 * linesize, linesize, block[2]); |
||
196 | a->idsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]); |
||
197 | |||
198 | if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) { |
||
199 | a->idsp.idct_put(dest_cb, frame->linesize[1], block[4]); |
||
200 | a->idsp.idct_put(dest_cr, frame->linesize[2], block[5]); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
||
205 | AVPacket *avpkt) |
||
206 | { |
||
207 | ASV1Context *const a = avctx->priv_data; |
||
208 | const uint8_t *buf = avpkt->data; |
||
209 | int buf_size = avpkt->size; |
||
210 | AVFrame *const p = data; |
||
211 | int mb_x, mb_y, ret; |
||
212 | |||
213 | if ((ret = ff_get_buffer(avctx, p, 0)) < 0) |
||
214 | return ret; |
||
215 | p->pict_type = AV_PICTURE_TYPE_I; |
||
216 | p->key_frame = 1; |
||
217 | |||
218 | av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, |
||
219 | buf_size); |
||
220 | if (!a->bitstream_buffer) |
||
221 | return AVERROR(ENOMEM); |
||
222 | |||
223 | if (avctx->codec_id == AV_CODEC_ID_ASV1) { |
||
224 | a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer, |
||
225 | (const uint32_t *) buf, buf_size / 4); |
||
226 | } else { |
||
227 | int i; |
||
228 | for (i = 0; i < buf_size; i++) |
||
229 | a->bitstream_buffer[i] = ff_reverse[buf[i]]; |
||
230 | } |
||
231 | |||
232 | init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8); |
||
233 | |||
234 | for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { |
||
235 | for (mb_x = 0; mb_x < a->mb_width2; mb_x++) { |
||
236 | if ((ret = decode_mb(a, a->block)) < 0) |
||
237 | return ret; |
||
238 | |||
239 | idct_put(a, p, mb_x, mb_y); |
||
240 | } |
||
241 | } |
||
242 | |||
243 | if (a->mb_width2 != a->mb_width) { |
||
244 | mb_x = a->mb_width2; |
||
245 | for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { |
||
246 | if ((ret = decode_mb(a, a->block)) < 0) |
||
247 | return ret; |
||
248 | |||
249 | idct_put(a, p, mb_x, mb_y); |
||
250 | } |
||
251 | } |
||
252 | |||
253 | if (a->mb_height2 != a->mb_height) { |
||
254 | mb_y = a->mb_height2; |
||
255 | for (mb_x = 0; mb_x < a->mb_width; mb_x++) { |
||
256 | if ((ret = decode_mb(a, a->block)) < 0) |
||
257 | return ret; |
||
258 | |||
259 | idct_put(a, p, mb_x, mb_y); |
||
260 | } |
||
261 | } |
||
262 | |||
263 | *got_frame = 1; |
||
264 | |||
265 | emms_c(); |
||
266 | |||
267 | return (get_bits_count(&a->gb) + 31) / 32 * 4; |
||
268 | } |
||
269 | |||
270 | static av_cold int decode_init(AVCodecContext *avctx) |
||
271 | { |
||
272 | ASV1Context *const a = avctx->priv_data; |
||
273 | const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; |
||
274 | int i; |
||
275 | |||
276 | if (avctx->extradata_size < 1) { |
||
277 | av_log(avctx, AV_LOG_WARNING, "No extradata provided\n"); |
||
278 | } |
||
279 | |||
280 | ff_asv_common_init(avctx); |
||
281 | ff_blockdsp_init(&a->bdsp, avctx); |
||
282 | ff_idctdsp_init(&a->idsp, avctx); |
||
283 | init_vlcs(a); |
||
284 | ff_init_scantable(a->idsp.idct_permutation, &a->scantable, ff_asv_scantab); |
||
285 | avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
||
286 | |||
287 | if (avctx->extradata_size < 1 || (a->inv_qscale = avctx->extradata[0]) == 0) { |
||
288 | av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n"); |
||
289 | if (avctx->codec_id == AV_CODEC_ID_ASV1) |
||
290 | a->inv_qscale = 6; |
||
291 | else |
||
292 | a->inv_qscale = 10; |
||
293 | } |
||
294 | |||
295 | for (i = 0; i < 64; i++) { |
||
296 | int index = ff_asv_scantab[i]; |
||
297 | |||
298 | a->intra_matrix[i] = 64 * scale * ff_mpeg1_default_intra_matrix[index] / |
||
299 | a->inv_qscale; |
||
300 | } |
||
301 | |||
302 | return 0; |
||
303 | } |
||
304 | |||
305 | static av_cold int decode_end(AVCodecContext *avctx) |
||
306 | { |
||
307 | ASV1Context *const a = avctx->priv_data; |
||
308 | |||
309 | av_freep(&a->bitstream_buffer); |
||
310 | a->bitstream_buffer_size = 0; |
||
311 | |||
312 | return 0; |
||
313 | } |
||
314 | |||
315 | #if CONFIG_ASV1_DECODER |
||
316 | AVCodec ff_asv1_decoder = { |
||
317 | .name = "asv1", |
||
318 | .long_name = NULL_IF_CONFIG_SMALL("ASUS V1"), |
||
319 | .type = AVMEDIA_TYPE_VIDEO, |
||
320 | .id = AV_CODEC_ID_ASV1, |
||
321 | .priv_data_size = sizeof(ASV1Context), |
||
322 | .init = decode_init, |
||
323 | .close = decode_end, |
||
324 | .decode = decode_frame, |
||
325 | .capabilities = AV_CODEC_CAP_DR1, |
||
326 | }; |
||
327 | #endif |
||
328 | |||
329 | #if CONFIG_ASV2_DECODER |
||
330 | AVCodec ff_asv2_decoder = { |
||
331 | .name = "asv2", |
||
332 | .long_name = NULL_IF_CONFIG_SMALL("ASUS V2"), |
||
333 | .type = AVMEDIA_TYPE_VIDEO, |
||
334 | .id = AV_CODEC_ID_ASV2, |
||
335 | .priv_data_size = sizeof(ASV1Context), |
||
336 | .init = decode_init, |
||
337 | .close = decode_end, |
||
338 | .decode = decode_frame, |
||
339 | .capabilities = AV_CODEC_CAP_DR1, |
||
340 | }; |
||
341 | #endif>>>>>>>>>>>>>>>>>>>><> |