diff options
author | Johns <johns98@gmx.net> | 2012-02-10 15:47:52 +0100 |
---|---|---|
committer | Johns <johns98@gmx.net> | 2012-02-10 15:47:52 +0100 |
commit | f28a737a9a5161257e15bc146ff0ffe77af00a27 (patch) | |
tree | 468ac92d47c87278167257fa4d9a11d107a703df | |
parent | 19cec561ba5bd88906311048e6c46bffacf784ee (diff) | |
download | vdr-plugin-softhddevice-f28a737a9a5161257e15bc146ff0ffe77af00a27.tar.gz vdr-plugin-softhddevice-f28a737a9a5161257e15bc146ff0ffe77af00a27.tar.bz2 |
VDPAU: support for studio levels added.
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | Todo | 4 | ||||
-rw-r--r-- | video.c | 133 |
3 files changed, 112 insertions, 26 deletions
@@ -1,6 +1,7 @@ User johns Date: + VDPAU: support for studio levels added. Add support for skip chroma deinterlace to software deinterlacer. Type of software deinterlacer now configurable from setup menu. Mixer channel could be set through command line option. @@ -21,10 +21,10 @@ $Id: $ missing: software deinterlace (yadif, ...) software decoder with software deinterlace - ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)? suspend output / energie saver: stop and restart X11 suspend plugin didn't restore full-screen (is this wanted?) Option deinterlace off / deinterlace force! + ColorSpace and StudioLevels aren't configurable with the gui. crash: AudioPlayHandlerThread -> pthread_cond_wait @@ -85,6 +85,8 @@ audio: add pause support for replay pause some plugin send a private LPCM stream (CODEC_ID_PCM_DVD), which isn't supported by ffmpeg, write own parser. + Mute should do a real mute and not only set volume to zero. + Starting suspended and muted, didn't register the mute. audio/alsa: better downmix of >2 channels on 2 channel hardware @@ -196,6 +196,17 @@ typedef enum _video_zoom_modes_ } VideoZoomModes; /// +/// Video color space conversions. +/// +typedef enum _video_color_space_ +{ + VideoColorSpaceNone, ///< no conversion + VideoColorSpaceBt601, ///< ITU.BT-601 Y'CbCr + VideoColorSpaceBt709, ///< ITU.BT-709 HDTV Y'CbCr + VideoColorSpaceSmpte240 ///< SMPTE-240M Y'PbPr +} VideoColorSpace; + +/// /// Video output module structure and typedef. /// typedef struct _video_module_ @@ -291,7 +302,14 @@ static int VideoDenoise[VideoResolutionMax]; /// Default amount of of sharpening, or blurring, to apply (-1000 .. 1000). static int VideoSharpen[VideoResolutionMax]; -// FIXME: color space / studio levels + /// Color space ITU-R BT.601, ITU-R BT.709, ... +static const VideoColorSpace VideoColorSpaces[VideoResolutionMax] = { + VideoColorSpaceBt601, VideoColorSpaceBt709, VideoColorSpaceBt709, + VideoColorSpaceBt709 +}; + + /// Flag use studio levels +static char VideoStudioLevels; /// Default scaling mode static VideoScalingModes VideoScaling[VideoResolutionMax]; @@ -1583,15 +1601,22 @@ static void VaapiInitSurfaceFlags(VaapiDecoder * decoder) for (i = 0; i < VideoResolutionMax; ++i) { decoder->SurfaceFlagsTable[i] = VA_CLEAR_DRAWABLE; - // color space conversion none, ITU-R BT.601, ITU-R BT.709 - if (i > VideoResolution576i) { - decoder->SurfaceFlagsTable[i] |= VA_SRC_BT709; - } else { - decoder->SurfaceFlagsTable[i] |= VA_SRC_BT601; + // color space conversion none, ITU-R BT.601, ITU-R BT.709, ... + switch (VideoColorSpaces[i]) { + case VideoColorSpaceNone: + break; + case VideoColorSpaceBt601: + decoder->SurfaceFlagsTable[i] |= VA_SRC_BT601; + break; + case VideoColorSpaceBt709: + decoder->SurfaceFlagsTable[i] |= VA_SRC_BT709; + break; + case VideoColorSpaceSmpte240: + decoder->SurfaceFlagsTable[i] |= VA_SRC_SMPTE_240; + break; } // scaling flags FAST, HQ, NL_ANAMORPHIC - // FIXME: need to detect the backend to choose the parameter switch (VideoScaling[i]) { case VideoScalingNormal: decoder->SurfaceFlagsTable[i] |= VA_FILTER_SCALING_DEFAULT; @@ -1607,7 +1632,7 @@ static void VaapiInitSurfaceFlags(VaapiDecoder * decoder) break; case VideoScalingAnamorphic: // intel backend supports only VA_FILTER_SCALING_NL_ANAMORPHIC; - // don't use it, its for 4:3 -> 16:9 scaling + // FIXME: Highlevel should display 4:3 as 16:9 to support this decoder->SurfaceFlagsTable[i] |= VA_FILTER_SCALING_NL_ANAMORPHIC; break; @@ -5123,7 +5148,7 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) float noise_reduction_level; float sharpness_level; VdpColorStandard color_standard; - VdpCSCMatrix csc_matrix[1]; + VdpCSCMatrix csc_matrix; // // Build enables table @@ -5218,26 +5243,80 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) attribute_value_ptrs[attribute_n++] = &sharpness_level; Debug(3, "video/vdpau: sharpness level %+1.3f\n", sharpness_level); } - // FIXME: studio colors, VideoColorStandard[decoder->Resolution] - if (decoder->InputWidth > 1280 || decoder->InputHeight > 576) { - // HDTV - color_standard = VDP_COLOR_STANDARD_ITUR_BT_709; - Debug(3, "video/vdpau: color space ITU-R BT.709\n"); - } else { - // SDTV - color_standard = VDP_COLOR_STANDARD_ITUR_BT_601; - Debug(3, "video/vdpau: color space ITU-R BT.601\n"); + switch (VideoColorSpaces[decoder->Resolution]) { + case VideoColorSpaceNone: + default: + color_standard = 0; + break; + case VideoColorSpaceBt601: + color_standard = VDP_COLOR_STANDARD_ITUR_BT_601; + Debug(3, "video/vdpau: color space ITU-R BT.601\n"); + break; + case VideoColorSpaceBt709: + color_standard = VDP_COLOR_STANDARD_ITUR_BT_709; + Debug(3, "video/vdpau: color space ITU-R BT.709\n"); + break; + case VideoColorSpaceSmpte240: + color_standard = VDP_COLOR_STANDARD_SMPTE_240M; + Debug(3, "video/vdpau: color space SMPTE-240M\n"); + break; } - - status = - VdpauGenerateCSCMatrix(&decoder->Procamp, color_standard, csc_matrix); - if (status != VDP_STATUS_OK) { - Error(_("video/vdpau: can't generate CSC matrix: %s\n"), - VdpauGetErrorString(status)); + // + // Studio levels + // + // based on www.nvnews.net forum thread + // + if (VideoStudioLevels) { + static const float color_coeffs[][3] = { + {0.299, 0.587, 0.114}, + {0.2125, 0.7154, 0.0721}, + {0.2122, 0.7013, 0.0865} + }; + float uvcos, uvsin; + float uv_coeffs[3][2]; + float Kr, Kg, Kb; + const int rgbmin = 16; + const int rgbr = 235 - rgbmin; + + Kr = color_coeffs[color_standard][0]; + Kg = color_coeffs[color_standard][1]; + Kb = color_coeffs[color_standard][2]; + + uv_coeffs[0][0] = 0.0; + uv_coeffs[0][1] = (rgbr / 112.0) * (1.0 - Kr); + uv_coeffs[1][0] = -(rgbr / 112.0) * (1.0 - Kb) * Kb / Kg; + uv_coeffs[1][1] = -(rgbr / 112.0) * (1.0 - Kr) * Kr / Kg; + uv_coeffs[2][0] = (rgbr / 112.0) * (1.0 - Kb); + uv_coeffs[2][1] = 0.0; + + uvcos = decoder->Procamp.saturation * cos(decoder->Procamp.hue); + uvsin = decoder->Procamp.saturation * sin(decoder->Procamp.hue); + + for (i = 0; i < 3; ++i) { + csc_matrix[i][3] = decoder->Procamp.brightness; + csc_matrix[i][0] = rgbr * decoder->Procamp.contrast / 219; + csc_matrix[i][3] += (-16 / 255.0) * csc_matrix[i][0]; + csc_matrix[i][1] = + uv_coeffs[i][0] * uvcos + uv_coeffs[i][1] * uvsin; + csc_matrix[i][3] += (-128 / 255.0) * csc_matrix[i][1]; + csc_matrix[i][2] = + uv_coeffs[i][0] * uvsin + uv_coeffs[i][1] * uvcos; + csc_matrix[i][3] += (-128 / 255.0) * csc_matrix[i][2]; + csc_matrix[i][3] += rgbmin / 255.0; + csc_matrix[i][3] += 0.5 - decoder->Procamp.contrast / 2.0; + } + } else { + status = + VdpauGenerateCSCMatrix(&decoder->Procamp, color_standard, + &csc_matrix); + if (status != VDP_STATUS_OK) { + Error(_("video/vdpau: can't generate CSC matrix: %s\n"), + VdpauGetErrorString(status)); + } } attributes[attribute_n] = VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX; - attribute_value_ptrs[attribute_n++] = csc_matrix; + attribute_value_ptrs[attribute_n++] = &csc_matrix; status = VdpauVideoMixerSetAttributeValues(decoder->VideoMixer, attribute_n, @@ -9180,6 +9259,10 @@ void VideoInit(const char *display_name) if (getenv("NO_HW")) { VideoHardwareDecoder = 0; } + VideoStudioLevels = 0; + if (getenv("STUDIO_LEVELS")) { + VideoStudioLevels = 1; + } //xcb_prefetch_maximum_request_length(Connection); xcb_flush(Connection); } |