mirror of https://github.com/mpv-player/mpv
repack: use new imgfmt metadata in more cases
Now everything is super generic and super undebuggable. Some awkwardness because the new metadata is basically a transposed version of the mp_regular_imgfmt metadata, which was used for component info before.
This commit is contained in:
parent
2525aa3393
commit
756ae0321b
141
video/repack.c
141
video/repack.c
|
@ -67,7 +67,7 @@ struct mp_repack {
|
|||
|
||||
// Fringe RGB/YUV.
|
||||
uint8_t comp_size;
|
||||
uint8_t *comp_map;
|
||||
uint8_t comp_map[4];
|
||||
uint8_t comp_shifts[3];
|
||||
uint8_t *comp_lut;
|
||||
|
||||
|
@ -333,41 +333,41 @@ static void packed_repack(struct mp_repack *rp,
|
|||
// Tries to set a packer/unpacker for component-wise byte aligned formats.
|
||||
static void setup_packed_packer(struct mp_repack *rp)
|
||||
{
|
||||
struct mp_regular_imgfmt desc;
|
||||
if (!mp_get_regular_imgfmt(&desc, rp->imgfmt_a))
|
||||
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(rp->imgfmt_a);
|
||||
if (!(desc.flags & MP_IMGFLAG_HAS_COMPS) ||
|
||||
!(desc.flags & MP_IMGFLAG_TYPE_UINT) ||
|
||||
!(desc.flags & MP_IMGFLAG_NE) ||
|
||||
desc.num_planes != 1)
|
||||
return;
|
||||
|
||||
if (desc.num_planes != 1 || desc.planes[0].num_components < 2)
|
||||
return;
|
||||
struct mp_regular_imgfmt_plane *p = &desc.planes[0];
|
||||
|
||||
int num_real_components = 0;
|
||||
bool has_alpha = false;
|
||||
for (int n = 0; n < p->num_components; n++) {
|
||||
if (p->components[n]) {
|
||||
has_alpha |= p->components[n] == 4;
|
||||
num_real_components += 1;
|
||||
} else {
|
||||
// padding must be in MSB or LSB
|
||||
if (n != 0 && n != p->num_components - 1)
|
||||
return;
|
||||
}
|
||||
int components[4] = {0};
|
||||
for (int n = 0; n < MP_NUM_COMPONENTS; n++) {
|
||||
if (!desc.comps[n].size)
|
||||
continue;
|
||||
if (desc.comps[n].size != desc.comps[0].size ||
|
||||
desc.comps[n].pad != desc.comps[0].pad ||
|
||||
desc.comps[n].offset % desc.comps[0].size)
|
||||
return;
|
||||
int item = desc.comps[n].offset / desc.comps[0].size;
|
||||
if (item >= 4)
|
||||
return;
|
||||
components[item] = n + 1;
|
||||
num_real_components++;
|
||||
}
|
||||
|
||||
int depth = desc.component_size * 8 + MPMIN(0, desc.component_pad);
|
||||
int depth = desc.comps[0].size + MPMIN(0, desc.comps[0].pad);
|
||||
|
||||
static const int reorder_gbrp[] = {0, 3, 1, 2, 4};
|
||||
static const int reorder_yuv[] = {0, 1, 2, 3, 4};
|
||||
int planar_fmt = 0;
|
||||
const int *reorder = NULL;
|
||||
if (desc.forced_csp) {
|
||||
if (desc.forced_csp != MP_CSP_RGB && desc.forced_csp != MP_CSP_XYZ)
|
||||
return;
|
||||
planar_fmt = find_gbrp_format(depth, num_real_components);
|
||||
reorder = reorder_gbrp;
|
||||
} else {
|
||||
if (desc.flags & MP_IMGFLAG_COLOR_YUV) {
|
||||
planar_fmt = find_yuv_format(depth, num_real_components);
|
||||
reorder = reorder_yuv;
|
||||
} else {
|
||||
planar_fmt = find_gbrp_format(depth, num_real_components);
|
||||
reorder = reorder_gbrp;
|
||||
}
|
||||
if (!planar_fmt)
|
||||
return;
|
||||
|
@ -378,12 +378,12 @@ static void setup_packed_packer(struct mp_repack *rp)
|
|||
// The following may assume little endian (because some repack backends
|
||||
// use word access, while the metadata here uses byte access).
|
||||
|
||||
int prepad = p->components[0] ? 0 : 8;
|
||||
int first_comp = p->components[0] ? 0 : 1;
|
||||
int prepad = components[0] ? 0 : 8;
|
||||
int first_comp = components[0] ? 0 : 1;
|
||||
void (*repack_cb)(void *pa, void *pb[], int w) =
|
||||
rp->pack ? pa->pa_scanline : pa->un_scanline;
|
||||
|
||||
if (pa->packed_width != desc.component_size * p->num_components * 8 ||
|
||||
if (pa->packed_width != desc.bpp[0] ||
|
||||
pa->component_width != depth ||
|
||||
pa->num_components != num_real_components ||
|
||||
pa->prepadding != prepad ||
|
||||
|
@ -396,7 +396,7 @@ static void setup_packed_packer(struct mp_repack *rp)
|
|||
for (int n = 0; n < num_real_components; n++) {
|
||||
// Determine permutation that maps component order between the two
|
||||
// formats, with has_alpha special case (see above).
|
||||
int c = reorder[p->components[first_comp + n]];
|
||||
int c = reorder[components[first_comp + n]];
|
||||
rp->components[n] = c == 4 ? num_real_components - 1 : c - 1;
|
||||
}
|
||||
return;
|
||||
|
@ -564,19 +564,7 @@ static void bitmap_repack(struct mp_repack *rp,
|
|||
|
||||
static void setup_misc_packer(struct mp_repack *rp)
|
||||
{
|
||||
// Although it's in regular_repackers[], the generic mpv imgfmt metadata
|
||||
// can't handle it yet.
|
||||
if (rp->imgfmt_a == IMGFMT_RGB30) {
|
||||
int planar_fmt = find_gbrp_format(10, 3);
|
||||
if (!planar_fmt)
|
||||
return;
|
||||
rp->imgfmt_b = planar_fmt;
|
||||
rp->repack = packed_repack;
|
||||
rp->packed_repack_scanline = rp->pack ? pa_ccc10z2 : un_ccc10x2;
|
||||
static int c_order[] = {2, 1, 3};
|
||||
for (int n = 0; n < 3; n++)
|
||||
rp->components[n] = c_order[n] - 1;
|
||||
} else if (rp->imgfmt_a == IMGFMT_PAL8 && !rp->pack) {
|
||||
if (rp->imgfmt_a == IMGFMT_PAL8 && !rp->pack) {
|
||||
int grap_fmt = find_gbrp_format(8, 4);
|
||||
if (!grap_fmt)
|
||||
return;
|
||||
|
@ -603,26 +591,6 @@ static void setup_misc_packer(struct mp_repack *rp)
|
|||
}
|
||||
}
|
||||
|
||||
struct fringe_yuv422_repacker {
|
||||
// To avoid making a mess of IMGFMT_*, we use av formats directly.
|
||||
enum AVPixelFormat avfmt;
|
||||
// In bits (depth/8 rounded up gives byte size)
|
||||
int8_t depth;
|
||||
// Word index of each sample: {y0, y1, cb, cr}
|
||||
uint8_t comp[4];
|
||||
bool be;
|
||||
};
|
||||
|
||||
static const struct fringe_yuv422_repacker fringe_yuv422_repackers[] = {
|
||||
{AV_PIX_FMT_YUYV422, 8, {0, 2, 1, 3}},
|
||||
{AV_PIX_FMT_UYVY422, 8, {1, 3, 0, 2}},
|
||||
{AV_PIX_FMT_YVYU422, 8, {0, 2, 3, 1}},
|
||||
#ifdef AV_PIX_FMT_Y210
|
||||
{AV_PIX_FMT_Y210LE, 10, {0, 2, 1, 3}},
|
||||
{AV_PIX_FMT_Y210BE, 10, {0, 2, 1, 3}, .be = true},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define PA_P422(name, comp_t) \
|
||||
static void name(void *dst, void *src[], int w, uint8_t *c) { \
|
||||
for (int x = 0; x < w; x += 2) { \
|
||||
|
@ -672,20 +640,39 @@ static void fringe_yuv422_repack(struct mp_repack *rp,
|
|||
|
||||
static void setup_fringe_yuv422_packer(struct mp_repack *rp)
|
||||
{
|
||||
enum AVPixelFormat avfmt = imgfmt2pixfmt(rp->imgfmt_a);
|
||||
|
||||
const struct fringe_yuv422_repacker *fmt = NULL;
|
||||
for (int n = 0; n < MP_ARRAY_SIZE(fringe_yuv422_repackers); n++) {
|
||||
if (fringe_yuv422_repackers[n].avfmt == avfmt) {
|
||||
fmt = &fringe_yuv422_repackers[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fmt)
|
||||
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(rp->imgfmt_a);
|
||||
if (!(desc.flags & MP_IMGFLAG_PACKED_SS_YUV) ||
|
||||
mp_imgfmt_desc_get_num_comps(&desc) != 3 ||
|
||||
desc.align_x != 2)
|
||||
return;
|
||||
|
||||
rp->comp_size = (fmt->depth + 7) / 8;
|
||||
uint8_t y_loc[2];
|
||||
if (!mp_imgfmt_get_packed_yuv_locations(desc.id, y_loc))
|
||||
return;
|
||||
|
||||
for (int n = 0; n < MP_NUM_COMPONENTS; n++) {
|
||||
if (!desc.comps[n].size)
|
||||
continue;
|
||||
if (desc.comps[n].size != desc.comps[0].size ||
|
||||
desc.comps[n].pad < 0 ||
|
||||
desc.comps[n].offset % desc.comps[0].size)
|
||||
return;
|
||||
if (n == 1 || n == 2) {
|
||||
rp->comp_map[n - 1 + desc.align_x] =
|
||||
desc.comps[n].offset / desc.comps[0].size;
|
||||
}
|
||||
}
|
||||
for (int n = 0; n < desc.align_x; n++) {
|
||||
if (y_loc[n] % desc.comps[0].size)
|
||||
return;
|
||||
rp->comp_map[n] = y_loc[n] / desc.comps[0].size;
|
||||
}
|
||||
|
||||
int depth = desc.comps[0].size;
|
||||
if (depth != 8 && depth != 16)
|
||||
return;
|
||||
|
||||
rp->comp_size = depth / 8u;
|
||||
assert(rp->comp_size == 1 || rp->comp_size == 2);
|
||||
|
||||
struct mp_regular_imgfmt yuvfmt = {
|
||||
|
@ -699,11 +686,10 @@ static void setup_fringe_yuv422_packer(struct mp_repack *rp)
|
|||
};
|
||||
rp->imgfmt_b = mp_find_regular_imgfmt(&yuvfmt);
|
||||
rp->repack = fringe_yuv422_repack;
|
||||
rp->comp_map = (uint8_t *)fmt->comp;
|
||||
|
||||
if (fmt->be) {
|
||||
assert(rp->comp_size == 2);
|
||||
rp->endian_size = 2;
|
||||
if (desc.endian_shift) {
|
||||
rp->endian_size = 1 << desc.endian_shift;
|
||||
assert(rp->endian_size == 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1031,7 +1017,6 @@ static void reset_params(struct mp_repack *rp)
|
|||
rp->endian_size = 0;
|
||||
rp->packed_repack_scanline = NULL;
|
||||
rp->comp_size = 0;
|
||||
rp->comp_map = NULL;
|
||||
talloc_free(rp->comp_lut);
|
||||
rp->comp_lut = NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue