| 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 & 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 = 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 = CODEC_CAP_DR1, |
| 340 | }; |
| 341 | #endif |