VDPAU: support for studio levels added.

This commit is contained in:
Johns 2012-02-10 15:47:52 +01:00
parent 19cec561ba
commit f28a737a9a
3 changed files with 111 additions and 25 deletions

View File

@ -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.

4
Todo
View File

@ -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

131
video.c
View File

@ -195,6 +195,17 @@ typedef enum _video_zoom_modes_
VideoAnamorphic, ///< anamorphic scaled (unsupported)
} 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.
///
@ -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;
}
//
// 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;
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));
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);
}