From b5c6f78155f82946919a78863a34b3f8be429c1a Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 21 Oct 2012 17:43:09 +0200 Subject: [PATCH] Ac3 passthrough mode, cec volume control, switch to recording device --- audioomx.cc | 339 ++++++++++++++++++++++++++++++++++--------------- audioomx.h | 8 +- command.cc | 24 +++- remote.h | 5 + remotelinux.cc | 93 ++++++++++++-- remotelinux.h | 11 ++ videoomx.cc | 12 +- videoomx.h | 1 + vopts.h | 2 +- 9 files changed, 368 insertions(+), 127 deletions(-) diff --git a/audioomx.cc b/audioomx.cc index 256051b..684dee8 100644 --- a/audioomx.cc +++ b/audioomx.cc @@ -24,6 +24,8 @@ #include "vdr.h" #include "woptionpane.h" +#include "osdopenvg.h" + AudioOMX::AudioOMX() { initted = 0; @@ -100,6 +102,31 @@ int AudioOMX::init(UCHAR tstreamType) { return 0; } + int ret; + + ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0); + if (ret==0) { + //canpass_mp2=true; + // not implemented + Log::getInstance()->log("Audio", Log::NOTICE, + "TV hdmi supports mpeg1 layer 1 and 2"); + } + ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0); + if (ret==0) { + //canpass_mp3=true; + // not implemented + Log::getInstance()->log("Audio", Log::NOTICE, + "TV hdmi supports mpeg1 layer 3"); + } + + ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0); + if (ret==0) { + canpass_ac3=true; + Log::getInstance()->log("Audio", Log::NOTICE, + "TV hdmi supports AC3"); + } + canpass_pcm_mch=false; + return 1; } @@ -485,10 +512,10 @@ int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to if (hdmi) { switch (lastAType) { case MPTYPE_MPEG_AUDIO: { - if (prefered_mp2 == 3 && false) { //not supported yet + if (prefered_mp2 == 2 && false) { //not supported yet } else { - if (prefered_mp2 == 2 && canpass_mp2) { + if (prefered_mp2 == 1 && canpass_mp2) { passthrough = true; encoding=OMX_AUDIO_CodingMP3; } else { @@ -500,10 +527,12 @@ int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to break; case MPTYPE_AC3_PRE13: case MPTYPE_AC3: { - if (prefered_ac3 == 3 && false) { //not supported yet + if (prefered_ac3 == 2 && false) { //not supported yet } else { - if (prefered_ac3 == 2 && canpass_ac3) { + Log::getInstance()->log("Audio", Log::DEBUG, + "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3); + if (prefered_ac3 == 1 && canpass_ac3) { passthrough = true; encoding=OMX_AUDIO_CodingDDP; } else { @@ -514,10 +543,10 @@ int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to } break; case MPTYPE_MPEG_AUDIO_LAYER3: { - if (prefered_mp3 == 3 && false) { //not supported yet + if (prefered_mp3 == 2 && false) { //not supported yet } else { - if (prefered_mp3 == 2 && canpass_mp2) { + if (prefered_mp3 == 1 && canpass_mp2) { passthrough = true; encoding=OMX_AUDIO_CodingMP3; } else { @@ -553,93 +582,107 @@ int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to DeAllocateCodecsOMX(); return 0; }*/ + VideoOMX* video=(VideoOMX*)Video::getInstance(); + if (disport) { + video->DisablePort(omx_aud_rend,omx_rend_input_port,false); + //DestroyInputBufsOMXwhilePlaying(); + //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port); + + } + + OMX_AUDIO_PARAM_PORTFORMATTYPE format; + memset(&format, 0, sizeof(format)); + format.nSize = sizeof(format); + format.nVersion.nVersion = OMX_VERSION; + format.nPortIndex = omx_rend_input_port; + error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, + &format); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Audio", Log::DEBUG, + "Get OMX_IndexParamAudioPortFormat failed %x %d", error, + omx_rend_input_port); + return 0; + } + if (disport) + Log::getInstance()->log("Audio", Log::DEBUG, + "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding ); + format.eEncoding = encoding; - if (!omx_running) { - OMX_AUDIO_PARAM_PORTFORMATTYPE format; - memset(&format, 0, sizeof(format)); - format.nSize = sizeof(format); - format.nVersion.nVersion = OMX_VERSION; - format.nPortIndex = omx_rend_input_port; - error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, - &format); + error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, + &format); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Audio", Log::DEBUG, + "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error, + omx_rend_input_port,format.eEncoding ); + //return 0; + } + + switch (encoding) { + case OMX_AUDIO_CodingPCM: { + OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm; + memset(&audio_pcm, 0, sizeof(audio_pcm)); + audio_pcm.nSize = sizeof(audio_pcm); + audio_pcm.nVersion.nVersion = OMX_VERSION; + audio_pcm.nChannels = 2; + audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; + audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; + //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax; + audio_pcm.eNumData = OMX_NumericalDataSigned; + audio_pcm.eEndian = OMX_EndianLittle; + audio_pcm.bInterleaved = OMX_TRUE; + audio_pcm.nBitPerSample = 16; + audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; + audio_pcm.nChannels = 2; + audio_pcm.nSamplingRate = 48000; + audio_pcm.nPortIndex = omx_rend_input_port; + error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm, + &audio_pcm); if (error != OMX_ErrorNone) { Log::getInstance()->log("Audio", Log::DEBUG, - "Get OMX_IndexParamAudioPortFormat failed %x %d", error, + "Init OMX_IndexParamAudioPcm failed %x %d", error, omx_rend_input_port); return 0; } - - format.eEncoding = encoding; - - error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, - &format); + } break; + case OMX_AUDIO_CodingDDP: { + OMX_AUDIO_PARAM_DDPTYPE audio_ddp; + memset(&audio_ddp, 0, sizeof(audio_ddp)); + audio_ddp.nSize = sizeof(audio_ddp); + audio_ddp.nVersion.nVersion = OMX_VERSION; + audio_ddp.nPortIndex = omx_rend_input_port; + audio_ddp.nChannels = 8; //unknown + audio_ddp.nBitRate=0; + audio_ddp.nSampleRate=48000; + audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF; + audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF; + audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF; + audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE; + audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR; + audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR; + audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS; + audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS; + audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS; + error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp, + &audio_ddp); if (error != OMX_ErrorNone) { Log::getInstance()->log("Audio", Log::DEBUG, - "Set OMX_IndexParamAudioPortFormat failed %x %d", error, + "Init OMX_IndexParamAudioDdp failed %x %d", error, omx_rend_input_port); return 0; } - switch (encoding) { - case OMX_AUDIO_CodingPCM: { - OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm; - memset(&audio_pcm, 0, sizeof(audio_pcm)); - audio_pcm.nSize = sizeof(audio_pcm); - audio_pcm.nVersion.nVersion = OMX_VERSION; - audio_pcm.nChannels = 2; - audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; - audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; - //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax; - audio_pcm.eNumData = OMX_NumericalDataSigned; - audio_pcm.eEndian = OMX_EndianLittle; - audio_pcm.bInterleaved = OMX_TRUE; - audio_pcm.nBitPerSample = 16; - audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; - audio_pcm.nChannels = 2; - audio_pcm.nSamplingRate = 48000; - audio_pcm.nPortIndex = omx_rend_input_port; - error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm, - &audio_pcm); - if (error != OMX_ErrorNone) { - Log::getInstance()->log("Audio", Log::DEBUG, - "Init OMX_IndexParamAudioPcm failed %x %d", error, - omx_rend_input_port); - return 0; - } - } break; - case OMX_AUDIO_CodingDDP: { - OMX_AUDIO_PARAM_DDPTYPE audio_ddp; - memset(&audio_ddp, 0, sizeof(audio_ddp)); - audio_ddp.nSize = sizeof(audio_ddp); - audio_ddp.nVersion.nVersion = OMX_VERSION; - audio_ddp.nPortIndex = omx_rend_input_port; - audio_ddp.nChannels = 8; //unknown - audio_ddp.nBitRate=0; - audio_ddp.nSampleRate=48000; - audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF; - audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF; - audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF; - audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE; - audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR; - audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR; - audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS; - audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS; - audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS; - error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp, - &audio_ddp); - if (error != OMX_ErrorNone) { - Log::getInstance()->log("Audio", Log::DEBUG, - "Init OMX_IndexParamAudioDdp failed %x %d", error, - omx_rend_input_port); - return 0; - } + } break; + default: break; //Make compiler happy + }; - } break; - }; + if (disport) { + + //PrepareInputBufsOMX(false); + video->EnablePort(omx_aud_rend,omx_rend_input_port,false); } @@ -884,7 +927,7 @@ int AudioOMX::AllocateCodecsOMX() - if (!PrepareInputBufsOMX()) { + if (!PrepareInputBufsOMX(true)) { video->UnlockClock(); DeAllocateCodecsOMX(); return 0; @@ -941,7 +984,7 @@ int AudioOMX::AllocateCodecsOMX() -int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock mutex +int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex { VideoOMX *video=(VideoOMX*)Video::getInstance(); OMX_ERRORTYPE error; @@ -958,13 +1001,15 @@ int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock m } - port_def_type.nBufferCountActual=2; - port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important + if (setportdef) { + port_def_type.nBufferCountActual=2; + port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important - error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type); + error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type); - if (error!=OMX_ErrorNone){ + if (error!=OMX_ErrorNone){ Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error); + } } @@ -1020,6 +1065,36 @@ int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked } +int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked +{ + OMX_ERRORTYPE error; + + cur_input_buf_omx=NULL; + input_bufs_omx_mutex.Lock(); + while (input_bufs_omx_all.size()>0) { + if (input_bufs_omx_free.size()>0) { + // Destroy one buffer + vector::iterator itty=input_bufs_omx_all.begin(); + OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front(); + for (; itty!= input_bufs_omx_all.end();itty++) { + if ((*itty)==cur_buf) { + input_bufs_omx_all.erase(itty); + input_bufs_omx_free.pop_front(); + break; + } + } + } else { + input_bufs_omx_mutex.Unlock(); + MILLISLEEP(5); + input_bufs_omx_mutex.Lock(); + } + } + + Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size()); + input_bufs_omx_mutex.Unlock(); + return 1; +} + int AudioOMX::DeAllocateCodecsOMX() { @@ -1359,7 +1434,7 @@ int AudioOMX::test() } #endif -unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize) +unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize) { if (size<=2) return size; // silly; unsigned int test=0; @@ -1371,7 +1446,7 @@ unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned return size; } -unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize) +unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize) { if (size<=4) return size; // silly; const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128, @@ -1467,6 +1542,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, if (packet.synched && packet.presentation_time <= 0) { *samplepos = packet.length; firstsynched = false; + lsync=true; Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX Frameskip"); return packet.length; @@ -1487,6 +1563,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, } cur_input_buf_omx = NULL; } + lsync=true; } if (packet.type != lastAType) {//Format Change //Push data out ! @@ -1510,6 +1587,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, "Changing audio port config failed", error); } vw->UnlockClock(); + lsync=true; } @@ -1594,8 +1672,68 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more! unsigned int haveToCopy=packet.length-*samplepos; + if (passthrough) { - //TODO + while (haveToCopy>0) { + if (lsync) { + unsigned int gotframesize=0; + int adv=0; + switch (packet.type) { + case MPTYPE_MPEG_AUDIO: + case MPTYPE_MPEG_AUDIO_LAYER3: { + adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos, + haveToCopy,&gotframesize); + } + break; + case MPTYPE_AC3: + case MPTYPE_AC3_PRE13: { + adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos, + haveToCopy,&gotframesize); + } + break; + }; + if (adv!=haveToCopy) { + lsync=false; + haveToCopy-=adv; + *samplepos+=adv; + } else { + *samplepos=packet.length; //no ac3 sync byte + return packet.length; + } + } + // so everything is fine now do a memcpy + int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen); + memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy); + haveToCopy-=cancopy; + cur_input_buf_omx->nFilledLen+=cancopy; + *samplepos+=cancopy; + + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Audio", Log::DEBUG, + "OMX_EmptyThisBuffer 5 failed %x", error); + } + cur_input_buf_omx=NULL; + if (haveToCopy>0) { + // get5 new buffer + input_bufs_omx_mutex.Lock(); + if (input_bufs_omx_free.size()==0) { + input_bufs_omx_mutex.Unlock(); + // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2"); + return *samplepos; // we do not have a free media sample + } + cur_input_buf_omx=input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen=0; + cur_input_buf_omx->nOffset=0; + cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; + cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0); + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.Unlock(); + } + + + } + } else { int len; int gotta; @@ -1799,27 +1937,26 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, } } + decompress_buffer_filled=0; + if (haveToCopy ) { + Log::getInstance()->log("Audio", Log::DEBUG,"We can not decompress %d save for later %d %x %x",haveToCopy,packet.type,incoming_paket_libav.data,packet.pos_buffer); + memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size)); - } - decompress_buffer_filled=0; - if (haveToCopy ) { - Log::getInstance()->log("Audio", Log::DEBUG,"We can not decompress %d save for later %d %x %x",haveToCopy,packet.type,incoming_paket_libav.data,packet.pos_buffer); - memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size)); - - decompress_buffer_filled=min(haveToCopy,decompress_buffer_size); + decompress_buffer_filled=min(haveToCopy,decompress_buffer_size); - } + } - if (cur_input_buf_omx->nFilledLen) { - //Log::getInstance()->log("Audio", Log::DEBUG, + if (cur_input_buf_omx->nFilledLen) { + //Log::getInstance()->log("Audio", Log::DEBUG, // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts); - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); - if (error != OMX_ErrorNone) { - Log::getInstance()->log("Audio", Log::DEBUG, - "OMX_EmptyThisBuffer 5 failed %x", error); + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Audio", Log::DEBUG, + "OMX_EmptyThisBuffer 5 failed %x", error); + } + //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); + cur_input_buf_omx = NULL; } - //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); - cur_input_buf_omx = NULL; } diff --git a/audioomx.h b/audioomx.h index 23f9b21..360a093 100644 --- a/audioomx.h +++ b/audioomx.h @@ -117,8 +117,8 @@ class AudioOMX : public Audio - unsigned int AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize); - unsigned int AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize); + unsigned int AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize); + unsigned int AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize); void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver); @@ -141,8 +141,9 @@ class AudioOMX : public Audio int AllocateCodecsOMX(); int DeAllocateCodecsOMX(); - int PrepareInputBufsOMX(); + int PrepareInputBufsOMX(bool setportdef); int DestroyInputBufsOMX(); + int DestroyInputBufsOMXwhilePlaying(); int ChangeAudioPortConfig(bool disport); int ChangeAudioDestination(); @@ -167,6 +168,7 @@ class AudioOMX : public Audio UCHAR * decompress_buffer; unsigned int decompress_buffer_size; unsigned int decompress_buffer_filled; + bool lsync; int InitDecoderLibAV(); diff --git a/command.cc b/command.cc index a60e39f..3ce19e2 100644 --- a/command.cc +++ b/command.cc @@ -469,17 +469,27 @@ void Command::handleCommand(int button) case Remote::VOLUMEUP: case Remote::VOLUMEDOWN: { - VVolume* v = new VVolume(); - boxstack->add(v); - v->handleCommand(button); // this will draw+show + if (remote->handlesVolume()) { + if (button==Remote::DF_LEFT || button==Remote::VOLUMEDOWN) + remote->volumeDown(); + else remote->volumeUp(); + } else { + VVolume* v = new VVolume(); + boxstack->add(v); + v->handleCommand(button); // this will draw+show + } return; } case Remote::MUTE: { - VMute* v = new VMute(); - v->draw(); - boxstack->add(v); - boxstack->update(v); + if (remote->handlesVolume()) { + remote->volumeMute(); + } else { + VMute* v = new VMute(); + v->draw(); + boxstack->add(v); + boxstack->update(v); + } return; } case Remote::POWER: diff --git a/remote.h b/remote.h index 9f7b935..b517811 100644 --- a/remote.h +++ b/remote.h @@ -56,6 +56,11 @@ class Remote: public AbstractOption virtual bool mayHaveFewButtons() {return false;}; + virtual bool handlesVolume() {return false;}; + virtual void volumeUp() {}; + virtual void volumeDown() {}; + virtual void volumeMute() {}; + virtual void InitHWCListwithDefaults(); virtual char* HCWDesc(ULLONG hcw); const char *CommandDesc(UCHAR number); diff --git a/remotelinux.cc b/remotelinux.cc index 8d300f0..4506da0 100644 --- a/remotelinux.cc +++ b/remotelinux.cc @@ -20,6 +20,9 @@ #include "remotelinux.h" #include "i18n.h" +#include "vdr.h" +#include "woptionpane.h" + #include #include @@ -58,6 +61,7 @@ RemoteLinux::RemoteLinux() signal=false; cec_adap=NULL; num_loop=0; + cechandlesvolume=false; } @@ -133,7 +137,8 @@ int RemoteLinux::initCec() { cec_config.bActivateSource=1; cec_config.bUseTVMenuLanguage=1; //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE); - cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER); + cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE); + //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER); strncpy(cec_config.strDeviceName,"vomp",sizeof(cec_config.strDeviceName)); @@ -330,6 +335,9 @@ UCHAR RemoteLinux::TranslateHWCFixed(ULLONG code) case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_SELECT): case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_AN_RETURN): return OK; + case W_G_HCW(W_HCW_KC,KEY_POWER): + case W_G_HCW(W_HCW_KC,KEY_ESC): + case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_POWER): case POWER: return POWER; default: @@ -891,18 +899,81 @@ void RemoteLinux::incomingCECkey(int keys) } -/* -void RemoteLinux::Signal() { - signal=true; - //PulseEvent(event); - SetEvent(event); +bool RemoteLinux::loadOptionsfromServer(VDR* vdr) +{ + + // Set remote keys + char * name; + name = vdr->configLoad("RemoteLinux", "HandleVolume"); + + if (name != NULL) { + if (STRCASECMP(name, "Vomp") == 0) { + cechandlesvolume=false; + } else if (STRCASECMP(name, "Cec") == 0) { + cechandlesvolume=true; + } + } + return Remote::loadOptionsfromServer(vdr); +} + +bool RemoteLinux::saveOptionstoServer() +{ + if (cechandlesvolume) VDR::getInstance()->configSave("RemoteLinux", "HandleVolume","Cec"); + else VDR::getInstance()->configSave("RemoteLinux", "HandleVolume","Vomp"); + + return Remote::saveOptionstoServer(); } -void RemoteLinux::SendPower() +bool RemoteLinux::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane) { + if (!Remote::addOptionsToPanes(panenumber,options,pane)) return false; + + + Option* option; + if (panenumber == 2) + { + static const char* volumeopts[]={"Vomp","Cec"}; + option = new Option(100,tr("Volume handled by"), "RemoteLinux","HandleVolume",Option::TYPE_TEXT,/*4,2*/2,0,0,volumeopts,NULL,false,this); + options->push_back(option); + pane->addOptionLine(option); + } - curevent=POWER; - hascurevent=true; - SetEvent(event); -}*/ + return true; +} + +bool RemoteLinux::handleOptionChanges(Option* option) +{ + if (Remote::handleOptionChanges(option)) + return true; + switch (option->id) { + case 100: { + if (STRCASECMP(option->options[option->userSetChoice], "Vomp") == 0) { + cechandlesvolume=false; + } else if (STRCASECMP(option->options[option->userSetChoice], "Cec") + == 0) { + cechandlesvolume=true; + } + Log::getInstance()->log("Remote", Log::DEBUG, "Set volume handling to to %s %d",option->options[option->userSetChoice],cechandlesvolume); + return true; + } + break; + }; + return false; + +} + +void RemoteLinux::volumeUp() +{ + cec_adap->VolumeUp(); +} + +void RemoteLinux::volumeDown() +{ + cec_adap->VolumeDown(); +} + +void RemoteLinux::volumeMute() +{ + cec_adap->MuteAudio(); +} diff --git a/remotelinux.h b/remotelinux.h index 78790bf..0c96427 100644 --- a/remotelinux.h +++ b/remotelinux.h @@ -52,8 +52,18 @@ class RemoteLinux : public Remote const char*HardcodedTranslateStr(UCHAR command); char* HCWDesc(ULLONG hcw); + bool loadOptionsfromServer(VDR* vdr); + bool saveOptionstoServer(); + bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane); + bool handleOptionChanges(Option* option); + bool mayHaveFewButtons() {return true;}; + virtual bool handlesVolume() {return cechandlesvolume;}; + virtual void volumeUp(); + virtual void volumeDown(); + virtual void volumeMute(); + int initCec(); void deinitCec(); @@ -64,6 +74,7 @@ class RemoteLinux : public Remote bool signal; int curcec; bool hascurcec; + bool cechandlesvolume; UCHAR TranslateHWCFixed(ULLONG code); void InitKeymap(); diff --git a/videoomx.cc b/videoomx.cc index 05966c0..6d1f612 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -58,6 +58,8 @@ VideoOMX::VideoOMX() { xpos=ypos=0.f; deinterlace=2; //advanced + signalon=false; + } VideoOMX::~VideoOMX() @@ -408,7 +410,7 @@ void VideoOMX::selectVideoMode(int interlaced) } - + signalon=true; } @@ -535,13 +537,15 @@ void VideoOMX::updateMode() int VideoOMX::signalOff() { -// if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0; - return 1; + //TODO reinit osd + //vc_tv_power_off(); + //signalon=false; + return 1; } int VideoOMX::signalOn() { -// if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0; + if (!signalon) selectVideoMode(0); return 1; } diff --git a/videoomx.h b/videoomx.h index 395f04a..6feee0d 100644 --- a/videoomx.h +++ b/videoomx.h @@ -265,6 +265,7 @@ class VideoOMX : public Video void updateMode();//called internally to adjust for different parameters void selectVideoMode(int interlaced); UCHAR tvsystem; + bool signalon; diff --git a/vopts.h b/vopts.h index 4e31031..17ee301 100644 --- a/vopts.h +++ b/vopts.h @@ -35,7 +35,7 @@ class VOpts : public TBBoxx { public: VOpts(); - ~VOpts(); + virtual ~VOpts(); int handleCommand(int command); void processMessage(Message* m); -- 2.39.2