From bcf6ecabc1ca83d8f6de578ee2d25ad162518981 Mon Sep 17 00:00:00 2001 From: Johns Date: Thu, 26 Jan 2012 15:00:49 +0100 Subject: [PATCH] Support external players. --- ChangeLog | 1 + Todo | 14 +++------ softhddev.c | 80 +++++++++++++++++++++++++----------------------- softhddev.h | 2 +- softhddevice.cpp | 14 +++++---- 5 files changed, 56 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2f71584..0b264f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ User johns Date: + Support external players. Add VDPAU display preemption support. User m.Rcu diff --git a/Todo b/Todo index 4f6f3ef..371f2d5 100644 --- a/Todo +++ b/Todo @@ -23,7 +23,7 @@ missing: software decoder with software deinterlace zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?) ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)? - suspend output / energie saver: stop audio, stop video, configurable + suspend output / energie saver: stop and restart X11 Option deinterlace off / deinterlace force! Make output drivers better modular (under construction). @@ -37,15 +37,14 @@ video: grab image with hardware and better scaling support suspendoutput didn't show logo or black pictures (must detect video format to show image) + incomplete mpeg packets creates artefacts after channel switch + hard channel switch vdpau: - hard channel switch libva: - hard channel switch yaepghd (VaapiSetOutputPosition) support can associate ony displayed part of osd - ready(not intel checked) auto crop for va-api grab image for va-api still many: [drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung @@ -55,8 +54,7 @@ libva: branch vaapi-ext add support for vaapi-ext libva-intel-driver: - intel still has hangups most with 1080i - 1080i does no v-sync (workaround written, fixed with vaapi-ext) + 1080i does no v-sync (sometimes correct working with vaapi-ext) OSD has sometimes wrong size (workaround written) libva-vdpau-driver: @@ -73,10 +71,10 @@ x11: audio: write TS -> PES parser, which feeds audio before the next start packet - CodecAudioOpen can fail "can't open audio codec" and does Fatal exit. Combine alsa+oss ringbuffer code. Make alsa thread/polled and oss thread/polled output module runtime selectable. + software volume support audio/alsa: better downmix of >2 channels on 2 channel hardware @@ -91,7 +89,6 @@ audio/oss: HDMI/SPDIF Passthrough: only AC-3 written Channels are wrong setup, if changing setting during operation. - split pcm and ac-3 out into two devices support oss pass-through playback of recording @@ -119,6 +116,5 @@ future features (not planed for 1.0 - 1.5) atmolight support multistream handling pip support - grab image with jpeg upmix stereo to AC-3 diff --git a/softhddev.c b/softhddev.c index cbeaed1..1380424 100644 --- a/softhddev.c +++ b/softhddev.c @@ -61,8 +61,6 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible #endif static char ConfigFullscreen; ///< fullscreen modus -char ConfigSuspendClose; ///< suspend should close devices -char ConfigSuspendX11; ///< suspend should stop x11 static pthread_mutex_t SuspendLockMutex; ///< suspend lock mutex @@ -212,15 +210,15 @@ int PlayAudio(const uint8_t * data, int size, if (VideoFreezed) { // video freezed return 0; } + if (SkipAudio || !MyAudioDecoder) { // skip audio + return size; + } if (NewAudioStream) { // FIXME: does this clear the audio ringbuffer? CodecAudioClose(MyAudioDecoder); AudioCodecID = CODEC_ID_NONE; NewAudioStream = 0; } - if (SkipAudio) { // skip audio - return size; - } // PES header 0x00 0x00 0x01 ID // ID 0xBD 0xC0-0xCF @@ -263,27 +261,17 @@ int PlayAudio(const uint8_t * data, int size, // Syncword - 0x0B77 if (data[0] == 0x0B && data[1] == 0x77) { - if (!MyAudioDecoder) { - MyAudioDecoder = CodecAudioNewDecoder(); - AudioCodecID = CODEC_ID_NONE; - } if (AudioCodecID != CODEC_ID_AC3) { Debug(3, "[softhddev]%s: AC-3 %d\n", __FUNCTION__, id); CodecAudioClose(MyAudioDecoder); - CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AC3); AudioCodecID = CODEC_ID_AC3; } // Syncword - 0xFFFC - 0xFFFF } else if (data[0] == 0xFF && (data[1] & 0xFC) == 0xFC) { - if (!MyAudioDecoder) { - MyAudioDecoder = CodecAudioNewDecoder(); - AudioCodecID = CODEC_ID_NONE; - } if (AudioCodecID != CODEC_ID_MP2) { Debug(3, "[softhddev]%s: MP2 %d\n", __FUNCTION__, id); CodecAudioClose(MyAudioDecoder); - CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2); AudioCodecID = CODEC_ID_MP2; } @@ -300,9 +288,6 @@ int PlayAudio(const uint8_t * data, int size, if (n < 0) { return osize; } - if (!MyAudioDecoder) { - MyAudioDecoder = CodecAudioNewDecoder(); - } CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2); AudioCodecID = CODEC_ID_MP2; @@ -312,7 +297,7 @@ int PlayAudio(const uint8_t * data, int size, } // no decoder or codec known - if (!MyAudioDecoder || AudioCodecID == CODEC_ID_NONE) { + if (AudioCodecID == CODEC_ID_NONE) { return osize; } @@ -757,13 +742,15 @@ int PlayVideo(const uint8_t * data, int size) } #endif } - // FIXME: no valid mpeg2/h264 detection yet check = data + 9 + n; if (0) { printf("%02x: %02x %02x %02x %02x %02x\n", data[6], check[0], check[1], check[2], check[3], check[4]); } + // FIXME: no valid mpeg2/h264 detection yet + // FIXME: better skip all zero's >3 && 0x01 0x09 h264, >2 && 0x01 -> mpeg2 + // PES_VIDEO_STREAM 0xE0 or PES start code //(data[6] & 0xC0) != 0x80 || if ((!check[0] && !check[1] && check[2] == 0x1)) { @@ -803,7 +790,9 @@ int PlayVideo(const uint8_t * data, int size) Debug(3, "video: not detected\n"); return size; } - if (VideoCodecID == CODEC_ID_MPEG2VIDEO) { + // FIXME: incomplete packets produce artefacts after channel switch + if (atomic_read(&VideoPacketsFilled) + && VideoCodecID == CODEC_ID_MPEG2VIDEO) { // mpeg codec supports incomplete packets // waiting for a full complete packages, increases needed delays VideoNextPacket(CODEC_ID_MPEG2VIDEO); @@ -1079,7 +1068,6 @@ void OsdClose(void) */ void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb) { - Resume(); VideoOsdDrawARGB(x, y, height, width, argb); } @@ -1316,8 +1304,12 @@ void Start(void) StartXServer(); } CodecInit(); + // FIXME: AudioInit for HDMI after X11 startup AudioInit(); + MyAudioDecoder = CodecAudioNewDecoder(); + AudioCodecID = CODEC_ID_NONE; + if (!ConfigStartX11Server) { StartVideo(); } @@ -1350,8 +1342,12 @@ void MainThreadHook(void) /** ** Suspend plugin. +** +** @param video suspend closes video +** @param audio suspend closes audio +** @param dox11 suspend closes x11 server */ -void Suspend(void) +void Suspend(int video, int audio, int dox11) { pthread_mutex_lock(&SuspendLockMutex); if (SkipVideo && SkipAudio) { // already suspended @@ -1365,22 +1361,25 @@ void Suspend(void) SkipAudio = 1; pthread_mutex_unlock(&SuspendLockMutex); - if (ConfigSuspendClose) { + if (audio || video) { pthread_mutex_lock(&SuspendLockMutex); - AudioExit(); - if (MyAudioDecoder) { - CodecAudioClose(MyAudioDecoder); - CodecAudioDelDecoder(MyAudioDecoder); - MyAudioDecoder = NULL; + if (audio) { + AudioExit(); + if (MyAudioDecoder) { + CodecAudioClose(MyAudioDecoder); + CodecAudioDelDecoder(MyAudioDecoder); + MyAudioDecoder = NULL; + } + NewAudioStream = 0; + } + if (video) { + StopVideo(); } - NewAudioStream = 0; - - StopVideo(); pthread_mutex_unlock(&SuspendLockMutex); } - if (ConfigSuspendX11) { + if (dox11) { // FIXME: stop x11, if started } } @@ -1396,17 +1395,20 @@ void Resume(void) Debug(3, "[softhddev]%s:\n", __FUNCTION__); - if (ConfigSuspendX11) { - } - if (ConfigSuspendClose) { - pthread_mutex_lock(&SuspendLockMutex); + pthread_mutex_lock(&SuspendLockMutex); + // FIXME: start x11 + if (!MyHwDecoder) { // video not running StartVideo(); + } + if (!MyAudioDecoder) { // audio not running AudioInit(); - - pthread_mutex_unlock(&SuspendLockMutex); + MyAudioDecoder = CodecAudioNewDecoder(); + AudioCodecID = CODEC_ID_NONE; } SkipVideo = 0; SkipAudio = 0; + + pthread_mutex_unlock(&SuspendLockMutex); } diff --git a/softhddev.h b/softhddev.h index a1e21e3..feb4a26 100644 --- a/softhddev.h +++ b/softhddev.h @@ -79,7 +79,7 @@ extern "C" extern void MainThreadHook(void); /// Suspend plugin - extern void Suspend(void); + extern void Suspend(int, int, int); /// Resume plugin extern void Resume(void); #ifdef __cplusplus diff --git a/softhddevice.cpp b/softhddevice.cpp index a841316..8e3a336 100644 --- a/softhddevice.cpp +++ b/softhddevice.cpp @@ -38,8 +38,6 @@ 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 } ////////////////////////////////////////////////////////////////////////////// @@ -84,6 +82,9 @@ static int ConfigAudioPassthrough; ///< config audio pass-through static int ConfigAutoCropInterval; ///< auto crop detection interval static int ConfigAutoCropDelay; ///< auto crop detection delay +static char ConfigSuspendClose; ///< suspend should close devices +static char ConfigSuspendX11; ///< suspend should stop x11 + static volatile char DoMakePrimary; ///< flag switch primary ////////////////////////////////////////////////////////////////////////////// @@ -722,7 +723,8 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode) return true; case pmExtern_THIS_SHOULD_BE_AVOIDED: dsyslog("[softhddev] play mode external\n"); - break; + Suspend(1, 1, 0); + return true; default: dsyslog("[softhddev]playmode not implemented... %d\n", play_mode); break; @@ -1096,7 +1098,7 @@ cOsdObject *cPluginSoftHdDevice::MainMenuAction(void) //MyDevice->StopReplay(); cControl::Launch(new cSoftHdControl); cControl::Attach(); - Suspend(); + Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11); if (ShutdownHandler.GetUserInactiveTime()) { dsyslog("[softhddev]%s: set user inactive\n", __FUNCTION__); ShutdownHandler.SetUserInactive(); @@ -1121,7 +1123,7 @@ void cPluginSoftHdDevice::MainThreadHook(void) // check if user is inactive, automatic enter suspend mode if (ShutdownHandler.IsUserInactive()) { // this is regular called, but guarded against double calls - Suspend(); + Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11); } ::MainThreadHook(); @@ -1271,7 +1273,7 @@ cString cPluginSoftHdDevice::SVDRPCommand(const char *command, if (!strcasecmp(command, "SUSP")) { cControl::Launch(new cSoftHdControl); cControl::Attach(); - Suspend(); + Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11); return "SoftHdDevice is suspended"; } if (!strcasecmp(command, "RESU")) {