diff options
author | Thomas Reufer <thomas@reufer.ch> | 2014-01-07 16:40:32 +0100 |
---|---|---|
committer | Thomas Reufer <thomas@reufer.ch> | 2014-01-07 16:40:32 +0100 |
commit | 88f137d194b1768344e954a1b1d35fb1fce03df9 (patch) | |
tree | b2b3a5293fe02ba30fe57f39ef3edc42d7ec7a04 /omx.c | |
parent | 4e710fc5c2bf2e2e33518eb3c537b7022085bda9 (diff) | |
download | vdr-plugin-rpihddevice-0.0.7.tar.gz vdr-plugin-rpihddevice-0.0.7.tar.bz2 |
2013-12-30: Version 0.0.70.0.7
-------------------------
- new:
- support audio sampling rates other than 48kHz
- changed setting of trick speed with APIVERSNUM >= 20103
- added deinterlacer
- fixed:
- improved audio parser
- fixed still image for H264 video
- mute audio render if volume is set to zero
- missing:
- image grabbing
- video format/output options
Diffstat (limited to 'omx.c')
-rw-r--r-- | omx.c | 167 |
1 files changed, 100 insertions, 67 deletions
@@ -5,6 +5,7 @@ */ #include "omx.h" +#include "setup.h" #include <vdr/tools.h> #include <vdr/thread.h> @@ -99,31 +100,33 @@ const char* cOmx::errStr(int err) "unknown"; } -void cOmx::HandleEndOfStream(unsigned int portId) - { - dsyslog("rpihddevice: HandleEndOfStream(%d)", portId); - - switch (portId) +void cOmx::Action(void) +{ + while (Running()) { - case 131: - break; - - case 11: - break; - - case 90: - break; + m_portEventReady->Wait(); + while (!m_portEvents->empty()) + { + HandlePortSettingsChanged(m_portEvents->front()); + m_portEvents->pop(); + } } } void cOmx::HandlePortSettingsChanged(unsigned int portId) { - //dsyslog("rpihddevice: HandlePortSettingsChanged(%d)", portId); +// dsyslog("rpihddevice: HandlePortSettingsChanged(%d)", portId); switch (portId) { - case 131: + case 191: + if (ilclient_setup_tunnel(&m_tun[eVideoFxToVideoScheduler], 0, 0) != 0) + esyslog("rpihddevice: failed to setup up tunnel from video fx to scheduler!"); + if (ilclient_change_component_state(m_comp[eVideoScheduler], OMX_StateExecuting) != 0) + esyslog("rpihddevice: failed to enable video scheduler!"); + break; + case 131: OMX_PARAM_PORTDEFINITIONTYPE portdef; OMX_INIT_STRUCT(portdef); portdef.nPortIndex = 131; @@ -138,15 +141,30 @@ void cOmx::HandlePortSettingsChanged(unsigned int portId) &interlace) != OMX_ErrorNone) esyslog("rpihddevice: failed to get video decoder interlace config!"); - dsyslog("rpihddevice: decoding video %dx%d%s", + bool deinterlace; + deinterlace = (cRpiSetup::IsDisplayProgressive() && + (interlace.eMode != OMX_InterlaceProgressive)); + + dsyslog("rpihddevice: decoding video %dx%d%s, %sabling deinterlacer", portdef.format.video.nFrameWidth, portdef.format.video.nFrameHeight, - interlace.eMode == OMX_InterlaceProgressive ? "p" : "i"); - - if (ilclient_setup_tunnel(&m_tun[eVideoDecoderToVideoScheduler], 0, 0) != 0) - esyslog("rpihddevice: failed to setup up tunnel from video decoder to scheduler!"); - if (ilclient_change_component_state(m_comp[eVideoScheduler], OMX_StateExecuting) != 0) - esyslog("rpihddevice: failed to enable video scheduler!"); + interlace.eMode == OMX_InterlaceProgressive ? "p" : "i", + deinterlace ? "en" : "dis"); + + OMX_CONFIG_IMAGEFILTERPARAMSTYPE filterparam; + OMX_INIT_STRUCT(filterparam); + filterparam.nPortIndex = 191; + filterparam.nNumParams = 1; + filterparam.nParams[0] = 3; + filterparam.eImageFilter = deinterlace ? OMX_ImageFilterDeInterlaceAdvanced : OMX_ImageFilterNone; + if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eVideoFx]), + OMX_IndexConfigCommonImageFilterParameters, &filterparam) != OMX_ErrorNone) + esyslog("rpihddevice: failed to set deinterlacing paramaters!"); + + if (ilclient_setup_tunnel(&m_tun[eVideoDecoderToVideoFx], 0, 0) != 0) + esyslog("rpihddevice: failed to setup up tunnel from video decoder to fx!"); + if (ilclient_change_component_state(m_comp[eVideoFx], OMX_StateExecuting) != 0) + esyslog("rpihddevice: failed to enable video fx!"); break; case 11: @@ -158,30 +176,25 @@ void cOmx::HandlePortSettingsChanged(unsigned int portId) } } -void cOmx::HandleBufferEmpty(COMPONENT_T *comp) -{ - if (comp == m_comp[eVideoDecoder]) - m_freeVideoBuffers++; - else if (comp == m_comp[eAudioRender]) - m_freeAudioBuffers++; -} - void cOmx::OnBufferEmpty(void *instance, COMPONENT_T *comp) { cOmx* omx = static_cast <cOmx*> (instance); - omx->HandleBufferEmpty(comp); + if (comp == omx->m_comp[eVideoDecoder]) + omx->m_freeVideoBuffers++; + else if (comp == omx->m_comp[eAudioRender]) + omx->m_freeAudioBuffers++; } void cOmx::OnPortSettingsChanged(void *instance, COMPONENT_T *comp, OMX_U32 data) { cOmx* omx = static_cast <cOmx*> (instance); - omx->HandlePortSettingsChanged(data); + omx->m_portEvents->push(data); + omx->m_portEventReady->Signal(); } void cOmx::OnEndOfStream(void *instance, COMPONENT_T *comp, OMX_U32 data) { cOmx* omx = static_cast <cOmx*> (instance); - omx->HandleEndOfStream(data); } void cOmx::OnError(void *instance, COMPONENT_T *comp, OMX_U32 data) @@ -191,19 +204,24 @@ void cOmx::OnError(void *instance, COMPONENT_T *comp, OMX_U32 data) } cOmx::cOmx() : + cThread(), m_mutex(new cMutex()), m_setAudioStartTime(false), m_setVideoStartTime(false), m_setVideoDiscontinuity(false), m_freeAudioBuffers(0), m_freeVideoBuffers(0), - m_clockReference(eClockRefAudio) + m_clockReference(eClockRefAudio), + m_portEventReady(new cCondWait()), + m_portEvents(new std::queue<unsigned int>) { } cOmx::~cOmx() { delete m_mutex; + delete m_portEventReady; + delete m_portEvents; } int cOmx::Init(void) @@ -226,6 +244,11 @@ int cOmx::Init(void) (ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0) esyslog("rpihddevice: failed creating video decoder!"); + // create image_fx + if (ilclient_create_component(m_client, &m_comp[eVideoFx], + "image_fx", ILCLIENT_DISABLE_ALL_PORTS) != 0) + esyslog("rpihddevice: failed creating video fx!"); + // create video_render if (ilclient_create_component(m_client, &m_comp[eVideoRender], "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) @@ -248,8 +271,11 @@ int cOmx::Init(void) esyslog("rpihddevice: failed creating video scheduler!"); // setup tunnels - set_tunnel(&m_tun[eVideoDecoderToVideoScheduler], - m_comp[eVideoDecoder], 131, m_comp[eVideoScheduler], 10); + set_tunnel(&m_tun[eVideoDecoderToVideoFx], + m_comp[eVideoDecoder], 131, m_comp[eVideoFx], 190); + + set_tunnel(&m_tun[eVideoFxToVideoScheduler], + m_comp[eVideoFx], 191, m_comp[eVideoScheduler], 10); set_tunnel(&m_tun[eVideoSchedulerToVideoRender], m_comp[eVideoScheduler], 11, m_comp[eVideoRender], 90); @@ -269,6 +295,7 @@ int cOmx::Init(void) ilclient_change_component_state(m_comp[eClock], OMX_StateExecuting); ilclient_change_component_state(m_comp[eVideoDecoder], OMX_StateIdle); + ilclient_change_component_state(m_comp[eVideoFx], OMX_StateIdle); // set up the number and size of buffers for audio render m_freeAudioBuffers = 2; //64; @@ -318,11 +345,15 @@ int cOmx::Init(void) SetClockState(cOmx::eClockStateRun); + Start(); + return 0; } int cOmx::DeInit(void) { + Cancel(); + ilclient_teardown_tunnels(m_tun); ilclient_state_transition(m_comp, OMX_StateIdle); ilclient_state_transition(m_comp, OMX_StateLoaded); @@ -402,14 +433,14 @@ bool cOmx::IsClockRunning(void) void cOmx::SetClockState(eClockState clockState) { - dsyslog("rpihddevice: SetClockState(%s)", +/* dsyslog("rpihddevice: SetClockState(%s)", clockState == eClockStateRun ? "eClockStateRun" : clockState == eClockStateStop ? "eClockStateStop" : clockState == eClockStateWaitForVideo ? "eClockStateWaitForVideo" : clockState == eClockStateWaitForAudio ? "eClockStateWaitForAudio" : clockState == eClockStateWaitForAudioVideo ? "eClockStateWaitForAudioVideo" : "unknown"); - +*/ OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; OMX_INIT_STRUCT(cstate); @@ -463,7 +494,7 @@ void cOmx::SetClockState(eClockState clockState) if (cstate.eState == OMX_TIME_ClockStateWaitingForStartTime) // 200ms pre roll, value taken from omxplayer - cstate.nOffset = ToOmxTicks(-1000LL * 400); + cstate.nOffset = ToOmxTicks(-1000LL * 200); if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eClock]), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) @@ -537,15 +568,13 @@ void cOmx::SetClockReference(eClockReference clockReference) if (OMX_SetConfig(ILC_GET_HANDLE(m_comp[eClock]), OMX_IndexConfigTimeActiveRefClock, &refClock) != OMX_ErrorNone) esyslog("rpihddevice: failed set active clock reference!"); - else +/* else dsyslog("rpihddevice: set active clock reference to %s", - m_clockReference == eClockRefAudio ? "audio" : "video"); + m_clockReference == eClockRefAudio ? "audio" : "video"); */ } void cOmx::SetVolume(int vol) { - dsyslog("rpihddevice: SetVolumeDevice(%d)", vol); - OMX_AUDIO_CONFIG_VOLUMETYPE volume; OMX_INIT_STRUCT(volume); volume.nPortIndex = 100; @@ -557,6 +586,18 @@ void cOmx::SetVolume(int vol) esyslog("rpihddevice: 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) + esyslog("rpihddevice: failed to set mute state!"); +} + void cOmx::SendEos(void) { #if 0 @@ -582,9 +623,14 @@ void cOmx::StopVideo(void) // put video decoder into idle ilclient_change_component_state(m_comp[eVideoDecoder], OMX_StateIdle); + // put video fx into idle + ilclient_flush_tunnels(&m_tun[eVideoDecoderToVideoFx], 1); + ilclient_disable_tunnel(&m_tun[eVideoDecoderToVideoFx]); + ilclient_change_component_state(m_comp[eVideoFx], OMX_StateIdle); + // put video scheduler into idle - ilclient_flush_tunnels(&m_tun[eVideoDecoderToVideoScheduler], 1); - ilclient_disable_tunnel(&m_tun[eVideoDecoderToVideoScheduler]); + ilclient_flush_tunnels(&m_tun[eVideoFxToVideoScheduler], 1); + ilclient_disable_tunnel(&m_tun[eVideoFxToVideoScheduler]); ilclient_flush_tunnels(&m_tun[eClockToVideoScheduler], 1); ilclient_disable_tunnel(&m_tun[eClockToVideoScheduler]); ilclient_change_component_state(m_comp[eVideoScheduler], OMX_StateIdle); @@ -648,7 +694,8 @@ void cOmx::FlushVideo(bool flushRender) if (OMX_SendCommand(ILC_GET_HANDLE(m_comp[eVideoDecoder]), OMX_CommandFlush, 130, NULL) != OMX_ErrorNone) esyslog("rpihddevice: failed to flush video decoder!"); - ilclient_flush_tunnels(&m_tun[eVideoDecoderToVideoScheduler], 1); + ilclient_flush_tunnels(&m_tun[eVideoDecoderToVideoFx], 1); + ilclient_flush_tunnels(&m_tun[eVideoFxToVideoScheduler], 1); if (flushRender) ilclient_flush_tunnels(&m_tun[eVideoSchedulerToVideoRender], 1); @@ -658,8 +705,6 @@ void cOmx::FlushVideo(bool flushRender) int cOmx::SetVideoCodec(cVideoCodec::eCodec codec, eDataUnitType dataUnit) { - dsyslog("rpihddevice: SetVideoCodec()"); - if (ilclient_change_component_state(m_comp[eVideoDecoder], OMX_StateIdle) != 0) esyslog("rpihddevice: failed to set video decoder to idle state!"); @@ -679,7 +724,7 @@ int cOmx::SetVideoCodec(cVideoCodec::eCodec codec, eDataUnitType dataUnit) // start with valid frames only if codec is MPEG2 SetVideoErrorConcealment(codec == cVideoCodec::eMPEG2); SetVideoDataUnitType(dataUnit); - //SetVideoDecoderExtraBuffers(3); + SetVideoDecoderExtraBuffers(3); if (ilclient_enable_port_buffers(m_comp[eVideoDecoder], 130, NULL, NULL, NULL) != 0) esyslog("rpihddevice: failed to enable port buffer on video decoder!"); @@ -730,7 +775,7 @@ int cOmx::SetupAudioRender(cAudioCodec::eCodec outputFormat, int channels, outputFormat == cAudioCodec::eAC3 ? OMX_AUDIO_CodingDDP : outputFormat == cAudioCodec::eEAC3 ? OMX_AUDIO_CodingDDP : outputFormat == cAudioCodec::eAAC ? OMX_AUDIO_CodingAAC : - outputFormat == cAudioCodec::eADTS ? OMX_AUDIO_CodingDTS : + outputFormat == cAudioCodec::eADTS ? OMX_AUDIO_CodingAAC : OMX_AUDIO_CodingAutoDetect; if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]), @@ -768,34 +813,22 @@ int cOmx::SetupAudioRender(cAudioCodec::eCodec outputFormat, int channels, break; case cAudioCodec::eAAC: + case cAudioCodec::eADTS: OMX_AUDIO_PARAM_AACPROFILETYPE aac; OMX_INIT_STRUCT(aac); aac.nPortIndex = 100; aac.nChannels = channels; aac.nSampleRate = samplingRate; - aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LATM; + aac.eAACStreamFormat = + outputFormat == cAudioCodec::eAAC ? OMX_AUDIO_AACStreamFormatMP4LATM : + outputFormat == cAudioCodec::eADTS ? OMX_AUDIO_AACStreamFormatMP4ADTS : + (OMX_AUDIO_AACSTREAMFORMATTYPE)0; if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]), OMX_IndexParamAudioAac, &aac) != OMX_ErrorNone) esyslog("rpihddevice: failed to set audio render aac parameters!"); break; - case cAudioCodec::eADTS: - OMX_AUDIO_PARAM_DTSTYPE dts; - OMX_INIT_STRUCT(aac); - dts.nPortIndex = 100; - dts.nChannels = channels; - dts.nSampleRate = samplingRate; - dts.nDtsType = 1; // ?? - dts.nFormat = 0; // ?? - dts.nDtsFrameSizeBytes = 0; // ? - OMX_AUDIO_CHANNEL_MAPPING(dts, channels); - - if (OMX_SetParameter(ILC_GET_HANDLE(m_comp[eAudioRender]), - OMX_IndexParamAudioDts, &dts) != OMX_ErrorNone) - esyslog("rpihddevice: failed to set audio render dts parameters!"); - break; - case cAudioCodec::ePCM: OMX_AUDIO_PARAM_PCMMODETYPE pcm; OMX_INIT_STRUCT(pcm); |