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();
508 VideoOMX *video=(VideoOMX*)Video::getInstance();
512 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
513 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
514 VideoOMX *video=(VideoOMX*)Video::getInstance();
516 return OMX_ErrorNone;
521 int AudioOMX::setStreamType(UCHAR type)
523 if (!initted) return 0;
525 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
529 int AudioOMX::setChannel()
531 if (!initted) return 0;
533 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
537 int AudioOMX::setSource()
539 if (!initted) return 0;
541 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
547 if (!initted) return 0;
549 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
553 int AudioOMX::play() {
556 lastAType=MPTYPE_MPEG_AUDIO;
557 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
559 ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
561 if (!AllocateCodecsOMX()) {
568 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
571 const char * destinations[]={"local","hdmi"};
576 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
577 memset(&auddest,0,sizeof(auddest));
578 auddest.nSize=sizeof(auddest);
579 auddest.nVersion.nVersion=OMX_VERSION;
580 strcpy((char *)auddest.sName, destinations[dest]);
582 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
583 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
584 if (error!=OMX_ErrorNone){
585 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
586 DeAllocateCodecsOMX();
594 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
597 //Ok first fidle a working configuration
598 Log::getInstance()->log("Audio", Log::DEBUG,
599 "ChangeAudioPortConfig");
601 OMX_AUDIO_CODINGTYPE encoding;
604 case MPTYPE_MPEG_AUDIO: {
605 if (prefered_mp2 == 2 && false) { //not supported yet
608 if (prefered_mp2 == 1 && canpass_mp2) {
610 encoding=OMX_AUDIO_CodingMP3;
613 encoding=OMX_AUDIO_CodingPCM;
618 case MPTYPE_AAC_LATM: {
619 if (prefered_aac == 2 && false) { //not supported yet
622 Log::getInstance()->log("Audio", Log::DEBUG,
623 "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
624 if (prefered_aac == 1 && canpass_aac) {
626 encoding=OMX_AUDIO_CodingAAC;
629 encoding=OMX_AUDIO_CodingPCM;
634 case MPTYPE_AC3_PRE13:
636 if (prefered_ac3 == 2 && false) { //not supported yet
639 Log::getInstance()->log("Audio", Log::DEBUG,
640 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
641 if (prefered_ac3 == 1 && canpass_ac3) {
643 encoding=OMX_AUDIO_CodingDDP;
646 encoding=OMX_AUDIO_CodingPCM;
651 case MPTYPE_MPEG_AUDIO_LAYER3: {
652 if (prefered_mp3 == 2 && false) { //not supported yet
655 if (prefered_mp3 == 1 && canpass_mp2) {
657 encoding=OMX_AUDIO_CodingMP3;
660 encoding=OMX_AUDIO_CodingPCM;
668 encoding=OMX_AUDIO_CodingPCM;
669 //mch=false; // multichannel also false
674 /*OMX_CONFIG_BOOLEANTYPE booly;
675 memset(&booly, 0, sizeof(booly));
676 booly.nSize = sizeof(booly);
677 booly.nVersion.nVersion = OMX_VERSION;
679 booly.bEnabled = OMX_TRUE;
681 booly.bEnabled = OMX_FALSE;
683 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
685 if (error != OMX_ErrorNone) {
686 Log::getInstance()->log("Audio", Log::DEBUG,
687 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
688 DeAllocateCodecsOMX();
691 VideoOMX* video=(VideoOMX*)Video::getInstance();
693 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
694 //DestroyInputBufsOMXwhilePlaying();
695 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
700 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
701 memset(&format, 0, sizeof(format));
702 format.nSize = sizeof(format);
703 format.nVersion.nVersion = OMX_VERSION;
704 format.nPortIndex = omx_rend_input_port;
705 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
707 if (error != OMX_ErrorNone) {
708 Log::getInstance()->log("Audio", Log::DEBUG,
709 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
710 omx_rend_input_port);
715 Log::getInstance()->log("Audio", Log::DEBUG,
716 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
717 format.eEncoding = encoding;
719 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
721 if (error != OMX_ErrorNone) {
722 Log::getInstance()->log("Audio", Log::DEBUG,
723 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
724 omx_rend_input_port,format.eEncoding );
729 case OMX_AUDIO_CodingPCM: {
730 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
731 memset(&audio_pcm, 0, sizeof(audio_pcm));
732 audio_pcm.nSize = sizeof(audio_pcm);
733 audio_pcm.nVersion.nVersion = OMX_VERSION;
734 audio_pcm.nChannels = 2;
735 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
736 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
737 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
738 audio_pcm.eNumData = OMX_NumericalDataSigned;
739 audio_pcm.eEndian = OMX_EndianLittle;
740 audio_pcm.bInterleaved = OMX_TRUE;
741 audio_pcm.nBitPerSample = 16;
742 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
743 audio_pcm.nChannels = 2;
744 audio_pcm.nSamplingRate = 48000;
745 audio_pcm.nPortIndex = omx_rend_input_port;
746 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
748 if (error != OMX_ErrorNone) {
749 Log::getInstance()->log("Audio", Log::DEBUG,
750 "Init OMX_IndexParamAudioPcm failed %x %d", error,
751 omx_rend_input_port);
755 case OMX_AUDIO_CodingDDP: {
756 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
757 memset(&audio_ddp, 0, sizeof(audio_ddp));
758 audio_ddp.nSize = sizeof(audio_ddp);
759 audio_ddp.nVersion.nVersion = OMX_VERSION;
760 audio_ddp.nPortIndex = omx_rend_input_port;
761 audio_ddp.nChannels = 8; //unknown
762 audio_ddp.nBitRate=0;
763 audio_ddp.nSampleRate=48000;
764 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
765 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
766 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
767 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
768 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
769 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
770 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
771 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
772 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
773 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
775 if (error != OMX_ErrorNone) {
776 Log::getInstance()->log("Audio", Log::DEBUG,
777 "Init OMX_IndexParamAudioDdp failed %x %d", error,
778 omx_rend_input_port);
783 default: break; //Make compiler happy
790 //PrepareInputBufsOMX(false);
791 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
801 int AudioOMX::InitDecoderLibAV()
804 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
805 if (!ac3codec_context_libav) {
806 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
810 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
811 ac3codec_context_libav->request_channels=2;
813 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
815 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
816 libav_mutex.Unlock();
820 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
821 if (!aaclatmcodec_context_libav) {
822 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
826 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
827 aaclatmcodec_context_libav->request_channels=2;
829 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
831 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
832 libav_mutex.Unlock();
837 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
838 if (!ac3codec_context_libav) {
839 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
840 libav_mutex.Unlock();
844 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
845 mp23codec_context_libav->request_channels=2;
847 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
849 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
850 libav_mutex.Unlock();
853 #ifdef USE_LIBRESAMPLE
854 resam_con_libav = avresample_alloc_context();
855 if (resam_con_libav == NULL) {
856 Log::getInstance()->log("Audio", Log::DEBUG,
857 "Alloc resample context failed");
861 av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format
862 av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
863 av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
865 av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
866 av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
867 av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example
870 av_init_packet(&incoming_paket_libav);
871 decode_frame_libav=avcodec_alloc_frame();
872 libav_mutex.Unlock();
873 decompress_buffer_filled=0;
880 void AudioOMX::DeinitDecoderLibAV() {
884 if (ac3codec_context_libav) {
885 avcodec_close(ac3codec_context_libav);
886 av_free(ac3codec_context_libav);
887 ac3codec_context_libav = NULL;
889 avcodec_close(aaclatmcodec_context_libav);
890 av_free(aaclatmcodec_context_libav);
891 aaclatmcodec_context_libav = NULL;
893 av_free(decode_frame_libav);
895 avcodec_close(mp23codec_context_libav);
896 av_free(mp23codec_context_libav);
897 mp23codec_context_libav = NULL;
898 #ifdef USE_LIBRESAMPLE
899 avresample_free(resam_con_libav);
900 resam_con_libav=NULL;
904 libav_mutex.Unlock();
909 int AudioOMX::AllocateCodecsOMX()
912 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
914 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
915 //Clock, move later to audio
916 VideoOMX *video=(VideoOMX*)Video::getInstance();
918 if (!InitDecoderLibAV()) return 0;;
921 OMX_PORT_PARAM_TYPE p_param;
922 memset(&p_param,0,sizeof(p_param));
923 p_param.nSize=sizeof(p_param);
924 p_param.nVersion.nVersion=OMX_VERSION;
927 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
928 return 0;// get the clock and init it if necessary
932 if (!video->idleClock()) {
937 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
938 if (error != OMX_ErrorNone) {
939 Log::getInstance()->log("Audio", Log::DEBUG,
940 "Init OMX audio rend failed %x", error);
941 video->UnlockClock();
942 DeAllocateCodecsOMX();
946 if (!ChangeAudioDestination()) {
947 video->UnlockClock();
948 DeAllocateCodecsOMX();
952 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
953 if (error != OMX_ErrorNone) {
954 Log::getInstance()->log("Audio", Log::DEBUG,
955 "Init OMX audio rend OMX_GetParameter failed %x", error);
956 video->UnlockClock();
957 DeAllocateCodecsOMX();
960 omx_rend_input_port = p_param.nStartPortNumber;
966 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
967 if (error != OMX_ErrorNone) {
968 Log::getInstance()->log("Audio", Log::DEBUG,
969 "Init OMX aud rend OMX_GetParameter failed %x", error);
970 video->UnlockClock();
971 DeAllocateCodecsOMX();
974 // buggy return value
975 omx_rend_clock_port = p_param.nStartPortNumber;
980 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
982 if (error!=OMX_ErrorNone){
983 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
984 video->UnlockClock();
985 DeAllocateCodecsOMX();
989 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
990 if (error!=OMX_ErrorNone){
991 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
992 video->UnlockClock();
993 DeAllocateCodecsOMX();
996 omx_codec_input_port=p_param.nStartPortNumber;
997 omx_codec_output_port=p_param.nStartPortNumber+1;
999 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
1000 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
1001 video->UnlockClock();
1002 DeAllocateCodecsOMX();
1009 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
1010 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
1011 video->UnlockClock();
1012 DeAllocateCodecsOMX();
1016 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
1017 Log::getInstance()->log("Audio", Log::DEBUG,
1018 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
1019 video->UnlockClock();
1020 DeAllocateCodecsOMX();
1030 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
1031 if (error!=OMX_ErrorNone){
1032 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);
1033 video->UnlockClock();
1034 DeAllocateCodecsOMX();
1038 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1040 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1041 video->UnlockClock();
1042 DeAllocateCodecsOMX();
1046 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1047 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1048 video->UnlockClock();
1049 DeAllocateCodecsOMX();
1056 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1057 video->UnlockClock();
1058 DeAllocateCodecsOMX();
1062 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1063 video->UnlockClock();
1064 DeAllocateCodecsOMX();
1070 if (!ChangeAudioPortConfig(false)){
1071 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1072 video->UnlockClock();
1073 DeAllocateCodecsOMX();
1077 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1078 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1079 DeAllocateCodecsOMX();
1085 if (!PrepareInputBufsOMX(true)) {
1086 video->UnlockClock();
1087 DeAllocateCodecsOMX();
1093 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1094 if (error!=OMX_ErrorNone){
1095 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1096 video->UnlockClock();
1097 DeAllocateCodecsOMX();
1103 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1105 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1106 video->UnlockClock();
1107 DeAllocateCodecsOMX();
1111 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1112 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1113 video->UnlockClock();
1114 DeAllocateCodecsOMX();
1118 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1119 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1120 video->UnlockClock();
1121 DeAllocateCodecsOMX();
1126 video->UnlockClock();
1130 video->clockUnpause();
1133 if (!video->setClockExecutingandRunning()) return 0;
1135 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1143 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1145 VideoOMX *video=(VideoOMX*)Video::getInstance();
1146 OMX_ERRORTYPE error;
1147 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1148 memset(&port_def_type,0,sizeof(port_def_type));
1149 port_def_type.nSize=sizeof(port_def_type);
1150 port_def_type.nVersion.nVersion=OMX_VERSION;
1151 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1153 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1155 if (error!=OMX_ErrorNone){
1156 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1161 port_def_type.nBufferCountActual=2;
1162 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1164 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1166 if (error!=OMX_ErrorNone){
1167 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1172 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1173 if (error!=OMX_ErrorNone){
1174 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1178 input_bufs_omx_mutex.Lock();
1179 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1180 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1181 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1182 if (error!=OMX_ErrorNone){
1183 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1184 input_bufs_omx_mutex.Unlock();
1187 input_bufs_omx_all.push_back(buf_head);
1188 input_bufs_omx_free.push_back(buf_head);
1190 omx_first_frame=true;
1193 cur_input_buf_omx=NULL;
1194 input_bufs_omx_mutex.Unlock();
1196 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1203 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1205 OMX_ERRORTYPE error;
1207 cur_input_buf_omx=NULL;
1208 input_bufs_omx_mutex.Lock();
1209 for (int i=0; i< input_bufs_omx_all.size();i++) {
1210 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1211 if (error!=OMX_ErrorNone){
1212 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1213 input_bufs_omx_mutex.Unlock();
1218 input_bufs_omx_all.clear();
1219 input_bufs_omx_free.clear();
1220 input_bufs_omx_mutex.Unlock();
1224 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1226 OMX_ERRORTYPE error;
1228 cur_input_buf_omx=NULL;
1229 input_bufs_omx_mutex.Lock();
1230 while (input_bufs_omx_all.size()>0) {
1231 if (input_bufs_omx_free.size()>0) {
1232 // Destroy one buffer
1233 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1234 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1235 for (; itty!= input_bufs_omx_all.end();itty++) {
1236 if ((*itty)==cur_buf) {
1237 input_bufs_omx_all.erase(itty);
1238 input_bufs_omx_free.pop_front();
1243 input_bufs_omx_mutex.Unlock();
1245 input_bufs_omx_mutex.Lock();
1249 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1250 input_bufs_omx_mutex.Unlock();
1255 int AudioOMX::DeAllocateCodecsOMX()
1257 OMX_ERRORTYPE error;
1259 VideoOMX *video=(VideoOMX*)Video::getInstance();
1260 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1264 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1265 if (cur_input_buf_omx) {
1266 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1267 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1268 if (error!=OMX_ErrorNone) {
1269 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1272 cur_input_buf_omx=NULL;//write out old data
1274 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1277 if (omx_aud_rend/*dec*/) {
1278 // first stop the omx elements
1279 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1280 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1282 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1284 video->UnlockClock();
1285 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1287 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1290 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1291 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1294 // TODO proper deinit sequence
1295 // first flush all buffers
1297 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1298 if (error!=OMX_ErrorNone) {
1299 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1303 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1304 if (error!=OMX_ErrorNone){
1305 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1310 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1311 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1316 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1317 if (error!=OMX_ErrorNone){
1318 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1322 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1323 if (error!=OMX_ErrorNone){
1324 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1327 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1329 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1330 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1331 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1334 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1335 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1336 DeinitDecoderLibAV();
1337 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1340 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1341 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1344 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1345 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1348 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1349 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1353 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1354 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1357 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1358 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1363 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1364 if (error!=OMX_ErrorNone) {
1365 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1371 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1372 if (error!=OMX_ErrorNone) {
1373 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1377 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1378 if (error!=OMX_ErrorNone) {
1379 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1383 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1384 if (error!=OMX_ErrorNone) {
1385 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1388 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1391 //error=OMX_FreeHandle(omx_aud_dec);
1392 error=OMX_FreeHandle(omx_aud_rend);
1393 video->UnlockClock();
1394 video->destroyClock();
1395 omx_aud_rend/*dec*/=NULL;
1396 if (error!=OMX_ErrorNone) {
1397 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1401 video->UnlockClock();
1402 DeinitDecoderLibAV();
1404 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1411 int AudioOMX::stop()
1413 if (!initted) return 0;
1415 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1416 DeAllocateCodecsOMX();
1417 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1421 int AudioOMX::mute() {
1424 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1425 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1429 OMX_AUDIO_CONFIG_MUTETYPE amute;
1430 memset(&amute, 0, sizeof(amute));
1431 amute.nSize = sizeof(amute);
1432 amute.nVersion.nVersion = OMX_VERSION;
1433 amute.nPortIndex = omx_rend_input_port;
1434 amute.bMute = OMX_TRUE;
1435 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1437 if (error != OMX_ErrorNone) {
1438 Log::getInstance()->log("Audio", Log::DEBUG,
1439 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1440 omx_rend_input_port);
1452 int AudioOMX::unMute()
1454 if (!initted) return 0;
1456 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1457 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1461 OMX_AUDIO_CONFIG_MUTETYPE amute;
1462 memset(&amute, 0, sizeof(amute));
1463 amute.nSize = sizeof(amute);
1464 amute.nVersion.nVersion = OMX_VERSION;
1465 amute.nPortIndex = omx_rend_input_port;
1466 amute.bMute = OMX_FALSE;
1467 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1469 if (error != OMX_ErrorNone) {
1470 Log::getInstance()->log("Audio", Log::DEBUG,
1471 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1472 omx_rend_input_port);
1484 int AudioOMX::pause() {
1488 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1494 int AudioOMX::unPause()
1496 if (!initted) return 0;
1498 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1505 int AudioOMX::reset()
1507 if (!initted) return 0;
1509 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1510 DeAllocateCodecsOMX();
1512 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1513 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1514 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1520 int AudioOMX::setVolume(int tvolume)
1522 // parameter: 0 for silence, 20 for full
1523 if ((tvolume < 0) || (tvolume > 20)) return 0;
1525 // volume = 2 * (20 - volume);
1526 // Right, that one was rubbish... 0-10 were almost
1527 // inaudible, 11-20 did what should have been done
1528 // over the whole 0-20 range
1532 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1536 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1537 memset(&avol, 0, sizeof(avol));
1538 avol.nSize = sizeof(avol);
1539 avol.nVersion.nVersion = OMX_VERSION;
1540 avol.nPortIndex = omx_rend_input_port;
1541 avol.bLinear=OMX_FALSE;
1542 avol.sVolume.nValue =(volume-20)*200;
1543 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1545 if (error != OMX_ErrorNone) {
1546 Log::getInstance()->log("Audio", Log::DEBUG,
1547 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1548 omx_rend_input_port);
1560 int AudioOMX::test()
1563 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1565 /* aud_sync_parms_t a;
1569 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1572 /*OK*/ //printf("Audio sync disable = %i\n", b);
1580 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1582 if (size<=2) return size; // silly;
1583 unsigned int test=0;
1585 //inspired by libav parsing code
1586 while (test+1<size) {
1587 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) {
1588 if ((data[test+1] & 0x18) == 0x08) {test++;continue;} //sanity check: mpeg version ID 01 -> reserved
1589 //sanity check inspired by libav
1592 const int sample_rates[4]={44100,48000,32000,0};
1593 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1594 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1595 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1596 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1597 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1598 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1599 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1600 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1603 int layer=4-((data[test+1]&0x06)>>1);
1604 if (layer==4) {test++;continue;} //sanity check
1606 int bitrate_index=(data[test+2]&0xf0)>>4;
1607 if (bitrate_index==0x0f || bitrate_index==0x0) {test++;continue;} //sanity check
1609 int samplerate_index=(data[test+2]&0x0C)>>2;
1610 if (samplerate_index==0x03) {test++;continue;} //sanity check
1612 int padding=(data[test+2]&2)>>1;
1613 if (0x10 & data[test+1]) {
1614 lsf=((data[test+1]) &0x8)?0:1;
1620 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1622 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1624 frame_size=(temp_frame_size*12000)/sample_rate;
1625 frame_size=(frame_size+padding)*4;
1626 } else if (layer==2) {
1627 frame_size=(temp_frame_size*144000)/sample_rate;
1628 frame_size=frame_size+padding;
1630 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1631 frame_size=frame_size+padding;
1633 unsigned int sameheadertest=(data[test]<<24)|(data[test+1]<<16) |(data[test+2]<<8);
1634 const unsigned mask=(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)); // from libav
1635 if (!mp3sameheader) {
1636 mp3sameheader=sameheadertest;
1637 mp3sameheadercount=2;
1639 if ((mp3sameheader& mask)== (sameheadertest &mask)) mp3sameheadercount++;
1640 else mp3sameheadercount=0;
1641 mp3sameheader=sameheadertest;
1643 //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);
1644 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME DIAG: %x %x %x %d",data[test],data[test+1],data[test+2],mp3sameheadercount);
1646 if (mp3sameheadercount>4) {
1647 *framesize=frame_size;
1648 return test; // probably FrameSync
1649 } //skip it if the header changes too frequently
1656 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1658 if (size<=4) return size; // silly;
1659 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1660 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1661 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1662 1152, 1280, 1280, };
1663 unsigned int test=0;
1664 *framesize=20000; //if we do not find a start code do not decompress
1665 while (test+4<size) {
1666 if (data[test]==0x0B && data[test+1]==0x77) {
1667 // now figure out the length of the frame
1668 unsigned char code=data[test+4];
1669 unsigned char fscod=(code& 0xC0)>>6;
1670 unsigned char frmsize=(code &0x3f);
1671 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1672 *framesize=frm_size_tab[frmsize]*2;
1673 return test; // probably FrameSync
1680 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1682 if (size<=4) return size; // silly;
1683 unsigned int test=0;
1684 *framesize=20000; //if we do not find a start code do not decompress
1685 while (test+4<size) {
1686 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1687 // now figure out the length of the frame
1688 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1689 *framesize=length+3;
1690 return test; // probably FrameSync
1696 #ifndef USE_LIBRESAMPLE
1697 #define SQRT3_2 1.22474487139158904909
1699 void AudioOMX::getDownMixMatrix(unsigned long long channels,
1700 int *left_mat,int *right_mat)
1703 double downmix_matrix[2][64];
1704 for (i=0;i<64;i++) {
1706 downmix_matrix[j][i]=0.;
1709 downmix_matrix[0/*links*/][/*FRONT_LEFT*/0]=1.;
1710 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT*/1]=1.;
1711 downmix_matrix[0/*links*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1712 downmix_matrix[1/*rechts*/] [/*FRONT_CENTER*/2] = M_SQRT1_2;
1714 if (channels & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT) ) {
1715 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2*M_SQRT1_2;
1716 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2*M_SQRT1_2;
1718 downmix_matrix[0/*links*/][/*BACK_CENTER*/8]=-M_SQRT1_2;
1719 downmix_matrix[1/*rechts*/][/*BACK_CENTER*/8]=M_SQRT1_2;
1721 downmix_matrix[0/*links*/][/*BACK_LEFT*/4 ]=-M_SQRT1_2*SQRT3_2;
1722 downmix_matrix[1/*rechts*/][/*BACK_LEFT*/4]=M_SQRT1_2*M_SQRT1_2;
1723 downmix_matrix[0/*links*/][/*BACK_RIGHT*/5 ]=-M_SQRT1_2*M_SQRT1_2;
1724 downmix_matrix[1/*rechts*/][/*BACK_RIGHT*/5]=M_SQRT1_2*SQRT3_2;
1725 downmix_matrix[0/*links*/][/*SIDE_LEFT*/9 ]=-M_SQRT1_2*SQRT3_2;
1726 downmix_matrix[1/*rechts*/][/*SIDE_LEFT*/9]=M_SQRT1_2*M_SQRT1_2;
1727 downmix_matrix[0/*links*/][/*SIDE_RIGHT*/10 ]=-M_SQRT1_2*M_SQRT1_2;
1728 downmix_matrix[1/*rechts*/][/*SIDE_RIGHT*/10]=M_SQRT1_2*SQRT3_2;
1729 downmix_matrix[0/*links*/][/*FRONT_LEFT_OF_CENTER*/6]=1.;
1730 downmix_matrix[1/*rechts*/][/*FRONT_RIGHT_OF_CENTER*/7]=1.;
1731 downmix_matrix[0/*links*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1732 downmix_matrix[1/*rechts*/][/*LOW_FREQUENCY*/3]=M_SQRT1_2;
1734 for (i=0,j=0;i<64;i++) {
1735 if ((1ULL << i)& channels) {
1736 left_mat[j]=(int)(downmix_matrix[0][i]*(1<<16));
1737 right_mat[j]=(int)(downmix_matrix[1][i]*(1<<16));
1745 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1747 packet = mplist.front();
1750 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1751 DeliverMediaPacket(packet, buffer, samplepos);
1752 if (*samplepos == packet.length) {
1760 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1762 VideoOMX *video = (VideoOMX*) Video::getInstance();
1764 OMX_PARAM_U32TYPE audio_lat;
1765 OMX_ERRORTYPE error;
1766 memset(&audio_lat, 0, sizeof(audio_lat));
1767 audio_lat.nSize = sizeof(audio_lat);
1768 audio_lat.nVersion.nVersion = OMX_VERSION;
1769 audio_lat.nPortIndex = omx_rend_input_port;
1771 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1773 video->UnlockClock();
1774 if (error != OMX_ErrorNone) {
1775 Log::getInstance()->log("Audio", Log::DEBUG,
1776 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1777 omx_rend_input_port);
1778 return pts; // no correction in case of error
1780 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1783 long long workpts=0;
1784 workpts+=addsamples;
1785 workpts-=audio_lat.nU32;
1786 workpts*=10LL*1000LL*1000LL;
1787 workpts=workpts/((long long)srate); //one second /samplerate
1793 bool AudioOMX::DrainTargetBufferFull()
1795 //Check, if we have OMX output buffers
1797 input_bufs_omx_mutex.Lock();
1798 full=(input_bufs_omx_free.size()==0);
1799 input_bufs_omx_mutex.Unlock();
1805 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1807 /*First Check, if we have an audio sample*/
1808 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1810 OMX_ERRORTYPE error;
1811 Log *logger=Log::getInstance();
1812 if (vw->InIframemode()) {
1815 return 0; //Not in iframe mode!
1818 if (!omx_running) return 0; // if we are not runnig do not do this
1819 if (vw->isClockPaused()) return 0; //Block if we pause
1820 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1822 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1824 /* if (packet.synched && packet.presentation_time <= 0) {
1825 *samplepos = packet.length;
1826 firstsynched = false;
1828 Log::getInstance()->log("Audio", Log::DEBUG,
1829 "DeliverMediaPacketOMX Frameskip");
1830 return packet.length;
1833 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1835 UINT headerstrip = 0;
1836 if (packet.disconti) {
1837 firstsynched = false;
1838 decompress_buffer_filled=0;
1839 if (cur_input_buf_omx) {
1840 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1842 if (error != OMX_ErrorNone) {
1843 Log::getInstance()->log("Audio", Log::DEBUG,
1844 "OMX_EmptyThisBuffer 1 failed %x", error);
1846 cur_input_buf_omx = NULL;
1850 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1851 if (packet.type != lastAType) {//Format Change //Push data out !
1852 firstsynched = false;
1855 Log::getInstance()->log("Audio", Log::DEBUG,"Notice audio type change %d %d", packet.type,lastAType);
1856 lastAType = packet.type;
1857 decompress_buffer_filled=0;
1859 if (cur_input_buf_omx) {
1860 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1862 if (error != OMX_ErrorNone) {
1863 Log::getInstance()->log("Audio", Log::DEBUG,
1864 "OMX_EmptyThisBuffer 2 failed %x", error);
1866 cur_input_buf_omx = NULL;
1871 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1872 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1874 if (!ChangeAudioPortConfig(true)) {
1875 Log::getInstance()->log("Audio", Log::DEBUG,
1876 "Changing audio port config failed", error);
1879 pthread_setcancelstate(oldcancelstate, NULL);
1880 pthread_setcanceltype(oldcanceltype, NULL);
1884 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1886 /*Inspect PES-Header */
1887 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1888 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1889 if (packet.type == MPTYPE_AC3)
1890 headerstrip += 4; //skip ac3 bytes
1891 *samplepos += headerstrip;
1892 if (packet.synched) {
1893 if (cur_input_buf_omx) {
1894 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1895 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1897 if (error != OMX_ErrorNone) {
1898 Log::getInstance()->log("Audio", Log::DEBUG,
1899 "OMX_EmptyThisBuffer 3 failed %x", error);
1901 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1903 cur_input_buf_omx = NULL;//write out old data
1905 firstsynched = true;
1906 //decompress_buffer_filled=0;
1908 if (!firstsynched) {//
1909 *samplepos = packet.length;//if we have not processed at least one
1910 decompress_buffer_filled=0;
1911 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1912 return packet.length;//synched packet ignore it!
1916 if (!cur_input_buf_omx) {
1917 input_bufs_omx_mutex.Lock();
1918 if (input_bufs_omx_free.size()==0) {
1919 input_bufs_omx_mutex.Unlock();
1920 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1921 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1922 return 0; // we do not have a free media sample
1925 cur_input_buf_omx=input_bufs_omx_free.front();
1926 cur_input_buf_omx->nFilledLen=0;
1927 cur_input_buf_omx->nOffset=0;
1928 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1929 input_bufs_omx_free.pop_front();
1930 input_bufs_omx_mutex.Unlock();
1932 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1934 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1935 if (packet.synched) {
1936 //Log::getInstance()->log("Audio", Log::DEBUG,
1937 // "packet synched marker");
1939 //lastreftimePTS=packet.pts;
1940 if (omx_first_frame) { // TODO time
1941 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1942 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1943 omx_first_frame = false;
1945 cur_input_buf_omx->nFlags = 0;
1946 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1948 lastreftimeOMX = packet.presentation_time;
1949 //Log::getInstance()->log("Audio", Log::DEBUG,
1950 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1951 lastreftimePTS = packet.pts;
1952 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1954 // Log::getInstance()->log("Audio", Log::DEBUG,
1955 // "packet NOT synched marker");
1956 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1957 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1960 if (packet.disconti || achange) {
1961 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1962 //mp23codec_context_libav->frame_size=-1;
1963 //ac3codec_context_libav->frame_size=-1;
1967 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1969 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1970 unsigned int haveToCopy=packet.length-*samplepos;
1973 while (haveToCopy>0) {
1974 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1976 unsigned int gotframesize=0;
1978 switch (packet.type) {
1979 case MPTYPE_MPEG_AUDIO:
1980 case MPTYPE_MPEG_AUDIO_LAYER3: {
1981 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1982 haveToCopy,&gotframesize);
1986 case MPTYPE_AC3_PRE13: {
1987 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1988 haveToCopy,&gotframesize);
1992 case MPTYPE_AAC_LATM: {
1993 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1994 haveToCopy,&gotframesize);
1998 if (adv!=haveToCopy) {
2003 *samplepos=packet.length; //no ac3 sync byte
2004 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
2005 return packet.length;
2008 // so everything is fine now do a memcpy
2009 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
2010 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2011 haveToCopy-=cancopy;
2012 cur_input_buf_omx->nFilledLen+=cancopy;
2013 *samplepos+=cancopy;
2014 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
2016 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2017 if (error != OMX_ErrorNone) {
2018 Log::getInstance()->log("Audio", Log::DEBUG,
2019 "OMX_EmptyThisBuffer 5 failed %x", error);
2021 cur_input_buf_omx=NULL;
2024 input_bufs_omx_mutex.Lock();
2025 if (input_bufs_omx_free.size()==0) {
2026 input_bufs_omx_mutex.Unlock();
2027 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
2028 return *samplepos; // we do not have a free media sample
2030 cur_input_buf_omx=input_bufs_omx_free.front();
2031 cur_input_buf_omx->nFilledLen=0;
2032 cur_input_buf_omx->nOffset=0;
2033 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2034 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2035 input_bufs_omx_free.pop_front();
2036 input_bufs_omx_mutex.Unlock();
2038 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
2041 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
2049 AVCodecContext *current_context;
2050 switch (packet.type) {
2051 case MPTYPE_MPEG_AUDIO:
2052 case MPTYPE_MPEG_AUDIO_LAYER3: {
2053 current_context = mp23codec_context_libav;
2054 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2055 else framesize=current_context->frame_size;
2057 case MPTYPE_AAC_LATM: {
2058 current_context = aaclatmcodec_context_libav;
2061 case MPTYPE_AC3_PRE13: {
2062 current_context = ac3codec_context_libav;
2066 if (decompress_buffer_filled) { // have a remaining paket
2067 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2068 memcpy(decompress_buffer+decompress_buffer_filled,
2069 buffer+packet.pos_buffer+*samplepos,
2070 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2071 incoming_paket_libav.size = decompress_buffer_filled
2072 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2073 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d %d %d",packet.type,decompress_buffer_filled,packet.synched);
2075 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2076 incoming_paket_libav.size = haveToCopy;
2078 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
2080 while (haveToCopy> 0 && errcount<3) {
2082 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
2083 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
2084 // framesize, current_context->frame_size);
2086 bool donotdecompress=false;
2087 unsigned int gotframesize=0;
2088 // if (!decompress_buffer_filled) { // only do this if no old data is present
2090 switch (packet.type) {
2091 case MPTYPE_MPEG_AUDIO:
2092 case MPTYPE_MPEG_AUDIO_LAYER3: {
2093 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2094 incoming_paket_libav.size,&gotframesize);
2098 case MPTYPE_AC3_PRE13: {
2099 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2100 incoming_paket_libav.size,&gotframesize);
2103 case MPTYPE_AAC_LATM: {
2104 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2105 incoming_paket_libav.size,&gotframesize);
2109 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2110 incoming_paket_libav.data += adv;
2111 incoming_paket_libav.size-=adv;
2114 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2115 else*/ framesize=haveToCopy;
2116 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
2117 if (haveToCopy <= 0) {
2118 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
2119 *samplepos=packet.length;
2120 return packet.length;
2126 if (gotframesize>0 && gotframesize>haveToCopy) {
2127 donotdecompress=true;
2128 errcount=100; // exit loop
2130 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
2132 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
2133 if (!donotdecompress) {
2136 pthread_testcancel();
2137 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2138 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2140 if (!omx_running || !mp23codec_context_libav
2141 || !ac3codec_context_libav) {
2142 libav_mutex.Unlock();
2145 libav_mutex.Unlock();
2146 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
2147 int save_size=incoming_paket_libav.size;
2149 if (gotframesize<=incoming_paket_libav.size) {
2150 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2151 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2152 &gotta, &incoming_paket_libav);
2154 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:E %d %d",gotframesize,incoming_paket_libav.size);
2158 //Log::getInstance()->log("Audio", Log::DEBUG, "FRAME:T %d",len);
2159 incoming_paket_libav.size=save_size;
2160 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
2161 pthread_setcancelstate(oldcancelstate, NULL);
2162 pthread_setcanceltype(oldcanceltype, NULL);
2163 pthread_testcancel();
2169 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
2170 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
2172 libav_mutex.Unlock();
2176 if (decompress_buffer_filled) { // reset to normal decoding
2178 //Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2179 haveToCopy -= min(len-decompress_buffer_filled,0);
2180 *samplepos += min(len-decompress_buffer_filled,0);
2181 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2182 /*else*/ framesize=haveToCopy;
2184 framesize=haveToCopy;
2186 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2188 decompress_buffer_filled=0;
2192 incoming_paket_libav.data += len;
2196 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2197 else*/framesize=haveToCopy;
2200 framesize=haveToCopy;
2203 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2205 incoming_paket_libav.size =framesize;
2207 //Log::getInstance()->log("Audio", Log::DEBUG,
2210 int dsize = av_samples_get_buffer_size(NULL,
2211 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2212 current_context->sample_fmt, 1);
2213 int dsize_in = av_samples_get_buffer_size(NULL,
2214 current_context->channels, decode_frame_libav->nb_samples,
2215 current_context->sample_fmt, 1);
2216 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2217 if ((cur_input_buf_omx->nFilledLen + dsize)
2218 > cur_input_buf_omx->nAllocLen ) {
2219 // I doubt that this will ever happen
2220 // Log::getInstance()->log("Audio", Log::DEBUG,
2221 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2222 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2224 if (error != OMX_ErrorNone) {
2225 Log::getInstance()->log("Audio", Log::DEBUG,
2226 "OMX_EmptyThisBuffer 4 failed %x", error);
2228 cur_input_buf_omx = NULL;
2230 if (!cur_input_buf_omx) {
2232 while (count < 10 && omx_running) {
2234 input_bufs_omx_mutex.Lock();
2235 if (input_bufs_omx_free.size() == 0) {
2236 input_bufs_omx_mutex.Unlock();
2237 // Log::getInstance()->log("Audio", Log::DEBUG,
2238 // "Deliver MediaPacket no free sample");
2240 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2241 if (!omx_running) return *samplepos;
2242 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2245 cur_input_buf_omx = input_bufs_omx_free.front();
2246 cur_input_buf_omx->nFilledLen = 0;
2247 cur_input_buf_omx->nOffset = 0;
2248 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2249 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2250 input_bufs_omx_free.pop_front();
2251 input_bufs_omx_mutex.Unlock();
2254 if (!cur_input_buf_omx) return *samplepos;
2259 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2260 if (current_context->channels==2) {
2261 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2262 decode_frame_libav->data[0], dsize);
2264 #ifndef USE_LIBRESAMPLE
2265 else if (current_context->channels==1) { //convert to stereo
2266 short* startbuffer=(short* )decode_frame_libav->data[0];
2267 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize/2);
2268 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2269 while (startbuffer!=endbuffer) {
2270 unsigned short temp=*startbuffer;
2278 unsigned int channels=current_context->channels;
2279 int left_mat[channels];
2280 int right_mat[channels];
2281 getDownMixMatrix(current_context->channel_layout,left_mat,right_mat);
2283 short* startbuffer=(short* )decode_frame_libav->data[0];
2284 short* endbuffer=(short* )(decode_frame_libav->data[0]+dsize_in);
2285 short* destbuffer=(short* )(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen);
2286 while (startbuffer!=endbuffer) {
2287 short* cur_buf=startbuffer;
2288 short* cur_buf_end=startbuffer+channels;
2292 int *mat2=right_mat;
2293 while (cur_buf!=cur_buf_end) {
2294 work1+= ((*mat1)*(*cur_buf));
2295 work2+= ((*mat2)*(*cur_buf));
2300 *destbuffer=work1>>16;
2302 *destbuffer=work2>>16;
2304 startbuffer+=channels;
2311 //untested for future use
2312 av_opt_set_int(resam_con_libav, "in_sample_rate",current_context->sample_rate,0);
2313 av_opt_set_int(resam_con_libav, "in_sample_fmt",current_context->sample_fmt,0);
2314 av_opt_set_int(resam_con_libav, "in_channel_layout",current_context->channel_layout, 0);
2315 int ret=avresample_open(resam_con_libav);
2317 Log::getInstance()->log("Audio", Log::ERR,"Opening AV resample failed %d",ret);
2319 avresample_convert(resam_con_libav, cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2320 dsize, decode_frame_libav->nb_samples,
2321 decode_frame_libav->data[0], dsize_in, decode_frame_libav->nb_samples);
2322 avresample_close(resam_con_libav);
2328 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2329 cur_input_buf_omx->nFilledLen += dsize;
2331 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2332 /* uint8_t a1=incoming_paket_libav.data[0];
2333 uint8_t a2=incoming_paket_libav.data[1];
2334 uint8_t a3=incoming_paket_libav.data[2];
2335 uint8_t a4=incoming_paket_libav.data[3];*/
2336 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2341 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2342 decompress_buffer_filled=0;
2344 //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);
2345 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2347 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2351 if (cur_input_buf_omx->nFilledLen) {
2352 //Log::getInstance()->log("Audio", Log::DEBUG,
2353 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2354 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2355 if (error != OMX_ErrorNone) {
2356 Log::getInstance()->log("Audio", Log::DEBUG,
2357 "OMX_EmptyThisBuffer 5 failed %x", error);
2359 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2360 cur_input_buf_omx = NULL;
2365 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2367 *samplepos=packet.length;
2368 return packet.length;
2374 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2375 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2376 return vw->SetStartAudioOffset(curreftime,rsync);
2379 void AudioOMX::ResetTimeOffsets() {
2380 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2381 vw->ResetTimeOffsets();