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;
61 decompress_buffer=NULL;
62 decompress_buffer_size=0;
63 decompress_buffer_filled=0;
71 int AudioOMX::init(UCHAR tstreamType) {
76 streamType = tstreamType;
78 if (!initAllParams()) {
85 decompress_buffer_size=20000;
86 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
87 decompress_buffer_filled=0;
92 av_log_set_flags(AV_LOG_SKIP_REPEATED);
94 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
95 if (ac3codec_libav == NULL) {
96 Log::getInstance()->log("Audio", Log::DEBUG,
97 "Find libav ac3 decoder failed");
101 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
102 if (mp23codec_libav == NULL) {
103 Log::getInstance()->log("Audio", Log::DEBUG,
104 "Find libav mpeg audio decoder failed");
108 aaclatmcodec_libav = avcodec_find_decoder(CODEC_ID_AAC_LATM);
109 if (aaclatmcodec_libav == NULL) {
110 Log::getInstance()->log("Audio", Log::DEBUG,
111 "Find libav aac latm decoder failed");
117 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
121 Log::getInstance()->log("Audio", Log::NOTICE,
122 "TV hdmi supports mpeg1 layer 1 and 2");
124 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
128 Log::getInstance()->log("Audio", Log::NOTICE,
129 "TV hdmi supports mpeg1 layer 3");
132 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
135 Log::getInstance()->log("Audio", Log::NOTICE,
136 "TV hdmi supports AC3");
138 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
142 Log::getInstance()->log("Audio", Log::NOTICE,
143 "TV hdmi supports AAC");
146 canpass_pcm_mch=false;
151 int AudioOMX::initAllParams()
153 return (setStreamType(streamType) && setChannel() && setSource());
156 int AudioOMX::shutdown()
158 if (!initted) return 0;
161 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
162 DeAllocateCodecsOMX();
164 free(decompress_buffer);
165 decompress_buffer=NULL;
166 decompress_buffer_size=0;
167 decompress_buffer_filled=0;
172 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
174 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
175 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
178 if (STRCASECMP(name, "PCM") == 0) {
180 } else if (STRCASECMP(name, "Passthrough") == 0) {
182 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
187 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
190 if (STRCASECMP(name, "PCM") == 0) {
192 } else if (STRCASECMP(name, "Passthrough") == 0) {
194 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
199 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
202 if (STRCASECMP(name, "PCM") == 0) {
204 } else if (STRCASECMP(name, "Passthrough") == 0) {
206 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
211 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
214 if (STRCASECMP(name, "PCM") == 0) {
216 } else if (STRCASECMP(name, "Passthrough") == 0) {
218 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
223 name = vdr->configLoad("AudioOMX", "AudioOutput");
226 if (STRCASECMP(name, "analog") == 0) {
228 } else if (STRCASECMP(name, "HDMI") == 0) {
238 bool AudioOMX::handleOptionChanges(Option* option)
240 if (Audio::handleOptionChanges(option))
242 switch (option->id) {
244 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
246 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
254 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
256 } else if (STRCASECMP(option->options[option->userSetChoice],
257 "Passthrough") == 0) {
259 } else if (STRCASECMP(option->options[option->userSetChoice],
260 "PCMMultichannel") == 0) {
266 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
268 } else if (STRCASECMP(option->options[option->userSetChoice],
269 "Passthrough") == 0) {
271 } else if (STRCASECMP(option->options[option->userSetChoice],
272 "PCMMultichannel") == 0) {
278 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
280 } else if (STRCASECMP(option->options[option->userSetChoice],
281 "Passthrough") == 0) {
283 } else if (STRCASECMP(option->options[option->userSetChoice],
284 "PCMMultichannel") == 0) {
290 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
292 } else if (STRCASECMP(option->options[option->userSetChoice],
293 "Passthrough") == 0) {
295 } else if (STRCASECMP(option->options[option->userSetChoice],
296 "PCMMultichannel") == 0) {
306 bool AudioOMX::saveOptionstoServer()
309 switch (prefered_ac3) {
311 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
314 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
318 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
323 switch (prefered_aac) {
325 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
328 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
332 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
337 switch (prefered_mp2) {
339 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
342 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
346 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
351 switch (prefered_mp3) {
353 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
356 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
360 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
366 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
368 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
374 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
375 UINT numChoices, UINT defaultChoice, UINT startInt,
376 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
378 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
380 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
387 static const char* audioopts[]={"analog","HDMI"};
388 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
389 options->push_back(option);
390 pane->addOptionLine(option);
393 char **ac3opts=new char *[3];
395 ac3opts[i]=new char[strlen("PCM")+1];
396 strcpy(ac3opts[i],"PCM");
399 ac3opts[i]=new char[strlen("Passthrough")+1];
400 strcpy(ac3opts[i],"PassThrough");
403 if (canpass_pcm_mch) {
404 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
405 strcpy(ac3opts[i],"PCMMultichannel");
408 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
409 options->push_back(option);
410 pane->addOptionLine(option);
412 /* char **aacopts = new char *[3];
414 aacopts[i] = new char[strlen("PCM") + 1];
415 strcpy(mp2opts[i], "PCM");
418 aacopts[i] = new char[strlen("Passthrough") + 1];
419 strcpy(aacopts[i], "PassThrough");
422 if (canpass_pcm_mch) {
423 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
424 strcpy(aacopts[i], "PCMMultichannel");
427 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
428 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
429 aacopts, NULL, true, this);
430 options->push_back(option);
431 pane->addOptionLine(option);
434 char **mp2opts = new char *[3];
436 mp2opts[i] = new char[strlen("PCM") + 1];
437 strcpy(mp2opts[i], "PCM");
440 mp2opts[i] = new char[strlen("Passthrough") + 1];
441 strcpy(mp2opts[i], "PassThrough");
444 if (canpass_pcm_mch) {
445 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
446 strcpy(mp2opts[i], "PCMMultichannel");
449 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
450 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
451 mp2opts, NULL, true, this);
452 options->push_back(option);
453 pane->addOptionLine(option);
455 char **mp3opts = new char *[3];
457 mp3opts[i] = new char[strlen("PCM") + 1];
458 strcpy(mp3opts[i], "PCM");
461 mp3opts[i] = new char[strlen("Passthrough") + 1];
462 strcpy(mp3opts[i], "PassThrough");
465 if (canpass_pcm_mch) {
466 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
467 strcpy(mp3opts[i], "PCMMultichannel");
470 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
471 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
473 options->push_back(option);
474 pane->addOptionLine(option);*/
475 // Comment unsupported modes out
488 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
490 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
491 AudioOMX *audio=(AudioOMX *)getInstance();
492 audio->ReturnEmptyOMXBuffer(buffer);
493 return OMX_ErrorNone;
497 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
498 input_bufs_omx_mutex.Lock();
499 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
500 input_bufs_omx_free.push_back(buffer);
501 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
502 input_bufs_omx_mutex.Unlock();
505 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
506 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
507 return OMX_ErrorNone;
512 int AudioOMX::setStreamType(UCHAR type)
514 if (!initted) return 0;
516 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
520 int AudioOMX::setChannel()
522 if (!initted) return 0;
524 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
528 int AudioOMX::setSource()
530 if (!initted) return 0;
532 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
538 if (!initted) return 0;
540 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
544 int AudioOMX::play() {
547 lastAType=MPTYPE_MPEG_AUDIO;
548 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
550 ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
552 if (!AllocateCodecsOMX()) {
559 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
562 const char * destinations[]={"local","hdmi"};
567 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
568 memset(&auddest,0,sizeof(auddest));
569 auddest.nSize=sizeof(auddest);
570 auddest.nVersion.nVersion=OMX_VERSION;
571 strcpy((char *)auddest.sName, destinations[dest]);
573 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
574 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
575 if (error!=OMX_ErrorNone){
576 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
577 DeAllocateCodecsOMX();
585 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
588 //Ok first fidle a working configuration
589 Log::getInstance()->log("Audio", Log::DEBUG,
590 "ChangeAudioPortConfig");
592 OMX_AUDIO_CODINGTYPE encoding;
595 case MPTYPE_MPEG_AUDIO: {
596 if (prefered_mp2 == 2 && false) { //not supported yet
599 if (prefered_mp2 == 1 && canpass_mp2) {
601 encoding=OMX_AUDIO_CodingMP3;
604 encoding=OMX_AUDIO_CodingPCM;
609 case MPTYPE_AAC_LATM: {
610 if (prefered_aac == 2 && false) { //not supported yet
613 Log::getInstance()->log("Audio", Log::DEBUG,
614 "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
615 if (prefered_aac == 1 && canpass_aac) {
617 encoding=OMX_AUDIO_CodingAAC;
620 encoding=OMX_AUDIO_CodingPCM;
625 case MPTYPE_AC3_PRE13:
627 if (prefered_ac3 == 2 && false) { //not supported yet
630 Log::getInstance()->log("Audio", Log::DEBUG,
631 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
632 if (prefered_ac3 == 1 && canpass_ac3) {
634 encoding=OMX_AUDIO_CodingDDP;
637 encoding=OMX_AUDIO_CodingPCM;
642 case MPTYPE_MPEG_AUDIO_LAYER3: {
643 if (prefered_mp3 == 2 && false) { //not supported yet
646 if (prefered_mp3 == 1 && canpass_mp2) {
648 encoding=OMX_AUDIO_CodingMP3;
651 encoding=OMX_AUDIO_CodingPCM;
659 encoding=OMX_AUDIO_CodingPCM;
660 //mch=false; // multichannel also false
665 /*OMX_CONFIG_BOOLEANTYPE booly;
666 memset(&booly, 0, sizeof(booly));
667 booly.nSize = sizeof(booly);
668 booly.nVersion.nVersion = OMX_VERSION;
670 booly.bEnabled = OMX_TRUE;
672 booly.bEnabled = OMX_FALSE;
674 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
676 if (error != OMX_ErrorNone) {
677 Log::getInstance()->log("Audio", Log::DEBUG,
678 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
679 DeAllocateCodecsOMX();
682 VideoOMX* video=(VideoOMX*)Video::getInstance();
684 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
685 //DestroyInputBufsOMXwhilePlaying();
686 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
691 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
692 memset(&format, 0, sizeof(format));
693 format.nSize = sizeof(format);
694 format.nVersion.nVersion = OMX_VERSION;
695 format.nPortIndex = omx_rend_input_port;
696 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
698 if (error != OMX_ErrorNone) {
699 Log::getInstance()->log("Audio", Log::DEBUG,
700 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
701 omx_rend_input_port);
706 Log::getInstance()->log("Audio", Log::DEBUG,
707 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
708 format.eEncoding = encoding;
710 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
712 if (error != OMX_ErrorNone) {
713 Log::getInstance()->log("Audio", Log::DEBUG,
714 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
715 omx_rend_input_port,format.eEncoding );
720 case OMX_AUDIO_CodingPCM: {
721 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
722 memset(&audio_pcm, 0, sizeof(audio_pcm));
723 audio_pcm.nSize = sizeof(audio_pcm);
724 audio_pcm.nVersion.nVersion = OMX_VERSION;
725 audio_pcm.nChannels = 2;
726 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
727 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
728 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
729 audio_pcm.eNumData = OMX_NumericalDataSigned;
730 audio_pcm.eEndian = OMX_EndianLittle;
731 audio_pcm.bInterleaved = OMX_TRUE;
732 audio_pcm.nBitPerSample = 16;
733 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
734 audio_pcm.nChannels = 2;
735 audio_pcm.nSamplingRate = 48000;
736 audio_pcm.nPortIndex = omx_rend_input_port;
737 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
739 if (error != OMX_ErrorNone) {
740 Log::getInstance()->log("Audio", Log::DEBUG,
741 "Init OMX_IndexParamAudioPcm failed %x %d", error,
742 omx_rend_input_port);
746 case OMX_AUDIO_CodingDDP: {
747 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
748 memset(&audio_ddp, 0, sizeof(audio_ddp));
749 audio_ddp.nSize = sizeof(audio_ddp);
750 audio_ddp.nVersion.nVersion = OMX_VERSION;
751 audio_ddp.nPortIndex = omx_rend_input_port;
752 audio_ddp.nChannels = 8; //unknown
753 audio_ddp.nBitRate=0;
754 audio_ddp.nSampleRate=48000;
755 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
756 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
757 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
758 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
759 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
760 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
761 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
762 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
763 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
764 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
766 if (error != OMX_ErrorNone) {
767 Log::getInstance()->log("Audio", Log::DEBUG,
768 "Init OMX_IndexParamAudioDdp failed %x %d", error,
769 omx_rend_input_port);
774 default: break; //Make compiler happy
781 //PrepareInputBufsOMX(false);
782 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
792 int AudioOMX::InitDecoderLibAV()
795 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
796 if (!ac3codec_context_libav) {
797 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
801 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
802 ac3codec_context_libav->request_channels=2;
804 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
806 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
807 libav_mutex.Unlock();
811 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
812 if (!aaclatmcodec_context_libav) {
813 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
817 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
818 aaclatmcodec_context_libav->request_channels=2;
820 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
822 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
823 libav_mutex.Unlock();
828 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
829 if (!ac3codec_context_libav) {
830 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
831 libav_mutex.Unlock();
835 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
836 mp23codec_context_libav->request_channels=2;
838 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
840 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
841 libav_mutex.Unlock();
845 av_init_packet(&incoming_paket_libav);
846 decode_frame_libav=avcodec_alloc_frame();
847 libav_mutex.Unlock();
848 decompress_buffer_filled=0;
855 void AudioOMX::DeinitDecoderLibAV() {
859 if (ac3codec_context_libav) {
860 avcodec_close(ac3codec_context_libav);
861 av_free(ac3codec_context_libav);
862 ac3codec_context_libav = NULL;
864 avcodec_close(aaclatmcodec_context_libav);
865 av_free(aaclatmcodec_context_libav);
866 aaclatmcodec_context_libav = NULL;
868 av_free(decode_frame_libav);
870 avcodec_close(mp23codec_context_libav);
871 av_free(mp23codec_context_libav);
872 mp23codec_context_libav = NULL;
875 libav_mutex.Unlock();
880 int AudioOMX::AllocateCodecsOMX()
883 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
885 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
886 //Clock, move later to audio
887 VideoOMX *video=(VideoOMX*)Video::getInstance();
889 if (!InitDecoderLibAV()) return 0;;
892 OMX_PORT_PARAM_TYPE p_param;
893 memset(&p_param,0,sizeof(p_param));
894 p_param.nSize=sizeof(p_param);
895 p_param.nVersion.nVersion=OMX_VERSION;
898 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
899 return 0;// get the clock and init it if necessary
903 if (!video->idleClock()) {
908 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
909 if (error != OMX_ErrorNone) {
910 Log::getInstance()->log("Audio", Log::DEBUG,
911 "Init OMX audio rend failed %x", error);
912 video->UnlockClock();
913 DeAllocateCodecsOMX();
917 if (!ChangeAudioDestination()) {
918 video->UnlockClock();
919 DeAllocateCodecsOMX();
923 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
924 if (error != OMX_ErrorNone) {
925 Log::getInstance()->log("Audio", Log::DEBUG,
926 "Init OMX audio rend OMX_GetParameter failed %x", error);
927 video->UnlockClock();
928 DeAllocateCodecsOMX();
931 omx_rend_input_port = p_param.nStartPortNumber;
933 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
934 if (error != OMX_ErrorNone) {
935 Log::getInstance()->log("Audio", Log::DEBUG,
936 "Init OMX aud rend OMX_GetParameter failed %x", error);
937 video->UnlockClock();
938 DeAllocateCodecsOMX();
941 // buggy return value
942 omx_rend_clock_port = p_param.nStartPortNumber;
945 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
947 if (error!=OMX_ErrorNone){
948 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
949 video->UnlockClock();
950 DeAllocateCodecsOMX();
954 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
955 if (error!=OMX_ErrorNone){
956 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
957 video->UnlockClock();
958 DeAllocateCodecsOMX();
961 omx_codec_input_port=p_param.nStartPortNumber;
962 omx_codec_output_port=p_param.nStartPortNumber+1;
964 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
965 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
966 video->UnlockClock();
967 DeAllocateCodecsOMX();
974 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
975 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
976 video->UnlockClock();
977 DeAllocateCodecsOMX();
981 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
982 Log::getInstance()->log("Audio", Log::DEBUG,
983 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
984 video->UnlockClock();
985 DeAllocateCodecsOMX();
995 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
996 if (error!=OMX_ErrorNone){
997 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);
998 video->UnlockClock();
999 DeAllocateCodecsOMX();
1003 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1005 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1006 video->UnlockClock();
1007 DeAllocateCodecsOMX();
1011 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1012 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1013 video->UnlockClock();
1014 DeAllocateCodecsOMX();
1021 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1022 video->UnlockClock();
1023 DeAllocateCodecsOMX();
1027 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1028 video->UnlockClock();
1029 DeAllocateCodecsOMX();
1035 if (!ChangeAudioPortConfig(false)){
1036 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1037 video->UnlockClock();
1038 DeAllocateCodecsOMX();
1042 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1043 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1044 DeAllocateCodecsOMX();
1050 if (!PrepareInputBufsOMX(true)) {
1051 video->UnlockClock();
1052 DeAllocateCodecsOMX();
1058 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1059 if (error!=OMX_ErrorNone){
1060 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1061 video->UnlockClock();
1062 DeAllocateCodecsOMX();
1068 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1070 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1071 video->UnlockClock();
1072 DeAllocateCodecsOMX();
1076 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1077 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1078 video->UnlockClock();
1079 DeAllocateCodecsOMX();
1083 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1084 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1085 video->UnlockClock();
1086 DeAllocateCodecsOMX();
1091 video->UnlockClock();
1094 video->clockUnpause();
1097 if (!video->setClockExecutingandRunning()) return 0;
1099 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1107 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1109 VideoOMX *video=(VideoOMX*)Video::getInstance();
1110 OMX_ERRORTYPE error;
1111 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1112 memset(&port_def_type,0,sizeof(port_def_type));
1113 port_def_type.nSize=sizeof(port_def_type);
1114 port_def_type.nVersion.nVersion=OMX_VERSION;
1115 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1117 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1119 if (error!=OMX_ErrorNone){
1120 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1125 port_def_type.nBufferCountActual=2;
1126 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1128 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1130 if (error!=OMX_ErrorNone){
1131 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1136 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1137 if (error!=OMX_ErrorNone){
1138 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1142 input_bufs_omx_mutex.Lock();
1143 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1144 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1145 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1146 if (error!=OMX_ErrorNone){
1147 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1148 input_bufs_omx_mutex.Unlock();
1151 input_bufs_omx_all.push_back(buf_head);
1152 input_bufs_omx_free.push_back(buf_head);
1154 omx_first_frame=true;
1157 cur_input_buf_omx=NULL;
1158 input_bufs_omx_mutex.Unlock();
1160 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1167 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1169 OMX_ERRORTYPE error;
1171 cur_input_buf_omx=NULL;
1172 input_bufs_omx_mutex.Lock();
1173 for (int i=0; i< input_bufs_omx_all.size();i++) {
1174 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1175 if (error!=OMX_ErrorNone){
1176 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1177 input_bufs_omx_mutex.Unlock();
1182 input_bufs_omx_all.clear();
1183 input_bufs_omx_free.clear();
1184 input_bufs_omx_mutex.Unlock();
1188 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1190 OMX_ERRORTYPE error;
1192 cur_input_buf_omx=NULL;
1193 input_bufs_omx_mutex.Lock();
1194 while (input_bufs_omx_all.size()>0) {
1195 if (input_bufs_omx_free.size()>0) {
1196 // Destroy one buffer
1197 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1198 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1199 for (; itty!= input_bufs_omx_all.end();itty++) {
1200 if ((*itty)==cur_buf) {
1201 input_bufs_omx_all.erase(itty);
1202 input_bufs_omx_free.pop_front();
1207 input_bufs_omx_mutex.Unlock();
1209 input_bufs_omx_mutex.Lock();
1213 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1214 input_bufs_omx_mutex.Unlock();
1219 int AudioOMX::DeAllocateCodecsOMX()
1221 OMX_ERRORTYPE error;
1223 VideoOMX *video=(VideoOMX*)Video::getInstance();
1224 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1228 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1229 if (cur_input_buf_omx) {
1230 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1231 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1232 if (error!=OMX_ErrorNone) {
1233 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1236 cur_input_buf_omx=NULL;//write out old data
1238 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1241 if (omx_aud_rend/*dec*/) {
1242 // first stop the omx elements
1243 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1244 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1246 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1248 video->UnlockClock();
1249 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1251 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1254 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1255 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1258 // TODO proper deinit sequence
1259 // first flush all buffers
1261 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1262 if (error!=OMX_ErrorNone) {
1263 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1267 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1268 if (error!=OMX_ErrorNone){
1269 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1274 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1275 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1280 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1281 if (error!=OMX_ErrorNone){
1282 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1286 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1287 if (error!=OMX_ErrorNone){
1288 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1291 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1293 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1294 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1295 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1298 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1299 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1300 DeinitDecoderLibAV();
1301 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1304 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1305 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1308 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1309 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1312 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1313 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1317 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1318 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1321 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1322 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1327 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1328 if (error!=OMX_ErrorNone) {
1329 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1335 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1336 if (error!=OMX_ErrorNone) {
1337 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1341 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1342 if (error!=OMX_ErrorNone) {
1343 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1347 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1348 if (error!=OMX_ErrorNone) {
1349 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1352 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1355 //error=OMX_FreeHandle(omx_aud_dec);
1356 error=OMX_FreeHandle(omx_aud_rend);
1357 video->UnlockClock();
1358 video->destroyClock();
1359 omx_aud_rend/*dec*/=NULL;
1360 if (error!=OMX_ErrorNone) {
1361 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1365 video->UnlockClock();
1366 DeinitDecoderLibAV();
1368 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1375 int AudioOMX::stop()
1377 if (!initted) return 0;
1379 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1380 DeAllocateCodecsOMX();
1381 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1385 int AudioOMX::mute() {
1388 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1390 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1392 OMX_AUDIO_CONFIG_MUTETYPE amute;
1393 memset(&amute, 0, sizeof(amute));
1394 amute.nSize = sizeof(amute);
1395 amute.nVersion.nVersion = OMX_VERSION;
1396 amute.nPortIndex = omx_rend_input_port;
1397 amute.bMute = OMX_TRUE;
1398 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1400 if (error != OMX_ErrorNone) {
1401 Log::getInstance()->log("Audio", Log::DEBUG,
1402 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1403 omx_rend_input_port);
1413 int AudioOMX::unMute()
1415 if (!initted) return 0;
1417 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1419 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1421 OMX_AUDIO_CONFIG_MUTETYPE amute;
1422 memset(&amute, 0, sizeof(amute));
1423 amute.nSize = sizeof(amute);
1424 amute.nVersion.nVersion = OMX_VERSION;
1425 amute.nPortIndex = omx_rend_input_port;
1426 amute.bMute = OMX_FALSE;
1427 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1429 if (error != OMX_ErrorNone) {
1430 Log::getInstance()->log("Audio", Log::DEBUG,
1431 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1432 omx_rend_input_port);
1442 int AudioOMX::pause() {
1446 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1452 int AudioOMX::unPause()
1454 if (!initted) return 0;
1456 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1463 int AudioOMX::reset()
1465 if (!initted) return 0;
1467 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1468 DeAllocateCodecsOMX();
1470 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1471 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1472 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1478 int AudioOMX::setVolume(int tvolume)
1480 // parameter: 0 for silence, 20 for full
1481 if ((tvolume < 0) || (tvolume > 20)) return 0;
1483 // volume = 2 * (20 - volume);
1484 // Right, that one was rubbish... 0-10 were almost
1485 // inaudible, 11-20 did what should have been done
1486 // over the whole 0-20 range
1492 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1494 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1495 memset(&avol, 0, sizeof(avol));
1496 avol.nSize = sizeof(avol);
1497 avol.nVersion.nVersion = OMX_VERSION;
1498 avol.nPortIndex = omx_rend_input_port;
1499 avol.bLinear=OMX_FALSE;
1500 avol.sVolume.nValue =(volume-20)*200;
1501 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1503 if (error != OMX_ErrorNone) {
1504 Log::getInstance()->log("Audio", Log::DEBUG,
1505 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1506 omx_rend_input_port);
1516 int AudioOMX::test()
1519 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1521 /* aud_sync_parms_t a;
1525 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1528 /*OK*/ //printf("Audio sync disable = %i\n", b);
1536 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1538 if (size<=2) return size; // silly;
1539 unsigned int test=0;
1541 while (test+1<size) {
1542 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1548 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1550 if (size<=4) return size; // silly;
1551 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1552 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1553 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1554 1152, 1280, 1280, };
1555 unsigned int test=0;
1556 *framesize=20000; //if we do not find a start code do not decompress
1557 while (test+4<size) {
1558 if (data[test]==0x0B && data[test+1]==0x77) {
1559 // now figure out the length of the frame
1560 unsigned char code=data[test+4];
1561 unsigned char fscod=(code& 0xC0)>>6;
1562 unsigned char frmsize=(code &0x3f);
1563 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1564 *framesize=frm_size_tab[frmsize]*2;
1565 return test; // probably FrameSync
1572 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1574 if (size<=4) return size; // silly;
1575 unsigned int test=0;
1576 *framesize=20000; //if we do not find a start code do not decompress
1577 while (test+4<size) {
1578 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1579 // now figure out the length of the frame
1580 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1582 return test; // probably FrameSync
1590 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1592 packet = mplist.front();
1595 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1596 DeliverMediaPacket(packet, buffer, samplepos);
1597 if (*samplepos == packet.length) {
1605 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1607 VideoOMX *video = (VideoOMX*) Video::getInstance();
1609 OMX_PARAM_U32TYPE audio_lat;
1610 OMX_ERRORTYPE error;
1611 memset(&audio_lat, 0, sizeof(audio_lat));
1612 audio_lat.nSize = sizeof(audio_lat);
1613 audio_lat.nVersion.nVersion = OMX_VERSION;
1614 audio_lat.nPortIndex = omx_rend_input_port;
1616 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1618 video->UnlockClock();
1619 if (error != OMX_ErrorNone) {
1620 Log::getInstance()->log("Audio", Log::DEBUG,
1621 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1622 omx_rend_input_port);
1623 return pts; // no correction in case of error
1625 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1628 long long workpts=0;
1629 workpts+=addsamples;
1630 workpts-=audio_lat.nU32;
1631 workpts*=10LL*1000LL*1000LL;
1632 workpts=workpts/((long long)srate); //one second /samplerate
1640 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1642 /*First Check, if we have an audio sample*/
1643 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1645 OMX_ERRORTYPE error;
1646 Log *logger=Log::getInstance();
1647 if (vw->InIframemode()) {
1650 return 0; //Not in iframe mode!
1653 if (!omx_running) return 0; // if we are not runnig do not do this
1654 if (vw->isClockPaused()) return 0; //Block if we pause
1655 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1657 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1659 /* if (packet.synched && packet.presentation_time <= 0) {
1660 *samplepos = packet.length;
1661 firstsynched = false;
1663 Log::getInstance()->log("Audio", Log::DEBUG,
1664 "DeliverMediaPacketOMX Frameskip");
1665 return packet.length;
1668 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1670 UINT headerstrip = 0;
1671 if (packet.disconti) {
1672 firstsynched = false;
1673 decompress_buffer_filled=0;
1674 if (cur_input_buf_omx) {
1675 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1677 if (error != OMX_ErrorNone) {
1678 Log::getInstance()->log("Audio", Log::DEBUG,
1679 "OMX_EmptyThisBuffer 1 failed %x", error);
1681 cur_input_buf_omx = NULL;
1685 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1686 if (packet.type != lastAType) {//Format Change //Push data out !
1687 firstsynched = false;
1689 Log::getInstance()->log("Audio", Log::DEBUG,"Notice audio type change %d %d", packet.type,lastAType);
1690 lastAType = packet.type;
1691 decompress_buffer_filled=0;
1693 if (cur_input_buf_omx) {
1694 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1696 if (error != OMX_ErrorNone) {
1697 Log::getInstance()->log("Audio", Log::DEBUG,
1698 "OMX_EmptyThisBuffer 2 failed %x", error);
1700 cur_input_buf_omx = NULL;
1705 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1706 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1708 if (!ChangeAudioPortConfig(true)) {
1709 Log::getInstance()->log("Audio", Log::DEBUG,
1710 "Changing audio port config failed", error);
1713 pthread_setcancelstate(oldcancelstate, NULL);
1714 pthread_setcanceltype(oldcanceltype, NULL);
1718 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1720 /*Inspect PES-Header */
1721 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1722 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1723 if (packet.type == MPTYPE_AC3)
1724 headerstrip += 4; //skip ac3 bytes
1725 *samplepos += headerstrip;
1726 if (packet.synched) {
1727 if (cur_input_buf_omx) {
1728 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1729 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1731 if (error != OMX_ErrorNone) {
1732 Log::getInstance()->log("Audio", Log::DEBUG,
1733 "OMX_EmptyThisBuffer 3 failed %x", error);
1735 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1737 cur_input_buf_omx = NULL;//write out old data
1739 firstsynched = true;
1740 //decompress_buffer_filled=0;
1742 if (!firstsynched) {//
1743 *samplepos = packet.length;//if we have not processed at least one
1744 decompress_buffer_filled=0;
1745 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1746 return packet.length;//synched packet ignore it!
1750 if (!cur_input_buf_omx) {
1751 input_bufs_omx_mutex.Lock();
1752 if (input_bufs_omx_free.size()==0) {
1753 input_bufs_omx_mutex.Unlock();
1754 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1755 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1756 return 0; // we do not have a free media sample
1759 cur_input_buf_omx=input_bufs_omx_free.front();
1760 cur_input_buf_omx->nFilledLen=0;
1761 cur_input_buf_omx->nOffset=0;
1762 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1763 input_bufs_omx_free.pop_front();
1764 input_bufs_omx_mutex.Unlock();
1766 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1768 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1769 if (packet.synched) {
1770 //Log::getInstance()->log("Audio", Log::DEBUG,
1771 // "packet synched marker");
1773 //lastreftimePTS=packet.pts;
1774 if (omx_first_frame) { // TODO time
1775 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1776 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1777 omx_first_frame = false;
1779 cur_input_buf_omx->nFlags = 0;
1780 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1782 lastreftimeOMX = packet.presentation_time;
1783 //Log::getInstance()->log("Audio", Log::DEBUG,
1784 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1785 lastreftimePTS = packet.pts;
1786 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1788 // Log::getInstance()->log("Audio", Log::DEBUG,
1789 // "packet NOT synched marker");
1790 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1791 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1794 if (packet.disconti || achange) {
1795 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1796 //mp23codec_context_libav->frame_size=-1;
1797 //ac3codec_context_libav->frame_size=-1;
1801 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1803 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1804 unsigned int haveToCopy=packet.length-*samplepos;
1807 while (haveToCopy>0) {
1808 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1810 unsigned int gotframesize=0;
1812 switch (packet.type) {
1813 case MPTYPE_MPEG_AUDIO:
1814 case MPTYPE_MPEG_AUDIO_LAYER3: {
1815 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1816 haveToCopy,&gotframesize);
1820 case MPTYPE_AC3_PRE13: {
1821 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1822 haveToCopy,&gotframesize);
1826 case MPTYPE_AAC_LATM: {
1827 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1828 haveToCopy,&gotframesize);
1832 if (adv!=haveToCopy) {
1837 *samplepos=packet.length; //no ac3 sync byte
1838 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
1839 return packet.length;
1842 // so everything is fine now do a memcpy
1843 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1844 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1845 haveToCopy-=cancopy;
1846 cur_input_buf_omx->nFilledLen+=cancopy;
1847 *samplepos+=cancopy;
1848 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
1850 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1851 if (error != OMX_ErrorNone) {
1852 Log::getInstance()->log("Audio", Log::DEBUG,
1853 "OMX_EmptyThisBuffer 5 failed %x", error);
1855 cur_input_buf_omx=NULL;
1858 input_bufs_omx_mutex.Lock();
1859 if (input_bufs_omx_free.size()==0) {
1860 input_bufs_omx_mutex.Unlock();
1861 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
1862 return *samplepos; // we do not have a free media sample
1864 cur_input_buf_omx=input_bufs_omx_free.front();
1865 cur_input_buf_omx->nFilledLen=0;
1866 cur_input_buf_omx->nOffset=0;
1867 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1868 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1869 input_bufs_omx_free.pop_front();
1870 input_bufs_omx_mutex.Unlock();
1872 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
1875 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
1883 AVCodecContext *current_context;
1884 switch (packet.type) {
1885 case MPTYPE_MPEG_AUDIO:
1886 case MPTYPE_MPEG_AUDIO_LAYER3: {
1887 current_context = mp23codec_context_libav;
1888 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1889 else framesize=current_context->frame_size;
1891 case MPTYPE_AAC_LATM: {
1892 current_context = aaclatmcodec_context_libav;
1895 case MPTYPE_AC3_PRE13: {
1896 current_context = ac3codec_context_libav;
1900 if (decompress_buffer_filled) { // have a remaining paket
1901 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1902 memcpy(decompress_buffer+decompress_buffer_filled,
1903 buffer+packet.pos_buffer+*samplepos,
1904 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1905 incoming_paket_libav.size = decompress_buffer_filled
1906 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1907 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1909 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1910 incoming_paket_libav.size = haveToCopy;
1912 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
1914 while (haveToCopy> 0 && errcount<3) {
1916 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1917 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1918 // framesize, current_context->frame_size);
1920 bool donotdecompress=false;
1921 unsigned int gotframesize=0;
1922 if (!decompress_buffer_filled) { // only do this if no old data is present
1924 switch (packet.type) {
1925 case MPTYPE_MPEG_AUDIO:
1926 case MPTYPE_MPEG_AUDIO_LAYER3: {
1927 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1928 incoming_paket_libav.size,&gotframesize);
1932 case MPTYPE_AC3_PRE13: {
1933 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1934 incoming_paket_libav.size,&gotframesize);
1937 case MPTYPE_AAC_LATM: {
1938 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
1939 incoming_paket_libav.size,&gotframesize);
1944 incoming_paket_libav.data += adv;
1945 incoming_paket_libav.size-=adv;
1948 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1949 else*/ framesize=haveToCopy;
1950 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1951 if (haveToCopy <= 0) {
1952 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1953 *samplepos=packet.length;
1954 return packet.length;
1960 if (gotframesize>0 && gotframesize>haveToCopy) {
1961 donotdecompress=true;
1962 errcount=100; // exit loop
1964 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1966 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
1967 if (!donotdecompress) {
1970 pthread_testcancel();
1971 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1972 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1974 if (!omx_running || !mp23codec_context_libav
1975 || !ac3codec_context_libav) {
1976 libav_mutex.Unlock();
1979 libav_mutex.Unlock();
1980 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1981 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1982 &gotta, &incoming_paket_libav);
1983 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1984 pthread_setcancelstate(oldcancelstate, NULL);
1985 pthread_setcanceltype(oldcanceltype, NULL);
1986 pthread_testcancel();
1992 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1993 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
1995 libav_mutex.Unlock();
1999 if (decompress_buffer_filled) { // reset to normal decoding
2001 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2002 haveToCopy -= min(len-decompress_buffer_filled,0);
2003 *samplepos += min(len-decompress_buffer_filled,0);
2004 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2005 /*else*/ framesize=haveToCopy;
2007 framesize=haveToCopy;
2009 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2011 decompress_buffer_filled=0;
2015 incoming_paket_libav.data += len;
2019 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2020 else*/framesize=haveToCopy;
2023 framesize=haveToCopy;
2026 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2028 incoming_paket_libav.size =framesize;
2030 //Log::getInstance()->log("Audio", Log::DEBUG,
2032 int dsize = av_samples_get_buffer_size(NULL,
2033 current_context->channels, decode_frame_libav->nb_samples,
2034 current_context->sample_fmt, 1);
2035 if ((cur_input_buf_omx->nFilledLen + dsize)
2036 > cur_input_buf_omx->nAllocLen ) {
2037 // I doubt that this will ever happen
2038 // Log::getInstance()->log("Audio", Log::DEBUG,
2039 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2040 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2042 if (error != OMX_ErrorNone) {
2043 Log::getInstance()->log("Audio", Log::DEBUG,
2044 "OMX_EmptyThisBuffer 4 failed %x", error);
2046 cur_input_buf_omx = NULL;
2048 if (!cur_input_buf_omx) {
2050 while (count < 10 && omx_running) {
2052 input_bufs_omx_mutex.Lock();
2053 if (input_bufs_omx_free.size() == 0) {
2054 input_bufs_omx_mutex.Unlock();
2055 // Log::getInstance()->log("Audio", Log::DEBUG,
2056 // "Deliver MediaPacket no free sample");
2058 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2059 if (!omx_running) return *samplepos;
2060 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2063 cur_input_buf_omx = input_bufs_omx_free.front();
2064 cur_input_buf_omx->nFilledLen = 0;
2065 cur_input_buf_omx->nOffset = 0;
2066 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2067 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2068 input_bufs_omx_free.pop_front();
2069 input_bufs_omx_mutex.Unlock();
2072 if (!cur_input_buf_omx) return *samplepos;
2077 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2078 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2079 decode_frame_libav->data[0], dsize);
2080 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2081 cur_input_buf_omx->nFilledLen += dsize;
2083 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2084 /* uint8_t a1=incoming_paket_libav.data[0];
2085 uint8_t a2=incoming_paket_libav.data[1];
2086 uint8_t a3=incoming_paket_libav.data[2];
2087 uint8_t a4=incoming_paket_libav.data[3];*/
2088 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2093 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2094 decompress_buffer_filled=0;
2096 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);
2097 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2099 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2103 if (cur_input_buf_omx->nFilledLen) {
2104 //Log::getInstance()->log("Audio", Log::DEBUG,
2105 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2106 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2107 if (error != OMX_ErrorNone) {
2108 Log::getInstance()->log("Audio", Log::DEBUG,
2109 "OMX_EmptyThisBuffer 5 failed %x", error);
2111 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2112 cur_input_buf_omx = NULL;
2117 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2119 *samplepos=packet.length;
2120 return packet.length;
2126 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2127 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2128 return vw->SetStartAudioOffset(curreftime,rsync);
2131 void AudioOMX::ResetTimeOffsets() {
2132 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2133 vw->ResetTimeOffsets();