summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-30 00:27:50 +0200
committerwm4 <wm4@nowhere>2013-07-15 00:00:43 +0200
commit5b01ef4572cb4490d5ee1800e3f2b34ef24da811 (patch)
treee77c21e13bd5d3928e87f8f42dcfb4cb342cb223 /video
parent65d8709152c5e3942e1a4db958be7cae80ea05b0 (diff)
downloadmpv-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.c53
-rw-r--r--video/mp_image.h2
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(&params, image);
+ mp_image_params_guess_csp(&params);
+ 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);