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;
960 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
961 if (error != OMX_ErrorNone) {
962 Log::getInstance()->log("Audio", Log::DEBUG,
963 "Init OMX aud rend OMX_GetParameter failed %x", error);
964 video->UnlockClock();
965 DeAllocateCodecsOMX();
968 // buggy return value
969 omx_rend_clock_port = p_param.nStartPortNumber;
974 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
976 if (error!=OMX_ErrorNone){
977 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
978 video->UnlockClock();
979 DeAllocateCodecsOMX();
983 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
984 if (error!=OMX_ErrorNone){
985 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
986 video->UnlockClock();
987 DeAllocateCodecsOMX();
990 omx_codec_input_port=p_param.nStartPortNumber;
991 omx_codec_output_port=p_param.nStartPortNumber+1;
993 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
994 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
995 video->UnlockClock();
996 DeAllocateCodecsOMX();
1003 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
1004 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
1005 video->UnlockClock();
1006 DeAllocateCodecsOMX();
1010 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
1011 Log::getInstance()->log("Audio", Log::DEBUG,
1012 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
1013 video->UnlockClock();
1014 DeAllocateCodecsOMX();
1024 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
1025 if (error!=OMX_ErrorNone){
1026 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);
1027 video->UnlockClock();
1028 DeAllocateCodecsOMX();
1032 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1034 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1035 video->UnlockClock();
1036 DeAllocateCodecsOMX();
1040 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1041 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1042 video->UnlockClock();
1043 DeAllocateCodecsOMX();
1050 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1051 video->UnlockClock();
1052 DeAllocateCodecsOMX();
1056 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1057 video->UnlockClock();
1058 DeAllocateCodecsOMX();
1064 if (!ChangeAudioPortConfig(false)){
1065 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1066 video->UnlockClock();
1067 DeAllocateCodecsOMX();
1071 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1072 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1073 DeAllocateCodecsOMX();
1079 if (!PrepareInputBufsOMX(true)) {
1080 video->UnlockClock();
1081 DeAllocateCodecsOMX();
1087 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1088 if (error!=OMX_ErrorNone){
1089 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1090 video->UnlockClock();
1091 DeAllocateCodecsOMX();
1097 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1099 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1100 video->UnlockClock();
1101 DeAllocateCodecsOMX();
1105 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1106 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1107 video->UnlockClock();
1108 DeAllocateCodecsOMX();
1112 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1113 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1114 video->UnlockClock();
1115 DeAllocateCodecsOMX();
1120 video->UnlockClock();
1124 video->clockUnpause();
1127 if (!video->setClockExecutingandRunning()) return 0;
1129 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1137 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1139 VideoOMX *video=(VideoOMX*)Video::getInstance();
1140 OMX_ERRORTYPE error;
1141 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1142 memset(&port_def_type,0,sizeof(port_def_type));
1143 port_def_type.nSize=sizeof(port_def_type);
1144 port_def_type.nVersion.nVersion=OMX_VERSION;
1145 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1147 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1149 if (error!=OMX_ErrorNone){
1150 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1155 port_def_type.nBufferCountActual=2;
1156 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1158 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1160 if (error!=OMX_ErrorNone){
1161 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1166 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1167 if (error!=OMX_ErrorNone){
1168 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1172 input_bufs_omx_mutex.Lock();
1173 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1174 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1175 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1176 if (error!=OMX_ErrorNone){
1177 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1178 input_bufs_omx_mutex.Unlock();
1181 input_bufs_omx_all.push_back(buf_head);
1182 input_bufs_omx_free.push_back(buf_head);
1184 omx_first_frame=true;
1187 cur_input_buf_omx=NULL;
1188 input_bufs_omx_mutex.Unlock();
1190 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1197 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1199 OMX_ERRORTYPE error;
1201 cur_input_buf_omx=NULL;
1202 input_bufs_omx_mutex.Lock();
1203 for (int i=0; i< input_bufs_omx_all.size();i++) {
1204 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1205 if (error!=OMX_ErrorNone){
1206 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1207 input_bufs_omx_mutex.Unlock();
1212 input_bufs_omx_all.clear();
1213 input_bufs_omx_free.clear();
1214 input_bufs_omx_mutex.Unlock();
1218 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1220 OMX_ERRORTYPE error;
1222 cur_input_buf_omx=NULL;
1223 input_bufs_omx_mutex.Lock();
1224 while (input_bufs_omx_all.size()>0) {
1225 if (input_bufs_omx_free.size()>0) {
1226 // Destroy one buffer
1227 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1228 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1229 for (; itty!= input_bufs_omx_all.end();itty++) {
1230 if ((*itty)==cur_buf) {
1231 input_bufs_omx_all.erase(itty);
1232 input_bufs_omx_free.pop_front();
1237 input_bufs_omx_mutex.Unlock();
1239 input_bufs_omx_mutex.Lock();
1243 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1244 input_bufs_omx_mutex.Unlock();
1249 int AudioOMX::DeAllocateCodecsOMX()
1251 OMX_ERRORTYPE error;
1253 VideoOMX *video=(VideoOMX*)Video::getInstance();
1254 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1258 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1259 if (cur_input_buf_omx) {
1260 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1261 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1262 if (error!=OMX_ErrorNone) {
1263 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1266 cur_input_buf_omx=NULL;//write out old data
1268 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1271 if (omx_aud_rend/*dec*/) {
1272 // first stop the omx elements
1273 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1274 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1276 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1278 video->UnlockClock();
1279 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1281 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1284 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1285 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1288 // TODO proper deinit sequence
1289 // first flush all buffers
1291 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1292 if (error!=OMX_ErrorNone) {
1293 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1297 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1298 if (error!=OMX_ErrorNone){
1299 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1304 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1305 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1310 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1311 if (error!=OMX_ErrorNone){
1312 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1316 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1317 if (error!=OMX_ErrorNone){
1318 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1321 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1323 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1324 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1325 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1328 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1329 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1330 DeinitDecoderLibAV();
1331 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1334 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1335 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1338 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1339 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1342 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1343 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1347 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1348 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1351 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1352 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1357 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1358 if (error!=OMX_ErrorNone) {
1359 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1365 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1366 if (error!=OMX_ErrorNone) {
1367 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1371 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1372 if (error!=OMX_ErrorNone) {
1373 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1377 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1378 if (error!=OMX_ErrorNone) {
1379 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1382 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1385 //error=OMX_FreeHandle(omx_aud_dec);
1386 error=OMX_FreeHandle(omx_aud_rend);
1387 video->UnlockClock();
1388 video->destroyClock();
1389 omx_aud_rend/*dec*/=NULL;
1390 if (error!=OMX_ErrorNone) {
1391 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1395 video->UnlockClock();
1396 DeinitDecoderLibAV();
1398 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1405 int AudioOMX::stop()
1407 if (!initted) return 0;
1409 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1410 DeAllocateCodecsOMX();
1411 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1415 int AudioOMX::mute() {
1418 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1419 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1423 OMX_AUDIO_CONFIG_MUTETYPE amute;
1424 memset(&amute, 0, sizeof(amute));
1425 amute.nSize = sizeof(amute);
1426 amute.nVersion.nVersion = OMX_VERSION;
1427 amute.nPortIndex = omx_rend_input_port;
1428 amute.bMute = OMX_TRUE;
1429 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1431 if (error != OMX_ErrorNone) {
1432 Log::getInstance()->log("Audio", Log::DEBUG,
1433 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1434 omx_rend_input_port);
1446 int AudioOMX::unMute()
1448 if (!initted) return 0;
1450 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1451 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1455 OMX_AUDIO_CONFIG_MUTETYPE amute;
1456 memset(&amute, 0, sizeof(amute));
1457 amute.nSize = sizeof(amute);
1458 amute.nVersion.nVersion = OMX_VERSION;
1459 amute.nPortIndex = omx_rend_input_port;
1460 amute.bMute = OMX_FALSE;
1461 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1463 if (error != OMX_ErrorNone) {
1464 Log::getInstance()->log("Audio", Log::DEBUG,
1465 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1466 omx_rend_input_port);
1478 int AudioOMX::pause() {
1482 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1488 int AudioOMX::unPause()
1490 if (!initted) return 0;
1492 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1499 int AudioOMX::reset()
1501 if (!initted) return 0;
1503 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1504 DeAllocateCodecsOMX();
1506 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1507 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1508 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1514 int AudioOMX::setVolume(int tvolume)
1516 // parameter: 0 for silence, 20 for full
1517 if ((tvolume < 0) || (tvolume > 20)) return 0;
1519 // volume = 2 * (20 - volume);
1520 // Right, that one was rubbish... 0-10 were almost
1521 // inaudible, 11-20 did what should have been done
1522 // over the whole 0-20 range
1526 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1530 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1531 memset(&avol, 0, sizeof(avol));
1532 avol.nSize = sizeof(avol);
1533 avol.nVersion.nVersion = OMX_VERSION;
1534 avol.nPortIndex = omx_rend_input_port;
1535 avol.bLinear=OMX_FALSE;
1536 avol.sVolume.nValue =(volume-20)*200;
1537 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1539 if (error != OMX_ErrorNone) {
1540 Log::getInstance()->log("Audio", Log::DEBUG,
1541 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1542 omx_rend_input_port);
1554 int AudioOMX::test()
1557 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1559 /* aud_sync_parms_t a;
1563 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1566 /*OK*/ //printf("Audio sync disable = %i\n", b);
1574 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1576 if (size<=2) return size; // silly;
1577 unsigned int test=0;
1579 //inspired by libav parsing code
1580 while (test+1<size) {
1581 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) {
1582 const int sample_rates[4]={44100,48000,32000,0};
1583 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1584 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1585 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1586 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1587 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1588 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1589 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1590 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1593 int layer=4-((data[test+1]&0x06)>>1);
1594 if (layer==4) {test++;continue;} //sanity check
1596 int bitrate_index=(data[test+2]&0xf0)>>4;
1597 if (bitrate_index==0x0f || bitrate_index==0x0) {test++;continue;} //sanity check
1599 int samplerate_index=(data[test+2]&0x0C)>>2;
1600 if (samplerate_index==0x03) {test++;continue;} //sanity check
1602 int padding=(data[test+2]&2)>>1;
1603 if (0x10 & data[test+1]) {
1604 lsf=((data[test+1]) &0x8)?0:1;
1610 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1612 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1614 frame_size=(temp_frame_size*12000)/sample_rate;
1615 frame_size=(frame_size+padding)*4;
1616 } else if (layer==2) {
1617 frame_size=(temp_frame_size*144000)/sample_rate;
1618 frame_size=frame_size+padding;
1620 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1621 frame_size=frame_size+padding;
1623 //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);
1624 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME DIAG: %x %x %x ",data[test],data[test+1],data[test+2]);
1625 *framesize=frame_size;
1627 return test; // probably FrameSync
1634 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1636 if (size<=4) return size; // silly;
1637 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1638 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1639 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1640 1152, 1280, 1280, };
1641 unsigned int test=0;
1642 *framesize=20000; //if we do not find a start code do not decompress
1643 while (test+4<size) {
1644 if (data[test]==0x0B && data[test+1]==0x77) {
1645 // now figure out the length of the frame
1646 unsigned char code=data[test+4];
1647 unsigned char fscod=(code& 0xC0)>>6;
1648 unsigned char frmsize=(code &0x3f);
1649 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1650 *framesize=frm_size_tab[frmsize]*2;
1651 return test; // probably FrameSync
1658 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1660 if (size<=4) return size; // silly;
1661 unsigned int test=0;
1662 *framesize=20000; //if we do not find a start code do not decompress
1663 while (test+4<size) {
1664 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1665 // now figure out the length of the frame
1666 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1667 *framesize=length+3;
1668 return test; // probably FrameSync
1674 #ifndef USE_LIBRESAMPLE
1675 #define SQRT3_2 1.22474487139158904909
1677 void AudioOMX::getDownMixMatrix(unsigned long long channels,
1678 int *left_mat,int *right_mat)
1681 double downmix_matrix[2][64];
1682 for (i=0;i<64;i++) {
1684 downmix_matrix[j][i]=0.;
1687 downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
1688 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
1689 downmix_matrix[0/*links*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1690 downmix_matrix[1/*rechts*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1692 if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
1693 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
1694 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
1696 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
1697 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
1699 downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
1700 downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
1701 downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
1702 downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
1703 downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
1704 downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
1705 downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
1706 downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
1707 downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
1708 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
1709 downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1710 downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1712 for (i=0,j=0;i<64;i++) {
1713 if ((1ULL << i)& channels) {
1714 left_mat[j]=(int)(downmix_matrix[0][i]*(1<<16));
1715 right_mat[j]=(int)(downmix_matrix[1][i]*(1<<16));
1723 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1725 packet = mplist.front();
1728 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1729 DeliverMediaPacket(packet, buffer, samplepos);
1730 if (*samplepos == packet.length) {
1738 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1740 VideoOMX *video = (VideoOMX*) Video::getInstance();
1742 OMX_PARAM_U32TYPE audio_lat;
1743 OMX_ERRORTYPE error;
1744 memset(&audio_lat, 0, sizeof(audio_lat));
1745 audio_lat.nSize = sizeof(audio_lat);
1746 audio_lat.nVersion.nVersion = OMX_VERSION;
1747 audio_lat.nPortIndex = omx_rend_input_port;
1749 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1751 video->UnlockClock();
1752 if (error != OMX_ErrorNone) {
1753 Log::getInstance()->log("Audio", Log::DEBUG,
1754 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1755 omx_rend_input_port);
1756 return pts; // no correction in case of error
1758 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1761 long long workpts=0;
1762 workpts+=addsamples;
1763 workpts-=audio_lat.nU32;
1764 workpts*=10LL*1000LL*1000LL;
1765 workpts=workpts/((long long)srate); //one second /samplerate
1771 bool AudioOMX::DrainTargetBufferFull()
1773 //Check, if we have OMX output buffers
1775 input_bufs_omx_mutex.Lock();
1776 full=(input_bufs_omx_free.size()==0);
1777 input_bufs_omx_mutex.Unlock();
1783 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1785 /*First Check, if we have an audio sample*/
1786 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1788 OMX_ERRORTYPE error;
1789 Log *logger=Log::getInstance();
1790 if (vw->InIframemode()) {
1793 return 0; //Not in iframe mode!
1796 if (!omx_running) return 0; // if we are not runnig do not do this
1797 if (vw->isClockPaused()) return 0; //Block if we pause
1798 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1800 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1802 /* if (packet.synched && packet.presentation_time <= 0) {
1803 *samplepos = packet.length;
1804 firstsynched = false;
1806 Log::getInstance()->log("Audio", Log::DEBUG,
1807 "DeliverMediaPacketOMX Frameskip");
1808 return packet.length;
1811 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1813 UINT headerstrip = 0;
1814 if (packet.disconti) {
1815 firstsynched = false;
1816 decompress_buffer_filled=0;
1817 if (cur_input_buf_omx) {
1818 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1820 if (error != OMX_ErrorNone) {
1821 Log::getInstance()->log("Audio", Log::DEBUG,
1822 "OMX_EmptyThisBuffer 1 failed %x", error);
1824 cur_input_buf_omx = NULL;
1828 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1829 if (packet.type != lastAType) {//Format Change //Push data out !
1830 firstsynched = false;
1832 Log::getInstance()->log("Audio", Log::DEBUG,"Notice audio type change %d %d", packet.type,lastAType);
1833 lastAType = packet.type;
1834 decompress_buffer_filled=0;
1836 if (cur_input_buf_omx) {
1837 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1839 if (error != OMX_ErrorNone) {
1840 Log::getInstance()->log("Audio", Log::DEBUG,
1841 "OMX_EmptyThisBuffer 2 failed %x", error);
1843 cur_input_buf_omx = NULL;
1848 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1849 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1851 if (!ChangeAudioPortConfig(true)) {
1852 Log::getInstance()->log("Audio", Log::DEBUG,
1853 "Changing audio port config failed", error);
1856 pthread_setcancelstate(oldcancelstate, NULL);
1857 pthread_setcanceltype(oldcanceltype, NULL);
1861 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1863 /*Inspect PES-Header */
1864 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1865 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1866 if (packet.type == MPTYPE_AC3)
1867 headerstrip += 4; //skip ac3 bytes
1868 *samplepos += headerstrip;
1869 if (packet.synched) {
1870 if (cur_input_buf_omx) {
1871 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1872 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1874 if (error != OMX_ErrorNone) {
1875 Log::getInstance()->log("Audio", Log::DEBUG,
1876 "OMX_EmptyThisBuffer 3 failed %x", error);
1878 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1880 cur_input_buf_omx = NULL;//write out old data
1882 firstsynched = true;
1883 //decompress_buffer_filled=0;
1885 if (!firstsynched) {//
1886 *samplepos = packet.length;//if we have not processed at least one
1887 decompress_buffer_filled=0;
1888 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1889 return packet.length;//synched packet ignore it!
1893 if (!cur_input_buf_omx) {
1894 input_bufs_omx_mutex.Lock();
1895 if (input_bufs_omx_free.size()==0) {
1896 input_bufs_omx_mutex.Unlock();
1897 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1898 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1899 return 0; // we do not have a free media sample
1902 cur_input_buf_omx=input_bufs_omx_free.front();
1903 cur_input_buf_omx->nFilledLen=0;
1904 cur_input_buf_omx->nOffset=0;
1905 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1906 input_bufs_omx_free.pop_front();
1907 input_bufs_omx_mutex.Unlock();
1909 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1911 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1912 if (packet.synched) {
1913 //Log::getInstance()->log("Audio", Log::DEBUG,
1914 // "packet synched marker");
1916 //lastreftimePTS=packet.pts;
1917 if (omx_first_frame) { // TODO time
1918 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1919 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1920 omx_first_frame = false;
1922 cur_input_buf_omx->nFlags = 0;
1923 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1925 lastreftimeOMX = packet.presentation_time;
1926 //Log::getInstance()->log("Audio", Log::DEBUG,
1927 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1928 lastreftimePTS = packet.pts;
1929 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1931 // Log::getInstance()->log("Audio", Log::DEBUG,
1932 // "packet NOT synched marker");
1933 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1934 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1937 if (packet.disconti || achange) {
1938 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1939 //mp23codec_context_libav->frame_size=-1;
1940 //ac3codec_context_libav->frame_size=-1;
1944 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1946 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1947 unsigned int haveToCopy=packet.length-*samplepos;
1950 while (haveToCopy>0) {
1951 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1953 unsigned int gotframesize=0;
1955 switch (packet.type) {
1956 case MPTYPE_MPEG_AUDIO:
1957 case MPTYPE_MPEG_AUDIO_LAYER3: {
1958 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1959 haveToCopy,&gotframesize);
1963 case MPTYPE_AC3_PRE13: {
1964 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1965 haveToCopy,&gotframesize);
1969 case MPTYPE_AAC_LATM: {
1970 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1971 haveToCopy,&gotframesize);
1975 if (adv!=haveToCopy) {
1980 *samplepos=packet.length; //no ac3 sync byte
1981 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
1982 return packet.length;
1985 // so everything is fine now do a memcpy
1986 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1987 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1988 haveToCopy-=cancopy;
1989 cur_input_buf_omx->nFilledLen+=cancopy;
1990 *samplepos+=cancopy;
1991 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
1993 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1994 if (error != OMX_ErrorNone) {
1995 Log::getInstance()->log("Audio", Log::DEBUG,
1996 "OMX_EmptyThisBuffer 5 failed %x", error);
1998 cur_input_buf_omx=NULL;
2001 input_bufs_omx_mutex.Lock();
2002 if (input_bufs_omx_free.size()==0) {
2003 input_bufs_omx_mutex.Unlock();
2004 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
2005 return *samplepos; // we do not have a free media sample
2007 cur_input_buf_omx=input_bufs_omx_free.front();
2008 cur_input_buf_omx->nFilledLen=0;
2009 cur_input_buf_omx->nOffset=0;
2010 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2011 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2012 input_bufs_omx_free.pop_front();
2013 input_bufs_omx_mutex.Unlock();
2015 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
2018 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
2026 AVCodecContext *current_context;
2027 switch (packet.type) {
2028 case MPTYPE_MPEG_AUDIO:
2029 case MPTYPE_MPEG_AUDIO_LAYER3: {
2030 current_context = mp23codec_context_libav;
2031 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2032 else framesize=current_context->frame_size;
2034 case MPTYPE_AAC_LATM: {
2035 current_context = aaclatmcodec_context_libav;
2038 case MPTYPE_AC3_PRE13: {
2039 current_context = ac3codec_context_libav;
2043 if (decompress_buffer_filled) { // have a remaining paket
2044 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2045 memcpy(decompress_buffer+decompress_buffer_filled,
2046 buffer+packet.pos_buffer+*samplepos,
2047 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2048 incoming_paket_libav.size = decompress_buffer_filled
2049 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2050 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d %d %d",packet.type,decompress_buffer_filled,packet.synched);
2052 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2053 incoming_paket_libav.size = haveToCopy;
2055 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
2057 while (haveToCopy> 0 && errcount<3) {
2059 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
2060 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
2061 // framesize, current_context->frame_size);
2063 bool donotdecompress=false;
2064 unsigned int gotframesize=0;
2065 // if (!decompress_buffer_filled) { // only do this if no old data is present
2067 switch (packet.type) {
2068 case MPTYPE_MPEG_AUDIO:
2069 case MPTYPE_MPEG_AUDIO_LAYER3: {
2070 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2071 incoming_paket_libav.size,&gotframesize);
2075 case MPTYPE_AC3_PRE13: {
2076 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2077 incoming_paket_libav.size,&gotframesize);
2080 case MPTYPE_AAC_LATM: {
2081 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2082 incoming_paket_libav.size,&gotframesize);
2086 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2087 incoming_paket_libav.data += adv;
2088 incoming_paket_libav.size-=adv;
2091 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2092 else*/ framesize=haveToCopy;
2093 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
2094 if (haveToCopy <= 0) {
2095 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
2096 *samplepos=packet.length;
2097 return packet.length;
2103 if (gotframesize>0 && gotframesize>haveToCopy) {
2104 donotdecompress=true;
2105 errcount=100; // exit loop
2107 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
2109 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
2110 if (!donotdecompress) {
2113 pthread_testcancel();
2114 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2115 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2117 if (!omx_running || !mp23codec_context_libav
2118 || !ac3codec_context_libav) {
2119 libav_mutex.Unlock();
2122 libav_mutex.Unlock();
2123 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
2124 int save_size=incoming_paket_libav.size;
2126 if (gotframesize<=incoming_paket_libav.size) {
2127 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2128 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2129 &gotta, &incoming_paket_libav);
2131 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:E %d %d",gotframesize,incoming_paket_libav.size);
2135 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:T %d",len);
2136 incoming_paket_libav.size=save_size;
2137 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
2138 pthread_setcancelstate(oldcancelstate, NULL);
2139 pthread_setcanceltype(oldcanceltype, NULL);
2140 pthread_testcancel();
2146 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
2147 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
2149 libav_mutex.Unlock();
2153 if (decompress_buffer_filled) { // reset to normal decoding
2155 //Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2156 haveToCopy -= min(len-decompress_buffer_filled,0);
2157 *samplepos += min(len-decompress_buffer_filled,0);
2158 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2159 /*else*/ framesize=haveToCopy;
2161 framesize=haveToCopy;
2163 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2165 decompress_buffer_filled=0;
2169 incoming_paket_libav.data += len;
2173 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2174 else*/framesize=haveToCopy;
2177 framesize=haveToCopy;
2180 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2182 incoming_paket_libav.size =framesize;
2184 //Log::getInstance()->log("Audio", Log::DEBUG,
2187 int dsize = av_samples_get_buffer_size(NULL,
2188 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2189 current_context->sample_fmt, 1);
2190 int dsize_in = av_samples_get_buffer_size(NULL,
2191 current_context->channels, decode_frame_libav->nb_samples,
2192 current_context->sample_fmt, 1);
2193 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2194 if ((cur_input_buf_omx->nFilledLen + dsize)
2195 > cur_input_buf_omx->nAllocLen ) {
2196 // I doubt that this will ever happen
2197 // Log::getInstance()->log("Audio", Log::DEBUG,
2198 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2199 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2201 if (error != OMX_ErrorNone) {
2202 Log::getInstance()->log("Audio", Log::DEBUG,
2203 "OMX_EmptyThisBuffer 4 failed %x", error);
2205 cur_input_buf_omx = NULL;
2207 if (!cur_input_buf_omx) {
2209 while (count < 10 && omx_running) {
2211 input_bufs_omx_mutex.Lock();
2212 if (input_bufs_omx_free.size() == 0) {
2213 input_bufs_omx_mutex.Unlock();
2214 // Log::getInstance()->log("Audio", Log::DEBUG,
2215 // "Deliver MediaPacket no free sample");
2217 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2218 if (!omx_running) return *samplepos;
2219 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2222 cur_input_buf_omx = input_bufs_omx_free.front();
2223 cur_input_buf_omx->nFilledLen = 0;
2224 cur_input_buf_omx->nOffset = 0;
2225 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2226 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2227 input_bufs_omx_free.pop_front();
2228 input_bufs_omx_mutex.Unlock();
2231 if (!cur_input_buf_omx) return *samplepos;
2236 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2237 if (current_context->channels==2) {
2238 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2239 decode_frame_libav->data[0], dsize);
2241 #ifndef USE_LIBRESAMPLE
2242 else if (current_context->channels==1) { //convert to stereo
2243 short* startbuffer=(short* )decode_frame_libav->data[0];
2244 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
2245 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2246 while (startbuffer!=endbuffer) {
2247 unsigned short temp=*startbuffer;
2255 unsigned int channels=current_context->channels;
2256 int left_mat[channels];
2257 int right_mat[channels];
2258 getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
2260 short* startbuffer=(short* )decode_frame_libav->data[0];
2261 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
2262 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2263 while (startbuffer!=endbuffer) {
2264 short* cur_buf=startbuffer;
2265 short* cur_buf_end=startbuffer+channels;
2269 int *mat2=right_mat;
2270 while (cur_buf!=cur_buf_end) {
2271 work1+= ((*mat1)*(*cur_buf));
2272 work2+= ((*mat2)*(*cur_buf));
2277 *destbuffer=work1>>16;
2279 *destbuffer=work2>>16;
2281 startbuffer+=channels;
2288 //untested for future use
2289 av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
2290 av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
2291 av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
2292 int ret=avresample_open(resam_con_libav);
2294 Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
2296 avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2297 dsize, decode_frame_libav->nb_samples,
2298 decode_frame_libav->data[0], dsize_in, decode_frame_libav->nb_samples);
2299 avresample_close(resam_con_libav);
2305 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2306 cur_input_buf_omx->nFilledLen += dsize;
2308 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2309 /* uint8_t a1=incoming_paket_libav.data[0];
2310 uint8_t a2=incoming_paket_libav.data[1];
2311 uint8_t a3=incoming_paket_libav.data[2];
2312 uint8_t a4=incoming_paket_libav.data[3];*/
2313 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2318 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2319 decompress_buffer_filled=0;
2321 //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);
2322 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2324 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2328 if (cur_input_buf_omx->nFilledLen) {
2329 //Log::getInstance()->log("Audio", Log::DEBUG,
2330 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2331 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2332 if (error != OMX_ErrorNone) {
2333 Log::getInstance()->log("Audio", Log::DEBUG,
2334 "OMX_EmptyThisBuffer 5 failed %x", error);
2336 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2337 cur_input_buf_omx = NULL;
2342 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2344 *samplepos=packet.length;
2345 return packet.length;
2351 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2352 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2353 return vw->SetStartAudioOffset(curreftime,rsync);
2356 void AudioOMX::ResetTimeOffsets() {
2357 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2358 vw->ResetTimeOffsets();