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
|
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
14
Todo
@ -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
|
||||||
|
64
softhddev.c
64
softhddev.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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")) {
|
||||||
|
Loading…
Reference in New Issue
Block a user