| @@ -67,9 +67,10 @@ struct mp_repack { · 66 unmodified lines |
| 67 | 67 | |
| 68 | 68 | // Fringe RGB/YUV. |
| 69 | 69 | uint8_t comp_size; |
| 70 | | − uint8_t comp_map[4]; |
| 70 | + uint8_t comp_map[6]; |
| 71 | 71 | uint8_t comp_shifts[3]; |
| 72 | 72 | uint8_t *comp_lut; |
| 73 | + void (*repack_fringe_yuv)(void *dst, void *src[], int w, uint8_t *c); |
| 73 | 74 | |
| 74 | 75 | // F32 repacking. |
| 75 | 76 | int f32_comp_size; |
| @@ -596,8 +597,8 @@ static void setup_misc_packer(struct mp_repack *rp) · 520 unmodified lines |
| 596 | 597 | for (int x = 0; x < w; x += 2) { \ |
| 597 | 598 | ((comp_t *)dst)[x * 2 + c[0]] = ((comp_t *)src[0])[x + 0]; \ |
| 598 | 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[3]] = ((comp_t *)src[2])[x >> 1]; \ |
| 600 | + ((comp_t *)dst)[x * 2 + c[4]] = ((comp_t *)src[1])[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 | 608 | for (int x = 0; x < w; x += 2) { \ |
| 608 | 609 | ((comp_t *)dst[0])[x + 0] = ((comp_t *)src)[x * 2 + c[0]]; \ |
| 609 | 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[2])[x >> 1] = ((comp_t *)src)[x * 2 + c[3]]; \ |
| 611 | + ((comp_t *)dst[1])[x >> 1] = ((comp_t *)src)[x * 2 + c[4]]; \ |
| 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 | 618 | UN_P422(un_p422_8, uint8_t) |
| 618 | 619 | UN_P422(un_p422_16, uint16_t) |
| 619 | 620 | |
| 620 | | −static void fringe_yuv422_repack(struct mp_repack *rp, |
| 621 | | − struct mp_image *a, int a_x, int a_y, |
| 622 | | − struct mp_image *b, int b_x, int b_y, int w) |
| 621 | +static void pa_p411_8(void *dst, void *src[], int w, uint8_t *c) |
| 622 | +{ |
| 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 | 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 | 653 | for (int p = 0; p < b->num_planes; p++) |
| 628 | 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); |
| 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); |
| 656 | + rp->repack_fringe_yuv(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 | 661 | struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(rp->imgfmt_a); |
| 644 | 662 | if (!(desc.flags & MP_IMGFLAG_PACKED_SS_YUV) || |
| 645 | 663 | mp_imgfmt_desc_get_num_comps(&desc) != 3 || |
| 646 | | − desc.align_x != 2) |
| 664 | + desc.align_x > 4) |
| 647 | 665 | return; |
| 648 | 666 | |
| 649 | | − uint8_t y_loc[2]; |
| 667 | + uint8_t y_loc[4]; |
| 650 | 668 | if (!mp_imgfmt_get_packed_yuv_locations(desc.id, y_loc)) |
| 651 | 669 | return; |
| 652 | 670 | |
| @@ -658,7 +676,7 @@ static void setup_fringe_yuv422_packer(struct mp_repack *rp) · 5 unmodified lines |
| 658 | 676 | desc.comps[n].offset % desc.comps[0].size) |
| 659 | 677 | return; |
| 660 | 678 | if (n == 1 || n == 2) { |
| 661 | | − rp->comp_map[n - 1 + desc.align_x] = |
| 679 | + rp->comp_map[4 + (n - 1)] = |
| 662 | 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 | 686 | rp->comp_map[n] = y_loc[n] / desc.comps[0].size; |
| 669 | 687 | } |
| 670 | 688 | |
| 671 | | − int depth = desc.comps[0].size; |
| 672 | | − if (depth != 8 && depth != 16) |
| 673 | | − return; |
| 689 | + if (desc.comps[0].size == 8 && desc.align_x == 2) { |
| 690 | + rp->repack_fringe_yuv = rp->pack ? pa_p422_8 : un_p422_8; |
| 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; |
| 676 | | − assert(rp->comp_size == 1 || rp->comp_size == 2); |
| 697 | + if (!rp->repack_fringe_yuv) |
| 698 | + return; |
| 677 | 699 | |
| 678 | 700 | struct mp_regular_imgfmt yuvfmt = { |
| 679 | 701 | .component_type = MP_COMPONENT_TYPE_UINT, |
| 680 | 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 | 704 | .num_planes = 3, |
| 683 | 705 | .planes = { {1, {1}}, {1, {2}}, {1, {3}} }, |
| 684 | | − .chroma_xs = 1, |
| 706 | + .chroma_xs = desc.chroma_xs, |
| 685 | 707 | .chroma_ys = 0, |
| 686 | 708 | }; |
| 687 | 709 | rp->imgfmt_b = mp_find_regular_imgfmt(&yuvfmt); |
| 688 | | − rp->repack = fringe_yuv422_repack; |
| 710 | + rp->repack = fringe_yuv_repack; |
| 689 | 711 | |
| 690 | 712 | if (desc.endian_shift) { |
| 691 | 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 | 935 | if (!rp->imgfmt_b) |
| 914 | 936 | setup_fringe_rgb_packer(rp); |
| 915 | 937 | if (!rp->imgfmt_b) |
| 916 | | − setup_fringe_yuv422_packer(rp); |
| 938 | + setup_fringe_yuv_packer(rp); |
| 917 | 939 | if (!rp->imgfmt_b) |
| 918 | 940 | rp->imgfmt_b = rp->imgfmt_a; // maybe it was planar after all |
| 919 | 941 | |