| @@ -0,0 +1,653 @@ |
| | 1 | /* |
| | 2 | * Amuse Graphics Movie decoder |
| | 3 | * |
| | 4 | * Copyright (c) 2018 Paul B Mahol |
| | 5 | * |
| | 6 | * This file is part of FFmpeg. |
| | 7 | * |
| | 8 | * FFmpeg is free software; you can redistribute it and/or |
| | 9 | * modify it under the terms of the GNU Lesser General Public |
| | 10 | * License as published by the Free Software Foundation; either |
| | 11 | * version 2.1 of the License, or (at your option) any later version. |
| | 12 | * |
| | 13 | * FFmpeg is distributed in the hope that it will be useful, |
| | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| | 16 | * Lesser General Public License for more details. |
| | 17 | * |
| | 18 | * You should have received a copy of the GNU Lesser General Public |
| | 19 | * License along with FFmpeg; if not, write to the Free Software |
| | 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| | 21 | */ |
| | 22 | |
| | 23 | #include <stdio.h> |
| | 24 | #include <stdlib.h> |
| | 25 | #include <string.h> |
| | 26 | |
| | 27 | #define BITSTREAM_READER_LE |
| | 28 | |
| | 29 | #include "avcodec.h" |
| | 30 | #include "bytestream.h" |
| | 31 | #include "copy_block.h" |
| | 32 | #include "get_bits.h" |
| | 33 | #include "idctdsp.h" |
| | 34 | #include "internal.h" |
| | 35 | |
| | 36 | static const uint8_t unscaled_luma[64] = { |
| | 37 | 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, |
| | 38 | 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, |
| | 39 | 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, |
| | 40 | 68,109,103, 77, 24, 35, 55, 64, 81,104,113, 92, |
| | 41 | 49, 64, 78, 87,103,121,120,101, 72, 92, 95, 98, |
| | 42 | 112,100,103,99 |
| | 43 | }; |
| | 44 | |
| | 45 | static const uint8_t unscaled_chroma[64] = { |
| | 46 | 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, |
| | 47 | 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, |
| | 48 | 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, |
| | 49 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, |
| | 50 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, |
| | 51 | 99, 99, 99, 99 |
| | 52 | }; |
| | 53 | |
| | 54 | typedef struct MotionVector { |
| | 55 | int16_t x, y; |
| | 56 | } MotionVector; |
| | 57 | |
| | 58 | typedef struct AGMContext { |
| | 59 | const AVClass *class; |
| | 60 | AVCodecContext *avctx; |
| | 61 | GetBitContext gb; |
| | 62 | GetByteContext gbyte; |
| | 63 | |
| | 64 | int key_frame; |
| | 65 | int bitstream_size; |
| | 66 | int compression; |
| | 67 | int blocks_w; |
| | 68 | int blocks_h; |
| | 69 | int size[3]; |
| | 70 | int plus; |
| | 71 | unsigned flags; |
| | 72 | unsigned fflags; |
| | 73 | |
| | 74 | MotionVector *mvectors; |
| | 75 | int mvectors_size; |
| | 76 | |
| | 77 | AVFrame *prev_frame; |
| | 78 | |
| | 79 | int luma_quant_matrix[64]; |
| | 80 | int chroma_quant_matrix[64]; |
| | 81 | |
| | 82 | ScanTable scantable; |
| | 83 | DECLARE_ALIGNED(32, int16_t, block)[64]; |
| | 84 | IDCTDSPContext idsp; |
| | 85 | } AGMContext; |
| | 86 | |
| | 87 | static int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mode) |
| | 88 | { |
| | 89 | int len = 0, skip = 0, max; |
| | 90 | |
| | 91 | if (show_bits(gb, 2)) { |
| | 92 | switch (show_bits(gb, 4)) { |
| | 93 | case 1: |
| | 94 | case 9: |
| | 95 | len = 1; |
| | 96 | skip = 3; |
| | 97 | break; |
| | 98 | case 2: |
| | 99 | len = 3; |
| | 100 | skip = 4; |
| | 101 | break; |
| | 102 | case 3: |
| | 103 | len = 7; |
| | 104 | skip = 4; |
| | 105 | break; |
| | 106 | case 5: |
| | 107 | case 13: |
| | 108 | len = 2; |
| | 109 | skip = 3; |
| | 110 | break; |
| | 111 | case 6: |
| | 112 | len = 4; |
| | 113 | skip = 4; |
| | 114 | break; |
| | 115 | case 7: |
| | 116 | len = 8; |
| | 117 | skip = 4; |
| | 118 | break; |
| | 119 | case 10: |
| | 120 | len = 5; |
| | 121 | skip = 4; |
| | 122 | break; |
| | 123 | case 11: |
| | 124 | len = 9; |
| | 125 | skip = 4; |
| | 126 | break; |
| | 127 | case 14: |
| | 128 | len = 6; |
| | 129 | skip = 4; |
| | 130 | break; |
| | 131 | case 15: |
| | 132 | len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4; |
| | 133 | skip = 5; |
| | 134 | break; |
| | 135 | default: |
| | 136 | return AVERROR_INVALIDDATA; |
| | 137 | } |
| | 138 | |
| | 139 | skip_bits(gb, skip); |
| | 140 | *level = get_bits(gb, len); |
| | 141 | *map = 1; |
| | 142 | *oskip = 0; |
| | 143 | max = 1 << (len - 1); |
| | 144 | if (*level < max) |
| | 145 | *level = -(max + *level); |
| | 146 | } else if (show_bits(gb, 3) & 4) { |
| | 147 | skip_bits(gb, 3); |
| | 148 | if (mode == 1) { |
| | 149 | if (show_bits(gb, 4)) { |
| | 150 | if (show_bits(gb, 4) == 1) { |
| | 151 | skip_bits(gb, 4); |
| | 152 | *oskip = get_bits(gb, 16); |
| | 153 | } else { |
| | 154 | *oskip = get_bits(gb, 4); |
| | 155 | } |
| | 156 | } else { |
| | 157 | skip_bits(gb, 4); |
| | 158 | *oskip = get_bits(gb, 10); |
| | 159 | } |
| | 160 | } else if (mode == 0) { |
| | 161 | *oskip = get_bits(gb, 10); |
| | 162 | } |
| | 163 | *level = 0; |
| | 164 | } else { |
| | 165 | skip_bits(gb, 3); |
| | 166 | if (mode == 0) |
| | 167 | *oskip = get_bits(gb, 4); |
| | 168 | else if (mode == 1) |
| | 169 | *oskip = 0; |
| | 170 | *level = 0; |
| | 171 | } |
| | 172 | |
| | 173 | return 0; |
| | 174 | } |
| | 175 | |
| | 176 | static int decode_intra_block(AGMContext *s, GetBitContext *gb, int size, |
| | 177 | const int *quant_matrix, int *skip, int *dc_level) |
| | 178 | { |
| | 179 | const uint8_t *scantable = s->scantable.permutated; |
| | 180 | const int offset = s->plus ? 0 : 1024; |
| | 181 | int16_t *block = s->block; |
| | 182 | int level, ret, map = 0; |
| | 183 | |
| | 184 | memset(block, 0, sizeof(s->block)); |
| | 185 | |
| | 186 | if (*skip > 0) { |
| | 187 | (*skip)--; |
| | 188 | } else { |
| | 189 | ret = read_code(gb, skip, &level, &map, s->flags & 1); |
| | 190 | if (ret < 0) |
| | 191 | return ret; |
| | 192 | *dc_level += level; |
| | 193 | } |
| | 194 | block[scantable[0]] = offset + *dc_level * quant_matrix[0]; |
| | 195 | |
| | 196 | for (int i = 1; i < 64;) { |
| | 197 | if (*skip > 0) { |
| | 198 | int rskip; |
| | 199 | |
| | 200 | rskip = FFMIN(*skip, 64 - i); |
| | 201 | i += rskip; |
| | 202 | *skip -= rskip; |
| | 203 | } else { |
| | 204 | ret = read_code(gb, skip, &level, &map, s->flags & 1); |
| | 205 | if (ret < 0) |
| | 206 | return ret; |
| | 207 | |
| | 208 | block[scantable[i]] = level * quant_matrix[i]; |
| | 209 | i++; |
| | 210 | } |
| | 211 | } |
| | 212 | |
| | 213 | return 0; |
| | 214 | } |
| | 215 | |
| | 216 | static int decode_intra_plane(AGMContext *s, GetBitContext *gb, int size, |
| | 217 | const int *quant_matrix, AVFrame *frame, |
| | 218 | int plane) |
| | 219 | { |
| | 220 | int ret, skip = 0, dc_level = 0; |
| | 221 | |
| | 222 | if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) |
| | 223 | return ret; |
| | 224 | |
| | 225 | for (int y = 0; y < s->blocks_h; y++) { |
| | 226 | for (int x = 0; x < s->blocks_w; x++) { |
| | 227 | ret = decode_intra_block(s, gb, size, quant_matrix, &skip, &dc_level); |
| | 228 | if (ret < 0) |
| | 229 | return ret; |
| | 230 | |
| | 231 | s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
| | 232 | frame->linesize[plane], s->block); |
| | 233 | } |
| | 234 | } |
| | 235 | |
| | 236 | align_get_bits(gb); |
| | 237 | if (get_bits_left(gb) < 0) |
| | 238 | av_log(s->avctx, AV_LOG_WARNING, "overread\n"); |
| | 239 | if (get_bits_left(gb) > 0) |
| | 240 | av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); |
| | 241 | |
| | 242 | return 0; |
| | 243 | } |
| | 244 | |
| | 245 | static int decode_inter_block(AGMContext *s, GetBitContext *gb, int size, |
| | 246 | const int *quant_matrix, int *skip, |
| | 247 | int *map) |
| | 248 | { |
| | 249 | const uint8_t *scantable = s->scantable.permutated; |
| | 250 | int16_t *block = s->block; |
| | 251 | int level, ret; |
| | 252 | |
| | 253 | memset(block, 0, sizeof(s->block)); |
| | 254 | |
| | 255 | for (int i = 0; i < 64;) { |
| | 256 | if (*skip > 0) { |
| | 257 | int rskip; |
| | 258 | |
| | 259 | rskip = FFMIN(*skip, 64 - i); |
| | 260 | i += rskip; |
| | 261 | *skip -= rskip; |
| | 262 | } else { |
| | 263 | ret = read_code(gb, skip, &level, map, s->flags & 1); |
| | 264 | if (ret < 0) |
| | 265 | return ret; |
| | 266 | |
| | 267 | block[scantable[i]] = level * quant_matrix[i]; |
| | 268 | i++; |
| | 269 | } |
| | 270 | } |
| | 271 | |
| | 272 | return 0; |
| | 273 | } |
| | 274 | |
| | 275 | static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, |
| | 276 | const int *quant_matrix, AVFrame *frame, |
| | 277 | AVFrame *prev, int plane) |
| | 278 | { |
| | 279 | int ret, skip = 0; |
| | 280 | |
| | 281 | if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) |
| | 282 | return ret; |
| | 283 | |
| | 284 | if (s->flags & 2) { |
| | 285 | for (int y = 0; y < s->blocks_h; y++) { |
| | 286 | for (int x = 0; x < s->blocks_w; x++) { |
| | 287 | int shift = plane == 0; |
| | 288 | int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); |
| | 289 | int orig_mv_x = s->mvectors[mvpos].x; |
| | 290 | int mv_x = s->mvectors[mvpos].x / (1 + !shift); |
| | 291 | int mv_y = s->mvectors[mvpos].y / (1 + !shift); |
| | 292 | int h = s->avctx->coded_height >> !shift; |
| | 293 | int w = s->avctx->coded_width >> !shift; |
| | 294 | int map = 0; |
| | 295 | |
| | 296 | ret = decode_inter_block(s, gb, size, quant_matrix, &skip, &map); |
| | 297 | if (ret < 0) |
| | 298 | return ret; |
| | 299 | |
| | 300 | if (orig_mv_x >= -32) { |
| | 301 | if (y * 8 + mv_y < 0 || y * 8 + mv_y >= h || |
| | 302 | x * 8 + mv_x < 0 || x * 8 + mv_x >= w) |
| | 303 | return AVERROR_INVALIDDATA; |
| | 304 | |
| | 305 | copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
| | 306 | prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), |
| | 307 | frame->linesize[plane], prev->linesize[plane], 8); |
| | 308 | if (map) { |
| | 309 | s->idsp.idct(s->block); |
| | 310 | for (int i = 0; i < 64; i++) |
| | 311 | s->block[i] = (s->block[i] + 1) & 0xFFFC; |
| | 312 | s->idsp.add_pixels_clamped(s->block, frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
| | 313 | frame->linesize[plane]); |
| | 314 | } |
| | 315 | } else if (map) { |
| | 316 | s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
| | 317 | frame->linesize[plane], s->block); |
| | 318 | } |
| | 319 | } |
| | 320 | } |
| | 321 | } else { |
| | 322 | for (int y = 0; y < s->blocks_h; y++) { |
| | 323 | for (int x = 0; x < s->blocks_w; x++) { |
| | 324 | int map = 0; |
| | 325 | |
| | 326 | ret = decode_inter_block(s, gb, size, quant_matrix, &skip, &map); |
| | 327 | if (ret < 0) |
| | 328 | return ret; |
| | 329 | |
| | 330 | if (!map) |
| | 331 | continue; |
| | 332 | s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
| | 333 | frame->linesize[plane], s->block); |
| | 334 | } |
| | 335 | } |
| | 336 | } |
| | 337 | |
| | 338 | align_get_bits(gb); |
| | 339 | if (get_bits_left(gb) < 0) |
| | 340 | av_log(s->avctx, AV_LOG_WARNING, "overread\n"); |
| | 341 | if (get_bits_left(gb) > 0) |
| | 342 | av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); |
| | 343 | |
| | 344 | return 0; |
| | 345 | } |
| | 346 | |
| | 347 | static void compute_quant_matrix(AGMContext *s, double qscale) |
| | 348 | { |
| | 349 | int luma[64], chroma[64]; |
| | 350 | double f = 1.0 - fabs(qscale); |
| | 351 | |
| | 352 | if (!s->key_frame && (s->flags & 2)) { |
| | 353 | if (qscale >= 0.0) { |
| | 354 | for (int i = 0; i < 64; i++) { |
| | 355 | luma[i] = FFMAX(1, 16 * f); |
| | 356 | chroma[i] = FFMAX(1, 16 * f); |
| | 357 | } |
| | 358 | } else { |
| | 359 | for (int i = 0; i < 64; i++) { |
| | 360 | luma[i] = FFMAX(1, 16 - qscale * 32); |
| | 361 | chroma[i] = FFMAX(1, 16 - qscale * 32); |
| | 362 | } |
| | 363 | } |
| | 364 | } else { |
| | 365 | if (qscale >= 0.0) { |
| | 366 | for (int i = 0; i < 64; i++) { |
| | 367 | luma[i] = FFMAX(1, unscaled_luma [(i & 7) * 8 + (i >> 3)] * f); |
| | 368 | chroma[i] = FFMAX(1, unscaled_chroma[(i & 7) * 8 + (i >> 3)] * f); |
| | 369 | } |
| | 370 | } else { |
| | 371 | for (int i = 0; i < 64; i++) { |
| | 372 | luma[i] = FFMAX(1, 255.0 - (255 - unscaled_luma [(i & 7) * 8 + (i >> 3)]) * f); |
| | 373 | chroma[i] = FFMAX(1, 255.0 - (255 - unscaled_chroma[(i & 7) * 8 + (i >> 3)]) * f); |
| | 374 | } |
| | 375 | } |
| | 376 | } |
| | 377 | |
| | 378 | for (int i = 0; i < 64; i++) { |
| | 379 | int pos = ff_zigzag_direct[i]; |
| | 380 | |
| | 381 | s->luma_quant_matrix[i] = luma[pos] * ((pos / 8) & 1 ? -1 : 1); |
| | 382 | s->chroma_quant_matrix[i] = chroma[pos] * ((pos / 8) & 1 ? -1 : 1); |
| | 383 | } |
| | 384 | } |
| | 385 | |
| | 386 | static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame) |
| | 387 | { |
| | 388 | AGMContext *s = avctx->priv_data; |
| | 389 | int ret; |
| | 390 | |
| | 391 | compute_quant_matrix(s, (2 * s->compression - 100) / 100.0); |
| | 392 | |
| | 393 | s->blocks_w = avctx->coded_width >> 3; |
| | 394 | s->blocks_h = avctx->coded_height >> 3; |
| | 395 | |
| | 396 | ret = decode_intra_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, 0); |
| | 397 | if (ret < 0) |
| | 398 | return ret; |
| | 399 | |
| | 400 | bytestream2_skip(&s->gbyte, s->size[0]); |
| | 401 | |
| | 402 | s->blocks_w = avctx->coded_width >> 4; |
| | 403 | s->blocks_h = avctx->coded_height >> 4; |
| | 404 | |
| | 405 | ret = decode_intra_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, 2); |
| | 406 | if (ret < 0) |
| | 407 | return ret; |
| | 408 | |
| | 409 | bytestream2_skip(&s->gbyte, s->size[1]); |
| | 410 | |
| | 411 | s->blocks_w = avctx->coded_width >> 4; |
| | 412 | s->blocks_h = avctx->coded_height >> 4; |
| | 413 | |
| | 414 | ret = decode_intra_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, 1); |
| | 415 | if (ret < 0) |
| | 416 | return ret; |
| | 417 | |
| | 418 | return 0; |
| | 419 | } |
| | 420 | |
| | 421 | static int decode_motion_vectors(AVCodecContext *avctx, GetBitContext *gb) |
| | 422 | { |
| | 423 | AGMContext *s = avctx->priv_data; |
| | 424 | int nb_mvs = ((avctx->height + 15) >> 4) * ((avctx->width + 15) >> 4); |
| | 425 | int ret, skip = 0, value, map; |
| | 426 | |
| | 427 | av_fast_padded_malloc(&s->mvectors, &s->mvectors_size, |
| | 428 | nb_mvs * sizeof(*s->mvectors)); |
| | 429 | if (!s->mvectors) |
| | 430 | return AVERROR(ENOMEM); |
| | 431 | |
| | 432 | if ((ret = init_get_bits8(gb, s->gbyte.buffer, bytestream2_get_bytes_left(&s->gbyte) - |
| | 433 | (s->size[0] + s->size[1] + s->size[2]))) < 0) |
| | 434 | return ret; |
| | 435 | |
| | 436 | memset(s->mvectors, 0, sizeof(*s->mvectors) * nb_mvs); |
| | 437 | |
| | 438 | for (int i = 0; i < nb_mvs; i++) { |
| | 439 | ret = read_code(gb, &skip, &value, &map, 1); |
| | 440 | if (ret < 0) |
| | 441 | return ret; |
| | 442 | s->mvectors[i].x = value; |
| | 443 | i += skip; |
| | 444 | } |
| | 445 | |
| | 446 | for (int i = 0; i < nb_mvs; i++) { |
| | 447 | ret = read_code(gb, &skip, &value, &map, 1); |
| | 448 | if (ret < 0) |
| | 449 | return ret; |
| | 450 | s->mvectors[i].y = value; |
| | 451 | i += skip; |
| | 452 | } |
| | 453 | |
| | 454 | if (get_bits_left(gb) <= 0) |
| | 455 | return AVERROR_INVALIDDATA; |
| | 456 | skip = (get_bits_count(gb) >> 3) + 1; |
| | 457 | bytestream2_skip(&s->gbyte, skip); |
| | 458 | |
| | 459 | return 0; |
| | 460 | } |
| | 461 | |
| | 462 | static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, |
| | 463 | AVFrame *frame, AVFrame *prev) |
| | 464 | { |
| | 465 | AGMContext *s = avctx->priv_data; |
| | 466 | int ret; |
| | 467 | |
| | 468 | compute_quant_matrix(s, (2 * s->compression - 100) / 100.0); |
| | 469 | |
| | 470 | if (s->flags & 2) { |
| | 471 | ret = decode_motion_vectors(avctx, gb); |
| | 472 | if (ret < 0) |
| | 473 | return ret; |
| | 474 | } |
| | 475 | |
| | 476 | s->blocks_w = avctx->coded_width >> 3; |
| | 477 | s->blocks_h = avctx->coded_height >> 3; |
| | 478 | |
| | 479 | ret = decode_inter_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, prev, 0); |
| | 480 | if (ret < 0) |
| | 481 | return ret; |
| | 482 | |
| | 483 | bytestream2_skip(&s->gbyte, s->size[0]); |
| | 484 | |
| | 485 | s->blocks_w = avctx->coded_width >> 4; |
| | 486 | s->blocks_h = avctx->coded_height >> 4; |
| | 487 | |
| | 488 | ret = decode_inter_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, prev, 2); |
| | 489 | if (ret < 0) |
| | 490 | return ret; |
| | 491 | |
| | 492 | bytestream2_skip(&s->gbyte, s->size[1]); |
| | 493 | |
| | 494 | s->blocks_w = avctx->coded_width >> 4; |
| | 495 | s->blocks_h = avctx->coded_height >> 4; |
| | 496 | |
| | 497 | ret = decode_inter_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, prev, 1); |
| | 498 | if (ret < 0) |
| | 499 | return ret; |
| | 500 | |
| | 501 | return 0; |
| | 502 | } |
| | 503 | |
| | 504 | static int decode_frame(AVCodecContext *avctx, void *data, |
| | 505 | int *got_frame, AVPacket *avpkt) |
| | 506 | { |
| | 507 | AGMContext *s = avctx->priv_data; |
| | 508 | GetBitContext *gb = &s->gb; |
| | 509 | GetByteContext *gbyte = &s->gbyte; |
| | 510 | AVFrame *frame = data; |
| | 511 | int w, h, width, height, header; |
| | 512 | int ret; |
| | 513 | |
| | 514 | if (!avpkt->size) |
| | 515 | return 0; |
| | 516 | |
| | 517 | bytestream2_init(gbyte, avpkt->data, avpkt->size); |
| | 518 | |
| | 519 | header = bytestream2_get_le32(gbyte); |
| | 520 | s->fflags = bytestream2_get_le32(gbyte); |
| | 521 | s->bitstream_size = s->fflags & 0x1FFFFFFF; |
| | 522 | s->fflags >>= 29; |
| | 523 | av_log(avctx, AV_LOG_DEBUG, "fflags: %X\n", s->fflags); |
| | 524 | if (avpkt->size < s->bitstream_size + 8) |
| | 525 | return AVERROR_INVALIDDATA; |
| | 526 | |
| | 527 | s->key_frame = s->fflags & 0x1; |
| | 528 | frame->key_frame = s->key_frame; |
| | 529 | frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
| | 530 | |
| | 531 | if (header) { |
| | 532 | av_log(avctx, AV_LOG_ERROR, "header: %X\n", header); |
| | 533 | return AVERROR_PATCHWELCOME; |
| | 534 | } |
| | 535 | |
| | 536 | s->flags = 0; |
| | 537 | w = bytestream2_get_le32(gbyte); |
| | 538 | if (w < 0) { |
| | 539 | w = -w; |
| | 540 | s->flags |= 2; |
| | 541 | } |
| | 542 | h = bytestream2_get_le32(gbyte); |
| | 543 | if (h < 0) { |
| | 544 | h = -h; |
| | 545 | s->flags |= 1; |
| | 546 | } |
| | 547 | |
| | 548 | width = avctx->width; |
| | 549 | height = avctx->height; |
| | 550 | if (w < width || h < height || w & 7 || h & 7) |
| | 551 | return AVERROR_INVALIDDATA; |
| | 552 | |
| | 553 | ret = ff_set_dimensions(avctx, w, h); |
| | 554 | if (ret < 0) |
| | 555 | return ret; |
| | 556 | avctx->width = width; |
| | 557 | avctx->height = height; |
| | 558 | |
| | 559 | s->compression = bytestream2_get_le32(gbyte); |
| | 560 | if (s->compression < 0 || s->compression > 100) |
| | 561 | return AVERROR_INVALIDDATA; |
| | 562 | |
| | 563 | for (int i = 0; i < 3; i++) |
| | 564 | s->size[i] = bytestream2_get_le32(gbyte); |
| | 565 | if (32LL + s->size[0] + s->size[1] + s->size[2] > avpkt->size) |
| | 566 | return AVERROR_INVALIDDATA; |
| | 567 | |
| | 568 | if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) |
| | 569 | return ret; |
| | 570 | |
| | 571 | if (frame->key_frame) { |
| | 572 | ret = decode_intra(avctx, gb, frame); |
| | 573 | } else { |
| | 574 | if (!s->prev_frame->data[0]) { |
| | 575 | av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); |
| | 576 | return AVERROR_INVALIDDATA; |
| | 577 | } |
| | 578 | |
| | 579 | if (!(s->flags & 2)) { |
| | 580 | ret = av_frame_copy(frame, s->prev_frame); |
| | 581 | if (ret < 0) |
| | 582 | return ret; |
| | 583 | } |
| | 584 | |
| | 585 | ret = decode_inter(avctx, gb, frame, s->prev_frame); |
| | 586 | } |
| | 587 | if (ret < 0) |
| | 588 | return ret; |
| | 589 | |
| | 590 | av_frame_unref(s->prev_frame); |
| | 591 | if ((ret = av_frame_ref(s->prev_frame, frame)) < 0) |
| | 592 | return ret; |
| | 593 | |
| | 594 | frame->crop_top = avctx->coded_height - avctx->height; |
| | 595 | frame->crop_left = avctx->coded_width - avctx->width; |
| | 596 | |
| | 597 | *got_frame = 1; |
| | 598 | |
| | 599 | return avpkt->size; |
| | 600 | } |
| | 601 | |
| | 602 | static av_cold int decode_init(AVCodecContext *avctx) |
| | 603 | { |
| | 604 | AGMContext *s = avctx->priv_data; |
| | 605 | |
| | 606 | avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
| | 607 | s->avctx = avctx; |
| | 608 | s->plus = avctx->codec_tag == MKTAG('A', 'G', 'M', '3'); |
| | 609 | |
| | 610 | avctx->idct_algo = FF_IDCT_SIMPLE; |
| | 611 | ff_idctdsp_init(&s->idsp, avctx); |
| | 612 | ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct); |
| | 613 | |
| | 614 | s->prev_frame = av_frame_alloc(); |
| | 615 | if (!s->prev_frame) |
| | 616 | return AVERROR(ENOMEM); |
| | 617 | |
| | 618 | return 0; |
| | 619 | } |
| | 620 | |
| | 621 | static void decode_flush(AVCodecContext *avctx) |
| | 622 | { |
| | 623 | AGMContext *s = avctx->priv_data; |
| | 624 | |
| | 625 | av_frame_unref(s->prev_frame); |
| | 626 | } |
| | 627 | |
| | 628 | static av_cold int decode_close(AVCodecContext *avctx) |
| | 629 | { |
| | 630 | AGMContext *s = avctx->priv_data; |
| | 631 | |
| | 632 | av_frame_free(&s->prev_frame); |
| | 633 | av_freep(&s->mvectors); |
| | 634 | s->mvectors_size = 0; |
| | 635 | |
| | 636 | return 0; |
| | 637 | } |
| | 638 | |
| | 639 | AVCodec ff_agm_decoder = { |
| | 640 | .name = "agm", |
| | 641 | .long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"), |
| | 642 | .type = AVMEDIA_TYPE_VIDEO, |
| | 643 | .id = AV_CODEC_ID_AGM, |
| | 644 | .priv_data_size = sizeof(AGMContext), |
| | 645 | .init = decode_init, |
| | 646 | .close = decode_close, |
| | 647 | .decode = decode_frame, |
| | 648 | .flush = decode_flush, |
| | 649 | .capabilities = AV_CODEC_CAP_DR1, |
| | 650 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | |
| | 651 | FF_CODEC_CAP_INIT_CLEANUP | |
| | 652 | FF_CODEC_CAP_EXPORTS_CROPPING, |
| | 653 | }; |