diff --git a/ChangeLog b/ChangeLog index faeecd1..8301b67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/README.txt b/README.txt index 6b9cab2..108cb10 100644 --- a/README.txt +++ b/README.txt @@ -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: -------- diff --git a/audio.c b/audio.c index 77f95a5..a9f4251 100644 --- a/audio.c +++ b/audio.c @@ -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 diff --git a/softhddev.c b/softhddev.c index b1e29cf..649fcd3 100644 --- a/softhddev.c +++ b/softhddev.c @@ -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 // 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); } diff --git a/softhddevice.cpp b/softhddevice.cpp index 83c3b7b..4bdb6a3 100644 --- a/softhddevice.cpp +++ b/softhddevice.cpp @@ -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; diff --git a/video.c b/video.c index 68e8581..37b3cc5 100644 --- a/video.c +++ b/video.c @@ -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