summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2012-01-09 17:03:04 +0100
committerJohns <johns98@gmx.net>2012-01-09 17:03:04 +0100
commit96eefca699ad32353ddb8c71f25ee3f5d864b156 (patch)
tree523422dcb6155146e14c4ad883413b58165c1e00
parent5e005eeff5e40ac78fa17bb0ffc44b7a4aa4e1f6 (diff)
downloadvdr-plugin-softhddevice-96eefca699ad32353ddb8c71f25ee3f5d864b156.tar.gz
vdr-plugin-softhddevice-96eefca699ad32353ddb8c71f25ee3f5d864b156.tar.bz2
Video improvements.
Fix generate of video output from StillPicture. Add support for resolution dependend video parameterts (Deinterlace, Scaling, Denoise, Sharpen, ...).
-rw-r--r--ChangeLog4
-rw-r--r--README.txt18
-rw-r--r--Todo1
-rw-r--r--softhddev.c17
-rw-r--r--softhddevice.cpp189
-rw-r--r--video.c264
-rw-r--r--video.h10
7 files changed, 350 insertions, 153 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
+ <res> of the next parameters is 567i, 720p, 1080i_fake or 1080i.
+ 1080i_fake is 1280x1080 or 1440x1080
+ 1080i is "real" 1920x1080
+
+ softhddevice.<res>.Scaling = 0
+ 0 = normal, 1 = fast, 2 = HQ, 3 = anamorphic
+
+ softhddevice.<res>.Deinterlace = 0
0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software
(only 0, 1 supported with vaapi)
- softhddevice.SkipChromaDeinterlace = 0
+ softhddevice.<res>.SkipChromaDeinterlace = 0
0 = disabled, 1 = enabled (for slower cards, poor qualität)
- softhddevice.Denoise = 0
+ softhddevice.<res>.Denoise = 0
0 .. 1000 noise reduction level (0 off, 1000 max)
- softhddevice.Sharpness = 0
+ softhddevice.<res>.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:
@@ -303,6 +320,19 @@ class cMenuSetupSoft:public cMenuSetupPage
};
/**
+** 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.
*/
cMenuSetupSoft::cMenuSetupSoft(void)
@@ -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);
+
+ 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);
- SetupStore("SkipChromaDeinterlace", ConfigVideoSkipChromaDeinterlace =
- SkipChromaDeinterlace);
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
- SetupStore("Denoise", ConfigVideoDenoise = Denoise);
VideoSetDenoise(ConfigVideoDenoise);
- SetupStore("Sharpen", ConfigVideoSharpen = Sharpen);
VideoSetSharpen(ConfigVideoSharpen);
- SetupStore("Scaling", ConfigVideoScaling = Scaling);
- VideoSetScaling(ConfigVideoScaling);
+
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
@@ -130,6 +130,18 @@
//----------------------------------------------------------------------------
///
+/// 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.
///
typedef enum _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;
@@ -734,6 +746,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
@@ -1128,6 +1176,63 @@ static void VaapiPrintFrames(const VaapiDecoder * decoder)
}
///
+/// 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.
///
/// @returns a new prepared va-api hardware 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);