mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Support external players.
This commit is contained in:
parent
9063b4e3ff
commit
bcf6ecabc1
@ -1,6 +1,7 @@
|
||||
User johns
|
||||
Date:
|
||||
|
||||
Support external players.
|
||||
Add VDPAU display preemption support.
|
||||
|
||||
User m.Rcu
|
||||
|
14
Todo
14
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
|
||||
|
80
softhddev.c
80
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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")) {
|
||||
|
Loading…
Reference in New Issue
Block a user