Skip to content

Commit

Permalink
[videoplayer/rbp] Add pi specific option to maintain vsync with pll a…
Browse files Browse the repository at this point in the history
…djustment

New A/V sync option in settings/video/playback to do "Adjust PLL".
This uses video clock (so perfect video syncing) but avoids having to resample
or drop/dupe audio packets which is normally required.
  • Loading branch information
popcornmix committed Apr 3, 2020
1 parent 9a5d864 commit 1be60ea
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 21 deletions.
32 changes: 32 additions & 0 deletions addons/resource.language.en_gb/resources/strings.po
Expand Up @@ -22013,3 +22013,35 @@ msgstr ""
msgctxt "#39118"
msgid "Share debug log"
msgstr ""

#. Description of setting "System -> Audio Ouput -> A/V sync method" with label #38200
#: system/settings/settings.xml
msgctxt "#38200"
msgid "PLL adjustment to maintain audio/video sync"
msgstr ""

#. Description of setting "Videos -> Playback -> A/V sync method" with label #38201
#: system/settings/settings.xml
msgctxt "#38201"
msgid "Allows sync adjustment without resampling. Lower the settings if you get audio/video dropouts."
msgstr ""

msgctxt "#38202"
msgid "Off"
msgstr ""

msgctxt "#38203"
msgid "Low"
msgstr ""

msgctxt "#38204"
msgid "Medium"
msgstr ""

msgctxt "#38205"
msgid "High"
msgstr ""

msgctxt "#38206"
msgid "Max"
msgstr ""
14 changes: 14 additions & 0 deletions system/settings/rbp.xml
Expand Up @@ -104,6 +104,20 @@
<setting id="audiooutput.audiodevice">
<default>PI:HDMI</default>
</setting>
<setting id="audiooutput.plladjust" type="integer" label="38200" help="38201">
<level>3</level>
<default>0</default>
<constraints>
<options>
<option label="38202">0</option> <!-- off -->
<option label="38203">1</option> <!-- low -->
<option label="38204">2</option> <!-- medium -->
<option label="38205">3</option> <!-- high -->
<option label="38206">4</option> <!-- max -->
</options>
</constraints>
<control type="spinner" format="string" />
</setting>
</group>
<group id="3">
<setting id="audiooutput.ac3transcode" help="37024">
Expand Down
25 changes: 17 additions & 8 deletions xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
Expand Up @@ -359,11 +359,12 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::APPFOCUSED, msg->data, sizeof(bool));
return;
case CActiveAEControlProtocol::STREAMRESAMPLEMODE:
MsgStreamParameter *par;
par = reinterpret_cast<MsgStreamParameter*>(msg->data);
MsgStreamResample *par;
par = reinterpret_cast<MsgStreamResample*>(msg->data);
if (par->stream)
{
par->stream->m_resampleMode = par->parameter.int_par;
par->stream->m_resampleMode = par->mode;
par->stream->m_pllAdjust = par->plladjust;
par->stream->m_resampleIntegral = 0.0;
}
return;
Expand Down Expand Up @@ -2514,7 +2515,14 @@ CSampleBuffer* CActiveAE::SyncStream(CActiveAEStream *stream)
{
if (stream->m_processingBuffers)
{
stream->m_processingBuffers->SetRR(stream->CalcResampleRatio(error), m_settings.atempoThreshold);
double pllAdjustRequest = 0.0, pllAdjustActual = 0.0, e = 0.0;
if (stream->m_pllAdjust > 0.0)
{
e = std::max(std::min(error / 50.0, 1.0), - 1.0);
pllAdjustRequest = 1.0 + e * stream->m_pllAdjust;
}
stream->m_processingBuffers->SetRR(stream->CalcResampleRatio(error), m_settings.atempoThreshold, pllAdjustRequest, stream->m_pllAdjust, pllAdjustActual);
CLog::Log(LOGDEBUG, "ActiveAE::%s pll:%.5f (act:%.5f lim:%.5f) rr:%.5f threshold:%.3f error:%.6f", __FUNCTION__, pllAdjustRequest, pllAdjustActual, stream->m_pllAdjust, stream->m_processingBuffers->GetRR(), m_settings.atempoThreshold, error );
}
}
else if (stream->m_processingBuffers)
Expand Down Expand Up @@ -3383,13 +3391,14 @@ void CActiveAE::SetStreamResampleRatio(CActiveAEStream *stream, double ratio)
&msg, sizeof(MsgStreamParameter));
}

void CActiveAE::SetStreamResampleMode(CActiveAEStream *stream, int mode)
void CActiveAE::SetStreamResampleMode(CActiveAEStream *stream, int mode, float plladjust)
{
MsgStreamParameter msg;
MsgStreamResample msg;
msg.stream = stream;
msg.parameter.int_par = mode;
msg.mode = mode;
msg.plladjust = plladjust;
m_controlPort.SendOutMessage(CActiveAEControlProtocol::STREAMRESAMPLEMODE,
&msg, sizeof(MsgStreamParameter));
&msg, sizeof(MsgStreamResample));
}

void CActiveAE::SetStreamFFmpegInfo(CActiveAEStream *stream, int profile, enum AVMatrixEncoding matrix_encoding, enum AVAudioServiceType audio_service_type)
Expand Down
9 changes: 8 additions & 1 deletion xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h
Expand Up @@ -171,6 +171,13 @@ struct MsgStreamFFmpegInfo
enum AVAudioServiceType audio_service_type;
};

struct MsgStreamResample
{
CActiveAEStream *stream;
int mode;
float plladjust;
};

class CEngineStats
{
public:
Expand Down Expand Up @@ -281,7 +288,7 @@ class CActiveAE : public IAE, public IDispResource, private CThread
void SetStreamReplaygain(CActiveAEStream *stream, float rgain);
void SetStreamVolume(CActiveAEStream *stream, float volume);
void SetStreamResampleRatio(CActiveAEStream *stream, double ratio);
void SetStreamResampleMode(CActiveAEStream *stream, int mode);
void SetStreamResampleMode(CActiveAEStream *stream, int mode, float plladjust);
void SetStreamFFmpegInfo(CActiveAEStream *stream, int profile, enum AVMatrixEncoding matrix_encoding, enum AVAudioServiceType audio_service_type);
void SetStreamFade(CActiveAEStream *stream, float from, float target, unsigned int millis);

Expand Down
24 changes: 20 additions & 4 deletions xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
Expand Up @@ -14,6 +14,10 @@
#include "threads/SingleLock.h"
#include "utils/log.h"

#if defined(TARGET_RASPBERRY_PI)
#include "platform/linux/RBP.h"
#endif

using namespace ActiveAE;

CActiveAEStream::CActiveAEStream(AEAudioFormat *format, unsigned int streamid, CActiveAE *ae)
Expand Down Expand Up @@ -52,6 +56,7 @@ CActiveAEStream::CActiveAEStream(AEAudioFormat *format, unsigned int streamid, C
m_lastPtsJump = 0;
m_errorInterval = 1000;
m_clockSpeed = 1.0;
m_pllAdjust = 0.0f;
}

CActiveAEStream::~CActiveAEStream()
Expand Down Expand Up @@ -520,11 +525,12 @@ void CActiveAEStream::SetResampleRatio(double ratio)
m_streamResampleRatio = ratio;
}

void CActiveAEStream::SetResampleMode(int mode)
void CActiveAEStream::SetResampleMode(int mode, float plladjust)
{
if (mode != m_streamResampleMode)
m_activeAE->SetStreamResampleMode(this, mode);
if (mode != m_streamResampleMode || plladjust != m_streamPllAdjust)
m_activeAE->SetStreamResampleMode(this, mode, plladjust);
m_streamResampleMode = mode;
m_streamPllAdjust = plladjust;
}

void CActiveAEStream::SetFFmpegInfo(int profile, enum AVMatrixEncoding matrix_encoding, enum AVAudioServiceType audio_service_type)
Expand Down Expand Up @@ -720,8 +726,18 @@ bool CActiveAEStreamBuffers::IsDrained()
return false;
}

void CActiveAEStreamBuffers::SetRR(double rr, double atempoThreshold)
void CActiveAEStreamBuffers::SetRR(double rr, double atempoThreshold, double pllAdjustRequest, double pllThreshold, double &pllAdjustActual)
{
#if defined(TARGET_RASPBERRY_PI)
if (pllAdjustRequest > 0.0f) // pll adjust
{
pllAdjustActual = g_RBP.AdjustHDMIClock(pllAdjustRequest);
rr = 1.0;
}
else
pllAdjustActual = g_RBP.AdjustHDMIClock(1.0);
#endif

if (fabs(rr - 1.0) < atempoThreshold)
{
m_resampleBuffers->SetRR(rr);
Expand Down
7 changes: 5 additions & 2 deletions xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h
Expand Up @@ -105,7 +105,8 @@ class CActiveAEStreamBuffers
void Flush();
void SetDrain(bool drain);
bool IsDrained();
void SetRR(double rr, double atempoThreshold);
void SetRR(double rr, double atempoThreshold, double pllAdjustRequest, double pllThreshold, double &pllAdjustActual);
void SetRR(double rr, double atempoThreshold) { double pllAdjustActual; SetRR(rr, atempoThreshold, 0.0, 0.0, pllAdjustActual); }
double GetRR();
void FillBuffer();
bool DoesNormalize();
Expand Down Expand Up @@ -176,7 +177,7 @@ class CActiveAEStream : public IAEStream

double GetResampleRatio() override;
void SetResampleRatio(double ratio) override;
void SetResampleMode(int mode) override;
void SetResampleMode(int mode, float plladjust) override;
void RegisterAudioCallback(IAudioCallback* pCallback) override;
void UnRegisterAudioCallback() override;
void FadeVolume(float from, float to, unsigned int time) override;
Expand All @@ -193,6 +194,7 @@ class CActiveAEStream : public IAEStream
float m_streamAmplify;
double m_streamResampleRatio;
int m_streamResampleMode;
float m_streamPllAdjust;
unsigned int m_streamSpace;
bool m_streamDraining;
bool m_streamDrained;
Expand Down Expand Up @@ -232,6 +234,7 @@ class CActiveAEStream : public IAEStream
int m_fadingTime;
int m_profile;
int m_resampleMode;
float m_pllAdjust;
double m_resampleIntegral;
double m_clockSpeed;
enum AVMatrixEncoding m_matrixEncoding;
Expand Down
10 changes: 9 additions & 1 deletion xbmc/cores/AudioEngine/Interfaces/AEStream.h
Expand Up @@ -31,6 +31,14 @@ class IAEClockCallback
class CAESyncInfo
{
public:
CAESyncInfo()
{
delay = 0.0;
error = 0.0;
rr = 1.0;
errortime = 0;
state = SYNC_OFF;
}
double delay;
double error;
double rr;
Expand Down Expand Up @@ -235,7 +243,7 @@ class IAEStream
/**
* Sets the resamplling on/ff
*/
virtual void SetResampleMode(int mode) = 0;
virtual void SetResampleMode(int mode, float plladjust) = 0;

/**
* Registers the audio callback to call with each block of data, this is used by Audio Visualizations
Expand Down
4 changes: 2 additions & 2 deletions xbmc/cores/VideoPlayer/AudioSinkAE.cpp
Expand Up @@ -311,12 +311,12 @@ double CAudioSinkAE::GetResampleRatio()
return m_resampleRatio;
}

void CAudioSinkAE::SetResampleMode(int mode)
void CAudioSinkAE::SetResampleMode(int mode, float plladjust)
{
CSingleLock lock (m_critSection);
if(m_pAudioStream)
{
m_pAudioStream->SetResampleMode(mode);
m_pAudioStream->SetResampleMode(mode, plladjust);
}
}

Expand Down
2 changes: 1 addition & 1 deletion xbmc/cores/VideoPlayer/AudioSinkAE.h
Expand Up @@ -51,7 +51,7 @@ class CAudioSinkAE : IAEClockCallback
*/
double GetResampleRatio();

void SetResampleMode(int mode);
void SetResampleMode(int mode, float plladjust);
void Flush();
void Drain();
void AbortAddPackets();
Expand Down
12 changes: 10 additions & 2 deletions xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
Expand Up @@ -83,6 +83,7 @@ bool CVideoPlayerAudio::OpenStream(CDVDStreamInfo hints)

CAEStreamInfo::DataType streamType =
m_audioSink.GetPassthroughStreamType(hints.codec, hints.samplerate, hints.profile);
allowpassthrough |= CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt("audiooutput.plladjust") > 0;
CDVDAudioCodec* codec = CDVDFactoryCodec::CreateAudioCodec(hints, m_processInfo,
allowpassthrough, m_processInfo.AllowDTSHDDecode(),
streamType);
Expand Down Expand Up @@ -205,8 +206,12 @@ void CVideoPlayerAudio::UpdatePlayerInfo()

//print the inverse of the resample ratio, since that makes more sense
//if the resample ratio is 0.5, then we're playing twice as fast
#ifdef TARGET_RASPBERRY_PI
s << ", rr:" << std::fixed << std::setprecision(5) << 1.0 / m_audioSink.GetResampleRatio() << ", pll:" << std::fixed << std::setprecision(5) << g_RBP.GetAdjustHDMIClock() << ", err:" << std::fixed << std::setprecision(1) << m_audioSink.GetSyncError() * 1e-3 << "ms";
#else
if (m_synctype == SYNC_RESAMPLE)
s << ", rr:" << std::fixed << std::setprecision(5) << 1.0 / m_audioSink.GetResampleRatio();
#endif

SInfo info;
info.info = s.str();
Expand Down Expand Up @@ -567,10 +572,12 @@ void CVideoPlayerAudio::SetSyncType(bool passthrough)
int synctype = (m_synctype >= 0 && m_synctype <= 1) ? m_synctype : 2;
CLog::Log(LOGDEBUG, "CVideoPlayerAudio:: synctype set to %i: %s", m_synctype, synctypes[synctype]);
m_prevsynctype = m_synctype;
const float plladjusts[] = { 0.0f, 0.00001f, 0.0001f, 0.001f, 0.01f };
float plladjust = plladjusts[CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt("audiooutput.plladjust")];
if (m_synctype == SYNC_RESAMPLE)
m_audioSink.SetResampleMode(1);
m_audioSink.SetResampleMode(1, plladjust);
else
m_audioSink.SetResampleMode(0);
m_audioSink.SetResampleMode(0, plladjust);
}
}

Expand Down Expand Up @@ -614,6 +621,7 @@ bool CVideoPlayerAudio::SwitchCodecIfNeeded()

CAEStreamInfo::DataType streamType = m_audioSink.GetPassthroughStreamType(
m_streaminfo.codec, m_streaminfo.samplerate, m_streaminfo.profile);
allowpassthrough |= CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt("audiooutput.plladjust") > 0;
CDVDAudioCodec *codec = CDVDFactoryCodec::CreateAudioCodec(m_streaminfo, m_processInfo,
allowpassthrough, m_processInfo.AllowDTSHDDecode(),
streamType);
Expand Down
21 changes: 21 additions & 0 deletions xbmc/platform/linux/RBP.cpp
Expand Up @@ -71,6 +71,8 @@ CRBP::CRBP()
m_DllBcmHost = new DllBcmHost();
m_OMX = new COMXCore();
m_display = DISPMANX_NO_HANDLE;
m_requested_pll_adjust = -1.0;
m_actual_pll_adjust = -1.0;
m_mb = mbox_open();
vcsm_init();
m_vsync_count = 0;
Expand Down Expand Up @@ -178,6 +180,8 @@ void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display)
assert(s == 0);
vc_dispmanx_display_close(m_display);
m_display = DISPMANX_NO_HANDLE;
m_requested_pll_adjust = -1.0;
m_actual_pll_adjust = -1.0;
}

void CRBP::GetDisplaySize(int &width, int &height)
Expand Down Expand Up @@ -501,3 +505,20 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi
}
return geo;
}

double CRBP::AdjustHDMIClock(double adjust)
{
char response[80];

if (adjust == m_requested_pll_adjust)
return m_actual_pll_adjust;

m_requested_pll_adjust = adjust;
vc_gencmd(response, sizeof response, "hdmi_adjust_clock %f", adjust);
char *p = strchr(response, '=');
if (p)
m_actual_pll_adjust = atof(p+1);
CLog::Log(LOGDEBUG, "CRBP::%s(%.5f) = %.5f", __func__, adjust, m_actual_pll_adjust);
return m_actual_pll_adjust;
}

5 changes: 5 additions & 0 deletions xbmc/platform/linux/RBP.h
Expand Up @@ -99,6 +99,8 @@ class CRBP
void VSyncCallback();
int GetMBox() { return m_mb; }
AVRpiZcFrameGeometry GetFrameGeometry(uint32_t encoding, unsigned short video_width, unsigned short video_height);
double AdjustHDMIClock(double adjust);
double GetAdjustHDMIClock() { return m_actual_pll_adjust; }

private:
DllBcmHost *m_DllBcmHost;
Expand All @@ -120,6 +122,9 @@ class CRBP
CCriticalSection m_critSection;

int m_mb;
double m_requested_pll_adjust;
double m_actual_pll_adjust;
public:
};

extern CRBP g_RBP;

0 comments on commit 1be60ea

Please sign in to comment.