mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 17:16:51 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cac1e5ce17 | ||
|
|
d6e2d04505 | ||
|
|
45a34a3381 | ||
|
|
92ffd978b0 | ||
|
|
878813f206 | ||
|
|
cb2314837c | ||
|
|
820c246148 | ||
|
|
8dda2a0b8a | ||
|
|
761c06eac1 | ||
|
|
0776bc5ee4 |
15
ChangeLog
15
ChangeLog
@@ -1,5 +1,18 @@
|
||||
User johns
|
||||
Date:
|
||||
Data: Sat Jan 7 13:20:07 CET 2012
|
||||
|
||||
Release Version 0.2.0
|
||||
Add support for ac3 audio pass through.
|
||||
Add workaround for alsa not playing hdmi sound.
|
||||
Fix bug: broken device plugin stop and exit.
|
||||
Show transparent cursor to hide cursor.
|
||||
VDPAU: Add color standard support.
|
||||
VDPAU: Add denoise and sharpness support.
|
||||
VDPAU: Add skip chroma deinterlace support.
|
||||
VDPAU: Show OSD only if something is to display, improves performance.
|
||||
VDPAU: Add deinterlace with only 4 surfaces.
|
||||
|
||||
Date: Thu Jan 4 17:00:00 CET 2012
|
||||
|
||||
Release Version 0.1.5
|
||||
Adds OSS mixer support.
|
||||
|
||||
18
README.txt
18
README.txt
@@ -92,12 +92,22 @@ Setup: /etc/vdr/setup.conf
|
||||
------
|
||||
Following is supported:
|
||||
|
||||
softhddevice.MakePrimary = 1
|
||||
0 = no change, 1 make softhddevice primary at start
|
||||
|
||||
softhddevice.Deinterlace = 0
|
||||
0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software
|
||||
(only 0, 1 supported with vaapi)
|
||||
|
||||
softhddevice.MakePrimary = 1
|
||||
0 = no change, 1 make softhddevice primary at start
|
||||
softhddevice.SkipChromaDeinterlace = 0
|
||||
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
||||
|
||||
softhddevice.Denoise = 0
|
||||
0 .. 1000 noise reduction level (0 off, 1000 max)
|
||||
|
||||
softhddevice.Sharpness = 0
|
||||
-1000 .. 1000 noise reduction level (0 off, -1000 max blur,
|
||||
1000 max sharp)
|
||||
|
||||
softhddevice.Scaling = 0
|
||||
0 = normal, 1 = fast, 2 = HQ, 3 = anamorphic
|
||||
@@ -105,6 +115,10 @@ Setup: /etc/vdr/setup.conf
|
||||
softhddevice.AudioDelay = 0
|
||||
+n or -n ms
|
||||
|
||||
softhddevice.AudioPassthrough = 0
|
||||
0 = none, 1 = AC-3
|
||||
|
||||
|
||||
Commandline:
|
||||
------------
|
||||
|
||||
|
||||
16
Todo
16
Todo
@@ -27,14 +27,20 @@ missing:
|
||||
atmolight
|
||||
zoom/fit-zoom 4:3
|
||||
multistream handling
|
||||
HDMI/SPDIF Passthrough
|
||||
disable screensaver
|
||||
disable window cursor
|
||||
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
||||
|
||||
vdpau:
|
||||
1080i with temporal spatial and level 1 scaling too slow with GT 520
|
||||
1080i with temporal spatial too slow with GT 520 on some channels
|
||||
1080i with temporal spatial and level 1 scaling too slow with my GT 520
|
||||
1080i with temporal spatial too slow with my GT 520 on some channels
|
||||
SkipChromaDeinterlace improves performance
|
||||
Improve OSD handling, show only what is used. Big OSD costs performance
|
||||
VdpPreemptionCallback handling
|
||||
hard channel switch
|
||||
|
||||
libva:
|
||||
hard channel switch
|
||||
|
||||
libva-intel-driver:
|
||||
intel still has hangups most with 1080i
|
||||
@@ -71,8 +77,12 @@ audio/oss:
|
||||
alsa oss emulation mixer "pcm" not working
|
||||
ring buffer overflow with alsa oss emulation
|
||||
|
||||
HDMI/SPDIF Passthrough:
|
||||
only AC-3 written
|
||||
|
||||
playback of recording
|
||||
play back is too fast
|
||||
pause is not reset, when replay exit
|
||||
|
||||
setup:
|
||||
Setup of decoder type.
|
||||
|
||||
282
audio.c
282
audio.c
@@ -43,6 +43,8 @@
|
||||
#endif
|
||||
//#define USE_ALSA ///< enable alsa support
|
||||
//#define USE_OSS ///< enable oss support
|
||||
#define noSEARCH_HDMI_BUG
|
||||
#define noSEARCH_HDMI_BUG2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -88,6 +90,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <alsa/iatomic.h> // portable atomic_t
|
||||
|
||||
#include "ringbuffer.h"
|
||||
#include "misc.h"
|
||||
#include "audio.h"
|
||||
@@ -110,6 +114,95 @@ static int64_t AudioPTS; ///< audio pts clock
|
||||
static pthread_cond_t AudioStartCond; ///< condition variable
|
||||
#endif
|
||||
|
||||
#ifdef SEARCH_HDMI_BUG2
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ring buffer
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// FIXME: use this code, to combine alsa&oss ring buffers
|
||||
|
||||
#define AUDIO_RING_MAX 8 ///< number of audio ring buffers
|
||||
|
||||
/**
|
||||
** Audio ring buffer.
|
||||
*/
|
||||
typedef struct _audio_ring_ring_
|
||||
{
|
||||
char FlushBuffers; ///< flag: flush buffers
|
||||
unsigned SampleRate; ///< sample rate in hz
|
||||
unsigned Channels; ///< number of channels
|
||||
} AudioRingRing;
|
||||
|
||||
/// ring of audio ring buffers
|
||||
static AudioRingRing AudioRing[AUDIO_RING_MAX];
|
||||
static int AudioRingWrite; ///< audio ring write pointer
|
||||
static int AudioRingRead; ///< audio ring read pointer
|
||||
static atomic_t AudioRingFilled; ///< how many of the ring is used
|
||||
|
||||
/**
|
||||
** Add sample rate, number of channel change to ring.
|
||||
**
|
||||
** @param freq sample frequency
|
||||
** @param channels number of channels
|
||||
*/
|
||||
static int AudioRingAdd(int freq, int channels)
|
||||
{
|
||||
int filled;
|
||||
|
||||
filled = atomic_read(&AudioRingFilled);
|
||||
if (filled == AUDIO_RING_MAX) { // no free slot
|
||||
// FIXME: can wait for ring buffer empty
|
||||
Error(_("audio: out of ring buffers\n"));
|
||||
return -1;
|
||||
}
|
||||
AudioRing[AudioRingWrite].FlushBuffers = 1;
|
||||
AudioRing[AudioRingWrite].SampleRate = freq;
|
||||
AudioRing[AudioRingWrite].Channels = channels;
|
||||
|
||||
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
|
||||
atomic_inc(&AudioRingFilled);
|
||||
|
||||
#ifdef USE_AUDIO_THREAD
|
||||
// tell thread, that something todo
|
||||
AudioRunning = 1;
|
||||
pthread_cond_signal(&AudioStartCond);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Setup audio ring.
|
||||
*/
|
||||
static void AudioRingInit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AUDIO_RING_MAX; ++i) {
|
||||
// FIXME:
|
||||
//AlsaRingBuffer = RingBufferNew(48000 * 8 * 2); // ~1s 8ch 16bit
|
||||
}
|
||||
// one slot always reservered
|
||||
AudioRingWrite = 1;
|
||||
atomic_set(&AudioRingFilled, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
** Cleanup audio ring.
|
||||
*/
|
||||
static void AudioRingExit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AUDIO_RING_MAX; ++i) {
|
||||
// FIXME:
|
||||
//RingBufferDel(AlsaRingBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_ALSA
|
||||
|
||||
//============================================================================
|
||||
@@ -152,6 +245,7 @@ static int AlsaAddToRingbuffer(const void *samples, int count)
|
||||
if (n != count) {
|
||||
Error(_("audio/alsa: can't place %d samples in ring buffer\n"), count);
|
||||
// too many bytes are lost
|
||||
// FIXME: should skip more, longer skip, but less often?
|
||||
}
|
||||
// Update audio clock
|
||||
AudioPTS +=
|
||||
@@ -207,7 +301,19 @@ static int AlsaPlayRingbuffer(void)
|
||||
snd_pcm_state_name(snd_pcm_state(AlsaPCMHandle)));
|
||||
break;
|
||||
}
|
||||
#ifdef SEARCH_HDMI_BUG
|
||||
{
|
||||
uint16_t buf[8192];
|
||||
unsigned u;
|
||||
|
||||
for (u = 0; u < sizeof(buf) / 2; u++) {
|
||||
buf[u] = random() & 0xffff;
|
||||
}
|
||||
|
||||
n = sizeof(buf);
|
||||
p = buf;
|
||||
}
|
||||
#else
|
||||
n = RingBufferGetReadPointer(AlsaRingBuffer, &p);
|
||||
if (!n) { // ring buffer empty
|
||||
if (first) { // only error on first loop
|
||||
@@ -215,6 +321,7 @@ static int AlsaPlayRingbuffer(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (n < avail) { // not enough bytes in ring buffer
|
||||
avail = n;
|
||||
}
|
||||
@@ -229,7 +336,7 @@ static int AlsaPlayRingbuffer(void)
|
||||
} else {
|
||||
err = snd_pcm_writei(AlsaPCMHandle, p, frames);
|
||||
}
|
||||
Debug(4, "audio/alsa: wrote %d/%d frames\n", err, frames);
|
||||
//Debug(3, "audio/alsa: wrote %d/%d frames\n", err, frames);
|
||||
if (err != frames) {
|
||||
if (err < 0) {
|
||||
if (err == -EAGAIN) {
|
||||
@@ -255,6 +362,19 @@ static int AlsaPlayRingbuffer(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Flush alsa buffers.
|
||||
*/
|
||||
static void AlsaFlushBuffers(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
RingBufferReadAdvance(AlsaRingBuffer, RingBufferUsedBytes(AlsaRingBuffer));
|
||||
if ((err = snd_pcm_drop(AlsaPCMHandle))) {
|
||||
Error(_("audio: snd_pcm_drop(): %s\n"), snd_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -462,16 +582,10 @@ static void AlsaThread(void)
|
||||
if (AlsaFlushBuffer) {
|
||||
// we can flush too many, but wo cares
|
||||
Debug(3, "audio/alsa: flushing buffers\n");
|
||||
RingBufferReadAdvance(AlsaRingBuffer,
|
||||
RingBufferUsedBytes(AlsaRingBuffer));
|
||||
#if 1
|
||||
if ((err = snd_pcm_drop(AlsaPCMHandle))) {
|
||||
Error(_("audio: snd_pcm_drop(): %s\n"), snd_strerror(err));
|
||||
}
|
||||
AlsaFlushBuffers();
|
||||
if ((err = snd_pcm_prepare(AlsaPCMHandle))) {
|
||||
Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err));
|
||||
}
|
||||
#endif
|
||||
AlsaFlushBuffer = 0;
|
||||
break;
|
||||
}
|
||||
@@ -499,8 +613,9 @@ static void AlsaThread(void)
|
||||
*/
|
||||
static void AlsaEnqueue(const void *samples, int count)
|
||||
{
|
||||
if (!AlsaRingBuffer || !AlsaPCMHandle) {
|
||||
Debug(3, "audio/alsa: not ready\n");
|
||||
if (!AlsaRingBuffer || !AlsaPCMHandle || !AudioSampleRate) {
|
||||
printf("%p %p %d\n", AlsaRingBuffer, AlsaPCMHandle, AudioSampleRate);
|
||||
Debug(3, "audio/alsa: enqueue not ready\n");
|
||||
return;
|
||||
}
|
||||
if (AlsaAddToRingbuffer(samples, count)) {
|
||||
@@ -518,35 +633,48 @@ static void AlsaEnqueue(const void *samples, int count)
|
||||
#endif
|
||||
|
||||
/**
|
||||
** Initialize alsa pcm device.
|
||||
**
|
||||
** @see AudioPCMDevice
|
||||
** Open alsa pcm device.
|
||||
*/
|
||||
static void AlsaInitPCM(void)
|
||||
static snd_pcm_t *AlsaOpenPCM(void)
|
||||
{
|
||||
const char *device;
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_hw_params_t *hw_params;
|
||||
int err;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
|
||||
if (!(device = AudioPCMDevice)) {
|
||||
if (!(device = getenv("ALSA_DEVICE"))) {
|
||||
device = "default";
|
||||
}
|
||||
}
|
||||
// FIXME: must set alsa error output to /dev/null
|
||||
if ((err =
|
||||
snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK,
|
||||
SND_PCM_NONBLOCK)) < 0) {
|
||||
Fatal(_("audio/alsa: playback open '%s' error: %s\n"), device,
|
||||
Error(_("audio/alsa: playback open '%s' error: %s\n"), device,
|
||||
snd_strerror(err));
|
||||
// FIXME: no fatal error for plugins!
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_nonblock(handle, 0)) < 0) {
|
||||
Error(_("audio/alsa: can't set block mode: %s\n"), snd_strerror(err));
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
** Initialize alsa pcm device.
|
||||
**
|
||||
** @see AudioPCMDevice
|
||||
*/
|
||||
static void AlsaInitPCM(void)
|
||||
{
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_hw_params_t *hw_params;
|
||||
int err;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
|
||||
if (!(handle = AlsaOpenPCM())) {
|
||||
return;
|
||||
}
|
||||
|
||||
snd_pcm_hw_params_alloca(&hw_params);
|
||||
// choose all parameters
|
||||
@@ -556,8 +684,7 @@ static void AlsaInitPCM(void)
|
||||
snd_strerror(err));
|
||||
}
|
||||
AlsaCanPause = snd_pcm_hw_params_can_pause(hw_params);
|
||||
Info(_("audio/alsa: hw '%s' supports pause: %s\n"), device,
|
||||
AlsaCanPause ? "yes" : "no");
|
||||
Info(_("audio/alsa: supports pause: %s\n"), AlsaCanPause ? "yes" : "no");
|
||||
snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
|
||||
Info(_("audio/alsa: max buffer size %lu\n"), buffer_size);
|
||||
|
||||
@@ -656,7 +783,7 @@ static uint64_t AlsaGetDelay(void)
|
||||
snd_pcm_sframes_t delay;
|
||||
uint64_t pts;
|
||||
|
||||
if (!AlsaPCMHandle) {
|
||||
if (!AlsaPCMHandle || !AudioSampleRate) {
|
||||
return 0UL;
|
||||
}
|
||||
// FIXME: thread safe? __assert_fail_base in snd_pcm_delay
|
||||
@@ -702,12 +829,14 @@ static int AlsaSetup(int *freq, int *channels)
|
||||
snd_pcm_uframes_t period_size;
|
||||
int err;
|
||||
int ret;
|
||||
snd_pcm_t *handle;
|
||||
|
||||
if (!AlsaPCMHandle) { // alsa not running yet
|
||||
return -1;
|
||||
}
|
||||
#if 1
|
||||
// flush any buffered data
|
||||
#ifndef SEARCH_HDMI_BUG2
|
||||
#ifdef USE_AUDIO_THREAD
|
||||
if (AudioRunning) {
|
||||
while (AudioRunning) {
|
||||
@@ -718,11 +847,21 @@ static int AlsaSetup(int *freq, int *channels)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
RingBufferReadAdvance(AlsaRingBuffer,
|
||||
RingBufferUsedBytes(AlsaRingBuffer));
|
||||
AlsaFlushBuffers();
|
||||
}
|
||||
#endif
|
||||
AudioPTS = INT64_C(0x8000000000000000);
|
||||
|
||||
if (1) { // close+open to fix hdmi no sound bugs
|
||||
handle = AlsaPCMHandle;
|
||||
AlsaPCMHandle = NULL;
|
||||
snd_pcm_close(handle);
|
||||
if (!(handle = AlsaOpenPCM())) {
|
||||
return -1;
|
||||
}
|
||||
AlsaPCMHandle = handle;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
try_again:
|
||||
AudioChannels = *channels;
|
||||
@@ -844,6 +983,41 @@ static int AlsaSetup(int *freq, int *channels)
|
||||
// FIXME: use hw_params for buffer_size period_size
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (0) { // no underruns allowed, play silence
|
||||
snd_pcm_sw_params_t *sw_params;
|
||||
snd_pcm_uframes_t boundary;
|
||||
|
||||
snd_pcm_sw_params_alloca(&sw_params);
|
||||
err = snd_pcm_sw_params_current(AlsaPCMHandle, sw_params);
|
||||
if (err < 0) {
|
||||
Error(_("audio: snd_pcm_sw_params_current failed: %s\n"),
|
||||
snd_strerror(err));
|
||||
}
|
||||
if ((err = snd_pcm_sw_params_get_boundary(sw_params, &boundary)) < 0) {
|
||||
Error(_("audio: snd_pcm_sw_params_get_boundary failed: %s\n"),
|
||||
snd_strerror(err));
|
||||
}
|
||||
Debug(4, "audio/alsa: boundary %lu frames\n", boundary);
|
||||
if ((err =
|
||||
snd_pcm_sw_params_set_stop_threshold(AlsaPCMHandle, sw_params,
|
||||
boundary)) < 0) {
|
||||
Error(_("audio: snd_pcm_sw_params_set_silence_size failed: %s\n"),
|
||||
snd_strerror(err));
|
||||
}
|
||||
if ((err =
|
||||
snd_pcm_sw_params_set_silence_size(AlsaPCMHandle, sw_params,
|
||||
boundary)) < 0) {
|
||||
Error(_("audio: snd_pcm_sw_params_set_silence_size failed: %s\n"),
|
||||
snd_strerror(err));
|
||||
}
|
||||
if ((err = snd_pcm_sw_params(AlsaPCMHandle, sw_params)) < 0) {
|
||||
Error(_("audio: snd_pcm_sw_params failed: %s\n"),
|
||||
snd_strerror(err));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// update buffer
|
||||
|
||||
snd_pcm_get_params(AlsaPCMHandle, &buffer_size, &period_size);
|
||||
@@ -954,6 +1128,7 @@ static int OssAddToRingbuffer(const void *samples, int count)
|
||||
if (n != count) {
|
||||
Error(_("audio/oss: can't place %d samples in ring buffer\n"), count);
|
||||
// too many bytes are lost
|
||||
// FIXME: should skip more, longer skip, but less often?
|
||||
}
|
||||
// Update audio clock
|
||||
AudioPTS +=
|
||||
@@ -1375,12 +1550,59 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
Debug(3, "audio: wait on start condition\n");
|
||||
pthread_mutex_lock(&AudioMutex);
|
||||
AudioRunning = 0;
|
||||
#ifndef SEARCH_HDMI_BUG
|
||||
do {
|
||||
pthread_cond_wait(&AudioStartCond, &AudioMutex);
|
||||
// cond_wait can return, without signal!
|
||||
} while (!AudioRunning);
|
||||
#else
|
||||
usleep(1 * 1000);
|
||||
AudioRunning = 1;
|
||||
#endif
|
||||
pthread_mutex_unlock(&AudioMutex);
|
||||
|
||||
#ifdef SEARCH_HDMI_BUG2
|
||||
if (atomic_read(&AudioRingFilled) > 1) {
|
||||
int sample_rate;
|
||||
int channels;
|
||||
|
||||
// skip all sample changes between
|
||||
while (atomic_read(&AudioRingFilled) > 1) {
|
||||
Debug(3, "audio: skip ring buffer\n");
|
||||
AudioRingRead = (AudioRingRead + 1) % AUDIO_RING_MAX;
|
||||
atomic_dec(&AudioRingFilled);
|
||||
}
|
||||
|
||||
#ifdef USE_ALSA
|
||||
// FIXME: flush only if there is something to flush
|
||||
AlsaFlushBuffers();
|
||||
|
||||
sample_rate = AudioRing[AudioRingRead].SampleRate;
|
||||
channels = AudioRing[AudioRingRead].Channels;
|
||||
Debug(3, "audio: thread channels %d sample-rate %d hz\n", channels,
|
||||
sample_rate);
|
||||
|
||||
if (AlsaSetup(&sample_rate, &channels)) {
|
||||
Error(_("audio: can't set channels %d sample-rate %d hz\n"),
|
||||
channels, sample_rate);
|
||||
}
|
||||
Debug(3, "audio: thread channels %d sample-rate %d hz\n",
|
||||
AudioChannels, AudioSampleRate);
|
||||
if (1) {
|
||||
int16_t buf[6144 / 2];
|
||||
|
||||
buf[0] = htole16(0xF872); // iec 61937 sync word
|
||||
buf[1] = htole16(0x4E1F);
|
||||
buf[2] = htole16((7 << 5) << 8 | 0x00);
|
||||
buf[3] = htole16(0x0000);
|
||||
memset(buf + 4, 0, 6144 - 8);
|
||||
|
||||
AlsaEnqueue(buf, 6144);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Debug(3, "audio: play start\n");
|
||||
#ifdef USE_ALSA
|
||||
AlsaThread();
|
||||
@@ -1406,6 +1628,8 @@ static void AudioInitThread(void)
|
||||
pthread_yield();
|
||||
} while (!AlsaPCMHandle);
|
||||
#endif
|
||||
pthread_yield();
|
||||
usleep(5 * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1550,6 +1774,10 @@ int AudioSetup(int *freq, int *channels)
|
||||
// FIXME: set flag invalid setup
|
||||
return -1;
|
||||
}
|
||||
#if defined(SEARCH_HDMI_BUG) || defined(SEARCH_HDMI_BUG2)
|
||||
// FIXME: need to store possible combination and report this
|
||||
return AudioRingAdd(*freq, *channels);
|
||||
#endif
|
||||
#ifdef USE_ALSA
|
||||
return AlsaSetup(freq, channels);
|
||||
#endif
|
||||
@@ -1577,6 +1805,9 @@ void AudioInit(void)
|
||||
int freq;
|
||||
int chan;
|
||||
|
||||
#ifdef SEARCH_HDMI_BUG2
|
||||
AudioRingInit();
|
||||
#endif
|
||||
#ifdef USE_ALSA
|
||||
AlsaInit();
|
||||
#endif
|
||||
@@ -1609,6 +1840,9 @@ void AudioExit(void)
|
||||
#ifdef USE_OSS
|
||||
OssExit();
|
||||
#endif
|
||||
#ifdef SEARCH_HDMI_BUG2
|
||||
AudioRingExit();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef AUDIO_TEST
|
||||
|
||||
196
codec.c
196
codec.c
@@ -35,8 +35,12 @@
|
||||
*/
|
||||
#define USE_AVPARSER
|
||||
|
||||
/// compile with passthrough support (experimental)
|
||||
#define USE_PASSTHROUGH
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -585,8 +589,17 @@ struct _audio_decoder_
|
||||
int HwChannels; ///< hw channels
|
||||
|
||||
ReSampleContext *ReSample; ///< audio resampling context
|
||||
|
||||
};
|
||||
|
||||
#ifdef USE_PASSTHROUGH
|
||||
//static char CodecPassthroughPCM; ///< pass pcm through (unsupported)
|
||||
static char CodecPassthroughAC3; ///< pass ac3 through
|
||||
|
||||
//static char CodecPassthroughDTS; ///< pass dts through (unsupported)
|
||||
//static char CodecPassthroughMPA; ///< pass mpa through (unsupported)
|
||||
#endif
|
||||
|
||||
/**
|
||||
** Allocate a new audio decoder context.
|
||||
**
|
||||
@@ -683,6 +696,18 @@ void CodecAudioClose(AudioDecoder * audio_decoder)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Set audio pass-through.
|
||||
*/
|
||||
void CodecSetAudioPassthrough(int mask)
|
||||
{
|
||||
#ifdef USE_PASSTHROUGH
|
||||
CodecPassthroughAC3 = mask & 1 ? 1 : 0;
|
||||
#endif
|
||||
// FIXME: must update audio decoder (nr. of channels wrong)
|
||||
(void)mask;
|
||||
}
|
||||
|
||||
#ifdef USE_AVPARSER
|
||||
|
||||
/**
|
||||
@@ -730,6 +755,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
!index ? (uint64_t) spkt->pts : AV_NOPTS_VALUE,
|
||||
!index ? (uint64_t) spkt->dts : AV_NOPTS_VALUE, -1);
|
||||
|
||||
// FIXME: make this a function for both #ifdef cases
|
||||
if (dpkt->size) {
|
||||
int buf_sz;
|
||||
|
||||
@@ -765,7 +791,15 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
||||
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
||||
audio_decoder->Channels = audio_ctx->channels;
|
||||
audio_decoder->HwChannels = audio_ctx->channels;
|
||||
#ifdef USE_PASSTHROUGH
|
||||
// SPDIF/HDMI passthrough
|
||||
if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
|
||||
audio_decoder->HwChannels = 2;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
audio_decoder->HwChannels = audio_ctx->channels;
|
||||
}
|
||||
|
||||
// channels not support?
|
||||
if ((err =
|
||||
@@ -826,6 +860,81 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
AudioEnqueue(outbuf, outlen);
|
||||
}
|
||||
} else {
|
||||
#ifdef USE_PASSTHROUGH
|
||||
// SPDIF/HDMI passthrough
|
||||
if (CodecPassthroughAC3
|
||||
&& audio_ctx->codec_id == CODEC_ID_AC3) {
|
||||
// build SPDIF header and append A52 audio to it
|
||||
// dpkt is the original data
|
||||
buf_sz = 6144;
|
||||
if (buf_sz < dpkt->size + 8) {
|
||||
Error(_
|
||||
("codec/audio: decoded data smaller than encoded\n"));
|
||||
break;
|
||||
}
|
||||
// copy original data for output
|
||||
// FIXME: not 100% sure, if endian is correct
|
||||
buf[0] = htole16(0xF872); // iec 61937 sync word
|
||||
buf[1] = htole16(0x4E1F);
|
||||
buf[2] = htole16(0x01 | (dpkt->data[5] & 0x07) << 8);
|
||||
buf[3] = htole16(dpkt->size * 8);
|
||||
swab(dpkt->data, buf + 4, dpkt->size);
|
||||
memset(buf + 4 + dpkt->size / 2, 0,
|
||||
buf_sz - 8 - dpkt->size);
|
||||
}
|
||||
#if 0
|
||||
//
|
||||
// old experimental code
|
||||
//
|
||||
if (1) {
|
||||
// FIXME: need to detect dts
|
||||
// copy original data for output
|
||||
// FIXME: buf is sint
|
||||
buf[0] = 0x72;
|
||||
buf[1] = 0xF8;
|
||||
buf[2] = 0x1F;
|
||||
buf[3] = 0x4E;
|
||||
buf[4] = 0x00;
|
||||
switch (dpkt->size) {
|
||||
case 512:
|
||||
buf[5] = 0x0B;
|
||||
break;
|
||||
case 1024:
|
||||
buf[5] = 0x0C;
|
||||
break;
|
||||
case 2048:
|
||||
buf[5] = 0x0D;
|
||||
break;
|
||||
default:
|
||||
Debug(3,
|
||||
"codec/audio: dts sample burst not supported\n");
|
||||
buf[5] = 0x00;
|
||||
break;
|
||||
}
|
||||
buf[6] = (dpkt->size * 8);
|
||||
buf[7] = (dpkt->size * 8) >> 8;
|
||||
//buf[8] = 0x0B;
|
||||
//buf[9] = 0x77;
|
||||
//printf("%x %x\n", dpkt->data[0],dpkt->data[1]);
|
||||
// swab?
|
||||
memcpy(buf + 8, dpkt->data, dpkt->size);
|
||||
memset(buf + 8 + dpkt->size, 0,
|
||||
buf_sz - 8 - dpkt->size);
|
||||
} else if (1) {
|
||||
// FIXME: need to detect mp2
|
||||
// FIXME: mp2 passthrough
|
||||
// see softhddev.c version/layer
|
||||
// 0x04 mpeg1 layer1
|
||||
// 0x05 mpeg1 layer23
|
||||
// 0x06 mpeg2 ext
|
||||
// 0x07 mpeg2.5 layer 1
|
||||
// 0x08 mpeg2.5 layer 2
|
||||
// 0x09 mpeg2.5 layer 3
|
||||
}
|
||||
// DTS HD?
|
||||
// True HD?
|
||||
#endif
|
||||
#endif
|
||||
AudioEnqueue(buf, buf_sz);
|
||||
}
|
||||
}
|
||||
@@ -904,90 +1013,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
avcodec_decode_audio4(audio_ctx, frame, &got_frame, dpkt);
|
||||
#else
|
||||
#endif
|
||||
if (buf_sz > 0) { // something decoded
|
||||
// Update audio clock
|
||||
if ((uint64_t) spkt->pts != AV_NOPTS_VALUE) {
|
||||
AudioSetClock(spkt->pts);
|
||||
spkt->pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
// FIXME: must first play remainings bytes, than change and play new.
|
||||
if (audio_decoder->SampleRate != audio_ctx->sample_rate
|
||||
|| audio_decoder->Channels != audio_ctx->channels) {
|
||||
int err;
|
||||
|
||||
if (audio_decoder->ReSample) {
|
||||
audio_resample_close(audio_decoder->ReSample);
|
||||
audio_decoder->ReSample = NULL;
|
||||
}
|
||||
|
||||
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
||||
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
||||
audio_decoder->Channels = audio_ctx->channels;
|
||||
audio_decoder->HwChannels = audio_ctx->channels;
|
||||
|
||||
// channels not support?
|
||||
if ((err =
|
||||
AudioSetup(&audio_decoder->HwSampleRate,
|
||||
&audio_decoder->HwChannels))) {
|
||||
Debug(3, "codec/audio: resample %dHz *%d -> %dHz *%d\n",
|
||||
audio_ctx->sample_rate, audio_ctx->channels,
|
||||
audio_decoder->HwSampleRate,
|
||||
audio_decoder->HwChannels);
|
||||
|
||||
if (err == 1) {
|
||||
audio_decoder->ReSample =
|
||||
av_audio_resample_init(audio_decoder->HwChannels,
|
||||
audio_ctx->channels, audio_decoder->HwSampleRate,
|
||||
audio_ctx->sample_rate, audio_ctx->sample_fmt,
|
||||
audio_ctx->sample_fmt, 16, 10, 0, 0.8);
|
||||
// libav-0.8_pre didn't support 6 -> 2 channels
|
||||
if (!audio_decoder->ReSample) {
|
||||
Error(_("codec/audio: resample setup error\n"));
|
||||
audio_decoder->HwChannels = 0;
|
||||
audio_decoder->HwSampleRate = 0;
|
||||
}
|
||||
} else {
|
||||
// FIXME: handle errors
|
||||
Debug(3, "codec/audio: audio setup error\n");
|
||||
audio_decoder->HwChannels = 0;
|
||||
audio_decoder->HwSampleRate = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_decoder->HwSampleRate && audio_decoder->HwChannels) {
|
||||
// need to resample audio
|
||||
if (audio_decoder->ReSample) {
|
||||
int16_t outbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
||||
FF_INPUT_BUFFER_PADDING_SIZE]
|
||||
__attribute__ ((aligned(16)));
|
||||
int outlen;
|
||||
|
||||
// FIXME: libav-0.7.2 crash here
|
||||
outlen =
|
||||
audio_resample(audio_decoder->ReSample, outbuf, buf,
|
||||
buf_sz);
|
||||
#ifdef DEBUG
|
||||
if (outlen != buf_sz) {
|
||||
Debug(3, "codec/audio: possible fixed ffmpeg\n");
|
||||
}
|
||||
#endif
|
||||
if (outlen) {
|
||||
// outlen seems to be wrong in ffmpeg-0.9
|
||||
outlen /= audio_ctx->channels *
|
||||
av_get_bytes_per_sample(audio_ctx->sample_fmt);
|
||||
outlen *=
|
||||
audio_decoder->HwChannels *
|
||||
av_get_bytes_per_sample(audio_ctx->sample_fmt);
|
||||
Debug(4, "codec/audio: %d -> %d\n", buf_sz, outlen);
|
||||
AudioEnqueue(outbuf, outlen);
|
||||
}
|
||||
} else {
|
||||
AudioEnqueue(buf, buf_sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME: see above, old code removed
|
||||
|
||||
index += n;
|
||||
}
|
||||
|
||||
94
softhddev.c
94
softhddev.c
@@ -42,7 +42,9 @@
|
||||
#include "video.h"
|
||||
#include "codec.h"
|
||||
|
||||
static char BrokenThreadsAndPlugins; ///< broken vdr threads and plugins
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef USE_VDPAU
|
||||
static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
|
||||
@@ -50,6 +52,8 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
|
||||
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
||||
#endif
|
||||
|
||||
static const char DeviceStopped = 1; ///< flag device stopped
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Audio
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -189,9 +193,6 @@ void PlayAudio(const uint8_t * data, int size,
|
||||
int n;
|
||||
AVPacket avpkt[1];
|
||||
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
|
||||
|
||||
if (NewAudioStream) {
|
||||
@@ -301,9 +302,6 @@ void PlayAudio(const uint8_t * data, int size,
|
||||
*/
|
||||
void Mute(void)
|
||||
{
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
AudioSetVolume(0);
|
||||
}
|
||||
|
||||
@@ -314,9 +312,6 @@ void Mute(void)
|
||||
*/
|
||||
void SetVolumeDevice(int volume)
|
||||
{
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
AudioSetVolume((volume * 100) / 255);
|
||||
}
|
||||
|
||||
@@ -439,6 +434,8 @@ static void VideoEnqueue(int64_t pts, const void *data, int size)
|
||||
|
||||
/**
|
||||
** Finish current packet advance to next.
|
||||
**
|
||||
** @param codec_id codec id of packet (MPEG/H264)
|
||||
*/
|
||||
static void VideoNextPacket(int codec_id)
|
||||
{
|
||||
@@ -637,9 +634,6 @@ int PlayVideo(const uint8_t * data, int size)
|
||||
int64_t pts;
|
||||
int n;
|
||||
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return size;
|
||||
}
|
||||
if (Usr1Signal) { // x11 server ready
|
||||
Usr1Signal = 0;
|
||||
StartVideo();
|
||||
@@ -760,9 +754,6 @@ int PlayVideo(const uint8_t * data, int size)
|
||||
*/
|
||||
void SetPlayMode(void)
|
||||
{
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
if (MyVideoDecoder) {
|
||||
if (VideoCodecID != CODEC_ID_NONE) {
|
||||
NewVideoStream = 1;
|
||||
@@ -850,9 +841,6 @@ void GetOsdSize(int *width, int *height, double *aspect)
|
||||
*/
|
||||
void OsdClose(void)
|
||||
{
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
VideoOsdClear();
|
||||
}
|
||||
|
||||
@@ -861,9 +849,6 @@ void OsdClose(void)
|
||||
*/
|
||||
void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb)
|
||||
{
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
VideoOsdDrawARGB(x, y, height, width, argb);
|
||||
}
|
||||
|
||||
@@ -1030,39 +1015,6 @@ static void StartXServer(void)
|
||||
*/
|
||||
void SoftHdDeviceExit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** Prepare plugin.
|
||||
*/
|
||||
void Start(void)
|
||||
{
|
||||
if (StartX11Server) {
|
||||
StartXServer();
|
||||
}
|
||||
CodecInit();
|
||||
// FIXME: AudioInit for HDMI after X11 startup
|
||||
AudioInit();
|
||||
if (!StartX11Server) {
|
||||
StartVideo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Stop plugin.
|
||||
*/
|
||||
void Stop(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debug(3, "video: max used PES packet size: %d\n", VideoMaxPacketSize);
|
||||
#endif
|
||||
|
||||
// FIXME:
|
||||
// don't let any thread enter our plugin, but can still crash, when
|
||||
// a thread has called any function, while Stop is called.
|
||||
BrokenThreadsAndPlugins = 1;
|
||||
usleep(2 * 1000);
|
||||
|
||||
// lets hope that vdr does a good thead cleanup
|
||||
// no it doesn't do a good thread cleanup
|
||||
if (MyVideoDecoder) {
|
||||
@@ -1091,10 +1043,40 @@ void Stop(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Prepare plugin.
|
||||
*/
|
||||
void Start(void)
|
||||
{
|
||||
if (StartX11Server) {
|
||||
StartXServer();
|
||||
}
|
||||
CodecInit();
|
||||
// FIXME: AudioInit for HDMI after X11 startup
|
||||
AudioInit();
|
||||
if (!StartX11Server) {
|
||||
StartVideo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Stop plugin.
|
||||
**
|
||||
** @note stop everything, but don't cleanup, module is still called.
|
||||
*/
|
||||
void Stop(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debug(3, "video: max used PES packet size: %d\n", VideoMaxPacketSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
** Main thread hook, periodic called from main thread.
|
||||
*/
|
||||
void MainThreadHook(void)
|
||||
{
|
||||
VideoDisplayHandler();
|
||||
if (!DeviceStopped) {
|
||||
VideoDisplayHandler();
|
||||
}
|
||||
}
|
||||
|
||||
150
softhddevice.cpp
150
softhddevice.cpp
@@ -33,14 +33,16 @@
|
||||
|
||||
#include "softhddev.h"
|
||||
#include "softhddevice.h"
|
||||
extern "C" {
|
||||
#include "video.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "video.h"
|
||||
extern void AudioPoller(void);
|
||||
extern void CodecSetAudioPassthrough(int);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char *const VERSION = "0.1.5";
|
||||
static const char *const VERSION = "0.2.0";
|
||||
static const char *const DESCRIPTION =
|
||||
trNOOP("A software and GPU emulated HD device");
|
||||
|
||||
@@ -49,11 +51,15 @@ static class cSoftHdDevice *MyDevice;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static char ConfigMakePrimary; ///< config primary wanted
|
||||
static char ConfigVideoDeinterlace; ///< config deinterlace
|
||||
static char ConfigVideoScaling; ///< config scaling
|
||||
static int ConfigVideoAudioDelay; ///< config audio delay
|
||||
static char DoMakePrimary; ///< flag switch primary
|
||||
static char ConfigMakePrimary; ///< config primary wanted
|
||||
static char ConfigVideoDeinterlace; ///< config deinterlace
|
||||
static char ConfigVideoSkipChromaDeinterlace; ///< config skip chroma
|
||||
static int ConfigVideoDenoise; ///< config denoise
|
||||
static int ConfigVideoSharpen; ///< config sharpen
|
||||
static char ConfigVideoScaling; ///< config scaling
|
||||
static int ConfigVideoAudioDelay; ///< config audio delay
|
||||
static int ConfigAudioPassthrough; ///< config audio pass-through
|
||||
static volatile char DoMakePrimary; ///< flag switch primary
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -126,7 +132,7 @@ cSoftOsd::cSoftOsd(int left, int top, uint level)
|
||||
|
||||
cSoftOsd::~cSoftOsd(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
SetActive(false);
|
||||
|
||||
OsdClose();
|
||||
@@ -203,8 +209,10 @@ void cSoftOsd::Flush(void)
|
||||
w = pm->ViewPort().Width();
|
||||
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());
|
||||
|
||||
@@ -226,14 +234,14 @@ class cSoftOsdProvider:public cOsdProvider
|
||||
cSoftOsdProvider(void);
|
||||
};
|
||||
|
||||
cOsd *cSoftOsdProvider::Osd; ///< single osd
|
||||
cOsd *cSoftOsdProvider::Osd; ///< single osd
|
||||
|
||||
/**
|
||||
** Create a new OSD.
|
||||
*/
|
||||
cOsd *cSoftOsdProvider::CreateOsd(int left, int top, uint level)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d, %d, %d\n", __FUNCTION__, left, top, level);
|
||||
//dsyslog("[softhddev]%s: %d, %d, %d\n", __FUNCTION__, left, top, level);
|
||||
|
||||
Osd = new cSoftOsd(left, top, level);
|
||||
return Osd;
|
||||
@@ -250,7 +258,7 @@ bool cSoftOsdProvider::ProvidesTrueColor(void)
|
||||
cSoftOsdProvider::cSoftOsdProvider(void)
|
||||
: cOsdProvider()
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -262,8 +270,12 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
protected:
|
||||
int MakePrimary;
|
||||
int Deinterlace;
|
||||
int SkipChromaDeinterlace;
|
||||
int Denoise;
|
||||
int Sharpen;
|
||||
int Scaling;
|
||||
int AudioDelay;
|
||||
int AudioPassthrough;
|
||||
protected:
|
||||
virtual void Store(void);
|
||||
public:
|
||||
@@ -275,10 +287,15 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
*/
|
||||
cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
{
|
||||
static const char * const deinterlace[] = {
|
||||
"Bob", "Weave", "Temporal", "TemporalSpatial", "Software" };
|
||||
static const char * const scaling[] = {
|
||||
"Normal", "Fast", "HQ", "Anamorphic" };
|
||||
static const char *const deinterlace[] = {
|
||||
"Bob", "Weave", "Temporal", "TemporalSpatial", "Software"
|
||||
};
|
||||
static const char *const scaling[] = {
|
||||
"Normal", "Fast", "HQ", "Anamorphic"
|
||||
};
|
||||
static const char *const passthrough[] = {
|
||||
"None", "AC-3"
|
||||
};
|
||||
|
||||
// cMenuEditBoolItem cMenuEditBitItem cMenuEditNumItem
|
||||
// cMenuEditStrItem cMenuEditStraItem cMenuEditIntItem
|
||||
@@ -286,11 +303,25 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
Add(new cMenuEditBoolItem(tr("Make primary device"), &MakePrimary,
|
||||
tr("no"), tr("yes")));
|
||||
Deinterlace = ConfigVideoDeinterlace;
|
||||
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace, 5, deinterlace));
|
||||
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace, 5,
|
||||
deinterlace));
|
||||
SkipChromaDeinterlace = ConfigVideoSkipChromaDeinterlace;
|
||||
Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"),
|
||||
&SkipChromaDeinterlace, tr("no"), tr("yes")));
|
||||
Denoise = ConfigVideoDenoise;
|
||||
Add(new cMenuEditIntItem(tr("Denoise (vdpau 0..1000)"), &Denoise, 0,
|
||||
1000));
|
||||
Sharpen = ConfigVideoSharpen;
|
||||
Add(new cMenuEditIntItem(tr("Sharpen (vdpau -1000..1000)"), &Sharpen,
|
||||
-1000, 1000));
|
||||
Scaling = ConfigVideoScaling;
|
||||
Add(new cMenuEditStraItem(tr("Scaling"), &Scaling, 4, scaling));
|
||||
AudioDelay = ConfigVideoAudioDelay;
|
||||
Add(new cMenuEditIntItem(tr("Audio delay (ms)"), &AudioDelay, -1000, 1000));
|
||||
Add(new cMenuEditIntItem(tr("Audio delay (ms)"), &AudioDelay, -1000,
|
||||
1000));
|
||||
AudioPassthrough = ConfigAudioPassthrough;
|
||||
Add(new cMenuEditStraItem(tr("Audio pass-through"), &AudioPassthrough, 2,
|
||||
passthrough));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,10 +332,19 @@ void cMenuSetupSoft::Store(void)
|
||||
SetupStore("MakePrimary", ConfigMakePrimary = MakePrimary);
|
||||
SetupStore("Deinterlace", ConfigVideoDeinterlace = Deinterlace);
|
||||
VideoSetDeinterlace(ConfigVideoDeinterlace);
|
||||
SetupStore("SkipChromaDeinterlace", ConfigVideoSkipChromaDeinterlace =
|
||||
SkipChromaDeinterlace);
|
||||
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
|
||||
SetupStore("Denoise", ConfigVideoDenoise = Denoise);
|
||||
VideoSetDenoise(ConfigVideoDenoise);
|
||||
SetupStore("Sharpen", ConfigVideoSharpen = Sharpen);
|
||||
VideoSetSharpen(ConfigVideoSharpen);
|
||||
SetupStore("Scaling", ConfigVideoScaling = Scaling);
|
||||
VideoSetScaling(ConfigVideoScaling);
|
||||
SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay);
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
||||
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -333,7 +373,7 @@ class cSoftHdDevice:public cDevice
|
||||
virtual void GetOsdSize(int &, int &, double &);
|
||||
virtual int PlayVideo(const uchar *, int);
|
||||
//virtual int PlayTsVideo(const uchar *, int);
|
||||
#ifdef USE_OSS // FIXME: testing only oss
|
||||
#ifdef USE_OSS // FIXME: testing only oss
|
||||
virtual int PlayTsAudio(const uchar *, int);
|
||||
#endif
|
||||
virtual void SetAudioChannelDevice(int);
|
||||
@@ -360,14 +400,14 @@ class cSoftHdDevice:public cDevice
|
||||
|
||||
cSoftHdDevice::cSoftHdDevice(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s\n", __FUNCTION__);
|
||||
|
||||
spuDecoder = NULL;
|
||||
}
|
||||
|
||||
cSoftHdDevice::~cSoftHdDevice(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void cSoftHdDevice::MakePrimaryDevice(bool on)
|
||||
@@ -383,7 +423,7 @@ void cSoftHdDevice::MakePrimaryDevice(bool on)
|
||||
int cSoftHdDevice::ProvidesCa(
|
||||
__attribute__ ((unused)) const cChannel * channel) const
|
||||
{
|
||||
dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
||||
//dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -436,7 +476,7 @@ int64_t cSoftHdDevice::GetSTC(void)
|
||||
{
|
||||
// dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
return ::VideoGetClock();
|
||||
return::VideoGetClock();
|
||||
}
|
||||
|
||||
void cSoftHdDevice::TrickSpeed(int Speed)
|
||||
@@ -479,7 +519,7 @@ void cSoftHdDevice::Mute(void)
|
||||
|
||||
void cSoftHdDevice::SetVolumeDevice(int volume)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume);
|
||||
//dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume);
|
||||
|
||||
::SetVolumeDevice(volume);
|
||||
}
|
||||
@@ -496,7 +536,7 @@ bool cSoftHdDevice::Poll(
|
||||
{
|
||||
// dsyslog("[softhddev]%s: %d\n", __FUNCTION__, timeout_ms);
|
||||
|
||||
return ::Poll(timeout_ms);
|
||||
return::Poll(timeout_ms);
|
||||
}
|
||||
|
||||
bool cSoftHdDevice::Flush(int timeout_ms)
|
||||
@@ -532,22 +572,23 @@ int cSoftHdDevice::PlayAudio(const uchar * data, int length, uchar id)
|
||||
void cSoftHdDevice::SetAudioTrackDevice(
|
||||
__attribute__ ((unused)) eTrackType type)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void cSoftHdDevice::SetDigitalAudioDevice(bool on)
|
||||
void cSoftHdDevice::SetDigitalAudioDevice( __attribute__ ((unused)) bool on)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %s\n", __FUNCTION__, on ? "true" : "false");
|
||||
//dsyslog("[softhddev]%s: %s\n", __FUNCTION__, on ? "true" : "false");
|
||||
}
|
||||
|
||||
void cSoftHdDevice::SetAudioChannelDevice(int audio_channel)
|
||||
void cSoftHdDevice::SetAudioChannelDevice( __attribute__ ((unused))
|
||||
int audio_channel)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, audio_channel);
|
||||
//dsyslog("[softhddev]%s: %d\n", __FUNCTION__, audio_channel);
|
||||
}
|
||||
|
||||
int cSoftHdDevice::GetAudioChannelDevice(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -560,7 +601,7 @@ int cSoftHdDevice::PlayVideo(const uchar * data, int length)
|
||||
{
|
||||
//dsyslog("[softhddev]%s: %p %d\n", __FUNCTION__, data, length);
|
||||
|
||||
return ::PlayVideo(data, length);
|
||||
return::PlayVideo(data, length);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -573,7 +614,7 @@ int cSoftHdDevice::PlayTsVideo(const uchar * Data, int Length)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OSS // FIXME: testing only oss
|
||||
#ifdef USE_OSS // FIXME: testing only oss
|
||||
///
|
||||
/// Play a TS audio packet.
|
||||
///
|
||||
@@ -583,7 +624,7 @@ int cSoftHdDevice::PlayTsAudio(const uchar * data, int length)
|
||||
{
|
||||
AudioPoller();
|
||||
|
||||
return cDevice::PlayTsAudio(data,length);
|
||||
return cDevice::PlayTsAudio(data, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -626,13 +667,13 @@ cPluginSoftHdDevice::cPluginSoftHdDevice(void)
|
||||
// Initialize any member variables here.
|
||||
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
|
||||
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
cPluginSoftHdDevice::~cPluginSoftHdDevice(void)
|
||||
{
|
||||
// Clean up after yourself!
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
::SoftHdDeviceExit();
|
||||
}
|
||||
@@ -660,7 +701,7 @@ const char *cPluginSoftHdDevice::CommandLineHelp(void)
|
||||
*/
|
||||
bool cPluginSoftHdDevice::ProcessArgs(int argc, char *argv[])
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
return::ProcessArgs(argc, argv);
|
||||
}
|
||||
@@ -668,7 +709,7 @@ bool cPluginSoftHdDevice::ProcessArgs(int argc, char *argv[])
|
||||
bool cPluginSoftHdDevice::Initialize(void)
|
||||
{
|
||||
// Start any background activities the plugin shall perform.
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
MyDevice = new cSoftHdDevice();
|
||||
|
||||
@@ -680,7 +721,7 @@ bool cPluginSoftHdDevice::Start(void)
|
||||
const cDevice *primary;
|
||||
|
||||
// Start any background activities the plugin shall perform.
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
primary = cDevice::PrimaryDevice();
|
||||
if (MyDevice != primary) {
|
||||
@@ -703,7 +744,7 @@ bool cPluginSoftHdDevice::Start(void)
|
||||
|
||||
void cPluginSoftHdDevice::Stop(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
::Stop();
|
||||
}
|
||||
@@ -717,7 +758,7 @@ void cPluginSoftHdDevice::Housekeeping(void)
|
||||
|
||||
const char *cPluginSoftHdDevice::MainMenuEntry(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
return tr(MAINMENUENTRY);
|
||||
return NULL;
|
||||
}
|
||||
@@ -730,7 +771,7 @@ const char *cPluginSoftHdDevice::MainMenuEntry(void)
|
||||
*/
|
||||
void cPluginSoftHdDevice::MainThreadHook(void)
|
||||
{
|
||||
// dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
if (DoMakePrimary && MyDevice) {
|
||||
dsyslog("[softhddev]%s: switching primary device\n", __FUNCTION__);
|
||||
@@ -765,7 +806,7 @@ cOsdObject *cPluginSoftHdDevice::MainMenuAction(void)
|
||||
*/
|
||||
cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
return new cMenuSetupSoft;
|
||||
}
|
||||
@@ -775,7 +816,7 @@ cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void)
|
||||
*/
|
||||
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
{
|
||||
dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
||||
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
||||
|
||||
// FIXME: handle the values
|
||||
if (!strcmp(name, "MakePrimary")) {
|
||||
@@ -786,6 +827,19 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
VideoSetDeinterlace(ConfigVideoDeinterlace = atoi(value));
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "SkipChromaDeinterlace")) {
|
||||
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace =
|
||||
atoi(value));
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "Denoise")) {
|
||||
VideoSetDenoise(ConfigVideoDenoise = atoi(value));
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "Sharpen")) {
|
||||
VideoSetSharpen(ConfigVideoSharpen = atoi(value));
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "Scaling")) {
|
||||
VideoSetScaling(ConfigVideoScaling = atoi(value));
|
||||
return true;
|
||||
@@ -794,6 +848,10 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "AudioPassthrough")) {
|
||||
CodecSetAudioPassthrough(ConfigAudioPassthrough = atoi(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
11
video.h
11
video.h
@@ -1,7 +1,7 @@
|
||||
///
|
||||
/// @file video.h @brief Video module header file
|
||||
///
|
||||
/// Copyright (c) 2009 - 2011 by Johns. All Rights Reserved.
|
||||
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
|
||||
///
|
||||
/// Contributor(s):
|
||||
///
|
||||
@@ -83,9 +83,18 @@ extern int VideoSetGeometry(const char *);
|
||||
/// set deinterlace
|
||||
extern void VideoSetDeinterlace(int);
|
||||
|
||||
/// set skip chroma deinterlace
|
||||
extern void VideoSetSkipChromaDeinterlace(int);
|
||||
|
||||
/// set scaling
|
||||
extern void VideoSetScaling(int);
|
||||
|
||||
/// set denoise
|
||||
extern void VideoSetDenoise(int);
|
||||
|
||||
/// set sharpen
|
||||
extern void VideoSetSharpen(int);
|
||||
|
||||
/// set audio delay
|
||||
extern void VideoSetAudioDelay(int);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user