summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2012-07-04 21:39:20 +0300
committerTorsten Jager <t.jager@gmx.de>2012-07-04 21:39:20 +0300
commit491a6c5ee427b6512f0d605b7b05ca8c30cb8a2f (patch)
tree90135a091aef2bf6e540b46dcb481c88d09ef3f7 /src
parent377d6bb567882193e8852a45860b85b8eb431f01 (diff)
downloadxine-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.c197
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 */