mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 17:16:51 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa27a1c73a | ||
|
|
e32857a27a | ||
|
|
5ba88bb822 | ||
|
|
0422b6aa5a | ||
|
|
eb024558de | ||
|
|
1593d5dd83 | ||
|
|
09f62307d4 |
10
ChangeLog
10
ChangeLog
@@ -1,4 +1,14 @@
|
||||
User johns
|
||||
Date: Sat Jan 21 15:49:16 CET 2012
|
||||
|
||||
Release Version 0.4.0
|
||||
VDPAU: Add grab image support.
|
||||
VDPAU: Add auto-crop support.
|
||||
VDPAU: Changed OSD alpha calculation.
|
||||
Fix bug: Used VideoSharpen for denoise settings.
|
||||
Instant update deinterlace/... configuration changes.
|
||||
Fix bug: AudioExit called without AudioInit crash.
|
||||
|
||||
Date: Thu Jan 19 15:58:40 CET 2012
|
||||
|
||||
Release Version 0.3.5
|
||||
|
||||
23
README.txt
23
README.txt
@@ -24,17 +24,20 @@ A software and GPU emulated HD output device plugin for VDR.
|
||||
o Video CPU/VA-API
|
||||
o Video VDPAU/VDPAU
|
||||
o Video CPU/VDPAU
|
||||
o Audio FFMpeg/Alsa/Analog
|
||||
o Audio FFMpeg/Alsa/Digital
|
||||
o Audio FFMpeg/OSS/Analog
|
||||
o HDMI/SPDIF Passthrough
|
||||
o VA-API bob software deinterlace
|
||||
o Auto-crop
|
||||
|
||||
o planned: Video VA-API/Opengl
|
||||
o planned: Video VDPAU/Opengl
|
||||
o planned: Video CPU/Xv
|
||||
o planned: Video CPU/Opengl
|
||||
o planned: Software Deinterlacer
|
||||
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
|
||||
o planned: Video XvBA/XvBA
|
||||
o Audio FFMpeg/Alsa/Analog
|
||||
o Audio FFMpeg/Alsa/Digital
|
||||
o Audio FFMpeg/OSS/Analog
|
||||
o Alsa HDMI/SPDIF Passthrough
|
||||
o planned: OSS HDMI/SPDIF Passthrough
|
||||
o planned: atmo light support
|
||||
|
||||
To compile you must have the 'requires' installed.
|
||||
|
||||
@@ -125,6 +128,14 @@ Setup: /etc/vdr/setup.conf
|
||||
softhddevice.AudioPassthrough = 0
|
||||
0 = none, 1 = AC-3
|
||||
|
||||
softhddevice.AutoCrop.Interval = 0
|
||||
0 disables auto-crop
|
||||
n each 'n' frames auto-crop is checked.
|
||||
|
||||
softhddevice.AutoCrop.Delay = 0
|
||||
if auto-crop is over after 'n' intervals the same, the cropping is
|
||||
used.
|
||||
|
||||
Setup: /etc/vdr/remote.conf
|
||||
------
|
||||
|
||||
|
||||
16
Todo
16
Todo
@@ -21,19 +21,19 @@ $Id: $
|
||||
missing:
|
||||
software deinterlace (yadif, ...)
|
||||
software decoder with software deinterlace
|
||||
auto crop
|
||||
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
|
||||
Option deinterlace off / deinterlace force!
|
||||
Make output drivers better modular.
|
||||
Make output drivers better modular (under construction).
|
||||
|
||||
video:
|
||||
subtitle not cleared
|
||||
subtitle could be asyncron
|
||||
reduce warnings after channel switch
|
||||
|
||||
vdpau:
|
||||
VdpPreemptionCallback handling
|
||||
VdpPreemptionCallback handling (under construction)
|
||||
hard channel switch
|
||||
suspendoutput didn't show logo or black picture.
|
||||
|
||||
@@ -41,10 +41,15 @@ libva:
|
||||
hard channel switch
|
||||
yaepghd (VaapiSetOutputPosition) support
|
||||
can associate ony displayed part of osd
|
||||
auto crop for va-api
|
||||
grab image for va-api
|
||||
|
||||
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)
|
||||
1080i does no v-sync (workaround written, fixed with vaapi-ext)
|
||||
OSD has sometimes wrong size (workaround written)
|
||||
|
||||
libva-vdpau-driver:
|
||||
@@ -91,7 +96,6 @@ setup:
|
||||
Setup 4:3 zoom type
|
||||
Some setup parameters are not used until restart.
|
||||
Can a notice be added to the setup menu?
|
||||
576i, 720p, fake 1080i, 1080i
|
||||
|
||||
unsorted:
|
||||
Menu -> Setup -> Plugins -> skingenigmang -> General
|
||||
@@ -105,5 +109,7 @@ future features (not planed for 1.0 - 1.5)
|
||||
software decoder for xv / opengl
|
||||
atmolight support
|
||||
multistream handling
|
||||
pip support
|
||||
grab image with jpeg
|
||||
|
||||
upmix stereo to AC-3
|
||||
|
||||
35
audio.c
35
audio.c
@@ -99,7 +99,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
** Audio output module typedef.
|
||||
** Audio output module structure and typedef.
|
||||
*/
|
||||
typedef struct _audio_module_
|
||||
{
|
||||
@@ -117,12 +117,16 @@ typedef struct _audio_module_
|
||||
void (*Exit) (void); ///< cleanup audio output module
|
||||
} AudioModule;
|
||||
|
||||
static const AudioModule NoopModule; ///< forward definition of noop module
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Variables
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static const char *AudioModuleName; ///< which audio module to use
|
||||
static const AudioModule *UsedAudioModule; ///< Selected audio module.
|
||||
|
||||
/// Selected audio module.
|
||||
static const AudioModule *AudioUsedModule = &NoopModule;
|
||||
static const char *AudioPCMDevice; ///< alsa/OSS PCM device name
|
||||
static const char *AudioMixerDevice; ///< alsa/OSS mixer device name
|
||||
static const char *AudioMixerChannel; ///< alsa/OSS mixer channel name
|
||||
@@ -1863,7 +1867,7 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
#endif
|
||||
|
||||
Debug(3, "audio: play start\n");
|
||||
UsedAudioModule->Thread();
|
||||
AudioUsedModule->Thread();
|
||||
}
|
||||
|
||||
return dummy;
|
||||
@@ -1928,7 +1932,7 @@ static const AudioModule *AudioModules[] = {
|
||||
*/
|
||||
void AudioEnqueue(const void *samples, int count)
|
||||
{
|
||||
UsedAudioModule->Enqueue(samples, count);
|
||||
AudioUsedModule->Enqueue(samples, count);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1936,7 +1940,7 @@ void AudioEnqueue(const void *samples, int count)
|
||||
*/
|
||||
void AudioFlushBuffers(void)
|
||||
{
|
||||
UsedAudioModule->FlushBuffers();
|
||||
AudioUsedModule->FlushBuffers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1944,7 +1948,7 @@ void AudioFlushBuffers(void)
|
||||
*/
|
||||
void AudioPoller(void)
|
||||
{
|
||||
UsedAudioModule->Poller();
|
||||
AudioUsedModule->Poller();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1952,7 +1956,7 @@ void AudioPoller(void)
|
||||
*/
|
||||
int AudioFreeBytes(void)
|
||||
{
|
||||
return UsedAudioModule->FreeBytes();
|
||||
return AudioUsedModule->FreeBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1962,7 +1966,7 @@ int AudioFreeBytes(void)
|
||||
*/
|
||||
uint64_t AudioGetDelay(void)
|
||||
{
|
||||
return UsedAudioModule->GetDelay();
|
||||
return AudioUsedModule->GetDelay();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2041,7 +2045,7 @@ int AudioSetup(int *freq, int *channels)
|
||||
// FIXME: need to store possible combination and report this
|
||||
return AudioRingAdd(*freq, *channels);
|
||||
#endif
|
||||
return UsedAudioModule->Setup(freq, channels);
|
||||
return AudioUsedModule->Setup(freq, channels);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2089,27 +2093,27 @@ void AudioInit(void)
|
||||
//
|
||||
for (u = 0; u < sizeof(AudioModules) / sizeof(*AudioModules); ++u) {
|
||||
if (!strcasecmp(name, AudioModules[u]->Name)) {
|
||||
UsedAudioModule = AudioModules[u];
|
||||
Info(_("audio: '%s' output module used\n"), UsedAudioModule->Name);
|
||||
AudioUsedModule = AudioModules[u];
|
||||
Info(_("audio: '%s' output module used\n"), AudioUsedModule->Name);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
Error(_("audio: '%s' output module isn't supported\n"), name);
|
||||
UsedAudioModule = &NoopModule;
|
||||
AudioUsedModule = &NoopModule;
|
||||
return;
|
||||
|
||||
found:
|
||||
#ifdef USE_AUDIORING
|
||||
AudioRingInit();
|
||||
#endif
|
||||
UsedAudioModule->Init();
|
||||
AudioUsedModule->Init();
|
||||
freq = 48000;
|
||||
chan = 2;
|
||||
if (AudioSetup(&freq, &chan)) { // set default parameters
|
||||
Error(_("audio: can't do initial setup\n"));
|
||||
}
|
||||
#ifdef USE_AUDIO_THREAD
|
||||
if (UsedAudioModule->Thread) { // supports threads
|
||||
if (AudioUsedModule->Thread) { // supports threads
|
||||
AudioInitThread();
|
||||
}
|
||||
#endif
|
||||
@@ -2125,7 +2129,8 @@ void AudioExit(void)
|
||||
#ifdef USE_AUDIO_THREAD
|
||||
AudioExitThread();
|
||||
#endif
|
||||
UsedAudioModule->Exit();
|
||||
AudioUsedModule->Exit();
|
||||
AudioUsedModule = &NoopModule;
|
||||
#ifdef USE_AUDIORING
|
||||
AudioRingExit();
|
||||
#endif
|
||||
|
||||
34
softhddev.c
34
softhddev.c
@@ -791,6 +791,29 @@ int PlayVideo(const uint8_t * data, int size)
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
** Grabs the currently visible screen image.
|
||||
**
|
||||
** @param size size of the returned data
|
||||
** @param jpeg flag true, create JPEG data
|
||||
** @param quality JPEG quality
|
||||
** @param width number of horizontal pixels in the frame
|
||||
** @param height number of vertical pixels in the frame
|
||||
*/
|
||||
uint8_t *GrabImage(int *size, int jpeg, int quality, int width, int height)
|
||||
{
|
||||
if (jpeg) {
|
||||
(void)quality;
|
||||
Error(_("softhddev: jpeg grabbing not supported\n"));
|
||||
return NULL;
|
||||
}
|
||||
if (width != -1 && height != -1) {
|
||||
Error(_("softhddev: scaling not supported\n"));
|
||||
return NULL;
|
||||
}
|
||||
return VideoGrab(size, &width, &height);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@@ -1117,8 +1140,12 @@ static void StartXServer(void)
|
||||
*/
|
||||
void SoftHdDeviceExit(void)
|
||||
{
|
||||
// lets hope that vdr does a good thead cleanup
|
||||
// no it doesn't do a good thread cleanup
|
||||
// lets hope that vdr does a good thread cleanup
|
||||
|
||||
VideoOsdExit();
|
||||
VideoExit();
|
||||
AudioExit();
|
||||
|
||||
if (MyVideoDecoder) {
|
||||
CodecVideoClose(MyVideoDecoder);
|
||||
// FIXME: CodecDelVideoDecoder(MyVideoDecoder);
|
||||
@@ -1130,9 +1157,6 @@ void SoftHdDeviceExit(void)
|
||||
MyAudioDecoder = NULL;
|
||||
}
|
||||
|
||||
VideoOsdExit();
|
||||
VideoExit();
|
||||
AudioExit();
|
||||
CodecExit();
|
||||
VideoPacketExit();
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ extern "C"
|
||||
extern int PlayVideo(const uint8_t *, int);
|
||||
/// C plugin play TS video packet
|
||||
extern void PlayTsVideo(const uint8_t *, int);
|
||||
/// C plugin grab an image
|
||||
extern uint8_t *GrabImage(int *, int, int, int, int);
|
||||
|
||||
/// C plugin set play mode
|
||||
extern void SetPlayMode(void);
|
||||
|
||||
@@ -42,7 +42,7 @@ extern "C"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char *const VERSION = "0.3.5";
|
||||
static const char *const VERSION = "0.4.0";
|
||||
static const char *const DESCRIPTION =
|
||||
trNOOP("A software and GPU emulated HD device");
|
||||
|
||||
@@ -79,6 +79,9 @@ static int ConfigVideoScaling[RESOLUTIONS];
|
||||
static int ConfigVideoAudioDelay; ///< config audio delay
|
||||
static int ConfigAudioPassthrough; ///< config audio pass-through
|
||||
|
||||
static int ConfigAutoCropInterval; ///< auto crop detection interval
|
||||
static int ConfigAutoCropDelay; ///< auto crop detection delay
|
||||
|
||||
static volatile char DoMakePrimary; ///< flag switch primary
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -123,7 +126,7 @@ extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
|
||||
csoft = new cSoftRemote(keymap);
|
||||
}
|
||||
|
||||
dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
|
||||
//dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
|
||||
csoft->Put(key, repeat, release);
|
||||
}
|
||||
|
||||
@@ -145,12 +148,13 @@ class cSoftOsd:public cOsd
|
||||
cSoftOsd::cSoftOsd(int left, int top, uint level)
|
||||
:cOsd(left, top, level)
|
||||
{
|
||||
// FIXME: OsdWidth/OsdHeight not correct!
|
||||
dsyslog("[softhddev]%s: %dx%d+%d+%d, %d\n", __FUNCTION__, OsdWidth(),
|
||||
OsdHeight(), left, top, level);
|
||||
/* FIXME: OsdWidth/OsdHeight not correct!
|
||||
dsyslog("[softhddev]%s: %dx%d+%d+%d, %d\n", __FUNCTION__, OsdWidth(),
|
||||
OsdHeight(), left, top, level);
|
||||
*/
|
||||
|
||||
this->Level = level;
|
||||
//SetActive(true);
|
||||
SetActive(true);
|
||||
}
|
||||
|
||||
cSoftOsd::~cSoftOsd(void)
|
||||
@@ -292,8 +296,8 @@ void cSoftOsd::Flush(void)
|
||||
h = pm->ViewPort().Height();
|
||||
|
||||
/*
|
||||
dsyslog("[softhddev]%s: draw %dx%d+%d+%d %p\n", __FUNCTION__, w, h, x,
|
||||
y, pm->Data());
|
||||
dsyslog("[softhddev]%s: draw %dx%d+%d+%d %p\n", __FUNCTION__, w, h,
|
||||
x, y, pm->Data());
|
||||
*/
|
||||
|
||||
OsdDrawARGB(x, y, w, h, pm->Data());
|
||||
@@ -362,6 +366,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
int Sharpen[RESOLUTIONS];
|
||||
int AudioDelay;
|
||||
int AudioPassthrough;
|
||||
int AutoCropInterval;
|
||||
int AutoCropDelay;
|
||||
protected:
|
||||
virtual void Store(void);
|
||||
public:
|
||||
@@ -370,6 +376,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
|
||||
/**
|
||||
** Create a seperator item.
|
||||
**
|
||||
** @param label text inside separator
|
||||
*/
|
||||
static inline cOsdItem *SeparatorItem(const char *label)
|
||||
{
|
||||
@@ -439,6 +447,16 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
AudioPassthrough = ConfigAudioPassthrough;
|
||||
Add(new cMenuEditStraItem(tr("Audio pass-through"), &AudioPassthrough, 2,
|
||||
passthrough));
|
||||
//
|
||||
// auto-crop
|
||||
//
|
||||
Add(SeparatorItem(tr("Auto-crop")));
|
||||
AutoCropInterval = ConfigAutoCropInterval;
|
||||
Add(new cMenuEditIntItem(tr("autocrop interval (frames)"),
|
||||
&AutoCropInterval, 0, 200));
|
||||
AutoCropDelay = ConfigAutoCropDelay;
|
||||
Add(new cMenuEditIntItem(tr("autocrop delay (n * interval)"),
|
||||
&AutoCropDelay, 0, 200));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -478,6 +496,11 @@ void cMenuSetupSoft::Store(void)
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
||||
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
||||
|
||||
SetupStore("AutoCrop.Interval", ConfigAutoCropInterval = AutoCropInterval);
|
||||
SetupStore("AutoCrop.Delay", ConfigAutoCropDelay = AutoCropDelay);
|
||||
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -810,13 +833,22 @@ int cSoftHdDevice::PlayTsAudio(const uchar * data, int length)
|
||||
|
||||
#endif
|
||||
|
||||
uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int sizex,
|
||||
int sizey)
|
||||
/**
|
||||
** Grabs the currently visible screen image.
|
||||
**
|
||||
** @param size size of the returned data
|
||||
** @param jpeg flag true, create JPEG data
|
||||
** @param quality JPEG quality
|
||||
** @param width number of horizontal pixels in the frame
|
||||
** @param height number of vertical pixels in the frame
|
||||
*/
|
||||
uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int width,
|
||||
int height)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d, %d, %d, %dx%d\n", __FUNCTION__, size, jpeg,
|
||||
quality, sizex, sizey);
|
||||
quality, width, height);
|
||||
|
||||
return NULL;
|
||||
return::GrabImage(&size, jpeg, quality, width, height);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1001,11 +1033,15 @@ cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void)
|
||||
|
||||
/**
|
||||
** Parse setup parameters
|
||||
**
|
||||
** @param name paramter name (case sensetive)
|
||||
** @param value value as string
|
||||
**
|
||||
** @returns true if the parameter is supported.
|
||||
*/
|
||||
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
{
|
||||
int i;
|
||||
char buf[128];
|
||||
|
||||
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
||||
|
||||
@@ -1018,6 +1054,8 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
return true;
|
||||
}
|
||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling");
|
||||
if (!strcmp(name, buf)) {
|
||||
ConfigVideoScaling[i] = atoi(value);
|
||||
@@ -1050,6 +1088,7 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(name, "AudioDelay")) {
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
||||
return true;
|
||||
@@ -1059,6 +1098,17 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "AutoCrop.Interval")) {
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval =
|
||||
atoi(value), ConfigAutoCropDelay);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "AutoCrop.Delay")) {
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay =
|
||||
atoi(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
6
video.h
6
video.h
@@ -100,6 +100,9 @@ extern void VideoSetSharpen(int[]);
|
||||
/// Set audio delay.
|
||||
extern void VideoSetAudioDelay(int);
|
||||
|
||||
/// Set auto-crop parameters.
|
||||
extern void VideoSetAutoCrop(int, int);
|
||||
|
||||
/// Clear OSD.
|
||||
extern void VideoOsdClear(void);
|
||||
|
||||
@@ -111,6 +114,9 @@ extern void VideoGetOsdSize(int *, int *);
|
||||
|
||||
extern int64_t VideoGetClock(void); ///< Get video clock.
|
||||
|
||||
/// Grab screen.
|
||||
extern uint8_t *VideoGrab(int *, int *, int *);
|
||||
|
||||
extern void VideoOsdInit(void); ///< Setup osd.
|
||||
extern void VideoOsdExit(void); ///< Cleanup osd.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user