History

video: add AV_PIX_FMT_UYYVYY411 conversion support

It may be completely useless, and I can't verify it as no known samples or other known/accessible software using it, but why not? Putting this together with he 422 code requires making it slightly more generic. I'm still staying with a "huge" if tree instead of a table to select the scanline worker callback, because it's actually small and not huge (although it not being generic still feels slightly painful).

wm4 committed 6 years ago

Commit 320fa3b1 parent 756ae034 files · +60 −34Browse files

Unified · Split

4 files
  1. test/ref/repack.txt +2 −1
  2. test/ref/zimg_formats.txt +1 −1
  3. test/repack.c +5 −2
  4. video/repack.c +52 −30
test/ref/repack.txt+2−1
@@ -200,7 +200,8 @@ rgba64be => [pa] [un] gbrap16 | a=1:1 [tu] [tp] · 199 unmodified lines
200rgba64be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]200rgba64be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
201uyvy422 => [pa] [un] yuv422p | a=2:1 [tu] [tp]201uyvy422 => [pa] [un] yuv422p | a=2:1 [tu] [tp]
202uyvy422 => [pa] [un] yuv422pf | a=2:1 [planar-f32]202uyvy422 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
203uyyvyy411 => no203uyyvyy411 => [pa] [un] yuv411p | a=4:1 [tu] [tp]
204uyyvyy411 => [pa] [un] yuv411pf | a=4:1 [planar-f32]
204vaapi => no205vaapi => no
205vaapi_idct => no206vaapi_idct => no
206vaapi_moco => no207vaapi_moco => no
test/ref/zimg_formats.txt+1−1
@@ -115,7 +115,7 @@ · 114 unmodified lines
115 rgba64 Zin Zout SWSin SWSout |115 rgba64 Zin Zout SWSin SWSout |
116 rgba64be Zin Zout SWSin SWSout |116 rgba64be Zin Zout SWSin SWSout |
117 uyvy422 Zin Zout SWSin SWSout |117 uyvy422 Zin Zout SWSin SWSout |
118 uyyvyy411 |118 uyyvyy411 Zin Zout |
119 vaapi |119 vaapi |
120 vaapi_idct |120 vaapi_idct |
121 vaapi_moco |121 vaapi_moco |
test/repack.c+5−2
@@ -141,8 +141,8 @@ static const struct entry repack_tests[] = { · 140 unmodified lines
141 -AV_PIX_FMT_YUVA444P16, {P16(2), P16(3), P16(4), P16(1)}},141 -AV_PIX_FMT_YUVA444P16, {P16(2), P16(3), P16(4), P16(1)}},
142 {1, 1, -AV_PIX_FMT_AYUV64BE, {P16(0x0100, 0x0200, 0x0300, 0x0400)},142 {1, 1, -AV_PIX_FMT_AYUV64BE, {P16(0x0100, 0x0200, 0x0300, 0x0400)},
143 -AV_PIX_FMT_YUVA444P16, {P16(2), P16(3), P16(4), P16(1)}},143 -AV_PIX_FMT_YUVA444P16, {P16(2), P16(3), P16(4), P16(1)}},
144 {2, 1, -AV_PIX_FMT_YUYV422, {P8(1, 2, 3, 4)},144 {4, 1, -AV_PIX_FMT_YUYV422, {P8(1, 2, 3, 4, 5, 6, 7, 8)},
145 -AV_PIX_FMT_YUV422P, {P8(1, 3), P8(2), P8(4)}},145 -AV_PIX_FMT_YUV422P, {P8(1, 3, 5, 7), P8(2, 6), P8(4, 8)}},
146 {2, 1, -AV_PIX_FMT_YVYU422, {P8(1, 2, 3, 4)},146 {2, 1, -AV_PIX_FMT_YVYU422, {P8(1, 2, 3, 4)},
147 -AV_PIX_FMT_YUV422P, {P8(1, 3), P8(4), P8(2)}},147 -AV_PIX_FMT_YUV422P, {P8(1, 3), P8(4), P8(2)}},
148 {2, 1, -AV_PIX_FMT_UYVY422, {P8(1, 2, 3, 4)},148 {2, 1, -AV_PIX_FMT_UYVY422, {P8(1, 2, 3, 4)},
@@ -159,6 +159,9 @@ static const struct entry repack_tests[] = { · 10 unmodified lines
159 P16(0x4a4b)},159 P16(0x4a4b)},
160 -AV_PIX_FMT_YUV422P16, {P16(0x1b1a, 0x2b2a), P16(0x3b3a),160 -AV_PIX_FMT_YUV422P16, {P16(0x1b1a, 0x2b2a), P16(0x3b3a),
161 P16(0x4b4a)}},161 P16(0x4b4a)}},
162 {8, 1, -AV_PIX_FMT_UYYVYY411, {P8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)},
163 -AV_PIX_FMT_YUV411P, {P8(2, 3, 5, 6, 8, 9, 11, 12),
164 P8(1, 7), P8(4, 10)}},
162};165};
163 166
164static bool is_true_planar(int imgfmt)167static bool is_true_planar(int imgfmt)
video/repack.c+52−30
@@ -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
617UN_P422(un_p422_8, uint8_t)618UN_P422(un_p422_8, uint8_t)
618UN_P422(un_p422_16, uint16_t)619UN_P422(un_p422_16, uint16_t)
619 620
620static void fringe_yuv422_repack(struct mp_repack *rp,621static 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
634static 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
646static 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
641static void setup_fringe_yuv422_packer(struct mp_repack *rp)659static 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 all940 rp->imgfmt_b = rp->imgfmt_a; // maybe it was planar after all
919 941

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t