From 96eefca699ad32353ddb8c71f25ee3f5d864b156 Mon Sep 17 00:00:00 2001 From: Johns Date: Mon, 9 Jan 2012 17:03:04 +0100 Subject: [PATCH] Video improvements. Fix generate of video output from StillPicture. Add support for resolution dependend video parameterts (Deinterlace, Scaling, Denoise, Sharpen, ...). --- ChangeLog | 4 + README.txt | 18 ++-- Todo | 1 + softhddev.c | 17 +-- softhddevice.cpp | 195 +++++++++++++++++++++++----------- video.c | 264 +++++++++++++++++++++++++++++++++-------------- video.h | 10 +- 7 files changed, 353 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c71bf0..4314856 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ User johns Date: + Add support of resolution dependend video parameters (deint, scale, ...). + Add support for recording play back. + Add workaround for alsa crash in snd_pcm_prepare. + Fix bug: audio crash on exit. Fix build with vdr without yaepg support. Support yaepghd video picture output position change. diff --git a/README.txt b/README.txt index d15f70e..5e9fcfa 100644 --- a/README.txt +++ b/README.txt @@ -95,23 +95,27 @@ Setup: /etc/vdr/setup.conf softhddevice.MakePrimary = 1 0 = no change, 1 make softhddevice primary at start - softhddevice.Deinterlace = 0 + of the next parameters is 567i, 720p, 1080i_fake or 1080i. + 1080i_fake is 1280x1080 or 1440x1080 + 1080i is "real" 1920x1080 + + softhddevice..Scaling = 0 + 0 = normal, 1 = fast, 2 = HQ, 3 = anamorphic + + softhddevice..Deinterlace = 0 0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software (only 0, 1 supported with vaapi) - softhddevice.SkipChromaDeinterlace = 0 + softhddevice..SkipChromaDeinterlace = 0 0 = disabled, 1 = enabled (for slower cards, poor qualität) - softhddevice.Denoise = 0 + softhddevice..Denoise = 0 0 .. 1000 noise reduction level (0 off, 1000 max) - softhddevice.Sharpness = 0 + softhddevice..Sharpness = 0 -1000 .. 1000 noise reduction level (0 off, -1000 max blur, 1000 max sharp) - softhddevice.Scaling = 0 - 0 = normal, 1 = fast, 2 = HQ, 3 = anamorphic - softhddevice.AudioDelay = 0 +n or -n ms diff --git a/Todo b/Todo index 68f1f30..a00b84f 100644 --- a/Todo +++ b/Todo @@ -93,3 +93,4 @@ setup: Setup 4:3 zoom type Setup parameters are not used until restart. Can a notice be added to the setup menu? + 576i, 720p, fake 1080i, 1080i diff --git a/softhddev.c b/softhddev.c index a715886..72c31e6 100644 --- a/softhddev.c +++ b/softhddev.c @@ -818,14 +818,19 @@ void Freeze(void) */ void StillPicture(const uint8_t * data, int size) { + int i; + // must be a PES start code if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) { Error(_("[softhddev] invalid PES video packet\n")); return; } - PlayVideo(data, size); - PlayVideo(data, size); - VideoNextPacket(VideoCodecID); // terminate work + Clear(); // flush video buffers + // +1 future for deinterlace + for (i = -1; i < (VideoCodecID == CODEC_ID_MPEG2VIDEO ? 3 : 17); ++i) { + PlayVideo(data, size); // reference frames + } + VideoNextPacket(VideoCodecID); // terminate last packet } /** @@ -917,10 +922,10 @@ static char StartX11Server; ///< flag start the x11 server */ const char *CommandLineHelp(void) { - return " -a device\talsa audio device (fe. hw:0,0)\n" - " -d display\tdisplay of x11 server (f.e :0.0)\n" + return " -a device\taudio device (fe. alsa: hw:0,0 oss: /dev/dsp)\n" + " -d display\tdisplay of x11 server (fe. :0.0)\n" " -g geometry\tx11 window geometry wxh+x+y\n" - " -x\tstart x11 server\n"; + " -x\t\tstart x11 server\n"; } /** diff --git a/softhddevice.cpp b/softhddevice.cpp index 5b94383..8ac556b 100644 --- a/softhddevice.cpp +++ b/softhddevice.cpp @@ -51,14 +51,32 @@ static class cSoftHdDevice *MyDevice; ////////////////////////////////////////////////////////////////////////////// +#define RESOLUTIONS 4 ///< number of resolutions + +static const char *const Resolution[RESOLUTIONS] = { + "576i", "720p", "1080i_fake", "1080i" +}; + static char ConfigMakePrimary; ///< config primary wanted -static char ConfigVideoDeinterlace; ///< config deinterlace -static char ConfigVideoSkipChromaDeinterlace; ///< config skip chroma -static int ConfigVideoDenoise; ///< config denoise -static int ConfigVideoSharpen; ///< config sharpen -static char ConfigVideoScaling; ///< config scaling + + /// config deinterlace +static int ConfigVideoDeinterlace[RESOLUTIONS]; + + /// config skip chroma +static int ConfigVideoSkipChromaDeinterlace[RESOLUTIONS]; + + /// config denoise +static int ConfigVideoDenoise[RESOLUTIONS]; + + /// config sharpen +static int ConfigVideoSharpen[RESOLUTIONS]; + + /// config scaling +static int ConfigVideoScaling[RESOLUTIONS]; + static int ConfigVideoAudioDelay; ///< config audio delay static int ConfigAudioPassthrough; ///< config audio pass-through + static volatile char DoMakePrimary; ///< flag switch primary ////////////////////////////////////////////////////////////////////////////// @@ -153,12 +171,11 @@ void cSoftOsd::Flush(void) if (!Active()) { return; } - // support yaepghd, video window #ifdef USE_YAEPG if (vidWin.bpp) { - dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__, - vidWin.Width(), vidWin.Height(), vidWin.x1, vidWin.y2 ); + dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__, vidWin.Width(), + vidWin.Height(), vidWin.x1, vidWin.y2); // FIXME: vidWin is OSD relative not video window. VideoSetOutputPosition(Left() + vidWin.x1, Top() + vidWin.y1, @@ -289,11 +306,11 @@ class cMenuSetupSoft:public cMenuSetupPage { protected: int MakePrimary; - int Deinterlace; - int SkipChromaDeinterlace; - int Denoise; - int Sharpen; - int Scaling; + int Scaling[RESOLUTIONS]; + int Deinterlace[RESOLUTIONS]; + int SkipChromaDeinterlace[RESOLUTIONS]; + int Denoise[RESOLUTIONS]; + int Sharpen[RESOLUTIONS]; int AudioDelay; int AudioPassthrough; protected: @@ -302,6 +319,19 @@ class cMenuSetupSoft:public cMenuSetupPage cMenuSetupSoft(void); }; +/** +** Create a seperator item. +*/ +static inline cOsdItem *SeparatorItem(const char *label) +{ + cOsdItem *item; + + item = new cOsdItem(cString::sprintf("* %s: ", label)); + item->SetSelectable(false); + + return item; +} + /** ** Constructor setup menu. */ @@ -316,26 +346,41 @@ cMenuSetupSoft::cMenuSetupSoft(void) static const char *const passthrough[] = { "None", "AC-3" }; + static const char *const resolution[RESOLUTIONS] = { + "576i", "720p", "fake 1080i", "1080i" + }; + int i; // cMenuEditBoolItem cMenuEditBitItem cMenuEditNumItem // cMenuEditStrItem cMenuEditStraItem cMenuEditIntItem MakePrimary = ConfigMakePrimary; Add(new cMenuEditBoolItem(tr("Make primary device"), &MakePrimary, tr("no"), tr("yes"))); - Deinterlace = ConfigVideoDeinterlace; - Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace, 5, - deinterlace)); - SkipChromaDeinterlace = ConfigVideoSkipChromaDeinterlace; - Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"), - &SkipChromaDeinterlace, tr("no"), tr("yes"))); - Denoise = ConfigVideoDenoise; - Add(new cMenuEditIntItem(tr("Denoise (vdpau 0..1000)"), &Denoise, 0, - 1000)); - Sharpen = ConfigVideoSharpen; - Add(new cMenuEditIntItem(tr("Sharpen (vdpau -1000..1000)"), &Sharpen, - -1000, 1000)); - Scaling = ConfigVideoScaling; - Add(new cMenuEditStraItem(tr("Scaling"), &Scaling, 4, scaling)); + // + // video + // + Add(SeparatorItem(tr("Video"))); + for (i = 0; i < RESOLUTIONS; ++i) { + Add(SeparatorItem(resolution[i])); + Scaling[i] = ConfigVideoScaling[i]; + Add(new cMenuEditStraItem(tr("Scaling"), &Scaling[i], 4, scaling)); + Deinterlace[i] = ConfigVideoDeinterlace[i]; + Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace[i], 5, + deinterlace)); + SkipChromaDeinterlace[i] = ConfigVideoSkipChromaDeinterlace[i]; + Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"), + &SkipChromaDeinterlace[i], tr("no"), tr("yes"))); + Denoise[i] = ConfigVideoDenoise[i]; + Add(new cMenuEditIntItem(tr("Denoise (0..1000) (vdpau)"), &Denoise[i], + 0, 1000)); + Sharpen[i] = ConfigVideoSharpen[i]; + Add(new cMenuEditIntItem(tr("Sharpen (-1000..1000) (vdpau)"), + &Sharpen[i], -1000, 1000)); + } + // + // audio + // + Add(SeparatorItem(tr("Audio"))); AudioDelay = ConfigVideoAudioDelay; Add(new cMenuEditIntItem(tr("Audio delay (ms)"), &AudioDelay, -1000, 1000)); @@ -349,18 +394,32 @@ cMenuSetupSoft::cMenuSetupSoft(void) */ void cMenuSetupSoft::Store(void) { + int i; + SetupStore("MakePrimary", ConfigMakePrimary = MakePrimary); - SetupStore("Deinterlace", ConfigVideoDeinterlace = Deinterlace); - VideoSetDeinterlace(ConfigVideoDeinterlace); - SetupStore("SkipChromaDeinterlace", ConfigVideoSkipChromaDeinterlace = - SkipChromaDeinterlace); - VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace); - SetupStore("Denoise", ConfigVideoDenoise = Denoise); - VideoSetDenoise(ConfigVideoDenoise); - SetupStore("Sharpen", ConfigVideoSharpen = Sharpen); - VideoSetSharpen(ConfigVideoSharpen); - SetupStore("Scaling", ConfigVideoScaling = Scaling); + + for (i = 0; i < RESOLUTIONS; ++i) { + char buf[128]; + + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling"); + SetupStore(buf, ConfigVideoScaling[i] = Scaling[i]); + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Deinterlace"); + SetupStore(buf, ConfigVideoDeinterlace[i] = Deinterlace[i]); + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], + "SkipChromaDeinterlace"); + SetupStore(buf, ConfigVideoSkipChromaDeinterlace[i] = + SkipChromaDeinterlace[i]); + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Denoise"); + SetupStore(buf, ConfigVideoDenoise[i] = Denoise[i]); + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Sharpen"); + SetupStore(buf, ConfigVideoSharpen[i] = Sharpen[i]); + } VideoSetScaling(ConfigVideoScaling); + VideoSetDeinterlace(ConfigVideoDeinterlace); + VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace); + VideoSetDenoise(ConfigVideoDenoise); + VideoSetSharpen(ConfigVideoSharpen); + SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay); VideoSetAudioDelay(ConfigVideoAudioDelay); SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough); @@ -553,9 +612,10 @@ void cSoftHdDevice::SetVolumeDevice(int volume) */ void cSoftHdDevice::StillPicture(const uchar * data, int length) { - dsyslog("[softhddev]%s:\n", __FUNCTION__); + dsyslog("[softhddev]%s: %s\n", __FUNCTION__, + data[0] == 0x47 ? "ts" : "pes"); - if ( data[0] == 0x47 ) { // ts sync + if (data[0] == 0x47) { // ts sync cDevice::StillPicture(data, length); return; } @@ -860,33 +920,48 @@ cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void) */ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value) { - //dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value); + int i; + char buf[128]; + + dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value); // FIXME: handle the values if (!strcmp(name, "MakePrimary")) { ConfigMakePrimary = atoi(value); return true; } - if (!strcmp(name, "Deinterlace")) { - VideoSetDeinterlace(ConfigVideoDeinterlace = atoi(value)); - return true; - } - if (!strcmp(name, "SkipChromaDeinterlace")) { - VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace = - atoi(value)); - return true; - } - if (!strcmp(name, "Denoise")) { - VideoSetDenoise(ConfigVideoDenoise = atoi(value)); - return true; - } - if (!strcmp(name, "Sharpen")) { - VideoSetSharpen(ConfigVideoSharpen = atoi(value)); - return true; - } - if (!strcmp(name, "Scaling")) { - VideoSetScaling(ConfigVideoScaling = atoi(value)); - return true; + for (i = 0; i < RESOLUTIONS; ++i) { + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling"); + if (!strcmp(name, buf)) { + ConfigVideoScaling[i] = atoi(value); + VideoSetScaling(ConfigVideoScaling); + return true; + } + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Deinterlace"); + if (!strcmp(name, buf)) { + ConfigVideoDeinterlace[i] = atoi(value); + VideoSetDeinterlace(ConfigVideoDeinterlace); + return true; + } + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], + "SkipChromaDeinterlace"); + if (!strcmp(name, buf)) { + ConfigVideoSkipChromaDeinterlace[i] = atoi(value); + VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace); + return true; + } + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Denoise"); + if (!strcmp(name, buf)) { + ConfigVideoDenoise[i] = atoi(value); + VideoSetDenoise(ConfigVideoDenoise); + return true; + } + snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Sharpen"); + if (!strcmp(name, buf)) { + ConfigVideoSharpen[i] = atoi(value); + VideoSetSharpen(ConfigVideoSharpen); + return true; + } } if (!strcmp(name, "AudioDelay")) { VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value)); diff --git a/video.c b/video.c index 4bf7717..5d5c982 100644 --- a/video.c +++ b/video.c @@ -129,6 +129,18 @@ // Declarations //---------------------------------------------------------------------------- +/// +/// Video resolutions selector. +/// +typedef enum _video_resolutions_ +{ + VideoResolution567i, ///< ...x567 interlaced + VideoResolution720p, ///< ...x720 progressive + VideoResolutionFake1080i, ///< 1280x1080 1440x1080 interlaced + VideoResolution1080i, ///< 1920x1080 interlaced + VideoResolutionMax ///< number of resolution indexs +} VideoResolutions; + /// /// Video deinterlace modes. /// @@ -196,25 +208,25 @@ static int VideoWindowY; ///< video outout window y coordinate static unsigned VideoWindowWidth; ///< video output window width static unsigned VideoWindowHeight; ///< video output window height - /// Default deinterlace mode -static VideoDeinterlaceModes VideoDeinterlace; + /// Default deinterlace mode. +static VideoDeinterlaceModes VideoDeinterlace[VideoResolutionMax]; /// Default number of deinterlace surfaces static const int VideoDeinterlaceSurfaces = 4; /// Default skip chroma deinterlace flag (VDPAU only) -static int VideoSkipChromaDeinterlace = 1; +static int VideoSkipChromaDeinterlace[VideoResolutionMax]; /// Default amount of noise reduction algorithm to apply (0 .. 1000). -static int VideoDenoise; +static int VideoDenoise[VideoResolutionMax]; /// Default amount of of sharpening, or blurring, to apply (-1000 .. 1000). -static int VideoSharpen; +static int VideoSharpen[VideoResolutionMax]; -// FIXME: color space +// FIXME: color space / studio levels /// Default scaling mode -static VideoScalingModes VideoScaling; +static VideoScalingModes VideoScaling[VideoResolutionMax]; /// Default audio/video delay static int VideoAudioDelay; @@ -733,6 +745,38 @@ static void GlxExit(void) #endif +//---------------------------------------------------------------------------- +// common functions +//---------------------------------------------------------------------------- + +/// +/// Calculate resolution group. +/// +/// @param width video picture raw width +/// @param height video picture raw height +/// @param interlace flag interlaced video picture +/// +/// @note interlace isn't used yet and probably wrong set by caller. +/// +static VideoResolutions VideoResolutionGroup(int width, int height, + __attribute__ ((unused)) + int interlace) +{ + if (height <= 567) { + return VideoResolution567i; + } + if (height <= 720) { + return VideoResolution720p; + } + if (height < 1080) { + return VideoResolutionFake1080i; + } + if (width < 1920) { + return VideoResolutionFake1080i; + } + return VideoResolution1080i; +} + //---------------------------------------------------------------------------- // auto-crop //---------------------------------------------------------------------------- @@ -862,7 +906,6 @@ typedef struct _vaapi_decoder_ VaapiDecoder; struct _vaapi_decoder_ { VADisplay *VaDisplay; ///< VA-API display - unsigned SurfaceFlags; ///< flags for put surface xcb_window_t Window; ///< output window int OutputX; ///< output window x @@ -870,6 +913,10 @@ struct _vaapi_decoder_ int OutputWidth; ///< output window width int OutputHeight; ///< output window height + /// flags for put surface for different resolutions groups + unsigned SurfaceFlagsTable[VideoResolutionMax]; + unsigned SurfaceFlags; ///< current flags for put surface + enum PixelFormat PixFmt; ///< ffmpeg frame pixfmt int WrongInterlacedWarned; ///< warning about interlace flag issued int Interlaced; ///< ffmpeg interlaced flag @@ -892,6 +939,7 @@ struct _vaapi_decoder_ int InputWidth; ///< video input width int InputHeight; ///< video input height AVRational InputAspect; ///< video input aspect ratio + VideoResolutions Resolution; ///< resolution group int CropX; ///< video crop x int CropY; ///< video crop y @@ -1127,6 +1175,63 @@ static void VaapiPrintFrames(const VaapiDecoder * decoder) #endif } +/// +/// Initialize surface flags. +/// +/// @param decoder video hardware decoder +/// +static void VaapiInitSurfaceFlags(VaapiDecoder * decoder) +{ + int i; + + for (i = 0; i < VideoResolutionMax; ++i) { + decoder->SurfaceFlagsTable[i] = VA_CLEAR_DRAWABLE; + // FIXME: color space conversion none, ITU-R BT.601, ITU-R BT.709 + decoder->SurfaceFlagsTable[i] |= VA_SRC_BT601; + + // 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; + break; + case VideoScalingFast: + decoder->SurfaceFlagsTable[i] |= VA_FILTER_SCALING_FAST; + break; + case VideoScalingHQ: + // vdpau backend supports only VA_FILTER_SCALING_HQ + // vdpau backend with advanced deinterlacer and my GT-210 + // is too slow + decoder->SurfaceFlagsTable[i] |= VA_FILTER_SCALING_HQ; + break; + case VideoScalingAnamorphic: + // intel backend supports only VA_FILTER_SCALING_NL_ANAMORPHIC; + // don't use it, its for 4:3 -> 16:9 scaling + decoder->SurfaceFlagsTable[i] |= + VA_FILTER_SCALING_NL_ANAMORPHIC; + break; + } + + // deinterlace flags (not yet supported by libva) + switch (VideoDeinterlace[i]) { + case VideoDeinterlaceBob: + break; + case VideoDeinterlaceWeave: + break; + case VideoDeinterlaceTemporal: + //FIXME: private hack + //decoder->SurfaceFlagsTable[i] |= 0x00002000; + break; + case VideoDeinterlaceTemporalSpatial: + //FIXME: private hack + //decoder->SurfaceFlagsTable[i] |= 0x00006000; + break; + case VideoDeinterlaceSoftware: + break; + } + } +} + /// /// Allocate new VA-API decoder. /// @@ -1147,49 +1252,8 @@ static VaapiDecoder *VaapiNewDecoder(void) decoder->VaDisplay = VaDisplay; decoder->Window = VideoWindow; - decoder->SurfaceFlags = VA_CLEAR_DRAWABLE; - // color space conversion none, ITU-R BT.601, ITU-R BT.709 - decoder->SurfaceFlags |= VA_SRC_BT601; - - // scaling flags FAST, HQ, NL_ANAMORPHIC - // FIXME: need to detect the backend to choose the parameter - switch (VideoScaling) { - case VideoScalingNormal: - decoder->SurfaceFlags |= VA_FILTER_SCALING_DEFAULT; - break; - case VideoScalingFast: - decoder->SurfaceFlags |= VA_FILTER_SCALING_FAST; - break; - case VideoScalingHQ: - // vdpau backend supports only VA_FILTER_SCALING_HQ - // vdpau backend with advanced deinterlacer and my GT-210 - // is too slow - decoder->SurfaceFlags |= VA_FILTER_SCALING_HQ; - break; - case VideoScalingAnamorphic: - // intel backend supports only VA_FILTER_SCALING_NL_ANAMORPHIC; - // don't use it, its for 4:3 -> 16:9 scaling - decoder->SurfaceFlags |= VA_FILTER_SCALING_NL_ANAMORPHIC; - break; - } - - // deinterlace flags (not yet supported by libva) - switch (VideoDeinterlace) { - case VideoDeinterlaceBob: - break; - case VideoDeinterlaceWeave: - break; - case VideoDeinterlaceTemporal: - //FIXME: private hack - //decoder->SurfaceFlags |= 0x00002000; - break; - case VideoDeinterlaceTemporalSpatial: - //FIXME: private hack - //decoder->SurfaceFlags |= 0x00006000; - break; - case VideoDeinterlaceSoftware: - break; - } + VaapiInitSurfaceFlags(decoder); + decoder->SurfaceFlags = decoder->SurfaceFlagsTable[0]; decoder->DeintImages[0].image_id = VA_INVALID_ID; decoder->DeintImages[1].image_id = VA_INVALID_ID; @@ -1719,7 +1783,13 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder, Error(_("codec: can't create config")); goto slow_path; } - // FIXME: need only to create and destroy surfaces for size changes! + // FIXME: interlaced not valid here? + decoder->Resolution = + VideoResolutionGroup(video_ctx->width, video_ctx->height, + decoder->Interlaced); + decoder->SurfaceFlags = decoder->SurfaceFlagsTable[decoder->Resolution]; + // FIXME: need only to create and destroy surfaces for size changes + // or when number of needed surfaces changed! VaapiCreateSurfaces(decoder, video_ctx->width, video_ctx->height); // bind surfaces to context @@ -1789,7 +1859,8 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface, VAStatus status; // deinterlace - if (interlaced && VideoDeinterlace != VideoDeinterlaceWeave) { + if (interlaced + && VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) { if (top_field_first) { if (field) { type = VA_BOTTOM_FIELD; @@ -1914,7 +1985,8 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface, uint32_t end; // deinterlace - if (interlaced && VideoDeinterlace != VideoDeinterlaceWeave) { + if (interlaced + && VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) { if (top_field_first) { if (field) { type = VA_BOTTOM_FIELD; @@ -2052,6 +2124,10 @@ static void VaapiSetup(VaapiDecoder * decoder, "video/vaapi: created image %dx%d with id 0x%08x and buffer id 0x%08x\n", width, height, decoder->Image->image_id, decoder->Image->buf); + // FIXME: interlaced not valid here? + decoder->Resolution = + VideoResolutionGroup(width, height, decoder->Interlaced); + decoder->SurfaceFlags = decoder->SurfaceFlagsTable[decoder->Resolution]; VaapiCreateSurfaces(decoder, width, height); #ifdef USE_GLX @@ -2529,7 +2605,8 @@ static void VaapiRenderFrame(VaapiDecoder * decoder, } #endif - if (VideoDeinterlace == VideoDeinterlaceSoftware && interlaced) { + if (VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceSoftware + && interlaced) { // FIXME: software deinterlace avpicture_deinterlace VaapiCpuDeinterlace(decoder, surface); } else { @@ -2729,7 +2806,7 @@ static void VaapiDisplayFrame(void) // FIXME: buggy libva-driver-vdpau, buggy libva-driver-intel && (VaapiBuggyVdpau || (0 && VaapiBuggyIntel && decoder->InputHeight == 1080)) - && VideoDeinterlace != VideoDeinterlaceWeave) { + && VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) { VaapiPutSurfaceX11(decoder, surface, decoder->Interlaced, decoder->TopFieldFirst, 0); put1 = GetMsTicks(); @@ -3206,6 +3283,7 @@ typedef struct _vdpau_decoder_ int InputWidth; ///< video input width int InputHeight; ///< video input height AVRational InputAspect; ///< video input aspect ratio + VideoResolutions Resolution; ///< resolution group int CropX; ///< video crop x int CropY; ///< video crop y @@ -3588,8 +3666,10 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) // feature_n = 0; if (VdpauTemporal) { - enables[feature_n] = (VideoDeinterlace == VideoDeinterlaceTemporal - || (VideoDeinterlace == VideoDeinterlaceTemporalSpatial + enables[feature_n] = + (VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceTemporal + || (VideoDeinterlace[decoder->Resolution] == + VideoDeinterlaceTemporalSpatial && !VdpauTemporalSpatial)) ? VDP_TRUE : VDP_FALSE; features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL; Debug(3, "video/vdpau: temporal deinterlace %s\n", @@ -3597,7 +3677,7 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) } if (VdpauTemporalSpatial) { enables[feature_n] = - VideoDeinterlace == + VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceTemporalSpatial ? VDP_TRUE : VDP_FALSE; features[feature_n++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; @@ -3611,13 +3691,15 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) enables[feature_n - 1] ? "enabled" : "disabled"); } if (VdpauNoiseReduction) { - enables[feature_n] = VideoDenoise ? VDP_TRUE : VDP_FALSE; + enables[feature_n] = + VideoDenoise[decoder->Resolution] ? 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; + enables[feature_n] = + VideoSharpen[decoder->Resolution] ? 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"); @@ -3625,7 +3707,8 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) for (i = VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1; i <= VdpauHqScalingMax; ++i) { enables[feature_n] = - VideoScaling == VideoScalingHQ ? VDP_TRUE : VDP_FALSE; + VideoScaling[decoder->Resolution] == + VideoScalingHQ ? VDP_TRUE : VDP_FALSE; features[feature_n++] = i; Debug(3, "video/vdpau: high quality scaling %d %s\n", 1 + i - VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1, @@ -3646,7 +3729,7 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) */ attribute_n = 0; if (VdpauSkipChroma) { - skip_chroma_value = VideoSkipChromaDeinterlace; + skip_chroma_value = VideoSkipChromaDeinterlace[decoder->Resolution]; attributes[attribute_n] = VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE; attribute_value_ptrs[attribute_n++] = &skip_chroma_value; @@ -3654,7 +3737,7 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) skip_chroma_value ? "enabled" : "disabled"); } if (VdpauNoiseReduction) { - noise_reduction_level = VideoDenoise / 1000.0; + noise_reduction_level = VideoDenoise[decoder->Resolution] / 1000.0; attributes[attribute_n] = VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL; attribute_value_ptrs[attribute_n++] = &noise_reduction_level; @@ -3662,7 +3745,7 @@ static void VdpauMixerSetup(VdpauDecoder * decoder) noise_reduction_level); } if (VdpauSharpness) { - sharpness_level = VideoSharpen / 1000.0; + sharpness_level = VideoSharpen[decoder->Resolution] / 1000.0; attributes[attribute_n] = VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL; attribute_value_ptrs[attribute_n++] = &sharpness_level; @@ -4488,6 +4571,7 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder, abort(); goto slow_path; } + // FIXME: Combine this with VdpauSetup decoder->CropX = 0; decoder->CropY = 0; @@ -4501,7 +4585,11 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder, VdpauMixerSetup(decoder); - // FIXME: need only to create and destroy surfaces for size changes! + // FIXME: need only to create and destroy surfaces for size changes + // or when number of needed surfaces changed! + decoder->Resolution = + VideoResolutionGroup(video_ctx->width, video_ctx->height, + decoder->Interlaced); VdpauCreateSurfaces(decoder, video_ctx->width, video_ctx->height); Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_pix_fmt_name(fmt_idx[0])); @@ -4532,6 +4620,9 @@ static void VdpauSetup(VdpauDecoder * decoder, VdpauCleanup(decoder); VdpauMixerSetup(decoder); + decoder->Resolution = + VideoResolutionGroup(video_ctx->width, video_ctx->height, + decoder->Interlaced); VdpauCreateSurfaces(decoder, video_ctx->width, video_ctx->height); // get real surface size @@ -4742,7 +4833,8 @@ static void VdpauRenderFrame(VdpauDecoder * decoder, } #endif - if (VideoDeinterlace == VideoDeinterlaceSoftware && interlaced) { + if (VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceSoftware + && interlaced) { // FIXME: software deinterlace avpicture_deinterlace // FIXME: VdpauCpuDeinterlace(decoder, surface); } else { @@ -4940,7 +5032,8 @@ static void VdpauMixVideo(VdpauDecoder * decoder) VdpauGrabSurface(decoder); #endif - if (decoder->Interlaced && VideoDeinterlace != VideoDeinterlaceWeave) { + if (decoder->Interlaced + && VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) { // // Build deinterlace structures // @@ -6576,41 +6669,56 @@ void VideoSetOutputPosition(int x, int y, int width, int height) /// /// Set deinterlace mode. /// -void VideoSetDeinterlace(int mode) +void VideoSetDeinterlace(int mode[VideoResolutionMax]) { - VideoDeinterlace = mode; + VideoDeinterlace[0] = mode[0]; + VideoDeinterlace[1] = mode[1]; + VideoDeinterlace[2] = mode[2]; + VideoDeinterlace[3] = mode[3]; } /// /// Set skip chroma deinterlace on/off. /// -void VideoSetSkipChromaDeinterlace(int onoff) +void VideoSetSkipChromaDeinterlace(int onoff[VideoResolutionMax]) { - VideoSkipChromaDeinterlace = onoff; + VideoSkipChromaDeinterlace[0] = onoff[0]; + VideoSkipChromaDeinterlace[1] = onoff[1]; + VideoSkipChromaDeinterlace[2] = onoff[2]; + VideoSkipChromaDeinterlace[3] = onoff[3]; } /// /// Set denoise level (0 .. 1000). /// -void VideoSetDenoise(int level) +void VideoSetDenoise(int level[VideoResolutionMax]) { - VideoDenoise = level; + VideoDenoise[0] = level[0]; + VideoSharpen[1] = level[1]; + VideoSharpen[2] = level[2]; + VideoSharpen[3] = level[3]; } /// /// Set sharpness level (-1000 .. 1000). /// -void VideoSetSharpen(int level) +void VideoSetSharpen(int level[VideoResolutionMax]) { - VideoSharpen = level; + VideoSharpen[0] = level[0]; + VideoSharpen[1] = level[1]; + VideoSharpen[2] = level[2]; + VideoSharpen[3] = level[3]; } /// /// Set scaling mode. /// -void VideoSetScaling(int mode) +void VideoSetScaling(int mode[VideoResolutionMax]) { - VideoScaling = mode; + VideoScaling[0] = mode[0]; + VideoScaling[1] = mode[1]; + VideoScaling[2] = mode[2]; + VideoScaling[3] = mode[3]; } /// diff --git a/video.h b/video.h index 159d019..815af72 100644 --- a/video.h +++ b/video.h @@ -77,19 +77,19 @@ extern int VideoSetGeometry(const char *); extern void VideoSetOutputPosition(int, int, int, int); /// Set deinterlace. -extern void VideoSetDeinterlace(int); +extern void VideoSetDeinterlace(int[]); /// Set skip chroma deinterlace. -extern void VideoSetSkipChromaDeinterlace(int); +extern void VideoSetSkipChromaDeinterlace(int[]); /// Set scaling. -extern void VideoSetScaling(int); +extern void VideoSetScaling(int[]); /// Set denoise. -extern void VideoSetDenoise(int); +extern void VideoSetDenoise(int[]); /// Set sharpen. -extern void VideoSetSharpen(int); +extern void VideoSetSharpen(int[]); /// Set audio delay. extern void VideoSetAudioDelay(int);