Skip to content

Commit

Permalink
Merge pull request xbmc#8139 from fritsch/pa-isengard
Browse files Browse the repository at this point in the history
  • Loading branch information
jenkins4kodi committed Sep 27, 2015
2 parents f9e9eb1 + 64c67f9 commit b9dd683
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
52 changes: 33 additions & 19 deletions xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "AESinkPULSE.h"
#include "utils/log.h"
#include "Util.h"
#include "utils/TimeUtils.h"
#include "guilib/LocalizeStrings.h"
#include "Application.h"

Expand Down Expand Up @@ -441,11 +442,14 @@ CAESinkPULSE::CAESinkPULSE()
m_MainLoop = NULL;
m_BytesPerSecond = 0;
m_BufferSize = 0;
m_filled_bytes = 0;
m_lastPackageStamp = 0;
m_Channels = 0;
m_Stream = NULL;
m_Context = NULL;
m_IsStreamPaused = false;
m_volume_needs_update = false;
m_periodSize = 0;
pa_cvolume_init(&m_Volume);
}

Expand All @@ -463,9 +467,12 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
m_passthrough = false;
m_BytesPerSecond = 0;
m_BufferSize = 0;
m_filled_bytes = 0;
m_lastPackageStamp = 0;
m_Channels = 0;
m_Stream = NULL;
m_Context = NULL;
m_periodSize = 0;

if (!SetupContext(NULL, &m_Context, &m_MainLoop))
{
Expand Down Expand Up @@ -641,6 +648,7 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
{
unsigned int packetSize = a->minreq;
m_BufferSize = a->tlength;
m_periodSize = a->minreq;

format.m_frames = packetSize / frameSize;
}
Expand Down Expand Up @@ -688,6 +696,9 @@ void CAESinkPULSE::Deinitialize()
CSingleLock lock(m_sec);
m_IsAllocated = false;
m_passthrough = false;
m_periodSize = 0;
m_filled_bytes = 0;
m_lastPackageStamp = 0;

if (m_Stream)
Drain();
Expand Down Expand Up @@ -724,25 +735,24 @@ void CAESinkPULSE::GetDelay(AEDelayStatus& status)
status.SetDelay(0);
return;
}
int error = 0;
pa_usec_t latency = (pa_usec_t) -1;

pa_threaded_mainloop_lock(m_MainLoop);
if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0)
{
if (error == -PA_ERR_NODATA)
{
WaitForOperation(pa_stream_update_timing_info(m_Stream, NULL,NULL), m_MainLoop, "Update Timing Information");
if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0)
{
CLog::Log(LOGDEBUG, "GetDelay - Failed to get Latency %d", error);
}
}
}
if (error < 0 )
latency = (pa_usec_t) 0;
const pa_timing_info* pti = pa_stream_get_timing_info(m_Stream);
// only incorporate local sink delay + internal PA transport delay
double sink_delay = (pti->configured_sink_usec / 1000000.0);
double transport_delay = pti->transport_usec / 1000000.0;

uint64_t diff = CurrentHostCounter() - m_lastPackageStamp;
unsigned int bytes_played = (unsigned int) ((double) diff * (double) m_BytesPerSecond / (double) CurrentHostFrequency() + 0.5);

int buffer_delay = m_filled_bytes - bytes_played;
if (buffer_delay < 0)
buffer_delay = 0;

pa_threaded_mainloop_unlock(m_MainLoop);
status.SetDelay(latency / 1000000.0);

double delay = buffer_delay / (double) m_BytesPerSecond + sink_delay + transport_delay;
status.SetDelay(delay);
}

double CAESinkPULSE::GetCacheTotal()
Expand All @@ -765,10 +775,11 @@ unsigned int CAESinkPULSE::AddPackets(uint8_t **data, unsigned int frames, unsig
unsigned int available = frames * m_format.m_frameSize;
unsigned int length = 0;
void *buffer = data[0]+offset*m_format.m_frameSize;
// revisit me after Gotham - should use a callback for the write function
while ((length = pa_stream_writable_size(m_Stream)) == 0)
// care a bit for fragmentation
while ((length = pa_stream_writable_size(m_Stream)) < m_periodSize)
pa_threaded_mainloop_wait(m_MainLoop);

unsigned int free = length;
length = std::min((unsigned int)length, available);

int error = pa_stream_write(m_Stream, buffer, length, NULL, 0, PA_SEEK_RELATIVE);
Expand All @@ -779,8 +790,11 @@ unsigned int CAESinkPULSE::AddPackets(uint8_t **data, unsigned int frames, unsig
CLog::Log(LOGERROR, "CPulseAudioDirectSound::AddPackets - pa_stream_write failed\n");
return 0;
}
m_lastPackageStamp = CurrentHostCounter();
m_filled_bytes = m_BufferSize - (free - length);
unsigned int res = (unsigned int)(length / m_format.m_frameSize);

return (unsigned int)(length / m_format.m_frameSize);
return res;
}

void CAESinkPULSE::Drain()
Expand Down
3 changes: 3 additions & 0 deletions xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class CAESinkPULSE : public IAESink
pa_stream *m_Stream;
pa_cvolume m_Volume;
bool m_volume_needs_update;
uint32_t m_periodSize;
uint64_t m_lastPackageStamp;
uint64_t m_filled_bytes;

pa_context *m_Context;
pa_threaded_mainloop *m_MainLoop;
Expand Down

0 comments on commit b9dd683

Please sign in to comment.