mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
VDPAU: Add auto-crop support.
This commit is contained in:
parent
eb024558de
commit
0422b6aa5a
@ -1,7 +1,8 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
Release Version 0.3.6
|
Release Version 0.4.0
|
||||||
|
VDPAU: Add auto-crop support.
|
||||||
VDPAU: Changed OSD alpha calculation.
|
VDPAU: Changed OSD alpha calculation.
|
||||||
Fix bug: Used VideoSharpen for denoise settings.
|
Fix bug: Used VideoSharpen for denoise settings.
|
||||||
Instant update deinterlace/... configuration changes.
|
Instant update deinterlace/... configuration changes.
|
||||||
|
23
README.txt
23
README.txt
@ -24,17 +24,20 @@ A software and GPU emulated HD output device plugin for VDR.
|
|||||||
o Video CPU/VA-API
|
o Video CPU/VA-API
|
||||||
o Video VDPAU/VDPAU
|
o Video VDPAU/VDPAU
|
||||||
o Video CPU/VDPAU
|
o Video CPU/VDPAU
|
||||||
|
o Audio FFMpeg/Alsa/Analog
|
||||||
|
o Audio FFMpeg/Alsa/Digital
|
||||||
|
o Audio FFMpeg/OSS/Analog
|
||||||
|
o HDMI/SPDIF Passthrough
|
||||||
|
o VA-API bob software deinterlace
|
||||||
|
o Auto-crop
|
||||||
|
|
||||||
o planned: Video VA-API/Opengl
|
o planned: Video VA-API/Opengl
|
||||||
o planned: Video VDPAU/Opengl
|
o planned: Video VDPAU/Opengl
|
||||||
o planned: Video CPU/Xv
|
o planned: Video CPU/Xv
|
||||||
o planned: Video CPU/Opengl
|
o planned: Video CPU/Opengl
|
||||||
o planned: Software Deinterlacer
|
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
|
||||||
o planned: Video XvBA/XvBA
|
o planned: Video XvBA/XvBA
|
||||||
o Audio FFMpeg/Alsa/Analog
|
o planned: atmo light support
|
||||||
o Audio FFMpeg/Alsa/Digital
|
|
||||||
o Audio FFMpeg/OSS/Analog
|
|
||||||
o Alsa HDMI/SPDIF Passthrough
|
|
||||||
o planned: OSS HDMI/SPDIF Passthrough
|
|
||||||
|
|
||||||
To compile you must have the 'requires' installed.
|
To compile you must have the 'requires' installed.
|
||||||
|
|
||||||
@ -125,6 +128,14 @@ Setup: /etc/vdr/setup.conf
|
|||||||
softhddevice.AudioPassthrough = 0
|
softhddevice.AudioPassthrough = 0
|
||||||
0 = none, 1 = AC-3
|
0 = none, 1 = AC-3
|
||||||
|
|
||||||
|
softhddevice.AutoCrop.Interval = 0
|
||||||
|
0 disables auto-crop
|
||||||
|
n each 'n' frames auto-crop is checked.
|
||||||
|
|
||||||
|
softhddevice.AutoCrop.Delay = 0
|
||||||
|
if auto-crop is over after 'n' intervals the same, the cropping is
|
||||||
|
used.
|
||||||
|
|
||||||
Setup: /etc/vdr/remote.conf
|
Setup: /etc/vdr/remote.conf
|
||||||
------
|
------
|
||||||
|
|
||||||
|
2
Todo
2
Todo
@ -21,7 +21,6 @@ $Id: $
|
|||||||
missing:
|
missing:
|
||||||
software deinterlace (yadif, ...)
|
software deinterlace (yadif, ...)
|
||||||
software decoder with software deinterlace
|
software decoder with software deinterlace
|
||||||
auto crop
|
|
||||||
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
||||||
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
||||||
suspend output / energie saver: stop audio, stop video, configurable
|
suspend output / energie saver: stop audio, stop video, configurable
|
||||||
@ -41,6 +40,7 @@ libva:
|
|||||||
hard channel switch
|
hard channel switch
|
||||||
yaepghd (VaapiSetOutputPosition) support
|
yaepghd (VaapiSetOutputPosition) support
|
||||||
can associate ony displayed part of osd
|
can associate ony displayed part of osd
|
||||||
|
auto crop for va-api
|
||||||
|
|
||||||
libva-intel-driver:
|
libva-intel-driver:
|
||||||
intel still has hangups most with 1080i
|
intel still has hangups most with 1080i
|
||||||
|
2
audio.c
2
audio.c
@ -2125,7 +2125,7 @@ void AudioExit(void)
|
|||||||
#ifdef USE_AUDIO_THREAD
|
#ifdef USE_AUDIO_THREAD
|
||||||
AudioExitThread();
|
AudioExitThread();
|
||||||
#endif
|
#endif
|
||||||
if ( UsedAudioModule ) {
|
if (UsedAudioModule) {
|
||||||
UsedAudioModule->Exit();
|
UsedAudioModule->Exit();
|
||||||
}
|
}
|
||||||
#ifdef USE_AUDIORING
|
#ifdef USE_AUDIORING
|
||||||
|
@ -42,7 +42,7 @@ extern "C"
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const char *const VERSION = "0.3.5";
|
static const char *const VERSION = "0.4.0";
|
||||||
static const char *const DESCRIPTION =
|
static const char *const DESCRIPTION =
|
||||||
trNOOP("A software and GPU emulated HD device");
|
trNOOP("A software and GPU emulated HD device");
|
||||||
|
|
||||||
@ -79,6 +79,9 @@ static int ConfigVideoScaling[RESOLUTIONS];
|
|||||||
static int ConfigVideoAudioDelay; ///< config audio delay
|
static int ConfigVideoAudioDelay; ///< config audio delay
|
||||||
static int ConfigAudioPassthrough; ///< config audio pass-through
|
static int ConfigAudioPassthrough; ///< config audio pass-through
|
||||||
|
|
||||||
|
static int ConfigAutoCropInterval; ///< auto crop detection interval
|
||||||
|
static int ConfigAutoCropDelay; ///< auto crop detection delay
|
||||||
|
|
||||||
static volatile char DoMakePrimary; ///< flag switch primary
|
static volatile char DoMakePrimary; ///< flag switch primary
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -362,6 +365,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
|||||||
int Sharpen[RESOLUTIONS];
|
int Sharpen[RESOLUTIONS];
|
||||||
int AudioDelay;
|
int AudioDelay;
|
||||||
int AudioPassthrough;
|
int AudioPassthrough;
|
||||||
|
int AutoCropInterval;
|
||||||
|
int AutoCropDelay;
|
||||||
protected:
|
protected:
|
||||||
virtual void Store(void);
|
virtual void Store(void);
|
||||||
public:
|
public:
|
||||||
@ -370,6 +375,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
** Create a seperator item.
|
** Create a seperator item.
|
||||||
|
**
|
||||||
|
** @param label text inside separator
|
||||||
*/
|
*/
|
||||||
static inline cOsdItem *SeparatorItem(const char *label)
|
static inline cOsdItem *SeparatorItem(const char *label)
|
||||||
{
|
{
|
||||||
@ -439,6 +446,16 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
|||||||
AudioPassthrough = ConfigAudioPassthrough;
|
AudioPassthrough = ConfigAudioPassthrough;
|
||||||
Add(new cMenuEditStraItem(tr("Audio pass-through"), &AudioPassthrough, 2,
|
Add(new cMenuEditStraItem(tr("Audio pass-through"), &AudioPassthrough, 2,
|
||||||
passthrough));
|
passthrough));
|
||||||
|
//
|
||||||
|
// auto-crop
|
||||||
|
//
|
||||||
|
Add(SeparatorItem(tr("Auto-crop")));
|
||||||
|
AutoCropInterval = ConfigAutoCropInterval;
|
||||||
|
Add(new cMenuEditIntItem(tr("autocrop interval (frames)"),
|
||||||
|
&AutoCropInterval, 0, 200));
|
||||||
|
AutoCropDelay = ConfigAutoCropDelay;
|
||||||
|
Add(new cMenuEditIntItem(tr("autocrop delay (n * interval)"),
|
||||||
|
&AutoCropDelay, 0, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -478,6 +495,11 @@ void cMenuSetupSoft::Store(void)
|
|||||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||||
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
||||||
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
||||||
|
|
||||||
|
SetupStore("AutoCrop.Interval", ConfigAutoCropInterval = AutoCropInterval);
|
||||||
|
SetupStore("AutoCrop.Delay", ConfigAutoCropDelay = AutoCropDelay);
|
||||||
|
|
||||||
|
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1001,11 +1023,15 @@ cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
** Parse setup parameters
|
** Parse setup parameters
|
||||||
|
**
|
||||||
|
** @param name paramter name (case sensetive)
|
||||||
|
** @param value value as string
|
||||||
|
**
|
||||||
|
** @returns true if the parameter is supported.
|
||||||
*/
|
*/
|
||||||
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char buf[128];
|
|
||||||
|
|
||||||
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
||||||
|
|
||||||
@ -1018,6 +1044,8 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling");
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling");
|
||||||
if (!strcmp(name, buf)) {
|
if (!strcmp(name, buf)) {
|
||||||
ConfigVideoScaling[i] = atoi(value);
|
ConfigVideoScaling[i] = atoi(value);
|
||||||
@ -1050,6 +1078,7 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(name, "AudioDelay")) {
|
if (!strcmp(name, "AudioDelay")) {
|
||||||
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
||||||
return true;
|
return true;
|
||||||
@ -1059,6 +1088,17 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(name, "AutoCrop.Interval")) {
|
||||||
|
VideoSetAutoCrop(ConfigAutoCropInterval =
|
||||||
|
atoi(value), ConfigAutoCropDelay);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcmp(name, "AutoCrop.Delay")) {
|
||||||
|
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay =
|
||||||
|
atoi(value));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
267
video.c
267
video.c
@ -37,6 +37,7 @@
|
|||||||
///
|
///
|
||||||
|
|
||||||
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
||||||
|
#define USE_AUTOCROP ///< compile autocrop support
|
||||||
#define noUSE_GRAB ///< experimental grab code
|
#define noUSE_GRAB ///< experimental grab code
|
||||||
#define noUSE_GLX ///< outdated GLX code
|
#define noUSE_GLX ///< outdated GLX code
|
||||||
#define noUSE_DOUBLEBUFFER ///< use GLX double buffers
|
#define noUSE_DOUBLEBUFFER ///< use GLX double buffers
|
||||||
@ -820,20 +821,31 @@ static VideoResolutions VideoResolutionGroup(int width, int height,
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
///
|
///
|
||||||
/// avfilter_vf_cropdetect
|
/// Autocrop context structure and typedef.
|
||||||
///
|
///
|
||||||
typedef struct _video_auto_crop_ctx_
|
typedef struct _auto_crop_ctx_
|
||||||
{
|
{
|
||||||
int x1; ///< detected left border
|
int X1; ///< detected left border
|
||||||
int x2; ///< detected right border
|
int X2; ///< detected right border
|
||||||
int y1; ///< detected top border
|
int Y1; ///< detected top border
|
||||||
int y2; ///< detected bottom border
|
int Y2; ///< detected bottom border
|
||||||
} VideoAutoCropCtx;
|
|
||||||
|
int Count; ///< counter to delay switch
|
||||||
|
int State; ///< autocrop state (0, 14, 16)
|
||||||
|
|
||||||
|
} AutoCropCtx;
|
||||||
|
|
||||||
|
#ifdef USE_AUTOCROP
|
||||||
|
|
||||||
#define YBLACK 0x20 ///< below is black
|
#define YBLACK 0x20 ///< below is black
|
||||||
#define UVBLACK 0x80 ///< around is black
|
#define UVBLACK 0x80 ///< around is black
|
||||||
#define M64 UINT64_C(0x0101010101010101) ///< 64bit multiplicator
|
#define M64 UINT64_C(0x0101010101010101) ///< 64bit multiplicator
|
||||||
|
|
||||||
|
/// percent of width to ignore logos
|
||||||
|
static const int AutoCropLogoIgnore = 24;
|
||||||
|
static int AutoCropInterval; ///< check interval
|
||||||
|
static int AutoCropDelay; ///< switch delay
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Detect black line Y.
|
/// Detect black line Y.
|
||||||
///
|
///
|
||||||
@ -872,8 +884,19 @@ static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride)
|
|||||||
///
|
///
|
||||||
/// Auto detect black borders and crop them.
|
/// Auto detect black borders and crop them.
|
||||||
///
|
///
|
||||||
static void AutoCropDetect(int width, int height, void *data[3],
|
/// @param autocrop autocrop variables
|
||||||
uint32_t pitches[3])
|
/// @param width frame width in pixel
|
||||||
|
/// @param height frame height in pixel
|
||||||
|
/// @param data frame planes data (Y, U, V)
|
||||||
|
/// @param pitches frame planes pitches (Y, U, V)
|
||||||
|
///
|
||||||
|
/// @note FIXME: can reduce the checked range, left, right crop isn't
|
||||||
|
/// used yet.
|
||||||
|
///
|
||||||
|
/// @note FIXME: only Y is checked, for black.
|
||||||
|
///
|
||||||
|
static void AutoCropDetect(AutoCropCtx * autocrop, int width, int height,
|
||||||
|
void *data[3], uint32_t pitches[3])
|
||||||
{
|
{
|
||||||
const void *data_y;
|
const void *data_y;
|
||||||
unsigned length_y;
|
unsigned length_y;
|
||||||
@ -886,15 +909,15 @@ static void AutoCropDetect(int width, int height, void *data[3],
|
|||||||
int logo_skip;
|
int logo_skip;
|
||||||
|
|
||||||
//
|
//
|
||||||
// ignore top+bottom 4 lines and left+right 8 pixels
|
// ignore top+bottom 6 lines and left+right 8 pixels
|
||||||
//
|
//
|
||||||
#define SKIP_X 8
|
#define SKIP_X 8
|
||||||
#define SKIP_Y 4
|
#define SKIP_Y 6
|
||||||
x1 = width - 1;
|
x1 = width - 1;
|
||||||
x2 = 0;
|
x2 = 0;
|
||||||
y1 = height - 1;
|
y1 = height - 1;
|
||||||
y2 = 0;
|
y2 = 0;
|
||||||
logo_skip = SKIP_X;
|
logo_skip = SKIP_X + (((width * AutoCropLogoIgnore) / 100 + 8) / 8) * 8;
|
||||||
|
|
||||||
data_y = data[0];
|
data_y = data[0];
|
||||||
length_y = pitches[0];
|
length_y = pitches[0];
|
||||||
@ -957,12 +980,21 @@ static void AutoCropDetect(int width, int height, void *data[3],
|
|||||||
Debug(3, "video/autocrop: top=%d bottom=%d left=%d right=%d\n", y1, y2,
|
Debug(3, "video/autocrop: top=%d bottom=%d left=%d right=%d\n", y1, y2,
|
||||||
x1, x2);
|
x1, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autocrop->X1 = x1;
|
||||||
|
autocrop->X2 = x2;
|
||||||
|
autocrop->Y1 = y1;
|
||||||
|
autocrop->Y2 = y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// software - deinterlace
|
// software - deinterlace
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// FIXME: move general software deinterlace functions to here.
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// VA-API
|
// VA-API
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -1703,6 +1735,9 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder)
|
|||||||
}
|
}
|
||||||
Debug(3, "video: aspect output %dx%d+%d+%d\n", decoder->OutputWidth,
|
Debug(3, "video: aspect output %dx%d+%d+%d\n", decoder->OutputWidth,
|
||||||
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
||||||
|
|
||||||
|
//decoder->AutoCrop->State = 0;
|
||||||
|
//decoder->AutoCrop->Count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -3698,6 +3733,8 @@ typedef struct _vdpau_decoder_
|
|||||||
int CropWidth; ///< video crop width
|
int CropWidth; ///< video crop width
|
||||||
int CropHeight; ///< video crop height
|
int CropHeight; ///< video crop height
|
||||||
|
|
||||||
|
AutoCropCtx AutoCrop[1]; ///< autocrop variables
|
||||||
|
|
||||||
#ifdef noyetUSE_GLX
|
#ifdef noyetUSE_GLX
|
||||||
GLuint GlTexture[2]; ///< gl texture for VDPAU
|
GLuint GlTexture[2]; ///< gl texture for VDPAU
|
||||||
void *GlxSurface[2]; ///< VDPAU/GLX surface
|
void *GlxSurface[2]; ///< VDPAU/GLX surface
|
||||||
@ -4906,6 +4943,7 @@ static void VdpauUpdateOutput(VdpauDecoder * decoder)
|
|||||||
case VideoStretch:
|
case VideoStretch:
|
||||||
case VideoZoom:
|
case VideoZoom:
|
||||||
case VideoAnamorphic:
|
case VideoAnamorphic:
|
||||||
|
// AutoCrop
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4925,6 +4963,9 @@ static void VdpauUpdateOutput(VdpauDecoder * decoder)
|
|||||||
}
|
}
|
||||||
Debug(3, "video: aspect output %dx%d+%d+%d\n", decoder->OutputWidth,
|
Debug(3, "video: aspect output %dx%d+%d+%d\n", decoder->OutputWidth,
|
||||||
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
||||||
|
|
||||||
|
decoder->AutoCrop->State = 0;
|
||||||
|
decoder->AutoCrop->Count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -5162,6 +5203,8 @@ static void VdpauSetup(VdpauDecoder * decoder,
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_GRAB
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Grab video surface.
|
/// Grab video surface.
|
||||||
///
|
///
|
||||||
@ -5213,6 +5256,9 @@ static void VdpauGrabSurface(VdpauDecoder * decoder)
|
|||||||
data[2] = base + width * height + width * height / 4;
|
data[2] = base + width * height + width * height / 4;
|
||||||
format = VDP_YCBCR_FORMAT_YV12;
|
format = VDP_YCBCR_FORMAT_YV12;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
Error(_("video/vdpau: unsupported chroma type %d\n"), chroma_type);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
status = VdpauVideoSurfaceGetBitsYCbCr(surface, format, data, pitches);
|
status = VdpauVideoSurfaceGetBitsYCbCr(surface, format, data, pitches);
|
||||||
if (status != VDP_STATUS_OK) {
|
if (status != VDP_STATUS_OK) {
|
||||||
@ -5221,11 +5267,165 @@ static void VdpauGrabSurface(VdpauDecoder * decoder)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoCropDetect(width, height, data, pitches);
|
|
||||||
|
|
||||||
free(base);
|
free(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_AUTOCROP
|
||||||
|
|
||||||
|
///
|
||||||
|
/// VDPAU Auto crop support.
|
||||||
|
///
|
||||||
|
/// @param decoder VDPAU hw decoder
|
||||||
|
///
|
||||||
|
static void VdpauAutoCrop(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];
|
||||||
|
int crop14;
|
||||||
|
int crop16;
|
||||||
|
int next_state;
|
||||||
|
VdpYCbCrFormat format;
|
||||||
|
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
Error(_("video/vdpau: unsupported chroma type %d\n"), chroma_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoCropDetect(decoder->AutoCrop, width, height, data, pitches);
|
||||||
|
free(base);
|
||||||
|
|
||||||
|
// ignore black frames
|
||||||
|
if (decoder->AutoCrop->Y1 >= decoder->AutoCrop->Y2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
crop14 =
|
||||||
|
(decoder->InputWidth * decoder->InputAspect.num * 9) /
|
||||||
|
(decoder->InputAspect.den * 14);
|
||||||
|
crop14 = (decoder->InputHeight - crop14) / 2;
|
||||||
|
crop16 =
|
||||||
|
(decoder->InputWidth * decoder->InputAspect.num * 9) /
|
||||||
|
(decoder->InputAspect.den * 16);
|
||||||
|
crop16 = (decoder->InputHeight - crop16) / 2;
|
||||||
|
|
||||||
|
// -2 for rounding errors
|
||||||
|
if (decoder->AutoCrop->Y1 >= crop16 - 2
|
||||||
|
&& decoder->InputHeight - decoder->AutoCrop->Y2 >= crop16 - 2) {
|
||||||
|
next_state = 16;
|
||||||
|
} else if (decoder->AutoCrop->Y1 >= crop14 - 2
|
||||||
|
&& decoder->InputHeight - decoder->AutoCrop->Y2 >= crop14 - 2) {
|
||||||
|
next_state = 14;
|
||||||
|
} else {
|
||||||
|
next_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoder->AutoCrop->State == next_state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(3, "video: crop aspect %d:%d %d/%d %d+%d\n",
|
||||||
|
decoder->InputAspect.num, decoder->InputAspect.den, crop14, crop16,
|
||||||
|
decoder->AutoCrop->Y1, decoder->InputHeight - decoder->AutoCrop->Y2);
|
||||||
|
|
||||||
|
Debug(3, "video: crop aspect %d -> %d\n", decoder->AutoCrop->State,
|
||||||
|
next_state);
|
||||||
|
|
||||||
|
switch (decoder->AutoCrop->State) {
|
||||||
|
case 16:
|
||||||
|
case 14:
|
||||||
|
if (decoder->AutoCrop->Count++ < AutoCropDelay / 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
if (decoder->AutoCrop->Count++ < AutoCropDelay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder->AutoCrop->Count = 0;
|
||||||
|
decoder->AutoCrop->State = next_state;
|
||||||
|
|
||||||
|
if (next_state) {
|
||||||
|
decoder->CropX = 0;
|
||||||
|
decoder->CropY = next_state == 16 ? crop16 : crop14;
|
||||||
|
decoder->CropWidth = decoder->InputWidth;
|
||||||
|
decoder->CropHeight = decoder->InputHeight - decoder->CropY * 2;
|
||||||
|
|
||||||
|
// FIXME: this overwrites user choosen output position
|
||||||
|
// FIXME: resize kills the auto crop values
|
||||||
|
decoder->OutputX = 0;
|
||||||
|
decoder->OutputY = 0;
|
||||||
|
decoder->OutputWidth = (VideoWindowHeight * next_state) / 9;
|
||||||
|
decoder->OutputHeight = (VideoWindowWidth * 9) / next_state;
|
||||||
|
if ((unsigned)decoder->OutputWidth > VideoWindowWidth) {
|
||||||
|
decoder->OutputWidth = VideoWindowWidth;
|
||||||
|
decoder->OutputY = (VideoWindowHeight - decoder->OutputHeight) / 2;
|
||||||
|
} else if ((unsigned)decoder->OutputHeight > VideoWindowHeight) {
|
||||||
|
decoder->OutputHeight = VideoWindowHeight;
|
||||||
|
decoder->OutputX = (VideoWindowWidth - decoder->OutputWidth) / 2;
|
||||||
|
}
|
||||||
|
Debug(3, "video: aspect output %dx%d %dx%d+%d+%d\n",
|
||||||
|
decoder->InputWidth, decoder->InputHeight, decoder->OutputWidth,
|
||||||
|
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
||||||
|
} else {
|
||||||
|
decoder->CropX = 0;
|
||||||
|
decoder->CropY = 0;
|
||||||
|
decoder->CropWidth = decoder->InputWidth;
|
||||||
|
decoder->CropHeight = decoder->InputHeight;
|
||||||
|
|
||||||
|
VdpauUpdateOutput(decoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Queue output surface.
|
/// Queue output surface.
|
||||||
///
|
///
|
||||||
@ -5568,6 +5768,24 @@ static void VdpauMixVideo(VdpauDecoder * decoder)
|
|||||||
#ifdef USE_GRAB
|
#ifdef USE_GRAB
|
||||||
VdpauGrabSurface(decoder);
|
VdpauGrabSurface(decoder);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_AUTOCROP
|
||||||
|
// reduce load, check only n frames
|
||||||
|
if (AutoCropInterval && !(decoder->FrameCounter % AutoCropInterval)) {
|
||||||
|
AVRational display_aspect_ratio;
|
||||||
|
|
||||||
|
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
||||||
|
decoder->InputWidth * decoder->InputAspect.num,
|
||||||
|
decoder->InputHeight * decoder->InputAspect.den, 1024 * 1024);
|
||||||
|
|
||||||
|
// only 4:3 with 16:9/14:9 inside supported
|
||||||
|
if (display_aspect_ratio.num == 4 && display_aspect_ratio.den == 3) {
|
||||||
|
VdpauAutoCrop(decoder);
|
||||||
|
} else {
|
||||||
|
decoder->AutoCrop->Count = 0;
|
||||||
|
decoder->AutoCrop->State = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (decoder->Interlaced
|
if (decoder->Interlaced
|
||||||
&& VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) {
|
&& VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) {
|
||||||
@ -7481,6 +7699,25 @@ void VideoSetAudioDelay(int ms)
|
|||||||
VideoAudioDelay = ms * 90;
|
VideoAudioDelay = ms * 90;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set auto-crop parameters.
|
||||||
|
///
|
||||||
|
void VideoSetAutoCrop(int interval, int delay)
|
||||||
|
{
|
||||||
|
#ifdef USE_AUTOCROP
|
||||||
|
int i;
|
||||||
|
|
||||||
|
AutoCropInterval = interval;
|
||||||
|
AutoCropDelay = delay;
|
||||||
|
#ifdef USE_VDPAU
|
||||||
|
for (i = 0; i < VdpauDecoderN; ++i) {
|
||||||
|
VdpauDecoders[i]->AutoCrop->State = 0;
|
||||||
|
VdpauDecoders[i]->AutoCrop->Count = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Initialize video output module.
|
/// Initialize video output module.
|
||||||
///
|
///
|
||||||
@ -7659,7 +7896,7 @@ static void PrintVersion(void)
|
|||||||
#ifdef GIT_REV
|
#ifdef GIT_REV
|
||||||
"(GIT-" GIT_REV ")"
|
"(GIT-" GIT_REV ")"
|
||||||
#endif
|
#endif
|
||||||
",\n\t(c) 2009 - 2011 by Johns\n"
|
",\n\t(c) 2009 - 2012 by Johns\n"
|
||||||
"\tLicense AGPLv3: GNU Affero General Public License version 3\n");
|
"\tLicense AGPLv3: GNU Affero General Public License version 3\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
video.h
3
video.h
@ -100,6 +100,9 @@ extern void VideoSetSharpen(int[]);
|
|||||||
/// Set audio delay.
|
/// Set audio delay.
|
||||||
extern void VideoSetAudioDelay(int);
|
extern void VideoSetAudioDelay(int);
|
||||||
|
|
||||||
|
/// Set auto-crop parameters.
|
||||||
|
extern void VideoSetAutoCrop(int, int);
|
||||||
|
|
||||||
/// Clear OSD.
|
/// Clear OSD.
|
||||||
extern void VideoOsdClear(void);
|
extern void VideoOsdClear(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user