| @@ -67,9 +67,10 @@ struct mp_repack { · 66 unmodified lines |
| 67 | | 67 | |
| 68 | // Fringe RGB/YUV. | 68 | // Fringe RGB/YUV. |
| 69 | uint8_t comp_size; | 69 | uint8_t comp_size; |
| 70 | uint8_t comp_map[4]; | 70 | uint8_t comp_map[6]; |
| 71 | uint8_t comp_shifts[3]; | 71 | uint8_t comp_shifts[3]; |
| 72 | uint8_t *comp_lut; | 72 | uint8_t *comp_lut; |
| | 73 | void (*repack_fringe_yuv)(void *dst, void *src[], int w, uint8_t *c); |
| 73 | | 74 | |
| 74 | // F32 repacking. | 75 | // F32 repacking. |
| 75 | int f32_comp_size; | 76 | int f32_comp_size; |
| @@ -596,8 +597,8 @@ static void setup_misc_packer(struct mp_repack *rp) · 520 unmodified lines |
| 596 | for (int x = 0; x < w; x += 2) { \ | 597 | for (int x = 0; x < w; x += 2) { \ |
| 597 | ((comp_t *)dst)[x * 2 + c[0]] = ((comp_t *)src[0])[x + 0]; \ | 598 | ((comp_t *)dst)[x * 2 + c[0]] = ((comp_t *)src[0])[x + 0]; \ |
| 598 | ((comp_t *)dst)[x * 2 + c[1]] = ((comp_t *)src[0])[x + 1]; \ | 599 | ((comp_t *)dst)[x * 2 + c[1]] = ((comp_t *)src[0])[x + 1]; \ |
| 599 | ((comp_t *)dst)[x * 2 + c[2]] = ((comp_t *)src[1])[x >> 1]; \ | 600 | ((comp_t *)dst)[x * 2 + c[4]] = ((comp_t *)src[1])[x >> 1]; \ |
| 600 | ((comp_t *)dst)[x * 2 + c[3]] = ((comp_t *)src[2])[x >> 1]; \ | 601 | ((comp_t *)dst)[x * 2 + c[5]] = ((comp_t *)src[2])[x >> 1]; \ |
| 601 | } \ | 602 | } \ |
| 602 | } | 603 | } |
| 603 | | 604 | |
| @@ -607,8 +608,8 @@ static void setup_misc_packer(struct mp_repack *rp) · 3 unmodified lines |
| 607 | for (int x = 0; x < w; x += 2) { \ | 608 | for (int x = 0; x < w; x += 2) { \ |
| 608 | ((comp_t *)dst[0])[x + 0] = ((comp_t *)src)[x * 2 + c[0]]; \ | 609 | ((comp_t *)dst[0])[x + 0] = ((comp_t *)src)[x * 2 + c[0]]; \ |
| 609 | ((comp_t *)dst[0])[x + 1] = ((comp_t *)src)[x * 2 + c[1]]; \ | 610 | ((comp_t *)dst[0])[x + 1] = ((comp_t *)src)[x * 2 + c[1]]; \ |
| 610 | ((comp_t *)dst[1])[x >> 1] = ((comp_t *)src)[x * 2 + c[2]]; \ | 611 | ((comp_t *)dst[1])[x >> 1] = ((comp_t *)src)[x * 2 + c[4]]; \ |
| 611 | ((comp_t *)dst[2])[x >> 1] = ((comp_t *)src)[x * 2 + c[3]]; \ | 612 | ((comp_t *)dst[2])[x >> 1] = ((comp_t *)src)[x * 2 + c[5]]; \ |
| 612 | } \ | 613 | } \ |
| 613 | } | 614 | } |
| 614 | | 615 | |
| @@ -617,9 +618,34 @@ PA_P422(pa_p422_16, uint16_t) · 2 unmodified lines |
| 617 | UN_P422(un_p422_8, uint8_t) | 618 | UN_P422(un_p422_8, uint8_t) |
| 618 | UN_P422(un_p422_16, uint16_t) | 619 | UN_P422(un_p422_16, uint16_t) |
| 619 | | 620 | |
| 620 | static void fringe_yuv422_repack(struct mp_repack *rp, | 621 | static void pa_p411_8(void *dst, void *src[], int w, uint8_t *c) |
| 621 | struct mp_image *a, int a_x, int a_y, | 622 | { |
| 622 | struct mp_image *b, int b_x, int b_y, int w) | 623 | for (int x = 0; x < w; x += 4) { |
| | 624 | ((uint8_t *)dst)[x / 4 * 6 + c[0]] = ((uint8_t *)src[0])[x + 0]; |
| | 625 | ((uint8_t *)dst)[x / 4 * 6 + c[1]] = ((uint8_t *)src[0])[x + 1]; |
| | 626 | ((uint8_t *)dst)[x / 4 * 6 + c[2]] = ((uint8_t *)src[0])[x + 2]; |
| | 627 | ((uint8_t *)dst)[x / 4 * 6 + c[3]] = ((uint8_t *)src[0])[x + 3]; |
| | 628 | ((uint8_t *)dst)[x / 4 * 6 + c[4]] = ((uint8_t *)src[1])[x >> 2]; |
| | 629 | ((uint8_t *)dst)[x / 4 * 6 + c[5]] = ((uint8_t *)src[2])[x >> 2]; |
| | 630 | } |
| | 631 | } |
| | 632 | |
| | 633 | |
| | 634 | static void un_p411_8(void *src, void *dst[], int w, uint8_t *c) |
| | 635 | { |
| | 636 | for (int x = 0; x < w; x += 4) { |
| | 637 | ((uint8_t *)dst[0])[x + 0] = ((uint8_t *)src)[x / 4 * 6 + c[0]]; |
| | 638 | ((uint8_t *)dst[0])[x + 1] = ((uint8_t *)src)[x / 4 * 6 + c[1]]; |
| | 639 | ((uint8_t *)dst[0])[x + 2] = ((uint8_t *)src)[x / 4 * 6 + c[2]]; |
| | 640 | ((uint8_t *)dst[0])[x + 3] = ((uint8_t *)src)[x / 4 * 6 + c[3]]; |
| | 641 | ((uint8_t *)dst[1])[x >> 2] = ((uint8_t *)src)[x / 4 * 6 + c[4]]; |
| | 642 | ((uint8_t *)dst[2])[x >> 2] = ((uint8_t *)src)[x / 4 * 6 + c[5]]; |
| | 643 | } |
| | 644 | } |
| | 645 | |
| | 646 | static void fringe_yuv_repack(struct mp_repack *rp, |
| | 647 | struct mp_image *a, int a_x, int a_y, |
| | 648 | struct mp_image *b, int b_x, int b_y, int w) |
| 623 | { | 649 | { |
| 624 | void *pa = mp_image_pixel_ptr(a, 0, a_x, a_y); | 650 | void *pa = mp_image_pixel_ptr(a, 0, a_x, a_y); |
| 625 | | 651 | |
| @@ -627,26 +653,18 @@ static void fringe_yuv422_repack(struct mp_repack *rp, · 1 unmodified line |
| 627 | for (int p = 0; p < b->num_planes; p++) | 653 | for (int p = 0; p < b->num_planes; p++) |
| 628 | pb[p] = mp_image_pixel_ptr(b, p, b_x, b_y); | 654 | pb[p] = mp_image_pixel_ptr(b, p, b_x, b_y); |
| 629 | | 655 | |
| 630 | assert(rp->comp_size == 1 || rp->comp_size == 2); | 656 | rp->repack_fringe_yuv(pa, pb, w, rp->comp_map); |
| 631 | | | |
| 632 | void (*repack)(void *a, void *b[], int w, uint8_t *c) = NULL; | | |
| 633 | if (rp->pack) { | | |
| 634 | repack = rp->comp_size == 1 ? pa_p422_8 : pa_p422_16; | | |
| 635 | } else { | | |
| 636 | repack = rp->comp_size == 1 ? un_p422_8 : un_p422_16; | | |
| 637 | } | | |
| 638 | repack(pa, pb, w, rp->comp_map); | | |
| 639 | } | 657 | } |
| 640 | | 658 | |
| 641 | static void setup_fringe_yuv422_packer(struct mp_repack *rp) | 659 | static void setup_fringe_yuv_packer(struct mp_repack *rp) |
| 642 | { | 660 | { |
| 643 | struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(rp->imgfmt_a); | 661 | struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(rp->imgfmt_a); |
| 644 | if (!(desc.flags & MP_IMGFLAG_PACKED_SS_YUV) || | 662 | if (!(desc.flags & MP_IMGFLAG_PACKED_SS_YUV) || |
| 645 | mp_imgfmt_desc_get_num_comps(&desc) != 3 || | 663 | mp_imgfmt_desc_get_num_comps(&desc) != 3 || |
| 646 | desc.align_x != 2) | 664 | desc.align_x > 4) |
| 647 | return; | 665 | return; |
| 648 | | 666 | |
| 649 | uint8_t y_loc[2]; | 667 | uint8_t y_loc[4]; |
| 650 | if (!mp_imgfmt_get_packed_yuv_locations(desc.id, y_loc)) | 668 | if (!mp_imgfmt_get_packed_yuv_locations(desc.id, y_loc)) |
| 651 | return; | 669 | return; |
| 652 | | 670 | |
| @@ -658,7 +676,7 @@ static void setup_fringe_yuv422_packer(struct mp_repack *rp) · 5 unmodified lines |
| 658 | desc.comps[n].offset % desc.comps[0].size) | 676 | desc.comps[n].offset % desc.comps[0].size) |
| 659 | return; | 677 | return; |
| 660 | if (n == 1 || n == 2) { | 678 | if (n == 1 || n == 2) { |
| 661 | rp->comp_map[n - 1 + desc.align_x] = | 679 | rp->comp_map[4 + (n - 1)] = |
| 662 | desc.comps[n].offset / desc.comps[0].size; | 680 | desc.comps[n].offset / desc.comps[0].size; |
| 663 | } | 681 | } |
| 664 | } | 682 | } |
| @@ -668,24 +686,28 @@ static void setup_fringe_yuv422_packer(struct mp_repack *rp) · 3 unmodified lines |
| 668 | rp->comp_map[n] = y_loc[n] / desc.comps[0].size; | 686 | rp->comp_map[n] = y_loc[n] / desc.comps[0].size; |
| 669 | } | 687 | } |
| 670 | | 688 | |
| 671 | int depth = desc.comps[0].size; | 689 | if (desc.comps[0].size == 8 && desc.align_x == 2) { |
| 672 | if (depth != 8 && depth != 16) | 690 | rp->repack_fringe_yuv = rp->pack ? pa_p422_8 : un_p422_8; |
| 673 | return; | 691 | } else if (desc.comps[0].size == 16 && desc.align_x == 2) { |
| | 692 | rp->repack_fringe_yuv = rp->pack ? pa_p422_16 : un_p422_16; |
| | 693 | } else if (desc.comps[0].size == 8 && desc.align_x == 4) { |
| | 694 | rp->repack_fringe_yuv = rp->pack ? pa_p411_8 : un_p411_8; |
| | 695 | } |
| 674 | | 696 | |
| 675 | rp->comp_size = depth / 8u; | 697 | if (!rp->repack_fringe_yuv) |
| 676 | assert(rp->comp_size == 1 || rp->comp_size == 2); | 698 | return; |
| 677 | | 699 | |
| 678 | struct mp_regular_imgfmt yuvfmt = { | 700 | struct mp_regular_imgfmt yuvfmt = { |
| 679 | .component_type = MP_COMPONENT_TYPE_UINT, | 701 | .component_type = MP_COMPONENT_TYPE_UINT, |
| 680 | // NB: same problem with P010 and not clearing padding. | 702 | // NB: same problem with P010 and not clearing padding. |
| 681 | .component_size = rp->comp_size, | 703 | .component_size = desc.comps[0].size / 8u, |
| 682 | .num_planes = 3, | 704 | .num_planes = 3, |
| 683 | .planes = { {1, {1}}, {1, {2}}, {1, {3}} }, | 705 | .planes = { {1, {1}}, {1, {2}}, {1, {3}} }, |
| 684 | .chroma_xs = 1, | 706 | .chroma_xs = desc.chroma_xs, |
| 685 | .chroma_ys = 0, | 707 | .chroma_ys = 0, |
| 686 | }; | 708 | }; |
| 687 | rp->imgfmt_b = mp_find_regular_imgfmt(&yuvfmt); | 709 | rp->imgfmt_b = mp_find_regular_imgfmt(&yuvfmt); |
| 688 | rp->repack = fringe_yuv422_repack; | 710 | rp->repack = fringe_yuv_repack; |
| 689 | | 711 | |
| 690 | if (desc.endian_shift) { | 712 | if (desc.endian_shift) { |
| 691 | rp->endian_size = 1 << desc.endian_shift; | 713 | rp->endian_size = 1 << desc.endian_shift; |
| @@ -913,7 +935,7 @@ static bool setup_format_ne(struct mp_repack *rp) · 221 unmodified lines |
| 913 | if (!rp->imgfmt_b) | 935 | if (!rp->imgfmt_b) |
| 914 | setup_fringe_rgb_packer(rp); | 936 | setup_fringe_rgb_packer(rp); |
| 915 | if (!rp->imgfmt_b) | 937 | if (!rp->imgfmt_b) |
| 916 | setup_fringe_yuv422_packer(rp); | 938 | setup_fringe_yuv_packer(rp); |
| 917 | if (!rp->imgfmt_b) | 939 | if (!rp->imgfmt_b) |
| 918 | rp->imgfmt_b = rp->imgfmt_a; // maybe it was planar after all | 940 | rp->imgfmt_b = rp->imgfmt_a; // maybe it was planar after all |
| 919 | | 941 | |