mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
VDPAU: Add screenshot support.
This commit is contained in:
parent
5ba88bb822
commit
e32857a27a
@ -2,6 +2,7 @@ User johns
|
|||||||
Date:
|
Date:
|
||||||
|
|
||||||
Release Version 0.4.0
|
Release Version 0.4.0
|
||||||
|
VDPAU: Add grab image support.
|
||||||
VDPAU: Add auto-crop support.
|
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.
|
||||||
|
23
softhddev.c
23
softhddev.c
@ -791,6 +791,29 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Grabs the currently visible screen image.
|
||||||
|
**
|
||||||
|
** @param size size of the returned data
|
||||||
|
** @param jpeg flag true, create JPEG data
|
||||||
|
** @param quality JPEG quality
|
||||||
|
** @param width number of horizontal pixels in the frame
|
||||||
|
** @param height number of vertical pixels in the frame
|
||||||
|
*/
|
||||||
|
uint8_t *GrabImage(int *size, int jpeg, int quality, int width, int height)
|
||||||
|
{
|
||||||
|
if (jpeg) {
|
||||||
|
(void)quality;
|
||||||
|
Error(_("softhddev: jpeg grabbing not supported\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (width != -1 && height != -1) {
|
||||||
|
Error(_("softhddev: scaling not supported\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return VideoGrab(size, &width, &height);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,6 +46,8 @@ extern "C"
|
|||||||
extern int PlayVideo(const uint8_t *, int);
|
extern int PlayVideo(const uint8_t *, int);
|
||||||
/// C plugin play TS video packet
|
/// C plugin play TS video packet
|
||||||
extern void PlayTsVideo(const uint8_t *, int);
|
extern void PlayTsVideo(const uint8_t *, int);
|
||||||
|
/// C plugin grab an image
|
||||||
|
extern uint8_t *GrabImage(int *, int, int, int, int);
|
||||||
|
|
||||||
/// C plugin set play mode
|
/// C plugin set play mode
|
||||||
extern void SetPlayMode(void);
|
extern void SetPlayMode(void);
|
||||||
|
@ -126,7 +126,7 @@ extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
|
|||||||
csoft = new cSoftRemote(keymap);
|
csoft = new cSoftRemote(keymap);
|
||||||
}
|
}
|
||||||
|
|
||||||
dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
|
//dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
|
||||||
csoft->Put(key, repeat, release);
|
csoft->Put(key, repeat, release);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,8 +295,8 @@ void cSoftOsd::Flush(void)
|
|||||||
h = pm->ViewPort().Height();
|
h = pm->ViewPort().Height();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dsyslog("[softhddev]%s: draw %dx%d+%d+%d %p\n", __FUNCTION__, w, h, x,
|
dsyslog("[softhddev]%s: draw %dx%d+%d+%d %p\n", __FUNCTION__, w, h,
|
||||||
y, pm->Data());
|
x, y, pm->Data());
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OsdDrawARGB(x, y, w, h, pm->Data());
|
OsdDrawARGB(x, y, w, h, pm->Data());
|
||||||
@ -832,13 +832,22 @@ int cSoftHdDevice::PlayTsAudio(const uchar * data, int length)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int sizex,
|
/**
|
||||||
int sizey)
|
** Grabs the currently visible screen image.
|
||||||
|
**
|
||||||
|
** @param size size of the returned data
|
||||||
|
** @param jpeg flag true, create JPEG data
|
||||||
|
** @param quality JPEG quality
|
||||||
|
** @param width number of horizontal pixels in the frame
|
||||||
|
** @param height number of vertical pixels in the frame
|
||||||
|
*/
|
||||||
|
uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int width,
|
||||||
|
int height)
|
||||||
{
|
{
|
||||||
dsyslog("[softhddev]%s: %d, %d, %d, %dx%d\n", __FUNCTION__, size, jpeg,
|
dsyslog("[softhddev]%s: %d, %d, %d, %dx%d\n", __FUNCTION__, size, jpeg,
|
||||||
quality, sizex, sizey);
|
quality, width, height);
|
||||||
|
|
||||||
return NULL;
|
return ::GrabImage(&size, jpeg, quality, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
195
video.c
195
video.c
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
||||||
#define USE_AUTOCROP ///< compile autocrop support
|
#define USE_AUTOCROP ///< compile autocrop support
|
||||||
#define noUSE_GRAB ///< experimental grab code
|
#define USE_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
|
||||||
|
|
||||||
@ -194,6 +194,19 @@ typedef enum _video_zoom_modes_
|
|||||||
VideoAnamorphic, ///< anamorphic scaled (unsupported)
|
VideoAnamorphic, ///< anamorphic scaled (unsupported)
|
||||||
} VideoZoomModes;
|
} VideoZoomModes;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Video output module structure and typedef.
|
||||||
|
///
|
||||||
|
typedef struct _video_module_
|
||||||
|
{
|
||||||
|
const char *Name; ///< video output module name
|
||||||
|
|
||||||
|
void (*const Thread) (void); ///< module thread handler
|
||||||
|
|
||||||
|
void (*const Init) (const char *); ///< initialize video output module
|
||||||
|
void (*const Exit) (void); ///< cleanup video output module
|
||||||
|
} VideoModule;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Defines
|
// Defines
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -227,6 +240,8 @@ static int VideoWindowY; ///< video outout window y coordinate
|
|||||||
static unsigned VideoWindowWidth; ///< video output window width
|
static unsigned VideoWindowWidth; ///< video output window width
|
||||||
static unsigned VideoWindowHeight; ///< video output window height
|
static unsigned VideoWindowHeight; ///< video output window height
|
||||||
|
|
||||||
|
static const VideoModule *VideoUsedModule; ///< selected video module
|
||||||
|
|
||||||
static char VideoHardwareDecoder; ///< flag use hardware decoder
|
static char VideoHardwareDecoder; ///< flag use hardware decoder
|
||||||
|
|
||||||
static char VideoSurfaceModesChanged; ///< flag surface modes changed
|
static char VideoSurfaceModesChanged; ///< flag surface modes changed
|
||||||
@ -3697,6 +3712,15 @@ static void VaapiOsdExit(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// VA-API module.
|
||||||
|
///
|
||||||
|
static const VideoModule VaapiModule = {
|
||||||
|
.Name = "va-api",
|
||||||
|
.Init = VideoVaapiInit,
|
||||||
|
.Exit = VideoVaapiExit,
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -3829,7 +3853,8 @@ static VdpOutputSurfaceQueryCapabilities *VdpauOutputSurfaceQueryCapabilities;
|
|||||||
|
|
||||||
static VdpOutputSurfaceCreate *VdpauOutputSurfaceCreate;
|
static VdpOutputSurfaceCreate *VdpauOutputSurfaceCreate;
|
||||||
static VdpOutputSurfaceDestroy *VdpauOutputSurfaceDestroy;
|
static VdpOutputSurfaceDestroy *VdpauOutputSurfaceDestroy;
|
||||||
|
static VdpOutputSurfaceGetParameters *VdpauOutputSurfaceGetParameters;
|
||||||
|
static VdpOutputSurfaceGetBitsNative *VdpauOutputSurfaceGetBitsNative;
|
||||||
static VdpOutputSurfacePutBitsNative *VdpauOutputSurfacePutBitsNative;
|
static VdpOutputSurfacePutBitsNative *VdpauOutputSurfacePutBitsNative;
|
||||||
|
|
||||||
static VdpBitmapSurfaceQueryCapabilities *VdpauBitmapSurfaceQueryCapabilities;
|
static VdpBitmapSurfaceQueryCapabilities *VdpauBitmapSurfaceQueryCapabilities;
|
||||||
@ -4571,10 +4596,10 @@ static void VideoVdpauInit(const char *display_name)
|
|||||||
"OutputSurfaceCreate");
|
"OutputSurfaceCreate");
|
||||||
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY,
|
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY,
|
||||||
&VdpauOutputSurfaceDestroy, "OutputSurfaceDestroy");
|
&VdpauOutputSurfaceDestroy, "OutputSurfaceDestroy");
|
||||||
#if 0
|
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS,
|
||||||
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS, &, "");
|
&VdpauOutputSurfaceGetParameters, "OutputSurfaceGetParameters");
|
||||||
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE, &, "");
|
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE,
|
||||||
#endif
|
&VdpauOutputSurfaceGetBitsNative, "OutputSurfaceGetBitsNative");
|
||||||
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE,
|
VdpauGetProc(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE,
|
||||||
&VdpauOutputSurfacePutBitsNative, "OutputSurfacePutBitsNative");
|
&VdpauOutputSurfacePutBitsNative, "OutputSurfacePutBitsNative");
|
||||||
#if 0
|
#if 0
|
||||||
@ -5210,7 +5235,7 @@ static void VdpauSetup(VdpauDecoder * decoder,
|
|||||||
///
|
///
|
||||||
/// @param decoder VDPAU hw decoder
|
/// @param decoder VDPAU hw decoder
|
||||||
///
|
///
|
||||||
static void VdpauGrabSurface(VdpauDecoder * decoder)
|
static void VdpauGrabVideoSurface(VdpauDecoder * decoder)
|
||||||
{
|
{
|
||||||
VdpVideoSurface surface;
|
VdpVideoSurface surface;
|
||||||
VdpStatus status;
|
VdpStatus status;
|
||||||
@ -5270,6 +5295,87 @@ static void VdpauGrabSurface(VdpauDecoder * decoder)
|
|||||||
free(base);
|
free(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Grab output surface.
|
||||||
|
///
|
||||||
|
/// @param decoder VDPAU hw decoder
|
||||||
|
///
|
||||||
|
static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
|
||||||
|
int *ret_height)
|
||||||
|
{
|
||||||
|
VdpOutputSurface surface;
|
||||||
|
VdpStatus status;
|
||||||
|
VdpRGBAFormat rgba_format;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
void *base;
|
||||||
|
void *data[1];
|
||||||
|
uint32_t pitches[1];
|
||||||
|
VdpRect source_rect;
|
||||||
|
|
||||||
|
// FIXME: test function to grab output surface content
|
||||||
|
|
||||||
|
surface = VdpauSurfacesRb[VdpauSurfaceIndex];
|
||||||
|
|
||||||
|
// get real surface size
|
||||||
|
status =
|
||||||
|
VdpauOutputSurfaceGetParameters(surface, &rgba_format, &width,
|
||||||
|
&height);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
Error(_("video/vdpau: can't get output surface parameters: %s\n"),
|
||||||
|
VdpauGetErrorString(status));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(3, "video/vdpau: grab %dx%d format %d\n", width, height,
|
||||||
|
rgba_format);
|
||||||
|
|
||||||
|
switch (rgba_format) {
|
||||||
|
case VDP_RGBA_FORMAT_B8G8R8A8:
|
||||||
|
case VDP_RGBA_FORMAT_R8G8B8A8:
|
||||||
|
size = width * height * sizeof(uint32_t);
|
||||||
|
base = malloc(size);
|
||||||
|
if (!base) {
|
||||||
|
Error(_("video/vdpau: out of memory\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pitches[0] = width * sizeof(uint32_t);
|
||||||
|
data[0] = base;
|
||||||
|
break;
|
||||||
|
case VDP_RGBA_FORMAT_R10G10B10A2:
|
||||||
|
case VDP_RGBA_FORMAT_B10G10R10A2:
|
||||||
|
case VDP_RGBA_FORMAT_A8:
|
||||||
|
Error(_("video/vdpau: unsupported rgba format %d\n"), rgba_format);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
source_rect.x0 = 0;
|
||||||
|
source_rect.y0 = 0;
|
||||||
|
source_rect.x1 = source_rect.x0 + width;
|
||||||
|
source_rect.y1 = source_rect.y0 + height;
|
||||||
|
status =
|
||||||
|
VdpauOutputSurfaceGetBitsNative(surface, &source_rect, data, pitches);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
Error(_("video/vdpau: can't get video surface bits native: %s\n"),
|
||||||
|
VdpauGetErrorString(status));
|
||||||
|
free(base);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret_size) {
|
||||||
|
*ret_size = size;
|
||||||
|
}
|
||||||
|
if (ret_width) {
|
||||||
|
*ret_width = width;
|
||||||
|
}
|
||||||
|
if (ret_height) {
|
||||||
|
*ret_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_AUTOCROP
|
#ifdef USE_AUTOCROP
|
||||||
@ -5765,9 +5871,6 @@ static void VdpauMixVideo(VdpauDecoder * decoder)
|
|||||||
dst_video_rect.x1 = decoder->OutputX + decoder->OutputWidth;
|
dst_video_rect.x1 = decoder->OutputX + decoder->OutputWidth;
|
||||||
dst_video_rect.y1 = decoder->OutputY + decoder->OutputHeight;
|
dst_video_rect.y1 = decoder->OutputY + decoder->OutputHeight;
|
||||||
|
|
||||||
#ifdef USE_GRAB
|
|
||||||
VdpauGrabSurface(decoder);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_AUTOCROP
|
#ifdef USE_AUTOCROP
|
||||||
// reduce load, check only n frames
|
// reduce load, check only n frames
|
||||||
if (AutoCropInterval && !(decoder->FrameCounter % AutoCropInterval)) {
|
if (AutoCropInterval && !(decoder->FrameCounter % AutoCropInterval)) {
|
||||||
@ -6497,6 +6600,15 @@ static void VdpauOsdExit(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// VDPAU module.
|
||||||
|
///
|
||||||
|
static const VideoModule VdpauModule = {
|
||||||
|
.Name = "vdpau",
|
||||||
|
.Init = VideoVdpauInit,
|
||||||
|
.Exit = VideoVdpauExit,
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -7377,6 +7489,48 @@ int64_t VideoGetClock(void)
|
|||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Grab full screen image.
|
||||||
|
///
|
||||||
|
uint8_t *VideoGrab(int *size, int *width, int *height)
|
||||||
|
{
|
||||||
|
Debug(3, "video: grab\n");
|
||||||
|
|
||||||
|
#ifdef USE_GRAB
|
||||||
|
#ifdef USE_VDPAU
|
||||||
|
if (VideoVdpauEnabled) {
|
||||||
|
uint8_t *data;
|
||||||
|
uint8_t *rgb;
|
||||||
|
char buf[64];
|
||||||
|
int i;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
data = VdpauGrabOutputSurface(size, width, height);
|
||||||
|
n = snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", *width, *height);
|
||||||
|
rgb = malloc(*width * *height * 3 + n);
|
||||||
|
if (!rgb) {
|
||||||
|
Error(_("video: out of memory\n"));
|
||||||
|
free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(rgb, buf, n); // header
|
||||||
|
|
||||||
|
for (i = 0; i < *size / 4; ++i) { // convert bgra -> rgb
|
||||||
|
rgb[n + i * 3 + 0] = data[i * 4 + 2];
|
||||||
|
rgb[n + i * 3 + 1] = data[i * 4 + 1];
|
||||||
|
rgb[n + i * 3 + 2] = data[i * 4 + 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
*size = *width * *height * 3 + n;
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Setup
|
// Setup
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -7818,17 +7972,21 @@ void VideoInit(const char *display_name)
|
|||||||
#ifdef USE_VDPAU
|
#ifdef USE_VDPAU
|
||||||
if (VideoVdpauEnabled) {
|
if (VideoVdpauEnabled) {
|
||||||
VideoVdpauInit(display_name);
|
VideoVdpauInit(display_name);
|
||||||
#ifdef USE_VAAPI
|
|
||||||
// disable va-api, if vdpau succeeded
|
|
||||||
if (VideoVdpauEnabled) {
|
if (VideoVdpauEnabled) {
|
||||||
|
VideoUsedModule = &VdpauModule;
|
||||||
|
#ifdef USE_VAAPI
|
||||||
|
// disable va-api, if vdpau succeeded
|
||||||
VideoVaapiEnabled = 0;
|
VideoVaapiEnabled = 0;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled) {
|
if (VideoVaapiEnabled) {
|
||||||
VideoVaapiInit(display_name);
|
VideoVaapiInit(display_name);
|
||||||
|
if (VideoVaapiEnabled) {
|
||||||
|
VideoUsedModule = &VaapiModule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -7851,16 +8009,9 @@ void VideoExit(void)
|
|||||||
#ifdef USE_VIDEO_THREAD
|
#ifdef USE_VIDEO_THREAD
|
||||||
VideoThreadExit();
|
VideoThreadExit();
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VDPAU
|
if (VideoUsedModule) {
|
||||||
if (VideoVdpauEnabled) {
|
VideoUsedModule->Exit();
|
||||||
VideoVdpauExit();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_VAAPI
|
|
||||||
if (VideoVaapiEnabled) {
|
|
||||||
VideoVaapiExit();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
GlxExit();
|
GlxExit();
|
||||||
|
3
video.h
3
video.h
@ -114,6 +114,9 @@ extern void VideoGetOsdSize(int *, int *);
|
|||||||
|
|
||||||
extern int64_t VideoGetClock(void); ///< Get video clock.
|
extern int64_t VideoGetClock(void); ///< Get video clock.
|
||||||
|
|
||||||
|
/// Grab screen.
|
||||||
|
extern uint8_t *VideoGrab(int *, int *, int *);
|
||||||
|
|
||||||
extern void VideoOsdInit(void); ///< Setup osd.
|
extern void VideoOsdInit(void); ///< Setup osd.
|
||||||
extern void VideoOsdExit(void); ///< Cleanup osd.
|
extern void VideoOsdExit(void); ///< Cleanup osd.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user