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:
wm4 2015-12-24 16:42:21 +01:00
parent 082c23515f
commit 3973a953df
4 changed files with 17 additions and 23 deletions

View File

@ -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,

View File

@ -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},

View File

@ -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))

View File

@ -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);