Survive lost X11 display.

This commit is contained in:
Johns 2012-02-23 17:57:21 +01:00
parent c17af0e958
commit 67e571f02b
3 changed files with 49 additions and 12 deletions

View File

@ -1,6 +1,7 @@
User johns User johns
Date: Date:
Survive lost X11 display.
Fix bug: 100% cpu use with plugins like mp3. Fix bug: 100% cpu use with plugins like mp3.
Wakeup display thread on channel switch, osd can now be shown without Wakeup display thread on channel switch, osd can now be shown without
video. video.

View File

@ -1848,7 +1848,7 @@ int SetPlayMode(int play_mode)
NewAudioStream = 1; NewAudioStream = 1;
} }
} }
if (play_mode == 2 || play_mode == 3 ) { if (play_mode == 2 || play_mode == 3) {
Debug(3, "softhddev: FIXME: audio only, silence video errors\n"); Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
} }
Play(); Play();
@ -1997,7 +1997,7 @@ void StillPicture(const uint8_t * data, int size)
int Poll(int timeout) int Poll(int timeout)
{ {
// buffers are too full // buffers are too full
if ( atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX * 2 / 3 if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX * 2 / 3
|| AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE * 2) { || AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE * 2) {
if (timeout) { // let display thread work if (timeout) { // let display thread work
usleep(timeout * 1000); usleep(timeout * 1000);

56
video.c
View File

@ -73,6 +73,7 @@
#endif #endif
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#include <signal.h>
#ifndef HAVE_PTHREAD_NAME #ifndef HAVE_PTHREAD_NAME
/// only available with newer glibc /// only available with newer glibc
#define pthread_setname_np(thread, name) #define pthread_setname_np(thread, name)
@ -363,6 +364,7 @@ static int64_t VideoDeltaPTS; ///< FIXME: fix pts
static void VideoThreadLock(void); ///< lock video thread static void VideoThreadLock(void); ///< lock video thread
static void VideoThreadUnlock(void); ///< unlock video thread static void VideoThreadUnlock(void); ///< unlock video thread
static void VideoThreadExit(void); ///< exit/kill video thread
#if defined(DEBUG) || defined(AV_INFO) #if defined(DEBUG) || defined(AV_INFO)
/// ///
@ -1354,6 +1356,9 @@ static void VaapiBlackSurface(VaapiDecoder *);
/// forward destroy deinterlace images /// forward destroy deinterlace images
static void VaapiDestroyDeinterlaceImages(VaapiDecoder *); static void VaapiDestroyDeinterlaceImages(VaapiDecoder *);
/// forward definition release surface
static void VaapiReleaseSurface(VaapiDecoder *, VASurfaceID);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// VA-API Functions // VA-API Functions
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1467,8 +1472,8 @@ static void VaapiCreateSurfaces(VaapiDecoder * decoder, int width, int height)
decoder->SurfaceFreeN = decoder->SurfacesNeeded; decoder->SurfaceFreeN = decoder->SurfacesNeeded;
// VA_RT_FORMAT_YUV420 VA_RT_FORMAT_YUV422 VA_RT_FORMAT_YUV444 // VA_RT_FORMAT_YUV420 VA_RT_FORMAT_YUV422 VA_RT_FORMAT_YUV444
if (vaCreateSurfaces(decoder->VaDisplay, VA_RT_FORMAT_YUV420, width, if (vaCreateSurfaces(decoder->VaDisplay, VA_RT_FORMAT_YUV420, width,
height, decoder->SurfacesFree, decoder->SurfaceFreeN, height, decoder->SurfacesFree, decoder->SurfaceFreeN, NULL,
NULL, 0) != VA_STATUS_SUCCESS) { 0) != VA_STATUS_SUCCESS) {
Fatal(_("video/vaapi: can't create %d surfaces\n"), Fatal(_("video/vaapi: can't create %d surfaces\n"),
decoder->SurfaceFreeN); decoder->SurfaceFreeN);
// FIXME: write error handler / fallback // FIXME: write error handler / fallback
@ -1507,9 +1512,6 @@ static void VaapiDestroySurfaces(VaapiDecoder * decoder)
// FIXME surfaces used for output // FIXME surfaces used for output
} }
/// forward definition release surface
static void VaapiReleaseSurface(VaapiDecoder *, VASurfaceID);
/// ///
/// Get a free surface. /// Get a free surface.
/// ///
@ -1932,8 +1934,8 @@ static void Vaapi1080i(void)
Error(_("codec: can't create config")); Error(_("codec: can't create config"));
return; return;
} }
if (vaCreateSurfaces(VaDisplay, VA_RT_FORMAT_YUV420, 1920, 1080, if (vaCreateSurfaces(VaDisplay, VA_RT_FORMAT_YUV420, 1920, 1080, surfaces,
surfaces, 32, NULL, 0) != VA_STATUS_SUCCESS) { 32, NULL, 0) != VA_STATUS_SUCCESS) {
Error(_("video/vaapi: can't create surfaces\n")); Error(_("video/vaapi: can't create surfaces\n"));
return; return;
} }
@ -2979,10 +2981,10 @@ static void VaapiQueueSurface(VaapiDecoder * decoder, VASurfaceID surface,
if ((old = decoder->SurfacesRb[decoder->SurfaceWrite]) if ((old = decoder->SurfacesRb[decoder->SurfaceWrite])
!= VA_INVALID_ID) { != VA_INVALID_ID) {
#if 0
if (vaSyncSurface(decoder->VaDisplay, old) != VA_STATUS_SUCCESS) { if (vaSyncSurface(decoder->VaDisplay, old) != VA_STATUS_SUCCESS) {
Error(_("video/vaapi: vaSyncSurface failed\n")); Error(_("video/vaapi: vaSyncSurface failed\n"));
} }
#if 0
VASurfaceStatus status; VASurfaceStatus status;
if (vaQuerySurfaceStatus(decoder->VaDisplay, old, &status) if (vaQuerySurfaceStatus(decoder->VaDisplay, old, &status)
@ -3063,8 +3065,8 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
if (decoder->BlackSurface == VA_INVALID_ID) { if (decoder->BlackSurface == VA_INVALID_ID) {
if (vaCreateSurfaces(decoder->VaDisplay, VA_RT_FORMAT_YUV420, if (vaCreateSurfaces(decoder->VaDisplay, VA_RT_FORMAT_YUV420,
VideoWindowWidth, VideoWindowHeight, VideoWindowWidth, VideoWindowHeight, &decoder->BlackSurface, 1,
&decoder->BlackSurface, 1, NULL, 0) != VA_STATUS_SUCCESS) { NULL, 0) != VA_STATUS_SUCCESS) {
Error(_("video/vaapi: can't create a surface\n")); Error(_("video/vaapi: can't create a surface\n"));
return; return;
} }
@ -8218,6 +8220,37 @@ static void VideoDisplayFrame(void)
/// C callback feed key press /// C callback feed key press
extern void FeedKeyPress(const char *, const char *, int, int); extern void FeedKeyPress(const char *, const char *, int, int);
///
/// Handle XLib I/O Errors.
///
/// @param display display with i/o error
///
static int VideoIOErrorHandler( __attribute__ ((unused)) Display * display)
{
Error(_("video: fatal i/o error\n"));
// should be called from VideoThread
if (VideoThread && VideoThread == pthread_self()) {
Debug(3, "video: called from video thread\n");
VideoUsedModule = NULL; // FIXME: NoopModule;
XlibDisplay = NULL;
VideoWindow = XCB_NONE;
#ifdef USE_VIDEO_THREAD
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_cond_destroy(&VideoWakeupCond);
pthread_mutex_destroy(&VideoLockMutex);
pthread_mutex_destroy(&VideoMutex);
VideoThread = 0;
pthread_exit("video thread exit");
#endif
}
do {
sleep(1000);
} while (1); // let other threads running
return -1;
}
/// ///
/// Handle X11 events. /// Handle X11 events.
/// ///
@ -9233,6 +9266,9 @@ void VideoInit(const char *display_name)
return; return;
} }
// XInitThreads(); // XInitThreads();
// Register error handler
XSetIOErrorHandler(VideoIOErrorHandler);
// Convert XLIB display to XCB connection // Convert XLIB display to XCB connection
if (!(Connection = XGetXCBConnection(XlibDisplay))) { if (!(Connection = XGetXCBConnection(XlibDisplay))) {
Error(_("video: Can't convert XLIB display to XCB connection\n")); Error(_("video: Can't convert XLIB display to XCB connection\n"));