Suspend can close and open video and audio device.

This commit is contained in:
Johns 2012-01-22 20:49:43 +01:00
parent 98d2e0f728
commit 9546233175
6 changed files with 174 additions and 50 deletions

View File

@ -1,6 +1,8 @@
User johns
Date:
Suspend can close/open X11 window, connection and audio device.
User Morone
Date: Sun Jan 22 16:43:23 CET 2012

View File

@ -140,6 +140,13 @@ Setup: /etc/vdr/setup.conf
if auto-crop is over after 'n' intervals the same, the cropping is
used.
softhddevice.Suspend.Close = 0
1 suspend closes x11 window, connection and audio device.
(use svdrpsend plug softhddevice RESU to resume, if you have no lirc)
softhddevice.Suspend.X11 = 0
1 suspend stops X11 server (not working yet)
Setup: /etc/vdr/remote.conf
------
@ -159,7 +166,7 @@ Setup: /etc/vdr/remote.conf
Commandline:
------------
Use vdr -h to see the command line arguments support by the plugin.
Use vdr -h to see the command line arguments supported by the plugin.
-a audio_device
@ -170,6 +177,12 @@ Commandline:
other to use alsa audio module (if compiled with alsa
support)
SVDRP:
------
Use 'svdrpsend.pl plug softhddevice HELP' to see the SVDRP commands
help and which are supported by the plugin.
Running:
--------

View File

@ -1932,6 +1932,7 @@ static void AudioExitThread(void)
}
pthread_cond_destroy(&AudioStartCond);
pthread_mutex_destroy(&AudioMutex);
AudioThread = 0;
}
}
@ -2187,6 +2188,7 @@ void AudioExit(void)
#ifdef USE_AUDIORING
AudioRingExit();
#endif
AudioRunning = 0;
}
#ifdef AUDIO_TEST

View File

@ -58,8 +58,8 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
#endif
static char ConfigFullscreen; ///< fullscreen modus
static char ConfigSuspendClose = 1; ///< suspend should close devices
static char ConfigSuspendX11 = 1; ///< suspend should stop x11
char ConfigSuspendClose; ///< suspend should close devices
char ConfigSuspendX11; ///< suspend should stop x11
static pthread_mutex_t SuspendLockMutex; ///< suspend lock mutex
@ -347,7 +347,8 @@ void SetVolumeDevice(int volume)
#include <alsa/iatomic.h> // portable atomic_t
uint32_t VideoSwitch; ///< debug video switch ticks
static volatile char NewVideoStream; ///< new video stream
static volatile char NewVideoStream; ///< flag new video stream
static VideoHwDecoder *MyHwDecoder; ///< video hw decoder
static VideoDecoder *MyVideoDecoder; ///< video decoder
static enum CodecID VideoCodecID; ///< current codec id
@ -592,16 +593,35 @@ static void StartVideo(void)
}
VideoOsdInit();
if (!MyVideoDecoder) {
VideoHwDecoder *hw_decoder;
if ((hw_decoder = VideoNewHwDecoder())) {
MyVideoDecoder = CodecVideoNewDecoder(hw_decoder);
if ((MyHwDecoder = VideoNewHwDecoder())) {
MyVideoDecoder = CodecVideoNewDecoder(MyHwDecoder);
}
VideoCodecID = CODEC_ID_NONE;
}
VideoPacketInit();
}
/**
** Stop video.
*/
static void StopVideo(void)
{
VideoOsdExit();
VideoExit();
if (MyVideoDecoder) {
CodecVideoClose(MyVideoDecoder);
CodecVideoDelDecoder(MyVideoDecoder);
MyVideoDecoder = NULL;
}
if (MyHwDecoder) {
// done by exit: VideoDelHwDecoder(MyHwDecoder);
MyHwDecoder = NULL;
}
VideoPacketExit();
NewVideoStream = 0;
}
#ifdef DEBUG
/**
@ -1152,20 +1172,15 @@ void SoftHdDeviceExit(void)
{
// lets hope that vdr does a good thread cleanup
VideoOsdExit();
VideoExit();
AudioExit();
if (MyVideoDecoder) {
CodecVideoClose(MyVideoDecoder);
CodecVideoDelDecoder(MyVideoDecoder);
MyVideoDecoder = NULL;
}
if (MyAudioDecoder) {
CodecAudioClose(MyAudioDecoder);
CodecAudioDelDecoder(MyAudioDecoder);
MyAudioDecoder = NULL;
}
NewAudioStream = 0;
StopVideo();
CodecExit();
VideoPacketExit();
@ -1242,9 +1257,17 @@ void Suspend(void)
if (ConfigSuspendClose) {
pthread_mutex_lock(&SuspendLockMutex);
// FIXME: close audio
// FIXME: close video
AudioExit();
if (MyAudioDecoder) {
CodecAudioClose(MyAudioDecoder);
CodecAudioDelDecoder(MyAudioDecoder);
MyAudioDecoder = NULL;
}
NewAudioStream = 0;
StopVideo();
pthread_mutex_unlock(&SuspendLockMutex);
}
if (ConfigSuspendX11) {
@ -1267,6 +1290,10 @@ void Resume(void)
}
if (ConfigSuspendClose) {
pthread_mutex_lock(&SuspendLockMutex);
StartVideo();
AudioInit();
pthread_mutex_unlock(&SuspendLockMutex);
}

View File

@ -38,6 +38,8 @@ extern "C"
#include "video.h"
extern void AudioPoller(void);
extern void CodecSetAudioPassthrough(int);
extern char ConfigSuspendClose; ///< suspend should close devices
extern char ConfigSuspendX11; ///< suspend should stop x11
}
//////////////////////////////////////////////////////////////////////////////
@ -368,6 +370,8 @@ class cMenuSetupSoft:public cMenuSetupPage
int AudioPassthrough;
int AutoCropInterval;
int AutoCropDelay;
int SuspendClose;
int SuspendX11;
protected:
virtual void Store(void);
public:
@ -457,6 +461,16 @@ cMenuSetupSoft::cMenuSetupSoft(void)
AutoCropDelay = ConfigAutoCropDelay;
Add(new cMenuEditIntItem(tr("autocrop delay (n * interval)"),
&AutoCropDelay, 0, 200));
//
// suspend
//
Add(SeparatorItem(tr("Suspend")));
SuspendClose = ConfigSuspendClose;
Add(new cMenuEditBoolItem(tr("suspend closes video+audio"), &SuspendClose,
trVDR("no"), trVDR("yes")));
SuspendX11 = ConfigSuspendX11;
Add(new cMenuEditBoolItem(tr("suspend stops x11"), &SuspendX11,
trVDR("no"), trVDR("yes")));
}
/**
@ -499,8 +513,10 @@ void cMenuSetupSoft::Store(void)
SetupStore("AutoCrop.Interval", ConfigAutoCropInterval = AutoCropInterval);
SetupStore("AutoCrop.Delay", ConfigAutoCropDelay = AutoCropDelay);
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay);
SetupStore("Suspend.Close", ConfigSuspendClose = SuspendClose);
SetupStore("Suspend.X11", ConfigSuspendX11 = SuspendX11);
}
//////////////////////////////////////////////////////////////////////////////
@ -705,6 +721,7 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
case pmNone:
return true;
case pmExtern_THIS_SHOULD_BE_AVOIDED:
dsyslog("[softhddev] play mode external\n");
break;
default:
dsyslog("[softhddev]playmode not implemented... %d\n", play_mode);
@ -1198,6 +1215,14 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
return true;
}
if (!strcmp(name, "Suspend.Close")) {
ConfigSuspendClose = atoi(value);
return true;
}
if (!strcmp(name, "Suspend.X11")) {
ConfigSuspendX11 = atoi(value);
return true;
}
return false;
}
@ -1226,10 +1251,10 @@ const char **cPluginSoftHdDevice::SVDRPHelpPages(void)
{
// FIXME: translation?
static const char *text[] = {
"SUSP\n",
" Suspend plugin",
"RESU\n",
" Resume plugin",
"SUSP\n"
" Suspend plugin.\n",
"RESU\n"
" Resume plugin.\n",
NULL
};
@ -1250,8 +1275,11 @@ cString cPluginSoftHdDevice::SVDRPCommand(const char *command,
return "SoftHdDevice is suspended";
}
if (!strcasecmp(command, "RESU")) {
if (ShutdownHandler.GetUserInactiveTime()) {
ShutdownHandler.SetUserInactiveTimeout();
}
Resume();
cControl::Shutdown();
cControl::Shutdown(); // not need, if not suspended
return "SoftHdDevice is resumed";
}
return NULL;

104
video.c
View File

@ -203,6 +203,10 @@ typedef struct _video_module_
void (*const Thread) (void); ///< module thread handler
/// allocate new video hw decoder
VideoHwDecoder *(*const NewHwDecoder)(void);
void (*const DelHwDecoder) (VideoHwDecoder *);
void (*const Init) (const char *); ///< initialize video output module
void (*const Exit) (void); ///< cleanup video output module
} VideoModule;
@ -1551,6 +1555,9 @@ static void VaapiCleanup(VaapiDecoder * decoder)
///
static void VaapiDelDecoder(VaapiDecoder * decoder)
{
VaapiDecoderN = 0;
VaapiDecoders[0] = NULL;
VaapiCleanup(decoder);
if (decoder->BlackSurface != VA_INVALID_ID) {
@ -3717,6 +3724,8 @@ static void VaapiOsdExit(void)
///
static const VideoModule VaapiModule = {
.Name = "va-api",
.NewHwDecoder = (VideoHwDecoder * (*const)(void))VaapiNewDecoder,
.DelHwDecoder = (void (*const) (VideoHwDecoder *))VaapiDelDecoder,
.Init = VideoVaapiInit,
.Exit = VideoVaapiExit,
};
@ -4389,6 +4398,10 @@ static void VdpauCleanup(VdpauDecoder * decoder)
///
static void VdpauDelDecoder(VdpauDecoder * decoder)
{
// FIXME: hack
VdpauDecoderN = 0;
VdpauDecoders[0] = NULL;
VdpauCleanup(decoder);
VdpauPrintFrames(decoder);
@ -4477,14 +4490,6 @@ static void VdpauExitOutputQueue(void)
{
int i;
if (VdpauQueue) {
VdpauPresentationQueueDestroy(VdpauQueue);
VdpauQueue = 0;
}
if (VdpauQueueTarget) {
VdpauPresentationQueueTargetDestroy(VdpauQueueTarget);
VdpauQueueTarget = 0;
}
//
// destroy display output surfaces
//
@ -4502,6 +4507,14 @@ static void VdpauExitOutputQueue(void)
VdpauSurfacesRb[i] = VDP_INVALID_HANDLE;
}
}
if (VdpauQueue) {
VdpauPresentationQueueDestroy(VdpauQueue);
VdpauQueue = 0;
}
if (VdpauQueueTarget) {
VdpauPresentationQueueTargetDestroy(VdpauQueueTarget);
VdpauQueueTarget = 0;
}
}
///
@ -4915,6 +4928,7 @@ static void VideoVdpauExit(void)
}
if (VdpauDevice) {
xcb_flush(Connection);
VdpauExitOutputQueue();
// FIXME: more VDPAU cleanups...
@ -6612,6 +6626,8 @@ static void VdpauOsdExit(void)
///
static const VideoModule VdpauModule = {
.Name = "vdpau",
.NewHwDecoder = (VideoHwDecoder * (*const)(void))VdpauNewDecoder,
.DelHwDecoder = (void (*const) (VideoHwDecoder *))VdpauDelDecoder,
.Init = VideoVdpauInit,
.Exit = VideoVdpauExit,
};
@ -7157,9 +7173,12 @@ static void VideoThreadExit(void)
void *retval;
Debug(3, "video: video thread canceled\n");
VideoThreadLock();
// FIXME: can't cancel locked
if (pthread_cancel(VideoThread)) {
Error(_("video: can't queue cancel video display thread\n"));
}
VideoThreadUnlock();
if (pthread_join(VideoThread, &retval) || retval != PTHREAD_CANCELED) {
Error(_("video: can't cancel video display thread\n"));
}
@ -7213,20 +7232,22 @@ struct _video_hw_decoder_
///
VideoHwDecoder *VideoNewHwDecoder(void)
{
if (!XlibDisplay) { // waiting for x11 start
if (!XlibDisplay && !VideoUsedModule) { // waiting for x11 start
return NULL;
}
#ifdef USE_VAAPI
if (VideoVaapiEnabled) {
return (VideoHwDecoder *) VaapiNewDecoder();
return VideoUsedModule->NewHwDecoder();
}
///
/// Destroy a video hw decoder.
///
/// @param decoder video hw decoder
///
void VideoDelHwDecoder(VideoHwDecoder * decoder)
{
if (decoder && VideoUsedModule) {
VideoUsedModule->DelHwDecoder(decoder);
}
#endif
#ifdef USE_VDPAU
if (VideoVdpauEnabled) {
return (VideoHwDecoder *) VdpauNewDecoder();
}
#endif
return NULL;
}
///
@ -7484,12 +7505,12 @@ void VideoDisplayHandler(void)
int64_t VideoGetClock(void)
{
#ifdef USE_VAAPI
if (VideoVaapiEnabled) {
if (VideoVaapiEnabled && VaapiDecoders[0]) {
return VaapiGetClock(VaapiDecoders[0]);
}
#endif
#ifdef USE_VDPAU
if (VideoVdpauEnabled) {
if (VideoVdpauEnabled && VdpauDecoders[0]) {
return VdpauGetClock(VdpauDecoders[0]);
}
#endif
@ -7535,6 +7556,9 @@ uint8_t *VideoGrab(int *size, int *width, int *height)
}
#endif
#endif
(void)size;
(void)width;
(void)height;
return NULL;
}
@ -7733,6 +7757,7 @@ void VideoSetVideoMode( __attribute__ ((unused))
if (VideoVaapiEnabled && VaapiDecoders[0]) {
VaapiDeassociate(VaapiDecoders[0]);
VideoOsdExit();
VideoOsdInit();
if (VaapiDecoders[0]->InputWidth && VaapiDecoders[0]->InputHeight) {
VaapiAssociate(VaapiDecoders[0], VaapiDecoders[0]->InputWidth,
@ -7747,6 +7772,7 @@ void VideoSetVideoMode( __attribute__ ((unused))
if (VideoVdpauEnabled && VdpauDecoders[0]) {
VdpauExitOutputQueue();
VideoOsdExit();
VideoOsdInit();
VdpauInitOutputQueue();
VdpauUpdateOutput(VdpauDecoders[0]);
@ -7866,14 +7892,26 @@ void VideoSetAudioDelay(int ms)
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;
if (VideoVdpauEnabled) {
int i;
for (i = 0; i < VdpauDecoderN; ++i) {
VdpauDecoders[i]->AutoCrop->State = 0;
VdpauDecoders[i]->AutoCrop->Count = 0;
}
}
#endif
#ifdef USE_VAAPI
if (VideoVaapiEnabled) {
int i;
for (i = 0; i < VaapiDecoderN; ++i) {
// FIXME: VaapiDecoders[i]->AutoCrop->State = 0;
// FIXME: VaapiDecoders[i]->AutoCrop->Count = 0;
}
}
#endif
#endif
@ -8035,6 +8073,20 @@ void VideoExit(void)
// FIXME: cleanup.
//
//RandrExit();
//
// X11/xcb cleanup
//
if (VideoWindow != XCB_NONE) {
xcb_destroy_window(Connection, VideoWindow);
VideoWindow = XCB_NONE;
}
if (XlibDisplay) {
if (XCloseDisplay(XlibDisplay)) {
Error(_("video: error closing display\n"));
}
XlibDisplay = NULL;
}
}
#endif