Unified · Split
| @@ -32,9 +32,44 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "internal.h" |
| 33 | 33 | #include "unary.h" |
| 34 | 34 | |
| 35 | +static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip) | |
| 36 | +{ | |
| 37 | + if (!vflip) | |
| 38 | + return; | |
| 39 | + | |
| 40 | + switch (pic->format) { | |
| 41 | + case AV_PIX_FMT_YUV444P: | |
| 42 | + pic->data[1] += (avctx->height - 1) * pic->linesize[1]; | |
| 43 | + pic->linesize[1] = -pic->linesize[1]; | |
| 44 | + pic->data[2] += (avctx->height - 1) * pic->linesize[2]; | |
| 45 | + pic->linesize[2] = -pic->linesize[2]; | |
| 46 | + case AV_PIX_FMT_BGR24: | |
| 47 | + case AV_PIX_FMT_RGB24: | |
| 48 | + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; | |
| 49 | + pic->linesize[0] = -pic->linesize[0]; | |
| 50 | + break; | |
| 51 | + case AV_PIX_FMT_YUV410P: | |
| 52 | + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; | |
| 53 | + pic->linesize[0] = -pic->linesize[0]; | |
| 54 | + pic->data[1] += ((avctx->height >> 2) - 1) * pic->linesize[1]; | |
| 55 | + pic->linesize[1] = -pic->linesize[1]; | |
| 56 | + pic->data[2] += ((avctx->height >> 2) - 1) * pic->linesize[2]; | |
| 57 | + pic->linesize[2] = -pic->linesize[2]; | |
| 58 | + break; | |
| 59 | + case AV_PIX_FMT_YUV420P: | |
| 60 | + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; | |
| 61 | + pic->linesize[0] = -pic->linesize[0]; | |
| 62 | + pic->data[1] += ((avctx->height >> 1) - 1) * pic->linesize[1]; | |
| 63 | + pic->linesize[1] = -pic->linesize[1]; | |
| 64 | + pic->data[2] += ((avctx->height >> 1) - 1) * pic->linesize[2]; | |
| 65 | + pic->linesize[2] = -pic->linesize[2]; | |
| 66 | + break; | |
| 67 | + } | |
| 68 | +} | |
| 69 | + | |
| 35 | 70 | static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, |
| 36 | 71 | const uint8_t *src, int src_size, |
| 37 | − int id, int bpp) | |
| 72 | + int id, int bpp, uint32_t vflipped) | |
| 38 | 73 | { |
| 39 | 74 | int h; |
| 40 | 75 | uint8_t *dst; |
| @@ -49,6 +84,8 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines | ||
| 49 | 84 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
| 50 | 85 | return ret; |
| 51 | 86 | |
| 87 | + do_vflip(avctx, pic, vflipped); | |
| 88 | + | |
| 52 | 89 | dst = pic->data[0]; |
| 53 | 90 | for (h = 0; h < avctx->height; h++) { |
| 54 | 91 | memcpy(dst, src, avctx->width * bpp); |
| @@ -56,11 +93,14 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, · 1 unmodified line | ||
| 56 | 93 | dst += pic->linesize[0]; |
| 57 | 94 | } |
| 58 | 95 | |
| 96 | + do_vflip(avctx, pic, vflipped); | |
| 97 | + | |
| 59 | 98 | return 0; |
| 60 | 99 | } |
| 61 | 100 | |
| 62 | 101 | static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, |
| 63 | − const uint8_t *src, int src_size) | |
| 102 | + const uint8_t *src, int src_size, | |
| 103 | + uint32_t vflipped) | |
| 64 | 104 | { |
| 65 | 105 | int h, w; |
| 66 | 106 | uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V; |
| @@ -75,6 +115,8 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines | ||
| 75 | 115 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
| 76 | 116 | return ret; |
| 77 | 117 | |
| 118 | + do_vflip(avctx, pic, vflipped); | |
| 119 | + | |
| 78 | 120 | Y1 = pic->data[0]; |
| 79 | 121 | Y2 = pic->data[0] + pic->linesize[0]; |
| 80 | 122 | Y3 = pic->data[0] + pic->linesize[0] * 2; |
| @@ -99,11 +141,14 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, · 18 unmodified lines | ||
| 99 | 141 | V += pic->linesize[2]; |
| 100 | 142 | } |
| 101 | 143 | |
| 144 | + do_vflip(avctx, pic, vflipped); | |
| 145 | + | |
| 102 | 146 | return 0; |
| 103 | 147 | } |
| 104 | 148 | |
| 105 | 149 | static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, |
| 106 | − const uint8_t *src, int src_size) | |
| 150 | + const uint8_t *src, int src_size, | |
| 151 | + uint32_t vflipped) | |
| 107 | 152 | { |
| 108 | 153 | int h, w; |
| 109 | 154 | uint8_t *Y1, *Y2, *U, *V; |
| @@ -118,6 +163,8 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines | ||
| 118 | 163 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
| 119 | 164 | return ret; |
| 120 | 165 | |
| 166 | + do_vflip(avctx, pic, vflipped); | |
| 167 | + | |
| 121 | 168 | Y1 = pic->data[0]; |
| 122 | 169 | Y2 = pic->data[0] + pic->linesize[0]; |
| 123 | 170 | U = pic->data[1]; |
| @@ -136,11 +183,14 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, · 12 unmodified lines | ||
| 136 | 183 | V += pic->linesize[2]; |
| 137 | 184 | } |
| 138 | 185 | |
| 186 | + do_vflip(avctx, pic, vflipped); | |
| 187 | + | |
| 139 | 188 | return 0; |
| 140 | 189 | } |
| 141 | 190 | |
| 142 | 191 | static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, |
| 143 | − const uint8_t *src, int src_size) | |
| 192 | + const uint8_t *src, int src_size, | |
| 193 | + uint32_t vflipped) | |
| 144 | 194 | { |
| 145 | 195 | int h, w; |
| 146 | 196 | uint8_t *Y, *U, *V; |
| @@ -155,6 +205,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines | ||
| 155 | 205 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
| 156 | 206 | return ret; |
| 157 | 207 | |
| 208 | + do_vflip(avctx, pic, vflipped); | |
| 209 | + | |
| 158 | 210 | Y = pic->data[0]; |
| 159 | 211 | U = pic->data[1]; |
| 160 | 212 | V = pic->data[2]; |
| @@ -169,6 +221,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines | ||
| 169 | 221 | V += pic->linesize[2]; |
| 170 | 222 | } |
| 171 | 223 | |
| 224 | + do_vflip(avctx, pic, vflipped); | |
| 225 | + | |
| 172 | 226 | return 0; |
| 173 | 227 | } |
| 174 | 228 | |
| @@ -270,7 +324,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, · 95 unmodified lines | ||
| 270 | 324 | const uint8_t *src, int src_size, |
| 271 | 325 | decode_slice_func decode_slice, |
| 272 | 326 | setup_lru_func setup_lru, |
| 273 | − enum AVPixelFormat fmt) | |
| 327 | + enum AVPixelFormat fmt, | |
| 328 | + uint32_t vflipped) | |
| 274 | 329 | { |
| 275 | 330 | GetByteContext gb, gb_check; |
| 276 | 331 | GetBitContext gb2; |
| @@ -301,6 +356,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, · 24 unmodified lines | ||
| 301 | 356 | if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) |
| 302 | 357 | return ret; |
| 303 | 358 | |
| 359 | + do_vflip(avctx, pic, vflipped); | |
| 360 | + | |
| 304 | 361 | for (slice = 0; slice < nslices; slice++) { |
| 305 | 362 | slice_size = bytestream2_get_le32(&gb); |
| 306 | 363 | |
| @@ -322,6 +379,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, · 15 unmodified lines | ||
| 322 | 379 | avpriv_request_sample(avctx, "Not enough slice data available"); |
| 323 | 380 | } |
| 324 | 381 | |
| 382 | + do_vflip(avctx, pic, vflipped); | |
| 383 | + | |
| 325 | 384 | return 0; |
| 326 | 385 | } |
| 327 | 386 | |
| @@ -379,19 +438,20 @@ static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame, · 51 unmodified lines | ||
| 379 | 438 | } |
| 380 | 439 | |
| 381 | 440 | static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, |
| 382 | − const uint8_t *src, int src_size, int is_565) | |
| 441 | + const uint8_t *src, int src_size, int is_565, | |
| 442 | + uint32_t vflipped) | |
| 383 | 443 | { |
| 384 | 444 | enum AVPixelFormat fmt = AV_PIX_FMT_RGB24; |
| 385 | 445 | if (is_565) |
| 386 | 446 | return dxtory_decode_v2(avctx, pic, src, src_size, |
| 387 | 447 | dx2_decode_slice_565, |
| 388 | 448 | setup_lru_565, |
| 389 | − fmt); | |
| 449 | + fmt, vflipped); | |
| 390 | 450 | else |
| 391 | 451 | return dxtory_decode_v2(avctx, pic, src, src_size, |
| 392 | 452 | dx2_decode_slice_555, |
| 393 | 453 | setup_lru_555, |
| 394 | − fmt); | |
| 454 | + fmt, vflipped); | |
| 395 | 455 | } |
| 396 | 456 | |
| 397 | 457 | static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, |
| @@ -424,12 +484,13 @@ static void default_setup_lru(uint8_t lru[3][8]) · 26 unmodified lines | ||
| 424 | 484 | } |
| 425 | 485 | |
| 426 | 486 | static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, |
| 427 | − const uint8_t *src, int src_size) | |
| 487 | + const uint8_t *src, int src_size, | |
| 488 | + uint32_t vflipped) | |
| 428 | 489 | { |
| 429 | 490 | return dxtory_decode_v2(avctx, pic, src, src_size, |
| 430 | 491 | dx2_decode_slice_rgb, |
| 431 | 492 | default_setup_lru, |
| 432 | − AV_PIX_FMT_BGR24); | |
| 493 | + AV_PIX_FMT_BGR24, vflipped); | |
| 433 | 494 | } |
| 434 | 495 | |
| 435 | 496 | static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, |
| @@ -466,12 +527,13 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, · 30 unmodified lines | ||
| 466 | 527 | |
| 467 | 528 | |
| 468 | 529 | static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, |
| 469 | − const uint8_t *src, int src_size) | |
| 530 | + const uint8_t *src, int src_size, | |
| 531 | + uint32_t vflipped) | |
| 470 | 532 | { |
| 471 | 533 | return dxtory_decode_v2(avctx, pic, src, src_size, |
| 472 | 534 | dx2_decode_slice_410, |
| 473 | 535 | default_setup_lru, |
| 474 | − AV_PIX_FMT_YUV410P); | |
| 536 | + AV_PIX_FMT_YUV410P, vflipped); | |
| 475 | 537 | } |
| 476 | 538 | |
| 477 | 539 | static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, |
| @@ -510,12 +572,13 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, · 32 unmodified lines | ||
| 510 | 572 | } |
| 511 | 573 | |
| 512 | 574 | static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, |
| 513 | − const uint8_t *src, int src_size) | |
| 575 | + const uint8_t *src, int src_size, | |
| 576 | + uint32_t vflipped) | |
| 514 | 577 | { |
| 515 | 578 | return dxtory_decode_v2(avctx, pic, src, src_size, |
| 516 | 579 | dx2_decode_slice_420, |
| 517 | 580 | default_setup_lru, |
| 518 | − AV_PIX_FMT_YUV420P); | |
| 581 | + AV_PIX_FMT_YUV420P, vflipped); | |
| 519 | 582 | } |
| 520 | 583 | |
| 521 | 584 | static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, |
| @@ -550,12 +613,13 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, · 28 unmodified lines | ||
| 550 | 613 | } |
| 551 | 614 | |
| 552 | 615 | static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic, |
| 553 | − const uint8_t *src, int src_size) | |
| 616 | + const uint8_t *src, int src_size, | |
| 617 | + uint32_t vflipped) | |
| 554 | 618 | { |
| 555 | 619 | return dxtory_decode_v2(avctx, pic, src, src_size, |
| 556 | 620 | dx2_decode_slice_444, |
| 557 | 621 | default_setup_lru, |
| 558 | − AV_PIX_FMT_YUV444P); | |
| 622 | + AV_PIX_FMT_YUV444P, vflipped); | |
| 559 | 623 | } |
| 560 | 624 | |
| 561 | 625 | static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
| @@ -563,57 +627,75 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, · 1 unmodified line | ||
| 563 | 627 | { |
| 564 | 628 | AVFrame *pic = data; |
| 565 | 629 | const uint8_t *src = avpkt->data; |
| 566 | − int ret; | |
| 630 | + uint32_t type; | |
| 631 | + int vflipped, ret; | |
| 567 | 632 | |
| 568 | 633 | if (avpkt->size < 16) { |
| 569 | 634 | av_log(avctx, AV_LOG_ERROR, "packet too small\n"); |
| 570 | 635 | return AVERROR_INVALIDDATA; |
| 571 | 636 | } |
| 572 | 637 | |
| 573 | − switch (AV_RB32(src)) { | |
| 638 | + type = AV_RB32(src); | |
| 639 | + vflipped = !!(type & 0x20); | |
| 640 | + | |
| 641 | + switch (type) { | |
| 642 | + case 0x01000021: | |
| 574 | 643 | case 0x01000001: |
| 575 | 644 | ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, |
| 576 | − AV_PIX_FMT_BGR24, 3); | |
| 645 | + AV_PIX_FMT_BGR24, 3, vflipped); | |
| 577 | 646 | break; |
| 647 | + case 0x01000029: | |
| 578 | 648 | case 0x01000009: |
| 579 | − ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16); | |
| 649 | + ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 580 | 650 | break; |
| 651 | + case 0x02000021: | |
| 581 | 652 | case 0x02000001: |
| 582 | − ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16); | |
| 653 | + ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 583 | 654 | break; |
| 655 | + case 0x02000029: | |
| 584 | 656 | case 0x02000009: |
| 585 | − ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16); | |
| 657 | + ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 586 | 658 | break; |
| 659 | + case 0x03000021: | |
| 587 | 660 | case 0x03000001: |
| 588 | − ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16); | |
| 661 | + ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 589 | 662 | break; |
| 663 | + case 0x03000029: | |
| 590 | 664 | case 0x03000009: |
| 591 | − ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16); | |
| 665 | + ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 592 | 666 | break; |
| 667 | + case 0x04000021: | |
| 593 | 668 | case 0x04000001: |
| 594 | − ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16); | |
| 669 | + ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 595 | 670 | break; |
| 671 | + case 0x04000029: | |
| 596 | 672 | case 0x04000009: |
| 597 | − ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16); | |
| 673 | + ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); | |
| 598 | 674 | break; |
| 675 | + case 0x17000021: | |
| 599 | 676 | case 0x17000001: |
| 600 | 677 | ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, |
| 601 | − AV_PIX_FMT_RGB565LE, 2); | |
| 678 | + AV_PIX_FMT_RGB565LE, 2, vflipped); | |
| 602 | 679 | break; |
| 680 | + case 0x17000029: | |
| 603 | 681 | case 0x17000009: |
| 604 | − ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1); | |
| 682 | + ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped); | |
| 605 | 683 | break; |
| 684 | + case 0x18000021: | |
| 685 | + case 0x19000021: | |
| 606 | 686 | case 0x18000001: |
| 607 | 687 | case 0x19000001: |
| 608 | 688 | ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, |
| 609 | − AV_PIX_FMT_RGB555LE, 2); | |
| 689 | + AV_PIX_FMT_RGB555LE, 2, vflipped); | |
| 610 | 690 | break; |
| 691 | + case 0x18000029: | |
| 692 | + case 0x19000029: | |
| 611 | 693 | case 0x18000009: |
| 612 | 694 | case 0x19000009: |
| 613 | − ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0); | |
| 695 | + ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped); | |
| 614 | 696 | break; |
| 615 | 697 | default: |
| 616 | − avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src)); | |
| 698 | + avpriv_request_sample(avctx, "Frame header %"PRIX32, type); | |
| 617 | 699 | return AVERROR_PATCHWELCOME; |
| 618 | 700 | } |
| 619 | 701 | |