diff options
author | Torsten Jager <t.jager@gmx.de> | 2012-07-04 21:39:20 +0300 |
---|---|---|
committer | Torsten Jager <t.jager@gmx.de> | 2012-07-04 21:39:20 +0300 |
commit | 491a6c5ee427b6512f0d605b7b05ca8c30cb8a2f (patch) | |
tree | 90135a091aef2bf6e540b46dcb481c88d09ef3f7 /src | |
parent | 377d6bb567882193e8852a45860b85b8eb431f01 (diff) | |
download | xine-lib-491a6c5ee427b6512f0d605b7b05ca8c30cb8a2f.tar.gz xine-lib-491a6c5ee427b6512f0d605b7b05ca8c30cb8a2f.tar.bz2 |
Updated version of color_matrix.c
Diffstat (limited to 'src')
-rw-r--r-- | src/video_out/color_matrix.c | 197 |
1 files changed, 102 insertions, 95 deletions
diff --git a/src/video_out/color_matrix.c b/src/video_out/color_matrix.c index 22b62ef02..7047559ad 100644 --- a/src/video_out/color_matrix.c +++ b/src/video_out/color_matrix.c @@ -25,7 +25,11 @@ This file must be included after declaration of xxxx_driver_t, and #define'ing CM_DRIVER_T to it. - That struct must contain the integer values cm_state and cm_new. + That struct must contain the integer value cm_state. + + cm_from_frame () returns current (color_matrix << 1) | color_range control value. + Having only 1 var simplifies change event handling and avoids unecessary vo + reconfiguration. In the libyuv2rgb case, they are even handled by same code. In theory, HD video uses a different YUV->RGB matrix than the rest. It shall come closer to the human eye's brightness feel, and give @@ -53,121 +57,124 @@ based on video size. Both not user configurable, and both not tested... */ -#ifdef CM_DRIVER_T - -/* cm_update () modes */ -#define CM_UPDATE_INIT 0 -#define CM_UPDATE_CONFIG 1 -#define CM_UPDATE_STREAM 2 -#define CM_UPDATE_HEIGHT 3 -#define CM_UPDATE_CLOSE 4 +/* eveybody gets these */ /* user configuration settings */ +#define CM_CONFIG_NAME "video.output.color_matrix" #define CM_CONFIG_SIGNAL 0 #define CM_CONFIG_SIZE 1 #define CM_CONFIG_SD 2 #define CM_CONFIG_HD 3 -static void cm_update (CM_DRIVER_T *this, int mode, int value); - -/* the names thereof */ -static const char * const cm_conf_labels[] = { - "Signal", "Signal+Size", "SD", "HD", NULL -}; - -#endif /* defined CM_DRIVER_T */ +#define CR_CONFIG_NAME "video.output.color_range" +#define CR_CONFIG_AUTO 0 +#define CR_CONFIG_MPEG 1 +#define CR_CONFIG_FULL 2 static const char * const cm_names[] = { - "ITU-R 470 BG / SDTV", + "RGB", + "RGB", "ITU-R 709 / HDTV", + "full range ITU-R 709 / HDTV", + "undefined", + "full range, undefined", "ITU-R 470 BG / SDTV", - "ITU-R 470 BG / SDTV", + "full range ITU-R 470 BG / SDTV", "FCC", + "full range FCC", "ITU-R 470 BG / SDTV", + "full range ITU-R 470 BG / SDTV", "SMPTE 170M", - "SMPTE 240M" + "full range SMPTE 170M", + "SMPTE 240M", + "full range SMPTE 240M" }; #ifdef CM_DRIVER_T +/* this is for vo plugins only */ + +/* the option names */ +static const char * const cm_conf_labels[] = { + "Signal", "Signal+Size", "SD", "HD", NULL +}; + +static const char * const cr_conf_labels[] = { + "Auto", "MPEG", "FULL", NULL +}; + /* callback when user changes them */ -static void cm_cb_config (void *this_gen, xine_cfg_entry_t *entry) { - CM_DRIVER_T *this = (CM_DRIVER_T *)this_gen; - cm_update (this, CM_UPDATE_CONFIG, entry->num_value); +static void cm_cb_config (void *this, xine_cfg_entry_t *entry) { + *((int *)this) = (*((int *)this) & 3) | (entry->num_value << 2); +} + +static void cr_cb_config (void *this, xine_cfg_entry_t *entry) { + *((int *)this) = (*((int *)this) & 0x1c) | entry->num_value; +} + +static void cm_init (CM_DRIVER_T *this) { + /* register configuration */ + this->cm_state = this->xine->config->register_enum ( + this->xine->config, + CM_CONFIG_NAME, + CM_CONFIG_SD, + (char **)cm_conf_labels, + _("Output color matrix"), + _("Tell how output colors should be calculated.\n\n" + "Signal: Do as current stream suggests.\n" + " This may be wrong sometimes.\n\n" + "Signal+Size: Same as above,\n" + " but assume HD color for unmarked HD streams.\n\n" + "SD: Force SD video standard ITU-R 470/601.\n" + " Try this if you get too little green.\n\n" + "HD: Force HD video standard ITU-R 709.\n" + " Try when there is too much green coming out.\n\n"), + 10, + cm_cb_config, + &this->cm_state + ) << 2; + this->cm_state |= this->xine->config->register_enum ( + this->xine->config, + CR_CONFIG_NAME, + CR_CONFIG_AUTO, + (char **)cr_conf_labels, + _("Output color range"), + _("Tell how output colors should be ranged.\n\n" + "Auto: Do as current stream suggests.\n" + " This may be wrong sometimes.\n\n" + "MPEG: Force MPEG color range (16..235) / studio swing / video mode.\n" + " Try if image looks dull (no real black or white in it).\n\n" + "FULL: Force FULL color range (0..255) / full swing / PC mode.\n" + " Try when flat black and white spots appear.\n\n"), + 10, + cr_cb_config, + &this->cm_state + ); +} + +static uint8_t cm_m[] = { + 5, 1, 5, 3, 4, 5, 6, 7, /* SIGNAL */ + 5, 1, 5, 3, 4, 5, 6, 7, /* SIZE */ + 5, 5, 5, 5, 5, 5, 5, 5, /* SD */ + 5, 1, 1, 1, 1, 1, 1, 1 /* HD */ +}; + +static uint8_t cm_r[] = {0, 0, 1, 0}; /* AUTO, MPEG, FULL, safety */ + +static int cm_from_frame (vo_frame_t *frame) { + CM_DRIVER_T *this = (CM_DRIVER_T *)frame->driver; + int cm = VO_GET_FLAGS_CM (frame->flags); + int cf = this->cm_state; + + cm_m[10] = (frame->height - frame->crop_top - frame->crop_bottom) >= 720 ? 1 : 5; + cm_r[0] = cm & 1; + return ((cm_m[((cf >> 2) << 3) | (cm >> 1)] << 1) | cm_r[cf & 2]); } -/* handle generic changes */ -static void cm_update (CM_DRIVER_T *this, int mode, int value) { - /* get state */ - int conf = this->cm_state & 7; - int stream = (this->cm_state >> 3) & 7; - int hd = (this->cm_state >> 6) & 1; - /* update it */ - switch (mode) { - case CM_UPDATE_INIT: - /* register configuration */ - conf = this->xine->config->register_enum ( - this->xine->config, - "video.output.color_matrix", - CM_CONFIG_SD, - (char **)cm_conf_labels, - _("Output color matrix to use"), - _("Tell how output colors should be calculated.\n\n" - "Signal: Do as current stream suggests.\n" - " This may be wrong sometimes.\n\n" - "Signal+Size: Same as above,\n" - " but assume HD color for unmarked HD streams.\n\n" - "SD: Force SD video standard ITU-R 470/601.\n" - " Try this if you get too little green.\n\n" - "HD: Force HD video standard ITU-R 709.\n" - " Try when there is too much green coming out.\n\n"), - 10, - cm_cb_config, - this - ); - /* lock to legacy matrix until someone sends CM_UPDATE_STREAM. - This way still images and audio visualisation stay correct */ - stream = 0; - hd = 0; - break; - case CM_UPDATE_CONFIG: - conf = value; - break; - case CM_UPDATE_STREAM: - stream = value; - if ((stream < 1) || (stream > 7)) stream = 2; /* undefined */ - break; - case CM_UPDATE_HEIGHT: - hd = value >= 720 ? 1 : 0; - break; - case CM_UPDATE_CLOSE: - /* dont know whether this is really necessary */ - this->xine->config->unregister_callback (this->xine->config, - "video.output.color_matrix"); - break; - } - /* check user configuration */ - switch (conf) { - case CM_CONFIG_SIZE: - if (stream == 2) { - /* no stream info, decide based on video size */ - this->yuv2rgb_cm = hd ? 1 : 2; - break; - } - /* fall through */ - case CM_CONFIG_SIGNAL: - /* follow stream info */ - this->yuv2rgb_cm = stream ? stream : 2; - break; - case CM_CONFIG_SD: - this->yuv2rgb_cm = 5; /* ITU-R 601/SDTV */ - break; - case CM_CONFIG_HD: - this->yuv2rgb_cm = 1; /* ITU-R 709/HDTV */ - break; - } - /* save state */ - this->cm_state = (hd << 6) | (stream << 3) | conf; +static void cm_close (CM_DRIVER_T *this) { + /* dont know whether this is really necessary */ + this->xine->config->unregister_callback (this->xine->config, CR_CONFIG_NAME); + this->xine->config->unregister_callback (this->xine->config, CM_CONFIG_NAME); } #endif /* defined CM_DRIVER_T */ |