Adds VDR DFAtmo Plugin support.

This commit is contained in:
durchflieger 2012-04-30 14:47:08 +02:00 committed by Johns
parent 49ae1c7211
commit aca508114b
6 changed files with 242 additions and 27 deletions

View File

@ -2,6 +2,15 @@ User johns
Date:
Release Version 0.5.1
User durchflieger
Date: Mon Apr 30 14:46:51 CEST 2012
Adds VDR DFAtmo Plugin support.
User johns
Date: Mon Apr 30 13:56:26 CEST 2012
Fix bug: don't normalize or compress pass-through samples.
Make audio ring buffer size a multiple of 3,5,7,8.
Add reset ring buffer support.

1
Todo
View File

@ -121,7 +121,6 @@ future features (not planed for 1.0 - 1.5)
video out with opengl
video out with xvba
software decoder for xv / opengl
atmolight support
multistream handling
pip support
save and use auto-crop with channel zapping

View File

@ -33,6 +33,7 @@
#include "softhddev.h"
#include "softhddevice.h"
#include "softhddevice_service.h"
extern "C"
{
#include "audio.h"
@ -693,8 +694,8 @@ void cMenuSetupSoft::Create(void)
if (Audio) {
Add(new cMenuEditIntItem(tr("Audio/Video delay (ms)"), &AudioDelay,
-1000, 1000));
Add(new cMenuEditStraItem(tr("Audio drift correction"),
&AudioDrift, 4, audiodrift));
Add(new cMenuEditStraItem(tr("Audio drift correction"), &AudioDrift, 4,
audiodrift));
Add(new cMenuEditStraItem(tr("Audio pass-through"), &AudioPassthrough,
2, passthrough));
Add(new cMenuEditBoolItem(tr("Enable AC-3 downmix"), &AudioDownmix,
@ -1720,7 +1721,7 @@ class cPluginSoftHdDevice:public cPlugin
virtual cOsdObject *MainMenuAction(void);
virtual cMenuSetupPage *SetupMenu(void);
virtual bool SetupParse(const char *, const char *);
// virtual bool Service(const char *, void * = NULL);
virtual bool Service(const char *, void * = NULL);
virtual const char **SVDRPHelpPages(void);
virtual cString SVDRPCommand(const char *, const char *, int &);
};
@ -2074,17 +2075,48 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
return false;
}
#if 0
bool cPluginSoftHdDevice::Service(const char *Id, void *Data)
/**
** Receive requests or messages.
**
** @param id unique identification string that identifies the
** service protocol
** @param data custom data structure
*/
bool cPluginSoftHdDevice::Service(const char *id, void *data)
{
dsyslog("[softhddev]%s:\n", __FUNCTION__);
dsyslog("[softhddev]%s: id %s\n", __FUNCTION__, id);
if (strcmp(id, ATMO_GRAB_SERVICE) == 0) {
int width;
int height;
if (data == NULL) {
return true;
}
SoftHDDevice_AtmoGrabService_v1_0_t *r =
(SoftHDDevice_AtmoGrabService_v1_0_t *) data;
if (r->structSize != sizeof(SoftHDDevice_AtmoGrabService_v1_0_t)
|| r->analyseSize < 64 || r->analyseSize > 256
|| r->clippedOverscan < 0 || r->clippedOverscan > 200) {
return false;
}
width = r->analyseSize * -1; // Internal marker for Atmo grab service
height = r->clippedOverscan;
r->img = VideoGrabService(&r->imgSize, &width, &height);
if (r->img == NULL) {
return false;
}
r->imgType = GRAB_IMG_RGBA_FORMAT_B8G8R8A8;
r->width = width;
r->height = height;
return true;
}
return false;
}
#endif
//----------------------------------------------------------------------------
// cPlugin SVDRP
//----------------------------------------------------------------------------

44
softhddevice_service.h Normal file
View File

@ -0,0 +1,44 @@
///
/// @file softhddev_service.h @brief software HD device service header file.
///
/// Copyright (c) 2012 by durchflieger. All Rights Reserved.
///
/// Contributor(s):
///
/// License: AGPLv3
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as
/// published by the Free Software Foundation, either version 3 of the
/// License.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// $Id$
//////////////////////////////////////////////////////////////////////////////
#pragma once
#define ATMO_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.0"
enum
{ GRAB_IMG_RGBA_FORMAT_B8G8R8A8 };
typedef struct
{
int structSize;
// request data
int analyseSize;
int clippedOverscan;
// reply data
int imgType;
int imgSize;
int width;
int height;
void *img;
} SoftHDDevice_AtmoGrabService_v1_0_t;

162
video.c
View File

@ -5079,6 +5079,10 @@ static VdpOutputSurface VdpauOsdOutputSurface[2] = {
#endif
static int VdpauOsdSurfaceIndex; ///< index into double buffered osd
/// grab render output surface
static VdpOutputSurface VdpauGrabRenderSurface = VDP_INVALID_HANDLE;
static pthread_mutex_t VdpauGrabMutex;
///
/// Function pointer of the VDPAU device.
///
@ -5807,6 +5811,7 @@ static inline void VdpauGetProc(const VdpFuncId id, void *addr,
static void VdpauInitOutputQueue(void)
{
VdpStatus status;
VdpRGBAFormat format;
int i;
status =
@ -5839,12 +5844,10 @@ static void VdpauInitOutputQueue(void)
//
// Create display output surfaces
//
format = VDP_RGBA_FORMAT_B8G8R8A8;
// FIXME: does a 10bit rgba produce a better output?
// format = VDP_RGBA_FORMAT_R10G10B10A2;
for (i = 0; i < OUTPUT_SURFACES_MAX; ++i) {
VdpRGBAFormat format;
format = VDP_RGBA_FORMAT_B8G8R8A8;
// FIXME: does a 10bit rgba produce a better output?
// format = VDP_RGBA_FORMAT_R10G10B10A2;
status =
VdpauOutputSurfaceCreate(VdpauDevice, format, VideoWindowWidth,
VideoWindowHeight, VdpauSurfacesRb + i);
@ -5855,6 +5858,20 @@ static void VdpauInitOutputQueue(void)
Debug(3, "video/vdpau: created output surface %dx%d with id 0x%08x\n",
VideoWindowWidth, VideoWindowHeight, VdpauSurfacesRb[i]);
}
//
// Create render output surface for grabbing
//
status =
VdpauOutputSurfaceCreate(VdpauDevice, format, VideoWindowWidth,
VideoWindowHeight, &VdpauGrabRenderSurface);
if (status != VDP_STATUS_OK) {
Fatal(_("video/vdpau: can't create grab render output surface: %s\n"),
VdpauGetErrorString(status));
}
Debug(3,
"video/vdpau: created grab render output surface %dx%d with id 0x%08x\n",
VideoWindowWidth, VideoWindowHeight, VdpauGrabRenderSurface);
}
///
@ -5863,13 +5880,12 @@ static void VdpauInitOutputQueue(void)
static void VdpauExitOutputQueue(void)
{
int i;
VdpStatus status;
//
// destroy display output surfaces
//
for (i = 0; i < OUTPUT_SURFACES_MAX; ++i) {
VdpStatus status;
Debug(4, "video/vdpau: destroy output surface with id 0x%08x\n",
VdpauSurfacesRb[i]);
if (VdpauSurfacesRb[i] != VDP_INVALID_HANDLE) {
@ -5881,6 +5897,15 @@ static void VdpauExitOutputQueue(void)
VdpauSurfacesRb[i] = VDP_INVALID_HANDLE;
}
}
if (VdpauGrabRenderSurface != VDP_INVALID_HANDLE) {
status = VdpauOutputSurfaceDestroy(VdpauGrabRenderSurface);
if (status != VDP_STATUS_OK) {
Error(_
("video/vdpau: can't destroy grab render output surface: %s\n"),
VdpauGetErrorString(status));
}
VdpauGrabRenderSurface = VDP_INVALID_HANDLE;
}
if (VdpauQueue) {
VdpauPresentationQueueDestroy(VdpauQueue);
VdpauQueue = 0;
@ -5927,6 +5952,8 @@ static int VdpauInit(const char *display_name)
uint32_t max_width;
uint32_t max_height;
pthread_mutex_init(&VdpauGrabMutex, NULL);
status =
vdp_device_create_x11(XlibDisplay, DefaultScreen(XlibDisplay),
&VdpauDevice, &VdpauGetProcAddress);
@ -6358,6 +6385,8 @@ static void VdpauExit(void)
}
VdpauDevice = 0;
}
pthread_mutex_destroy(&VdpauGrabMutex);
}
///
@ -6684,13 +6713,13 @@ static void VdpauGrabVideoSurface(VdpauDecoder * decoder)
#endif
///
/// Grab output surface.
/// Grab output surface already locked.
///
/// @param ret_size[out] size of allocated surface copy
/// @param ret_width[in,out] width of output
/// @param ret_height[in,out] height of output
///
static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
static uint8_t *VdpauGrabOutputSurfaceLocked(int *ret_size, int *ret_width,
int *ret_height)
{
VdpOutputSurface surface;
@ -6703,8 +6732,7 @@ static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
void *data[1];
uint32_t pitches[1];
VdpRect source_rect;
// FIXME: test function to grab output surface content
VdpRect output_rect;
surface = VdpauSurfacesRb[VdpauSurfaceIndex];
@ -6721,8 +6749,62 @@ static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
Debug(3, "video/vdpau: grab %dx%d format %d\n", width, height,
rgba_format);
// FIXME: scale surface to requested size with
// VdpauOutputSurfaceRenderOutputSurface
source_rect.x0 = 0;
source_rect.y0 = 0;
source_rect.x1 = width;
source_rect.y1 = height;
if (ret_width && ret_height) {
if (*ret_width <= -64) { // this is a Atmo grab service request
int overscan;
// calculate aspect correct size of analyze image
width = *ret_width * -1;
height = (width * source_rect.y1) / source_rect.x1;
// calculate size of grab (sub) window
overscan = *ret_height;
if (overscan > 0 && overscan <= 200) {
source_rect.x0 = source_rect.x1 * overscan / 1000;
source_rect.x1 -= source_rect.x0;
source_rect.y0 = source_rect.y1 * overscan / 1000;
source_rect.y1 -= source_rect.y0;
}
} else {
if (*ret_width > 0 && (unsigned)*ret_width < width) {
width = *ret_width;
}
if (*ret_height > 0 && (unsigned)*ret_height < height) {
height = *ret_height;
}
}
Debug(3, "video/vdpau: grab source rect %d,%d:%d,%d dest dim %dx%d\n",
source_rect.x0, source_rect.y0, source_rect.x1, source_rect.y1,
width, height);
if ((source_rect.x1 - source_rect.x0) != width
|| (source_rect.y1 - source_rect.y0) != height) {
output_rect.x0 = 0;
output_rect.y0 = 0;
output_rect.x1 = width;
output_rect.y1 = height;
status =
VdpauOutputSurfaceRenderOutputSurface(VdpauGrabRenderSurface,
&output_rect, surface, &source_rect, NULL, NULL,
VDP_OUTPUT_SURFACE_RENDER_ROTATE_0);
if (status != VDP_STATUS_OK) {
Error(_("video/vdpau: can't render output surface: %s\n"),
VdpauGetErrorString(status));
return NULL;
}
surface = VdpauGrabRenderSurface;
source_rect = output_rect;
}
}
switch (rgba_format) {
case VDP_RGBA_FORMAT_B8G8R8A8:
@ -6744,10 +6826,6 @@ static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
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) {
@ -6770,6 +6848,28 @@ static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
return base;
}
///
/// Grab output surface.
///
/// @param ret_size[out] size of allocated surface copy
/// @param ret_width[in,out] width of output
/// @param ret_height[in,out] height of output
///
static uint8_t *VdpauGrabOutputSurface(int *ret_size, int *ret_width,
int *ret_height)
{
uint8_t *img;
if (VdpauGrabRenderSurface == VDP_INVALID_HANDLE) {
return NULL; // vdpau video module not yet initialized
}
pthread_mutex_lock(&VdpauGrabMutex);
img = VdpauGrabOutputSurfaceLocked(ret_size, ret_width, ret_height);
pthread_mutex_unlock(&VdpauGrabMutex);
return img;
}
#endif
#ifdef USE_AUTOCROP
@ -9264,6 +9364,8 @@ uint8_t *VideoGrab(int *size, int *width, int *height, int write_header)
scale_height = *height;
n = 0;
data = VideoUsedModule->GrabOutput(size, width, height);
if (data == NULL)
return NULL;
if (scale_width <= 0) {
scale_width = *width;
@ -9350,6 +9452,32 @@ uint8_t *VideoGrab(int *size, int *width, int *height, int write_header)
return NULL;
}
///
/// Grab image service.
///
/// @param size[out] size of allocated image
/// @param width[in,out] width of image
/// @param height[in,out] height of image
///
uint8_t *VideoGrabService(int *size, int *width, int *height)
{
Debug(3, "video: grab service\n");
#ifdef USE_GRAB
if (VideoUsedModule->GrabOutput) {
return VideoUsedModule->GrabOutput(size, width, height);
} else
#endif
{
Warning(_("softhddev: grab unsupported\n"));
}
(void)size;
(void)width;
(void)height;
return NULL;
}
#ifdef USE_SCREENSAVER
//----------------------------------------------------------------------------

View File

@ -168,6 +168,9 @@ extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
/// Grab screen.
extern uint8_t *VideoGrab(int *, int *, int *, int);
/// Grab screen raw.
extern uint8_t *VideoGrabService(int *, int *, int *);
extern void VideoOsdInit(void); ///< Setup osd.
extern void VideoOsdExit(void); ///< Cleanup osd.