diff options
author | wm4 <wm4@nowhere> | 2013-06-30 00:27:50 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-07-15 00:00:43 +0200 |
commit | 5b01ef4572cb4490d5ee1800e3f2b34ef24da811 (patch) | |
tree | e77c21e13bd5d3928e87f8f42dcfb4cb342cb223 /video | |
parent | 65d8709152c5e3942e1a4db958be7cae80ea05b0 (diff) | |
download | mpv-5b01ef4572cb4490d5ee1800e3f2b34ef24da811.tar.bz2 mpv-5b01ef4572cb4490d5ee1800e3f2b34ef24da811.tar.xz |
mp_image: refactor colorspace guessing/fallback
This actually handles XYZ too.
Diffstat (limited to 'video')
-rw-r--r-- | video/mp_image.c | 53 | ||||
-rw-r--r-- | video/mp_image.h | 2 |
2 files changed, 46 insertions, 9 deletions
diff --git a/video/mp_image.c b/video/mp_image.c index d395fcf572..003ce4a0c7 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -419,19 +419,54 @@ enum mp_csp_levels mp_image_levels(struct mp_image *img) return (img->flags & MP_IMGFLAG_YUV) ? MP_CSP_LEVELS_TV : MP_CSP_LEVELS_PC; } +static void mp_image_params_from_image(struct mp_image_params *params, + const struct mp_image *image) +{ + // (Ideally mp_image should use mp_image_params directly instead) + *params = (struct mp_image_params) { + .imgfmt = image->imgfmt, + .w = image->w, + .h = image->h, + .d_w = image->display_w, + .d_h = image->display_h, + .colorspace = image->colorspace, + .colorlevels = image->levels, + }; +} + void mp_image_set_colorspace_details(struct mp_image *image, struct mp_csp_details *csp) { - if (image->flags & MP_IMGFLAG_YUV) { - image->colorspace = csp->format; - if (image->colorspace == MP_CSP_AUTO) - image->colorspace = MP_CSP_BT_601; - image->levels = csp->levels_in; - if (image->levels == MP_CSP_LEVELS_AUTO) - image->levels = MP_CSP_LEVELS_TV; + struct mp_image_params params; + mp_image_params_from_image(¶ms, image); + mp_image_params_guess_csp(¶ms); + image->colorspace = params.colorspace; + image->levels = params.colorlevels; +} + +// If details like params->colorspace/colorlevels are missing, guess them from +// the other settings. Also, even if they are set, make them consistent with +// the colorspace as implied by the pixel format. +void mp_image_params_guess_csp(struct mp_image_params *params) +{ + struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(params->imgfmt); + if (!fmt.id) + return; + if (fmt.flags & MP_IMGFLAG_YUV) { + if (params->colorspace == MP_CSP_AUTO) + params->colorspace = mp_csp_guess_colorspace(params->w, params->h); + if (params->colorlevels == MP_CSP_LEVELS_AUTO) + params->colorlevels = MP_CSP_LEVELS_TV; + } else if (fmt.flags & MP_IMGFLAG_RGB) { + params->colorspace = MP_CSP_RGB; + params->colorlevels = MP_CSP_LEVELS_PC; + } else if (fmt.flags & MP_IMGFLAG_XYZ) { + params->colorspace = MP_CSP_XYZ; + params->colorlevels = MP_CSP_LEVELS_PC; } else { - image->colorspace = MP_CSP_RGB; - image->levels = MP_CSP_LEVELS_PC; + // We have no clue. + params->colorspace = MP_CSP_AUTO; + params->colorlevels = MP_CSP_LEVELS_AUTO; } } diff --git a/video/mp_image.h b/video/mp_image.h index 96b980039d..69e3ae52b0 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -138,6 +138,8 @@ struct mp_csp_details; void mp_image_set_colorspace_details(struct mp_image *image, struct mp_csp_details *csp); +void mp_image_params_guess_csp(struct mp_image_params *params); + struct AVFrame; void mp_image_copy_fields_from_av_frame(struct mp_image *dst, struct AVFrame *src); |