2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "woptionpane.h"
27 #include "osdopenvg.h"
36 lastAType = MPTYPE_MPEG_AUDIO;
42 canpass_pcm_mch=false;
44 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
52 omx_aud_rend/*dec*/=0;
53 cur_input_buf_omx=NULL;
56 ac3codec_context_libav=NULL;
59 mp23codec_context_libav=NULL;
60 #ifdef USE_LIBRESAMPLE
64 decompress_buffer=NULL;
65 decompress_buffer_size=0;
66 decompress_buffer_filled=0;
76 int AudioOMX::init(UCHAR tstreamType) {
81 streamType = tstreamType;
83 if (!initAllParams()) {
90 decompress_buffer_size=20000;
91 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
92 decompress_buffer_filled=0;
97 av_log_set_flags(AV_LOG_SKIP_REPEATED);
99 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
100 if (ac3codec_libav == NULL) {
101 Log::getInstance()->log("Audio", Log::DEBUG,
102 "Find libav ac3 decoder failed");
106 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
107 if (mp23codec_libav == NULL) {
108 Log::getInstance()->log("Audio", Log::DEBUG,
109 "Find libav mpeg audio decoder failed");
113 aaclatmcodec_libav = avcodec_find_decoder(CODEC_ID_AAC_LATM);
114 if (aaclatmcodec_libav == NULL) {
115 Log::getInstance()->log("Audio", Log::DEBUG,
116 "Find libav aac latm decoder failed");
122 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
126 Log::getInstance()->log("Audio", Log::NOTICE,
127 "TV hdmi supports mpeg1 layer 1 and 2");
129 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
133 Log::getInstance()->log("Audio", Log::NOTICE,
134 "TV hdmi supports mpeg1 layer 3");
137 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
140 Log::getInstance()->log("Audio", Log::NOTICE,
141 "TV hdmi supports AC3");
143 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
147 Log::getInstance()->log("Audio", Log::NOTICE,
148 "TV hdmi supports AAC");
151 canpass_pcm_mch=false;
156 int AudioOMX::initAllParams()
158 return (setStreamType(streamType) && setChannel() && setSource());
161 int AudioOMX::shutdown()
163 if (!initted) return 0;
166 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
167 DeAllocateCodecsOMX();
169 free(decompress_buffer);
170 decompress_buffer=NULL;
171 decompress_buffer_size=0;
172 decompress_buffer_filled=0;
177 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
179 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
180 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
183 if (STRCASECMP(name, "PCM") == 0) {
185 } else if (STRCASECMP(name, "Passthrough") == 0) {
187 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
192 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
195 if (STRCASECMP(name, "PCM") == 0) {
197 } else if (STRCASECMP(name, "Passthrough") == 0) {
199 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
204 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
207 if (STRCASECMP(name, "PCM") == 0) {
209 } else if (STRCASECMP(name, "Passthrough") == 0) {
211 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
216 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
219 if (STRCASECMP(name, "PCM") == 0) {
221 } else if (STRCASECMP(name, "Passthrough") == 0) {
223 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
228 name = vdr->configLoad("AudioOMX", "AudioOutput");
231 if (STRCASECMP(name, "analog") == 0) {
233 } else if (STRCASECMP(name, "HDMI") == 0) {
243 bool AudioOMX::handleOptionChanges(Option* option)
245 if (Audio::handleOptionChanges(option))
247 switch (option->id) {
249 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
251 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
259 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
261 } else if (STRCASECMP(option->options[option->userSetChoice],
262 "Passthrough") == 0) {
264 } else if (STRCASECMP(option->options[option->userSetChoice],
265 "PCMMultichannel") == 0) {
271 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
273 } else if (STRCASECMP(option->options[option->userSetChoice],
274 "Passthrough") == 0) {
276 } else if (STRCASECMP(option->options[option->userSetChoice],
277 "PCMMultichannel") == 0) {
283 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
285 } else if (STRCASECMP(option->options[option->userSetChoice],
286 "Passthrough") == 0) {
288 } else if (STRCASECMP(option->options[option->userSetChoice],
289 "PCMMultichannel") == 0) {
295 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
297 } else if (STRCASECMP(option->options[option->userSetChoice],
298 "Passthrough") == 0) {
300 } else if (STRCASECMP(option->options[option->userSetChoice],
301 "PCMMultichannel") == 0) {
311 bool AudioOMX::saveOptionstoServer()
314 switch (prefered_ac3) {
316 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
319 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
323 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
328 switch (prefered_aac) {
330 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
333 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
337 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
342 switch (prefered_mp2) {
344 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
347 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
351 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
356 switch (prefered_mp3) {
358 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
361 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
365 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
371 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
373 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
379 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
380 UINT numChoices, UINT defaultChoice, UINT startInt,
381 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
383 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
385 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
392 static const char* audioopts[]={"analog","HDMI"};
393 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
394 options->push_back(option);
395 pane->addOptionLine(option);
398 char **ac3opts=new char *[3];
400 ac3opts[i]=new char[strlen("PCM")+1];
401 strcpy(ac3opts[i],"PCM");
404 ac3opts[i]=new char[strlen("Passthrough")+1];
405 strcpy(ac3opts[i],"PassThrough");
408 if (canpass_pcm_mch) {
409 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
410 strcpy(ac3opts[i],"PCMMultichannel");
413 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
414 options->push_back(option);
415 pane->addOptionLine(option);
417 /* char **aacopts = new char *[3];
419 aacopts[i] = new char[strlen("PCM") + 1];
420 strcpy(mp2opts[i], "PCM");
423 aacopts[i] = new char[strlen("Passthrough") + 1];
424 strcpy(aacopts[i], "PassThrough");
427 if (canpass_pcm_mch) {
428 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
429 strcpy(aacopts[i], "PCMMultichannel");
432 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
433 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
434 aacopts, NULL, true, this);
435 options->push_back(option);
436 pane->addOptionLine(option);
439 char **mp2opts = new char *[3];
441 mp2opts[i] = new char[strlen("PCM") + 1];
442 strcpy(mp2opts[i], "PCM");
445 mp2opts[i] = new char[strlen("Passthrough") + 1];
446 strcpy(mp2opts[i], "PassThrough");
449 if (canpass_pcm_mch) {
450 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
451 strcpy(mp2opts[i], "PCMMultichannel");
454 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
455 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
456 mp2opts, NULL, true, this);
457 options->push_back(option);
458 pane->addOptionLine(option);
460 char **mp3opts = new char *[3];
462 mp3opts[i] = new char[strlen("PCM") + 1];
463 strcpy(mp3opts[i], "PCM");
466 mp3opts[i] = new char[strlen("Passthrough") + 1];
467 strcpy(mp3opts[i], "PassThrough");
470 if (canpass_pcm_mch) {
471 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
472 strcpy(mp3opts[i], "PCMMultichannel");
475 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
476 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
478 options->push_back(option);
479 pane->addOptionLine(option);*/
480 // Comment unsupported modes out
493 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
495 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
496 AudioOMX *audio=(AudioOMX *)getInstance();
497 audio->ReturnEmptyOMXBuffer(buffer);
498 return OMX_ErrorNone;
502 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
503 input_bufs_omx_mutex.Lock();
504 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
505 input_bufs_omx_free.push_back(buffer);
506 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
507 input_bufs_omx_mutex.Unlock();
510 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
511 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
512 return OMX_ErrorNone;
517 int AudioOMX::setStreamType(UCHAR type)
519 if (!initted) return 0;
521 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
525 int AudioOMX::setChannel()
527 if (!initted) return 0;
529 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
533 int AudioOMX::setSource()
535 if (!initted) return 0;
537 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
543 if (!initted) return 0;
545 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
549 int AudioOMX::play() {
552 lastAType=MPTYPE_MPEG_AUDIO;
553 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
555 ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
557 if (!AllocateCodecsOMX()) {
564 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
567 const char * destinations[]={"local","hdmi"};
572 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
573 memset(&auddest,0,sizeof(auddest));
574 auddest.nSize=sizeof(auddest);
575 auddest.nVersion.nVersion=OMX_VERSION;
576 strcpy((char *)auddest.sName, destinations[dest]);
578 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
579 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
580 if (error!=OMX_ErrorNone){
581 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
582 DeAllocateCodecsOMX();
590 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
593 //Ok first fidle a working configuration
594 Log::getInstance()->log("Audio", Log::DEBUG,
595 "ChangeAudioPortConfig");
597 OMX_AUDIO_CODINGTYPE encoding;
600 case MPTYPE_MPEG_AUDIO: {
601 if (prefered_mp2 == 2 && false) { //not supported yet
604 if (prefered_mp2 == 1 && canpass_mp2) {
606 encoding=OMX_AUDIO_CodingMP3;
609 encoding=OMX_AUDIO_CodingPCM;
614 case MPTYPE_AAC_LATM: {
615 if (prefered_aac == 2 && false) { //not supported yet
618 Log::getInstance()->log("Audio", Log::DEBUG,
619 "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
620 if (prefered_aac == 1 && canpass_aac) {
622 encoding=OMX_AUDIO_CodingAAC;
625 encoding=OMX_AUDIO_CodingPCM;
630 case MPTYPE_AC3_PRE13:
632 if (prefered_ac3 == 2 && false) { //not supported yet
635 Log::getInstance()->log("Audio", Log::DEBUG,
636 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
637 if (prefered_ac3 == 1 && canpass_ac3) {
639 encoding=OMX_AUDIO_CodingDDP;
642 encoding=OMX_AUDIO_CodingPCM;
647 case MPTYPE_MPEG_AUDIO_LAYER3: {
648 if (prefered_mp3 == 2 && false) { //not supported yet
651 if (prefered_mp3 == 1 && canpass_mp2) {
653 encoding=OMX_AUDIO_CodingMP3;
656 encoding=OMX_AUDIO_CodingPCM;
664 encoding=OMX_AUDIO_CodingPCM;
665 //mch=false; // multichannel also false
670 /*OMX_CONFIG_BOOLEANTYPE booly;
671 memset(&booly, 0, sizeof(booly));
672 booly.nSize = sizeof(booly);
673 booly.nVersion.nVersion = OMX_VERSION;
675 booly.bEnabled = OMX_TRUE;
677 booly.bEnabled = OMX_FALSE;
679 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
681 if (error != OMX_ErrorNone) {
682 Log::getInstance()->log("Audio", Log::DEBUG,
683 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
684 DeAllocateCodecsOMX();
687 VideoOMX* video=(VideoOMX*)Video::getInstance();
689 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
690 //DestroyInputBufsOMXwhilePlaying();
691 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
696 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
697 memset(&format, 0, sizeof(format));
698 format.nSize = sizeof(format);
699 format.nVersion.nVersion = OMX_VERSION;
700 format.nPortIndex = omx_rend_input_port;
701 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
703 if (error != OMX_ErrorNone) {
704 Log::getInstance()->log("Audio", Log::DEBUG,
705 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
706 omx_rend_input_port);
711 Log::getInstance()->log("Audio", Log::DEBUG,
712 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
713 format.eEncoding = encoding;
715 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
717 if (error != OMX_ErrorNone) {
718 Log::getInstance()->log("Audio", Log::DEBUG,
719 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
720 omx_rend_input_port,format.eEncoding );
725 case OMX_AUDIO_CodingPCM: {
726 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
727 memset(&audio_pcm, 0, sizeof(audio_pcm));
728 audio_pcm.nSize = sizeof(audio_pcm);
729 audio_pcm.nVersion.nVersion = OMX_VERSION;
730 audio_pcm.nChannels = 2;
731 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
732 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
733 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
734 audio_pcm.eNumData = OMX_NumericalDataSigned;
735 audio_pcm.eEndian = OMX_EndianLittle;
736 audio_pcm.bInterleaved = OMX_TRUE;
737 audio_pcm.nBitPerSample = 16;
738 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
739 audio_pcm.nChannels = 2;
740 audio_pcm.nSamplingRate = 48000;
741 audio_pcm.nPortIndex = omx_rend_input_port;
742 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
744 if (error != OMX_ErrorNone) {
745 Log::getInstance()->log("Audio", Log::DEBUG,
746 "Init OMX_IndexParamAudioPcm failed %x %d", error,
747 omx_rend_input_port);
751 case OMX_AUDIO_CodingDDP: {
752 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
753 memset(&audio_ddp, 0, sizeof(audio_ddp));
754 audio_ddp.nSize = sizeof(audio_ddp);
755 audio_ddp.nVersion.nVersion = OMX_VERSION;
756 audio_ddp.nPortIndex = omx_rend_input_port;
757 audio_ddp.nChannels = 8; //unknown
758 audio_ddp.nBitRate=0;
759 audio_ddp.nSampleRate=48000;
760 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
761 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
762 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
763 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
764 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
765 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
766 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
767 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
768 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
769 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
771 if (error != OMX_ErrorNone) {
772 Log::getInstance()->log("Audio", Log::DEBUG,
773 "Init OMX_IndexParamAudioDdp failed %x %d", error,
774 omx_rend_input_port);
779 default: break; //Make compiler happy
786 //PrepareInputBufsOMX(false);
787 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
797 int AudioOMX::InitDecoderLibAV()
800 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
801 if (!ac3codec_context_libav) {
802 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
806 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
807 ac3codec_context_libav->request_channels=2;
809 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
811 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
812 libav_mutex.Unlock();
816 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
817 if (!aaclatmcodec_context_libav) {
818 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
822 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
823 aaclatmcodec_context_libav->request_channels=2;
825 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
827 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
828 libav_mutex.Unlock();
833 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
834 if (!ac3codec_context_libav) {
835 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
836 libav_mutex.Unlock();
840 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
841 mp23codec_context_libav->request_channels=2;
843 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
845 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
846 libav_mutex.Unlock();
849 #ifdef USE_LIBRESAMPLE
850 resam_con_libav = avresample_alloc_context();
851 if (resam_con_libav == NULL) {
852 Log::getInstance()->log("Audio", Log::DEBUG,
853 "Alloc resample context failed");
857 av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format
858 av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
859 av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
861 av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
862 av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
863 av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example
866 av_init_packet(&incoming_paket_libav);
867 decode_frame_libav=avcodec_alloc_frame();
868 libav_mutex.Unlock();
869 decompress_buffer_filled=0;
876 void AudioOMX::DeinitDecoderLibAV() {
880 if (ac3codec_context_libav) {
881 avcodec_close(ac3codec_context_libav);
882 av_free(ac3codec_context_libav);
883 ac3codec_context_libav = NULL;
885 avcodec_close(aaclatmcodec_context_libav);
886 av_free(aaclatmcodec_context_libav);
887 aaclatmcodec_context_libav = NULL;
889 av_free(decode_frame_libav);
891 avcodec_close(mp23codec_context_libav);
892 av_free(mp23codec_context_libav);
893 mp23codec_context_libav = NULL;
894 #ifdef USE_LIBRESAMPLE
895 avresample_free(resam_con_libav);
896 resam_con_libav=NULL;
900 libav_mutex.Unlock();
905 int AudioOMX::AllocateCodecsOMX()
908 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
910 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
911 //Clock, move later to audio
912 VideoOMX *video=(VideoOMX*)Video::getInstance();
914 if (!InitDecoderLibAV()) return 0;;
917 OMX_PORT_PARAM_TYPE p_param;
918 memset(&p_param,0,sizeof(p_param));
919 p_param.nSize=sizeof(p_param);
920 p_param.nVersion.nVersion=OMX_VERSION;
923 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
924 return 0;// get the clock and init it if necessary
928 if (!video->idleClock()) {
933 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
934 if (error != OMX_ErrorNone) {
935 Log::getInstance()->log("Audio", Log::DEBUG,
936 "Init OMX audio rend failed %x", error);
937 video->UnlockClock();
938 DeAllocateCodecsOMX();
942 if (!ChangeAudioDestination()) {
943 video->UnlockClock();
944 DeAllocateCodecsOMX();
948 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
949 if (error != OMX_ErrorNone) {
950 Log::getInstance()->log("Audio", Log::DEBUG,
951 "Init OMX audio rend OMX_GetParameter failed %x", error);
952 video->UnlockClock();
953 DeAllocateCodecsOMX();
956 omx_rend_input_port = p_param.nStartPortNumber;
962 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
963 if (error != OMX_ErrorNone) {
964 Log::getInstance()->log("Audio", Log::DEBUG,
965 "Init OMX aud rend OMX_GetParameter failed %x", error);
966 video->UnlockClock();
967 DeAllocateCodecsOMX();
970 // buggy return value
971 omx_rend_clock_port = p_param.nStartPortNumber;
976 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
978 if (error!=OMX_ErrorNone){
979 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
980 video->UnlockClock();
981 DeAllocateCodecsOMX();
985 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
986 if (error!=OMX_ErrorNone){
987 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
988 video->UnlockClock();
989 DeAllocateCodecsOMX();
992 omx_codec_input_port=p_param.nStartPortNumber;
993 omx_codec_output_port=p_param.nStartPortNumber+1;
995 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
996 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
997 video->UnlockClock();
998 DeAllocateCodecsOMX();
1005 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
1006 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
1007 video->UnlockClock();
1008 DeAllocateCodecsOMX();
1012 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
1013 Log::getInstance()->log("Audio", Log::DEBUG,
1014 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
1015 video->UnlockClock();
1016 DeAllocateCodecsOMX();
1026 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
1027 if (error!=OMX_ErrorNone){
1028 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);
1029 video->UnlockClock();
1030 DeAllocateCodecsOMX();
1034 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1036 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1037 video->UnlockClock();
1038 DeAllocateCodecsOMX();
1042 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1043 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1044 video->UnlockClock();
1045 DeAllocateCodecsOMX();
1052 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1053 video->UnlockClock();
1054 DeAllocateCodecsOMX();
1058 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1059 video->UnlockClock();
1060 DeAllocateCodecsOMX();
1066 if (!ChangeAudioPortConfig(false)){
1067 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1068 video->UnlockClock();
1069 DeAllocateCodecsOMX();
1073 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1074 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1075 DeAllocateCodecsOMX();
1081 if (!PrepareInputBufsOMX(true)) {
1082 video->UnlockClock();
1083 DeAllocateCodecsOMX();
1089 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1090 if (error!=OMX_ErrorNone){
1091 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1092 video->UnlockClock();
1093 DeAllocateCodecsOMX();
1099 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1101 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1102 video->UnlockClock();
1103 DeAllocateCodecsOMX();
1107 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1108 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1109 video->UnlockClock();
1110 DeAllocateCodecsOMX();
1114 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1115 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1116 video->UnlockClock();
1117 DeAllocateCodecsOMX();
1122 video->UnlockClock();
1126 video->clockUnpause();
1129 if (!video->setClockExecutingandRunning()) return 0;
1131 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1139 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1141 VideoOMX *video=(VideoOMX*)Video::getInstance();
1142 OMX_ERRORTYPE error;
1143 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1144 memset(&port_def_type,0,sizeof(port_def_type));
1145 port_def_type.nSize=sizeof(port_def_type);
1146 port_def_type.nVersion.nVersion=OMX_VERSION;
1147 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1149 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1151 if (error!=OMX_ErrorNone){
1152 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1157 port_def_type.nBufferCountActual=2;
1158 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1160 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1162 if (error!=OMX_ErrorNone){
1163 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1168 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1169 if (error!=OMX_ErrorNone){
1170 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1174 input_bufs_omx_mutex.Lock();
1175 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1176 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1177 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1178 if (error!=OMX_ErrorNone){
1179 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1180 input_bufs_omx_mutex.Unlock();
1183 input_bufs_omx_all.push_back(buf_head);
1184 input_bufs_omx_free.push_back(buf_head);
1186 omx_first_frame=true;
1189 cur_input_buf_omx=NULL;
1190 input_bufs_omx_mutex.Unlock();
1192 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1199 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1201 OMX_ERRORTYPE error;
1203 cur_input_buf_omx=NULL;
1204 input_bufs_omx_mutex.Lock();
1205 for (int i=0; i< input_bufs_omx_all.size();i++) {
1206 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1207 if (error!=OMX_ErrorNone){
1208 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1209 input_bufs_omx_mutex.Unlock();
1214 input_bufs_omx_all.clear();
1215 input_bufs_omx_free.clear();
1216 input_bufs_omx_mutex.Unlock();
1220 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1222 OMX_ERRORTYPE error;
1224 cur_input_buf_omx=NULL;
1225 input_bufs_omx_mutex.Lock();
1226 while (input_bufs_omx_all.size()>0) {
1227 if (input_bufs_omx_free.size()>0) {
1228 // Destroy one buffer
1229 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1230 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1231 for (; itty!= input_bufs_omx_all.end();itty++) {
1232 if ((*itty)==cur_buf) {
1233 input_bufs_omx_all.erase(itty);
1234 input_bufs_omx_free.pop_front();
1239 input_bufs_omx_mutex.Unlock();
1241 input_bufs_omx_mutex.Lock();
1245 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1246 input_bufs_omx_mutex.Unlock();
1251 int AudioOMX::DeAllocateCodecsOMX()
1253 OMX_ERRORTYPE error;
1255 VideoOMX *video=(VideoOMX*)Video::getInstance();
1256 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1260 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1261 if (cur_input_buf_omx) {
1262 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1263 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1264 if (error!=OMX_ErrorNone) {
1265 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1268 cur_input_buf_omx=NULL;//write out old data
1270 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1273 if (omx_aud_rend/*dec*/) {
1274 // first stop the omx elements
1275 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1276 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1278 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1280 video->UnlockClock();
1281 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1283 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1286 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1287 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1290 // TODO proper deinit sequence
1291 // first flush all buffers
1293 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1294 if (error!=OMX_ErrorNone) {
1295 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1299 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1300 if (error!=OMX_ErrorNone){
1301 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1306 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1307 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1312 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1313 if (error!=OMX_ErrorNone){
1314 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1318 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1319 if (error!=OMX_ErrorNone){
1320 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1323 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1325 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1326 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1327 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1330 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1331 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1332 DeinitDecoderLibAV();
1333 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1336 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1337 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1340 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1341 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1344 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1345 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1349 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1350 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1353 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1354 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1359 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1360 if (error!=OMX_ErrorNone) {
1361 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1367 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1368 if (error!=OMX_ErrorNone) {
1369 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1373 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1374 if (error!=OMX_ErrorNone) {
1375 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1379 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1380 if (error!=OMX_ErrorNone) {
1381 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1384 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1387 //error=OMX_FreeHandle(omx_aud_dec);
1388 error=OMX_FreeHandle(omx_aud_rend);
1389 video->UnlockClock();
1390 video->destroyClock();
1391 omx_aud_rend/*dec*/=NULL;
1392 if (error!=OMX_ErrorNone) {
1393 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1397 video->UnlockClock();
1398 DeinitDecoderLibAV();
1400 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1407 int AudioOMX::stop()
1409 if (!initted) return 0;
1411 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1412 DeAllocateCodecsOMX();
1413 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1417 int AudioOMX::mute() {
1420 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1421 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1425 OMX_AUDIO_CONFIG_MUTETYPE amute;
1426 memset(&amute, 0, sizeof(amute));
1427 amute.nSize = sizeof(amute);
1428 amute.nVersion.nVersion = OMX_VERSION;
1429 amute.nPortIndex = omx_rend_input_port;
1430 amute.bMute = OMX_TRUE;
1431 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1433 if (error != OMX_ErrorNone) {
1434 Log::getInstance()->log("Audio", Log::DEBUG,
1435 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1436 omx_rend_input_port);
1448 int AudioOMX::unMute()
1450 if (!initted) return 0;
1452 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1453 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1457 OMX_AUDIO_CONFIG_MUTETYPE amute;
1458 memset(&amute, 0, sizeof(amute));
1459 amute.nSize = sizeof(amute);
1460 amute.nVersion.nVersion = OMX_VERSION;
1461 amute.nPortIndex = omx_rend_input_port;
1462 amute.bMute = OMX_FALSE;
1463 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1465 if (error != OMX_ErrorNone) {
1466 Log::getInstance()->log("Audio", Log::DEBUG,
1467 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1468 omx_rend_input_port);
1480 int AudioOMX::pause() {
1484 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1490 int AudioOMX::unPause()
1492 if (!initted) return 0;
1494 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1501 int AudioOMX::reset()
1503 if (!initted) return 0;
1505 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1506 DeAllocateCodecsOMX();
1508 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1509 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1510 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1516 int AudioOMX::setVolume(int tvolume)
1518 // parameter: 0 for silence, 20 for full
1519 if ((tvolume < 0) || (tvolume > 20)) return 0;
1521 // volume = 2 * (20 - volume);
1522 // Right, that one was rubbish... 0-10 were almost
1523 // inaudible, 11-20 did what should have been done
1524 // over the whole 0-20 range
1528 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1532 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1533 memset(&avol, 0, sizeof(avol));
1534 avol.nSize = sizeof(avol);
1535 avol.nVersion.nVersion = OMX_VERSION;
1536 avol.nPortIndex = omx_rend_input_port;
1537 avol.bLinear=OMX_FALSE;
1538 avol.sVolume.nValue =(volume-20)*200;
1539 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1541 if (error != OMX_ErrorNone) {
1542 Log::getInstance()->log("Audio", Log::DEBUG,
1543 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1544 omx_rend_input_port);
1556 int AudioOMX::test()
1559 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1561 /* aud_sync_parms_t a;
1565 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1568 /*OK*/ //printf("Audio sync disable = %i\n", b);
1576 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1578 if (size<=2) return size; // silly;
1579 unsigned int test=0;
1581 //inspired by libav parsing code
1582 while (test+1<size) {
1583 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) {
1584 if ((data[test+1] & 0x18) == 0x08) {test++;continue;} //sanity check: mpeg version ID 01 -> reserved
1585 //sanity check inspired by libav
1588 const int sample_rates[4]={44100,48000,32000,0};
1589 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1590 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1591 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1592 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1593 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1594 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1595 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1596 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1599 int layer=4-((data[test+1]&0x06)>>1);
1600 if (layer==4) {test++;continue;} //sanity check
1602 int bitrate_index=(data[test+2]&0xf0)>>4;
1603 if (bitrate_index==0x0f || bitrate_index==0x0) {test++;continue;} //sanity check
1605 int samplerate_index=(data[test+2]&0x0C)>>2;
1606 if (samplerate_index==0x03) {test++;continue;} //sanity check
1608 int padding=(data[test+2]&2)>>1;
1609 if (0x10 & data[test+1]) {
1610 lsf=((data[test+1]) &0x8)?0:1;
1616 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1618 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1620 frame_size=(temp_frame_size*12000)/sample_rate;
1621 frame_size=(frame_size+padding)*4;
1622 } else if (layer==2) {
1623 frame_size=(temp_frame_size*144000)/sample_rate;
1624 frame_size=frame_size+padding;
1626 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1627 frame_size=frame_size+padding;
1629 unsigned int sameheadertest=(data[test]<<24)|(data[test+1]<<16) |(data[test+2]<<8);
1630 const unsigned mask=(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)); // from libav
1631 if (!mp3sameheader) {
1632 mp3sameheader=sameheadertest;
1633 mp3sameheadercount=2;
1635 if ((mp3sameheader& mask)== (sameheadertest &mask)) mp3sameheadercount++;
1636 else mp3sameheadercount=0;
1637 mp3sameheader=sameheadertest;
1639 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME: %d %d %d %d %d %d %d",lsf,layer,bitrate_index,sample_rate,padding,temp_frame_size, frame_size);
1640 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME DIAG: %x %x %x %d",data[test],data[test+1],data[test+2],mp3sameheadercount);
1642 if (mp3sameheadercount>4) {
1643 *framesize=frame_size;
1644 return test; // probably FrameSync
1645 } //skip it if the header changes too frequently
1652 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1654 if (size<=4) return size; // silly;
1655 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1656 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1657 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1658 1152, 1280, 1280, };
1659 unsigned int test=0;
1660 *framesize=20000; //if we do not find a start code do not decompress
1661 while (test+4<size) {
1662 if (data[test]==0x0B && data[test+1]==0x77) {
1663 // now figure out the length of the frame
1664 unsigned char code=data[test+4];
1665 unsigned char fscod=(code& 0xC0)>>6;
1666 unsigned char frmsize=(code &0x3f);
1667 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1668 *framesize=frm_size_tab[frmsize]*2;
1669 return test; // probably FrameSync
1676 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1678 if (size<=4) return size; // silly;
1679 unsigned int test=0;
1680 *framesize=20000; //if we do not find a start code do not decompress
1681 while (test+4<size) {
1682 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1683 // now figure out the length of the frame
1684 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1685 *framesize=length+3;
1686 return test; // probably FrameSync
1692 #ifndef USE_LIBRESAMPLE
1693 #define SQRT3_2 1.22474487139158904909
1695 void AudioOMX::getDownMixMatrix(unsigned long long channels,
1696 int *left_mat,int *right_mat)
1699 double downmix_matrix[2][64];
1700 for (i=0;i<64;i++) {
1702 downmix_matrix[j][i]=0.;
1705 downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
1706 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
1707 downmix_matrix[0/*links*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1708 downmix_matrix[1/*rechts*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1710 if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
1711 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
1712 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
1714 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
1715 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
1717 downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
1718 downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
1719 downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
1720 downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
1721 downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
1722 downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
1723 downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
1724 downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
1725 downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
1726 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
1727 downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1728 downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1730 for (i=0,j=0;i<64;i++) {
1731 if ((1ULL << i)& channels) {
1732 left_mat[j]=(int)(downmix_matrix[0][i]*(1<<16));
1733 right_mat[j]=(int)(downmix_matrix[1][i]*(1<<16));
1741 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1743 packet = mplist.front();
1746 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1747 DeliverMediaPacket(packet, buffer, samplepos);
1748 if (*samplepos == packet.length) {
1756 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1758 VideoOMX *video = (VideoOMX*) Video::getInstance();
1760 OMX_PARAM_U32TYPE audio_lat;
1761 OMX_ERRORTYPE error;
1762 memset(&audio_lat, 0, sizeof(audio_lat));
1763 audio_lat.nSize = sizeof(audio_lat);
1764 audio_lat.nVersion.nVersion = OMX_VERSION;
1765 audio_lat.nPortIndex = omx_rend_input_port;
1767 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1769 video->UnlockClock();
1770 if (error != OMX_ErrorNone) {
1771 Log::getInstance()->log("Audio", Log::DEBUG,
1772 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1773 omx_rend_input_port);
1774 return pts; // no correction in case of error
1776 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1779 long long workpts=0;
1780 workpts+=addsamples;
1781 workpts-=audio_lat.nU32;
1782 workpts*=10LL*1000LL*1000LL;
1783 workpts=workpts/((long long)srate); //one second /samplerate
1789 bool AudioOMX::DrainTargetBufferFull()
1791 //Check, if we have OMX output buffers
1793 input_bufs_omx_mutex.Lock();
1794 full=(input_bufs_omx_free.size()==0);
1795 input_bufs_omx_mutex.Unlock();
1801 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1803 /*First Check, if we have an audio sample*/
1804 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1806 OMX_ERRORTYPE error;
1807 Log *logger=Log::getInstance();
1808 if (vw->InIframemode()) {
1811 return 0; //Not in iframe mode!
1814 if (!omx_running) return 0; // if we are not runnig do not do this
1815 if (vw->isClockPaused()) return 0; //Block if we pause
1816 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1818 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1820 /* if (packet.synched && packet.presentation_time <= 0) {
1821 *samplepos = packet.length;
1822 firstsynched = false;
1824 Log::getInstance()->log("Audio", Log::DEBUG,
1825 "DeliverMediaPacketOMX Frameskip");
1826 return packet.length;
1829 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1831 UINT headerstrip = 0;
1832 if (packet.disconti) {
1833 firstsynched = false;
1834 decompress_buffer_filled=0;
1835 if (cur_input_buf_omx) {
1836 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1838 if (error != OMX_ErrorNone) {
1839 Log::getInstance()->log("Audio", Log::DEBUG,
1840 "OMX_EmptyThisBuffer 1 failed %x", error);
1842 cur_input_buf_omx = NULL;
1846 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1847 if (packet.type != lastAType) {//Format Change //Push data out !
1848 firstsynched = false;
1851 Log::getInstance()->log("Audio", Log::DEBUG,"Notice audio type change %d %d", packet.type,lastAType);
1852 lastAType = packet.type;
1853 decompress_buffer_filled=0;
1855 if (cur_input_buf_omx) {
1856 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1858 if (error != OMX_ErrorNone) {
1859 Log::getInstance()->log("Audio", Log::DEBUG,
1860 "OMX_EmptyThisBuffer 2 failed %x", error);
1862 cur_input_buf_omx = NULL;
1867 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1868 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1870 if (!ChangeAudioPortConfig(true)) {
1871 Log::getInstance()->log("Audio", Log::DEBUG,
1872 "Changing audio port config failed", error);
1875 pthread_setcancelstate(oldcancelstate, NULL);
1876 pthread_setcanceltype(oldcanceltype, NULL);
1880 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1882 /*Inspect PES-Header */
1883 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1884 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1885 if (packet.type == MPTYPE_AC3)
1886 headerstrip += 4; //skip ac3 bytes
1887 *samplepos += headerstrip;
1888 if (packet.synched) {
1889 if (cur_input_buf_omx) {
1890 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1891 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1893 if (error != OMX_ErrorNone) {
1894 Log::getInstance()->log("Audio", Log::DEBUG,
1895 "OMX_EmptyThisBuffer 3 failed %x", error);
1897 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1899 cur_input_buf_omx = NULL;//write out old data
1901 firstsynched = true;
1902 //decompress_buffer_filled=0;
1904 if (!firstsynched) {//
1905 *samplepos = packet.length;//if we have not processed at least one
1906 decompress_buffer_filled=0;
1907 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1908 return packet.length;//synched packet ignore it!
1912 if (!cur_input_buf_omx) {
1913 input_bufs_omx_mutex.Lock();
1914 if (input_bufs_omx_free.size()==0) {
1915 input_bufs_omx_mutex.Unlock();
1916 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1917 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1918 return 0; // we do not have a free media sample
1921 cur_input_buf_omx=input_bufs_omx_free.front();
1922 cur_input_buf_omx->nFilledLen=0;
1923 cur_input_buf_omx->nOffset=0;
1924 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1925 input_bufs_omx_free.pop_front();
1926 input_bufs_omx_mutex.Unlock();
1928 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1930 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1931 if (packet.synched) {
1932 //Log::getInstance()->log("Audio", Log::DEBUG,
1933 // "packet synched marker");
1935 //lastreftimePTS=packet.pts;
1936 if (omx_first_frame) { // TODO time
1937 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1938 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1939 omx_first_frame = false;
1941 cur_input_buf_omx->nFlags = 0;
1942 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1944 lastreftimeOMX = packet.presentation_time;
1945 //Log::getInstance()->log("Audio", Log::DEBUG,
1946 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1947 lastreftimePTS = packet.pts;
1948 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1950 // Log::getInstance()->log("Audio", Log::DEBUG,
1951 // "packet NOT synched marker");
1952 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1953 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1956 if (packet.disconti || achange) {
1957 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1958 //mp23codec_context_libav->frame_size=-1;
1959 //ac3codec_context_libav->frame_size=-1;
1963 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1965 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1966 unsigned int haveToCopy=packet.length-*samplepos;
1969 while (haveToCopy>0) {
1970 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1972 unsigned int gotframesize=0;
1974 switch (packet.type) {
1975 case MPTYPE_MPEG_AUDIO:
1976 case MPTYPE_MPEG_AUDIO_LAYER3: {
1977 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1978 haveToCopy,&gotframesize);
1982 case MPTYPE_AC3_PRE13: {
1983 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1984 haveToCopy,&gotframesize);
1988 case MPTYPE_AAC_LATM: {
1989 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1990 haveToCopy,&gotframesize);
1994 if (adv!=haveToCopy) {
1999 *samplepos=packet.length; //no ac3 sync byte
2000 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
2001 return packet.length;
2004 // so everything is fine now do a memcpy
2005 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
2006 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2007 haveToCopy-=cancopy;
2008 cur_input_buf_omx->nFilledLen+=cancopy;
2009 *samplepos+=cancopy;
2010 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
2012 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2013 if (error != OMX_ErrorNone) {
2014 Log::getInstance()->log("Audio", Log::DEBUG,
2015 "OMX_EmptyThisBuffer 5 failed %x", error);
2017 cur_input_buf_omx=NULL;
2020 input_bufs_omx_mutex.Lock();
2021 if (input_bufs_omx_free.size()==0) {
2022 input_bufs_omx_mutex.Unlock();
2023 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
2024 return *samplepos; // we do not have a free media sample
2026 cur_input_buf_omx=input_bufs_omx_free.front();
2027 cur_input_buf_omx->nFilledLen=0;
2028 cur_input_buf_omx->nOffset=0;
2029 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2030 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2031 input_bufs_omx_free.pop_front();
2032 input_bufs_omx_mutex.Unlock();
2034 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
2037 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
2045 AVCodecContext *current_context;
2046 switch (packet.type) {
2047 case MPTYPE_MPEG_AUDIO:
2048 case MPTYPE_MPEG_AUDIO_LAYER3: {
2049 current_context = mp23codec_context_libav;
2050 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2051 else framesize=current_context->frame_size;
2053 case MPTYPE_AAC_LATM: {
2054 current_context = aaclatmcodec_context_libav;
2057 case MPTYPE_AC3_PRE13: {
2058 current_context = ac3codec_context_libav;
2062 if (decompress_buffer_filled) { // have a remaining paket
2063 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2064 memcpy(decompress_buffer+decompress_buffer_filled,
2065 buffer+packet.pos_buffer+*samplepos,
2066 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2067 incoming_paket_libav.size = decompress_buffer_filled
2068 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2069 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d %d %d",packet.type,decompress_buffer_filled,packet.synched);
2071 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2072 incoming_paket_libav.size = haveToCopy;
2074 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
2076 while (haveToCopy> 0 && errcount<3) {
2078 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
2079 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
2080 // framesize, current_context->frame_size);
2082 bool donotdecompress=false;
2083 unsigned int gotframesize=0;
2084 // if (!decompress_buffer_filled) { // only do this if no old data is present
2086 switch (packet.type) {
2087 case MPTYPE_MPEG_AUDIO:
2088 case MPTYPE_MPEG_AUDIO_LAYER3: {
2089 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2090 incoming_paket_libav.size,&gotframesize);
2094 case MPTYPE_AC3_PRE13: {
2095 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2096 incoming_paket_libav.size,&gotframesize);
2099 case MPTYPE_AAC_LATM: {
2100 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2101 incoming_paket_libav.size,&gotframesize);
2105 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2106 incoming_paket_libav.data += adv;
2107 incoming_paket_libav.size-=adv;
2110 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2111 else*/ framesize=haveToCopy;
2112 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
2113 if (haveToCopy <= 0) {
2114 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
2115 *samplepos=packet.length;
2116 return packet.length;
2122 if (gotframesize>0 && gotframesize>haveToCopy) {
2123 donotdecompress=true;
2124 errcount=100; // exit loop
2126 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
2128 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
2129 if (!donotdecompress) {
2132 pthread_testcancel();
2133 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2134 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2136 if (!omx_running || !mp23codec_context_libav
2137 || !ac3codec_context_libav) {
2138 libav_mutex.Unlock();
2141 libav_mutex.Unlock();
2142 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
2143 int save_size=incoming_paket_libav.size;
2145 if (gotframesize<=incoming_paket_libav.size) {
2146 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2147 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2148 &gotta, &incoming_paket_libav);
2150 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:E %d %d",gotframesize,incoming_paket_libav.size);
2154 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:T %d",len);
2155 incoming_paket_libav.size=save_size;
2156 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
2157 pthread_setcancelstate(oldcancelstate, NULL);
2158 pthread_setcanceltype(oldcanceltype, NULL);
2159 pthread_testcancel();
2165 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
2166 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
2168 libav_mutex.Unlock();
2172 if (decompress_buffer_filled) { // reset to normal decoding
2174 //Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2175 haveToCopy -= min(len-decompress_buffer_filled,0);
2176 *samplepos += min(len-decompress_buffer_filled,0);
2177 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2178 /*else*/ framesize=haveToCopy;
2180 framesize=haveToCopy;
2182 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2184 decompress_buffer_filled=0;
2188 incoming_paket_libav.data += len;
2192 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2193 else*/framesize=haveToCopy;
2196 framesize=haveToCopy;
2199 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2201 incoming_paket_libav.size =framesize;
2203 //Log::getInstance()->log("Audio", Log::DEBUG,
2206 int dsize = av_samples_get_buffer_size(NULL,
2207 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2208 current_context->sample_fmt, 1);
2209 int dsize_in = av_samples_get_buffer_size(NULL,
2210 current_context->channels, decode_frame_libav->nb_samples,
2211 current_context->sample_fmt, 1);
2212 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2213 if ((cur_input_buf_omx->nFilledLen + dsize)
2214 > cur_input_buf_omx->nAllocLen ) {
2215 // I doubt that this will ever happen
2216 // Log::getInstance()->log("Audio", Log::DEBUG,
2217 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2218 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2220 if (error != OMX_ErrorNone) {
2221 Log::getInstance()->log("Audio", Log::DEBUG,
2222 "OMX_EmptyThisBuffer 4 failed %x", error);
2224 cur_input_buf_omx = NULL;
2226 if (!cur_input_buf_omx) {
2228 while (count < 10 && omx_running) {
2230 input_bufs_omx_mutex.Lock();
2231 if (input_bufs_omx_free.size() == 0) {
2232 input_bufs_omx_mutex.Unlock();
2233 // Log::getInstance()->log("Audio", Log::DEBUG,
2234 // "Deliver MediaPacket no free sample");
2236 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2237 if (!omx_running) return *samplepos;
2238 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2241 cur_input_buf_omx = input_bufs_omx_free.front();
2242 cur_input_buf_omx->nFilledLen = 0;
2243 cur_input_buf_omx->nOffset = 0;
2244 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2245 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2246 input_bufs_omx_free.pop_front();
2247 input_bufs_omx_mutex.Unlock();
2250 if (!cur_input_buf_omx) return *samplepos;
2255 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2256 if (current_context->channels==2) {
2257 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2258 decode_frame_libav->data[0], dsize);
2260 #ifndef USE_LIBRESAMPLE
2261 else if (current_context->channels==1) { //convert to stereo
2262 short* startbuffer=(short* )decode_frame_libav->data[0];
2263 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
2264 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2265 while (startbuffer!=endbuffer) {
2266 unsigned short temp=*startbuffer;
2274 unsigned int channels=current_context->channels;
2275 int left_mat[channels];
2276 int right_mat[channels];
2277 getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
2279 short* startbuffer=(short* )decode_frame_libav->data[0];
2280 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
2281 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2282 while (startbuffer!=endbuffer) {
2283 short* cur_buf=startbuffer;
2284 short* cur_buf_end=startbuffer+channels;
2288 int *mat2=right_mat;
2289 while (cur_buf!=cur_buf_end) {
2290 work1+= ((*mat1)*(*cur_buf));
2291 work2+= ((*mat2)*(*cur_buf));
2296 *destbuffer=work1>>16;
2298 *destbuffer=work2>>16;
2300 startbuffer+=channels;
2307 //untested for future use
2308 av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
2309 av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
2310 av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
2311 int ret=avresample_open(resam_con_libav);
2313 Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
2315 avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2316 dsize, decode_frame_libav->nb_samples,
2317 decode_frame_libav->data[0], dsize_in, decode_frame_libav->nb_samples);
2318 avresample_close(resam_con_libav);
2324 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2325 cur_input_buf_omx->nFilledLen += dsize;
2327 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2328 /* uint8_t a1=incoming_paket_libav.data[0];
2329 uint8_t a2=incoming_paket_libav.data[1];
2330 uint8_t a3=incoming_paket_libav.data[2];
2331 uint8_t a4=incoming_paket_libav.data[3];*/
2332 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2337 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2338 decompress_buffer_filled=0;
2340 //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);
2341 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2343 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2347 if (cur_input_buf_omx->nFilledLen) {
2348 //Log::getInstance()->log("Audio", Log::DEBUG,
2349 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2350 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2351 if (error != OMX_ErrorNone) {
2352 Log::getInstance()->log("Audio", Log::DEBUG,
2353 "OMX_EmptyThisBuffer 5 failed %x", error);
2355 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2356 cur_input_buf_omx = NULL;
2361 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2363 *samplepos=packet.length;
2364 return packet.length;
2370 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2371 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2372 return vw->SetStartAudioOffset(curreftime,rsync);
2375 void AudioOMX::ResetTimeOffsets() {
2376 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2377 vw->ResetTimeOffsets();