Support external players.

This commit is contained in:
Johns 2012-01-26 15:00:49 +01:00
parent 9063b4e3ff
commit bcf6ecabc1
5 changed files with 56 additions and 55 deletions

View File

@ -1,6 +1,7 @@
User johns User johns
Date: Date:
Support external players.
Add VDPAU display preemption support. Add VDPAU display preemption support.
User m.Rcu User m.Rcu

14
Todo
View File

@ -23,7 +23,7 @@ missing:
software decoder with software deinterlace software decoder with software deinterlace
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?) zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)? 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! Option deinterlace off / deinterlace force!
Make output drivers better modular (under construction). Make output drivers better modular (under construction).
@ -37,15 +37,14 @@ video:
grab image with hardware and better scaling support grab image with hardware and better scaling support
suspendoutput didn't show logo or black pictures suspendoutput didn't show logo or black pictures
(must detect video format to show image) (must detect video format to show image)
incomplete mpeg packets creates artefacts after channel switch
hard channel switch
vdpau: vdpau:
hard channel switch
libva: libva:
hard channel switch
yaepghd (VaapiSetOutputPosition) support yaepghd (VaapiSetOutputPosition) support
can associate ony displayed part of osd can associate ony displayed part of osd
ready(not intel checked) auto crop for va-api
grab image for va-api grab image for va-api
still many: still many:
[drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung [drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung
@ -55,8 +54,7 @@ libva: branch vaapi-ext
add support for vaapi-ext add support for vaapi-ext
libva-intel-driver: libva-intel-driver:
intel still has hangups most with 1080i 1080i does no v-sync (sometimes correct working with vaapi-ext)
1080i does no v-sync (workaround written, fixed with vaapi-ext)
OSD has sometimes wrong size (workaround written) OSD has sometimes wrong size (workaround written)
libva-vdpau-driver: libva-vdpau-driver:
@ -73,10 +71,10 @@ x11:
audio: audio:
write TS -> PES parser, which feeds audio before the next start packet 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. Combine alsa+oss ringbuffer code.
Make alsa thread/polled and oss thread/polled output module runtime Make alsa thread/polled and oss thread/polled output module runtime
selectable. selectable.
software volume support
audio/alsa: audio/alsa:
better downmix of >2 channels on 2 channel hardware better downmix of >2 channels on 2 channel hardware
@ -91,7 +89,6 @@ audio/oss:
HDMI/SPDIF Passthrough: HDMI/SPDIF Passthrough:
only AC-3 written only AC-3 written
Channels are wrong setup, if changing setting during operation. Channels are wrong setup, if changing setting during operation.
split pcm and ac-3 out into two devices
support oss pass-through support oss pass-through
playback of recording playback of recording
@ -119,6 +116,5 @@ future features (not planed for 1.0 - 1.5)
atmolight support atmolight support
multistream handling multistream handling
pip support pip support
grab image with jpeg
upmix stereo to AC-3 upmix stereo to AC-3

View File

@ -61,8 +61,6 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
#endif #endif
static char ConfigFullscreen; ///< fullscreen modus 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 static pthread_mutex_t SuspendLockMutex; ///< suspend lock mutex
@ -212,15 +210,15 @@ int PlayAudio(const uint8_t * data, int size,
if (VideoFreezed) { // video freezed if (VideoFreezed) { // video freezed
return 0; return 0;
} }
if (SkipAudio || !MyAudioDecoder) { // skip audio
return size;
}
if (NewAudioStream) { if (NewAudioStream) {
// FIXME: does this clear the audio ringbuffer? // FIXME: does this clear the audio ringbuffer?
CodecAudioClose(MyAudioDecoder); CodecAudioClose(MyAudioDecoder);
AudioCodecID = CODEC_ID_NONE; AudioCodecID = CODEC_ID_NONE;
NewAudioStream = 0; NewAudioStream = 0;
} }
if (SkipAudio) { // skip audio
return size;
}
// PES header 0x00 0x00 0x01 ID // PES header 0x00 0x00 0x01 ID
// ID 0xBD 0xC0-0xCF // ID 0xBD 0xC0-0xCF
@ -263,27 +261,17 @@ int PlayAudio(const uint8_t * data, int size,
// Syncword - 0x0B77 // Syncword - 0x0B77
if (data[0] == 0x0B && data[1] == 0x77) { if (data[0] == 0x0B && data[1] == 0x77) {
if (!MyAudioDecoder) {
MyAudioDecoder = CodecAudioNewDecoder();
AudioCodecID = CODEC_ID_NONE;
}
if (AudioCodecID != CODEC_ID_AC3) { if (AudioCodecID != CODEC_ID_AC3) {
Debug(3, "[softhddev]%s: AC-3 %d\n", __FUNCTION__, id); Debug(3, "[softhddev]%s: AC-3 %d\n", __FUNCTION__, id);
CodecAudioClose(MyAudioDecoder); CodecAudioClose(MyAudioDecoder);
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AC3); CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AC3);
AudioCodecID = CODEC_ID_AC3; AudioCodecID = CODEC_ID_AC3;
} }
// Syncword - 0xFFFC - 0xFFFF // Syncword - 0xFFFC - 0xFFFF
} else if (data[0] == 0xFF && (data[1] & 0xFC) == 0xFC) { } else if (data[0] == 0xFF && (data[1] & 0xFC) == 0xFC) {
if (!MyAudioDecoder) {
MyAudioDecoder = CodecAudioNewDecoder();
AudioCodecID = CODEC_ID_NONE;
}
if (AudioCodecID != CODEC_ID_MP2) { if (AudioCodecID != CODEC_ID_MP2) {
Debug(3, "[softhddev]%s: MP2 %d\n", __FUNCTION__, id); Debug(3, "[softhddev]%s: MP2 %d\n", __FUNCTION__, id);
CodecAudioClose(MyAudioDecoder); CodecAudioClose(MyAudioDecoder);
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2); CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2);
AudioCodecID = CODEC_ID_MP2; AudioCodecID = CODEC_ID_MP2;
} }
@ -300,9 +288,6 @@ int PlayAudio(const uint8_t * data, int size,
if (n < 0) { if (n < 0) {
return osize; return osize;
} }
if (!MyAudioDecoder) {
MyAudioDecoder = CodecAudioNewDecoder();
}
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2); CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2);
AudioCodecID = CODEC_ID_MP2; AudioCodecID = CODEC_ID_MP2;
@ -312,7 +297,7 @@ int PlayAudio(const uint8_t * data, int size,
} }
// no decoder or codec known // no decoder or codec known
if (!MyAudioDecoder || AudioCodecID == CODEC_ID_NONE) { if (AudioCodecID == CODEC_ID_NONE) {
return osize; return osize;
} }
@ -757,13 +742,15 @@ int PlayVideo(const uint8_t * data, int size)
} }
#endif #endif
} }
// FIXME: no valid mpeg2/h264 detection yet
check = data + 9 + n; check = data + 9 + n;
if (0) { if (0) {
printf("%02x: %02x %02x %02x %02x %02x\n", data[6], check[0], check[1], printf("%02x: %02x %02x %02x %02x %02x\n", data[6], check[0], check[1],
check[2], check[3], check[4]); 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 // PES_VIDEO_STREAM 0xE0 or PES start code
//(data[6] & 0xC0) != 0x80 || //(data[6] & 0xC0) != 0x80 ||
if ((!check[0] && !check[1] && check[2] == 0x1)) { 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"); Debug(3, "video: not detected\n");
return size; 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 // mpeg codec supports incomplete packets
// waiting for a full complete packages, increases needed delays // waiting for a full complete packages, increases needed delays
VideoNextPacket(CODEC_ID_MPEG2VIDEO); 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) void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb)
{ {
Resume();
VideoOsdDrawARGB(x, y, height, width, argb); VideoOsdDrawARGB(x, y, height, width, argb);
} }
@ -1316,8 +1304,12 @@ void Start(void)
StartXServer(); StartXServer();
} }
CodecInit(); CodecInit();
// FIXME: AudioInit for HDMI after X11 startup // FIXME: AudioInit for HDMI after X11 startup
AudioInit(); AudioInit();
MyAudioDecoder = CodecAudioNewDecoder();
AudioCodecID = CODEC_ID_NONE;
if (!ConfigStartX11Server) { if (!ConfigStartX11Server) {
StartVideo(); StartVideo();
} }
@ -1350,8 +1342,12 @@ void MainThreadHook(void)
/** /**
** Suspend plugin. ** 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); pthread_mutex_lock(&SuspendLockMutex);
if (SkipVideo && SkipAudio) { // already suspended if (SkipVideo && SkipAudio) { // already suspended
@ -1365,9 +1361,10 @@ void Suspend(void)
SkipAudio = 1; SkipAudio = 1;
pthread_mutex_unlock(&SuspendLockMutex); pthread_mutex_unlock(&SuspendLockMutex);
if (ConfigSuspendClose) { if (audio || video) {
pthread_mutex_lock(&SuspendLockMutex); pthread_mutex_lock(&SuspendLockMutex);
if (audio) {
AudioExit(); AudioExit();
if (MyAudioDecoder) { if (MyAudioDecoder) {
CodecAudioClose(MyAudioDecoder); CodecAudioClose(MyAudioDecoder);
@ -1375,12 +1372,14 @@ void Suspend(void)
MyAudioDecoder = NULL; MyAudioDecoder = NULL;
} }
NewAudioStream = 0; NewAudioStream = 0;
}
if (video) {
StopVideo(); StopVideo();
}
pthread_mutex_unlock(&SuspendLockMutex); pthread_mutex_unlock(&SuspendLockMutex);
} }
if (ConfigSuspendX11) { if (dox11) {
// FIXME: stop x11, if started // FIXME: stop x11, if started
} }
} }
@ -1396,17 +1395,20 @@ void Resume(void)
Debug(3, "[softhddev]%s:\n", __FUNCTION__); 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(); StartVideo();
}
if (!MyAudioDecoder) { // audio not running
AudioInit(); AudioInit();
MyAudioDecoder = CodecAudioNewDecoder();
pthread_mutex_unlock(&SuspendLockMutex); AudioCodecID = CODEC_ID_NONE;
} }
SkipVideo = 0; SkipVideo = 0;
SkipAudio = 0; SkipAudio = 0;
pthread_mutex_unlock(&SuspendLockMutex);
} }

View File

@ -79,7 +79,7 @@ extern "C"
extern void MainThreadHook(void); extern void MainThreadHook(void);
/// Suspend plugin /// Suspend plugin
extern void Suspend(void); extern void Suspend(int, int, int);
/// Resume plugin /// Resume plugin
extern void Resume(void); extern void Resume(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -38,8 +38,6 @@ extern "C"
#include "video.h" #include "video.h"
extern void AudioPoller(void); extern void AudioPoller(void);
extern void CodecSetAudioPassthrough(int); 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 ConfigAutoCropInterval; ///< auto crop detection interval
static int ConfigAutoCropDelay; ///< auto crop detection delay 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 static volatile char DoMakePrimary; ///< flag switch primary
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -722,7 +723,8 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
return true; return true;
case pmExtern_THIS_SHOULD_BE_AVOIDED: case pmExtern_THIS_SHOULD_BE_AVOIDED:
dsyslog("[softhddev] play mode external\n"); dsyslog("[softhddev] play mode external\n");
break; Suspend(1, 1, 0);
return true;
default: default:
dsyslog("[softhddev]playmode not implemented... %d\n", play_mode); dsyslog("[softhddev]playmode not implemented... %d\n", play_mode);
break; break;
@ -1096,7 +1098,7 @@ cOsdObject *cPluginSoftHdDevice::MainMenuAction(void)
//MyDevice->StopReplay(); //MyDevice->StopReplay();
cControl::Launch(new cSoftHdControl); cControl::Launch(new cSoftHdControl);
cControl::Attach(); cControl::Attach();
Suspend(); Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11);
if (ShutdownHandler.GetUserInactiveTime()) { if (ShutdownHandler.GetUserInactiveTime()) {
dsyslog("[softhddev]%s: set user inactive\n", __FUNCTION__); dsyslog("[softhddev]%s: set user inactive\n", __FUNCTION__);
ShutdownHandler.SetUserInactive(); ShutdownHandler.SetUserInactive();
@ -1121,7 +1123,7 @@ void cPluginSoftHdDevice::MainThreadHook(void)
// check if user is inactive, automatic enter suspend mode // check if user is inactive, automatic enter suspend mode
if (ShutdownHandler.IsUserInactive()) { if (ShutdownHandler.IsUserInactive()) {
// this is regular called, but guarded against double calls // this is regular called, but guarded against double calls
Suspend(); Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11);
} }
::MainThreadHook(); ::MainThreadHook();
@ -1271,7 +1273,7 @@ cString cPluginSoftHdDevice::SVDRPCommand(const char *command,
if (!strcasecmp(command, "SUSP")) { if (!strcasecmp(command, "SUSP")) {
cControl::Launch(new cSoftHdControl); cControl::Launch(new cSoftHdControl);
cControl::Attach(); cControl::Attach();
Suspend(); Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11);
return "SoftHdDevice is suspended"; return "SoftHdDevice is suspended";
} }
if (!strcasecmp(command, "RESU")) { if (!strcasecmp(command, "RESU")) {