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"
35 lastAType = MPTYPE_MPEG_AUDIO;
41 canpass_pcm_mch=false;
43 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
51 omx_aud_rend/*dec*/=0;
52 cur_input_buf_omx=NULL;
55 ac3codec_context_libav=NULL;
58 mp23codec_context_libav=NULL;
60 decompress_buffer=NULL;
61 decompress_buffer_size=0;
62 decompress_buffer_filled=0;
70 int AudioOMX::init(UCHAR tstreamType) {
75 streamType = tstreamType;
77 if (!initAllParams()) {
84 decompress_buffer_size=20000;
85 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
86 decompress_buffer_filled=0;
91 av_log_set_flags(AV_LOG_SKIP_REPEATED);
93 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
94 if (ac3codec_libav == NULL) {
95 Log::getInstance()->log("Audio", Log::DEBUG,
96 "Find libav ac3 decoder failed");
100 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
101 if (mp23codec_libav == NULL) {
102 Log::getInstance()->log("Audio", Log::DEBUG,
103 "Find libav mpeg audio decoder failed");
107 aaclatmcodec_libav = avcodec_find_decoder(CODEC_ID_AAC_LATM);
108 if (aaclatmcodec_libav == NULL) {
109 Log::getInstance()->log("Audio", Log::DEBUG,
110 "Find libav aac latm decoder failed");
116 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
120 Log::getInstance()->log("Audio", Log::NOTICE,
121 "TV hdmi supports mpeg1 layer 1 and 2");
123 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
127 Log::getInstance()->log("Audio", Log::NOTICE,
128 "TV hdmi supports mpeg1 layer 3");
131 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
134 Log::getInstance()->log("Audio", Log::NOTICE,
135 "TV hdmi supports AC3");
137 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
141 Log::getInstance()->log("Audio", Log::NOTICE,
142 "TV hdmi supports AAC");
145 canpass_pcm_mch=false;
150 int AudioOMX::initAllParams()
152 return (setStreamType(streamType) && setChannel() && setSource());
155 int AudioOMX::shutdown()
157 if (!initted) return 0;
160 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
161 DeAllocateCodecsOMX();
163 free(decompress_buffer);
164 decompress_buffer=NULL;
165 decompress_buffer_size=0;
166 decompress_buffer_filled=0;
171 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
173 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
174 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
177 if (STRCASECMP(name, "PCM") == 0) {
179 } else if (STRCASECMP(name, "Passthrough") == 0) {
181 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
186 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
189 if (STRCASECMP(name, "PCM") == 0) {
191 } else if (STRCASECMP(name, "Passthrough") == 0) {
193 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
198 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
201 if (STRCASECMP(name, "PCM") == 0) {
203 } else if (STRCASECMP(name, "Passthrough") == 0) {
205 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
210 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
213 if (STRCASECMP(name, "PCM") == 0) {
215 } else if (STRCASECMP(name, "Passthrough") == 0) {
217 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
222 name = vdr->configLoad("AudioOMX", "AudioOutput");
225 if (STRCASECMP(name, "analog") == 0) {
227 } else if (STRCASECMP(name, "HDMI") == 0) {
237 bool AudioOMX::handleOptionChanges(Option* option)
239 if (Audio::handleOptionChanges(option))
241 switch (option->id) {
243 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
245 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
253 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
255 } else if (STRCASECMP(option->options[option->userSetChoice],
256 "Passthrough") == 0) {
258 } else if (STRCASECMP(option->options[option->userSetChoice],
259 "PCMMultichannel") == 0) {
265 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
267 } else if (STRCASECMP(option->options[option->userSetChoice],
268 "Passthrough") == 0) {
270 } else if (STRCASECMP(option->options[option->userSetChoice],
271 "PCMMultichannel") == 0) {
277 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
279 } else if (STRCASECMP(option->options[option->userSetChoice],
280 "Passthrough") == 0) {
282 } else if (STRCASECMP(option->options[option->userSetChoice],
283 "PCMMultichannel") == 0) {
289 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
291 } else if (STRCASECMP(option->options[option->userSetChoice],
292 "Passthrough") == 0) {
294 } else if (STRCASECMP(option->options[option->userSetChoice],
295 "PCMMultichannel") == 0) {
305 bool AudioOMX::saveOptionstoServer()
308 switch (prefered_ac3) {
310 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
313 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
317 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
322 switch (prefered_aac) {
324 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
327 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
331 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
336 switch (prefered_mp2) {
338 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
341 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
345 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
350 switch (prefered_mp3) {
352 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
355 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
359 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
365 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
367 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
373 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
374 UINT numChoices, UINT defaultChoice, UINT startInt,
375 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
377 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
379 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
386 static const char* audioopts[]={"analog","HDMI"};
387 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
388 options->push_back(option);
389 pane->addOptionLine(option);
392 char **ac3opts=new char *[3];
394 ac3opts[i]=new char[strlen("PCM")+1];
395 strcpy(ac3opts[i],"PCM");
398 ac3opts[i]=new char[strlen("Passthrough")+1];
399 strcpy(ac3opts[i],"PassThrough");
402 if (canpass_pcm_mch) {
403 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
404 strcpy(ac3opts[i],"PCMMultichannel");
407 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
408 options->push_back(option);
409 pane->addOptionLine(option);
411 /* char **aacopts = new char *[3];
413 aacopts[i] = new char[strlen("PCM") + 1];
414 strcpy(mp2opts[i], "PCM");
417 aacopts[i] = new char[strlen("Passthrough") + 1];
418 strcpy(aacopts[i], "PassThrough");
421 if (canpass_pcm_mch) {
422 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
423 strcpy(aacopts[i], "PCMMultichannel");
426 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
427 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
428 aacopts, NULL, true, this);
429 options->push_back(option);
430 pane->addOptionLine(option);
433 char **mp2opts = new char *[3];
435 mp2opts[i] = new char[strlen("PCM") + 1];
436 strcpy(mp2opts[i], "PCM");
439 mp2opts[i] = new char[strlen("Passthrough") + 1];
440 strcpy(mp2opts[i], "PassThrough");
443 if (canpass_pcm_mch) {
444 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
445 strcpy(mp2opts[i], "PCMMultichannel");
448 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
449 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
450 mp2opts, NULL, true, this);
451 options->push_back(option);
452 pane->addOptionLine(option);
454 char **mp3opts = new char *[3];
456 mp3opts[i] = new char[strlen("PCM") + 1];
457 strcpy(mp3opts[i], "PCM");
460 mp3opts[i] = new char[strlen("Passthrough") + 1];
461 strcpy(mp3opts[i], "PassThrough");
464 if (canpass_pcm_mch) {
465 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
466 strcpy(mp3opts[i], "PCMMultichannel");
469 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
470 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
472 options->push_back(option);
473 pane->addOptionLine(option);*/
474 // Comment unsupported modes out
487 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
489 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
490 AudioOMX *audio=(AudioOMX *)getInstance();
491 audio->ReturnEmptyOMXBuffer(buffer);
492 return OMX_ErrorNone;
496 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
497 input_bufs_omx_mutex.Lock();
498 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
499 input_bufs_omx_free.push_back(buffer);
500 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
501 input_bufs_omx_mutex.Unlock();
504 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
505 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
506 return OMX_ErrorNone;
511 int AudioOMX::setStreamType(UCHAR type)
513 if (!initted) return 0;
515 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
519 int AudioOMX::setChannel()
521 if (!initted) return 0;
523 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
527 int AudioOMX::setSource()
529 if (!initted) return 0;
531 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
537 if (!initted) return 0;
539 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
543 int AudioOMX::play() {
546 lastAType=MPTYPE_MPEG_AUDIO;
547 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
549 ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
551 if (!AllocateCodecsOMX()) {
558 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
561 const char * destinations[]={"local","hdmi"};
566 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
567 memset(&auddest,0,sizeof(auddest));
568 auddest.nSize=sizeof(auddest);
569 auddest.nVersion.nVersion=OMX_VERSION;
570 strcpy((char *)auddest.sName, destinations[dest]);
572 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
573 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
574 if (error!=OMX_ErrorNone){
575 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
576 DeAllocateCodecsOMX();
584 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
587 //Ok first fidle a working configuration
588 Log::getInstance()->log("Audio", Log::DEBUG,
589 "ChangeAudioPortConfig");
591 OMX_AUDIO_CODINGTYPE encoding;
594 case MPTYPE_MPEG_AUDIO: {
595 if (prefered_mp2 == 2 && false) { //not supported yet
598 if (prefered_mp2 == 1 && canpass_mp2) {
600 encoding=OMX_AUDIO_CodingMP3;
603 encoding=OMX_AUDIO_CodingPCM;
608 case MPTYPE_AAC_LATM: {
609 if (prefered_aac == 2 && false) { //not supported yet
612 Log::getInstance()->log("Audio", Log::DEBUG,
613 "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
614 if (prefered_aac == 1 && canpass_aac) {
616 encoding=OMX_AUDIO_CodingAAC;
619 encoding=OMX_AUDIO_CodingPCM;
624 case MPTYPE_AC3_PRE13:
626 if (prefered_ac3 == 2 && false) { //not supported yet
629 Log::getInstance()->log("Audio", Log::DEBUG,
630 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
631 if (prefered_ac3 == 1 && canpass_ac3) {
633 encoding=OMX_AUDIO_CodingDDP;
636 encoding=OMX_AUDIO_CodingPCM;
641 case MPTYPE_MPEG_AUDIO_LAYER3: {
642 if (prefered_mp3 == 2 && false) { //not supported yet
645 if (prefered_mp3 == 1 && canpass_mp2) {
647 encoding=OMX_AUDIO_CodingMP3;
650 encoding=OMX_AUDIO_CodingPCM;
658 encoding=OMX_AUDIO_CodingPCM;
659 //mch=false; // multichannel also false
664 /*OMX_CONFIG_BOOLEANTYPE booly;
665 memset(&booly, 0, sizeof(booly));
666 booly.nSize = sizeof(booly);
667 booly.nVersion.nVersion = OMX_VERSION;
669 booly.bEnabled = OMX_TRUE;
671 booly.bEnabled = OMX_FALSE;
673 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
675 if (error != OMX_ErrorNone) {
676 Log::getInstance()->log("Audio", Log::DEBUG,
677 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
678 DeAllocateCodecsOMX();
681 VideoOMX* video=(VideoOMX*)Video::getInstance();
683 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
684 //DestroyInputBufsOMXwhilePlaying();
685 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
690 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
691 memset(&format, 0, sizeof(format));
692 format.nSize = sizeof(format);
693 format.nVersion.nVersion = OMX_VERSION;
694 format.nPortIndex = omx_rend_input_port;
695 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
697 if (error != OMX_ErrorNone) {
698 Log::getInstance()->log("Audio", Log::DEBUG,
699 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
700 omx_rend_input_port);
705 Log::getInstance()->log("Audio", Log::DEBUG,
706 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
707 format.eEncoding = encoding;
709 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
711 if (error != OMX_ErrorNone) {
712 Log::getInstance()->log("Audio", Log::DEBUG,
713 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
714 omx_rend_input_port,format.eEncoding );
719 case OMX_AUDIO_CodingPCM: {
720 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
721 memset(&audio_pcm, 0, sizeof(audio_pcm));
722 audio_pcm.nSize = sizeof(audio_pcm);
723 audio_pcm.nVersion.nVersion = OMX_VERSION;
724 audio_pcm.nChannels = 2;
725 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
726 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
727 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
728 audio_pcm.eNumData = OMX_NumericalDataSigned;
729 audio_pcm.eEndian = OMX_EndianLittle;
730 audio_pcm.bInterleaved = OMX_TRUE;
731 audio_pcm.nBitPerSample = 16;
732 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
733 audio_pcm.nChannels = 2;
734 audio_pcm.nSamplingRate = 48000;
735 audio_pcm.nPortIndex = omx_rend_input_port;
736 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
738 if (error != OMX_ErrorNone) {
739 Log::getInstance()->log("Audio", Log::DEBUG,
740 "Init OMX_IndexParamAudioPcm failed %x %d", error,
741 omx_rend_input_port);
745 case OMX_AUDIO_CodingDDP: {
746 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
747 memset(&audio_ddp, 0, sizeof(audio_ddp));
748 audio_ddp.nSize = sizeof(audio_ddp);
749 audio_ddp.nVersion.nVersion = OMX_VERSION;
750 audio_ddp.nPortIndex = omx_rend_input_port;
751 audio_ddp.nChannels = 8; //unknown
752 audio_ddp.nBitRate=0;
753 audio_ddp.nSampleRate=48000;
754 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
755 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
756 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
757 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
758 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
759 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
760 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
761 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
762 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
763 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
765 if (error != OMX_ErrorNone) {
766 Log::getInstance()->log("Audio", Log::DEBUG,
767 "Init OMX_IndexParamAudioDdp failed %x %d", error,
768 omx_rend_input_port);
773 default: break; //Make compiler happy
780 //PrepareInputBufsOMX(false);
781 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
791 int AudioOMX::InitDecoderLibAV()
794 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
795 if (!ac3codec_context_libav) {
796 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
800 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
801 ac3codec_context_libav->request_channels=2;
803 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
805 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
806 libav_mutex.Unlock();
810 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
811 if (!aaclatmcodec_context_libav) {
812 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
816 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
817 aaclatmcodec_context_libav->request_channels=2;
819 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
821 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
822 libav_mutex.Unlock();
827 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
828 if (!ac3codec_context_libav) {
829 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
830 libav_mutex.Unlock();
834 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
835 mp23codec_context_libav->request_channels=2;
837 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
839 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
840 libav_mutex.Unlock();
844 av_init_packet(&incoming_paket_libav);
845 decode_frame_libav=avcodec_alloc_frame();
846 libav_mutex.Unlock();
847 decompress_buffer_filled=0;
854 void AudioOMX::DeinitDecoderLibAV() {
858 if (ac3codec_context_libav) {
859 avcodec_close(ac3codec_context_libav);
860 av_free(ac3codec_context_libav);
861 ac3codec_context_libav = NULL;
863 avcodec_close(aaclatmcodec_context_libav);
864 av_free(aaclatmcodec_context_libav);
865 aaclatmcodec_context_libav = NULL;
867 av_free(decode_frame_libav);
869 avcodec_close(mp23codec_context_libav);
870 av_free(mp23codec_context_libav);
871 mp23codec_context_libav = NULL;
874 libav_mutex.Unlock();
879 int AudioOMX::AllocateCodecsOMX()
882 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
884 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
885 //Clock, move later to audio
886 VideoOMX *video=(VideoOMX*)Video::getInstance();
888 if (!InitDecoderLibAV()) return 0;;
891 OMX_PORT_PARAM_TYPE p_param;
892 memset(&p_param,0,sizeof(p_param));
893 p_param.nSize=sizeof(p_param);
894 p_param.nVersion.nVersion=OMX_VERSION;
897 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
898 return 0;// get the clock and init it if necessary
902 if (!video->idleClock()) {
907 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
908 if (error != OMX_ErrorNone) {
909 Log::getInstance()->log("Audio", Log::DEBUG,
910 "Init OMX audio rend failed %x", error);
911 video->UnlockClock();
912 DeAllocateCodecsOMX();
916 if (!ChangeAudioDestination()) {
917 video->UnlockClock();
918 DeAllocateCodecsOMX();
922 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
923 if (error != OMX_ErrorNone) {
924 Log::getInstance()->log("Audio", Log::DEBUG,
925 "Init OMX audio rend OMX_GetParameter failed %x", error);
926 video->UnlockClock();
927 DeAllocateCodecsOMX();
930 omx_rend_input_port = p_param.nStartPortNumber;
932 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
933 if (error != OMX_ErrorNone) {
934 Log::getInstance()->log("Audio", Log::DEBUG,
935 "Init OMX aud rend OMX_GetParameter failed %x", error);
936 video->UnlockClock();
937 DeAllocateCodecsOMX();
940 // buggy return value
941 omx_rend_clock_port = p_param.nStartPortNumber;
944 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
946 if (error!=OMX_ErrorNone){
947 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
948 video->UnlockClock();
949 DeAllocateCodecsOMX();
953 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
954 if (error!=OMX_ErrorNone){
955 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
956 video->UnlockClock();
957 DeAllocateCodecsOMX();
960 omx_codec_input_port=p_param.nStartPortNumber;
961 omx_codec_output_port=p_param.nStartPortNumber+1;
963 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
964 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
965 video->UnlockClock();
966 DeAllocateCodecsOMX();
973 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
974 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
975 video->UnlockClock();
976 DeAllocateCodecsOMX();
980 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
981 Log::getInstance()->log("Audio", Log::DEBUG,
982 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
983 video->UnlockClock();
984 DeAllocateCodecsOMX();
994 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
995 if (error!=OMX_ErrorNone){
996 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);
997 video->UnlockClock();
998 DeAllocateCodecsOMX();
1002 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1004 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1005 video->UnlockClock();
1006 DeAllocateCodecsOMX();
1010 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1011 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1012 video->UnlockClock();
1013 DeAllocateCodecsOMX();
1020 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1021 video->UnlockClock();
1022 DeAllocateCodecsOMX();
1026 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1027 video->UnlockClock();
1028 DeAllocateCodecsOMX();
1034 if (!ChangeAudioPortConfig(false)){
1035 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1036 video->UnlockClock();
1037 DeAllocateCodecsOMX();
1041 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1042 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1043 DeAllocateCodecsOMX();
1049 if (!PrepareInputBufsOMX(true)) {
1050 video->UnlockClock();
1051 DeAllocateCodecsOMX();
1057 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1058 if (error!=OMX_ErrorNone){
1059 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1060 video->UnlockClock();
1061 DeAllocateCodecsOMX();
1067 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1069 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1070 video->UnlockClock();
1071 DeAllocateCodecsOMX();
1075 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1076 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1077 video->UnlockClock();
1078 DeAllocateCodecsOMX();
1082 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1083 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1084 video->UnlockClock();
1085 DeAllocateCodecsOMX();
1090 video->UnlockClock();
1093 video->clockUnpause();
1096 if (!video->setClockExecutingandRunning()) return 0;
1098 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1106 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1108 VideoOMX *video=(VideoOMX*)Video::getInstance();
1109 OMX_ERRORTYPE error;
1110 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1111 memset(&port_def_type,0,sizeof(port_def_type));
1112 port_def_type.nSize=sizeof(port_def_type);
1113 port_def_type.nVersion.nVersion=OMX_VERSION;
1114 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1116 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1118 if (error!=OMX_ErrorNone){
1119 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1124 port_def_type.nBufferCountActual=2;
1125 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1127 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1129 if (error!=OMX_ErrorNone){
1130 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1135 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1136 if (error!=OMX_ErrorNone){
1137 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1141 input_bufs_omx_mutex.Lock();
1142 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1143 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1144 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1145 if (error!=OMX_ErrorNone){
1146 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1147 input_bufs_omx_mutex.Unlock();
1150 input_bufs_omx_all.push_back(buf_head);
1151 input_bufs_omx_free.push_back(buf_head);
1153 omx_first_frame=true;
1156 cur_input_buf_omx=NULL;
1157 input_bufs_omx_mutex.Unlock();
1159 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1166 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1168 OMX_ERRORTYPE error;
1170 cur_input_buf_omx=NULL;
1171 input_bufs_omx_mutex.Lock();
1172 for (int i=0; i< input_bufs_omx_all.size();i++) {
1173 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1174 if (error!=OMX_ErrorNone){
1175 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1176 input_bufs_omx_mutex.Unlock();
1181 input_bufs_omx_all.clear();
1182 input_bufs_omx_free.clear();
1183 input_bufs_omx_mutex.Unlock();
1187 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1189 OMX_ERRORTYPE error;
1191 cur_input_buf_omx=NULL;
1192 input_bufs_omx_mutex.Lock();
1193 while (input_bufs_omx_all.size()>0) {
1194 if (input_bufs_omx_free.size()>0) {
1195 // Destroy one buffer
1196 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1197 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1198 for (; itty!= input_bufs_omx_all.end();itty++) {
1199 if ((*itty)==cur_buf) {
1200 input_bufs_omx_all.erase(itty);
1201 input_bufs_omx_free.pop_front();
1206 input_bufs_omx_mutex.Unlock();
1208 input_bufs_omx_mutex.Lock();
1212 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1213 input_bufs_omx_mutex.Unlock();
1218 int AudioOMX::DeAllocateCodecsOMX()
1220 OMX_ERRORTYPE error;
1222 VideoOMX *video=(VideoOMX*)Video::getInstance();
1223 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1227 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1228 if (cur_input_buf_omx) {
1229 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1230 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1231 if (error!=OMX_ErrorNone) {
1232 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1235 cur_input_buf_omx=NULL;//write out old data
1237 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1240 if (omx_aud_rend/*dec*/) {
1241 // first stop the omx elements
1242 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1243 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1245 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1247 video->UnlockClock();
1248 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1250 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1253 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1254 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1257 // TODO proper deinit sequence
1258 // first flush all buffers
1260 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1261 if (error!=OMX_ErrorNone) {
1262 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1266 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1267 if (error!=OMX_ErrorNone){
1268 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1273 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1274 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1279 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1280 if (error!=OMX_ErrorNone){
1281 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1285 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1286 if (error!=OMX_ErrorNone){
1287 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1290 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1292 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1293 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1294 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1297 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1298 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1299 DeinitDecoderLibAV();
1300 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1303 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1304 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1307 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1308 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1311 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1312 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1316 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1317 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1320 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1321 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1326 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1327 if (error!=OMX_ErrorNone) {
1328 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1334 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1335 if (error!=OMX_ErrorNone) {
1336 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1340 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1341 if (error!=OMX_ErrorNone) {
1342 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1346 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1347 if (error!=OMX_ErrorNone) {
1348 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1351 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1354 //error=OMX_FreeHandle(omx_aud_dec);
1355 error=OMX_FreeHandle(omx_aud_rend);
1356 video->UnlockClock();
1357 video->destroyClock();
1358 omx_aud_rend/*dec*/=NULL;
1359 if (error!=OMX_ErrorNone) {
1360 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1364 video->UnlockClock();
1365 DeinitDecoderLibAV();
1367 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1374 int AudioOMX::stop()
1376 if (!initted) return 0;
1378 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1379 DeAllocateCodecsOMX();
1380 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1384 int AudioOMX::mute() {
1387 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1389 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1391 OMX_AUDIO_CONFIG_MUTETYPE amute;
1392 memset(&amute, 0, sizeof(amute));
1393 amute.nSize = sizeof(amute);
1394 amute.nVersion.nVersion = OMX_VERSION;
1395 amute.nPortIndex = omx_rend_input_port;
1396 amute.bMute = OMX_TRUE;
1397 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1399 if (error != OMX_ErrorNone) {
1400 Log::getInstance()->log("Audio", Log::DEBUG,
1401 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1402 omx_rend_input_port);
1412 int AudioOMX::unMute()
1414 if (!initted) return 0;
1416 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1418 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1420 OMX_AUDIO_CONFIG_MUTETYPE amute;
1421 memset(&amute, 0, sizeof(amute));
1422 amute.nSize = sizeof(amute);
1423 amute.nVersion.nVersion = OMX_VERSION;
1424 amute.nPortIndex = omx_rend_input_port;
1425 amute.bMute = OMX_FALSE;
1426 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1428 if (error != OMX_ErrorNone) {
1429 Log::getInstance()->log("Audio", Log::DEBUG,
1430 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1431 omx_rend_input_port);
1441 int AudioOMX::pause() {
1445 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1451 int AudioOMX::unPause()
1453 if (!initted) return 0;
1455 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1462 int AudioOMX::reset()
1464 if (!initted) return 0;
1466 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1467 DeAllocateCodecsOMX();
1469 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1470 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1471 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1477 int AudioOMX::setVolume(int tvolume)
1479 // parameter: 0 for silence, 20 for full
1480 if ((tvolume < 0) || (tvolume > 20)) return 0;
1482 // volume = 2 * (20 - volume);
1483 // Right, that one was rubbish... 0-10 were almost
1484 // inaudible, 11-20 did what should have been done
1485 // over the whole 0-20 range
1491 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1493 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1494 memset(&avol, 0, sizeof(avol));
1495 avol.nSize = sizeof(avol);
1496 avol.nVersion.nVersion = OMX_VERSION;
1497 avol.nPortIndex = omx_rend_input_port;
1498 avol.bLinear=OMX_FALSE;
1499 avol.sVolume.nValue =(volume-20)*200;
1500 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1502 if (error != OMX_ErrorNone) {
1503 Log::getInstance()->log("Audio", Log::DEBUG,
1504 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1505 omx_rend_input_port);
1515 int AudioOMX::test()
1518 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1520 /* aud_sync_parms_t a;
1524 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1527 /*OK*/ //printf("Audio sync disable = %i\n", b);
1535 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1537 if (size<=2) return size; // silly;
1538 unsigned int test=0;
1540 while (test+1<size) {
1541 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1547 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1549 if (size<=4) return size; // silly;
1550 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1551 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1552 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1553 1152, 1280, 1280, };
1554 unsigned int test=0;
1555 *framesize=20000; //if we do not find a start code do not decompress
1556 while (test+4<size) {
1557 if (data[test]==0x0B && data[test+1]==0x77) {
1558 // now figure out the length of the frame
1559 unsigned char code=data[test+4];
1560 unsigned char fscod=(code& 0xC0)>>6;
1561 unsigned char frmsize=(code &0x3f);
1562 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1563 *framesize=frm_size_tab[frmsize]*2;
1564 return test; // probably FrameSync
1571 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1573 if (size<=4) return size; // silly;
1574 unsigned int test=0;
1575 *framesize=20000; //if we do not find a start code do not decompress
1576 while (test+4<size) {
1577 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1578 // now figure out the length of the frame
1579 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1581 return test; // probably FrameSync
1589 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1591 packet = mplist.front();
1594 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1595 DeliverMediaPacket(packet, buffer, samplepos);
1596 if (*samplepos == packet.length) {
1604 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1606 VideoOMX *video = (VideoOMX*) Video::getInstance();
1608 OMX_PARAM_U32TYPE audio_lat;
1609 OMX_ERRORTYPE error;
1610 memset(&audio_lat, 0, sizeof(audio_lat));
1611 audio_lat.nSize = sizeof(audio_lat);
1612 audio_lat.nVersion.nVersion = OMX_VERSION;
1613 audio_lat.nPortIndex = omx_rend_input_port;
1615 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1617 video->UnlockClock();
1618 if (error != OMX_ErrorNone) {
1619 Log::getInstance()->log("Audio", Log::DEBUG,
1620 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1621 omx_rend_input_port);
1622 return pts; // no correction in case of error
1624 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1627 long long workpts=0;
1628 workpts+=addsamples;
1629 workpts-=audio_lat.nU32;
1630 workpts*=10LL*1000LL*1000LL;
1631 workpts=workpts/((long long)srate); //one second /samplerate
1639 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1641 /*First Check, if we have an audio sample*/
1642 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1644 OMX_ERRORTYPE error;
1645 Log *logger=Log::getInstance();
1646 if (vw->InIframemode()) {
1649 return 0; //Not in iframe mode!
1652 if (!omx_running) return 0; // if we are not runnig do not do this
1653 if (vw->isClockPaused()) return 0; //Block if we pause
1654 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1656 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1658 /* if (packet.synched && packet.presentation_time <= 0) {
1659 *samplepos = packet.length;
1660 firstsynched = false;
1662 Log::getInstance()->log("Audio", Log::DEBUG,
1663 "DeliverMediaPacketOMX Frameskip");
1664 return packet.length;
1667 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1669 UINT headerstrip = 0;
1670 if (packet.disconti) {
1671 firstsynched = false;
1672 decompress_buffer_filled=0;
1673 if (cur_input_buf_omx) {
1674 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1676 if (error != OMX_ErrorNone) {
1677 Log::getInstance()->log("Audio", Log::DEBUG,
1678 "OMX_EmptyThisBuffer 1 failed %x", error);
1680 cur_input_buf_omx = NULL;
1684 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1685 if (packet.type != lastAType) {//Format Change //Push data out !
1686 firstsynched = false;
1688 lastAType = packet.type;
1689 decompress_buffer_filled=0;
1691 if (cur_input_buf_omx) {
1692 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1694 if (error != OMX_ErrorNone) {
1695 Log::getInstance()->log("Audio", Log::DEBUG,
1696 "OMX_EmptyThisBuffer 2 failed %x", error);
1698 cur_input_buf_omx = NULL;
1702 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1703 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1705 if (!ChangeAudioPortConfig(true)) {
1706 Log::getInstance()->log("Audio", Log::DEBUG,
1707 "Changing audio port config failed", error);
1710 pthread_setcancelstate(oldcancelstate, NULL);
1711 pthread_setcanceltype(oldcanceltype, NULL);
1715 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1717 /*Inspect PES-Header */
1718 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1719 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1720 if (packet.type == MPTYPE_AC3)
1721 headerstrip += 4; //skip ac3 bytes
1722 *samplepos += headerstrip;
1723 if (packet.synched) {
1724 if (cur_input_buf_omx) {
1725 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1726 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1728 if (error != OMX_ErrorNone) {
1729 Log::getInstance()->log("Audio", Log::DEBUG,
1730 "OMX_EmptyThisBuffer 3 failed %x", error);
1732 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1734 cur_input_buf_omx = NULL;//write out old data
1736 firstsynched = true;
1737 //decompress_buffer_filled=0;
1739 if (!firstsynched) {//
1740 *samplepos = packet.length;//if we have not processed at least one
1741 decompress_buffer_filled=0;
1742 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1743 return packet.length;//synched packet ignore it!
1747 if (!cur_input_buf_omx) {
1748 input_bufs_omx_mutex.Lock();
1749 if (input_bufs_omx_free.size()==0) {
1750 input_bufs_omx_mutex.Unlock();
1751 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1752 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1753 return 0; // we do not have a free media sample
1756 cur_input_buf_omx=input_bufs_omx_free.front();
1757 cur_input_buf_omx->nFilledLen=0;
1758 cur_input_buf_omx->nOffset=0;
1759 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1760 input_bufs_omx_free.pop_front();
1761 input_bufs_omx_mutex.Unlock();
1763 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1765 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1766 if (packet.synched) {
1767 //Log::getInstance()->log("Audio", Log::DEBUG,
1768 // "packet synched marker");
1770 //lastreftimePTS=packet.pts;
1771 if (omx_first_frame) { // TODO time
1772 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1773 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1774 omx_first_frame = false;
1776 cur_input_buf_omx->nFlags = 0;
1777 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1779 lastreftimeOMX = packet.presentation_time;
1780 // Log::getInstance()->log("Audio", Log::DEBUG,
1781 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1782 lastreftimePTS = packet.pts;
1783 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1785 // Log::getInstance()->log("Audio", Log::DEBUG,
1786 // "packet NOT synched marker");
1787 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1788 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1791 if (packet.disconti || achange) {
1792 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1793 //mp23codec_context_libav->frame_size=-1;
1794 //ac3codec_context_libav->frame_size=-1;
1798 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1800 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1801 unsigned int haveToCopy=packet.length-*samplepos;
1804 while (haveToCopy>0) {
1805 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1807 unsigned int gotframesize=0;
1809 switch (packet.type) {
1810 case MPTYPE_MPEG_AUDIO:
1811 case MPTYPE_MPEG_AUDIO_LAYER3: {
1812 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1813 haveToCopy,&gotframesize);
1817 case MPTYPE_AC3_PRE13: {
1818 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1819 haveToCopy,&gotframesize);
1823 case MPTYPE_AAC_LATM: {
1824 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1825 haveToCopy,&gotframesize);
1829 if (adv!=haveToCopy) {
1834 *samplepos=packet.length; //no ac3 sync byte
1835 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
1836 return packet.length;
1839 // so everything is fine now do a memcpy
1840 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1841 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1842 haveToCopy-=cancopy;
1843 cur_input_buf_omx->nFilledLen+=cancopy;
1844 *samplepos+=cancopy;
1845 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
1847 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1848 if (error != OMX_ErrorNone) {
1849 Log::getInstance()->log("Audio", Log::DEBUG,
1850 "OMX_EmptyThisBuffer 5 failed %x", error);
1852 cur_input_buf_omx=NULL;
1855 input_bufs_omx_mutex.Lock();
1856 if (input_bufs_omx_free.size()==0) {
1857 input_bufs_omx_mutex.Unlock();
1858 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
1859 return *samplepos; // we do not have a free media sample
1861 cur_input_buf_omx=input_bufs_omx_free.front();
1862 cur_input_buf_omx->nFilledLen=0;
1863 cur_input_buf_omx->nOffset=0;
1864 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1865 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1866 input_bufs_omx_free.pop_front();
1867 input_bufs_omx_mutex.Unlock();
1869 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
1872 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
1880 AVCodecContext *current_context;
1881 switch (packet.type) {
1882 case MPTYPE_MPEG_AUDIO:
1883 case MPTYPE_MPEG_AUDIO_LAYER3: {
1884 current_context = mp23codec_context_libav;
1885 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1886 else framesize=current_context->frame_size;
1888 case MPTYPE_AAC_LATM: {
1889 current_context = aaclatmcodec_context_libav;
1892 case MPTYPE_AC3_PRE13: {
1893 current_context = ac3codec_context_libav;
1897 if (decompress_buffer_filled) { // have a remaining paket
1898 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1899 memcpy(decompress_buffer+decompress_buffer_filled,
1900 buffer+packet.pos_buffer+*samplepos,
1901 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1902 incoming_paket_libav.size = decompress_buffer_filled
1903 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1904 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1906 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1907 incoming_paket_libav.size = haveToCopy;
1909 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
1911 while (haveToCopy> 0 && errcount<3) {
1913 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1914 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1915 // framesize, current_context->frame_size);
1917 bool donotdecompress=false;
1918 unsigned int gotframesize=0;
1919 if (!decompress_buffer_filled) { // only do this if no old data is present
1921 switch (packet.type) {
1922 case MPTYPE_MPEG_AUDIO:
1923 case MPTYPE_MPEG_AUDIO_LAYER3: {
1924 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1925 incoming_paket_libav.size,&gotframesize);
1929 case MPTYPE_AC3_PRE13: {
1930 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1931 incoming_paket_libav.size,&gotframesize);
1934 case MPTYPE_AAC_LATM: {
1935 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
1936 incoming_paket_libav.size,&gotframesize);
1941 incoming_paket_libav.data += adv;
1942 incoming_paket_libav.size-=adv;
1945 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1946 else*/ framesize=haveToCopy;
1947 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1948 if (haveToCopy <= 0) {
1949 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1950 *samplepos=packet.length;
1951 return packet.length;
1957 if (gotframesize>0 && gotframesize>haveToCopy) {
1958 donotdecompress=true;
1959 errcount=100; // exit loop
1961 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1963 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
1964 if (!donotdecompress) {
1967 pthread_testcancel();
1968 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1969 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1971 if (!omx_running || !mp23codec_context_libav
1972 || !ac3codec_context_libav) {
1973 libav_mutex.Unlock();
1976 libav_mutex.Unlock();
1977 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1978 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1979 &gotta, &incoming_paket_libav);
1980 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1981 pthread_setcancelstate(oldcancelstate, NULL);
1982 pthread_setcanceltype(oldcanceltype, NULL);
1983 pthread_testcancel();
1989 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1990 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
1992 libav_mutex.Unlock();
1996 if (decompress_buffer_filled) { // reset to normal decoding
1998 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1999 haveToCopy -= min(len-decompress_buffer_filled,0);
2000 *samplepos += min(len-decompress_buffer_filled,0);
2001 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2002 /*else*/ framesize=haveToCopy;
2004 framesize=haveToCopy;
2006 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2008 decompress_buffer_filled=0;
2012 incoming_paket_libav.data += len;
2016 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2017 else*/framesize=haveToCopy;
2020 framesize=haveToCopy;
2023 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2025 incoming_paket_libav.size =framesize;
2027 //Log::getInstance()->log("Audio", Log::DEBUG,
2029 int dsize = av_samples_get_buffer_size(NULL,
2030 current_context->channels, decode_frame_libav->nb_samples,
2031 current_context->sample_fmt, 1);
2032 if ((cur_input_buf_omx->nFilledLen + dsize)
2033 > cur_input_buf_omx->nAllocLen ) {
2034 // I doubt that this will ever happen
2035 // Log::getInstance()->log("Audio", Log::DEBUG,
2036 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2037 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2039 if (error != OMX_ErrorNone) {
2040 Log::getInstance()->log("Audio", Log::DEBUG,
2041 "OMX_EmptyThisBuffer 4 failed %x", error);
2043 cur_input_buf_omx = NULL;
2045 if (!cur_input_buf_omx) {
2047 while (count < 10 && omx_running) {
2049 input_bufs_omx_mutex.Lock();
2050 if (input_bufs_omx_free.size() == 0) {
2051 input_bufs_omx_mutex.Unlock();
2052 // Log::getInstance()->log("Audio", Log::DEBUG,
2053 // "Deliver MediaPacket no free sample");
2055 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2056 if (!omx_running) return *samplepos;
2057 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2060 cur_input_buf_omx = input_bufs_omx_free.front();
2061 cur_input_buf_omx->nFilledLen = 0;
2062 cur_input_buf_omx->nOffset = 0;
2063 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2064 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2065 input_bufs_omx_free.pop_front();
2066 input_bufs_omx_mutex.Unlock();
2069 if (!cur_input_buf_omx) return *samplepos;
2074 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2075 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2076 decode_frame_libav->data[0], dsize);
2077 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2078 cur_input_buf_omx->nFilledLen += dsize;
2080 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2081 /* uint8_t a1=incoming_paket_libav.data[0];
2082 uint8_t a2=incoming_paket_libav.data[1];
2083 uint8_t a3=incoming_paket_libav.data[2];
2084 uint8_t a4=incoming_paket_libav.data[3];*/
2085 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2090 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2091 decompress_buffer_filled=0;
2093 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);
2094 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2096 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2100 if (cur_input_buf_omx->nFilledLen) {
2101 //Log::getInstance()->log("Audio", Log::DEBUG,
2102 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2103 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2104 if (error != OMX_ErrorNone) {
2105 Log::getInstance()->log("Audio", Log::DEBUG,
2106 "OMX_EmptyThisBuffer 5 failed %x", error);
2108 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2109 cur_input_buf_omx = NULL;
2114 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2116 *samplepos=packet.length;
2117 return packet.length;
2123 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2124 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2125 return vw->SetStartAudioOffset(curreftime,rsync);
2128 void AudioOMX::ResetTimeOffsets() {
2129 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2130 vw->ResetTimeOffsets();