2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "woptionpane.h"
27 #include "osdopenvg.h"
36 lastAType = MPTYPE_MPEG_AUDIO;
42 canpass_pcm_mch=false;
44 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
52 omx_aud_rend/*dec*/=0;
53 cur_input_buf_omx=NULL;
56 ac3codec_context_libav=NULL;
59 mp23codec_context_libav=NULL;
60 #ifdef USE_LIBRESAMPLE
64 decompress_buffer=NULL;
65 decompress_buffer_size=0;
66 decompress_buffer_filled=0;
74 int AudioOMX::init(UCHAR tstreamType) {
79 streamType = tstreamType;
81 if (!initAllParams()) {
88 decompress_buffer_size=20000;
89 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
90 decompress_buffer_filled=0;
95 av_log_set_flags(AV_LOG_SKIP_REPEATED);
97 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
98 if (ac3codec_libav == NULL) {
99 Log::getInstance()->log("Audio", Log::DEBUG,
100 "Find libav ac3 decoder failed");
104 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
105 if (mp23codec_libav == NULL) {
106 Log::getInstance()->log("Audio", Log::DEBUG,
107 "Find libav mpeg audio decoder failed");
111 aaclatmcodec_libav = avcodec_find_decoder(CODEC_ID_AAC_LATM);
112 if (aaclatmcodec_libav == NULL) {
113 Log::getInstance()->log("Audio", Log::DEBUG,
114 "Find libav aac latm decoder failed");
120 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
124 Log::getInstance()->log("Audio", Log::NOTICE,
125 "TV hdmi supports mpeg1 layer 1 and 2");
127 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
131 Log::getInstance()->log("Audio", Log::NOTICE,
132 "TV hdmi supports mpeg1 layer 3");
135 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
138 Log::getInstance()->log("Audio", Log::NOTICE,
139 "TV hdmi supports AC3");
141 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
145 Log::getInstance()->log("Audio", Log::NOTICE,
146 "TV hdmi supports AAC");
149 canpass_pcm_mch=false;
154 int AudioOMX::initAllParams()
156 return (setStreamType(streamType) && setChannel() && setSource());
159 int AudioOMX::shutdown()
161 if (!initted) return 0;
164 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
165 DeAllocateCodecsOMX();
167 free(decompress_buffer);
168 decompress_buffer=NULL;
169 decompress_buffer_size=0;
170 decompress_buffer_filled=0;
175 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
177 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
178 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
181 if (STRCASECMP(name, "PCM") == 0) {
183 } else if (STRCASECMP(name, "Passthrough") == 0) {
185 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
190 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
193 if (STRCASECMP(name, "PCM") == 0) {
195 } else if (STRCASECMP(name, "Passthrough") == 0) {
197 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
202 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
205 if (STRCASECMP(name, "PCM") == 0) {
207 } else if (STRCASECMP(name, "Passthrough") == 0) {
209 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
214 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
217 if (STRCASECMP(name, "PCM") == 0) {
219 } else if (STRCASECMP(name, "Passthrough") == 0) {
221 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
226 name = vdr->configLoad("AudioOMX", "AudioOutput");
229 if (STRCASECMP(name, "analog") == 0) {
231 } else if (STRCASECMP(name, "HDMI") == 0) {
241 bool AudioOMX::handleOptionChanges(Option* option)
243 if (Audio::handleOptionChanges(option))
245 switch (option->id) {
247 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
249 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
257 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
259 } else if (STRCASECMP(option->options[option->userSetChoice],
260 "Passthrough") == 0) {
262 } else if (STRCASECMP(option->options[option->userSetChoice],
263 "PCMMultichannel") == 0) {
269 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
271 } else if (STRCASECMP(option->options[option->userSetChoice],
272 "Passthrough") == 0) {
274 } else if (STRCASECMP(option->options[option->userSetChoice],
275 "PCMMultichannel") == 0) {
281 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
283 } else if (STRCASECMP(option->options[option->userSetChoice],
284 "Passthrough") == 0) {
286 } else if (STRCASECMP(option->options[option->userSetChoice],
287 "PCMMultichannel") == 0) {
293 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
295 } else if (STRCASECMP(option->options[option->userSetChoice],
296 "Passthrough") == 0) {
298 } else if (STRCASECMP(option->options[option->userSetChoice],
299 "PCMMultichannel") == 0) {
309 bool AudioOMX::saveOptionstoServer()
312 switch (prefered_ac3) {
314 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
317 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
321 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
326 switch (prefered_aac) {
328 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
331 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
335 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
340 switch (prefered_mp2) {
342 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
345 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
349 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
354 switch (prefered_mp3) {
356 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
359 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
363 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
369 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
371 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
377 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
378 UINT numChoices, UINT defaultChoice, UINT startInt,
379 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
381 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
383 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
390 static const char* audioopts[]={"analog","HDMI"};
391 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
392 options->push_back(option);
393 pane->addOptionLine(option);
396 char **ac3opts=new char *[3];
398 ac3opts[i]=new char[strlen("PCM")+1];
399 strcpy(ac3opts[i],"PCM");
402 ac3opts[i]=new char[strlen("Passthrough")+1];
403 strcpy(ac3opts[i],"PassThrough");
406 if (canpass_pcm_mch) {
407 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
408 strcpy(ac3opts[i],"PCMMultichannel");
411 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
412 options->push_back(option);
413 pane->addOptionLine(option);
415 /* char **aacopts = new char *[3];
417 aacopts[i] = new char[strlen("PCM") + 1];
418 strcpy(mp2opts[i], "PCM");
421 aacopts[i] = new char[strlen("Passthrough") + 1];
422 strcpy(aacopts[i], "PassThrough");
425 if (canpass_pcm_mch) {
426 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
427 strcpy(aacopts[i], "PCMMultichannel");
430 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
431 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
432 aacopts, NULL, true, this);
433 options->push_back(option);
434 pane->addOptionLine(option);
437 char **mp2opts = new char *[3];
439 mp2opts[i] = new char[strlen("PCM") + 1];
440 strcpy(mp2opts[i], "PCM");
443 mp2opts[i] = new char[strlen("Passthrough") + 1];
444 strcpy(mp2opts[i], "PassThrough");
447 if (canpass_pcm_mch) {
448 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
449 strcpy(mp2opts[i], "PCMMultichannel");
452 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
453 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
454 mp2opts, NULL, true, this);
455 options->push_back(option);
456 pane->addOptionLine(option);
458 char **mp3opts = new char *[3];
460 mp3opts[i] = new char[strlen("PCM") + 1];
461 strcpy(mp3opts[i], "PCM");
464 mp3opts[i] = new char[strlen("Passthrough") + 1];
465 strcpy(mp3opts[i], "PassThrough");
468 if (canpass_pcm_mch) {
469 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
470 strcpy(mp3opts[i], "PCMMultichannel");
473 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
474 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
476 options->push_back(option);
477 pane->addOptionLine(option);*/
478 // Comment unsupported modes out
491 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
493 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
494 AudioOMX *audio=(AudioOMX *)getInstance();
495 audio->ReturnEmptyOMXBuffer(buffer);
496 return OMX_ErrorNone;
500 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
501 input_bufs_omx_mutex.Lock();
502 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
503 input_bufs_omx_free.push_back(buffer);
504 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
505 input_bufs_omx_mutex.Unlock();
508 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
509 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
510 return OMX_ErrorNone;
515 int AudioOMX::setStreamType(UCHAR type)
517 if (!initted) return 0;
519 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
523 int AudioOMX::setChannel()
525 if (!initted) return 0;
527 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
531 int AudioOMX::setSource()
533 if (!initted) return 0;
535 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
541 if (!initted) return 0;
543 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
547 int AudioOMX::play() {
550 lastAType=MPTYPE_MPEG_AUDIO;
551 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
553 ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
555 if (!AllocateCodecsOMX()) {
562 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
565 const char * destinations[]={"local","hdmi"};
570 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
571 memset(&auddest,0,sizeof(auddest));
572 auddest.nSize=sizeof(auddest);
573 auddest.nVersion.nVersion=OMX_VERSION;
574 strcpy((char *)auddest.sName, destinations[dest]);
576 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
577 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
578 if (error!=OMX_ErrorNone){
579 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
580 DeAllocateCodecsOMX();
588 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
591 //Ok first fidle a working configuration
592 Log::getInstance()->log("Audio", Log::DEBUG,
593 "ChangeAudioPortConfig");
595 OMX_AUDIO_CODINGTYPE encoding;
598 case MPTYPE_MPEG_AUDIO: {
599 if (prefered_mp2 == 2 && false) { //not supported yet
602 if (prefered_mp2 == 1 && canpass_mp2) {
604 encoding=OMX_AUDIO_CodingMP3;
607 encoding=OMX_AUDIO_CodingPCM;
612 case MPTYPE_AAC_LATM: {
613 if (prefered_aac == 2 && false) { //not supported yet
616 Log::getInstance()->log("Audio", Log::DEBUG,
617 "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
618 if (prefered_aac == 1 && canpass_aac) {
620 encoding=OMX_AUDIO_CodingAAC;
623 encoding=OMX_AUDIO_CodingPCM;
628 case MPTYPE_AC3_PRE13:
630 if (prefered_ac3 == 2 && false) { //not supported yet
633 Log::getInstance()->log("Audio", Log::DEBUG,
634 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
635 if (prefered_ac3 == 1 && canpass_ac3) {
637 encoding=OMX_AUDIO_CodingDDP;
640 encoding=OMX_AUDIO_CodingPCM;
645 case MPTYPE_MPEG_AUDIO_LAYER3: {
646 if (prefered_mp3 == 2 && false) { //not supported yet
649 if (prefered_mp3 == 1 && canpass_mp2) {
651 encoding=OMX_AUDIO_CodingMP3;
654 encoding=OMX_AUDIO_CodingPCM;
662 encoding=OMX_AUDIO_CodingPCM;
663 //mch=false; // multichannel also false
668 /*OMX_CONFIG_BOOLEANTYPE booly;
669 memset(&booly, 0, sizeof(booly));
670 booly.nSize = sizeof(booly);
671 booly.nVersion.nVersion = OMX_VERSION;
673 booly.bEnabled = OMX_TRUE;
675 booly.bEnabled = OMX_FALSE;
677 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
679 if (error != OMX_ErrorNone) {
680 Log::getInstance()->log("Audio", Log::DEBUG,
681 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
682 DeAllocateCodecsOMX();
685 VideoOMX* video=(VideoOMX*)Video::getInstance();
687 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
688 //DestroyInputBufsOMXwhilePlaying();
689 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
694 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
695 memset(&format, 0, sizeof(format));
696 format.nSize = sizeof(format);
697 format.nVersion.nVersion = OMX_VERSION;
698 format.nPortIndex = omx_rend_input_port;
699 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
701 if (error != OMX_ErrorNone) {
702 Log::getInstance()->log("Audio", Log::DEBUG,
703 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
704 omx_rend_input_port);
709 Log::getInstance()->log("Audio", Log::DEBUG,
710 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
711 format.eEncoding = encoding;
713 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
715 if (error != OMX_ErrorNone) {
716 Log::getInstance()->log("Audio", Log::DEBUG,
717 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
718 omx_rend_input_port,format.eEncoding );
723 case OMX_AUDIO_CodingPCM: {
724 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
725 memset(&audio_pcm, 0, sizeof(audio_pcm));
726 audio_pcm.nSize = sizeof(audio_pcm);
727 audio_pcm.nVersion.nVersion = OMX_VERSION;
728 audio_pcm.nChannels = 2;
729 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
730 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
731 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
732 audio_pcm.eNumData = OMX_NumericalDataSigned;
733 audio_pcm.eEndian = OMX_EndianLittle;
734 audio_pcm.bInterleaved = OMX_TRUE;
735 audio_pcm.nBitPerSample = 16;
736 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
737 audio_pcm.nChannels = 2;
738 audio_pcm.nSamplingRate = 48000;
739 audio_pcm.nPortIndex = omx_rend_input_port;
740 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
742 if (error != OMX_ErrorNone) {
743 Log::getInstance()->log("Audio", Log::DEBUG,
744 "Init OMX_IndexParamAudioPcm failed %x %d", error,
745 omx_rend_input_port);
749 case OMX_AUDIO_CodingDDP: {
750 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
751 memset(&audio_ddp, 0, sizeof(audio_ddp));
752 audio_ddp.nSize = sizeof(audio_ddp);
753 audio_ddp.nVersion.nVersion = OMX_VERSION;
754 audio_ddp.nPortIndex = omx_rend_input_port;
755 audio_ddp.nChannels = 8; //unknown
756 audio_ddp.nBitRate=0;
757 audio_ddp.nSampleRate=48000;
758 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
759 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
760 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
761 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
762 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
763 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
764 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
765 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
766 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
767 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
769 if (error != OMX_ErrorNone) {
770 Log::getInstance()->log("Audio", Log::DEBUG,
771 "Init OMX_IndexParamAudioDdp failed %x %d", error,
772 omx_rend_input_port);
777 default: break; //Make compiler happy
784 //PrepareInputBufsOMX(false);
785 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
795 int AudioOMX::InitDecoderLibAV()
798 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
799 if (!ac3codec_context_libav) {
800 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
804 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
805 ac3codec_context_libav->request_channels=2;
807 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
809 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
810 libav_mutex.Unlock();
814 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
815 if (!aaclatmcodec_context_libav) {
816 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
820 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
821 aaclatmcodec_context_libav->request_channels=2;
823 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
825 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
826 libav_mutex.Unlock();
831 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
832 if (!ac3codec_context_libav) {
833 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
834 libav_mutex.Unlock();
838 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
839 mp23codec_context_libav->request_channels=2;
841 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
843 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
844 libav_mutex.Unlock();
847 #ifdef USE_LIBRESAMPLE
848 resam_con_libav = avresample_alloc_context();
849 if (resam_con_libav == NULL) {
850 Log::getInstance()->log("Audio", Log::DEBUG,
851 "Alloc resample context failed");
855 av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format
856 av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
857 av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
859 av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
860 av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
861 av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example
864 av_init_packet(&incoming_paket_libav);
865 decode_frame_libav=avcodec_alloc_frame();
866 libav_mutex.Unlock();
867 decompress_buffer_filled=0;
874 void AudioOMX::DeinitDecoderLibAV() {
878 if (ac3codec_context_libav) {
879 avcodec_close(ac3codec_context_libav);
880 av_free(ac3codec_context_libav);
881 ac3codec_context_libav = NULL;
883 avcodec_close(aaclatmcodec_context_libav);
884 av_free(aaclatmcodec_context_libav);
885 aaclatmcodec_context_libav = NULL;
887 av_free(decode_frame_libav);
889 avcodec_close(mp23codec_context_libav);
890 av_free(mp23codec_context_libav);
891 mp23codec_context_libav = NULL;
892 #ifdef USE_LIBRESAMPLE
893 avresample_free(resam_con_libav);
894 resam_con_libav=NULL;
898 libav_mutex.Unlock();
903 int AudioOMX::AllocateCodecsOMX()
906 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
908 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
909 //Clock, move later to audio
910 VideoOMX *video=(VideoOMX*)Video::getInstance();
912 if (!InitDecoderLibAV()) return 0;;
915 OMX_PORT_PARAM_TYPE p_param;
916 memset(&p_param,0,sizeof(p_param));
917 p_param.nSize=sizeof(p_param);
918 p_param.nVersion.nVersion=OMX_VERSION;
921 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
922 return 0;// get the clock and init it if necessary
926 if (!video->idleClock()) {
931 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
932 if (error != OMX_ErrorNone) {
933 Log::getInstance()->log("Audio", Log::DEBUG,
934 "Init OMX audio rend failed %x", error);
935 video->UnlockClock();
936 DeAllocateCodecsOMX();
940 if (!ChangeAudioDestination()) {
941 video->UnlockClock();
942 DeAllocateCodecsOMX();
946 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
947 if (error != OMX_ErrorNone) {
948 Log::getInstance()->log("Audio", Log::DEBUG,
949 "Init OMX audio rend OMX_GetParameter failed %x", error);
950 video->UnlockClock();
951 DeAllocateCodecsOMX();
954 omx_rend_input_port = p_param.nStartPortNumber;
956 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
957 if (error != OMX_ErrorNone) {
958 Log::getInstance()->log("Audio", Log::DEBUG,
959 "Init OMX aud rend OMX_GetParameter failed %x", error);
960 video->UnlockClock();
961 DeAllocateCodecsOMX();
964 // buggy return value
965 omx_rend_clock_port = p_param.nStartPortNumber;
968 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
970 if (error!=OMX_ErrorNone){
971 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
972 video->UnlockClock();
973 DeAllocateCodecsOMX();
977 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
978 if (error!=OMX_ErrorNone){
979 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
980 video->UnlockClock();
981 DeAllocateCodecsOMX();
984 omx_codec_input_port=p_param.nStartPortNumber;
985 omx_codec_output_port=p_param.nStartPortNumber+1;
987 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
988 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
989 video->UnlockClock();
990 DeAllocateCodecsOMX();
997 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
998 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
999 video->UnlockClock();
1000 DeAllocateCodecsOMX();
1004 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
1005 Log::getInstance()->log("Audio", Log::DEBUG,
1006 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
1007 video->UnlockClock();
1008 DeAllocateCodecsOMX();
1018 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
1019 if (error!=OMX_ErrorNone){
1020 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel clock to rend failed %x %d %d", error,omx_clock_output_port,omx_rend_clock_port);
1021 video->UnlockClock();
1022 DeAllocateCodecsOMX();
1026 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1028 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1029 video->UnlockClock();
1030 DeAllocateCodecsOMX();
1034 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1035 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1036 video->UnlockClock();
1037 DeAllocateCodecsOMX();
1044 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1045 video->UnlockClock();
1046 DeAllocateCodecsOMX();
1050 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1051 video->UnlockClock();
1052 DeAllocateCodecsOMX();
1058 if (!ChangeAudioPortConfig(false)){
1059 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1060 video->UnlockClock();
1061 DeAllocateCodecsOMX();
1065 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1066 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1067 DeAllocateCodecsOMX();
1073 if (!PrepareInputBufsOMX(true)) {
1074 video->UnlockClock();
1075 DeAllocateCodecsOMX();
1081 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1082 if (error!=OMX_ErrorNone){
1083 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1084 video->UnlockClock();
1085 DeAllocateCodecsOMX();
1091 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1093 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1094 video->UnlockClock();
1095 DeAllocateCodecsOMX();
1099 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1100 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1101 video->UnlockClock();
1102 DeAllocateCodecsOMX();
1106 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1107 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1108 video->UnlockClock();
1109 DeAllocateCodecsOMX();
1114 video->UnlockClock();
1117 video->clockUnpause();
1120 if (!video->setClockExecutingandRunning()) return 0;
1122 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1130 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1132 VideoOMX *video=(VideoOMX*)Video::getInstance();
1133 OMX_ERRORTYPE error;
1134 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1135 memset(&port_def_type,0,sizeof(port_def_type));
1136 port_def_type.nSize=sizeof(port_def_type);
1137 port_def_type.nVersion.nVersion=OMX_VERSION;
1138 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1140 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1142 if (error!=OMX_ErrorNone){
1143 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1148 port_def_type.nBufferCountActual=2;
1149 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1151 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1153 if (error!=OMX_ErrorNone){
1154 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1159 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1160 if (error!=OMX_ErrorNone){
1161 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1165 input_bufs_omx_mutex.Lock();
1166 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1167 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1168 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1169 if (error!=OMX_ErrorNone){
1170 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1171 input_bufs_omx_mutex.Unlock();
1174 input_bufs_omx_all.push_back(buf_head);
1175 input_bufs_omx_free.push_back(buf_head);
1177 omx_first_frame=true;
1180 cur_input_buf_omx=NULL;
1181 input_bufs_omx_mutex.Unlock();
1183 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1190 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1192 OMX_ERRORTYPE error;
1194 cur_input_buf_omx=NULL;
1195 input_bufs_omx_mutex.Lock();
1196 for (int i=0; i< input_bufs_omx_all.size();i++) {
1197 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1198 if (error!=OMX_ErrorNone){
1199 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1200 input_bufs_omx_mutex.Unlock();
1205 input_bufs_omx_all.clear();
1206 input_bufs_omx_free.clear();
1207 input_bufs_omx_mutex.Unlock();
1211 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1213 OMX_ERRORTYPE error;
1215 cur_input_buf_omx=NULL;
1216 input_bufs_omx_mutex.Lock();
1217 while (input_bufs_omx_all.size()>0) {
1218 if (input_bufs_omx_free.size()>0) {
1219 // Destroy one buffer
1220 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1221 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1222 for (; itty!= input_bufs_omx_all.end();itty++) {
1223 if ((*itty)==cur_buf) {
1224 input_bufs_omx_all.erase(itty);
1225 input_bufs_omx_free.pop_front();
1230 input_bufs_omx_mutex.Unlock();
1232 input_bufs_omx_mutex.Lock();
1236 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1237 input_bufs_omx_mutex.Unlock();
1242 int AudioOMX::DeAllocateCodecsOMX()
1244 OMX_ERRORTYPE error;
1246 VideoOMX *video=(VideoOMX*)Video::getInstance();
1247 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1251 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1252 if (cur_input_buf_omx) {
1253 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1254 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1255 if (error!=OMX_ErrorNone) {
1256 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1259 cur_input_buf_omx=NULL;//write out old data
1261 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1264 if (omx_aud_rend/*dec*/) {
1265 // first stop the omx elements
1266 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1267 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1269 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1271 video->UnlockClock();
1272 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1274 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1277 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1278 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1281 // TODO proper deinit sequence
1282 // first flush all buffers
1284 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1285 if (error!=OMX_ErrorNone) {
1286 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1290 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1291 if (error!=OMX_ErrorNone){
1292 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1297 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1298 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1303 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1304 if (error!=OMX_ErrorNone){
1305 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1309 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1310 if (error!=OMX_ErrorNone){
1311 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1314 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1316 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1317 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1318 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1321 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1322 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1323 DeinitDecoderLibAV();
1324 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1327 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1328 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1331 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1332 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1335 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1336 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1340 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1341 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1344 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1345 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1350 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1351 if (error!=OMX_ErrorNone) {
1352 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1358 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1359 if (error!=OMX_ErrorNone) {
1360 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1364 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1365 if (error!=OMX_ErrorNone) {
1366 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1370 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1371 if (error!=OMX_ErrorNone) {
1372 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1375 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1378 //error=OMX_FreeHandle(omx_aud_dec);
1379 error=OMX_FreeHandle(omx_aud_rend);
1380 video->UnlockClock();
1381 video->destroyClock();
1382 omx_aud_rend/*dec*/=NULL;
1383 if (error!=OMX_ErrorNone) {
1384 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1388 video->UnlockClock();
1389 DeinitDecoderLibAV();
1391 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1398 int AudioOMX::stop()
1400 if (!initted) return 0;
1402 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1403 DeAllocateCodecsOMX();
1404 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1408 int AudioOMX::mute() {
1411 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1412 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1416 OMX_AUDIO_CONFIG_MUTETYPE amute;
1417 memset(&amute, 0, sizeof(amute));
1418 amute.nSize = sizeof(amute);
1419 amute.nVersion.nVersion = OMX_VERSION;
1420 amute.nPortIndex = omx_rend_input_port;
1421 amute.bMute = OMX_TRUE;
1422 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1424 if (error != OMX_ErrorNone) {
1425 Log::getInstance()->log("Audio", Log::DEBUG,
1426 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1427 omx_rend_input_port);
1438 int AudioOMX::unMute()
1440 if (!initted) return 0;
1442 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1443 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1447 OMX_AUDIO_CONFIG_MUTETYPE amute;
1448 memset(&amute, 0, sizeof(amute));
1449 amute.nSize = sizeof(amute);
1450 amute.nVersion.nVersion = OMX_VERSION;
1451 amute.nPortIndex = omx_rend_input_port;
1452 amute.bMute = OMX_FALSE;
1453 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1455 if (error != OMX_ErrorNone) {
1456 Log::getInstance()->log("Audio", Log::DEBUG,
1457 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1458 omx_rend_input_port);
1469 int AudioOMX::pause() {
1473 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1479 int AudioOMX::unPause()
1481 if (!initted) return 0;
1483 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1490 int AudioOMX::reset()
1492 if (!initted) return 0;
1494 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1495 DeAllocateCodecsOMX();
1497 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1498 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1499 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1505 int AudioOMX::setVolume(int tvolume)
1507 // parameter: 0 for silence, 20 for full
1508 if ((tvolume < 0) || (tvolume > 20)) return 0;
1510 // volume = 2 * (20 - volume);
1511 // Right, that one was rubbish... 0-10 were almost
1512 // inaudible, 11-20 did what should have been done
1513 // over the whole 0-20 range
1517 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1521 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1522 memset(&avol, 0, sizeof(avol));
1523 avol.nSize = sizeof(avol);
1524 avol.nVersion.nVersion = OMX_VERSION;
1525 avol.nPortIndex = omx_rend_input_port;
1526 avol.bLinear=OMX_FALSE;
1527 avol.sVolume.nValue =(volume-20)*200;
1528 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1530 if (error != OMX_ErrorNone) {
1531 Log::getInstance()->log("Audio", Log::DEBUG,
1532 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1533 omx_rend_input_port);
1544 int AudioOMX::test()
1547 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1549 /* aud_sync_parms_t a;
1553 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1556 /*OK*/ //printf("Audio sync disable = %i\n", b);
1564 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1566 if (size<=2) return size; // silly;
1567 unsigned int test=0;
1569 //inspired by libav parsing code
1570 while (test+1<size) {
1571 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) {
1572 const int sample_rates[4]={44100,48000,32000,0};
1573 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1574 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1575 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1576 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1577 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1578 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1579 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1580 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1583 int layer=4-((data[test+1]&0x06)>>1);
1584 if (layer==4) {test++;continue;} //sanity check
1586 int bitrate_index=(data[test+2]&0xf0)>>4;
1587 if (bitrate_index==0x0f || bitrate_index==0x0) {test++;continue;} //sanity check
1589 int samplerate_index=(data[test+2]&0x0C)>>2;
1590 if (samplerate_index==0x03) {test++;continue;} //sanity check
1592 int padding=(data[test+2]&2)>>1;
1593 if (0x10 & data[test+1]) {
1594 lsf=((data[test+1]) &0x8)?0:1;
1600 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1602 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1604 frame_size=(temp_frame_size*12000)/sample_rate;
1605 frame_size=(frame_size+padding)*4;
1606 } else if (layer==2) {
1607 frame_size=(temp_frame_size*144000)/sample_rate;
1608 frame_size=frame_size+padding;
1610 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1611 frame_size=frame_size+padding;
1613 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME: %d %d %d %d %d %d %d",lsf,layer,bitrate_index,sample_rate,padding,temp_frame_size, frame_size);
1614 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME DIAG: %x %x %x ",data[test],data[test+1],data[test+2]);
1615 *framesize=frame_size;
1617 return test; // probably FrameSync
1624 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1626 if (size<=4) return size; // silly;
1627 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1628 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1629 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1630 1152, 1280, 1280, };
1631 unsigned int test=0;
1632 *framesize=20000; //if we do not find a start code do not decompress
1633 while (test+4<size) {
1634 if (data[test]==0x0B && data[test+1]==0x77) {
1635 // now figure out the length of the frame
1636 unsigned char code=data[test+4];
1637 unsigned char fscod=(code& 0xC0)>>6;
1638 unsigned char frmsize=(code &0x3f);
1639 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1640 *framesize=frm_size_tab[frmsize]*2;
1641 return test; // probably FrameSync
1648 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1650 if (size<=4) return size; // silly;
1651 unsigned int test=0;
1652 *framesize=20000; //if we do not find a start code do not decompress
1653 while (test+4<size) {
1654 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1655 // now figure out the length of the frame
1656 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1657 *framesize=length+3;
1658 return test; // probably FrameSync
1664 #ifndef USE_LIBRESAMPLE
1665 #define SQRT3_2 1.22474487139158904909
1667 void AudioOMX::getDownMixMatrix(unsigned long long channels,
1668 int *left_mat,int *right_mat)
1671 double downmix_matrix[2][64];
1672 for (i=0;i<64;i++) {
1674 downmix_matrix[j][i]=0.;
1677 downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
1678 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
1679 downmix_matrix[0/*links*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1680 downmix_matrix[1/*rechts*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1682 if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
1683 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
1684 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
1686 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
1687 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
1689 downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
1690 downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
1691 downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
1692 downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
1693 downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
1694 downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
1695 downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
1696 downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
1697 downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
1698 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
1699 downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1700 downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1702 for (i=0,j=0;i<64;i++) {
1703 if ((1ULL << i)& channels) {
1704 left_mat[j]=(int)(downmix_matrix[0][i]*(1<<16));
1705 right_mat[j]=(int)(downmix_matrix[1][i]*(1<<16));
1713 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1715 packet = mplist.front();
1718 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1719 DeliverMediaPacket(packet, buffer, samplepos);
1720 if (*samplepos == packet.length) {
1728 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1730 VideoOMX *video = (VideoOMX*) Video::getInstance();
1732 OMX_PARAM_U32TYPE audio_lat;
1733 OMX_ERRORTYPE error;
1734 memset(&audio_lat, 0, sizeof(audio_lat));
1735 audio_lat.nSize = sizeof(audio_lat);
1736 audio_lat.nVersion.nVersion = OMX_VERSION;
1737 audio_lat.nPortIndex = omx_rend_input_port;
1739 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1741 video->UnlockClock();
1742 if (error != OMX_ErrorNone) {
1743 Log::getInstance()->log("Audio", Log::DEBUG,
1744 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1745 omx_rend_input_port);
1746 return pts; // no correction in case of error
1748 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1751 long long workpts=0;
1752 workpts+=addsamples;
1753 workpts-=audio_lat.nU32;
1754 workpts*=10LL*1000LL*1000LL;
1755 workpts=workpts/((long long)srate); //one second /samplerate
1761 bool AudioOMX::DrainTargetBufferFull()
1763 //Check, if we have OMX output buffers
1765 input_bufs_omx_mutex.Lock();
1766 full=(input_bufs_omx_free.size()==0);
1767 input_bufs_omx_mutex.Unlock();
1773 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1775 /*First Check, if we have an audio sample*/
1776 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1778 OMX_ERRORTYPE error;
1779 Log *logger=Log::getInstance();
1780 if (vw->InIframemode()) {
1783 return 0; //Not in iframe mode!
1786 if (!omx_running) return 0; // if we are not runnig do not do this
1787 if (vw->isClockPaused()) return 0; //Block if we pause
1788 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1790 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1792 /* if (packet.synched && packet.presentation_time <= 0) {
1793 *samplepos = packet.length;
1794 firstsynched = false;
1796 Log::getInstance()->log("Audio", Log::DEBUG,
1797 "DeliverMediaPacketOMX Frameskip");
1798 return packet.length;
1801 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1803 UINT headerstrip = 0;
1804 if (packet.disconti) {
1805 firstsynched = false;
1806 decompress_buffer_filled=0;
1807 if (cur_input_buf_omx) {
1808 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1810 if (error != OMX_ErrorNone) {
1811 Log::getInstance()->log("Audio", Log::DEBUG,
1812 "OMX_EmptyThisBuffer 1 failed %x", error);
1814 cur_input_buf_omx = NULL;
1818 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1819 if (packet.type != lastAType) {//Format Change //Push data out !
1820 firstsynched = false;
1822 Log::getInstance()->log("Audio", Log::DEBUG,"Notice audio type change %d %d", packet.type,lastAType);
1823 lastAType = packet.type;
1824 decompress_buffer_filled=0;
1826 if (cur_input_buf_omx) {
1827 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1829 if (error != OMX_ErrorNone) {
1830 Log::getInstance()->log("Audio", Log::DEBUG,
1831 "OMX_EmptyThisBuffer 2 failed %x", error);
1833 cur_input_buf_omx = NULL;
1838 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1839 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1841 if (!ChangeAudioPortConfig(true)) {
1842 Log::getInstance()->log("Audio", Log::DEBUG,
1843 "Changing audio port config failed", error);
1846 pthread_setcancelstate(oldcancelstate, NULL);
1847 pthread_setcanceltype(oldcanceltype, NULL);
1851 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1853 /*Inspect PES-Header */
1854 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1855 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1856 if (packet.type == MPTYPE_AC3)
1857 headerstrip += 4; //skip ac3 bytes
1858 *samplepos += headerstrip;
1859 if (packet.synched) {
1860 if (cur_input_buf_omx) {
1861 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1862 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1864 if (error != OMX_ErrorNone) {
1865 Log::getInstance()->log("Audio", Log::DEBUG,
1866 "OMX_EmptyThisBuffer 3 failed %x", error);
1868 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1870 cur_input_buf_omx = NULL;//write out old data
1872 firstsynched = true;
1873 //decompress_buffer_filled=0;
1875 if (!firstsynched) {//
1876 *samplepos = packet.length;//if we have not processed at least one
1877 decompress_buffer_filled=0;
1878 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1879 return packet.length;//synched packet ignore it!
1883 if (!cur_input_buf_omx) {
1884 input_bufs_omx_mutex.Lock();
1885 if (input_bufs_omx_free.size()==0) {
1886 input_bufs_omx_mutex.Unlock();
1887 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1888 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1889 return 0; // we do not have a free media sample
1892 cur_input_buf_omx=input_bufs_omx_free.front();
1893 cur_input_buf_omx->nFilledLen=0;
1894 cur_input_buf_omx->nOffset=0;
1895 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1896 input_bufs_omx_free.pop_front();
1897 input_bufs_omx_mutex.Unlock();
1899 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1901 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1902 if (packet.synched) {
1903 //Log::getInstance()->log("Audio", Log::DEBUG,
1904 // "packet synched marker");
1906 //lastreftimePTS=packet.pts;
1907 if (omx_first_frame) { // TODO time
1908 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1909 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1910 omx_first_frame = false;
1912 cur_input_buf_omx->nFlags = 0;
1913 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1915 lastreftimeOMX = packet.presentation_time;
1916 //Log::getInstance()->log("Audio", Log::DEBUG,
1917 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1918 lastreftimePTS = packet.pts;
1919 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1921 // Log::getInstance()->log("Audio", Log::DEBUG,
1922 // "packet NOT synched marker");
1923 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1924 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1927 if (packet.disconti || achange) {
1928 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1929 //mp23codec_context_libav->frame_size=-1;
1930 //ac3codec_context_libav->frame_size=-1;
1934 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1936 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1937 unsigned int haveToCopy=packet.length-*samplepos;
1940 while (haveToCopy>0) {
1941 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1943 unsigned int gotframesize=0;
1945 switch (packet.type) {
1946 case MPTYPE_MPEG_AUDIO:
1947 case MPTYPE_MPEG_AUDIO_LAYER3: {
1948 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1949 haveToCopy,&gotframesize);
1953 case MPTYPE_AC3_PRE13: {
1954 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1955 haveToCopy,&gotframesize);
1959 case MPTYPE_AAC_LATM: {
1960 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1961 haveToCopy,&gotframesize);
1965 if (adv!=haveToCopy) {
1970 *samplepos=packet.length; //no ac3 sync byte
1971 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
1972 return packet.length;
1975 // so everything is fine now do a memcpy
1976 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1977 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1978 haveToCopy-=cancopy;
1979 cur_input_buf_omx->nFilledLen+=cancopy;
1980 *samplepos+=cancopy;
1981 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
1983 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1984 if (error != OMX_ErrorNone) {
1985 Log::getInstance()->log("Audio", Log::DEBUG,
1986 "OMX_EmptyThisBuffer 5 failed %x", error);
1988 cur_input_buf_omx=NULL;
1991 input_bufs_omx_mutex.Lock();
1992 if (input_bufs_omx_free.size()==0) {
1993 input_bufs_omx_mutex.Unlock();
1994 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
1995 return *samplepos; // we do not have a free media sample
1997 cur_input_buf_omx=input_bufs_omx_free.front();
1998 cur_input_buf_omx->nFilledLen=0;
1999 cur_input_buf_omx->nOffset=0;
2000 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2001 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2002 input_bufs_omx_free.pop_front();
2003 input_bufs_omx_mutex.Unlock();
2005 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
2008 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
2016 AVCodecContext *current_context;
2017 switch (packet.type) {
2018 case MPTYPE_MPEG_AUDIO:
2019 case MPTYPE_MPEG_AUDIO_LAYER3: {
2020 current_context = mp23codec_context_libav;
2021 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2022 else framesize=current_context->frame_size;
2024 case MPTYPE_AAC_LATM: {
2025 current_context = aaclatmcodec_context_libav;
2028 case MPTYPE_AC3_PRE13: {
2029 current_context = ac3codec_context_libav;
2033 if (decompress_buffer_filled) { // have a remaining paket
2034 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2035 memcpy(decompress_buffer+decompress_buffer_filled,
2036 buffer+packet.pos_buffer+*samplepos,
2037 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2038 incoming_paket_libav.size = decompress_buffer_filled
2039 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2040 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d %d %d",packet.type,decompress_buffer_filled,packet.synched);
2042 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2043 incoming_paket_libav.size = haveToCopy;
2045 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
2047 while (haveToCopy> 0 && errcount<3) {
2049 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
2050 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
2051 // framesize, current_context->frame_size);
2053 bool donotdecompress=false;
2054 unsigned int gotframesize=0;
2055 // if (!decompress_buffer_filled) { // only do this if no old data is present
2057 switch (packet.type) {
2058 case MPTYPE_MPEG_AUDIO:
2059 case MPTYPE_MPEG_AUDIO_LAYER3: {
2060 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2061 incoming_paket_libav.size,&gotframesize);
2065 case MPTYPE_AC3_PRE13: {
2066 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2067 incoming_paket_libav.size,&gotframesize);
2070 case MPTYPE_AAC_LATM: {
2071 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2072 incoming_paket_libav.size,&gotframesize);
2076 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2077 incoming_paket_libav.data += adv;
2078 incoming_paket_libav.size-=adv;
2081 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2082 else*/ framesize=haveToCopy;
2083 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
2084 if (haveToCopy <= 0) {
2085 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
2086 *samplepos=packet.length;
2087 return packet.length;
2093 if (gotframesize>0 && gotframesize>haveToCopy) {
2094 donotdecompress=true;
2095 errcount=100; // exit loop
2097 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
2099 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
2100 if (!donotdecompress) {
2103 pthread_testcancel();
2104 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2105 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2107 if (!omx_running || !mp23codec_context_libav
2108 || !ac3codec_context_libav) {
2109 libav_mutex.Unlock();
2112 libav_mutex.Unlock();
2113 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
2114 int save_size=incoming_paket_libav.size;
2116 if (gotframesize<=incoming_paket_libav.size) {
2117 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2118 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2119 &gotta, &incoming_paket_libav);
2121 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:E %d %d",gotframesize,incoming_paket_libav.size);
2125 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:T %d",len);
2126 incoming_paket_libav.size=save_size;
2127 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
2128 pthread_setcancelstate(oldcancelstate, NULL);
2129 pthread_setcanceltype(oldcanceltype, NULL);
2130 pthread_testcancel();
2136 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
2137 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
2139 libav_mutex.Unlock();
2143 if (decompress_buffer_filled) { // reset to normal decoding
2145 //Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2146 haveToCopy -= min(len-decompress_buffer_filled,0);
2147 *samplepos += min(len-decompress_buffer_filled,0);
2148 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2149 /*else*/ framesize=haveToCopy;
2151 framesize=haveToCopy;
2153 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2155 decompress_buffer_filled=0;
2159 incoming_paket_libav.data += len;
2163 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2164 else*/framesize=haveToCopy;
2167 framesize=haveToCopy;
2170 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2172 incoming_paket_libav.size =framesize;
2174 //Log::getInstance()->log("Audio", Log::DEBUG,
2177 int dsize = av_samples_get_buffer_size(NULL,
2178 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2179 current_context->sample_fmt, 1);
2180 int dsize_in = av_samples_get_buffer_size(NULL,
2181 current_context->channels, decode_frame_libav->nb_samples,
2182 current_context->sample_fmt, 1);
2183 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2184 if ((cur_input_buf_omx->nFilledLen + dsize)
2185 > cur_input_buf_omx->nAllocLen ) {
2186 // I doubt that this will ever happen
2187 // Log::getInstance()->log("Audio", Log::DEBUG,
2188 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2189 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2191 if (error != OMX_ErrorNone) {
2192 Log::getInstance()->log("Audio", Log::DEBUG,
2193 "OMX_EmptyThisBuffer 4 failed %x", error);
2195 cur_input_buf_omx = NULL;
2197 if (!cur_input_buf_omx) {
2199 while (count < 10 && omx_running) {
2201 input_bufs_omx_mutex.Lock();
2202 if (input_bufs_omx_free.size() == 0) {
2203 input_bufs_omx_mutex.Unlock();
2204 // Log::getInstance()->log("Audio", Log::DEBUG,
2205 // "Deliver MediaPacket no free sample");
2207 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2208 if (!omx_running) return *samplepos;
2209 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2212 cur_input_buf_omx = input_bufs_omx_free.front();
2213 cur_input_buf_omx->nFilledLen = 0;
2214 cur_input_buf_omx->nOffset = 0;
2215 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2216 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2217 input_bufs_omx_free.pop_front();
2218 input_bufs_omx_mutex.Unlock();
2221 if (!cur_input_buf_omx) return *samplepos;
2226 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2227 if (current_context->channels==2) {
2228 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2229 decode_frame_libav->data[0], dsize);
2231 #ifndef USE_LIBRESAMPLE
2232 else if (current_context->channels==1) { //convert to stereo
2233 short* startbuffer=(short* )decode_frame_libav->data[0];
2234 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
2235 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2236 while (startbuffer!=endbuffer) {
2237 unsigned short temp=*startbuffer;
2245 unsigned int channels=current_context->channels;
2246 int left_mat[channels];
2247 int right_mat[channels];
2248 getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
2250 short* startbuffer=(short* )decode_frame_libav->data[0];
2251 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
2252 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2253 while (startbuffer!=endbuffer) {
2254 short* cur_buf=startbuffer;
2255 short* cur_buf_end=startbuffer+channels;
2259 int *mat2=right_mat;
2260 while (cur_buf!=cur_buf_end) {
2261 work1+= ((*mat1)*(*cur_buf));
2262 work2+= ((*mat2)*(*cur_buf));
2267 *destbuffer=work1>>16;
2269 *destbuffer=work2>>16;
2271 startbuffer+=channels;
2278 //untested for future use
2279 av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
2280 av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
2281 av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
2282 int ret=avresample_open(resam_con_libav);
2284 Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
2286 avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2287 dsize, decode_frame_libav->nb_samples,
2288 decode_frame_libav->data[0], dsize_in, decode_frame_libav->nb_samples);
2289 avresample_close(resam_con_libav);
2295 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2296 cur_input_buf_omx->nFilledLen += dsize;
2298 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2299 /* uint8_t a1=incoming_paket_libav.data[0];
2300 uint8_t a2=incoming_paket_libav.data[1];
2301 uint8_t a3=incoming_paket_libav.data[2];
2302 uint8_t a4=incoming_paket_libav.data[3];*/
2303 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2308 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2309 decompress_buffer_filled=0;
2311 //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);
2312 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2314 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2318 if (cur_input_buf_omx->nFilledLen) {
2319 //Log::getInstance()->log("Audio", Log::DEBUG,
2320 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2321 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2322 if (error != OMX_ErrorNone) {
2323 Log::getInstance()->log("Audio", Log::DEBUG,
2324 "OMX_EmptyThisBuffer 5 failed %x", error);
2326 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2327 cur_input_buf_omx = NULL;
2332 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2334 *samplepos=packet.length;
2335 return packet.length;
2341 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2342 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2343 return vw->SetStartAudioOffset(curreftime,rsync);
2346 void AudioOMX::ResetTimeOffsets() {
2347 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2348 vw->ResetTimeOffsets();