mirror of
https://github.com/mpv-player/mpv
synced 2024-12-18 21:06:00 +00:00
video: shuffle imgfmt metadata code around
I guess I decided to stuff it all into mp_imgfmt_desc (the "old" struct). This is probably a mistake. At first I was afraid that this struct would get too fat (probably justified, and hereby happened), but on the other hand mp_imgfmt_get_desc() (which builds the struct) calls the former mp_imgfmt_get_layout(), and the separation doesn't make too much sense anyway. Just merge them. Still, try to keep out the extra info for packed YUV bullshit. I think the result is OK, and there's as much information as there was before. The test output changes a little. There's no independent bits[] array anymore, so formats which did not previously have set this now show it. (These formats are mpv-only and are still missing the metadata. To be added later). Also, the output for the cursed packed formats changes.
This commit is contained in:
parent
a20ae0417f
commit
176f422213
@ -110,17 +110,12 @@ static void run(struct test_ctx *ctx)
|
||||
fprintf(f, " [NODESC]\n");
|
||||
}
|
||||
|
||||
struct mp_imgfmt_layout pd;
|
||||
mp_imgfmt_get_layout(mpfmt, &pd);
|
||||
|
||||
for (int n = 0; n < d.num_planes; n++) {
|
||||
fprintf(f, " %d: %dbits", n, pd.bits[n]);
|
||||
if (pd.extra_w)
|
||||
fprintf(f, " w=%d", pd.extra_w + 1);
|
||||
if (pd.endian_bytes)
|
||||
fprintf(f, " endian_bytes=%d", pd.endian_bytes);
|
||||
fprintf(f, " %d: %dbits", n, d.bpp[n]);
|
||||
if (d.endian_shift)
|
||||
fprintf(f, " endian_bytes=%d", 1 << d.endian_shift);
|
||||
for (int x = 0; x < MP_NUM_COMPONENTS; x++) {
|
||||
struct mp_imgfmt_comp_desc cm = pd.comps[x];
|
||||
struct mp_imgfmt_comp_desc cm = d.comps[x];
|
||||
fprintf(f, " {");
|
||||
if (cm.plane == n) {
|
||||
if (cm.size) {
|
||||
@ -133,12 +128,22 @@ static void run(struct test_ctx *ctx)
|
||||
}
|
||||
}
|
||||
fprintf(f, "}");
|
||||
if (!(d.flags & (MP_IMGFLAG_PACKED_SS_YUV | MP_IMGFLAG_HAS_COMPS)))
|
||||
{
|
||||
assert(cm.size == 0);
|
||||
assert(cm.offset == 0);
|
||||
assert(cm.pad == 0);
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
if (pd.extra_w) {
|
||||
fprintf(f, " extra_luma_offsets=[");
|
||||
for (int x = 0; x < pd.extra_w; x++)
|
||||
fprintf(f, " %d", pd.extra_luma_offsets[x]);
|
||||
if (d.flags & MP_IMGFLAG_PACKED_SS_YUV) {
|
||||
assert(!(d.flags & MP_IMGFLAG_HAS_COMPS));
|
||||
uint8_t offsets[10];
|
||||
bool r = mp_imgfmt_get_packed_yuv_locations(mpfmt, offsets);
|
||||
assert(r);
|
||||
fprintf(f, " luma_offsets=[");
|
||||
for (int x = 0; x < d.align_x; x++)
|
||||
fprintf(f, " %d", offsets[x]);
|
||||
fprintf(f, "]\n");
|
||||
}
|
||||
}
|
||||
|
@ -517,9 +517,9 @@ gbrp1: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
2: 8bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=1 bitpad=-7 chroma=1x1 ctype=uint
|
||||
0: {2}
|
||||
1: {3}
|
||||
@ -632,9 +632,9 @@ gbrp2: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
2: 8bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=1 bitpad=-6 chroma=1x1 ctype=uint
|
||||
0: {2}
|
||||
1: {3}
|
||||
@ -643,9 +643,9 @@ gbrp3: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
2: 8bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=1 bitpad=-5 chroma=1x1 ctype=uint
|
||||
0: {2}
|
||||
1: {3}
|
||||
@ -654,9 +654,9 @@ gbrp4: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
2: 8bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=1 bitpad=-4 chroma=1x1 ctype=uint
|
||||
0: {2}
|
||||
1: {3}
|
||||
@ -665,9 +665,9 @@ gbrp5: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
2: 8bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=1 bitpad=-3 chroma=1x1 ctype=uint
|
||||
0: {2}
|
||||
1: {3}
|
||||
@ -676,9 +676,9 @@ gbrp6: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
2: 8bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=1 bitpad=-2 chroma=1x1 ctype=uint
|
||||
0: {2}
|
||||
1: {3}
|
||||
@ -828,8 +828,8 @@ grayaf32: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=2, chroma=0:0 align=1:1
|
||||
{32/[0:0] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
Regular: planes=2 compbytes=4 bitpad=0 chroma=1x1 ctype=float
|
||||
0: {1}
|
||||
1: {4}
|
||||
@ -1190,8 +1190,8 @@ uyvy422: ctype=uint
|
||||
Basic desc: [ba][yuv][le][be]
|
||||
planes=1, chroma=1:0 align=2:1
|
||||
{16/[0:0] }
|
||||
0: 32bits w=2 {8:8} {0:8} {16:8} {}
|
||||
extra_luma_offsets=[ 24]
|
||||
0: 16bits {8:8} {0:8} {16:8} {}
|
||||
luma_offsets=[ 8 24]
|
||||
AVD: name=uyvy422 chroma=1:0 flags=0x0
|
||||
0: p=0 st=2 o=1 sh=0 d=8
|
||||
1: p=0 st=4 o=0 sh=0 d=8
|
||||
@ -1200,8 +1200,8 @@ uyyvyy411: [GENERIC] ctype=uint
|
||||
Basic desc: [yuv][le][be]
|
||||
planes=1, chroma=2:0 align=4:1
|
||||
{12/[0:0] }
|
||||
0: 48bits w=4 {8:8} {0:8} {24:8} {}
|
||||
extra_luma_offsets=[ 16 32 40]
|
||||
0: 12bits {8:8} {0:8} {24:8} {}
|
||||
luma_offsets=[ 8 16 32 40]
|
||||
AVD: name=uyyvyy411 chroma=2:0 flags=0x0
|
||||
0: p=0 st=4 o=1 sh=0 d=8
|
||||
1: p=0 st=6 o=0 sh=0 d=8
|
||||
@ -1269,15 +1269,15 @@ y1: fcsp=rgb ctype=uint
|
||||
Basic desc: [ba][rgb][le]
|
||||
planes=1, chroma=0:0 align=1:1
|
||||
{8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
Regular: planes=1 compbytes=1 bitpad=-7 chroma=1x1 ctype=uint
|
||||
0: {1}
|
||||
y210: [GENERIC] ctype=uint
|
||||
Basic desc: [ba][yuv][le]
|
||||
planes=1, chroma=1:0 align=2:1
|
||||
{32/[0:0] }
|
||||
0: 64bits w=2 {0:16/6} {16:16/6} {48:16/6} {}
|
||||
extra_luma_offsets=[ 32]
|
||||
0: 32bits {0:16/6} {16:16/6} {48:16/6} {}
|
||||
luma_offsets=[ 0 32]
|
||||
AVD: name=y210le chroma=1:0 flags=0x0
|
||||
0: p=0 st=4 o=0 sh=6 d=10
|
||||
1: p=0 st=8 o=2 sh=6 d=10
|
||||
@ -1286,8 +1286,8 @@ y210be: [GENERIC] ctype=uint
|
||||
Basic desc: [ba][yuv][be]
|
||||
planes=1, chroma=1:0 align=2:1
|
||||
{32/[0:0] }
|
||||
0: 64bits w=2 endian_bytes=2 {0:16/6} {16:16/6} {48:16/6} {}
|
||||
extra_luma_offsets=[ 32]
|
||||
0: 32bits endian_bytes=2 {0:16/6} {16:16/6} {48:16/6} {}
|
||||
luma_offsets=[ 0 32]
|
||||
AVD: name=y210be chroma=1:0 flags=0x1 [be]
|
||||
0: p=0 st=4 o=0 sh=6 d=10
|
||||
1: p=0 st=8 o=2 sh=6 d=10
|
||||
@ -1324,8 +1324,8 @@ yap16: ctype=uint
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=2, chroma=0:0 align=1:1
|
||||
{16/[0:0] 16/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
0: 16bits {} {} {} {}
|
||||
1: 16bits {} {} {} {}
|
||||
Regular: planes=2 compbytes=2 bitpad=0 chroma=1x1 ctype=uint
|
||||
0: {1}
|
||||
1: {4}
|
||||
@ -1333,8 +1333,8 @@ yap8: ctype=uint
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=2, chroma=0:0 align=1:1
|
||||
{8/[0:0] 8/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
0: 8bits {} {} {} {}
|
||||
1: 8bits {} {} {} {}
|
||||
Regular: planes=2 compbytes=1 bitpad=0 chroma=1x1 ctype=uint
|
||||
0: {1}
|
||||
1: {4}
|
||||
@ -1357,9 +1357,9 @@ yuv410pf: ctype=float
|
||||
Basic desc: [ba][yuvp][yuv][le]
|
||||
planes=3, chroma=2:2 align=4:4
|
||||
{32/[0:0] 32/[2:2] 32/[2:2] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=4 bitpad=0 chroma=4x4 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1383,9 +1383,9 @@ yuv411pf: ctype=float
|
||||
Basic desc: [ba][yuvp][yuv][le]
|
||||
planes=3, chroma=2:0 align=4:1
|
||||
{32/[0:0] 32/[2:0] 32/[2:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=4 bitpad=0 chroma=4x1 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1540,9 +1540,9 @@ yuv420pf: ctype=float
|
||||
Basic desc: [ba][yuvp][yuv][le]
|
||||
planes=3, chroma=1:1 align=2:2
|
||||
{32/[0:0] 32/[1:1] 32/[1:1] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=4 bitpad=0 chroma=2x2 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1696,9 +1696,9 @@ yuv422pf: ctype=float
|
||||
Basic desc: [ba][yuvp][yuv][le]
|
||||
planes=3, chroma=1:0 align=2:1
|
||||
{32/[0:0] 32/[1:0] 32/[1:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=4 bitpad=0 chroma=2x1 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1774,9 +1774,9 @@ yuv440pf: ctype=float
|
||||
Basic desc: [ba][yuvp][yuv][le]
|
||||
planes=3, chroma=0:1 align=1:2
|
||||
{32/[0:0] 32/[0:1] 32/[0:1] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=4 bitpad=0 chroma=1x2 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1931,9 +1931,9 @@ yuv444pf: ctype=float
|
||||
Basic desc: [ba][yuvp][yuv][le]
|
||||
planes=3, chroma=0:0 align=1:1
|
||||
{32/[0:0] 32/[0:0] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
Regular: planes=3 compbytes=4 bitpad=0 chroma=1x1 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1942,10 +1942,10 @@ yuva410pf: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=4, chroma=2:2 align=4:4
|
||||
{32/[0:0] 32/[2:2] 32/[2:2] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
3: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
3: 32bits {} {} {} {}
|
||||
Regular: planes=4 compbytes=4 bitpad=0 chroma=4x4 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -1955,10 +1955,10 @@ yuva411pf: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=4, chroma=2:0 align=4:1
|
||||
{32/[0:0] 32/[2:0] 32/[2:0] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
3: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
3: 32bits {} {} {} {}
|
||||
Regular: planes=4 compbytes=4 bitpad=0 chroma=4x1 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -2079,10 +2079,10 @@ yuva420pf: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=4, chroma=1:1 align=2:2
|
||||
{32/[0:0] 32/[1:1] 32/[1:1] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
3: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
3: 32bits {} {} {} {}
|
||||
Regular: planes=4 compbytes=4 bitpad=0 chroma=2x2 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -2234,10 +2234,10 @@ yuva422pf: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=4, chroma=1:0 align=2:1
|
||||
{32/[0:0] 32/[1:0] 32/[1:0] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
3: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
3: 32bits {} {} {} {}
|
||||
Regular: planes=4 compbytes=4 bitpad=0 chroma=2x1 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -2247,10 +2247,10 @@ yuva440pf: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=4, chroma=0:1 align=1:2
|
||||
{32/[0:0] 32/[0:1] 32/[0:1] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
3: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
3: 32bits {} {} {} {}
|
||||
Regular: planes=4 compbytes=4 bitpad=0 chroma=1x2 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -2402,10 +2402,10 @@ yuva444pf: ctype=float
|
||||
Basic desc: [ba][a][yuvp][yuv][le]
|
||||
planes=4, chroma=0:0 align=1:1
|
||||
{32/[0:0] 32/[0:0] 32/[0:0] 32/[0:0] }
|
||||
0: 0bits {} {} {} {}
|
||||
1: 0bits {} {} {} {}
|
||||
2: 0bits {} {} {} {}
|
||||
3: 0bits {} {} {} {}
|
||||
0: 32bits {} {} {} {}
|
||||
1: 32bits {} {} {} {}
|
||||
2: 32bits {} {} {} {}
|
||||
3: 32bits {} {} {} {}
|
||||
Regular: planes=4 compbytes=4 bitpad=0 chroma=1x1 ctype=float
|
||||
0: {1}
|
||||
1: {2}
|
||||
@ -2460,8 +2460,8 @@ yuyv422: [GENERIC] ctype=uint
|
||||
Basic desc: [ba][yuv][le][be]
|
||||
planes=1, chroma=1:0 align=2:1
|
||||
{16/[0:0] }
|
||||
0: 32bits w=2 {0:8} {8:8} {24:8} {}
|
||||
extra_luma_offsets=[ 16]
|
||||
0: 16bits {0:8} {8:8} {24:8} {}
|
||||
luma_offsets=[ 0 16]
|
||||
AVD: name=yuyv422 chroma=1:0 flags=0x0
|
||||
0: p=0 st=2 o=0 sh=0 d=8
|
||||
1: p=0 st=4 o=1 sh=0 d=8
|
||||
@ -2470,8 +2470,8 @@ yvyu422: [GENERIC] ctype=uint
|
||||
Basic desc: [ba][yuv][le][be]
|
||||
planes=1, chroma=1:0 align=2:1
|
||||
{16/[0:0] }
|
||||
0: 32bits w=2 {0:8} {24:8} {8:8} {}
|
||||
extra_luma_offsets=[ 16]
|
||||
0: 16bits {0:8} {24:8} {8:8} {}
|
||||
luma_offsets=[ 0 16]
|
||||
AVD: name=yvyu422 chroma=1:0 flags=0x0
|
||||
0: p=0 st=2 o=0 sh=0 d=8
|
||||
1: p=0 st=4 o=3 sh=0 d=8
|
||||
|
@ -35,8 +35,6 @@ struct mp_imgfmt_entry {
|
||||
struct mp_imgfmt_desc desc;
|
||||
// valid if reg_desc.component_size is set
|
||||
struct mp_regular_imgfmt reg_desc;
|
||||
// valid if bits!=0
|
||||
struct mp_imgfmt_layout layout;
|
||||
// valid if non-0 and no reg_desc
|
||||
enum mp_csp forced_csp;
|
||||
enum mp_component_type ctype;
|
||||
@ -74,13 +72,14 @@ static const struct mp_imgfmt_entry mp_imgfmt_list[] = {
|
||||
.desc = {
|
||||
.id = IMGFMT_RGB30,
|
||||
.avformat = AV_PIX_FMT_NONE,
|
||||
.flags = MP_IMGFLAG_BYTE_ALIGNED | MP_IMGFLAG_NE | MP_IMGFLAG_RGB,
|
||||
.flags = MP_IMGFLAG_BYTE_ALIGNED | MP_IMGFLAG_NE | MP_IMGFLAG_RGB |
|
||||
MP_IMGFLAG_HAS_COMPS,
|
||||
.num_planes = 1,
|
||||
.align_x = 1,
|
||||
.align_y = 1,
|
||||
.bpp = {32},
|
||||
.comps = { {0, 20, 10}, {0, 10, 10}, {0, 0, 10} },
|
||||
},
|
||||
.layout = { {32}, { {0, 20, 10}, {0, 10, 10}, {0, 0, 10} } },
|
||||
.forced_csp = MP_CSP_RGB,
|
||||
.ctype = MP_COMPONENT_TYPE_UINT,
|
||||
},
|
||||
@ -229,23 +228,12 @@ static struct mp_imgfmt_desc to_legacy_desc(int fmt, struct mp_regular_imgfmt re
|
||||
return desc;
|
||||
}
|
||||
|
||||
void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
static void fill_pixdesc_layout(struct mp_imgfmt_desc *desc,
|
||||
enum AVPixelFormat fmt,
|
||||
const AVPixFmtDescriptor *pd)
|
||||
{
|
||||
const struct mp_imgfmt_entry *mpdesc = get_mp_desc(mpfmt);
|
||||
if (mpdesc && mpdesc->reg_desc.component_size) {
|
||||
*p_desc = (struct mp_imgfmt_layout){{0}};
|
||||
return;
|
||||
}
|
||||
if (mpdesc && mpdesc->layout.bits) {
|
||||
*p_desc = mpdesc->layout;
|
||||
return;
|
||||
}
|
||||
|
||||
enum AVPixelFormat fmt = imgfmt2pixfmt(mpfmt);
|
||||
const AVPixFmtDescriptor *pd = av_pix_fmt_desc_get(fmt);
|
||||
if (!pd ||
|
||||
(pd->flags & AV_PIX_FMT_FLAG_PAL) ||
|
||||
(pd->flags & AV_PIX_FMT_FLAG_HWACCEL))
|
||||
if (pd->flags & AV_PIX_FMT_FLAG_PAL ||
|
||||
pd->flags & AV_PIX_FMT_FLAG_HWACCEL)
|
||||
goto fail;
|
||||
|
||||
bool has_alpha = pd->flags & AV_PIX_FMT_FLAG_ALPHA;
|
||||
@ -253,8 +241,6 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
pd->nb_components != 3 + has_alpha)
|
||||
goto fail;
|
||||
|
||||
struct mp_imgfmt_layout desc = {0};
|
||||
|
||||
// Very convenient: we assume we're always on little endian, and FFmpeg
|
||||
// explicitly marks big endian formats => don't need to guess whether a
|
||||
// format is little endian, or not affected by byte order.
|
||||
@ -262,14 +248,11 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
|
||||
// Packed sub-sampled YUV is very... special.
|
||||
bool is_packed_ss_yuv = pd->log2_chroma_w && !pd->log2_chroma_h &&
|
||||
(1 << pd->log2_chroma_w) <= MP_ARRAY_SIZE(desc.extra_luma_offsets) + 1 &&
|
||||
pd->comp[1].plane == 0 && pd->comp[2].plane == 0 &&
|
||||
pd->nb_components == 3;
|
||||
|
||||
if (is_packed_ss_yuv) {
|
||||
desc.extra_w = (1 << pd->log2_chroma_w) - 1;
|
||||
desc.bits[0] = pd->comp[1].step * 8;
|
||||
}
|
||||
if (is_packed_ss_yuv)
|
||||
desc->bpp[0] = pd->comp[1].step * 8;
|
||||
|
||||
int num_planes = 0;
|
||||
int el_bits = (pd->flags & AV_PIX_FMT_FLAG_BITSTREAM) ? 1 : 8;
|
||||
@ -280,7 +263,7 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
|
||||
num_planes = MPMAX(num_planes, d->plane + 1);
|
||||
|
||||
int plane_bits = desc.bits[d->plane];
|
||||
int plane_bits = desc->bpp[d->plane];
|
||||
int c_bits = d->step * el_bits;
|
||||
|
||||
// The first component wins, because either all components result in
|
||||
@ -289,7 +272,7 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
if (c_bits > plane_bits)
|
||||
goto fail; // inconsistent
|
||||
} else {
|
||||
desc.bits[d->plane] = plane_bits = c_bits;
|
||||
desc->bpp[d->plane] = plane_bits = c_bits;
|
||||
}
|
||||
|
||||
int shift = d->shift;
|
||||
@ -323,21 +306,24 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
if (is_be && word == 1) {
|
||||
// Probably packed RGB formats with varying word sizes. Assume
|
||||
// the word access size is the entire pixel.
|
||||
if (plane_bits % 8 || plane_bits >= 64)
|
||||
int logend = mp_log2(plane_bits) - 3;
|
||||
if (!MP_IS_POWER_OF_2(plane_bits) || logend < 0 || logend > 3)
|
||||
goto fail;
|
||||
if (!desc.endian_bytes)
|
||||
desc.endian_bytes = plane_bits / 8;
|
||||
if (desc.endian_bytes != plane_bits / 8)
|
||||
if (!desc->endian_shift)
|
||||
desc->endian_shift = logend;
|
||||
if (desc->endian_shift != logend)
|
||||
goto fail;
|
||||
offset = desc.endian_bytes * 8 - 8 - offset;
|
||||
offset = (1 << desc->endian_shift) * 8 - 8 - offset;
|
||||
}
|
||||
if (is_be && word > 1) {
|
||||
if (desc.endian_bytes && desc.endian_bytes != word)
|
||||
int logend = mp_log2(word);
|
||||
if (desc->endian_shift && desc->endian_shift != logend)
|
||||
goto fail; // fortunately not needed/never happens
|
||||
if (word >= 64)
|
||||
if (logend > 3)
|
||||
goto fail;
|
||||
desc.endian_bytes = word;
|
||||
desc->endian_shift = logend;
|
||||
}
|
||||
|
||||
// We always use bit offsets; this doesn't lose any information,
|
||||
// and pixdesc is merely more redundant.
|
||||
offset += shift;
|
||||
@ -347,7 +333,7 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
goto fail;
|
||||
if (d->depth < 0 || d->depth >= (1 << 6))
|
||||
goto fail;
|
||||
desc.comps[c] = (struct mp_imgfmt_comp_desc){
|
||||
desc->comps[c] = (struct mp_imgfmt_comp_desc){
|
||||
.plane = d->plane,
|
||||
.offset = offset,
|
||||
.size = d->depth,
|
||||
@ -355,15 +341,15 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
}
|
||||
|
||||
for (int p = 0; p < num_planes; p++) {
|
||||
if (!desc.bits[p])
|
||||
if (!desc->bpp[p])
|
||||
goto fail; // plane doesn't exist
|
||||
}
|
||||
|
||||
// What the fuck: this is probably a pixdesc bug, so fix it.
|
||||
if (fmt == AV_PIX_FMT_RGB8) {
|
||||
desc.comps[2] = (struct mp_imgfmt_comp_desc){0, 0, 2};
|
||||
desc.comps[1] = (struct mp_imgfmt_comp_desc){0, 2, 3};
|
||||
desc.comps[0] = (struct mp_imgfmt_comp_desc){0, 5, 3};
|
||||
desc->comps[2] = (struct mp_imgfmt_comp_desc){0, 0, 2};
|
||||
desc->comps[1] = (struct mp_imgfmt_comp_desc){0, 2, 3};
|
||||
desc->comps[0] = (struct mp_imgfmt_comp_desc){0, 5, 3};
|
||||
}
|
||||
|
||||
// Overlap test. If any shared bits are happening, this is not a format we
|
||||
@ -373,8 +359,8 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
bool any_shared_bytes = false;
|
||||
for (int c = 0; c < pd->nb_components; c++) {
|
||||
for (int i = 0; i < c; i++) {
|
||||
struct mp_imgfmt_comp_desc *c1 = &desc.comps[c];
|
||||
struct mp_imgfmt_comp_desc *c2 = &desc.comps[i];
|
||||
struct mp_imgfmt_comp_desc *c1 = &desc->comps[c];
|
||||
struct mp_imgfmt_comp_desc *c2 = &desc->comps[i];
|
||||
if (c1->plane == c2->plane) {
|
||||
if (c1->offset + c1->size > c2->offset &&
|
||||
c2->offset + c2->size > c1->offset)
|
||||
@ -388,7 +374,7 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
|
||||
if (any_shared_bits) {
|
||||
for (int c = 0; c < pd->nb_components; c++)
|
||||
desc.comps[c] = (struct mp_imgfmt_comp_desc){0};
|
||||
desc->comps[c] = (struct mp_imgfmt_comp_desc){0};
|
||||
}
|
||||
|
||||
// Many important formats have padding within an access word. For example
|
||||
@ -400,7 +386,7 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
// guaranteed 0 padding. This could fail, but nobody said this pixdesc crap
|
||||
// is robust.
|
||||
for (int c = 0; c < pd->nb_components; c++) {
|
||||
struct mp_imgfmt_comp_desc *cd = &desc.comps[c];
|
||||
struct mp_imgfmt_comp_desc *cd = &desc->comps[c];
|
||||
// Note: rgb444 would defeat our heuristic if we checked only per comp.
|
||||
// also, exclude "bitstream" formats due to monow/monob
|
||||
int fsize = MP_ALIGN_UP(cd->size, 8);
|
||||
@ -418,59 +404,30 @@ void mp_imgfmt_get_layout(int mpfmt, struct mp_imgfmt_layout *p_desc)
|
||||
}
|
||||
}
|
||||
|
||||
if (is_packed_ss_yuv) {
|
||||
if (num_planes > 1)
|
||||
goto fail;
|
||||
// Guess at which positions the additional luma samples are. We iterate
|
||||
// starting with the first byte, and then put a luma sample at places
|
||||
// not covered by other luma/chroma.
|
||||
// Pixdesc does not and can not provide this information. This heuristic
|
||||
// may fail in certain cases. What a load of bullshit, right?
|
||||
int lsize = desc.comps[0].size;
|
||||
int cur_offset = 0;
|
||||
for (int lsample = 1; lsample < (1 << pd->log2_chroma_w); lsample++) {
|
||||
while (1) {
|
||||
if (cur_offset + lsize > desc.bits[0])
|
||||
goto fail;
|
||||
bool free = true;
|
||||
for (int c = 0; c < pd->nb_components; c++) {
|
||||
struct mp_imgfmt_comp_desc *cd = &desc.comps[c];
|
||||
if (!cd->size)
|
||||
continue;
|
||||
if (cd->offset + cd->size > cur_offset &&
|
||||
cur_offset + lsize > cd->offset)
|
||||
{
|
||||
free = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (free)
|
||||
break;
|
||||
cur_offset += lsize;
|
||||
}
|
||||
desc.extra_luma_offsets[lsample - 1] = cur_offset;
|
||||
cur_offset += lsize;
|
||||
}
|
||||
}
|
||||
|
||||
// The alpha component always has ID 4 (index 3) in our representation, so
|
||||
// move the alpha component to there.
|
||||
if (has_alpha && pd->nb_components < 4) {
|
||||
desc.comps[3] = desc.comps[pd->nb_components - 1];
|
||||
desc.comps[pd->nb_components - 1] = (struct mp_imgfmt_comp_desc){0};
|
||||
desc->comps[3] = desc->comps[pd->nb_components - 1];
|
||||
desc->comps[pd->nb_components - 1] = (struct mp_imgfmt_comp_desc){0};
|
||||
}
|
||||
|
||||
if (is_packed_ss_yuv) {
|
||||
desc->flags |= MP_IMGFLAG_PACKED_SS_YUV;
|
||||
desc->bpp[0] /= 1 << pd->log2_chroma_w;
|
||||
} else {
|
||||
desc->flags |= MP_IMGFLAG_HAS_COMPS;
|
||||
}
|
||||
|
||||
*p_desc = desc;
|
||||
return;
|
||||
|
||||
fail:
|
||||
*p_desc = (struct mp_imgfmt_layout){{0}};
|
||||
for (int n = 0; n < 4; n++)
|
||||
desc->comps[n] = (struct mp_imgfmt_comp_desc){0};
|
||||
// Average bit size fallback.
|
||||
int num_av_planes = av_pix_fmt_count_planes(fmt);
|
||||
for (int p = 0; p < num_av_planes; p++) {
|
||||
int ls = av_image_get_linesize(fmt, 256, p);
|
||||
if (ls > 0)
|
||||
p_desc->bits[p] = ls * 8 / 256;
|
||||
desc->bpp[p] = ls > 0 ? ls * 8 / 256 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,22 +455,30 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
for (int c = 0; c < pd->nb_components; c++)
|
||||
desc.num_planes = MPMAX(desc.num_planes, pd->comp[c].plane + 1);
|
||||
|
||||
struct mp_imgfmt_layout layout;
|
||||
mp_imgfmt_get_layout(mpfmt, &layout);
|
||||
for (int p = 0; p < desc.num_planes; p++) {
|
||||
desc.xs[p] = (p == 1 || p == 2) ? desc.chroma_xs : 0;
|
||||
desc.ys[p] = (p == 1 || p == 2) ? desc.chroma_ys : 0;
|
||||
}
|
||||
|
||||
desc.align_x = 1 << desc.chroma_xs;
|
||||
desc.align_y = 1 << desc.chroma_ys;
|
||||
|
||||
fill_pixdesc_layout(&desc, fmt, pd);
|
||||
|
||||
if (desc.bpp[0] % 8u && (pd->flags & AV_PIX_FMT_FLAG_BITSTREAM))
|
||||
desc.align_x = 8 / desc.bpp[0]; // expect power of 2
|
||||
|
||||
bool is_ba = desc.num_planes > 0;
|
||||
for (int p = 0; p < desc.num_planes; p++) {
|
||||
desc.bpp[p] = layout.bits[p] / (layout.extra_w + 1);
|
||||
for (int p = 0; p < desc.num_planes; p++)
|
||||
is_ba = !(desc.bpp[p] % 8u);
|
||||
}
|
||||
|
||||
if (is_ba)
|
||||
desc.flags |= MP_IMGFLAG_BYTE_ALIGNED;
|
||||
|
||||
// Very heuristical.
|
||||
bool is_be = layout.endian_bytes > 0;
|
||||
bool need_endian = (layout.comps[0].size % 8u && layout.bits[0] > 8) ||
|
||||
layout.comps[0].size > 8;
|
||||
bool is_be = desc.endian_shift > 0;
|
||||
bool need_endian = (desc.comps[0].size % 8u && desc.bpp[0] > 8) ||
|
||||
desc.comps[0].size > 8;
|
||||
|
||||
if (need_endian) {
|
||||
desc.flags |= is_be ? MP_IMGFLAG_BE : MP_IMGFLAG_LE;
|
||||
@ -545,10 +510,8 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
&& is_uint)
|
||||
{
|
||||
bool same_depth = true;
|
||||
for (int p = 0; p < desc.num_planes; p++) {
|
||||
same_depth &= layout.bits[p] == layout.bits[0] &&
|
||||
desc.bpp[p] == desc.bpp[0];
|
||||
}
|
||||
for (int p = 0; p < desc.num_planes; p++)
|
||||
same_depth &= desc.bpp[p] == desc.bpp[0];
|
||||
if (same_depth && pd->nb_components == desc.num_planes) {
|
||||
if (desc.flags & MP_IMGFLAG_YUV) {
|
||||
desc.flags |= MP_IMGFLAG_YUV_P;
|
||||
@ -565,18 +528,50 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
}
|
||||
}
|
||||
|
||||
for (int p = 0; p < desc.num_planes; p++) {
|
||||
desc.xs[p] = (p == 1 || p == 2) ? desc.chroma_xs : 0;
|
||||
desc.ys[p] = (p == 1 || p == 2) ? desc.chroma_ys : 0;
|
||||
return desc;
|
||||
}
|
||||
|
||||
bool mp_imgfmt_get_packed_yuv_locations(int imgfmt, uint8_t *luma_offsets)
|
||||
{
|
||||
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(imgfmt);
|
||||
if (!(desc.flags & MP_IMGFLAG_PACKED_SS_YUV))
|
||||
return false;
|
||||
|
||||
assert(desc.num_planes == 1);
|
||||
|
||||
// Guess at which positions the additional luma samples are. We iterate
|
||||
// starting with the first byte, and then put a luma sample at places
|
||||
// not covered by other luma/chroma.
|
||||
// Pixdesc does not and can not provide this information. This heuristic
|
||||
// may fail in certain cases. What a load of bullshit, right?
|
||||
int lsize = desc.comps[0].size;
|
||||
int cur_offset = 0;
|
||||
for (int lsample = 1; lsample < (1 << desc.chroma_xs); lsample++) {
|
||||
while (1) {
|
||||
if (cur_offset + lsize > desc.bpp[0] * desc.align_x)
|
||||
return false;
|
||||
bool free = true;
|
||||
for (int c = 0; c < 3; c++) {
|
||||
struct mp_imgfmt_comp_desc *cd = &desc.comps[c];
|
||||
if (!cd->size)
|
||||
continue;
|
||||
if (cd->offset + cd->size > cur_offset &&
|
||||
cur_offset + lsize > cd->offset)
|
||||
{
|
||||
free = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (free)
|
||||
break;
|
||||
cur_offset += lsize;
|
||||
}
|
||||
luma_offsets[lsample] = cur_offset;
|
||||
cur_offset += lsize;
|
||||
}
|
||||
|
||||
desc.align_x = 1 << desc.chroma_xs;
|
||||
desc.align_y = 1 << desc.chroma_ys;
|
||||
|
||||
if ((desc.bpp[0] * (layout.extra_w + 1) % 8) != 0)
|
||||
desc.align_x = 8 / desc.bpp[0]; // expect power of 2
|
||||
|
||||
return desc;
|
||||
luma_offsets[0] = desc.comps[0].offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool validate_regular_imgfmt(const struct mp_regular_imgfmt *fmt)
|
||||
@ -689,17 +684,14 @@ bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt)
|
||||
return false;
|
||||
res.num_planes = desc.num_planes;
|
||||
|
||||
struct mp_imgfmt_layout layout;
|
||||
mp_imgfmt_get_layout(imgfmt, &layout);
|
||||
|
||||
if (layout.endian_bytes || layout.extra_w)
|
||||
if (desc.endian_shift || !(desc.flags & MP_IMGFLAG_HAS_COMPS))
|
||||
return false;
|
||||
|
||||
res.component_type = mp_imgfmt_get_component_type(imgfmt);
|
||||
if (!res.component_type)
|
||||
return false;
|
||||
|
||||
struct mp_imgfmt_comp_desc *comp0 = &layout.comps[0];
|
||||
struct mp_imgfmt_comp_desc *comp0 = &desc.comps[0];
|
||||
if (comp0->size < 1 || comp0->size > 64 || (comp0->size % 8u))
|
||||
return false;
|
||||
|
||||
@ -707,13 +699,13 @@ bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt)
|
||||
res.component_pad = comp0->pad;
|
||||
|
||||
for (int n = 0; n < res.num_planes; n++) {
|
||||
if (layout.bits[n] % comp0->size)
|
||||
if (desc.bpp[n] % comp0->size)
|
||||
return false;
|
||||
res.planes[n].num_components = layout.bits[n] / comp0->size;
|
||||
res.planes[n].num_components = desc.bpp[n] / comp0->size;
|
||||
}
|
||||
|
||||
for (int n = 0; n < MP_NUM_COMPONENTS; n++) {
|
||||
struct mp_imgfmt_comp_desc *comp = &layout.comps[n];
|
||||
struct mp_imgfmt_comp_desc *comp = &desc.comps[n];
|
||||
if (!comp->size)
|
||||
continue;
|
||||
|
||||
|
@ -34,6 +34,10 @@
|
||||
|
||||
// All pixels start in byte boundaries
|
||||
#define MP_IMGFLAG_BYTE_ALIGNED 0x1
|
||||
// mp_imgfmt_desc.comps[] is set to useful values. Some types of formats will
|
||||
// use comps[], but not set this flag, because it doesn't cover all requirements
|
||||
// (for example MP_IMGFLAG_PACKED_SS_YUV).
|
||||
#define MP_IMGFLAG_HAS_COMPS (1 << 1)
|
||||
// set if (possibly) alpha is included (might be not definitive for packed RGB)
|
||||
#define MP_IMGFLAG_ALPHA 0x80
|
||||
// set if it's YUV colorspace
|
||||
@ -63,6 +67,30 @@
|
||||
// Semi-planar YUV formats, like AV_PIX_FMT_NV12.
|
||||
#define MP_IMGFLAG_YUV_NV 0x80000
|
||||
|
||||
// Packed, sub-sampled YUV format. Does not apply to packed non-subsampled YUV.
|
||||
// These formats pack multiple pixels into one sample with strange organization.
|
||||
// In this specific case, mp_imgfmt_desc.align_x gives the size of a "full"
|
||||
// pixel, which has align_x luma samples, and 1 chroma sample of each Cb and Cr.
|
||||
// mp_imgfmt_desc.comps describes the chroma samples, and the first luma sample.
|
||||
// All luma samples have the same configuration as the first one, and you can
|
||||
// get their offsets with mp_imgfmt_get_packed_yuv_locations(). Note that the
|
||||
// component offsets can be >= bpp[0]; the actual range is bpp[0]*align_x.
|
||||
// These formats have no alpha.
|
||||
#define MP_IMGFLAG_PACKED_SS_YUV (1 << 20)
|
||||
|
||||
#define MP_NUM_COMPONENTS 4
|
||||
|
||||
struct mp_imgfmt_comp_desc {
|
||||
// Plane on which this component is.
|
||||
uint8_t plane;
|
||||
// Bit offset of first sample, from start of the pixel group (little endian).
|
||||
uint8_t offset : 6;
|
||||
// Number of bits used by each sample.
|
||||
uint8_t size : 6;
|
||||
// Internal padding. See mp_regular_imgfmt.component_pad.
|
||||
int8_t pad : 4;
|
||||
};
|
||||
|
||||
struct mp_imgfmt_desc {
|
||||
int id; // IMGFMT_*
|
||||
int avformat; // AV_PIX_FMT_* (or AV_PIX_FMT_NONE)
|
||||
@ -80,10 +108,31 @@ struct mp_imgfmt_desc {
|
||||
// addition to chroma, and thus is not sub-sampled (uses align_x=2 instead).
|
||||
int8_t xs[MP_MAX_PLANES];
|
||||
int8_t ys[MP_MAX_PLANES];
|
||||
|
||||
// Description for each component. Generally valid only if flags has
|
||||
// MP_IMGFLAG_HAS_COMPS set.
|
||||
// This is indexed by component_type-1 (so 0=R, 1=G, etc.), see
|
||||
// mp_regular_imgfmt_plane.components[x] for component_type. Components not
|
||||
// present, or which have an unknown layout, use size=0. Bits not covered by
|
||||
// any component are random and not interpreted by any software.
|
||||
// In particular, don't make the mistake to index this by plane.
|
||||
struct mp_imgfmt_comp_desc comps[MP_NUM_COMPONENTS];
|
||||
|
||||
// log(2) of the word size in bytes for endian swapping that needs to be
|
||||
// performed for converting to native endian. This is performed before any
|
||||
// other unpacking steps, and for all data covered by bits.
|
||||
// Always 0 if IMGFLAG_NE is set.
|
||||
uint8_t endian_shift : 2;
|
||||
};
|
||||
|
||||
struct mp_imgfmt_desc mp_imgfmt_get_desc(int imgfmt);
|
||||
|
||||
// For MP_IMGFLAG_PACKED_SS_YUV formats (packed sub-sampled YUV): positions of
|
||||
// further luma samples. luma_offsets must be an array of align_x size, and the
|
||||
// function will return the offset (like in mp_imgfmt_comp_desc.offset) of each
|
||||
// luma pixel. luma_offsets[0] == mp_imgfmt_desc.comps[0].offset.
|
||||
bool mp_imgfmt_get_packed_yuv_locations(int imgfmt, uint8_t *luma_offsets);
|
||||
|
||||
// MP_CSP_AUTO for YUV, MP_CSP_RGB or MP_CSP_XYZ otherwise.
|
||||
// (Because IMGFMT/AV_PIX_FMT conflate format and csp for RGB and XYZ.)
|
||||
enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt);
|
||||
@ -96,8 +145,6 @@ enum mp_component_type {
|
||||
|
||||
enum mp_component_type mp_imgfmt_get_component_type(int imgfmt);
|
||||
|
||||
#define MP_NUM_COMPONENTS 4
|
||||
|
||||
struct mp_regular_imgfmt_plane {
|
||||
uint8_t num_components;
|
||||
// 1 is red/luminance/gray, 2 is green/Cb, 3 is blue/Cr, 4 is alpha.
|
||||
@ -141,63 +188,6 @@ struct mp_regular_imgfmt {
|
||||
bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt);
|
||||
int mp_find_regular_imgfmt(struct mp_regular_imgfmt *src);
|
||||
|
||||
struct mp_imgfmt_comp_desc {
|
||||
// Plane on which this component is.
|
||||
uint8_t plane;
|
||||
// Bit offset of first sample, from start of the pixel group (little endian).
|
||||
uint8_t offset : 6;
|
||||
// Number of bits used by each sample.
|
||||
uint8_t size : 6;
|
||||
// Internal padding. See mp_regular_imgfmt.component_pad.
|
||||
int8_t pad : 4;
|
||||
};
|
||||
|
||||
// Describes component layout of a specific image format.
|
||||
// Complements struct mp_imgfmt_desc, mp_imgfmt_get_component_type(), and
|
||||
// mp_imgfmt_get_forced_csp().
|
||||
// struct mp_regular_imgfmt provides a simpler description in some cases.
|
||||
struct mp_imgfmt_layout {
|
||||
// Size of a pixel on each plane. If bits is not a multiple of 8, this is
|
||||
// what FFmpeg calls a bitstream format.
|
||||
// For planar sub-sampled formats, this describes a sub-sample. For
|
||||
// example, with yuv420p, both luma and chroma planes use bits=8, extra_w=0.
|
||||
// mp_imgfmt_desc.align_x gives the number of pixels needed to reach byte
|
||||
// align.
|
||||
// If extra_w>0, this is the size of extra_w+1 pixels (bundled together).
|
||||
uint8_t bits[MP_MAX_PLANES];
|
||||
|
||||
// Description for each component. This is indexed by component_type-1,
|
||||
// where component_type is as in mp_regular_imgfmt_plane.components[x] (so
|
||||
// 1=R, 2=G, etc.). Components not present, or which have an unknown layout,
|
||||
// use size=0.
|
||||
struct mp_imgfmt_comp_desc comps[MP_NUM_COMPONENTS];
|
||||
|
||||
// If !=0, this gives the word size in bytes for endian swapping that needs
|
||||
// to be performed for converting to native endian. This is performed before
|
||||
// any other unpacking steps, and for all data covered by bits.
|
||||
uint8_t endian_bytes : 4;
|
||||
|
||||
// Number of extra pixels in a pixel group. Packed, sub-sampled YUV formats
|
||||
// use extra_w>0. There are no other types of formats that use this. Packed
|
||||
// sub-sampled is defined as mixed non-sub-sampled (luma, alpha) and sub-
|
||||
// sampled (chroma) components on the same plane. There are extra_w+1 luma
|
||||
// samples in the pixel group, but only 1 chroma sample of each type.
|
||||
// NB: mp_imgfmt_desc.align_x gives the number of pixels needed to get a
|
||||
// "super pixel" with full chroma information, even for w=1 formats.
|
||||
uint8_t extra_w : 4;
|
||||
|
||||
// For packed sub-sampled YUV: positions of further luma samples. Generally,
|
||||
// you can access extra_luma_offsets[x] for (x >= 0 && x < extra_w). Luma
|
||||
// sample 0 is described in comps[0]; luma sample N (N>1) uses all fields in
|
||||
// comps[0], except offset=extra_luma_offsets[N-1].
|
||||
// In theory, alpha also requires extra offsets, but we do not support any
|
||||
// packed YUV formats with alpha and sub-sampled chroma.
|
||||
uint8_t extra_luma_offsets[3];
|
||||
};
|
||||
|
||||
// Return description for the given format, or desc={0} if unavailable.
|
||||
void mp_imgfmt_get_layout(int imgfmt, struct mp_imgfmt_layout *desc);
|
||||
|
||||
// If imgfmt is valid, and there exists a format that is exactly the same, but
|
||||
// has inverse endianness, return this other format. Otherwise return 0.
|
||||
int mp_find_other_endian(int imgfmt);
|
||||
|
@ -459,17 +459,17 @@ static void fringe_rgb_repack(struct mp_repack *rp,
|
||||
static void setup_fringe_rgb_packer(struct mp_repack *rp)
|
||||
{
|
||||
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(rp->imgfmt_a);
|
||||
struct mp_imgfmt_layout layout;
|
||||
mp_imgfmt_get_layout(rp->imgfmt_a, &layout);
|
||||
|
||||
if (layout.bits[0] > 16 || (layout.bits[0] % 8u) || layout.extra_w ||
|
||||
mp_imgfmt_get_forced_csp(rp->imgfmt_a) != MP_CSP_RGB ||
|
||||
desc.num_planes != 1 || layout.comps[3].size)
|
||||
if (!(desc.flags & MP_IMGFLAG_HAS_COMPS))
|
||||
return;
|
||||
|
||||
int depth = layout.comps[0].size;
|
||||
if (desc.bpp[0] > 16 || (desc.bpp[0] % 8u) ||
|
||||
mp_imgfmt_get_forced_csp(rp->imgfmt_a) != MP_CSP_RGB ||
|
||||
desc.num_planes != 1 || desc.comps[3].size)
|
||||
return;
|
||||
|
||||
int depth = desc.comps[0].size;
|
||||
for (int n = 0; n < 3; n++) {
|
||||
struct mp_imgfmt_comp_desc *c = &layout.comps[n];
|
||||
struct mp_imgfmt_comp_desc *c = &desc.comps[n];
|
||||
|
||||
if (c->size < 1 || c->size > 8 || c->pad)
|
||||
return;
|
||||
@ -492,8 +492,8 @@ static void setup_fringe_rgb_packer(struct mp_repack *rp)
|
||||
rp->components[n] = ((int[]){3, 1, 2})[n] - 1;
|
||||
|
||||
for (int n = 0; n < 3; n++) {
|
||||
int bits = layout.comps[n].size;
|
||||
rp->comp_shifts[n] = layout.comps[n].offset;
|
||||
int bits = desc.comps[n].size;
|
||||
rp->comp_shifts[n] = desc.comps[n].offset;
|
||||
if (rp->comp_lut) {
|
||||
uint8_t *lut = rp->comp_lut + 256 * n;
|
||||
uint8_t zmax = (1 << depth) - 1;
|
||||
@ -508,11 +508,11 @@ static void setup_fringe_rgb_packer(struct mp_repack *rp)
|
||||
}
|
||||
}
|
||||
|
||||
rp->comp_size = (layout.bits[0] + 7) / 8;
|
||||
rp->comp_size = (desc.bpp[0] + 7) / 8;
|
||||
assert(rp->comp_size == 1 || rp->comp_size == 2);
|
||||
|
||||
if (layout.endian_bytes) {
|
||||
assert(rp->comp_size == 2 && layout.endian_bytes == 2);
|
||||
if (desc.endian_shift) {
|
||||
assert(rp->comp_size == 2 && (1 << desc.endian_shift) == 2);
|
||||
rp->endian_size = 2;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user