1/* 2 * MagicYUV decoder 3 * Copyright (c) 2016 Paul B Mahol 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#include <stdlib.h> 23#include <string.h> 24 25#define CACHED_BITSTREAM_READER !ARCH_X86_32 26 27#include "libavutil/pixdesc.h" 28 29#include "avcodec.h" 30#include "bytestream.h" 31#include "codec_internal.h" 32#include "get_bits.h" 33#include "huffyuvdsp.h" 34#include "internal.h" 35#include "lossless_videodsp.h" 36#include "thread.h" 37 38typedef struct Slice { 39 uint32_t start; 40 uint32_t size; 41} Slice; 42 43typedef enum Prediction { 44 LEFT = 1, 45 GRADIENT, 46 MEDIAN, 47} Prediction; 48 49typedef struct HuffEntry { 50 uint8_t len; 51 uint16_t sym; 52} HuffEntry; 53 54typedef struct MagicYUVContext { 55 AVFrame *p; 56 int max; 57 int bps; 58 int slice_height; 59 int nb_slices; 60 int planes; // number of encoded planes in bitstream 61 int decorrelate; // postprocessing work 62 int color_matrix; // video color matrix 63 int flags; 64 int interlaced; // video is interlaced 65 const uint8_t *buf; // pointer to AVPacket->data 66 int hshift[4]; 67 int vshift[4]; 68 Slice *slices[4]; // slice bitstream positions for each plane 69 unsigned int slices_size[4]; // slice sizes for each plane 70 VLC vlc[4]; // VLC for each plane 71 int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata, 72 int j, int threadnr); 73 LLVidDSPContext llviddsp; 74} MagicYUVContext; 75 76static int huff_build(const uint8_t len[], uint16_t codes_pos[33], 77 VLC *vlc, int nb_elems, void *logctx) 78{ 79 HuffEntry he[4096]; 80 81 for (int i = 31; i > 0; i--) 82 codes_pos[i] += codes_pos[i + 1]; 83 84 for (unsigned i = nb_elems; i-- > 0;) 85 he[--codes_pos[len[i]]] = (HuffEntry){ len[i], i }; 86 87 ff_free_vlc(vlc); 88 return ff_init_vlc_from_lengths(vlc, FFMIN(he[0].len, 12), nb_elems, 89 &he[0].len, sizeof(he[0]), 90 &he[0].sym, sizeof(he[0]), sizeof(he[0].sym), 91 0, 0, logctx); 92} 93 94static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1, 95 const uint16_t *diff, intptr_t w, 96 int *left, int *left_top, int max) 97{ 98 int i; 99 uint16_t l, lt; 100 101 l = *left; 102 lt = *left_top; 103 104 for (i = 0; i < w; i++) { 105 l = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i]; 106 l &= max; 107 lt = src1[i]; 108 dst[i] = l; 109 } 110 111 *left = l; 112 *left_top = lt; 113} 114 115static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, 116 int j, int threadnr) 117{ 118 MagicYUVContext *s = avctx->priv_data; 119 int interlaced = s->interlaced; 120 const int bps = s->bps; 121 const int max = s->max - 1; 122 AVFrame *p = s->p; 123 int i, k, x; 124 GetBitContext gb; 125 uint16_t *dst; 126 127 for (i = 0; i < s->planes; i++) { 128 int left, lefttop, top; 129 int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); 130 int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); 131 int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); 132 ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced); 133 ptrdiff_t stride = p->linesize[i] / 2; 134 int flags, pred; 135 int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, 136 s->slices[i][j].size); 137 138 if (ret < 0) 139 return ret; 140 141 flags = get_bits(&gb, 8); 142 pred = get_bits(&gb, 8); 143 144 dst = (uint16_t *)p->data[i] + j * sheight * stride; 145 if (flags & 1) { 146 if (get_bits_left(&gb) < bps * width * height) 147 return AVERROR_INVALIDDATA; 148 for (k = 0; k < height; k++) { 149 for (x = 0; x < width; x++) 150 dst[x] = get_bits(&gb, bps); 151 152 dst += stride; 153 } 154 } else { 155 for (k = 0; k < height; k++) { 156 for (x = 0; x < width; x++) { 157 int pix; 158 if (get_bits_left(&gb) <= 0) 159 return AVERROR_INVALIDDATA; 160 161 pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); 162 if (pix < 0) 163 return AVERROR_INVALIDDATA; 164 165 dst[x] = pix; 166 } 167 dst += stride; 168 } 169 } 170 171 switch (pred) { 172 case LEFT: 173 dst = (uint16_t *)p->data[i] + j * sheight * stride; 174 s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); 175 dst += stride; 176 if (interlaced) { 177 s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); 178 dst += stride; 179 } 180 for (k = 1 + interlaced; k < height; k++) { 181 s->llviddsp.add_left_pred_int16(dst, dst, max, width, dst[-fake_stride]); 182 dst += stride; 183 } 184 break; 185 case GRADIENT: 186 dst = (uint16_t *)p->data[i] + j * sheight * stride; 187 s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); 188 dst += stride; 189 if (interlaced) { 190 s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); 191 dst += stride; 192 } 193 for (k = 1 + interlaced; k < height; k++) { 194 top = dst[-fake_stride]; 195 left = top + dst[0]; 196 dst[0] = left & max; 197 for (x = 1; x < width; x++) { 198 top = dst[x - fake_stride]; 199 lefttop = dst[x - (fake_stride + 1)]; 200 left += top - lefttop + dst[x]; 201 dst[x] = left & max; 202 } 203 dst += stride; 204 } 205 break; 206 case MEDIAN: 207 dst = (uint16_t *)p->data[i] + j * sheight * stride; 208 s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); 209 dst += stride; 210 if (interlaced) { 211 s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); 212 dst += stride; 213 } 214 lefttop = left = dst[0]; 215 for (k = 1 + interlaced; k < height; k++) { 216 magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max); 217 lefttop = left = dst[0]; 218 dst += stride; 219 } 220 break; 221 default: 222 avpriv_request_sample(avctx, "Unknown prediction: %d", pred); 223 } 224 } 225 226 if (s->decorrelate) { 227 int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); 228 int width = avctx->coded_width; 229 uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2; 230 uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2; 231 uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2; 232 233 for (i = 0; i < height; i++) { 234 for (k = 0; k < width; k++) { 235 b[k] = (b[k] + g[k]) & max; 236 r[k] = (r[k] + g[k]) & max; 237 } 238 b += p->linesize[0] / 2; 239 g += p->linesize[1] / 2; 240 r += p->linesize[2] / 2; 241 } 242 } 243 244 return 0; 245} 246 247static int magy_decode_slice(AVCodecContext *avctx, void *tdata, 248 int j, int threadnr) 249{ 250 MagicYUVContext *s = avctx->priv_data; 251 int interlaced = s->interlaced; 252 AVFrame *p = s->p; 253 int i, k, x, min_width; 254 GetBitContext gb; 255 uint8_t *dst; 256 257 for (i = 0; i < s->planes; i++) { 258 int left, lefttop, top; 259 int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); 260 int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); 261 int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); 262 ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); 263 ptrdiff_t stride = p->linesize[i]; 264 const uint8_t *slice = s->buf + s->slices[i][j].start; 265 int flags, pred; 266 267 flags = bytestream_get_byte(&slice); 268 pred = bytestream_get_byte(&slice); 269 270 dst = p->data[i] + j * sheight * stride; 271 if (flags & 1) { 272 if (s->slices[i][j].size - 2 < width * height) 273 return AVERROR_INVALIDDATA; 274 for (k = 0; k < height; k++) { 275 bytestream_get_buffer(&slice, dst, width); 276 dst += stride; 277 } 278 } else { 279 int ret = init_get_bits8(&gb, slice, s->slices[i][j].size - 2); 280 281 if (ret < 0) 282 return ret; 283 284 for (k = 0; k < height; k++) { 285 for (x = 0; x < width; x++) { 286 int pix; 287 if (get_bits_left(&gb) <= 0) 288 return AVERROR_INVALIDDATA; 289 290 pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); 291 if (pix < 0) 292 return AVERROR_INVALIDDATA; 293 294 dst[x] = pix; 295 } 296 dst += stride; 297 } 298 } 299 300 switch (pred) { 301 case LEFT: 302 dst = p->data[i] + j * sheight * stride; 303 s->llviddsp.add_left_pred(dst, dst, width, 0); 304 dst += stride; 305 if (interlaced) { 306 s->llviddsp.add_left_pred(dst, dst, width, 0); 307 dst += stride; 308 } 309 for (k = 1 + interlaced; k < height; k++) { 310 s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]); 311 dst += stride; 312 } 313 break; 314 case GRADIENT: 315 dst = p->data[i] + j * sheight * stride; 316 s->llviddsp.add_left_pred(dst, dst, width, 0); 317 dst += stride; 318 if (interlaced) { 319 s->llviddsp.add_left_pred(dst, dst, width, 0); 320 dst += stride; 321 } 322 min_width = FFMIN(width, 32); 323 for (k = 1 + interlaced; k < height; k++) { 324 top = dst[-fake_stride]; 325 left = top + dst[0]; 326 dst[0] = left; 327 for (x = 1; x < min_width; x++) { /* dsp need aligned 32 */ 328 top = dst[x - fake_stride]; 329 lefttop = dst[x - (fake_stride + 1)]; 330 left += top - lefttop + dst[x]; 331 dst[x] = left; 332 } 333 if (width > 32) 334 s->llviddsp.add_gradient_pred(dst + 32, fake_stride, width - 32); 335 dst += stride; 336 } 337 break; 338 case MEDIAN: 339 dst = p->data[i] + j * sheight * stride; 340 s->llviddsp.add_left_pred(dst, dst, width, 0); 341 dst += stride; 342 if (interlaced) { 343 s->llviddsp.add_left_pred(dst, dst, width, 0); 344 dst += stride; 345 } 346 lefttop = left = dst[0]; 347 for (k = 1 + interlaced; k < height; k++) { 348 s->llviddsp.add_median_pred(dst, dst - fake_stride, 349 dst, width, &left, &lefttop); 350 lefttop = left = dst[0]; 351 dst += stride; 352 } 353 break; 354 default: 355 avpriv_request_sample(avctx, "Unknown prediction: %d", pred); 356 } 357 } 358 359 if (s->decorrelate) { 360 int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); 361 int width = avctx->coded_width; 362 uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0]; 363 uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1]; 364 uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2]; 365 366 for (i = 0; i < height; i++) { 367 s->llviddsp.add_bytes(b, g, width); 368 s->llviddsp.add_bytes(r, g, width); 369 b += p->linesize[0]; 370 g += p->linesize[1]; 371 r += p->linesize[2]; 372 } 373 } 374 375 return 0; 376} 377 378static int build_huffman(AVCodecContext *avctx, const uint8_t *table, 379 int table_size, int max) 380{ 381 MagicYUVContext *s = avctx->priv_data; 382 GetByteContext gb; 383 uint8_t len[4096]; 384 uint16_t length_count[33] = { 0 }; 385 int i = 0, j = 0, k; 386 387 bytestream2_init(&gb, table, table_size); 388 389 while (bytestream2_get_bytes_left(&gb) > 0) { 390 int b = bytestream2_peek_byteu(&gb) & 0x80; 391 int x = bytestream2_get_byteu(&gb) & ~0x80; 392 int l = 1; 393 394 if (b) { 395 if (bytestream2_get_bytes_left(&gb) <= 0) 396 break; 397 l += bytestream2_get_byteu(&gb); 398 } 399 k = j + l; 400 if (k > max || x == 0 || x > 32) { 401 av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n"); 402 return AVERROR_INVALIDDATA; 403 } 404 405 length_count[x] += l; 406 for (; j < k; j++) 407 len[j] = x; 408 409 if (j == max) { 410 j = 0; 411 if (huff_build(len, length_count, &s->vlc[i], max, avctx)) { 412 av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); 413 return AVERROR_INVALIDDATA; 414 } 415 i++; 416 if (i == s->planes) { 417 break; 418 } 419 memset(length_count, 0, sizeof(length_count)); 420 } 421 } 422 423 if (i != s->planes) { 424 av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n"); 425 return AVERROR_INVALIDDATA; 426 } 427 428 return 0; 429} 430 431static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p, 432 int *got_frame, AVPacket *avpkt) 433{ 434 MagicYUVContext *s = avctx->priv_data; 435 GetByteContext gb; 436 uint32_t first_offset, offset, next_offset, header_size, slice_width; 437 int width, height, format, version, table_size; 438 int ret, i, j; 439 440 if (avpkt->size < 36) 441 return AVERROR_INVALIDDATA; 442 443 bytestream2_init(&gb, avpkt->data, avpkt->size); 444 if (bytestream2_get_le32u(&gb) != MKTAG('M', 'A', 'G', 'Y')) 445 return AVERROR_INVALIDDATA; 446 447 header_size = bytestream2_get_le32u(&gb); 448 if (header_size < 32 || header_size >= avpkt->size) { 449 av_log(avctx, AV_LOG_ERROR, 450 "header or packet too small %"PRIu32"\n", header_size); 451 return AVERROR_INVALIDDATA; 452 } 453 454 version = bytestream2_get_byteu(&gb); 455 if (version != 7) { 456 avpriv_request_sample(avctx, "Version %d", version); 457 return AVERROR_PATCHWELCOME; 458 } 459 460 s->hshift[1] = 461 s->vshift[1] = 462 s->hshift[2] = 463 s->vshift[2] = 0; 464 s->decorrelate = 0; 465 s->bps = 8; 466 467 format = bytestream2_get_byteu(&gb); 468 switch (format) { 469 case 0x65: 470 avctx->pix_fmt = AV_PIX_FMT_GBRP; 471 s->decorrelate = 1; 472 break; 473 case 0x66: 474 avctx->pix_fmt = AV_PIX_FMT_GBRAP; 475 s->decorrelate = 1; 476 break; 477 case 0x67: 478 avctx->pix_fmt = AV_PIX_FMT_YUV444P; 479 break; 480 case 0x68: 481 avctx->pix_fmt = AV_PIX_FMT_YUV422P; 482 s->hshift[1] = 483 s->hshift[2] = 1; 484 break; 485 case 0x69: 486 avctx->pix_fmt = AV_PIX_FMT_YUV420P; 487 s->hshift[1] = 488 s->vshift[1] = 489 s->hshift[2] = 490 s->vshift[2] = 1; 491 break; 492 case 0x6a: 493 avctx->pix_fmt = AV_PIX_FMT_YUVA444P; 494 break; 495 case 0x6b: 496 avctx->pix_fmt = AV_PIX_FMT_GRAY8; 497 break; 498 case 0x6c: 499 avctx->pix_fmt = AV_PIX_FMT_YUV422P10; 500 s->hshift[1] = 501 s->hshift[2] = 1; 502 s->bps = 10; 503 break; 504 case 0x76: 505 avctx->pix_fmt = AV_PIX_FMT_YUV444P10; 506 s->bps = 10; 507 break; 508 case 0x6d: 509 avctx->pix_fmt = AV_PIX_FMT_GBRP10; 510 s->decorrelate = 1; 511 s->bps = 10; 512 break; 513 case 0x6e: 514 avctx->pix_fmt = AV_PIX_FMT_GBRAP10; 515 s->decorrelate = 1; 516 s->bps = 10; 517 break; 518 case 0x6f: 519 avctx->pix_fmt = AV_PIX_FMT_GBRP12; 520 s->decorrelate = 1; 521 s->bps = 12; 522 break; 523 case 0x70: 524 avctx->pix_fmt = AV_PIX_FMT_GBRAP12; 525 s->decorrelate = 1; 526 s->bps = 12; 527 break; 528 case 0x73: 529 avctx->pix_fmt = AV_PIX_FMT_GRAY10; 530 s->bps = 10; 531 break; 532 case 0x7b: 533 avctx->pix_fmt = AV_PIX_FMT_YUV420P10; 534 s->hshift[1] = 535 s->vshift[1] = 536 s->hshift[2] = 537 s->vshift[2] = 1; 538 s->bps = 10; 539 break; 540 default: 541 avpriv_request_sample(avctx, "Format 0x%X", format); 542 return AVERROR_PATCHWELCOME; 543 } 544 s->max = 1 << s->bps; 545 s->magy_decode_slice = s->bps == 8 ? magy_decode_slice : magy_decode_slice10; 546 s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); 547 548 bytestream2_skipu(&gb, 1); 549 s->color_matrix = bytestream2_get_byteu(&gb); 550 s->flags = bytestream2_get_byteu(&gb); 551 s->interlaced = !!(s->flags & 2); 552 bytestream2_skipu(&gb, 3); 553 554 width = bytestream2_get_le32u(&gb); 555 height = bytestream2_get_le32u(&gb); 556 ret = ff_set_dimensions(avctx, width, height); 557 if (ret < 0) 558 return ret; 559 560 slice_width = bytestream2_get_le32u(&gb); 561 if (slice_width != avctx->coded_width) { 562 avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width); 563 return AVERROR_PATCHWELCOME; 564 } 565 s->slice_height = bytestream2_get_le32u(&gb); 566 if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) { 567 av_log(avctx, AV_LOG_ERROR, 568 "invalid slice height: %d\n", s->slice_height); 569 return AVERROR_INVALIDDATA; 570 } 571 572 bytestream2_skipu(&gb, 4); 573 574 s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height; 575 if (s->nb_slices > INT_MAX / FFMAX(sizeof(Slice), 4 * 5)) { 576 av_log(avctx, AV_LOG_ERROR, 577 "invalid number of slices: %d\n", s->nb_slices); 578 return AVERROR_INVALIDDATA; 579 } 580 581 if (s->interlaced) { 582 if ((s->slice_height >> s->vshift[1]) < 2) { 583 av_log(avctx, AV_LOG_ERROR, "impossible slice height\n"); 584 return AVERROR_INVALIDDATA; 585 } 586 if ((avctx->coded_height % s->slice_height) && ((avctx->coded_height % s->slice_height) >> s->vshift[1]) < 2) { 587 av_log(avctx, AV_LOG_ERROR, "impossible height\n"); 588 return AVERROR_INVALIDDATA; 589 } 590 } 591 592 if (bytestream2_get_bytes_left(&gb) <= s->nb_slices * s->planes * 5) 593 return AVERROR_INVALIDDATA; 594 for (i = 0; i < s->planes; i++) { 595 av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice)); 596 if (!s->slices[i]) 597 return AVERROR(ENOMEM); 598 599 offset = bytestream2_get_le32u(&gb); 600 if (offset >= avpkt->size - header_size) 601 return AVERROR_INVALIDDATA; 602 603 if (i == 0) 604 first_offset = offset; 605 606 for (j = 0; j < s->nb_slices - 1; j++) { 607 s->slices[i][j].start = offset + header_size; 608 609 next_offset = bytestream2_get_le32u(&gb); 610 if (next_offset <= offset || next_offset >= avpkt->size - header_size) 611 return AVERROR_INVALIDDATA; 612 613 s->slices[i][j].size = next_offset - offset; 614 if (s->slices[i][j].size < 2) 615 return AVERROR_INVALIDDATA; 616 offset = next_offset; 617 } 618 619 s->slices[i][j].start = offset + header_size; 620 s->slices[i][j].size = avpkt->size - s->slices[i][j].start; 621 622 if (s->slices[i][j].size < 2) 623 return AVERROR_INVALIDDATA; 624 } 625 626 if (bytestream2_get_byteu(&gb) != s->planes) 627 return AVERROR_INVALIDDATA; 628 629 bytestream2_skipu(&gb, s->nb_slices * s->planes); 630 631 table_size = header_size + first_offset - bytestream2_tell(&gb); 632 if (table_size < 2) 633 return AVERROR_INVALIDDATA; 634 635 ret = build_huffman(avctx, avpkt->data + bytestream2_tell(&gb), 636 table_size, s->max); 637 if (ret < 0) 638 return ret; 639 640 p->pict_type = AV_PICTURE_TYPE_I; 641 p->key_frame = 1; 642 643 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0) 644 return ret; 645 646 s->buf = avpkt->data; 647 s->p = p; 648 avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices); 649 650 if (avctx->pix_fmt == AV_PIX_FMT_GBRP || 651 avctx->pix_fmt == AV_PIX_FMT_GBRAP || 652 avctx->pix_fmt == AV_PIX_FMT_GBRP10 || 653 avctx->pix_fmt == AV_PIX_FMT_GBRAP10|| 654 avctx->pix_fmt == AV_PIX_FMT_GBRAP12|| 655 avctx->pix_fmt == AV_PIX_FMT_GBRP12) { 656 FFSWAP(uint8_t*, p->data[0], p->data[1]); 657 FFSWAP(int, p->linesize[0], p->linesize[1]); 658 } else { 659 switch (s->color_matrix) { 660 case 1: 661 p->colorspace = AVCOL_SPC_BT470BG; 662 break; 663 case 2: 664 p->colorspace = AVCOL_SPC_BT709; 665 break; 666 } 667 p->color_range = (s->flags & 4) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; 668 } 669 670 *got_frame = 1; 671 672 return avpkt->size; 673} 674 675static av_cold int magy_decode_init(AVCodecContext *avctx) 676{ 677 MagicYUVContext *s = avctx->priv_data; 678 ff_llviddsp_init(&s->llviddsp); 679 return 0; 680} 681 682static av_cold int magy_decode_end(AVCodecContext *avctx) 683{ 684 MagicYUVContext * const s = avctx->priv_data; 685 int i; 686 687 for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) { 688 av_freep(&s->slices[i]); 689 s->slices_size[i] = 0; 690 ff_free_vlc(&s->vlc[i]); 691 } 692 693 return 0; 694} 695 696const FFCodec ff_magicyuv_decoder = { 697 .p.name = "magicyuv", 698 .p.long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), 699 .p.type = AVMEDIA_TYPE_VIDEO, 700 .p.id = AV_CODEC_ID_MAGICYUV, 701 .priv_data_size = sizeof(MagicYUVContext), 702 .init = magy_decode_init, 703 .close = magy_decode_end, 704 FF_CODEC_DECODE_CB(magy_decode_frame), 705 .p.capabilities = AV_CODEC_CAP_DR1 | 706 AV_CODEC_CAP_FRAME_THREADS | 707 AV_CODEC_CAP_SLICE_THREADS, 708 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 709}; 710