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 //sanity check inspired by libav
1587 const int sample_rates[4]={44100,48000,32000,0};
1588 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1589 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1590 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1591 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1592 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1593 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1594 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1595 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1598 int layer=4-((data[test+1]&0x06)>>1);
1599 if (layer==4) {test++;continue;} //sanity check
1601 int bitrate_index=(data[test+2]&0xf0)>>4;
1602 if (bitrate_index==0x0f || bitrate_index==0x0) {test++;continue;} //sanity check
1604 int samplerate_index=(data[test+2]&0x0C)>>2;
1605 if (samplerate_index==0x03) {test++;continue;} //sanity check
1607 int padding=(data[test+2]&2)>>1;
1608 if (0x10 & data[test+1]) {
1609 lsf=((data[test+1]) &0x8)?0:1;
1615 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1617 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1619 frame_size=(temp_frame_size*12000)/sample_rate;
1620 frame_size=(frame_size+padding)*4;
1621 } else if (layer==2) {
1622 frame_size=(temp_frame_size*144000)/sample_rate;
1623 frame_size=frame_size+padding;
1625 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1626 frame_size=frame_size+padding;
1628 unsigned int sameheadertest=(data[test]<<24)|(data[test+1]<<16) |(data[test+2]<<8);
1629 const unsigned mask=(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)); // from libav
1630 if (!mp3sameheader) {
1631 mp3sameheader=sameheadertest;
1632 mp3sameheadercount=2;
1634 if ((mp3sameheader& mask)== (sameheadertest &mask)) mp3sameheadercount++;
1635 else mp3sameheadercount=0;
1636 mp3sameheader=sameheadertest;
1638 //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);
1639 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME DIAG: %x %x %x %d",data[test],data[test+1],data[test+2],mp3sameheadercount);
1641 if (mp3sameheadercount>4) {
1642 *framesize=frame_size;
1643 return test; // probably FrameSync
1644 } //skip it if the header changes too frequently
1651 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1653 if (size<=4) return size; // silly;
1654 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1655 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1656 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1657 1152, 1280, 1280, };
1658 unsigned int test=0;
1659 *framesize=20000; //if we do not find a start code do not decompress
1660 while (test+4<size) {
1661 if (data[test]==0x0B && data[test+1]==0x77) {
1662 // now figure out the length of the frame
1663 unsigned char code=data[test+4];
1664 unsigned char fscod=(code& 0xC0)>>6;
1665 unsigned char frmsize=(code &0x3f);
1666 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1667 *framesize=frm_size_tab[frmsize]*2;
1668 return test; // probably FrameSync
1675 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1677 if (size<=4) return size; // silly;
1678 unsigned int test=0;
1679 *framesize=20000; //if we do not find a start code do not decompress
1680 while (test+4<size) {
1681 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1682 // now figure out the length of the frame
1683 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1684 *framesize=length+3;
1685 return test; // probably FrameSync
1691 #ifndef USE_LIBRESAMPLE
1692 #define SQRT3_2 1.22474487139158904909
1694 void AudioOMX::getDownMixMatrix(unsigned long long channels,
1695 int *left_mat,int *right_mat)
1698 double downmix_matrix[2][64];
1699 for (i=0;i<64;i++) {
1701 downmix_matrix[j][i]=0.;
1704 downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
1705 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
1706 downmix_matrix[0/*links*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1707 downmix_matrix[1/*rechts*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1709 if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
1710 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
1711 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
1713 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
1714 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
1716 downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
1717 downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
1718 downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
1719 downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
1720 downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
1721 downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
1722 downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
1723 downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
1724 downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
1725 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
1726 downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1727 downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1729 for (i=0,j=0;i<64;i++) {
1730 if ((1ULL << i)& channels) {
1731 left_mat[j]=(int)(downmix_matrix[0][i]*(1<<16));
1732 right_mat[j]=(int)(downmix_matrix[1][i]*(1<<16));
1740 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1742 packet = mplist.front();
1745 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1746 DeliverMediaPacket(packet, buffer, samplepos);
1747 if (*samplepos == packet.length) {
1755 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1757 VideoOMX *video = (VideoOMX*) Video::getInstance();
1759 OMX_PARAM_U32TYPE audio_lat;
1760 OMX_ERRORTYPE error;
1761 memset(&audio_lat, 0, sizeof(audio_lat));
1762 audio_lat.nSize = sizeof(audio_lat);
1763 audio_lat.nVersion.nVersion = OMX_VERSION;
1764 audio_lat.nPortIndex = omx_rend_input_port;
1766 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1768 video->UnlockClock();
1769 if (error != OMX_ErrorNone) {
1770 Log::getInstance()->log("Audio", Log::DEBUG,
1771 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1772 omx_rend_input_port);
1773 return pts; // no correction in case of error
1775 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1778 long long workpts=0;
1779 workpts+=addsamples;
1780 workpts-=audio_lat.nU32;
1781 workpts*=10LL*1000LL*1000LL;
1782 workpts=workpts/((long long)srate); //one second /samplerate
1788 bool AudioOMX::DrainTargetBufferFull()
1790 //Check, if we have OMX output buffers
1792 input_bufs_omx_mutex.Lock();
1793 full=(input_bufs_omx_free.size()==0);
1794 input_bufs_omx_mutex.Unlock();
1800 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1802 /*First Check, if we have an audio sample*/
1803 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1805 OMX_ERRORTYPE error;
1806 Log *logger=Log::getInstance();
1807 if (vw->InIframemode()) {
1810 return 0; //Not in iframe mode!
1813 if (!omx_running) return 0; // if we are not runnig do not do this
1814 if (vw->isClockPaused()) return 0; //Block if we pause
1815 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1817 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1819 /* if (packet.synched && packet.presentation_time <= 0) {
1820 *samplepos = packet.length;
1821 firstsynched = false;
1823 Log::getInstance()->log("Audio", Log::DEBUG,
1824 "DeliverMediaPacketOMX Frameskip");
1825 return packet.length;
1828 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1830 UINT headerstrip = 0;
1831 if (packet.disconti) {
1832 firstsynched = false;
1833 decompress_buffer_filled=0;
1834 if (cur_input_buf_omx) {
1835 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1837 if (error != OMX_ErrorNone) {
1838 Log::getInstance()->log("Audio", Log::DEBUG,
1839 "OMX_EmptyThisBuffer 1 failed %x", error);
1841 cur_input_buf_omx = NULL;
1845 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1846 if (packet.type != lastAType) {//Format Change //Push data out !
1847 firstsynched = false;
1850 Log::getInstance()->log("Audio", Log::DEBUG,"Notice audio type change %d %d", packet.type,lastAType);
1851 lastAType = packet.type;
1852 decompress_buffer_filled=0;
1854 if (cur_input_buf_omx) {
1855 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1857 if (error != OMX_ErrorNone) {
1858 Log::getInstance()->log("Audio", Log::DEBUG,
1859 "OMX_EmptyThisBuffer 2 failed %x", error);
1861 cur_input_buf_omx = NULL;
1866 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1867 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1869 if (!ChangeAudioPortConfig(true)) {
1870 Log::getInstance()->log("Audio", Log::DEBUG,
1871 "Changing audio port config failed", error);
1874 pthread_setcancelstate(oldcancelstate, NULL);
1875 pthread_setcanceltype(oldcanceltype, NULL);
1879 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1881 /*Inspect PES-Header */
1882 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1883 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1884 if (packet.type == MPTYPE_AC3)
1885 headerstrip += 4; //skip ac3 bytes
1886 *samplepos += headerstrip;
1887 if (packet.synched) {
1888 if (cur_input_buf_omx) {
1889 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1890 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1892 if (error != OMX_ErrorNone) {
1893 Log::getInstance()->log("Audio", Log::DEBUG,
1894 "OMX_EmptyThisBuffer 3 failed %x", error);
1896 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1898 cur_input_buf_omx = NULL;//write out old data
1900 firstsynched = true;
1901 //decompress_buffer_filled=0;
1903 if (!firstsynched) {//
1904 *samplepos = packet.length;//if we have not processed at least one
1905 decompress_buffer_filled=0;
1906 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1907 return packet.length;//synched packet ignore it!
1911 if (!cur_input_buf_omx) {
1912 input_bufs_omx_mutex.Lock();
1913 if (input_bufs_omx_free.size()==0) {
1914 input_bufs_omx_mutex.Unlock();
1915 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1916 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1917 return 0; // we do not have a free media sample
1920 cur_input_buf_omx=input_bufs_omx_free.front();
1921 cur_input_buf_omx->nFilledLen=0;
1922 cur_input_buf_omx->nOffset=0;
1923 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1924 input_bufs_omx_free.pop_front();
1925 input_bufs_omx_mutex.Unlock();
1927 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1929 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1930 if (packet.synched) {
1931 //Log::getInstance()->log("Audio", Log::DEBUG,
1932 // "packet synched marker");
1934 //lastreftimePTS=packet.pts;
1935 if (omx_first_frame) { // TODO time
1936 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1937 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1938 omx_first_frame = false;
1940 cur_input_buf_omx->nFlags = 0;
1941 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1943 lastreftimeOMX = packet.presentation_time;
1944 //Log::getInstance()->log("Audio", Log::DEBUG,
1945 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1946 lastreftimePTS = packet.pts;
1947 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1949 // Log::getInstance()->log("Audio", Log::DEBUG,
1950 // "packet NOT synched marker");
1951 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1952 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1955 if (packet.disconti || achange) {
1956 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1957 //mp23codec_context_libav->frame_size=-1;
1958 //ac3codec_context_libav->frame_size=-1;
1962 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1964 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1965 unsigned int haveToCopy=packet.length-*samplepos;
1968 while (haveToCopy>0) {
1969 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1971 unsigned int gotframesize=0;
1973 switch (packet.type) {
1974 case MPTYPE_MPEG_AUDIO:
1975 case MPTYPE_MPEG_AUDIO_LAYER3: {
1976 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1977 haveToCopy,&gotframesize);
1981 case MPTYPE_AC3_PRE13: {
1982 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1983 haveToCopy,&gotframesize);
1987 case MPTYPE_AAC_LATM: {
1988 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1989 haveToCopy,&gotframesize);
1993 if (adv!=haveToCopy) {
1998 *samplepos=packet.length; //no ac3 sync byte
1999 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
2000 return packet.length;
2003 // so everything is fine now do a memcpy
2004 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
2005 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2006 haveToCopy-=cancopy;
2007 cur_input_buf_omx->nFilledLen+=cancopy;
2008 *samplepos+=cancopy;
2009 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
2011 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2012 if (error != OMX_ErrorNone) {
2013 Log::getInstance()->log("Audio", Log::DEBUG,
2014 "OMX_EmptyThisBuffer 5 failed %x", error);
2016 cur_input_buf_omx=NULL;
2019 input_bufs_omx_mutex.Lock();
2020 if (input_bufs_omx_free.size()==0) {
2021 input_bufs_omx_mutex.Unlock();
2022 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
2023 return *samplepos; // we do not have a free media sample
2025 cur_input_buf_omx=input_bufs_omx_free.front();
2026 cur_input_buf_omx->nFilledLen=0;
2027 cur_input_buf_omx->nOffset=0;
2028 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2029 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2030 input_bufs_omx_free.pop_front();
2031 input_bufs_omx_mutex.Unlock();
2033 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
2036 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
2044 AVCodecContext *current_context;
2045 switch (packet.type) {
2046 case MPTYPE_MPEG_AUDIO:
2047 case MPTYPE_MPEG_AUDIO_LAYER3: {
2048 current_context = mp23codec_context_libav;
2049 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2050 else framesize=current_context->frame_size;
2052 case MPTYPE_AAC_LATM: {
2053 current_context = aaclatmcodec_context_libav;
2056 case MPTYPE_AC3_PRE13: {
2057 current_context = ac3codec_context_libav;
2061 if (decompress_buffer_filled) { // have a remaining paket
2062 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2063 memcpy(decompress_buffer+decompress_buffer_filled,
2064 buffer+packet.pos_buffer+*samplepos,
2065 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2066 incoming_paket_libav.size = decompress_buffer_filled
2067 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2068 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d %d %d",packet.type,decompress_buffer_filled,packet.synched);
2070 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2071 incoming_paket_libav.size = haveToCopy;
2073 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
2075 while (haveToCopy> 0 && errcount<3) {
2077 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
2078 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
2079 // framesize, current_context->frame_size);
2081 bool donotdecompress=false;
2082 unsigned int gotframesize=0;
2083 // if (!decompress_buffer_filled) { // only do this if no old data is present
2085 switch (packet.type) {
2086 case MPTYPE_MPEG_AUDIO:
2087 case MPTYPE_MPEG_AUDIO_LAYER3: {
2088 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2089 incoming_paket_libav.size,&gotframesize);
2093 case MPTYPE_AC3_PRE13: {
2094 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2095 incoming_paket_libav.size,&gotframesize);
2098 case MPTYPE_AAC_LATM: {
2099 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2100 incoming_paket_libav.size,&gotframesize);
2104 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2105 incoming_paket_libav.data += adv;
2106 incoming_paket_libav.size-=adv;
2109 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2110 else*/ framesize=haveToCopy;
2111 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
2112 if (haveToCopy <= 0) {
2113 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
2114 *samplepos=packet.length;
2115 return packet.length;
2121 if (gotframesize>0 && gotframesize>haveToCopy) {
2122 donotdecompress=true;
2123 errcount=100; // exit loop
2125 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
2127 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
2128 if (!donotdecompress) {
2131 pthread_testcancel();
2132 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2133 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2135 if (!omx_running || !mp23codec_context_libav
2136 || !ac3codec_context_libav) {
2137 libav_mutex.Unlock();
2140 libav_mutex.Unlock();
2141 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
2142 int save_size=incoming_paket_libav.size;
2144 if (gotframesize<=incoming_paket_libav.size) {
2145 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2146 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2147 &gotta, &incoming_paket_libav);
2149 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:E %d %d",gotframesize,incoming_paket_libav.size);
2153 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:T %d",len);
2154 incoming_paket_libav.size=save_size;
2155 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
2156 pthread_setcancelstate(oldcancelstate, NULL);
2157 pthread_setcanceltype(oldcanceltype, NULL);
2158 pthread_testcancel();
2164 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
2165 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
2167 libav_mutex.Unlock();
2171 if (decompress_buffer_filled) { // reset to normal decoding
2173 //Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2174 haveToCopy -= min(len-decompress_buffer_filled,0);
2175 *samplepos += min(len-decompress_buffer_filled,0);
2176 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2177 /*else*/ framesize=haveToCopy;
2179 framesize=haveToCopy;
2181 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2183 decompress_buffer_filled=0;
2187 incoming_paket_libav.data += len;
2191 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2192 else*/framesize=haveToCopy;
2195 framesize=haveToCopy;
2198 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2200 incoming_paket_libav.size =framesize;
2202 //Log::getInstance()->log("Audio", Log::DEBUG,
2205 int dsize = av_samples_get_buffer_size(NULL,
2206 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2207 current_context->sample_fmt, 1);
2208 int dsize_in = av_samples_get_buffer_size(NULL,
2209 current_context->channels, decode_frame_libav->nb_samples,
2210 current_context->sample_fmt, 1);
2211 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2212 if ((cur_input_buf_omx->nFilledLen + dsize)
2213 > cur_input_buf_omx->nAllocLen ) {
2214 // I doubt that this will ever happen
2215 // Log::getInstance()->log("Audio", Log::DEBUG,
2216 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2217 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2219 if (error != OMX_ErrorNone) {
2220 Log::getInstance()->log("Audio", Log::DEBUG,
2221 "OMX_EmptyThisBuffer 4 failed %x", error);
2223 cur_input_buf_omx = NULL;
2225 if (!cur_input_buf_omx) {
2227 while (count < 10 && omx_running) {
2229 input_bufs_omx_mutex.Lock();
2230 if (input_bufs_omx_free.size() == 0) {
2231 input_bufs_omx_mutex.Unlock();
2232 // Log::getInstance()->log("Audio", Log::DEBUG,
2233 // "Deliver MediaPacket no free sample");
2235 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2236 if (!omx_running) return *samplepos;
2237 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2240 cur_input_buf_omx = input_bufs_omx_free.front();
2241 cur_input_buf_omx->nFilledLen = 0;
2242 cur_input_buf_omx->nOffset = 0;
2243 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2244 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2245 input_bufs_omx_free.pop_front();
2246 input_bufs_omx_mutex.Unlock();
2249 if (!cur_input_buf_omx) return *samplepos;
2254 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2255 if (current_context->channels==2) {
2256 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2257 decode_frame_libav->data[0], dsize);
2259 #ifndef USE_LIBRESAMPLE
2260 else if (current_context->channels==1) { //convert to stereo
2261 short* startbuffer=(short* )decode_frame_libav->data[0];
2262 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
2263 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2264 while (startbuffer!=endbuffer) {
2265 unsigned short temp=*startbuffer;
2273 unsigned int channels=current_context->channels;
2274 int left_mat[channels];
2275 int right_mat[channels];
2276 getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
2278 short* startbuffer=(short* )decode_frame_libav->data[0];
2279 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
2280 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2281 while (startbuffer!=endbuffer) {
2282 short* cur_buf=startbuffer;
2283 short* cur_buf_end=startbuffer+channels;
2287 int *mat2=right_mat;
2288 while (cur_buf!=cur_buf_end) {
2289 work1+= ((*mat1)*(*cur_buf));
2290 work2+= ((*mat2)*(*cur_buf));
2295 *destbuffer=work1>>16;
2297 *destbuffer=work2>>16;
2299 startbuffer+=channels;
2306 //untested for future use
2307 av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
2308 av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
2309 av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
2310 int ret=avresample_open(resam_con_libav);
2312 Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
2314 avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2315 dsize, decode_frame_libav->nb_samples,
2316 decode_frame_libav->data[0], dsize_in, decode_frame_libav->nb_samples);
2317 avresample_close(resam_con_libav);
2323 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2324 cur_input_buf_omx->nFilledLen += dsize;
2326 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2327 /* uint8_t a1=incoming_paket_libav.data[0];
2328 uint8_t a2=incoming_paket_libav.data[1];
2329 uint8_t a3=incoming_paket_libav.data[2];
2330 uint8_t a4=incoming_paket_libav.data[3];*/
2331 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2336 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2337 decompress_buffer_filled=0;
2339 //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);
2340 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2342 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2346 if (cur_input_buf_omx->nFilledLen) {
2347 //Log::getInstance()->log("Audio", Log::DEBUG,
2348 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2349 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2350 if (error != OMX_ErrorNone) {
2351 Log::getInstance()->log("Audio", Log::DEBUG,
2352 "OMX_EmptyThisBuffer 5 failed %x", error);
2354 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2355 cur_input_buf_omx = NULL;
2360 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2362 *samplepos=packet.length;
2363 return packet.length;
2369 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2370 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2371 return vw->SetStartAudioOffset(curreftime,rsync);
2374 void AudioOMX::ResetTimeOffsets() {
2375 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2376 vw->ResetTimeOffsets();