diff options
author | Johns <johns98@gmx.net> | 2013-02-07 16:54:16 +0100 |
---|---|---|
committer | Johns <johns98@gmx.net> | 2013-02-07 16:54:16 +0100 |
commit | d4535a34c9afa899cc21eeba5cc0e6acedc7b1a9 (patch) | |
tree | 35ddf375c34bf04fa09c9c1c3609d5fc29fa346b /softhddev.c | |
parent | ebd2f85f902d0c35c47dc37c27a336b881750129 (diff) | |
download | vdr-plugin-softhddevice-d4535a34c9afa899cc21eeba5cc0e6acedc7b1a9.tar.gz vdr-plugin-softhddevice-d4535a34c9afa899cc21eeba5cc0e6acedc7b1a9.tar.bz2 |
Fix xcb deadlock while closing PIP decoder.
Close video decoder from inside the decoder thread,
otherwise xcb hangs in a lock.
Diffstat (limited to 'softhddev.c')
-rw-r--r-- | softhddev.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/softhddev.c b/softhddev.c index b1217ec..9877e8f 100644 --- a/softhddev.c +++ b/softhddev.c @@ -1269,7 +1269,8 @@ struct __video_stream__ volatile char Freezed; ///< stream freezed volatile char TrickSpeed; ///< current trick speed - volatile char ClearBuffers; ///< clear video buffers + volatile char Close; ///< command close video stream + volatile char ClearBuffers; ///< command clear video buffers volatile char ClearClose; ///< clear video buffers for close AVPacket PacketRb[VIDEO_PACKET_MAX]; ///< PES packet ring buffer @@ -1682,6 +1683,39 @@ static void FixPacketForFFMpeg(VideoDecoder * vdecoder, AVPacket * avpkt) #endif /** +** Close video stream. +** +** @param stream video stream +** +** @note must be called from the video thread, othewise xcb has a +** deadlock. +*/ +static void VideoStreamClose(VideoStream * stream) +{ + // FIXME: use this function to close the main video stream! + stream->SkipStream = 1; + if (stream->Decoder) { + VideoDecoder *decoder; + + decoder = stream->Decoder; + // FIXME: this lock shouldn't be necessary now + pthread_mutex_lock(&stream->DecoderLockMutex); + stream->Decoder = NULL; // lock read thread + pthread_mutex_unlock(&stream->DecoderLockMutex); + CodecVideoClose(decoder); + CodecVideoDelDecoder(decoder); + } + if (stream->HwDecoder) { + VideoDelHwDecoder(stream->HwDecoder); + stream->HwDecoder = NULL; + // FIXME: CodecVideoClose calls/uses hw decoder + } + VideoPacketExit(stream); + + stream->NewStream = 1; +} + +/** ** Poll PES packet ringbuffer. ** ** Called if video frame buffers are full. @@ -1700,6 +1734,11 @@ int VideoPollInput(VideoStream * stream) return -1; } + if (stream->Close) { // close stream request + VideoStreamClose(stream); + stream->Close = 0; + return 1; + } if (stream->ClearBuffers) { // clear buffer request atomic_set(&stream->PacketsFilled, 0); stream->PacketRead = stream->PacketWrite; @@ -1738,6 +1777,11 @@ int VideoDecodeInput(VideoStream * stream) return -1; } + if (stream->Close) { // close stream request + VideoStreamClose(stream); + stream->Close = 0; + return 1; + } if (stream->ClearBuffers) { // clear buffer request atomic_set(&stream->PacketsFilled, 0); stream->PacketRead = stream->PacketWrite; @@ -3254,10 +3298,15 @@ void PipStart(int x, int y, int width, int height, int pip_x, int pip_y, */ void PipStop(void) { + int i; + if (!MyVideoStream->HwDecoder) { // video not running return; } + ScaleVideo(0, 0, 0, 0); + +#if 0 PipVideoStream->SkipStream = 1; // lock write thread if (PipVideoStream->Decoder) { VideoDecoder *decoder; @@ -3277,8 +3326,13 @@ void PipStop(void) VideoPacketExit(PipVideoStream); PipVideoStream->NewStream = 1; - - ScaleVideo(0, 0, 0, 0); +#else + PipVideoStream->Close = 1; + for (i = 0; PipVideoStream->Close && i < 50; ++i) { + usleep(1 * 1000); + } + Info("[softhddev]%s: pip close %dms\n", __FUNCTION__, i); +#endif } /** |