| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * ClearVideo decoder | ||
| 3 | * Copyright (c) 2012-2018 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 | /** | ||
| 23 | * @file | ||
| 24 | * ClearVideo decoder | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include "libavutil/mem.h" | ||
| 28 | #include "libavutil/mem_internal.h" | ||
| 29 | #include "libavutil/thread.h" | ||
| 30 | |||
| 31 | #include "avcodec.h" | ||
| 32 | #include "bytestream.h" | ||
| 33 | #include "codec_internal.h" | ||
| 34 | #include "decode.h" | ||
| 35 | #include "get_bits.h" | ||
| 36 | #include "idctdsp.h" | ||
| 37 | #include "mathops.h" | ||
| 38 | #include "clearvideodata.h" | ||
| 39 | |||
| 40 | #define CLV_VLC_BITS 9 | ||
| 41 | |||
| 42 | typedef struct LevelCodes { | ||
| 43 | const VLCElem *flags_cb; | ||
| 44 | const VLCElem *mv_cb; | ||
| 45 | const VLCElem *bias_cb; | ||
| 46 | } LevelCodes; | ||
| 47 | |||
| 48 | typedef struct MV { | ||
| 49 | int16_t x, y; | ||
| 50 | } MV; | ||
| 51 | |||
| 52 | static const MV zero_mv = { 0 }; | ||
| 53 | |||
| 54 | typedef struct MVInfo { | ||
| 55 | int mb_w; | ||
| 56 | int mb_h; | ||
| 57 | int mb_size; | ||
| 58 | int mb_stride; | ||
| 59 | int top; | ||
| 60 | MV *mv; | ||
| 61 | } MVInfo; | ||
| 62 | |||
| 63 | typedef struct CLVContext { | ||
| 64 | AVCodecContext *avctx; | ||
| 65 | IDCTDSPContext idsp; | ||
| 66 | AVFrame *pic; | ||
| 67 | AVFrame *prev; | ||
| 68 | GetBitContext gb; | ||
| 69 | int mb_width, mb_height; | ||
| 70 | int pmb_width, pmb_height; | ||
| 71 | MVInfo mvi; | ||
| 72 | int tile_size; | ||
| 73 | int tile_shift; | ||
| 74 | int luma_dc_quant, chroma_dc_quant, ac_quant; | ||
| 75 | DECLARE_ALIGNED(16, int16_t, block)[64]; | ||
| 76 | int top_dc[3], left_dc[4]; | ||
| 77 | } CLVContext; | ||
| 78 | |||
| 79 | static VLCElem dc_vlc[1104], ac_vlc[554]; | ||
| 80 | static LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V | ||
| 81 | |||
| 82 | ✗ | static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, | |
| 83 | int ac_quant) | ||
| 84 | { | ||
| 85 | ✗ | GetBitContext *gb = &ctx->gb; | |
| 86 | ✗ | int idx = 1, last = 0, val, skip; | |
| 87 | |||
| 88 | ✗ | memset(blk, 0, sizeof(*blk) * 64); | |
| 89 | ✗ | blk[0] = get_vlc2(gb, dc_vlc, CLV_VLC_BITS, 3); | |
| 90 | |||
| 91 | ✗ | if (!has_ac) | |
| 92 | ✗ | return 0; | |
| 93 | |||
| 94 | ✗ | while (idx < 64 && !last) { | |
| 95 | ✗ | val = get_vlc2(gb, ac_vlc, CLV_VLC_BITS, 2); | |
| 96 | ✗ | if (val < 0) | |
| 97 | ✗ | return AVERROR_INVALIDDATA; | |
| 98 | ✗ | if (val != 0x1BFF) { | |
| 99 | ✗ | last = val >> 12; | |
| 100 | ✗ | skip = (val >> 4) & 0xFF; | |
| 101 | ✗ | val &= 0xF; | |
| 102 | ✗ | if (get_bits1(gb)) | |
| 103 | ✗ | val = -val; | |
| 104 | } else { | ||
| 105 | ✗ | last = get_bits1(gb); | |
| 106 | ✗ | skip = get_bits(gb, 6); | |
| 107 | ✗ | val = get_sbits(gb, 8); | |
| 108 | } | ||
| 109 | ✗ | if (val) { | |
| 110 | ✗ | int aval = FFABS(val), sign = val < 0; | |
| 111 | ✗ | val = ac_quant * (2 * aval + 1); | |
| 112 | ✗ | if (!(ac_quant & 1)) | |
| 113 | ✗ | val--; | |
| 114 | ✗ | if (sign) | |
| 115 | ✗ | val = -val; | |
| 116 | } | ||
| 117 | ✗ | idx += skip; | |
| 118 | ✗ | if (idx >= 64) | |
| 119 | ✗ | return AVERROR_INVALIDDATA; | |
| 120 | ✗ | blk[ff_zigzag_direct[idx++]] = val; | |
| 121 | } | ||
| 122 | |||
| 123 | ✗ | return (idx <= 64 && last) ? 0 : -1; | |
| 124 | } | ||
| 125 | |||
| 126 | #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \ | ||
| 127 | const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \ | ||
| 128 | const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \ | ||
| 129 | const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \ | ||
| 130 | const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \ | ||
| 131 | const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \ | ||
| 132 | const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \ | ||
| 133 | const int t6 = ((blk[0 * step] + blk[4 * step]) * (1 << dshift)) + bias; \ | ||
| 134 | const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \ | ||
| 135 | const int t8 = t0 + t2; \ | ||
| 136 | const int t9 = t0 - t2; \ | ||
| 137 | const int tA = (int)(181U * (t9 + (t1 - t3)) + 0x80) >> 8; \ | ||
| 138 | const int tB = (int)(181U * (t9 - (t1 - t3)) + 0x80) >> 8; \ | ||
| 139 | const int tC = t1 + t3; \ | ||
| 140 | \ | ||
| 141 | blk[0 * step] = (t6 + t5 + t8) >> shift; \ | ||
| 142 | blk[1 * step] = (t7 + t4 + tA) >> shift; \ | ||
| 143 | blk[2 * step] = (t7 - t4 + tB) >> shift; \ | ||
| 144 | blk[3 * step] = (t6 - t5 + tC) >> shift; \ | ||
| 145 | blk[4 * step] = (t6 - t5 - tC) >> shift; \ | ||
| 146 | blk[5 * step] = (t7 - t4 - tB) >> shift; \ | ||
| 147 | blk[6 * step] = (t7 + t4 - tA) >> shift; \ | ||
| 148 | blk[7 * step] = (t6 + t5 - t8) >> shift; \ | ||
| 149 | |||
| 150 | #define ROP(x) x | ||
| 151 | #define COP(x) (((x) + 4) >> 3) | ||
| 152 | |||
| 153 | ✗ | static void clv_dct(int16_t *block) | |
| 154 | { | ||
| 155 | int i; | ||
| 156 | int16_t *ptr; | ||
| 157 | |||
| 158 | ✗ | ptr = block; | |
| 159 | ✗ | for (i = 0; i < 8; i++) { | |
| 160 | ✗ | DCT_TEMPLATE(ptr, 1, 0x80, 8, 11, ROP); | |
| 161 | ✗ | ptr += 8; | |
| 162 | } | ||
| 163 | |||
| 164 | ✗ | ptr = block; | |
| 165 | ✗ | for (i = 0; i < 8; i++) { | |
| 166 | ✗ | DCT_TEMPLATE(ptr, 8, 0x2000, 14, 8, COP); | |
| 167 | ✗ | ptr++; | |
| 168 | } | ||
| 169 | ✗ | } | |
| 170 | |||
| 171 | ✗ | static int decode_mb(CLVContext *c, int x, int y) | |
| 172 | { | ||
| 173 | int i, has_ac[6], off; | ||
| 174 | |||
| 175 | ✗ | for (i = 0; i < 6; i++) | |
| 176 | ✗ | has_ac[i] = get_bits1(&c->gb); | |
| 177 | |||
| 178 | ✗ | off = x * 16 + y * 16 * c->pic->linesize[0]; | |
| 179 | ✗ | for (i = 0; i < 4; i++) { | |
| 180 | ✗ | if (decode_block(c, c->block, has_ac[i], c->ac_quant) < 0) | |
| 181 | ✗ | return AVERROR_INVALIDDATA; | |
| 182 | ✗ | if (!x && !(i & 1)) { | |
| 183 | ✗ | c->block[0] += c->top_dc[0]; | |
| 184 | ✗ | c->top_dc[0] = c->block[0]; | |
| 185 | } else { | ||
| 186 | ✗ | c->block[0] += c->left_dc[(i & 2) >> 1]; | |
| 187 | } | ||
| 188 | ✗ | c->left_dc[(i & 2) >> 1] = c->block[0]; | |
| 189 | ✗ | c->block[0] *= c->luma_dc_quant; | |
| 190 | ✗ | clv_dct(c->block); | |
| 191 | ✗ | if (i == 2) | |
| 192 | ✗ | off += c->pic->linesize[0] * 8; | |
| 193 | ✗ | c->idsp.put_pixels_clamped(c->block, | |
| 194 | ✗ | c->pic->data[0] + off + (i & 1) * 8, | |
| 195 | ✗ | c->pic->linesize[0]); | |
| 196 | } | ||
| 197 | |||
| 198 | ✗ | off = x * 8 + y * 8 * c->pic->linesize[1]; | |
| 199 | ✗ | for (i = 1; i < 3; i++) { | |
| 200 | ✗ | if (decode_block(c, c->block, has_ac[i + 3], c->ac_quant) < 0) | |
| 201 | ✗ | return AVERROR_INVALIDDATA; | |
| 202 | ✗ | if (!x) { | |
| 203 | ✗ | c->block[0] += c->top_dc[i]; | |
| 204 | ✗ | c->top_dc[i] = c->block[0]; | |
| 205 | } else { | ||
| 206 | ✗ | c->block[0] += c->left_dc[i + 1]; | |
| 207 | } | ||
| 208 | ✗ | c->left_dc[i + 1] = c->block[0]; | |
| 209 | ✗ | c->block[0] *= c->chroma_dc_quant; | |
| 210 | ✗ | clv_dct(c->block); | |
| 211 | ✗ | c->idsp.put_pixels_clamped(c->block, c->pic->data[i] + off, | |
| 212 | ✗ | c->pic->linesize[i]); | |
| 213 | } | ||
| 214 | |||
| 215 | ✗ | return 0; | |
| 216 | } | ||
| 217 | |||
| 218 | ✗ | static int copy_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src, | |
| 219 | int plane, int x, int y, int dx, int dy, int size) | ||
| 220 | { | ||
| 221 | ✗ | int shift = plane > 0; | |
| 222 | ✗ | int sx = x + dx; | |
| 223 | ✗ | int sy = y + dy; | |
| 224 | int sstride, dstride, soff, doff; | ||
| 225 | uint8_t *dbuf; | ||
| 226 | const uint8_t *sbuf; | ||
| 227 | int i; | ||
| 228 | |||
| 229 | ✗ | if (x < 0 || sx < 0 || y < 0 || sy < 0 || | |
| 230 | ✗ | x + size > avctx->coded_width >> shift || | |
| 231 | ✗ | y + size > avctx->coded_height >> shift || | |
| 232 | ✗ | sx + size > avctx->coded_width >> shift || | |
| 233 | ✗ | sy + size > avctx->coded_height >> shift) | |
| 234 | ✗ | return AVERROR_INVALIDDATA; | |
| 235 | |||
| 236 | ✗ | sstride = src->linesize[plane]; | |
| 237 | ✗ | dstride = dst->linesize[plane]; | |
| 238 | ✗ | soff = sx + sy * sstride; | |
| 239 | ✗ | sbuf = src->data[plane]; | |
| 240 | ✗ | doff = x + y * dstride; | |
| 241 | ✗ | dbuf = dst->data[plane]; | |
| 242 | |||
| 243 | ✗ | for (i = 0; i < size; i++) { | |
| 244 | ✗ | uint8_t *dptr = &dbuf[doff]; | |
| 245 | ✗ | const uint8_t *sptr = &sbuf[soff]; | |
| 246 | |||
| 247 | ✗ | memcpy(dptr, sptr, size); | |
| 248 | ✗ | doff += dstride; | |
| 249 | ✗ | soff += sstride; | |
| 250 | } | ||
| 251 | |||
| 252 | ✗ | return 0; | |
| 253 | } | ||
| 254 | |||
| 255 | ✗ | static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src, | |
| 256 | int plane, int x, int y, int dx, int dy, int size, int bias) | ||
| 257 | { | ||
| 258 | ✗ | int shift = plane > 0; | |
| 259 | ✗ | int sx = x + dx; | |
| 260 | ✗ | int sy = y + dy; | |
| 261 | ✗ | int sstride = src->linesize[plane]; | |
| 262 | ✗ | int dstride = dst->linesize[plane]; | |
| 263 | ✗ | int soff = sx + sy * sstride; | |
| 264 | ✗ | const uint8_t *sbuf = src->data[plane]; | |
| 265 | ✗ | int doff = x + y * dstride; | |
| 266 | ✗ | uint8_t *dbuf = dst->data[plane]; | |
| 267 | int i, j; | ||
| 268 | |||
| 269 | ✗ | if (x < 0 || sx < 0 || y < 0 || sy < 0 || | |
| 270 | ✗ | x + size > avctx->coded_width >> shift || | |
| 271 | ✗ | y + size > avctx->coded_height >> shift || | |
| 272 | ✗ | sx + size > avctx->coded_width >> shift || | |
| 273 | ✗ | sy + size > avctx->coded_height >> shift) | |
| 274 | ✗ | return AVERROR_INVALIDDATA; | |
| 275 | |||
| 276 | ✗ | for (j = 0; j < size; j++) { | |
| 277 | ✗ | uint8_t *dptr = &dbuf[doff]; | |
| 278 | ✗ | const uint8_t *sptr = &sbuf[soff]; | |
| 279 | |||
| 280 | ✗ | for (i = 0; i < size; i++) { | |
| 281 | ✗ | int val = sptr[i] + bias; | |
| 282 | |||
| 283 | ✗ | dptr[i] = av_clip_uint8(val); | |
| 284 | } | ||
| 285 | |||
| 286 | ✗ | doff += dstride; | |
| 287 | ✗ | soff += sstride; | |
| 288 | } | ||
| 289 | |||
| 290 | ✗ | return 0; | |
| 291 | } | ||
| 292 | |||
| 293 | ✗ | static MV *mvi_predict(MVInfo *mvi, int mb_x, int mb_y) | |
| 294 | { | ||
| 295 | MV res, pred_mv; | ||
| 296 | int left_mv, right_mv, top_mv, bot_mv; | ||
| 297 | |||
| 298 | ✗ | if (mvi->top) { | |
| 299 | ✗ | if (mb_x > 0) { | |
| 300 | ✗ | pred_mv = mvi->mv[mvi->mb_stride + mb_x - 1]; | |
| 301 | } else { | ||
| 302 | ✗ | pred_mv = zero_mv; | |
| 303 | } | ||
| 304 | ✗ | } else if ((mb_x == 0) || (mb_x == mvi->mb_w - 1)) { | |
| 305 | ✗ | pred_mv = mvi->mv[mb_x]; | |
| 306 | } else { | ||
| 307 | ✗ | MV A = mvi->mv[mvi->mb_stride + mb_x - 1]; | |
| 308 | ✗ | MV B = mvi->mv[ mb_x ]; | |
| 309 | ✗ | MV C = mvi->mv[ mb_x + 1]; | |
| 310 | ✗ | pred_mv.x = mid_pred(A.x, B.x, C.x); | |
| 311 | ✗ | pred_mv.y = mid_pred(A.y, B.y, C.y); | |
| 312 | } | ||
| 313 | |||
| 314 | ✗ | res = pred_mv; | |
| 315 | |||
| 316 | ✗ | left_mv = -((mb_x * mvi->mb_size)); | |
| 317 | ✗ | right_mv = ((mvi->mb_w - mb_x - 1) * mvi->mb_size); | |
| 318 | ✗ | if (res.x < left_mv) { | |
| 319 | ✗ | res.x = left_mv; | |
| 320 | } | ||
| 321 | ✗ | if (res.x > right_mv) { | |
| 322 | ✗ | res.x = right_mv; | |
| 323 | } | ||
| 324 | ✗ | top_mv = -((mb_y * mvi->mb_size)); | |
| 325 | ✗ | bot_mv = ((mvi->mb_h - mb_y - 1) * mvi->mb_size); | |
| 326 | ✗ | if (res.y < top_mv) { | |
| 327 | ✗ | res.y = top_mv; | |
| 328 | } | ||
| 329 | ✗ | if (res.y > bot_mv) { | |
| 330 | ✗ | res.y = bot_mv; | |
| 331 | } | ||
| 332 | |||
| 333 | ✗ | mvi->mv[mvi->mb_stride + mb_x].x = res.x; | |
| 334 | ✗ | mvi->mv[mvi->mb_stride + mb_x].y = res.y; | |
| 335 | |||
| 336 | ✗ | return &mvi->mv[mvi->mb_stride + mb_x]; | |
| 337 | } | ||
| 338 | |||
| 339 | ✗ | static void mvi_update_prediction(MV *mv, MV diff) | |
| 340 | { | ||
| 341 | ✗ | mv->x += diff.x; | |
| 342 | ✗ | mv->y += diff.y; | |
| 343 | ✗ | } | |
| 344 | |||
| 345 | ✗ | static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size) | |
| 346 | { | ||
| 347 | ✗ | mvi->top = 1; | |
| 348 | ✗ | mvi->mb_w = mb_w; | |
| 349 | ✗ | mvi->mb_h = mb_h; | |
| 350 | ✗ | mvi->mb_size = mb_size; | |
| 351 | ✗ | mvi->mb_stride = mb_w; | |
| 352 | ✗ | memset(mvi->mv, 0, sizeof(MV) * mvi->mb_stride * 2); | |
| 353 | ✗ | } | |
| 354 | |||
| 355 | ✗ | static void mvi_update_row(MVInfo *mvi) | |
| 356 | { | ||
| 357 | int i; | ||
| 358 | |||
| 359 | ✗ | mvi->top = 0; | |
| 360 | ✗ | for (i = 0 ; i < mvi->mb_stride; i++) { | |
| 361 | ✗ | mvi->mv[i] = mvi->mv[mvi->mb_stride + i]; | |
| 362 | } | ||
| 363 | ✗ | } | |
| 364 | |||
| 365 | ✗ | static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src, | |
| 366 | int plane, int x, int y, int dx, int dy, int size, int bias) | ||
| 367 | { | ||
| 368 | int ret; | ||
| 369 | |||
| 370 | ✗ | if (!bias) { | |
| 371 | ✗ | ret = copy_block(avctx, dst, src, plane, x, y, dx, dy, size); | |
| 372 | } else { | ||
| 373 | ✗ | ret = copyadd_block(avctx, dst, src, plane, x, y, dx, dy, size, bias); | |
| 374 | } | ||
| 375 | |||
| 376 | ✗ | return ret; | |
| 377 | } | ||
| 378 | |||
| 379 | ✗ | static int decode_tile(AVCodecContext *avctx, GetBitContext *gb, | |
| 380 | const LevelCodes *lc, | ||
| 381 | AVFrame *dst, const AVFrame *src, | ||
| 382 | int plane, int x, int y, int size, | ||
| 383 | MV root_mv, MV *pred) | ||
| 384 | { | ||
| 385 | ✗ | int i, flags = 0; | |
| 386 | ✗ | int16_t bias = 0; | |
| 387 | ✗ | MV mv = { 0 }; | |
| 388 | int err; | ||
| 389 | |||
| 390 | ✗ | if (lc->flags_cb) | |
| 391 | ✗ | flags = get_vlc2(gb, lc->flags_cb, CLV_VLC_BITS, 2); | |
| 392 | |||
| 393 | ✗ | if (lc->mv_cb) { | |
| 394 | ✗ | uint16_t mv_code = get_vlc2(gb, lc->mv_cb, CLV_VLC_BITS, 2); | |
| 395 | |||
| 396 | ✗ | if (mv_code != MV_ESC) { | |
| 397 | ✗ | mv.x = (int8_t)(mv_code & 0xff); | |
| 398 | ✗ | mv.y = (int8_t)(mv_code >> 8); | |
| 399 | } else { | ||
| 400 | ✗ | mv.x = get_sbits(gb, 8); | |
| 401 | ✗ | mv.y = get_sbits(gb, 8); | |
| 402 | } | ||
| 403 | ✗ | if (pred) | |
| 404 | ✗ | mvi_update_prediction(pred, mv); | |
| 405 | } | ||
| 406 | ✗ | mv.x += root_mv.x; | |
| 407 | ✗ | mv.y += root_mv.y; | |
| 408 | |||
| 409 | ✗ | if (lc->bias_cb) { | |
| 410 | ✗ | uint16_t bias_val = get_vlc2(gb, lc->bias_cb, CLV_VLC_BITS, 2); | |
| 411 | |||
| 412 | ✗ | if (bias_val != BIAS_ESC) { | |
| 413 | ✗ | bias = (int16_t)(bias_val); | |
| 414 | } else { | ||
| 415 | ✗ | bias = get_sbits(gb, 16); | |
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | ✗ | if (flags) { | |
| 420 | ✗ | int hsize = size >> 1; | |
| 421 | ✗ | for (i = 0; i < 4; i++) { | |
| 422 | ✗ | int xoff = (i & 2) == 0 ? 0 : hsize; | |
| 423 | ✗ | int yoff = (i & 1) == 0 ? 0 : hsize; | |
| 424 | |||
| 425 | ✗ | if (flags & (1 << i)) { | |
| 426 | ✗ | err = decode_tile(avctx, gb, lc + 1, dst, src, plane, | |
| 427 | x + xoff, y + yoff, hsize, root_mv, NULL); | ||
| 428 | } else { | ||
| 429 | ✗ | err = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff, | |
| 430 | ✗ | mv.x, mv.y, hsize, bias); | |
| 431 | } | ||
| 432 | ✗ | if (err < 0) | |
| 433 | ✗ | return err; | |
| 434 | } | ||
| 435 | } else { | ||
| 436 | ✗ | err = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, bias); | |
| 437 | ✗ | if (err < 0) | |
| 438 | ✗ | return err; | |
| 439 | } | ||
| 440 | |||
| 441 | ✗ | return 0; | |
| 442 | } | ||
| 443 | |||
| 444 | ✗ | static void extend_edges(AVFrame *buf, int tile_size) | |
| 445 | { | ||
| 446 | int comp, i, j; | ||
| 447 | |||
| 448 | ✗ | for (comp = 0; comp < 3; comp++) { | |
| 449 | ✗ | int shift = comp > 0; | |
| 450 | ✗ | int w = buf->width >> shift; | |
| 451 | ✗ | int h = buf->height >> shift; | |
| 452 | ✗ | int size = comp == 0 ? tile_size : tile_size >> 1; | |
| 453 | ✗ | int stride = buf->linesize[comp]; | |
| 454 | ✗ | uint8_t *framebuf = buf->data[comp]; | |
| 455 | |||
| 456 | ✗ | int right = size - (w & (size - 1)); | |
| 457 | ✗ | int bottom = size - (h & (size - 1)); | |
| 458 | |||
| 459 | ✗ | if ((right == size) && (bottom == size)) { | |
| 460 | ✗ | return; | |
| 461 | } | ||
| 462 | ✗ | if (right != size) { | |
| 463 | ✗ | int off = w; | |
| 464 | ✗ | for (j = 0; j < h; j++) { | |
| 465 | ✗ | for (i = 0; i < right; i++) { | |
| 466 | ✗ | framebuf[off + i] = 0x80; | |
| 467 | } | ||
| 468 | ✗ | off += stride; | |
| 469 | } | ||
| 470 | } | ||
| 471 | ✗ | if (bottom != size) { | |
| 472 | ✗ | int off = h * stride; | |
| 473 | ✗ | for (j = 0; j < bottom; j++) { | |
| 474 | ✗ | for (i = 0; i < stride; i++) { | |
| 475 | ✗ | framebuf[off + i] = 0x80; | |
| 476 | } | ||
| 477 | ✗ | off += stride; | |
| 478 | } | ||
| 479 | } | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | ✗ | static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe, | |
| 484 | int *got_frame, AVPacket *avpkt) | ||
| 485 | { | ||
| 486 | ✗ | const uint8_t *buf = avpkt->data; | |
| 487 | ✗ | int buf_size = avpkt->size; | |
| 488 | ✗ | CLVContext *c = avctx->priv_data; | |
| 489 | GetByteContext gb; | ||
| 490 | uint32_t frame_type; | ||
| 491 | int i, j, ret; | ||
| 492 | ✗ | int mb_ret = 0; | |
| 493 | |||
| 494 | ✗ | bytestream2_init(&gb, buf, buf_size); | |
| 495 | ✗ | if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) { | |
| 496 | ✗ | int skip = bytestream2_get_byte(&gb); | |
| 497 | ✗ | bytestream2_skip(&gb, (skip + 1) * 8); | |
| 498 | } | ||
| 499 | |||
| 500 | ✗ | frame_type = bytestream2_get_byte(&gb); | |
| 501 | |||
| 502 | ✗ | if ((frame_type & 0x7f) == 0x30) { | |
| 503 | ✗ | *got_frame = 0; | |
| 504 | ✗ | return buf_size; | |
| 505 | ✗ | } else if (frame_type & 0x2) { | |
| 506 | ✗ | if (buf_size < c->mb_width * c->mb_height) { | |
| 507 | ✗ | av_log(avctx, AV_LOG_ERROR, "Packet too small\n"); | |
| 508 | ✗ | return AVERROR_INVALIDDATA; | |
| 509 | } | ||
| 510 | |||
| 511 | ✗ | if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0) | |
| 512 | ✗ | return ret; | |
| 513 | |||
| 514 | ✗ | c->pic->flags |= AV_FRAME_FLAG_KEY; | |
| 515 | ✗ | c->pic->pict_type = AV_PICTURE_TYPE_I; | |
| 516 | |||
| 517 | ✗ | bytestream2_get_be32(&gb); // frame size; | |
| 518 | ✗ | c->ac_quant = bytestream2_get_byte(&gb); | |
| 519 | ✗ | c->luma_dc_quant = 32; | |
| 520 | ✗ | c->chroma_dc_quant = 32; | |
| 521 | |||
| 522 | ✗ | if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb), | |
| 523 | ✗ | buf_size - bytestream2_tell(&gb))) < 0) | |
| 524 | ✗ | return ret; | |
| 525 | |||
| 526 | ✗ | for (i = 0; i < 3; i++) | |
| 527 | ✗ | c->top_dc[i] = 32; | |
| 528 | ✗ | for (i = 0; i < 4; i++) | |
| 529 | ✗ | c->left_dc[i] = 32; | |
| 530 | |||
| 531 | ✗ | for (j = 0; j < c->mb_height; j++) { | |
| 532 | ✗ | for (i = 0; i < c->mb_width; i++) { | |
| 533 | ✗ | ret = decode_mb(c, i, j); | |
| 534 | ✗ | if (ret < 0) | |
| 535 | ✗ | mb_ret = ret; | |
| 536 | } | ||
| 537 | } | ||
| 538 | ✗ | extend_edges(c->pic, c->tile_size); | |
| 539 | } else { | ||
| 540 | int plane; | ||
| 541 | |||
| 542 | ✗ | if (c->pmb_width * c->pmb_height > 8LL*(buf_size - bytestream2_tell(&gb))) | |
| 543 | ✗ | return AVERROR_INVALIDDATA; | |
| 544 | |||
| 545 | ✗ | if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0) | |
| 546 | ✗ | return ret; | |
| 547 | |||
| 548 | ✗ | ret = av_frame_copy(c->pic, c->prev); | |
| 549 | ✗ | if (ret < 0) | |
| 550 | ✗ | return ret; | |
| 551 | |||
| 552 | ✗ | if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb), | |
| 553 | ✗ | buf_size - bytestream2_tell(&gb))) < 0) | |
| 554 | ✗ | return ret; | |
| 555 | |||
| 556 | ✗ | mvi_reset(&c->mvi, c->pmb_width, c->pmb_height, 1 << c->tile_shift); | |
| 557 | |||
| 558 | ✗ | for (j = 0; j < c->pmb_height; j++) { | |
| 559 | ✗ | for (i = 0; i < c->pmb_width; i++) { | |
| 560 | MV *mvp, mv; | ||
| 561 | ✗ | if (get_bits_left(&c->gb) <= 0) | |
| 562 | ✗ | return AVERROR_INVALIDDATA; | |
| 563 | |||
| 564 | ✗ | mvp = mvi_predict(&c->mvi, i, j); | |
| 565 | ✗ | mv = *mvp; | |
| 566 | ✗ | if (get_bits1(&c->gb)) { | |
| 567 | ✗ | for (plane = 0; plane < 3; plane++) { | |
| 568 | ✗ | int16_t x = plane == 0 ? i << c->tile_shift : i << (c->tile_shift - 1); | |
| 569 | ✗ | int16_t y = plane == 0 ? j << c->tile_shift : j << (c->tile_shift - 1); | |
| 570 | ✗ | int16_t size = plane == 0 ? 1 << c->tile_shift : 1 << (c->tile_shift - 1); | |
| 571 | ✗ | int16_t mx = plane == 0 ? mv.x : mv.x / 2; | |
| 572 | ✗ | int16_t my = plane == 0 ? mv.y : mv.y / 2; | |
| 573 | |||
| 574 | ✗ | ret = copy_block(avctx, c->pic, c->prev, plane, x, y, mx, my, size); | |
| 575 | ✗ | if (ret < 0) | |
| 576 | ✗ | mb_ret = ret; | |
| 577 | } | ||
| 578 | } else { | ||
| 579 | ✗ | int x = i << c->tile_shift; | |
| 580 | ✗ | int y = j << c->tile_shift; | |
| 581 | ✗ | int size = 1 << c->tile_shift; | |
| 582 | MV cmv; | ||
| 583 | |||
| 584 | ✗ | ret = decode_tile(avctx, &c->gb, &lev[0], c->pic, c->prev, // Y | |
| 585 | 0, x, y, size, mv, mvp); | ||
| 586 | ✗ | if (ret < 0) | |
| 587 | ✗ | mb_ret = ret; | |
| 588 | ✗ | x = i << (c->tile_shift - 1); | |
| 589 | ✗ | y = j << (c->tile_shift - 1); | |
| 590 | ✗ | size = 1 << (c->tile_shift - 1); | |
| 591 | ✗ | cmv = *mvp; | |
| 592 | ✗ | cmv.x /= 2; | |
| 593 | ✗ | cmv.y /= 2; | |
| 594 | ✗ | ret = decode_tile(avctx, &c->gb, &lev[4], c->pic, c->prev, // U | |
| 595 | 1, x, y, size, cmv, NULL); | ||
| 596 | ✗ | if (ret < 0) | |
| 597 | ✗ | mb_ret = ret; | |
| 598 | ✗ | ret = decode_tile(avctx, &c->gb, &lev[7], c->pic, c->prev, // U | |
| 599 | 2, x, y, size, cmv, NULL); | ||
| 600 | ✗ | if (ret < 0) | |
| 601 | ✗ | mb_ret = ret; | |
| 602 | } | ||
| 603 | } | ||
| 604 | ✗ | mvi_update_row(&c->mvi); | |
| 605 | } | ||
| 606 | ✗ | extend_edges(c->pic, c->tile_size); | |
| 607 | |||
| 608 | ✗ | c->pic->flags &= ~AV_FRAME_FLAG_KEY; | |
| 609 | ✗ | c->pic->pict_type = AV_PICTURE_TYPE_P; | |
| 610 | } | ||
| 611 | |||
| 612 | ✗ | if ((ret = av_frame_ref(rframe, c->pic)) < 0) | |
| 613 | ✗ | return ret; | |
| 614 | |||
| 615 | ✗ | FFSWAP(AVFrame *, c->pic, c->prev); | |
| 616 | |||
| 617 | ✗ | *got_frame = 1; | |
| 618 | |||
| 619 | ✗ | if (get_bits_left(&c->gb) < 0) | |
| 620 | ✗ | av_log(c->avctx, AV_LOG_WARNING, "overread %d\n", -get_bits_left(&c->gb)); | |
| 621 | |||
| 622 | ✗ | return mb_ret < 0 ? mb_ret : buf_size; | |
| 623 | } | ||
| 624 | |||
| 625 | ✗ | static av_cold const VLCElem *build_vlc(VLCInitState *state, | |
| 626 | const uint8_t counts[16], | ||
| 627 | const uint16_t **syms) | ||
| 628 | { | ||
| 629 | uint8_t lens[MAX_VLC_ENTRIES]; | ||
| 630 | ✗ | const uint16_t *symbols = *syms; | |
| 631 | ✗ | unsigned num = 0; | |
| 632 | |||
| 633 | ✗ | for (int i = 0; i < 16; i++) { | |
| 634 | ✗ | unsigned count = counts[i]; | |
| 635 | ✗ | if (count == 255) /* Special case for Y_3 table */ | |
| 636 | ✗ | count = 303; | |
| 637 | ✗ | for (count += num; num < count; num++) | |
| 638 | ✗ | lens[num] = i + 1; | |
| 639 | } | ||
| 640 | ✗ | *syms += num; | |
| 641 | ✗ | return ff_vlc_init_tables_from_lengths(state, CLV_VLC_BITS, num, lens, 1, | |
| 642 | symbols, 2, 2, 0, 0); | ||
| 643 | } | ||
| 644 | |||
| 645 | ✗ | static av_cold void clv_init_static(void) | |
| 646 | { | ||
| 647 | static VLCElem vlc_buf[16716]; | ||
| 648 | ✗ | VLCInitState state = VLC_INIT_STATE(vlc_buf); | |
| 649 | ✗ | const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms; | |
| 650 | |||
| 651 | ✗ | VLC_INIT_STATIC_TABLE_FROM_LENGTHS(dc_vlc, CLV_VLC_BITS, NUM_DC_CODES, | |
| 652 | clv_dc_lens, 1, | ||
| 653 | clv_dc_syms, 1, 1, -63, 0); | ||
| 654 | ✗ | VLC_INIT_STATIC_TABLE_FROM_LENGTHS(ac_vlc, CLV_VLC_BITS, NUM_AC_CODES, | |
| 655 | clv_ac_bits, 1, | ||
| 656 | clv_ac_syms, 2, 2, 0, 0); | ||
| 657 | ✗ | for (unsigned i = 0, j = 0, k = 0;; i++) { | |
| 658 | ✗ | if (0x36F & (1 << i)) { | |
| 659 | ✗ | lev[i].mv_cb = build_vlc(&state, clv_mv_len_counts[k], &mv_syms); | |
| 660 | ✗ | k++; | |
| 661 | } | ||
| 662 | ✗ | if (i == FF_ARRAY_ELEMS(lev) - 1) | |
| 663 | ✗ | break; | |
| 664 | ✗ | if (0x1B7 & (1 << i)) { | |
| 665 | ✗ | lev[i].flags_cb = | |
| 666 | ✗ | ff_vlc_init_tables_from_lengths(&state, CLV_VLC_BITS, 16, | |
| 667 | ✗ | clv_flags_bits[j], 1, | |
| 668 | ✗ | clv_flags_syms[j], 1, 1, | |
| 669 | 0, 0); | ||
| 670 | |||
| 671 | ✗ | lev[i + 1].bias_cb = build_vlc(&state, clv_bias_len_counts[j], | |
| 672 | &bias_syms); | ||
| 673 | ✗ | j++; | |
| 674 | } | ||
| 675 | } | ||
| 676 | ✗ | } | |
| 677 | |||
| 678 | ✗ | static av_cold int clv_decode_init(AVCodecContext *avctx) | |
| 679 | { | ||
| 680 | static AVOnce init_static_once = AV_ONCE_INIT; | ||
| 681 | ✗ | CLVContext *const c = avctx->priv_data; | |
| 682 | int ret, w, h; | ||
| 683 | |||
| 684 | ✗ | if (avctx->extradata_size == 110) { | |
| 685 | ✗ | c->tile_size = AV_RL32(&avctx->extradata[94]); | |
| 686 | ✗ | } else if (avctx->extradata_size == 150) { | |
| 687 | ✗ | c->tile_size = AV_RB32(&avctx->extradata[134]); | |
| 688 | ✗ | } else if (!avctx->extradata_size) { | |
| 689 | ✗ | c->tile_size = 16; | |
| 690 | } else { | ||
| 691 | ✗ | av_log(avctx, AV_LOG_ERROR, "Unsupported extradata size: %d\n", avctx->extradata_size); | |
| 692 | ✗ | return AVERROR_INVALIDDATA; | |
| 693 | } | ||
| 694 | |||
| 695 | ✗ | c->tile_shift = av_log2(c->tile_size); | |
| 696 | ✗ | if (1U << c->tile_shift != c->tile_size || c->tile_shift < 1 || c->tile_shift > 30) { | |
| 697 | ✗ | av_log(avctx, AV_LOG_ERROR, "Tile size: %d, is not power of 2 > 1 and < 2^31\n", c->tile_size); | |
| 698 | ✗ | return AVERROR_INVALIDDATA; | |
| 699 | } | ||
| 700 | |||
| 701 | ✗ | avctx->pix_fmt = AV_PIX_FMT_YUV420P; | |
| 702 | ✗ | w = avctx->width; | |
| 703 | ✗ | h = avctx->height; | |
| 704 | ✗ | ret = ff_set_dimensions(avctx, FFALIGN(w, 1 << c->tile_shift), FFALIGN(h, 1 << c->tile_shift)); | |
| 705 | ✗ | if (ret < 0) | |
| 706 | ✗ | return ret; | |
| 707 | ✗ | avctx->width = w; | |
| 708 | ✗ | avctx->height = h; | |
| 709 | |||
| 710 | ✗ | c->avctx = avctx; | |
| 711 | ✗ | c->mb_width = FFALIGN(avctx->width, 16) >> 4; | |
| 712 | ✗ | c->mb_height = FFALIGN(avctx->height, 16) >> 4; | |
| 713 | ✗ | c->pmb_width = (w + c->tile_size - 1) >> c->tile_shift; | |
| 714 | ✗ | c->pmb_height = (h + c->tile_size - 1) >> c->tile_shift; | |
| 715 | ✗ | c->pic = av_frame_alloc(); | |
| 716 | ✗ | c->prev = av_frame_alloc(); | |
| 717 | ✗ | c->mvi.mv = av_calloc(c->pmb_width * 2, sizeof(*c->mvi.mv)); | |
| 718 | ✗ | if (!c->pic || !c->prev || !c->mvi.mv) | |
| 719 | ✗ | return AVERROR(ENOMEM); | |
| 720 | |||
| 721 | ✗ | ff_idctdsp_init(&c->idsp, avctx); | |
| 722 | |||
| 723 | ✗ | ff_thread_once(&init_static_once, clv_init_static); | |
| 724 | |||
| 725 | ✗ | return 0; | |
| 726 | } | ||
| 727 | |||
| 728 | ✗ | static av_cold int clv_decode_end(AVCodecContext *avctx) | |
| 729 | { | ||
| 730 | ✗ | CLVContext *const c = avctx->priv_data; | |
| 731 | |||
| 732 | ✗ | av_frame_free(&c->prev); | |
| 733 | ✗ | av_frame_free(&c->pic); | |
| 734 | |||
| 735 | ✗ | av_freep(&c->mvi.mv); | |
| 736 | |||
| 737 | ✗ | return 0; | |
| 738 | } | ||
| 739 | |||
| 740 | const FFCodec ff_clearvideo_decoder = { | ||
| 741 | .p.name = "clearvideo", | ||
| 742 | CODEC_LONG_NAME("Iterated Systems ClearVideo"), | ||
| 743 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 744 | .p.id = AV_CODEC_ID_CLEARVIDEO, | ||
| 745 | .priv_data_size = sizeof(CLVContext), | ||
| 746 | .init = clv_decode_init, | ||
| 747 | .close = clv_decode_end, | ||
| 748 | FF_CODEC_DECODE_CB(clv_decode_frame), | ||
| 749 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
| 750 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | ||
| 751 | }; | ||
| 752 |