#include "vdr.h"
#include "woptionpane.h"
+#include "osdopenvg.h"
+
AudioOMX::AudioOMX()
{
initted = 0;
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;
}
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 {
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 {
}
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 {
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);
}
- if (!PrepareInputBufsOMX()) {
+ if (!PrepareInputBufsOMX(true)) {
video->UnlockClock();
DeAllocateCodecsOMX();
return 0;
-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;
}
- 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);
+ }
}
}
+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<OMX_BUFFERHEADERTYPE*>::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()
{
}
#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;
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,
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;
}
cur_input_buf_omx = NULL;
}
+ lsync=true;
}
if (packet.type != lastAType) {//Format Change //Push data out !
"Changing audio port config failed", error);
}
vw->UnlockClock();
+ lsync=true;
}
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;
}
}
+ 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;
}