kodi: add PR5682

Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
Stephan Raue 2014-11-09 22:56:12 +01:00
parent 1af41effbc
commit 93987c3c2e
3 changed files with 141 additions and 40 deletions

View File

@ -0,0 +1,141 @@
From 970ff0341f05a0adfe3ca79e5fba26a7070a12b7 Mon Sep 17 00:00:00 2001
From: fritsch <Peter.Fruehberger@gmail.com>
Date: Sun, 9 Nov 2014 17:46:10 +0100
Subject: [PATCH 2/2] AESinkALSA: Allow fragmentation, e.g. even multiply of
PeriodSize
---
xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 66 ++++++++++++++++++++++-------
xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 4 +-
2 files changed, 53 insertions(+), 17 deletions(-)
diff -Naur kodi-14-2d88a9a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp kodi-14-2d88a9a.patch/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp
--- kodi-14-2d88a9a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-11-09 22:28:18.035651639 +0100
+++ kodi-14-2d88a9a.patch/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2014-11-10 00:35:57.351393193 +0100
@@ -39,6 +39,8 @@
#include "utils/AMLUtils.h"
#endif
+
+#define AE_MIN_PERIODSIZE 256
#define ALSA_CHMAP_KERNEL_BLACKLIST
#define ALSA_OPTIONS (SND_PCM_NO_AUTO_FORMAT | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_RESAMPLE)
@@ -86,7 +88,9 @@
m_formatSampleRateMul(0.0),
m_passthrough(false),
m_pcm(NULL),
- m_timeout(0)
+ m_timeout(0),
+ m_fragmented(false),
+ m_originalPeriodSize(AE_MIN_PERIODSIZE)
{
/* ensure that ALSA has been initialized */
if (!snd_config)
@@ -479,7 +483,8 @@
params += ",AES1=0x82,AES2=0x00";
- if (format.m_sampleRate == 192000) params += ",AES3=0x0e";
+ if (m_passthrough && format.m_channelLayout.Count() == 8) params += ",AES3=0x09";
+ else if (format.m_sampleRate == 192000) params += ",AES3=0x0e";
else if (format.m_sampleRate == 176400) params += ",AES3=0x0c";
else if (format.m_sampleRate == 96000) params += ",AES3=0x0a";
else if (format.m_sampleRate == 88200) params += ",AES3=0x08";
@@ -806,7 +811,19 @@
/* set the format parameters */
outconfig.sampleRate = sampleRate;
- outconfig.periodSize = periodSize;
+
+ /* if periodSize is too small Audio Engine might starve */
+ m_fragmented = false;
+ unsigned int fragments = 1;
+ if (periodSize < AE_MIN_PERIODSIZE)
+ {
+ fragments = std::ceil((double) AE_MIN_PERIODSIZE / periodSize);
+ CLog::Log(LOGDEBUG, "Audio Driver reports too low periodSize %d - will use %d fragments", (int) periodSize, (int) fragments);
+ m_fragmented = true;
+ }
+
+ m_originalPeriodSize = periodSize;
+ outconfig.periodSize = fragments * periodSize;
outconfig.frameSize = snd_pcm_frames_to_bytes(m_pcm, 1);
m_bufferSize = (unsigned int)bufferSize;
@@ -893,27 +910,45 @@
}
void *buffer = data[0]+offset*m_format.m_frameSize;
- int ret = snd_pcm_writei(m_pcm, buffer, frames);
- if (ret < 0)
- {
- CLog::Log(LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret));
- ret = snd_pcm_recover(m_pcm, ret, 1);
- if(ret < 0)
- {
- HandleError("snd_pcm_writei(1)", ret);
- ret = snd_pcm_writei(m_pcm, buffer, frames);
- if (ret < 0)
+ unsigned int amount = 0;
+ int64_t data_left = (int64_t) frames;
+ int frames_written = 0;
+
+ while (data_left > 0)
+ {
+ if (m_fragmented)
+ amount = std::min((unsigned int) data_left, m_originalPeriodSize);
+ else // take care as we can come here a second time if the sink does not eat all data
+ amount = (unsigned int) data_left;
+
+ int ret = snd_pcm_writei(m_pcm, buffer, amount);
+ if (ret < 0)
+ {
+ CLog::Log(LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret));
+ ret = snd_pcm_recover(m_pcm, ret, 1);
+ if(ret < 0)
{
- HandleError("snd_pcm_writei(2)", ret);
- ret = 0;
+ HandleError("snd_pcm_writei(1)", ret);
+ ret = snd_pcm_writei(m_pcm, buffer, amount);
+ if (ret < 0)
+ {
+ HandleError("snd_pcm_writei(2)", ret);
+ ret = 0;
+ }
}
}
- }
- if ( ret > 0 && snd_pcm_state(m_pcm) == SND_PCM_STATE_PREPARED)
- snd_pcm_start(m_pcm);
+ if ( ret > 0 && snd_pcm_state(m_pcm) == SND_PCM_STATE_PREPARED)
+ snd_pcm_start(m_pcm);
- return ret;
+ if (ret <= 0)
+ break;
+
+ frames_written += ret;
+ data_left -= ret;
+ buffer = data[0]+offset*m_format.m_frameSize + frames_written*m_format.m_frameSize;
+ }
+ return frames_written;
}
void CAESinkALSA::HandleError(const char* name, int err)
diff -Naur kodi-14-2d88a9a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h kodi-14-2d88a9a.patch/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h
--- kodi-14-2d88a9a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h 2014-11-09 22:28:18.036651638 +0100
+++ kodi-14-2d88a9a.patch/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h 2014-11-10 00:36:24.936426057 +0100
@@ -90,6 +90,10 @@
#endif
static CALSAHControlMonitor m_controlMonitor;
+ // support fragmentation, e.g. looping in the sink to get a certain amount of data onto the device
+ bool m_fragmented;
+ unsigned int m_originalPeriodSize;
+
struct ALSAConfig
{
unsigned int sampleRate;

View File

@ -1,29 +0,0 @@
From 22477eaf1286dd28fb87552d35e9c8a5dbc09658 Mon Sep 17 00:00:00 2001
From: Rudi <r.ihle@s-t.de>
Date: Sat, 9 Aug 2014 18:09:03 +0200
Subject: [PATCH] AESinkALSA: Set correct value for AES3 when using HBR mode
According to the HDMI 1.4a document, the only acceptable value
for AES3 in HBR mode is 0x09, which corresponds to a frame rate
of 768000. Some sinks or drivers ignore this, but some do not.
---
xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp
index c608231..322b8de 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp
@@ -156,7 +156,8 @@ void CAESinkALSA::GetAESParams(AEAudioFormat format, std::string& params)
params += ",AES1=0x82,AES2=0x00";
- if (format.m_sampleRate == 192000) params += ",AES3=0x0e";
+ if (m_passthrough && format.m_channelLayout.Count() == 8) params += ",AES3=0x09";
+ else if (format.m_sampleRate == 192000) params += ",AES3=0x0e";
else if (format.m_sampleRate == 176400) params += ",AES3=0x0c";
else if (format.m_sampleRate == 96000) params += ",AES3=0x0a";
else if (format.m_sampleRate == 88200) params += ",AES3=0x08";
--
2.0.3

View File

@ -1,11 +0,0 @@
--- xbmc-master-14-dae6f76/./xbmc/cores/AudioEngine/AESinkFactory.cpp.orig 2014-07-07 18:30:37.000000000 +0200
+++ xbmc-master-14-dae6f76/./xbmc/cores/AudioEngine/AESinkFactory.cpp 2014-07-15 10:30:16.513471771 +0200
@@ -134,7 +134,7 @@
CLog::Log(LOGERROR, "Sink %s:%s returned invalid sample rate", driver.c_str(), device.c_str());
else if (format.m_channelLayout.Count() == 0)
CLog::Log(LOGERROR, "Sink %s:%s returned invalid channel layout", driver.c_str(), device.c_str());
- else if (format.m_frames < 256)
+ else if (format.m_frames < 96)
CLog::Log(LOGERROR, "Sink %s:%s returned invalid buffer size: %d", driver.c_str(), device.c_str(), format.m_frames);
else
return sink;