summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Reufer <thomas@reufer.ch>2016-04-20 12:11:35 +0200
committerThomas Reufer <thomas@reufer.ch>2016-04-20 12:13:35 +0200
commit2ae1d9d53be5cf781c449ee0f026c77b9215167d (patch)
tree582b66504f90337fffe22de50130d90ba686e1b2
parentf2e71c5214d6bd20c76b0f0114e269ed74777e61 (diff)
downloadvdr-plugin-rpihddevice-2ae1d9d53be5cf781c449ee0f026c77b9215167d.tar.gz
vdr-plugin-rpihddevice-2ae1d9d53be5cf781c449ee0f026c77b9215167d.tar.bz2
move all audio related OMX stuff to cRpiOmxAudioRender
-rw-r--r--audio.c451
-rw-r--r--audio.h21
-rw-r--r--omx.c374
-rw-r--r--omx.h35
-rw-r--r--omxdevice.c66
5 files changed, 462 insertions, 485 deletions
diff --git a/audio.c b/audio.c
index bffd73e..9e2aee0 100644
--- a/audio.c
+++ b/audio.c
@@ -888,13 +888,43 @@ const uint32_t cRpiAudioDecoder::cParser::DtsSampleRateTable[16] =
/* ------------------------------------------------------------------------- */
-class cRpiAudioRender
+// default: 16x 4096 bytes, now 128x 16k (2M)
+#define OMX_AUDIO_BUFFERS 128
+#define OMX_AUDIO_BUFFERSIZE KILOBYTE(16);
+
+#define OMX_AUDIO_CHANNEL_MAPPING(s, c) \
+switch (c) { \
+case 4: \
+ (s).eChannelMapping[0] = OMX_AUDIO_ChannelLF; \
+ (s).eChannelMapping[1] = OMX_AUDIO_ChannelRF; \
+ (s).eChannelMapping[2] = OMX_AUDIO_ChannelLR; \
+ (s).eChannelMapping[3] = OMX_AUDIO_ChannelRR; \
+ break; \
+case 1: \
+ (s).eChannelMapping[0] = OMX_AUDIO_ChannelCF; \
+ break; \
+case 8: \
+ (s).eChannelMapping[6] = OMX_AUDIO_ChannelLS; \
+ (s).eChannelMapping[7] = OMX_AUDIO_ChannelRS; \
+case 6: \
+ (s).eChannelMapping[2] = OMX_AUDIO_ChannelCF; \
+ (s).eChannelMapping[3] = OMX_AUDIO_ChannelLFE; \
+ (s).eChannelMapping[4] = OMX_AUDIO_ChannelLR; \
+ (s).eChannelMapping[5] = OMX_AUDIO_ChannelRR; \
+case 2: \
+default: \
+ (s).eChannelMapping[0] = OMX_AUDIO_ChannelLF; \
+ (s).eChannelMapping[1] = OMX_AUDIO_ChannelRF; \
+ break; }
+
+class cRpiOmxAudioRender : protected cOmxEventHandler
{
public:
- cRpiAudioRender(cOmx *omx) :
- m_mutex(new cMutex()),
+ cRpiOmxAudioRender(cOmx *omx) :
+ cOmxEventHandler(),
+ m_mutex(),
m_omx(omx),
m_port(cRpiAudioPort::eLocal),
m_codec(cAudioCodec::eInvalid),
@@ -909,17 +939,36 @@ public:
m_resamplerConfigured(false),
#endif
m_pcmSampleFormat(AV_SAMPLE_FMT_NONE),
- m_pts(0)
+ m_pts(0),
+ m_setStartTime(true),
+ m_spareBuffers(0)
{
+ // create audio_render
+ if (!m_omx->CreateComponent(cOmx::eAudioRender, true))
+ ELOG("failed creating audio render!");
+
+ m_omx->SetTunnel(cOmx::eClockToAudioRender,
+ cOmx::eClock, 81, cOmx::eAudioRender, 101);
+
+ if (!m_omx->SetupTunnel(cOmx::eClockToAudioRender))
+ ELOG("failed to setup up tunnel from clock to audio render!");
+
+ m_omx->ChangeComponentState(cOmx::eAudioRender, OMX_StateIdle);
+ m_omx->AddEventHandler(this);
}
- ~cRpiAudioRender()
+ ~cRpiOmxAudioRender()
{
Flush();
#ifdef DO_RESAMPLE
swr_free(&m_resample);
#endif
- delete m_mutex;
+
+ m_omx->DisableTunnel(cOmx::eClockToAudioRender);
+ m_omx->ChangeComponentState(cOmx::eAudioRender, OMX_StateIdle);
+ m_omx->CleanupComponent(cOmx::eAudioRender);
+
+ m_omx->RemoveEventHandler(this);
}
int WriteSamples(uint8_t** data, int samples, int64_t pts,
@@ -928,7 +977,7 @@ public:
if (!Ready())
return 0;
- m_mutex->Lock();
+ cMutexLock MutexLock(&m_mutex);
int copied = 0;
if (sampleFormat == AV_SAMPLE_FMT_NONE)
@@ -936,10 +985,19 @@ public:
// pass through
while (samples > copied)
{
- OMX_BUFFERHEADERTYPE *buf = m_omx->GetAudioBuffer(pts);
+ OMX_BUFFERHEADERTYPE *buf = GetBuffer();
if (!buf)
break;
+ if (pts == OMX_INVALID_PTS)
+ buf->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
+ else if (m_setStartTime)
+ {
+ buf->nFlags |= OMX_BUFFERFLAG_STARTTIME;
+ m_setStartTime = false;
+ }
+ cOmx::PtsToTicks(pts, buf->nTimeStamp);
+
unsigned int len = samples - copied;
if (len > buf->nAllocLen)
len = buf->nAllocLen;
@@ -947,16 +1005,17 @@ public:
memcpy(buf->pBuffer, *data + copied, len);
buf->nFilledLen = len;
- if (!m_omx->EmptyAudioBuffer(buf))
+ if (!EmptyBuffer(buf))
break;
copied += len;
- pts = 0;
+ pts = OMX_INVALID_PTS;
}
}
else
{
#ifdef DO_RESAMPLE
+
// local decode, do resampling
if (!m_resamplerConfigured || m_pcmSampleFormat != sampleFormat)
{
@@ -965,10 +1024,18 @@ public:
}
if (m_resample)
{
- m_pts = pts ? pts : m_pts;
- OMX_BUFFERHEADERTYPE *buf = m_omx->GetAudioBuffer(m_pts);
- if (buf)
+ m_pts = pts != OMX_INVALID_PTS ? pts : m_pts;
+ if (OMX_BUFFERHEADERTYPE *buf = GetBuffer())
{
+ if (m_pts == OMX_INVALID_PTS)
+ buf->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
+ else if (m_setStartTime)
+ {
+ buf->nFlags |= OMX_BUFFERFLAG_STARTTIME;
+ m_setStartTime = false;
+ }
+ cOmx::PtsToTicks(m_pts, buf->nTimeStamp);
+
if (buf->nAllocLen >= (samples * m_outChannels *
av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)))
{
@@ -981,15 +1048,23 @@ public:
m_pts += copiedSamples * 90000 / m_samplingRate;
}
- copied = m_omx->EmptyAudioBuffer(buf) ? samples : 0;
+ copied = EmptyBuffer(buf) ? samples : 0;
}
}
#else
// local decode, no resampling
- m_pts = pts ? pts : m_pts;
- OMX_BUFFERHEADERTYPE *buf = m_omx->GetAudioBuffer(m_pts);
- if (buf)
+ m_pts = pts != OMX_INVALID_PTS ? pts : m_pts;
+ if (OMX_BUFFERHEADERTYPE *buf = GetBuffer())
{
+ if (m_pts == OMX_INVALID_PTS)
+ buf->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
+ else if (m_setStartTime)
+ {
+ buf->nFlags |= OMX_BUFFERFLAG_STARTTIME;
+ m_setStartTime = false;
+ }
+ cOmx::PtsToTicks(m_pts, buf->nTimeStamp);
+
unsigned int size = samples * m_outChannels *
av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
if (buf->nAllocLen >= size)
@@ -998,29 +1073,28 @@ public:
buf->nFilledLen = size;
m_pts += samples * 90000 / m_samplingRate;
}
- copied = m_omx->EmptyAudioBuffer(buf) ? samples : 0;
+ copied = EmptyBuffer(buf) ? samples : 0;
}
#endif
}
- m_mutex->Unlock();
return copied;
}
void Flush(void)
{
- m_mutex->Lock();
+ cMutexLock MutexLock(&m_mutex);
if (m_running)
- m_omx->StopAudio();
+ Stop();
m_configured = false;
m_running = false;
m_pts = 0;
- m_mutex->Unlock();
+ m_setStartTime = true;
}
void SetCodec(cAudioCodec::eCodec codec, unsigned int channels,
unsigned int samplingRate, unsigned int frameSize)
{
- m_mutex->Lock();
+ cMutexLock MutexLock(&m_mutex);
if (codec != cAudioCodec::eInvalid && channels > 0)
{
m_inChannels = channels;
@@ -1063,7 +1137,6 @@ public:
m_resamplerConfigured = false;
#endif
}
- m_mutex->Unlock();
}
bool IsPassthrough(void)
@@ -1081,7 +1154,7 @@ public:
if (!m_configured)
{
// wait until render is ready before applying new settings
- if (m_running && m_omx->GetAudioLatency())
+ if (m_running && GetLatency())
return false;
ApplyRenderSettings();
@@ -1089,15 +1162,51 @@ public:
return true;
}
+ void SetVolume(int vol)
+ {
+ OMX_AUDIO_CONFIG_VOLUMETYPE volume;
+ OMX_INIT_STRUCT(volume);
+ volume.nPortIndex = 100;
+ volume.bLinear = OMX_TRUE;
+ volume.sVolume.nValue = vol * 100 / 255;
+
+ if (!m_omx->SetConfig(cOmx::eAudioRender,
+ OMX_IndexConfigAudioVolume, &volume))
+ ELOG("failed to set volume!");
+ }
+
+ void SetMute(bool mute)
+ {
+ OMX_AUDIO_CONFIG_MUTETYPE amute;
+ OMX_INIT_STRUCT(amute);
+ amute.nPortIndex = 100;
+ amute.bMute = mute ? OMX_TRUE : OMX_FALSE;
+
+ if (!m_omx->SetConfig(cOmx::eAudioRender,
+ OMX_IndexConfigAudioMute, &amute))
+ ELOG("failed to set mute state!");
+ }
+
+ int GetBufferUsage(void)
+ {
+ int usage = 0;
+ for (int i = 0; i < BUFFERSTAT_FILTER_SIZE; i++)
+ usage += m_usedBuffers[i];
+
+ return usage * 100 / BUFFERSTAT_FILTER_SIZE / OMX_AUDIO_BUFFERS;
+ }
+
private:
- cRpiAudioRender(const cRpiAudioRender&);
- cRpiAudioRender& operator= (const cRpiAudioRender&);
+ cRpiOmxAudioRender(const cRpiOmxAudioRender&);
+ cRpiOmxAudioRender& operator= (const cRpiOmxAudioRender&);
void ApplyRenderSettings(void)
{
+ cMutexLock MutexLock(&m_mutex);
+
if (m_running)
- m_omx->StopAudio();
+ Stop();
if (m_codec != cAudioCodec::eInvalid)
{
@@ -1105,8 +1214,7 @@ private:
cRpiSetup::SetHDMIChannelMapping(m_codec != cAudioCodec::ePCM,
m_outChannels);
- m_omx->SetupAudioRender(m_codec, m_outChannels, m_port,
- m_samplingRate, m_frameSize);
+ Setup(m_codec, m_outChannels, m_port, m_samplingRate, m_frameSize);
DLOG("set %s audio output format to %dch %s, %d.%dkHz%s",
cRpiAudioPort::Str(m_port), m_outChannels,
@@ -1118,6 +1226,176 @@ private:
m_configured = true;
}
+ void Setup(cAudioCodec::eCodec outputFormat, int channels,
+ cRpiAudioPort::ePort audioPort, int samplingRate, int frameSize)
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE format;
+ OMX_INIT_STRUCT(format);
+ format.nPortIndex = 100;
+ if (!m_omx->GetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioPortFormat, &format))
+ ELOG("failed to get audio port format parameters!");
+
+ format.eEncoding =
+ outputFormat == cAudioCodec::ePCM ? OMX_AUDIO_CodingPCM :
+ outputFormat == cAudioCodec::eMPG ? OMX_AUDIO_CodingMP3 :
+ outputFormat == cAudioCodec::eAC3 ? OMX_AUDIO_CodingDDP :
+ outputFormat == cAudioCodec::eEAC3 ? OMX_AUDIO_CodingDDP :
+ outputFormat == cAudioCodec::eAAC ? OMX_AUDIO_CodingAAC :
+ outputFormat == cAudioCodec::eDTS ? OMX_AUDIO_CodingDTS :
+ OMX_AUDIO_CodingAutoDetect;
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioPortFormat, &format))
+ ELOG("failed to set audio port format parameters!");
+
+ switch (outputFormat)
+ {
+ case cAudioCodec::eMPG:
+ OMX_AUDIO_PARAM_MP3TYPE mp3;
+ OMX_INIT_STRUCT(mp3);
+ mp3.nPortIndex = 100;
+ mp3.nChannels = channels;
+ mp3.nSampleRate = samplingRate;
+ mp3.eChannelMode = OMX_AUDIO_ChannelModeStereo; // ?
+ mp3.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3; // should be MPEG-1 layer 2
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioMp3, &mp3))
+ ELOG("failed to set audio render mp3 parameters!");
+ break;
+
+ case cAudioCodec::eAC3:
+ case cAudioCodec::eEAC3:
+ OMX_AUDIO_PARAM_DDPTYPE ddp;
+ OMX_INIT_STRUCT(ddp);
+ ddp.nPortIndex = 100;
+ ddp.nChannels = channels;
+ ddp.nSampleRate = samplingRate;
+ OMX_AUDIO_CHANNEL_MAPPING(ddp, channels);
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioDdp, &ddp))
+ ELOG("failed to set audio render ddp parameters!");
+ break;
+
+ case cAudioCodec::eAAC:
+ OMX_AUDIO_PARAM_AACPROFILETYPE aac;
+ OMX_INIT_STRUCT(aac);
+ aac.nPortIndex = 100;
+ aac.nChannels = channels;
+ aac.nSampleRate = samplingRate;
+ aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioAac, &aac))
+ ELOG("failed to set audio render aac parameters!");
+ break;
+
+ case cAudioCodec::eDTS:
+ OMX_AUDIO_PARAM_DTSTYPE dts;
+ OMX_INIT_STRUCT(dts);
+ dts.nPortIndex = 100;
+ dts.nChannels = channels;
+ dts.nSampleRate = samplingRate;
+ dts.nDtsType = 1;
+ dts.nFormat = 3; /* 16bit, LE */
+ dts.nDtsFrameSizeBytes = frameSize;
+ OMX_AUDIO_CHANNEL_MAPPING(dts, channels);
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioDts, &dts))
+ ELOG("failed to set audio render dts parameters!");
+ break;
+
+ case cAudioCodec::ePCM:
+ OMX_AUDIO_PARAM_PCMMODETYPE pcm;
+ OMX_INIT_STRUCT(pcm);
+ pcm.nPortIndex = 100;
+ pcm.nChannels = channels;
+ pcm.eNumData = OMX_NumericalDataSigned;
+ pcm.eEndian = OMX_EndianLittle;
+ pcm.bInterleaved = OMX_TRUE;
+ pcm.nBitPerSample = 16;
+ pcm.nSamplingRate = samplingRate;
+ pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ OMX_AUDIO_CHANNEL_MAPPING(pcm, channels);
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamAudioPcm, &pcm))
+ ELOG("failed to set audio render pcm parameters!");
+ break;
+
+ default:
+ ELOG("output codec not supported: %s!",
+ cAudioCodec::Str(outputFormat));
+ break;
+ }
+
+ OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest;
+ OMX_INIT_STRUCT(audioDest);
+ strcpy((char *)audioDest.sName,
+ audioPort == cRpiAudioPort::eLocal ? "local" : "hdmi");
+
+ if (!m_omx->SetConfig(cOmx::eAudioRender,
+ OMX_IndexConfigBrcmAudioDestination, &audioDest))
+ ELOG("failed to set audio destination!");
+
+ // set up the number and size of buffers for audio render
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ OMX_INIT_STRUCT(param);
+ param.nPortIndex = 100;
+ if (!m_omx->GetParameter(cOmx::eAudioRender,
+ OMX_IndexParamPortDefinition, &param))
+ ELOG("failed to get audio render port parameters!");
+
+ param.nBufferSize = OMX_AUDIO_BUFFERSIZE;
+ param.nBufferCountActual = OMX_AUDIO_BUFFERS;
+ for (int i = 0; i < BUFFERSTAT_FILTER_SIZE; i++)
+ m_usedBuffers[i] = 0;
+
+ if (!m_omx->SetParameter(cOmx::eAudioRender,
+ OMX_IndexParamPortDefinition, &param))
+ ELOG("failed to set audio render port parameters!");
+
+ if (!m_omx->EnablePortBuffers(cOmx::eAudioRender, 100))
+ ELOG("failed to enable port buffer on audio render!");
+
+ if (!m_omx->ChangeComponentState(cOmx::eAudioRender, OMX_StateExecuting))
+ ELOG("failed to set audio render to executing state!");
+
+ if (!m_omx->SetupTunnel(cOmx::eClockToAudioRender))
+ ELOG("failed to setup up tunnel from clock to audio render!");
+ }
+
+ void Stop(void)
+ {
+ // put audio render onto idle
+ m_omx->FlushTunnel(cOmx::eClockToAudioRender);
+ m_omx->DisableTunnel(cOmx::eClockToAudioRender);
+ m_omx->ChangeComponentState(cOmx::eAudioRender, OMX_StateIdle);
+
+ m_omx->DisablePortBuffers(cOmx::eAudioRender, 100, m_spareBuffers);
+ m_spareBuffers = 0;
+ }
+
+ unsigned int GetLatency(void)
+ {
+ unsigned int ret = 0;
+
+ OMX_PARAM_U32TYPE u32;
+ OMX_INIT_STRUCT(u32);
+ u32.nPortIndex = 100;
+
+ if (!m_omx->GetConfig(cOmx::eAudioRender,
+ OMX_IndexConfigAudioRenderingLatency, &u32))
+ ELOG("failed get audio render latency!");
+ else
+ ret = u32.nU32;
+
+ return ret;
+ }
+
#ifdef DO_RESAMPLE
void ApplyResamplerSettings(void)
{
@@ -1145,25 +1423,93 @@ private:
}
#endif
- cMutex *m_mutex;
- cOmx *m_omx;
+ OMX_BUFFERHEADERTYPE* GetBuffer(void)
+ {
+ OMX_BUFFERHEADERTYPE* buf = 0;
+ cMutexLock MutexLock(&m_mutex);
+
+ if (m_spareBuffers)
+ {
+ buf = m_spareBuffers;
+ m_spareBuffers =
+ static_cast <OMX_BUFFERHEADERTYPE*>(buf->pAppPrivate);
+ buf->pAppPrivate = 0;
+ }
+ else
+ {
+ buf = m_omx->GetBuffer(cOmx::eAudioRender, 100);
+ if (buf)
+ m_usedBuffers[0]++;
+ }
- cRpiAudioPort::ePort m_port;
- cAudioCodec::eCodec m_codec;
- unsigned int m_inChannels;
- unsigned int m_outChannels;
- unsigned int m_samplingRate;
- unsigned int m_frameSize;
- bool m_configured;
- bool m_running;
+ if (buf)
+ {
+ buf->nFilledLen = 0;
+ buf->nOffset = 0;
+ buf->nFlags = 0;
+ }
+ return buf;
+ }
+
+ bool EmptyBuffer(OMX_BUFFERHEADERTYPE *buf)
+ {
+ bool ret = true;
+
+ #ifdef DEBUG_BUFFERS
+ cOmx::DumpBuffer(buf, "A");
+ #endif
+
+ if (!m_omx->EmptyBuffer(cOmx::eAudioRender, buf))
+ {
+ ELOG("failed to empty OMX audio buffer");
+ cMutexLock MutexLock(&m_mutex);
+
+ buf->nFilledLen = 0;
+ buf->pAppPrivate = m_spareBuffers;
+ m_spareBuffers = buf;
+ ret = false;
+ }
+ return ret;
+ }
+
+ void BufferEmptied(cOmx::eOmxComponent comp)
+ {
+ if (comp == cOmx::eAudioRender)
+ {
+ cMutexLock MutexLock(&m_mutex);
+ m_usedBuffers[0]--;
+ }
+ }
+
+ void Tick(void)
+ {
+ for (int i = BUFFERSTAT_FILTER_SIZE - 1; i > 0; i--)
+ m_usedBuffers[i] = m_usedBuffers[i - 1];
+ }
+
+ cMutex m_mutex;
+ cOmx *m_omx;
+
+ cRpiAudioPort::ePort m_port;
+ cAudioCodec::eCodec m_codec;
+ unsigned int m_inChannels;
+ unsigned int m_outChannels;
+ unsigned int m_samplingRate;
+ unsigned int m_frameSize;
+ bool m_configured;
+ bool m_running;
#ifdef DO_RESAMPLE
- SwrContext *m_resample;
- bool m_resamplerConfigured;
+ SwrContext *m_resample;
+ bool m_resamplerConfigured;
#endif
- AVSampleFormat m_pcmSampleFormat;
- int64_t m_pts;
+ AVSampleFormat m_pcmSampleFormat;
+ int64_t m_pts;
+
+ int m_usedBuffers[BUFFERSTAT_FILTER_SIZE];
+ bool m_setStartTime;
+ OMX_BUFFERHEADERTYPE *m_spareBuffers;
};
/* ------------------------------------------------------------------------- */
@@ -1175,7 +1521,7 @@ cRpiAudioDecoder::cRpiAudioDecoder(cOmx *omx) :
m_setupChanged(true),
m_wait(new cCondWait()),
m_parser(new cParser()),
- m_render(new cRpiAudioRender(omx))
+ m_render(new cRpiOmxAudioRender(omx))
{
memset(m_codecs, 0, sizeof(m_codecs));
}
@@ -1445,3 +1791,18 @@ void cRpiAudioDecoder::Log(void* ptr, int level, const char* fmt, va_list vl)
else if (level <= AV_LOG_VERBOSE)
DLOG("[libav] %s", line);
}
+
+int cRpiAudioDecoder::GetBufferUsage(void)
+{
+ return m_render->GetBufferUsage();
+}
+
+void cRpiAudioDecoder::SetVolume(int vol)
+{
+ m_render->SetVolume(vol);
+}
+
+void cRpiAudioDecoder::SetMute(bool mute)
+{
+ m_render->SetMute(mute);
+}
diff --git a/audio.h b/audio.h
index 1092ebe..81499e6 100644
--- a/audio.h
+++ b/audio.h
@@ -25,7 +25,7 @@
#include "tools.h"
#include "omx.h"
-class cRpiAudioRender;
+class cRpiOmxAudioRender;
class cRpiAudioDecoder : public cThread
{
@@ -44,6 +44,11 @@ public:
virtual bool Poll(void);
virtual void Reset(void);
+ int GetBufferUsage(void);
+
+ void SetVolume(int vol);
+ void SetMute(bool mute);
+
protected:
virtual void Action(void);
@@ -65,14 +70,14 @@ private:
class cParser;
- Codec m_codecs[cAudioCodec::eNumCodecs];
- bool m_passthrough;
- bool m_reset;
- bool m_setupChanged;
+ Codec m_codecs[cAudioCodec::eNumCodecs];
+ bool m_passthrough;
+ bool m_reset;
+ bool m_setupChanged;
- cCondWait *m_wait;
- cParser *m_parser;
- cRpiAudioRender *m_render;
+ cCondWait *m_wait;
+ cParser *m_parser;
+ cRpiOmxAudioRender *m_render;
};
#endif
diff --git a/omx.c b/omx.c
index 3cf66bd..fe25971 100644
--- a/omx.c
+++ b/omx.c
@@ -33,35 +33,6 @@ extern "C" {
#define OMX_PRE_ROLL 0
-// default: 16x 4096 bytes, now 128x 16k (2M)
-#define OMX_AUDIO_BUFFERS 128
-#define OMX_AUDIO_BUFFERSIZE KILOBYTE(16);
-
-#define OMX_AUDIO_CHANNEL_MAPPING(s, c) \
-switch (c) { \
-case 4: \
- (s).eChannelMapping[0] = OMX_AUDIO_ChannelLF; \
- (s).eChannelMapping[1] = OMX_AUDIO_ChannelRF; \
- (s).eChannelMapping[2] = OMX_AUDIO_ChannelLR; \
- (s).eChannelMapping[3] = OMX_AUDIO_ChannelRR; \
- break; \
-case 1: \
- (s).eChannelMapping[0] = OMX_AUDIO_ChannelCF; \
- break; \
-case 8: \
- (s).eChannelMapping[6] = OMX_AUDIO_ChannelLS; \
- (s).eChannelMapping[7] = OMX_AUDIO_ChannelRS; \
-case 6: \
- (s).eChannelMapping[2] = OMX_AUDIO_ChannelCF; \
- (s).eChannelMapping[3] = OMX_AUDIO_ChannelLFE; \
- (s).eChannelMapping[4] = OMX_AUDIO_ChannelLR; \
- (s).eChannelMapping[5] = OMX_AUDIO_ChannelRR; \
-case 2: \
-default: \
- (s).eChannelMapping[0] = OMX_AUDIO_ChannelLF; \
- (s).eChannelMapping[1] = OMX_AUDIO_ChannelRF; \
- break; }
-
class cOmxEvents
{
@@ -212,8 +183,6 @@ void cOmx::Action(void)
break;
case cOmxEvents::eBufferEmptied:
- HandlePortBufferEmptied((eOmxComponent)event->data);
-
for (cOmxEventHandler *handler = m_eventHandlers->First();
handler; handler = m_eventHandlers->Next(handler))
handler->BufferEmptied((eOmxComponent)event->data);
@@ -230,52 +199,13 @@ void cOmx::Action(void)
if (timer.TimedOut())
{
timer.Set(100);
- Lock();
- for (int i = BUFFERSTAT_FILTER_SIZE - 1; i > 0; i--)
- {
- m_usedAudioBuffers[i] = m_usedAudioBuffers[i - 1];
- m_usedVideoBuffers[i] = m_usedVideoBuffers[i - 1];
- }
-
for (cOmxEventHandler *handler = m_eventHandlers->First(); handler;
handler = m_eventHandlers->Next(handler))
handler->Tick();
- Unlock();
}
}
}
-void cOmx::GetBufferUsage(int &audio, int &video)
-{
- audio = 0;
- for (int i = 0; i < BUFFERSTAT_FILTER_SIZE; i++)
- {
- audio += m_usedAudioBuffers[i];
- }
- audio = audio * 100 / BUFFERSTAT_FILTER_SIZE / OMX_AUDIO_BUFFERS;
-}
-
-void cOmx::HandlePortBufferEmptied(eOmxComponent component)
-{
- Lock();
-
- switch (component)
- {
- case eVideoDecoder:
- m_usedVideoBuffers[0]--;
- break;
-
- case eAudioRender:
- m_usedAudioBuffers[0]--;
- break;
-
- default:
- ELOG("HandlePortBufferEmptied: invalid component!");
- break;
- }
- Unlock();
-}
-
void cOmx::HandlePortSettingsChanged(unsigned int portId)
{
Lock();
@@ -341,8 +271,6 @@ void cOmx::OnError(void *instance, COMPONENT_T *comp, OMX_U32 data)
cOmx::cOmx() :
cThread(),
m_client(NULL),
- m_setAudioStartTime(false),
- m_spareAudioBuffers(0),
m_clockReference(eClockRefNone),
m_clockScale(0),
m_portEvents(new cOmxEvents()),
@@ -381,10 +309,6 @@ int cOmx::Init(int display, int layer)
if (!CreateComponent(eClock))
ELOG("failed creating clock!");
- // create audio_render
- if (!CreateComponent(eAudioRender, true))
- ELOG("failed creating audio render!");
-
//create video_scheduler
if (!CreateComponent(eVideoScheduler))
ELOG("failed creating video scheduler!");
@@ -392,26 +316,18 @@ int cOmx::Init(int display, int layer)
// set tunnels
SetTunnel(eVideoSchedulerToVideoRender, eVideoScheduler, 11, eVideoRender, 90);
SetTunnel(eClockToVideoScheduler, eClock, 80, eVideoScheduler, 12);
- SetTunnel(eClockToAudioRender, eClock, 81, eAudioRender, 101);
// setup clock tunnels first
if (!SetupTunnel(eClockToVideoScheduler))
ELOG("failed to setup up tunnel from clock to video scheduler!");
- if (!SetupTunnel(eClockToAudioRender))
- ELOG("failed to setup up tunnel from clock to audio render!");
-
ChangeComponentState(eClock, OMX_StateExecuting);
- ChangeComponentState(eAudioRender, OMX_StateIdle);
SetDisplay(display, layer);
SetClockLatencyTarget();
SetClockReference(cOmx::eClockRefVideo);
- FlushAudio();
-
Start();
-
return 0;
}
@@ -420,13 +336,9 @@ int cOmx::DeInit(void)
Cancel(-1);
m_portEvents->Add(0);
- DisableTunnel(eClockToAudioRender);
-
ChangeComponentState(eClock, OMX_StateIdle);
- ChangeComponentState(eAudioRender, OMX_StateIdle);
CleanupComponent(eClock);
- CleanupComponent(eAudioRender);
CleanupComponent(eVideoScheduler);
CleanupComponent(eVideoRender);
@@ -504,7 +416,7 @@ bool cOmx::EmptyBuffer(eOmxComponent comp, OMX_BUFFERHEADERTYPE *buf)
{
return buf && comp >= 0 && comp < eNumComponents &&
(OMX_EmptyThisBuffer(ILC_GET_HANDLE(m_comp[comp]), buf)
- == OMX_ErrorNone);
+ == OMX_ErrorNone);
}
bool cOmx::GetParameter(eOmxComponent comp, OMX_INDEXTYPE index, OMX_PTR param)
@@ -667,7 +579,6 @@ void cOmx::StartClock(bool waitForVideo, bool waitForAudio)
if (waitForAudio)
{
cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
- m_setAudioStartTime = true;
cstate.nWaitMask |= OMX_CLOCKPORT1;
}
@@ -729,23 +640,6 @@ void cOmx::ResetClock(void)
}
}
-unsigned int cOmx::GetAudioLatency(void)
-{
- unsigned int ret = 0;
-
- OMX_PARAM_U32TYPE u32;
- OMX_INIT_STRUCT(u32);
- u32.nPortIndex = 100;
-
- if (OMX_GetConfig(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexConfigAudioRenderingLatency, &u32) != OMX_ErrorNone)
- ELOG("failed get audio render latency!");
- else
- ret = u32.nU32;
-
- return ret;
-}
-
void cOmx::SetClockReference(eClockReference clockReference)
{
if (m_clockReference != clockReference)
@@ -817,207 +711,6 @@ bool cOmx::IsBufferStall(void)
return stallConf.bStalled == OMX_TRUE;
}
-void cOmx::SetVolume(int vol)
-{
- OMX_AUDIO_CONFIG_VOLUMETYPE volume;
- OMX_INIT_STRUCT(volume);
- volume.nPortIndex = 100;
- volume.bLinear = OMX_TRUE;
- volume.sVolume.nValue = vol * 100 / 255;
-
- if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexConfigAudioVolume, &volume) != OMX_ErrorNone)
- ELOG("failed to set volume!");
-}
-
-void cOmx::SetMute(bool mute)
-{
- OMX_AUDIO_CONFIG_MUTETYPE amute;
- OMX_INIT_STRUCT(amute);
- amute.nPortIndex = 100;
- amute.bMute = mute ? OMX_TRUE : OMX_FALSE;
-
- if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexConfigAudioMute, &amute) != OMX_ErrorNone)
- ELOG("failed to set mute state!");
-}
-
-void cOmx::StopAudio(void)
-{
- Lock();
-
- // put audio render onto idle
- ilclient_flush_tunnels(&m_tun[eClockToAudioRender], 1);
- ilclient_disable_tunnel(&m_tun[eClockToAudioRender]);
- ilclient_change_component_state(m_comp[eAudioRender], OMX_StateIdle);
- ilclient_disable_port_buffers(m_comp[eAudioRender], 100,
- m_spareAudioBuffers, NULL, NULL);
-
- m_spareAudioBuffers = 0;
- Unlock();
-}
-
-void cOmx::FlushAudio(void)
-{
- Lock();
-
- if (OMX_SendCommand(ILC_GET_HANDLE(m_comp[eAudioRender]), OMX_CommandFlush, 100, NULL) != OMX_ErrorNone)
- ELOG("failed to flush audio render!");
-
- ilclient_wait_for_event(m_comp[eAudioRender], OMX_EventCmdComplete,
- OMX_CommandFlush, 0, 100, 0, ILCLIENT_PORT_FLUSH,
- VCOS_EVENT_FLAGS_SUSPEND);
-
- ilclient_flush_tunnels(&m_tun[eClockToAudioRender], 1);
- Unlock();
-}
-
-int cOmx::SetupAudioRender(cAudioCodec::eCodec outputFormat, int channels,
- cRpiAudioPort::ePort audioPort, int samplingRate, int frameSize)
-{
- Lock();
-
- OMX_AUDIO_PARAM_PORTFORMATTYPE format;
- OMX_INIT_STRUCT(format);
- format.nPortIndex = 100;
- if (OMX_GetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioPortFormat, &format) != OMX_ErrorNone)
- ELOG("failed to get audio port format parameters!");
-
- format.eEncoding =
- outputFormat == cAudioCodec::ePCM ? OMX_AUDIO_CodingPCM :
- outputFormat == cAudioCodec::eMPG ? OMX_AUDIO_CodingMP3 :
- outputFormat == cAudioCodec::eAC3 ? OMX_AUDIO_CodingDDP :
- outputFormat == cAudioCodec::eEAC3 ? OMX_AUDIO_CodingDDP :
- outputFormat == cAudioCodec::eAAC ? OMX_AUDIO_CodingAAC :
- outputFormat == cAudioCodec::eDTS ? OMX_AUDIO_CodingDTS :
- OMX_AUDIO_CodingAutoDetect;
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioPortFormat, &format) != OMX_ErrorNone)
- ELOG("failed to set audio port format parameters!");
-
- switch (outputFormat)
- {
- case cAudioCodec::eMPG:
- OMX_AUDIO_PARAM_MP3TYPE mp3;
- OMX_INIT_STRUCT(mp3);
- mp3.nPortIndex = 100;
- mp3.nChannels = channels;
- mp3.nSampleRate = samplingRate;
- mp3.eChannelMode = OMX_AUDIO_ChannelModeStereo; // ?
- mp3.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3; // should be MPEG-1 layer 2
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioMp3, &mp3) != OMX_ErrorNone)
- ELOG("failed to set audio render mp3 parameters!");
- break;
-
- case cAudioCodec::eAC3:
- case cAudioCodec::eEAC3:
- OMX_AUDIO_PARAM_DDPTYPE ddp;
- OMX_INIT_STRUCT(ddp);
- ddp.nPortIndex = 100;
- ddp.nChannels = channels;
- ddp.nSampleRate = samplingRate;
- OMX_AUDIO_CHANNEL_MAPPING(ddp, channels);
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioDdp, &ddp) != OMX_ErrorNone)
- ELOG("failed to set audio render ddp parameters!");
- break;
-
- case cAudioCodec::eAAC:
- OMX_AUDIO_PARAM_AACPROFILETYPE aac;
- OMX_INIT_STRUCT(aac);
- aac.nPortIndex = 100;
- aac.nChannels = channels;
- aac.nSampleRate = samplingRate;
- aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioAac, &aac) != OMX_ErrorNone)
- ELOG("failed to set audio render aac parameters!");
- break;
-
- case cAudioCodec::eDTS:
- OMX_AUDIO_PARAM_DTSTYPE dts;
- OMX_INIT_STRUCT(dts);
- dts.nPortIndex = 100;
- dts.nChannels = channels;
- dts.nSampleRate = samplingRate;
- dts.nDtsType = 1;
- dts.nFormat = 3; /* 16bit, LE */
- dts.nDtsFrameSizeBytes = frameSize;
- OMX_AUDIO_CHANNEL_MAPPING(dts, channels);
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioDts, &dts) != OMX_ErrorNone)
- ELOG("failed to set audio render dts parameters!");
- break;
-
- case cAudioCodec::ePCM:
- OMX_AUDIO_PARAM_PCMMODETYPE pcm;
- OMX_INIT_STRUCT(pcm);
- pcm.nPortIndex = 100;
- pcm.nChannels = channels;
- pcm.eNumData = OMX_NumericalDataSigned;
- pcm.eEndian = OMX_EndianLittle;
- pcm.bInterleaved = OMX_TRUE;
- pcm.nBitPerSample = 16;
- pcm.nSamplingRate = samplingRate;
- pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
- OMX_AUDIO_CHANNEL_MAPPING(pcm, channels);
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamAudioPcm, &pcm) != OMX_ErrorNone)
- ELOG("failed to set audio render pcm parameters!");
- break;
-
- default:
- ELOG("output codec not supported: %s!",
- cAudioCodec::Str(outputFormat));
- break;
- }
-
- OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest;
- OMX_INIT_STRUCT(audioDest);
- strcpy((char *)audioDest.sName,
- audioPort == cRpiAudioPort::eLocal ? "local" : "hdmi");
-
- if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexConfigBrcmAudioDestination, &audioDest) != OMX_ErrorNone)
- ELOG("failed to set audio destination!");
-
- // set up the number and size of buffers for audio render
- OMX_PARAM_PORTDEFINITIONTYPE param;
- OMX_INIT_STRUCT(param);
- param.nPortIndex = 100;
- if (OMX_GetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamPortDefinition, &param) != OMX_ErrorNone)
- ELOG("failed to get audio render port parameters!");
-
- param.nBufferSize = OMX_AUDIO_BUFFERSIZE;
- param.nBufferCountActual = OMX_AUDIO_BUFFERS;
- for (int i = 0; i < BUFFERSTAT_FILTER_SIZE; i++)
- m_usedAudioBuffers[i] = 0;
-
- if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]),
- OMX_IndexParamPortDefinition, &param) != OMX_ErrorNone)
- ELOG("failed to set audio render port parameters!");
-
- if (ilclient_enable_port_buffers(m_comp[eAudioRender], 100, NULL, NULL, NULL) != 0)
- ELOG("failed to enable port buffer on audio render!");
-
- ilclient_change_component_state(m_comp[eAudioRender], OMX_StateExecuting);
-
- if (ilclient_setup_tunnel(&m_tun[eClockToAudioRender], 0, 0) != 0)
- ELOG("failed to setup up tunnel from clock to audio render!");
-
- Unlock();
- return 0;
-}
-
void cOmx::SetDisplayMode(bool fill, bool noaspect)
{
OMX_CONFIG_DISPLAYREGIONTYPE region;
@@ -1083,43 +776,6 @@ void cOmx::SetDisplay(int display, int layer)
ELOG("failed to set display number and layer!");
}
-OMX_BUFFERHEADERTYPE* cOmx::GetAudioBuffer(int64_t pts)
-{
- Lock();
- OMX_BUFFERHEADERTYPE* buf = 0;
- if (m_spareAudioBuffers)
- {
- buf = m_spareAudioBuffers;
- m_spareAudioBuffers =
- static_cast <OMX_BUFFERHEADERTYPE*>(buf->pAppPrivate);
- buf->pAppPrivate = 0;
- }
- else
- {
- buf = ilclient_get_input_buffer(m_comp[eAudioRender], 100, 0);
- if (buf)
- m_usedAudioBuffers[0]++;
- }
-
- if (buf)
- {
- buf->nFilledLen = 0;
- buf->nOffset = 0;
- buf->nFlags = 0;
-
- if (pts == OMX_INVALID_PTS)
- buf->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
- else if (m_setAudioStartTime)
- {
- buf->nFlags |= OMX_BUFFERFLAG_STARTTIME;
- m_setAudioStartTime = false;
- }
- cOmx::PtsToTicks(pts, buf->nTimeStamp);
- }
- Unlock();
- return buf;
-}
-
#ifdef DEBUG_BUFFERS
void cOmx::DumpBuffer(OMX_BUFFERHEADERTYPE *buf, const char *prefix)
{
@@ -1146,31 +802,3 @@ void cOmx::DumpBuffer(OMX_BUFFERHEADERTYPE *buf, const char *prefix)
);
}
#endif
-
-bool cOmx::EmptyAudioBuffer(OMX_BUFFERHEADERTYPE *buf)
-{
- if (!buf)
- return false;
-
- Lock();
- bool ret = true;
-#ifdef DEBUG_BUFFERS
- DumpBuffer(buf, "A");
-#endif
-
- if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(m_comp[eAudioRender]), buf)
- != OMX_ErrorNone)
- {
- ELOG("failed to empty OMX audio buffer");
-
- if (buf->nFlags & OMX_BUFFERFLAG_STARTTIME)
- m_setAudioStartTime = true;
-
- buf->nFilledLen = 0;
- buf->pAppPrivate = m_spareAudioBuffers;
- m_spareAudioBuffers = buf;
- ret = false;
- }
- Unlock();
- return ret;
-}
diff --git a/omx.h b/omx.h
index d5eb467..f16714a 100644
--- a/omx.h
+++ b/omx.h
@@ -38,6 +38,8 @@ extern "C" {
(a).nVersion.s.nRevision = OMX_VERSION_REVISION; \
(a).nVersion.s.nStep = OMX_VERSION_STEP
+#define BUFFERSTAT_FILTER_SIZE 64
+
class cOmxEvents;
class cOmxEventHandler;
@@ -124,7 +126,6 @@ public:
void SetClockScale(OMX_S32 scale);
bool IsClockFreezed(void) { return m_clockScale == 0; }
- unsigned int GetAudioLatency(void);
enum eClockReference {
eClockRefAudio,
@@ -134,26 +135,15 @@ public:
void SetClockReference(eClockReference clockReference);
void SetClockLatencyTarget(void);
- void SetVolume(int vol);
- void SetMute(bool mute);
- void StopAudio(void);
-
- void FlushAudio(void);
-
- int SetupAudioRender(cAudioCodec::eCodec outputFormat,
- int channels, cRpiAudioPort::ePort audioPort,
- int samplingRate = 0, int frameSize = 0);
void SetDisplayMode(bool letterbox, bool noaspect);
void SetPixelAspectRatio(int width, int height);
void SetDisplayRegion(int x, int y, int width, int height);
void SetDisplay(int display, int layer);
- OMX_BUFFERHEADERTYPE* GetAudioBuffer(int64_t pts = OMX_INVALID_PTS);
-
- bool EmptyAudioBuffer(OMX_BUFFERHEADERTYPE *buf);
-
- void GetBufferUsage(int &audio, int &video);
+#ifdef DEBUG_BUFFERS
+ static void DumpBuffer(OMX_BUFFERHEADERTYPE *buf, const char *prefix = "");
+#endif
private:
@@ -161,23 +151,10 @@ private:
static const char* errStr(int err);
-#ifdef DEBUG_BUFFERS
- static void DumpBuffer(OMX_BUFFERHEADERTYPE *buf, const char *prefix = "");
-#endif
-
ILCLIENT_T *m_client;
COMPONENT_T *m_comp[cOmx::eNumComponents + 1];
TUNNEL_T m_tun[cOmx::eNumTunnels + 1];
- bool m_setAudioStartTime;
-
-#define BUFFERSTAT_FILTER_SIZE 64
-
- int m_usedAudioBuffers[BUFFERSTAT_FILTER_SIZE];
- int m_usedVideoBuffers[BUFFERSTAT_FILTER_SIZE];
-
- OMX_BUFFERHEADERTYPE* m_spareAudioBuffers;
-
eClockReference m_clockReference;
OMX_S32 m_clockScale;
@@ -185,7 +162,6 @@ private:
cList<cOmxEventHandler> *m_eventHandlers;
- void HandlePortBufferEmptied(eOmxComponent component);
void HandlePortSettingsChanged(unsigned int portId);
bool IsBufferStall(void);
@@ -194,7 +170,6 @@ private:
static void OnEndOfStream(void *instance, COMPONENT_T *comp, OMX_U32 data);
static void OnError(void *instance, COMPONENT_T *comp, OMX_U32 data);
static void OnConfigChanged(void *instance, COMPONENT_T *comp, OMX_U32 data);
-
};
/* ------------------------------------------------------------------------- */
diff --git a/omxdevice.c b/omxdevice.c
index 71b444e..debd0a8 100644
--- a/omxdevice.c
+++ b/omxdevice.c
@@ -55,7 +55,7 @@ cOmxDevice::cOmxDevice(void (*onPrimaryDevice)(void), int display, int layer) :
cDevice(),
m_onPrimaryDevice(onPrimaryDevice),
m_omx(new cOmx()),
- m_audio(new cRpiAudioDecoder(m_omx)),
+ m_audio(0),
m_video(0),
m_mutex(new cMutex()),
m_timer(new cTimeMs()),
@@ -81,7 +81,6 @@ cOmxDevice::~cOmxDevice()
DeInit();
delete m_omx;
- delete m_audio;
delete m_mutex;
delete m_timer;
}
@@ -93,6 +92,8 @@ int cOmxDevice::Init(void)
ELOG("failed to initialize OMX!");
return -1;
}
+
+ m_audio = new cRpiAudioDecoder(m_omx);
if (m_audio->Init() < 0)
{
ELOG("failed to initialize audio!");
@@ -110,6 +111,8 @@ int cOmxDevice::DeInit(void)
ELOG("failed to deinitialize audio!");
return -1;
}
+ delete m_audio;
+
if (m_omx->DeInit() < 0)
{
ELOG("failed to deinitialize OMX!");
@@ -587,30 +590,32 @@ void cOmxDevice::AdjustLiveSpeed(void)
{
if (m_timer->TimedOut())
{
- int usedBuffers, usedAudioBuffers, usedVideoBuffers;
- m_omx->GetBufferUsage(usedAudioBuffers, usedVideoBuffers);
- usedBuffers = m_hasAudio ? usedAudioBuffers : usedVideoBuffers;
-
- if (usedBuffers < 5)
- m_liveSpeed = eNegCorrection;
-
- else if (usedBuffers > 15)
- m_liveSpeed = ePosCorrection;
-
- else if ((usedBuffers > 10 && m_liveSpeed == eNegCorrection) ||
- (usedBuffers < 10 && m_liveSpeed == ePosCorrection))
- m_liveSpeed = eNoCorrection;
-
-#ifdef DEBUG_BUFFERSTAT
- DLOG("buffer usage: A=%3d%%, V=%3d%%, Corr=%d",
- usedAudioBuffers, usedVideoBuffers,
- m_liveSpeed == eNegMaxCorrection ? -2 :
- m_liveSpeed == eNegCorrection ? -1 :
- m_liveSpeed == eNoCorrection ? 0 :
- m_liveSpeed == ePosCorrection ? 1 :
- m_liveSpeed == ePosMaxCorrection ? 2 : 0);
-#endif
- m_omx->SetClockScale(s_liveSpeeds[m_liveSpeed]);
+ int usedBuffers = m_hasAudio ? m_audio->GetBufferUsage() :
+ (m_video ? m_video->GetBufferUsage() : -1);
+
+ if (usedBuffers >= 0)
+ {
+ if (usedBuffers < 5)
+ m_liveSpeed = eNegCorrection;
+
+ else if (usedBuffers > 15)
+ m_liveSpeed = ePosCorrection;
+
+ else if ((usedBuffers > 10 && m_liveSpeed == eNegCorrection) ||
+ (usedBuffers < 10 && m_liveSpeed == ePosCorrection))
+ m_liveSpeed = eNoCorrection;
+
+ #ifdef DEBUG_BUFFERSTAT
+ DLOG("buffer usage: A=%3d%%, V=%3d%%, Corr=%d",
+ usedAudioBuffers, usedVideoBuffers,
+ m_liveSpeed == eNegMaxCorrection ? -2 :
+ m_liveSpeed == eNegCorrection ? -1 :
+ m_liveSpeed == eNoCorrection ? 0 :
+ m_liveSpeed == ePosCorrection ? 1 :
+ m_liveSpeed == ePosMaxCorrection ? 2 : 0);
+ #endif
+ m_omx->SetClockScale(s_liveSpeeds[m_liveSpeed]);
+ }
m_timer->Set(1000);
}
}
@@ -625,6 +630,9 @@ void cOmxDevice::HandleEndOfStream(void)
if (m_hasVideo && m_video)
m_video->Clear();
+ if (m_hasAudio)
+ m_audio->Reset();
+
m_omx->ResetClock();
m_omx->SetClockScale(s_playbackSpeeds[m_direction][m_playbackSpeed]);
@@ -674,11 +682,11 @@ void cOmxDevice::SetVolumeDevice(int Volume)
DBG("SetVolume(%d)", Volume);
if (Volume)
{
- m_omx->SetVolume(Volume);
- m_omx->SetMute(false);
+ m_audio->SetVolume(Volume);
+ m_audio->SetMute(false);
}
else
- m_omx->SetMute(true);
+ m_audio->SetMute(true);
}
bool cOmxDevice::Poll(cPoller &Poller, int TimeoutMs)