diff options
author | Johns <johns98@gmx.net> | 2012-01-05 17:20:44 +0100 |
---|---|---|
committer | Johns <johns98@gmx.net> | 2012-01-05 17:20:44 +0100 |
commit | 0776bc5ee472f5013e2507ecb088673e9152caee (patch) | |
tree | 4c07baa0c35e60e3f36687c978779022743169a0 /video.c | |
parent | aba14813c008c4d5a7577e4191be686ab8bf4cc4 (diff) | |
download | vdr-plugin-softhddevice-0776bc5ee472f5013e2507ecb088673e9152caee.tar.gz vdr-plugin-softhddevice-0776bc5ee472f5013e2507ecb088673e9152caee.tar.bz2 |
VDPAU improvements.
Add denoise, sharpness, skip chroma deinterlace support.
Show OSD only if something is to display, improves performance.
Add deinterlace mode with only 4 surfaces.
Diffstat (limited to 'video.c')
-rw-r--r-- | video.c | 385 |
1 files changed, 290 insertions, 95 deletions
@@ -1,7 +1,7 @@ /// /// @file video.c @brief Video module /// -/// Copyright (c) 2009 - 2011 by Johns. All Rights Reserved. +/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved. /// /// Contributor(s): /// @@ -37,6 +37,7 @@ /// #define USE_XLIB_XCB +#define noUSE_GRAB #define noUSE_GLX #define noUSE_DOUBLEBUFFER @@ -197,6 +198,20 @@ static unsigned VideoWindowHeight; ///< video output window height /// Default deinterlace mode static VideoDeinterlaceModes VideoDeinterlace; + /// Default number of deinterlace surfaces +static const int VideoDeinterlaceSurfaces = 4; + + /// Default skip chroma deinterlace flag (VDPAU only) +static int VideoSkipChromaDeinterlace = 1; + + /// Default amount of noise reduction algorithm to apply (0 .. 1000). +static int VideoDenoise; + + /// Default amount of of sharpening, or blurring, to apply (-1000 .. 1000). +static int VideoSharpen; + +// FIXME: color space + /// Default scaling mode static VideoScalingModes VideoScaling; @@ -3135,6 +3150,7 @@ static int VdpauTemporal; ///< temporal deinterlacer supported static int VdpauTemporalSpatial; ///< temporal spatial deint. supported static int VdpauInverseTelecine; ///< inverse telecine deint. supported static int VdpauNoiseReduction; ///< noise reduction supported +static int VdpauSharpness; ///< sharpness supported static int VdpauSkipChroma; ///< skip chroma deint. supported /// display surface ring buffer @@ -3143,6 +3159,7 @@ static int VdpauSurfaceIndex; ///< current display surface static int VdpauOsdWidth; ///< width of osd surface static int VdpauOsdHeight; ///< height of osd surface +static int VdpauShowOsd; ///< flag show osd #ifdef USE_BITMAP /// bitmap surfaces for osd @@ -3165,13 +3182,12 @@ static VdpGetErrorString *VdpauGetErrorString; static VdpDeviceDestroy *VdpauDeviceDestroy; static VdpGenerateCSCMatrix *VdpauGenerateCSCMatrix; static VdpVideoSurfaceQueryCapabilities *VdpauVideoSurfaceQueryCapabilities; -static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities - *VdpauVideoSurfaceQueryGetPutBitsYCbCrCapabilities; +static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities * + VdpauVideoSurfaceQueryGetPutBitsYCbCrCapabilities; static VdpVideoSurfaceCreate *VdpauVideoSurfaceCreate; static VdpVideoSurfaceDestroy *VdpauVideoSurfaceDestroy; static VdpVideoSurfaceGetParameters *VdpauVideoSurfaceGetParameters; - -//static VdpVideoSurfaceGetBitsYCbCr * VdpauVideoSurfaceGetBitsYCbCr; +static VdpVideoSurfaceGetBitsYCbCr *VdpauVideoSurfaceGetBitsYCbCr; static VdpVideoSurfacePutBitsYCbCr *VdpauVideoSurfacePutBitsYCbCr; static VdpOutputSurfaceCreate *VdpauOutputSurfaceCreate; @@ -3185,10 +3201,10 @@ static VdpBitmapSurfaceDestroy *VdpauBitmapSurfaceDestroy; static VdpBitmapSurfacePutBitsNative *VdpauBitmapSurfacePutBitsNative; -static VdpOutputSurfaceRenderOutputSurface * - VdpauOutputSurfaceRenderOutputSurface; -static VdpOutputSurfaceRenderBitmapSurface * - VdpauOutputSurfaceRenderBitmapSurface; +static VdpOutputSurfaceRenderOutputSurface + *VdpauOutputSurfaceRenderOutputSurface; +static VdpOutputSurfaceRenderBitmapSurface + *VdpauOutputSurfaceRenderBitmapSurface; static VdpDecoderQueryCapabilities *VdpauDecoderQueryCapabilities; static VdpDecoderCreate *VdpauDecoderCreate; @@ -3197,6 +3213,9 @@ static VdpDecoderDestroy *VdpauDecoderDestroy; static VdpDecoderRender *VdpauDecoderRender; static VdpVideoMixerQueryFeatureSupport *VdpauVideoMixerQueryFeatureSupport; +static VdpVideoMixerQueryAttributeSupport + *VdpauVideoMixerQueryAttributeSupport; + static VdpVideoMixerCreate *VdpauVideoMixerCreate; static VdpVideoMixerSetFeatureEnables *VdpauVideoMixerSetFeatureEnables; static VdpVideoMixerSetAttributeValues *VdpauVideoMixerSetAttributeValues; @@ -3206,18 +3225,18 @@ static VdpVideoMixerRender *VdpauVideoMixerRender; static VdpPresentationQueueTargetDestroy *VdpauPresentationQueueTargetDestroy; static VdpPresentationQueueCreate *VdpauPresentationQueueCreate; static VdpPresentationQueueDestroy *VdpauPresentationQueueDestroy; -static VdpPresentationQueueSetBackgroundColor - *VdpauPresentationQueueSetBackgroundColor; +static VdpPresentationQueueSetBackgroundColor * + VdpauPresentationQueueSetBackgroundColor; static VdpPresentationQueueGetTime *VdpauPresentationQueueGetTime; static VdpPresentationQueueDisplay *VdpauPresentationQueueDisplay; -static VdpPresentationQueueBlockUntilSurfaceIdle * - VdpauPresentationQueueBlockUntilSurfaceIdle; -static VdpPresentationQueueQuerySurfaceStatus * - VdpauPresentationQueueQuerySurfaceStatus; +static VdpPresentationQueueBlockUntilSurfaceIdle + *VdpauPresentationQueueBlockUntilSurfaceIdle; +static VdpPresentationQueueQuerySurfaceStatus + *VdpauPresentationQueueQuerySurfaceStatus; -static VdpPresentationQueueTargetCreateX11 - *VdpauPresentationQueueTargetCreateX11; +static VdpPresentationQueueTargetCreateX11 * + VdpauPresentationQueueTargetCreateX11; ///@} /// @@ -3374,16 +3393,25 @@ static void VdpauPrintFrames(const VdpauDecoder * decoder) /// /// @param decoder VDPAU hw decoder /// +/// @note don't forget to update features, paramaters, attributes table +/// size, if more is add. +/// static void VdpauMixerSetup(VdpauDecoder * decoder) { VdpStatus status; int i; - VdpVideoMixerFeature features[14]; - VdpBool enables[14]; + VdpVideoMixerFeature features[15]; + VdpBool enables[15]; int feature_n; - VdpVideoMixerParameter paramaters[10]; - void const *values[10]; + VdpVideoMixerParameter paramaters[4]; + void const *value_ptrs[4]; int parameter_n; + VdpVideoMixerAttribute attributes[3]; + void const *attribute_value_ptrs[3]; + int attribute_n; + uint8_t skip_chroma_value; + float noise_reduction_level; + float sharpness_level; VdpChromaType chroma_type; int layers; @@ -3404,7 +3432,9 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) if (VdpauNoiseReduction) { features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION; } - // VDP_VIDEO_MIXER_FEATURE_SHARPNESS + if (VdpauSharpness) { + features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; + } for (i = VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1; i <= VdpauHqScalingMax; ++i) { features[feature_n++] = i; @@ -3417,19 +3447,19 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) // Setup parameter/value tables // paramaters[0] = VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH; - values[0] = &decoder->InputWidth; + value_ptrs[0] = &decoder->InputWidth; paramaters[1] = VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT; - values[1] = &decoder->InputHeight; + value_ptrs[1] = &decoder->InputHeight; paramaters[2] = VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE; - values[2] = &chroma_type; + value_ptrs[2] = &chroma_type; layers = 0; paramaters[3] = VDP_VIDEO_MIXER_PARAMETER_LAYERS; - values[3] = &layers; + value_ptrs[3] = &layers; parameter_n = 4; status = VdpauVideoMixerCreate(VdpauDevice, feature_n, features, parameter_n, - paramaters, values, &decoder->VideoMixer); + paramaters, value_ptrs, &decoder->VideoMixer); if (status != VDP_STATUS_OK) { Fatal(_("video/vdpau: can't create video mixer: %s\n"), VdpauGetErrorString(status)); @@ -3441,8 +3471,8 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) feature_n = 0; if (VdpauTemporal) { enables[feature_n] = (VideoDeinterlace == VideoDeinterlaceTemporal - || VideoDeinterlace == - VideoDeinterlaceTemporalSpatial) ? VDP_TRUE : VDP_FALSE; + || (VideoDeinterlace == VideoDeinterlaceTemporalSpatial + && !VdpauTemporalSpatial)) ? VDP_TRUE : VDP_FALSE; features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL; Debug(3, "video/vdpau: temporal deinterlace %s\n", enables[feature_n - 1] ? "enabled" : "disabled"); @@ -3463,11 +3493,17 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) enables[feature_n - 1] ? "enabled" : "disabled"); } if (VdpauNoiseReduction) { - enables[feature_n] = VDP_FALSE; - features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE; + enables[feature_n] = VideoDenoise ? VDP_TRUE : VDP_FALSE; + features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION; Debug(3, "video/vdpau: noise reduction %s\n", enables[feature_n - 1] ? "enabled" : "disabled"); } + if (VdpauSharpness) { + enables[feature_n] = VideoSharpen ? VDP_TRUE : VDP_FALSE; + features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; + Debug(3, "video/vdpau: sharpness %s\n", + enables[feature_n - 1] ? "enabled" : "disabled"); + } for (i = VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1; i <= VdpauHqScalingMax; ++i) { enables[feature_n] = @@ -3486,10 +3522,34 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA - VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE - VdpVideoMixerSetAttributeValues(decoder->Mixer, attribute_n, - attributes, values); */ + attribute_n = 0; + if (VdpauSkipChroma) { + skip_chroma_value = VideoSkipChromaDeinterlace; + attributes[attribute_n] + = VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE; + attribute_value_ptrs[attribute_n++] = &skip_chroma_value; + Debug(3, "video/vdpau: skip chroma deinterlace %s\n", + skip_chroma_value ? "enabled" : "disabled"); + } + if (VdpauNoiseReduction) { + noise_reduction_level = VideoDenoise / 1000.0; + attributes[attribute_n] + = VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL; + attribute_value_ptrs[attribute_n++] = &noise_reduction_level; + Debug(3, "video/vdpau: noise reduction level %1.3f\n", + noise_reduction_level); + } + if (VdpauSharpness) { + sharpness_level = VideoSharpen / 1000.0; + attributes[attribute_n] + = VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL; + attribute_value_ptrs[attribute_n++] = &sharpness_level; + Debug(3, "video/vdpau: sharpness level %+1.3f\n", sharpness_level); + } + + VdpauVideoMixerSetAttributeValues(decoder->VideoMixer, attribute_n, + attributes, attribute_value_ptrs); //VdpColorStandard color_standard; //color_standard = VDP_COLOR_STANDARD_ITUR_BT_601; @@ -3711,7 +3771,8 @@ static void VideoVdpauInit(const char *display_name) "VideoSurfaceDestroy"); VdpauGetProc(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, &VdpauVideoSurfaceGetParameters, "VideoSurfaceGetParameters"); - // VdpauGetProc(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, &VdpauVideoSurfaceGetBitsYCbCr, "VideoSurfaceGetBitsYCbCr"); + VdpauGetProc(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + &VdpauVideoSurfaceGetBitsYCbCr, "VideoSurfaceGetBitsYCbCr"); VdpauGetProc(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, &VdpauVideoSurfacePutBitsYCbCr, "VideoSurfacePutBitsYCbCr"); #if 0 @@ -3775,7 +3836,11 @@ static void VideoVdpauInit(const char *display_name) &VdpauVideoMixerQueryFeatureSupport, "VideoMixerQueryFeatureSupport"); #if 0 VdpauGetProc(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT, &, ""); - VdpauGetProc(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT, &, ""); +#endif + VdpauGetProc(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT, + &VdpauVideoMixerQueryAttributeSupport, + "VideoMixerQueryAttributeSupport"); +#if 0 VdpauGetProc(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE, &, ""); VdpauGetProc(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE, &, ""); #endif @@ -3921,6 +3986,16 @@ static void VideoVdpauInit(const char *display_name) status = VdpauVideoMixerQueryFeatureSupport(VdpauDevice, + VDP_VIDEO_MIXER_FEATURE_SHARPNESS, &flag); + if (status != VDP_STATUS_OK) { + Error(_("video/vdpau: can't query feature '%s': %s\n"), "sharpness", + VdpauGetErrorString(status)); + } else { + VdpauSharpness = flag; + } + + status = + VdpauVideoMixerQueryAttributeSupport(VdpauDevice, VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE, &flag); if (status != VDP_STATUS_OK) { Error(_("video/vdpau: can't query feature '%s': %s\n"), @@ -3937,9 +4012,9 @@ static void VideoVdpauInit(const char *display_name) Info(_("video/vdpau: feature deinterlace temporal %s\n"), VdpauTemporal ? _("supported") : _("unsupported")); Info(_("video/vdpau: feature deinterlace temporal spatial %s\n"), - VdpauTemporal ? _("supported") : _("unsupported")); + VdpauTemporalSpatial ? _("supported") : _("unsupported")); Info(_("video/vdpau: attribute skip chroma deinterlace %s\n"), - VdpauTemporal ? _("supported") : _("unsupported")); + VdpauSkipChroma ? _("supported") : _("unsupported")); // // video formats @@ -4338,6 +4413,69 @@ static void VdpauSetup(VdpauDecoder * decoder, } /// +/// Grab video surface. +/// +/// @param decoder VDPAU hw decoder +/// +static void VdpauGrabSurface(VdpauDecoder * decoder) +{ + VdpVideoSurface surface; + VdpStatus status; + VdpChromaType chroma_type; + uint32_t size; + uint32_t width; + uint32_t height; + void *base; + void *data[3]; + uint32_t pitches[3]; + VdpYCbCrFormat format; + + // FIXME: test function to grab output surface content + // for screen shots, atom light and auto crop. + + surface = decoder->SurfacesRb[(decoder->SurfaceRead + 1) + % VIDEO_SURFACES_MAX]; + + // get real surface size + status = + VdpauVideoSurfaceGetParameters(surface, &chroma_type, &width, &height); + if (status != VDP_STATUS_OK) { + Error(_("video/vdpau: can't get video surface parameters: %s\n"), + VdpauGetErrorString(status)); + return; + } + switch (chroma_type) { + case VDP_CHROMA_TYPE_420: + case VDP_CHROMA_TYPE_422: + case VDP_CHROMA_TYPE_444: + size = width * height + ((width + 1) / 2) * ((height + 1) / 2) + + ((width + 1) / 2) * ((height + 1) / 2); + base = malloc(size); + if (!base) { + Error(_("video/vdpau: out of memory\n")); + return; + } + pitches[0] = width; + pitches[1] = width / 2; + pitches[2] = width / 2; + data[0] = base; + data[1] = base + width * height; + data[2] = base + width * height + width * height / 4; + format = VDP_YCBCR_FORMAT_YV12; + break; + } + status = VdpauVideoSurfaceGetBitsYCbCr(surface, format, data, pitches); + if (status != VDP_STATUS_OK) { + Error(_("video/vdpau: can't get video surface bits: %s\n"), + VdpauGetErrorString(status)); + return; + } + // 0x10 0x80 0x80 black + + free(base); +} + +/// /// Queue output surface. /// /// @param decoder VDPAU hw decoder @@ -4562,8 +4700,9 @@ static void VdpauMixOsd(void) VdpRect source_rect; VdpRect output_rect; VdpStatus status; - uint32_t start; - uint32_t end; + + //uint32_t start; + //uint32_t end; // // blend overlay over output @@ -4592,7 +4731,7 @@ static void VdpauMixOsd(void) output_rect.x1 = VideoWindowWidth; output_rect.y1 = VideoWindowHeight; - start = GetMsTicks(); + //start = GetMsTicks(); VdpauOsdSurfaceIndex = 1; #ifdef USE_BITMAP @@ -4616,7 +4755,7 @@ static void VdpauMixOsd(void) VdpauGetErrorString(status)); } #endif - end = GetMsTicks(); + //end = GetMsTicks(); //Debug(3, "video:/vdpau: osd render %d ms\n", end - start); @@ -4651,56 +4790,99 @@ static void VdpauMixVideo(VdpauDecoder * decoder) dst_video_rect.x1 = decoder->OutputX + decoder->OutputWidth; dst_video_rect.y1 = decoder->OutputY + decoder->OutputHeight; +#ifdef USE_GRAB + VdpauGrabSurface(decoder); +#endif + if (decoder->Interlaced && VideoDeinterlace != VideoDeinterlaceWeave) { // // Build deinterlace structures // VdpVideoMixerPictureStructure cps; - VdpVideoSurface past[2]; - VdpVideoSurface future[2]; + VdpVideoSurface past[3]; + int past_n; + VdpVideoSurface future[3]; + int future_n; #ifdef DEBUG if (atomic_read(&decoder->SurfacesFilled) < 3) { Debug(3, "only %d\n", atomic_read(&decoder->SurfacesFilled)); } #endif + // FIXME: can use VDP_INVALID_HANDLE to support less surface on start - // FIXME: wrong for bottom-field first - // read: past: B0 T0 current T1 future B1 T2 (0 1 2) - // read: past: T1 B0 current B1 future T2 B2 (0 1 2) - if (decoder->TopFieldFirst != decoder->SurfaceField) { - cps = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; + if (VideoDeinterlaceSurfaces == 5) { + past_n = 2; + future_n = 2; - past[1] = decoder->SurfacesRb[decoder->SurfaceRead]; - past[0] = past[1]; - current = decoder->SurfacesRb[(decoder->SurfaceRead + 1) - % VIDEO_SURFACES_MAX]; - future[0] = current; - future[1] = decoder->SurfacesRb[(decoder->SurfaceRead + 2) - % VIDEO_SURFACES_MAX]; - // FIXME: can support 1 future more - } else { - cps = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; + // FIXME: wrong for bottom-field first + // read: past: B0 T0 current T1 future B1 T2 (0 1 2) + // read: past: T1 B0 current B1 future T2 B2 (0 1 2) + if (decoder->TopFieldFirst != decoder->SurfaceField) { + cps = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; + + past[1] = decoder->SurfacesRb[decoder->SurfaceRead]; + past[0] = past[1]; + current = decoder->SurfacesRb[(decoder->SurfaceRead + 1) + % VIDEO_SURFACES_MAX]; + future[0] = current; + future[1] = decoder->SurfacesRb[(decoder->SurfaceRead + 2) + % VIDEO_SURFACES_MAX]; + // FIXME: can support 1 future more + } else { + cps = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; + + // FIXME: can support 1 past more + past[1] = decoder->SurfacesRb[decoder->SurfaceRead]; + past[0] = decoder->SurfacesRb[(decoder->SurfaceRead + 1) + % VIDEO_SURFACES_MAX]; + current = past[0]; + future[0] = decoder->SurfacesRb[(decoder->SurfaceRead + 2) + % VIDEO_SURFACES_MAX]; + future[1] = future[0]; + } - // FIXME: can support 1 past more - past[1] = decoder->SurfacesRb[decoder->SurfaceRead]; - past[0] = decoder->SurfacesRb[(decoder->SurfaceRead + 1) - % VIDEO_SURFACES_MAX]; - current = past[0]; - future[0] = decoder->SurfacesRb[(decoder->SurfaceRead + 2) - % VIDEO_SURFACES_MAX]; - future[1] = future[0]; + } else if (VideoDeinterlaceSurfaces == 4) { + past_n = 2; + future_n = 1; + + // FIXME: wrong for bottom-field first + // read: past: B0 T0 current T1 future B1 (0 1 2) + // read: past: T1 B0 current B1 future T2 (0 1 2) + if (decoder->TopFieldFirst != decoder->SurfaceField) { + cps = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; + + past[1] = decoder->SurfacesRb[decoder->SurfaceRead]; + past[0] = past[1]; + current = decoder->SurfacesRb[(decoder->SurfaceRead + 1) + % VIDEO_SURFACES_MAX]; + future[0] = current; + } else { + cps = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; + + past[1] = decoder->SurfacesRb[decoder->SurfaceRead]; + past[0] = decoder->SurfacesRb[(decoder->SurfaceRead + 1) + % VIDEO_SURFACES_MAX]; + current = past[0]; + future[0] = decoder->SurfacesRb[(decoder->SurfaceRead + 2) + % VIDEO_SURFACES_MAX]; + } + + } else { + Error(_("video/vdpau: %d surface deinterlace unsupported\n"), + VideoDeinterlaceSurfaces); } + // FIXME: past_n, future_n here: Debug(4, " %02d %02d(%c%02d) %02d %02d\n", past[1], past[0], cps == VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD ? 'T' : 'B', current, future[0], future[1]); status = VdpauVideoMixerRender(decoder->VideoMixer, VDP_INVALID_HANDLE, - NULL, cps, 2, past, current, 2, future, &video_src_rect, - VdpauSurfacesRb[VdpauSurfaceIndex], &dst_rect, &dst_video_rect, 0, - NULL); + NULL, cps, past_n, past, current, future_n, future, + &video_src_rect, VdpauSurfacesRb[VdpauSurfaceIndex], &dst_rect, + &dst_video_rect, 0, NULL); } else { current = decoder->SurfacesRb[decoder->SurfaceRead]; @@ -4804,32 +4986,25 @@ static void VdpauAdvanceFrame(void) /// static void VdpauDisplayFrame(void) { - uint32_t now; - uint32_t end; - static uint32_t last_frame_tick; VdpStatus status; VdpTime first_time; static VdpTime last_time; int i; - now = GetMsTicks(); - Debug(4, "video/vdpau: tick %d\n", now - last_frame_tick); - // // wait for surface visible (blocks max ~5ms) // status = VdpauPresentationQueueBlockUntilSurfaceIdle(VdpauQueue, VdpauSurfacesRb[VdpauSurfaceIndex], &first_time); - end = GetMsTicks(); if (status != VDP_STATUS_OK) { Error(_("video/vdpau: can't block queue: %s\n"), VdpauGetErrorString(status)); } // check if surface was displayed for more than 1 frame if (last_time && first_time > last_time + 21 * 1000 * 1000) { - Debug(3, "video/vdpau: %ld display time %ld - %d ms\n", first_time, - (first_time - last_time) / 1000, end - now); + Debug(3, "video/vdpau: %ld display time %ld\n", first_time / 1000, + (first_time - last_time) / 1000); // FIXME: can be more than 1 frame long shown for (i = 0; i < VdpauDecoderN; ++i) { VdpauDecoders[i]->FramesMissed++; @@ -4842,7 +5017,6 @@ static void VdpauDisplayFrame(void) } } last_time = first_time; - last_frame_tick = now; // // Render videos into output @@ -4868,8 +5042,9 @@ static void VdpauDisplayFrame(void) // // add osd to surface // - VdpauMixOsd(); - + if (VdpauShowOsd) { // showing costs performance + VdpauMixOsd(); + } // // place surface in presentation queue // @@ -4906,17 +5081,6 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) VdpauAdvanceFrame(); } filled = atomic_read(&decoder->SurfacesFilled); -#if 0 - // debug duplicate frames (done by VdpauAdvanceFrame) - if (filled == 1) { - decoder->FramesDuped++; - Warning(_("video: display buffer empty, duping frame (%d/%d)\n"), - decoder->FramesDuped, decoder->FrameCounter); - if (!(decoder->FramesDisplayed % 300)) { - VdpauPrintFrames(decoder); - } - } -#endif VdpauDisplayFrame(); @@ -4944,7 +5108,8 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) decoder->DropNextFrame = 1; } } - +#ifdef DEBUG + // debug audio/video sync if (decoder->DupNextFrame || decoder->DropNextFrame || !(decoder->FramesDisplayed % (50 * 10))) { static int64_t last_video_clock; @@ -4957,6 +5122,7 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) last_video_clock = video_clock; } +#endif } /// @@ -4969,9 +5135,11 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) static void VdpauSyncRenderFrame(VdpauDecoder * decoder, const AVCodecContext * video_ctx, const AVFrame * frame) { +#ifdef DEBUG if (!atomic_read(&decoder->SurfacesFilled)) { Debug(3, "video: new stream frame %d\n", GetMsTicks() - VideoSwitch); } +#endif if (decoder->DropNextFrame) { // drop frame requested ++decoder->FramesDropped; @@ -5067,7 +5235,8 @@ static void VdpauDisplayHandlerThread(void) clock_gettime(CLOCK_REALTIME, &nowtime); // time for one frame over? - if ((nowtime.tv_sec - decoder->FrameTime.tv_sec) + if ( //filled<VIDEO_SURFACES_MAX && + (nowtime.tv_sec - decoder->FrameTime.tv_sec) * 1000 * 1000 * 1000 + (nowtime.tv_nsec - decoder->FrameTime.tv_nsec) < 15 * 1000 * 1000) { return; @@ -5138,6 +5307,7 @@ static void VdpauOsdClear(void) #endif free(image); + VdpauShowOsd = 0; } /// @@ -5196,6 +5366,7 @@ static void VdpauUploadImage(int x, int y, int width, int height, VdpauGetErrorString(status)); } #endif + VdpauShowOsd = 1; } /// @@ -6192,6 +6363,30 @@ void VideoSetDeinterlace(int mode) } /** +** Set skip chroma deinterlace on/off. +*/ +void VideoSetSkipChromaDeinterlace(int onoff) +{ + VideoSkipChromaDeinterlace = onoff; +} + +/** +** Set denoise level (0 .. 1000). +*/ +void VideoSetDenoise(int level) +{ + VideoDenoise = level; +} + +/** +** Set sharpness level (-1000 .. 1000). +*/ +void VideoSetSharpen(int level) +{ + VideoSharpen = level; +} + +/** ** Set scaling mode. */ void VideoSetScaling(int mode) |