mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Survive lost X11 display.
This commit is contained in:
parent
c17af0e958
commit
67e571f02b
@ -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.
|
||||||
|
@ -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
56
video.c
@ -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"));
|
||||||
|
Loading…
Reference in New Issue
Block a user