mirror of
https://github.com/mpv-player/mpv
synced 2024-12-22 14:52:43 +00:00
sub: find GBRP format automatically when rendering to RGB
This removes the need to define IMGFMT_GBRAP, which fixes compilation with the current Libav release. This also makes it automatically pick up a GBRP format with the same bit width. (Unfortunately, it seems libswscale does not support conversion to AV_PIX_FMT_GBRAP16, so our code falls back to 8 bit, removing precision for video covered by subtitles in cases this code is used.) Also, when the source video is e.g. 10 bit YUV, upsample to 16 bit. Whether this is good or bad, it fixes behavior with alpha. Although I'm not sure if the alpha range is really correct ([0,2^16-1] vs. [0,255*256]). Keep in mind that libswscale doesn't even agree with the way we do it.
This commit is contained in:
parent
082c23515f
commit
3973a953df
@ -407,21 +407,20 @@ static bool align_bbox_for_swscale(struct mp_image *img, struct mp_rect *rc)
|
||||
static void get_closest_y444_format(int imgfmt, int *out_format, int *out_bits)
|
||||
{
|
||||
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(imgfmt);
|
||||
int planes = desc.flags & MP_IMGFLAG_ALPHA ? 4 : 3;
|
||||
int bits = desc.component_bits > 8 ? 16 : 8;
|
||||
if (desc.flags & MP_IMGFLAG_RGB) {
|
||||
*out_format = desc.flags & MP_IMGFLAG_ALPHA ? IMGFMT_GBRAP : IMGFMT_GBRP;
|
||||
*out_bits = 8;
|
||||
return;
|
||||
*out_format = mp_imgfmt_find(0, 0, planes, bits, MP_IMGFLAG_RGB_P);
|
||||
if (!mp_sws_supported_format(*out_format))
|
||||
*out_format = mp_imgfmt_find(0, 0, planes, 8, MP_IMGFLAG_RGB_P);
|
||||
} else if (desc.flags & MP_IMGFLAG_YUV_P) {
|
||||
*out_format = mp_imgfmt_find_yuv_planar(0, 0, desc.num_planes,
|
||||
desc.plane_bits);
|
||||
if (*out_format && mp_sws_supported_format(*out_format)) {
|
||||
*out_bits = mp_imgfmt_get_desc(*out_format).plane_bits;
|
||||
return;
|
||||
}
|
||||
*out_format = mp_imgfmt_find(0, 0, planes, bits, MP_IMGFLAG_YUV_P);
|
||||
} else {
|
||||
*out_format = 0;
|
||||
}
|
||||
// fallback
|
||||
*out_format = IMGFMT_444P;
|
||||
*out_bits = 8;
|
||||
if (!mp_sws_supported_format(*out_format))
|
||||
*out_format = IMGFMT_444P; // generic fallback
|
||||
*out_bits = mp_imgfmt_get_desc(*out_format).component_bits;
|
||||
}
|
||||
|
||||
static struct part *get_cache(struct mp_draw_sub_cache *cache,
|
||||
|
@ -48,8 +48,6 @@ static const struct {
|
||||
{IMGFMT_BGR8, AV_PIX_FMT_BGR8},
|
||||
{IMGFMT_BGR4, AV_PIX_FMT_BGR4},
|
||||
{IMGFMT_PAL8, AV_PIX_FMT_PAL8},
|
||||
{IMGFMT_GBRP, AV_PIX_FMT_GBRP},
|
||||
{IMGFMT_GBRAP, AV_PIX_FMT_GBRAP},
|
||||
{IMGFMT_YUYV, AV_PIX_FMT_YUYV422},
|
||||
{IMGFMT_UYVY, AV_PIX_FMT_UYVY422},
|
||||
{IMGFMT_NV12, AV_PIX_FMT_NV12},
|
||||
|
@ -275,12 +275,12 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
||||
return desc;
|
||||
}
|
||||
|
||||
// Find a format that is MP_IMGFLAG_YUV_P with the following configuration.
|
||||
int mp_imgfmt_find_yuv_planar(int xs, int ys, int planes, int component_bits)
|
||||
// Find a format that has the given flags set with the following configuration.
|
||||
int mp_imgfmt_find(int xs, int ys, int planes, int component_bits, int flags)
|
||||
{
|
||||
for (int n = IMGFMT_START + 1; n < IMGFMT_END; n++) {
|
||||
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(n);
|
||||
if (desc.id && (desc.flags & MP_IMGFLAG_YUV_P)) {
|
||||
if (desc.id && ((desc.flags & flags) == flags)) {
|
||||
if (desc.num_planes == planes && desc.chroma_xs == xs &&
|
||||
desc.chroma_ys == ys && desc.plane_bits == component_bits &&
|
||||
(desc.flags & MP_IMGFLAG_NE))
|
||||
|
@ -67,7 +67,8 @@
|
||||
#define MP_IMGFLAG_HWACCEL 0x10000
|
||||
// Set if the chroma resolution is lower than luma resolution. Unset for non-YUV.
|
||||
#define MP_IMGFLAG_SUBSAMPLED 0x20000
|
||||
// Like MP_IMGFLAG_YUV_P, but RGB. The planes are organized as in IMGFMT_GBRP.
|
||||
// Like MP_IMGFLAG_YUV_P, but RGB. This can be e.g. AV_PIX_FMT_GBRP. The planes
|
||||
// are always shuffled (G - B - R [- A]).
|
||||
#define MP_IMGFLAG_RGB_P 0x40000
|
||||
|
||||
// Exactly one of these bits is set in mp_imgfmt_desc.flags
|
||||
@ -195,10 +196,6 @@ enum mp_imgfmt {
|
||||
// 256 entries, with each entry encoded like in IMGFMT_BGR32.
|
||||
IMGFMT_PAL8,
|
||||
|
||||
// Planar RGB (planes are shuffled: plane 0 is G, etc.)
|
||||
IMGFMT_GBRP,
|
||||
IMGFMT_GBRAP,
|
||||
|
||||
// XYZ colorspace, similar organization to RGB48. Even though it says "12",
|
||||
// the components are stored as 16 bit, with lower 4 bits set to 0.
|
||||
IMGFMT_XYZ12,
|
||||
@ -246,7 +243,7 @@ char **mp_imgfmt_name_list(void);
|
||||
|
||||
#define vo_format_name mp_imgfmt_to_name
|
||||
|
||||
int mp_imgfmt_find_yuv_planar(int xs, int ys, int planes, int component_bits);
|
||||
int mp_imgfmt_find(int xs, int ys, int planes, int component_bits, int flags);
|
||||
|
||||
int mp_imgfmt_select_best(int dst1, int dst2, int src);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user