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, see <https://www.gnu.org/licenses/>.
26 #include "woptionpane.h"
27 #include "osdopenvg.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/opt.h"
37 static const char* TAG = "AudioOMX";
45 lastAType = MPTYPE_MPEG_AUDIO;
51 canpass_pcm_mch=false;
53 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
61 omx_aud_rend/*dec*/=0;
62 cur_input_buf_omx=NULL;
65 ac3codec_context_libav=NULL;
68 mp23codec_context_libav=NULL;
74 decompress_buffer=NULL;
75 decompress_buffer_size=0;
76 decompress_buffer_filled=0;
80 strcpy(L_VPE_OMX_AUDIO_REND, VPE_OMX_AUDIO_REND);
87 int AudioOMX::init(UCHAR tstreamType) {
92 streamType = tstreamType;
94 if (!initAllParams()) {
101 decompress_buffer_size=20000;
102 decompress_buffer=static_cast<UCHAR*>(malloc(decompress_buffer_size));
103 decompress_buffer_filled=0;
105 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
109 av_log_set_flags(AV_LOG_SKIP_REPEATED);
111 ac3codec_libav = avcodec_find_decoder(AV_CODEC_ID_AC3);
112 if (ac3codec_libav == NULL) {
113 LogNT::getInstance()->debug(TAG,
114 "Find libav ac3 decoder failed");
118 mp23codec_libav = avcodec_find_decoder(AV_CODEC_ID_MP3);
119 if (mp23codec_libav == NULL) {
120 LogNT::getInstance()->debug(TAG,
121 "Find libav mpeg audio decoder failed");
125 aaclatmcodec_libav = avcodec_find_decoder(AV_CODEC_ID_AAC_LATM);
126 if (aaclatmcodec_libav == NULL) {
127 LogNT::getInstance()->debug(TAG,
128 "Find libav aac latm decoder failed");
134 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
138 LogNT::getInstance()->info(TAG,
139 "TV hdmi supports mpeg1 layer 1 and 2");
141 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
145 LogNT::getInstance()->info(TAG,
146 "TV hdmi supports mpeg1 layer 3");
149 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
152 LogNT::getInstance()->info(TAG,
153 "TV hdmi supports AC3");
155 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
159 LogNT::getInstance()->info(TAG,
160 "TV hdmi supports AAC");
163 canpass_pcm_mch=false;
168 int AudioOMX::initAllParams()
170 return (setStreamType(streamType) && setChannel() && setSource());
173 int AudioOMX::shutdown()
175 if (!initted) return 0;
178 LogNT::getInstance()->debug(TAG, "audio shutdown called");
179 DeAllocateCodecsOMX();
181 free(decompress_buffer);
182 decompress_buffer=NULL;
183 decompress_buffer_size=0;
184 decompress_buffer_filled=0;
189 bool AudioOMX::loadOptionsFromServer(VDR* vdr)
191 LogNT::getInstance()->debug(TAG, "AudioOMX config load");
192 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
195 if (STRCASECMP(name, "PCM") == 0) {
197 } else if (STRCASECMP(name, "Passthrough") == 0) {
199 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
205 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
208 if (STRCASECMP(name, "PCM") == 0) {
210 } else if (STRCASECMP(name, "Passthrough") == 0) {
212 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
218 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
221 if (STRCASECMP(name, "PCM") == 0) {
223 } else if (STRCASECMP(name, "Passthrough") == 0) {
225 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
231 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
234 if (STRCASECMP(name, "PCM") == 0) {
236 } else if (STRCASECMP(name, "Passthrough") == 0) {
238 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
244 name = vdr->configLoad("AudioOMX", "AudioOutput");
247 if (STRCASECMP(name, "analog") == 0) {
249 } else if (STRCASECMP(name, "HDMI") == 0) {
260 bool AudioOMX::handleOptionChanges(Option* option)
262 if (Audio::handleOptionChanges(option))
264 switch (option->id) {
266 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
268 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
276 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
278 } else if (STRCASECMP(option->options[option->userSetChoice],
279 "Passthrough") == 0) {
281 } else if (STRCASECMP(option->options[option->userSetChoice],
282 "PCMMultichannel") == 0) {
288 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
290 } else if (STRCASECMP(option->options[option->userSetChoice],
291 "Passthrough") == 0) {
293 } else if (STRCASECMP(option->options[option->userSetChoice],
294 "PCMMultichannel") == 0) {
300 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
302 } else if (STRCASECMP(option->options[option->userSetChoice],
303 "Passthrough") == 0) {
305 } else if (STRCASECMP(option->options[option->userSetChoice],
306 "PCMMultichannel") == 0) {
312 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
314 } else if (STRCASECMP(option->options[option->userSetChoice],
315 "Passthrough") == 0) {
317 } else if (STRCASECMP(option->options[option->userSetChoice],
318 "PCMMultichannel") == 0) {
328 bool AudioOMX::saveOptionstoServer()
331 switch (prefered_ac3) {
333 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
336 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
340 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
345 switch (prefered_aac) {
347 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
350 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
354 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
359 switch (prefered_mp2) {
361 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
364 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
368 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
373 switch (prefered_mp3) {
375 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
378 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
382 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
388 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
390 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
396 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
397 UINT numChoices, UINT defaultChoice, UINT startInt,
398 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
400 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
402 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
409 static const char* audioopts[]={"analog","HDMI"};
410 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
411 options->push_back(option);
412 pane->addOptionLine(option);
415 char **ac3opts=new char *[3];
417 ac3opts[i]=new char[strlen("PCM")+1];
418 strcpy(ac3opts[i],"PCM");
421 ac3opts[i]=new char[strlen("Passthrough")+1];
422 strcpy(ac3opts[i],"PassThrough");
425 if (canpass_pcm_mch) {
426 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
427 strcpy(ac3opts[i],"PCMMultichannel");
430 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
431 options->push_back(option);
432 pane->addOptionLine(option);
434 /* char **aacopts = new char *[3];
436 aacopts[i] = new char[strlen("PCM") + 1];
437 strcpy(mp2opts[i], "PCM");
440 aacopts[i] = new char[strlen("Passthrough") + 1];
441 strcpy(aacopts[i], "PassThrough");
444 if (canpass_pcm_mch) {
445 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
446 strcpy(aacopts[i], "PCMMultichannel");
449 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
450 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
451 aacopts, NULL, true, this);
452 options->push_back(option);
453 pane->addOptionLine(option);
456 char **mp2opts = new char *[3];
458 mp2opts[i] = new char[strlen("PCM") + 1];
459 strcpy(mp2opts[i], "PCM");
462 mp2opts[i] = new char[strlen("Passthrough") + 1];
463 strcpy(mp2opts[i], "PassThrough");
466 if (canpass_pcm_mch) {
467 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
468 strcpy(mp2opts[i], "PCMMultichannel");
471 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
472 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
473 mp2opts, NULL, true, this);
474 options->push_back(option);
475 pane->addOptionLine(option);
477 char **mp3opts = new char *[3];
479 mp3opts[i] = new char[strlen("PCM") + 1];
480 strcpy(mp3opts[i], "PCM");
483 mp3opts[i] = new char[strlen("Passthrough") + 1];
484 strcpy(mp3opts[i], "PassThrough");
487 if (canpass_pcm_mch) {
488 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
489 strcpy(mp3opts[i], "PCMMultichannel");
492 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
493 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
495 options->push_back(option);
496 pane->addOptionLine(option);*/
497 // Comment unsupported modes out
506 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /* hcomp */, OMX_IN OMX_PTR /* appdata */, OMX_IN OMX_BUFFERHEADERTYPE* buffer)
508 //LogNT::getInstance()->info(TAG, "EmptyBufferDone");
509 AudioOMX* audio = static_cast<AudioOMX*>(getInstance());
510 audio->ReturnEmptyOMXBuffer(buffer);
511 return OMX_ErrorNone;
514 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer)
516 input_bufs_omx_mutex.lock();
517 //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
518 input_bufs_omx_free.push_back(buffer);
519 //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
520 input_bufs_omx_mutex.unlock();
521 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
525 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /* hcomp */, OMX_IN OMX_PTR /* appdata */, OMX_IN OMX_BUFFERHEADERTYPE* /* buffer */)
527 LogNT::getInstance()->info(TAG, "FillBufferDone");
528 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
530 return OMX_ErrorNone;
533 int AudioOMX::setStreamType(UCHAR /* type */)
535 if (!initted) return 0;
537 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
541 int AudioOMX::setChannel()
543 if (!initted) return 0;
545 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
549 int AudioOMX::setSource()
551 if (!initted) return 0;
553 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
559 if (!initted) return 0;
561 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
565 int AudioOMX::play() {
568 lastAType=MPTYPE_MPEG_AUDIO;
569 LogNT::getInstance()->debug(TAG, "enter play");
571 static_cast<VideoOMX*>(Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
573 if (!AllocateCodecsOMX()) {
580 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
583 const char * destinations[]={"local","hdmi"};
588 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
589 memset(&auddest,0,sizeof(auddest));
590 auddest.nSize=sizeof(auddest);
591 auddest.nVersion.nVersion=OMX_VERSION;
592 strcpy((char *)auddest.sName, destinations[dest]);
594 LogNT::getInstance()->debug(TAG, "setting destination to: {}",auddest.sName);
595 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
596 if (error!=OMX_ErrorNone){
597 LogNT::getInstance()->debug(TAG, "Init OMX_IndexConfigBrcmAudioDestination failed {:#x} {:#x} {}", error,omx_aud_rend,auddest.sName);
598 DeAllocateCodecsOMX();
606 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
609 //Ok first fidle a working configuration
610 LogNT::getInstance()->debug(TAG,
611 "ChangeAudioPortConfig");
613 OMX_AUDIO_CODINGTYPE encoding;
616 case MPTYPE_MPEG_AUDIO: {
617 if (prefered_mp2 == 2 && false) { //not supported yet
620 if (prefered_mp2 == 1 && canpass_mp2) {
622 encoding=OMX_AUDIO_CodingMP3;
625 encoding=OMX_AUDIO_CodingPCM;
630 case MPTYPE_AAC_LATM: {
631 if (prefered_aac == 2 && false) { //not supported yet
634 LogNT::getInstance()->debug(TAG,
635 "ChangeAudioPortConfig debug {} {}",prefered_aac,canpass_aac);
636 if (prefered_aac == 1 && canpass_aac) {
638 encoding=OMX_AUDIO_CodingAAC;
641 encoding=OMX_AUDIO_CodingPCM;
646 case MPTYPE_AC3_PRE13:
648 if (prefered_ac3 == 2 && false) { //not supported yet
651 LogNT::getInstance()->debug(TAG,
652 "ChangeAudioPortConfig debug {} {}",prefered_ac3,canpass_ac3);
653 if (prefered_ac3 == 1 && canpass_ac3) {
655 encoding=OMX_AUDIO_CodingDDP;
658 encoding=OMX_AUDIO_CodingPCM;
663 case MPTYPE_MPEG_AUDIO_LAYER3: {
664 if (prefered_mp3 == 2 && false) { //not supported yet
667 if (prefered_mp3 == 1 && canpass_mp2) {
669 encoding=OMX_AUDIO_CodingMP3;
672 encoding=OMX_AUDIO_CodingPCM;
680 encoding=OMX_AUDIO_CodingPCM;
681 //mch=false; // multichannel also false
686 /*OMX_CONFIG_BOOLEANTYPE booly;
687 memset(&booly, 0, sizeof(booly));
688 booly.nSize = sizeof(booly);
689 booly.nVersion.nVersion = OMX_VERSION;
691 booly.bEnabled = OMX_TRUE;
693 booly.bEnabled = OMX_FALSE;
695 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
697 if (error != OMX_ErrorNone) {
698 LogNT::getInstance()->debug(TAG,
699 "Init OMX_IndexParamBrcmDecoderPassThrough failed {:#x}", error);
700 DeAllocateCodecsOMX();
703 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
705 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
706 //DestroyInputBufsOMXwhilePlaying();
707 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
712 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
713 memset(&format, 0, sizeof(format));
714 format.nSize = sizeof(format);
715 format.nVersion.nVersion = OMX_VERSION;
716 format.nPortIndex = omx_rend_input_port;
717 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
719 if (error != OMX_ErrorNone) {
720 LogNT::getInstance()->debug(TAG,
721 "Get OMX_IndexParamAudioPortFormat failed {:#x} {}", error,
722 omx_rend_input_port);
727 LogNT::getInstance()->debug(TAG,
728 "Get OMX_IndexParamAudioPortFormat returned {}",format.eEncoding );
729 format.eEncoding = encoding;
731 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
733 if (error != OMX_ErrorNone) {
734 LogNT::getInstance()->debug(TAG,
735 "Set OMX_IndexParamAudioPortFormat failed {:#x} {} {}", error,
736 omx_rend_input_port,format.eEncoding );
741 case OMX_AUDIO_CodingPCM: {
742 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
743 memset(&audio_pcm, 0, sizeof(audio_pcm));
744 audio_pcm.nSize = sizeof(audio_pcm);
745 audio_pcm.nVersion.nVersion = OMX_VERSION;
746 audio_pcm.nChannels = 2;
747 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
748 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
749 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
750 audio_pcm.eNumData = OMX_NumericalDataSigned;
751 audio_pcm.eEndian = OMX_EndianLittle;
752 audio_pcm.bInterleaved = OMX_TRUE;
753 audio_pcm.nBitPerSample = 16;
754 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
755 audio_pcm.nChannels = 2;
756 audio_pcm.nSamplingRate = 48000;
757 audio_pcm.nPortIndex = omx_rend_input_port;
758 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
760 if (error != OMX_ErrorNone) {
761 LogNT::getInstance()->debug(TAG,
762 "Init OMX_IndexParamAudioPcm failed {:#x} {}", error,
763 omx_rend_input_port);
767 case OMX_AUDIO_CodingDDP: {
768 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
769 memset(&audio_ddp, 0, sizeof(audio_ddp));
770 audio_ddp.nSize = sizeof(audio_ddp);
771 audio_ddp.nVersion.nVersion = OMX_VERSION;
772 audio_ddp.nPortIndex = omx_rend_input_port;
773 audio_ddp.nChannels = 8; //unknown
774 audio_ddp.nBitRate=0;
775 audio_ddp.nSampleRate=48000;
776 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
777 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
778 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
779 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
780 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
781 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
782 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
783 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
784 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
785 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
787 if (error != OMX_ErrorNone) {
788 LogNT::getInstance()->debug(TAG,
789 "Init OMX_IndexParamAudioDdp failed {:#x} {}", error,
790 omx_rend_input_port);
795 default: break; //Make compiler happy
802 //PrepareInputBufsOMX(false);
803 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
813 int AudioOMX::InitDecoderLibAV()
816 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
817 if (!ac3codec_context_libav) {
818 LogNT::getInstance()->debug(TAG, "Alloc avcodec for ac3 decoding context failed!");
822 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1)
823 ac3codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED;
825 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
828 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
829 ac3codec_context_libav->request_channel_layout=2;
831 ac3codec_context_libav->request_channels=2;
834 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
836 LogNT::getInstance()->debug(TAG, "Opening libav codec failed");
837 libav_mutex.unlock();
841 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
842 if (!aaclatmcodec_context_libav) {
843 LogNT::getInstance()->debug(TAG, "Alloc avcodec for aac decoding context failed!");
847 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1)
848 aaclatmcodec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED;
850 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
853 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
854 aaclatmcodec_context_libav->request_channel_layout=2;
856 aaclatmcodec_context_libav->request_channels=2;
859 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
861 LogNT::getInstance()->debug(TAG, "Opening libav codec failed");
862 libav_mutex.unlock();
867 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
868 if (!ac3codec_context_libav) {
869 LogNT::getInstance()->debug(TAG, "Alloc avcodec for mp23 decoding context failed!");
870 libav_mutex.unlock();
874 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1)
875 mp23codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED;
877 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
880 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
881 mp23codec_context_libav->request_channel_layout=2;
883 mp23codec_context_libav->request_channels=2;
886 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
888 LogNT::getInstance()->debug(TAG, "Opening libav codec failed");
889 libav_mutex.unlock();
893 resam_con_libav = swr_alloc();
894 if (resam_con_libav == NULL) {
895 LogNT::getInstance()->debug(TAG,
896 "Alloc resample context failed");
900 av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format
901 av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
902 av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
903 av_opt_set_int(resam_con_libav, "matrix_encoding",AV_MATRIX_ENCODING_DPLII,0);
905 av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
906 av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
907 av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example
910 av_init_packet(&incoming_paket_libav);
911 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
912 decode_frame_libav=av_frame_alloc();
914 decode_frame_libav=avcodec_alloc_frame();
916 libav_mutex.unlock();
917 decompress_buffer_filled=0;
924 void AudioOMX::DeinitDecoderLibAV() {
928 if (ac3codec_context_libav) {
929 avcodec_close(ac3codec_context_libav);
930 av_free(ac3codec_context_libav);
931 ac3codec_context_libav = NULL;
933 avcodec_close(aaclatmcodec_context_libav);
934 av_free(aaclatmcodec_context_libav);
935 aaclatmcodec_context_libav = NULL;
937 av_free(decode_frame_libav);
939 avcodec_close(mp23codec_context_libav);
940 av_free(mp23codec_context_libav);
941 mp23codec_context_libav = NULL;
943 swr_free(&resam_con_libav);
944 resam_con_libav=NULL;
948 libav_mutex.unlock();
953 int AudioOMX::AllocateCodecsOMX()
956 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
958 LogNT::getInstance()->info(TAG, "Allocate Codecs OMX");
959 //Clock, move later to audio
960 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
962 if (!InitDecoderLibAV()) return 0;;
965 OMX_PORT_PARAM_TYPE p_param;
966 memset(&p_param,0,sizeof(p_param));
967 p_param.nSize=sizeof(p_param);
968 p_param.nVersion.nVersion=OMX_VERSION;
971 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
972 return 0;// get the clock and init it if necessary
976 if (!video->idleClock()) {
981 error = OMX_GetHandle(&omx_aud_rend, L_VPE_OMX_AUDIO_REND, NULL, &callbacks);
982 if (error != OMX_ErrorNone) {
983 LogNT::getInstance()->debug(TAG,
984 "Init OMX audio rend failed {:#x}", error);
985 video->UnlockClock();
986 DeAllocateCodecsOMX();
990 if (!ChangeAudioDestination()) {
991 video->UnlockClock();
992 DeAllocateCodecsOMX();
996 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
997 if (error != OMX_ErrorNone) {
998 LogNT::getInstance()->debug(TAG,
999 "Init OMX audio rend OMX_GetParameter failed {:#x}", error);
1000 video->UnlockClock();
1001 DeAllocateCodecsOMX();
1004 omx_rend_input_port = p_param.nStartPortNumber;
1010 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
1011 if (error != OMX_ErrorNone) {
1012 LogNT::getInstance()->debug(TAG,
1013 "Init OMX aud rend OMX_GetParameter failed {:#x}", error);
1014 video->UnlockClock();
1015 DeAllocateCodecsOMX();
1018 // buggy return value
1019 omx_rend_clock_port = p_param.nStartPortNumber;
1024 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
1026 if (error!=OMX_ErrorNone){
1027 LogNT::getInstance()->debug(TAG, "Init OMX audio decoder failed {:#x}", error);
1028 video->UnlockClock();
1029 DeAllocateCodecsOMX();
1033 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
1034 if (error!=OMX_ErrorNone){
1035 LogNT::getInstance()->debug(TAG, "Init OMX audio decoder OMX_GetParameter failed {:#x}", error);
1036 video->UnlockClock();
1037 DeAllocateCodecsOMX();
1040 omx_codec_input_port=p_param.nStartPortNumber;
1041 omx_codec_output_port=p_param.nStartPortNumber+1;
1043 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
1044 LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio decoder failed");
1045 video->UnlockClock();
1046 DeAllocateCodecsOMX();
1053 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
1054 LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio rend failed {}",omx_rend_input_port);
1055 video->UnlockClock();
1056 DeAllocateCodecsOMX();
1060 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
1061 LogNT::getInstance()->debug(TAG,
1062 "Disable Ports OMX rend clock port failed {}",omx_rend_clock_port);
1063 video->UnlockClock();
1064 DeAllocateCodecsOMX();
1074 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
1075 if (error!=OMX_ErrorNone){
1076 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel clock to rend failed {:#x} {} {}", error,omx_clock_output_port,omx_rend_clock_port);
1077 video->UnlockClock();
1078 DeAllocateCodecsOMX();
1082 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1084 LogNT::getInstance()->debug(TAG, "Enable Ports OMX clock rend failed");
1085 video->UnlockClock();
1086 DeAllocateCodecsOMX();
1090 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1091 LogNT::getInstance()->debug(TAG, "aud_rend idle ChangeComponentState");
1092 video->UnlockClock();
1093 DeAllocateCodecsOMX();
1100 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1101 video->UnlockClock();
1102 DeAllocateCodecsOMX();
1106 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1107 video->UnlockClock();
1108 DeAllocateCodecsOMX();
1114 if (!ChangeAudioPortConfig(false)){
1115 LogNT::getInstance()->info(TAG, "Change AudioPortConfig failed");
1116 video->UnlockClock();
1117 DeAllocateCodecsOMX();
1121 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1122 LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState");
1123 DeAllocateCodecsOMX();
1129 if (!PrepareInputBufsOMX(true)) {
1130 video->UnlockClock();
1131 DeAllocateCodecsOMX();
1137 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1138 if (error!=OMX_ErrorNone){
1139 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel dec to render failed {:#x}", error);
1140 video->UnlockClock();
1141 DeAllocateCodecsOMX();
1147 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1149 LogNT::getInstance()->debug(TAG, "Enable Ports OMX codec rend failed");
1150 video->UnlockClock();
1151 DeAllocateCodecsOMX();
1155 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1156 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1157 video->UnlockClock();
1158 DeAllocateCodecsOMX();
1162 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1163 LogNT::getInstance()->debug(TAG, "omx_aud_rend ChangeComponentState Execute");
1164 video->UnlockClock();
1165 DeAllocateCodecsOMX();
1170 video->UnlockClock();
1174 video->clockUnpause();
1177 if (!video->setClockExecutingandRunning()) return 0;
1179 LogNT::getInstance()->info(TAG, "Allocate Codecs OMX finished");
1184 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1186 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
1188 OMX_ERRORTYPE error;
1189 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1190 memset(&port_def_type,0,sizeof(port_def_type));
1191 port_def_type.nSize=sizeof(port_def_type);
1192 port_def_type.nVersion.nVersion=OMX_VERSION;
1193 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1195 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1197 if (error!=OMX_ErrorNone){
1198 LogNT::getInstance()->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1203 port_def_type.nBufferCountActual=2;
1204 port_def_type.nBufferSize=std::max(toi4(port_def_type.nBufferSize),50000); // for transcoder important
1206 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1208 if (error!=OMX_ErrorNone){
1209 LogNT::getInstance()->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1214 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1215 if (error!=OMX_ErrorNone){
1216 LogNT::getInstance()->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
1220 input_bufs_omx_mutex.lock();
1221 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1222 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1223 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1224 if (error!=OMX_ErrorNone){
1225 LogNT::getInstance()->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
1226 input_bufs_omx_mutex.unlock();
1229 input_bufs_omx_all.push_back(buf_head);
1230 input_bufs_omx_free.push_back(buf_head);
1232 omx_first_frame=true;
1235 cur_input_buf_omx=NULL;
1236 input_bufs_omx_mutex.unlock();
1238 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1245 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1247 OMX_ERRORTYPE error;
1249 cur_input_buf_omx=NULL;
1250 input_bufs_omx_mutex.lock();
1251 for (UINT i=0; i< input_bufs_omx_all.size();i++) {
1252 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1253 if (error!=OMX_ErrorNone){
1254 LogNT::getInstance()->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
1255 input_bufs_omx_mutex.unlock();
1260 input_bufs_omx_all.clear();
1261 input_bufs_omx_free.clear();
1262 input_bufs_omx_mutex.unlock();
1267 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1269 //OMX_ERRORTYPE error;
1271 cur_input_buf_omx=NULL;
1272 input_bufs_omx_mutex.lock();
1273 while (input_bufs_omx_all.size()>0) {
1274 if (input_bufs_omx_free.size()>0) {
1275 // Destroy one buffer
1276 std::vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1277 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1278 for (; itty!= input_bufs_omx_all.end();itty++) {
1279 if ((*itty)==cur_buf) {
1280 input_bufs_omx_all.erase(itty);
1281 input_bufs_omx_free.pop_front();
1286 input_bufs_omx_mutex.unlock();
1288 input_bufs_omx_mutex.lock();
1292 LogNT::getInstance()->debug(TAG, "DestroyInputBufsOMXwhilePlaying {} {}", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1293 input_bufs_omx_mutex.unlock();
1298 int AudioOMX::DeAllocateCodecsOMX()
1300 OMX_ERRORTYPE error;
1302 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
1303 LogNT::getInstance()->debug(TAG, "enter deallocatecodecsomx");
1306 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 1");
1307 if (cur_input_buf_omx) {
1308 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1309 error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1310 if (error!=OMX_ErrorNone) {
1311 LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 6 failed {:#x}", error);
1314 cur_input_buf_omx=NULL;//write out old data
1316 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 2");
1319 if (omx_aud_rend/*dec*/) {
1320 // first stop the omx elements
1321 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1322 LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState");
1324 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 3");
1326 video->UnlockClock();
1327 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 4");
1329 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 5");
1332 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1333 LogNT::getInstance()->debug(TAG, "aud_rend ChangeComponentState");
1336 // TODO proper deinit sequence
1337 // first flush all buffers
1339 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1340 if (error!=OMX_ErrorNone) {
1341 LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
1345 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1346 if (error!=OMX_ErrorNone){
1347 LogNT::getInstance()->debug(TAG, "OMX_Flush codec out failed {:#x}", error);
1352 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1353 LogNT::getInstance()->debug(TAG, "flush cmd codec input failed");
1358 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1359 if (error!=OMX_ErrorNone){
1360 LogNT::getInstance()->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
1364 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1365 if (error!=OMX_ErrorNone){
1366 LogNT::getInstance()->debug(TAG, "OMX_Flush rend clock failed {:#x}", error);
1369 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6");
1371 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1372 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1373 LogNT::getInstance()->debug(TAG, "flush cmd clock shed failed");
1376 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1377 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6a");
1378 DeinitDecoderLibAV();
1379 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 7");
1382 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1383 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 1");
1386 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1387 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 6");
1390 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1391 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 7");
1395 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1396 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 4");
1399 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1400 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 5");
1405 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1406 if (error!=OMX_ErrorNone) {
1407 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1413 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,0);
1414 if (error!=OMX_ErrorNone) {
1415 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1419 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
1420 if (error!=OMX_ErrorNone) {
1421 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1425 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,0);
1426 if (error!=OMX_ErrorNone) {
1427 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1430 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 8");
1433 //error=OMX_FreeHandle(omx_aud_dec);
1434 error=OMX_FreeHandle(omx_aud_rend);
1435 video->UnlockClock();
1436 video->destroyClock();
1437 omx_aud_rend/*dec*/=NULL;
1438 if (error!=OMX_ErrorNone) {
1439 LogNT::getInstance()->debug(TAG, "FreeHandle failed {}", error);
1443 video->UnlockClock();
1444 DeinitDecoderLibAV();
1446 LogNT::getInstance()->debug(TAG, "leave deallocate codecs OMX");
1453 int AudioOMX::stop()
1455 if (!initted) return 0;
1457 LogNT::getInstance()->debug(TAG, "Audio stop called");
1458 DeAllocateCodecsOMX();
1459 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1463 int AudioOMX::mute() {
1466 LogNT::getInstance()->debug(TAG, "MUTE MUTE MUTE");
1467 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1471 OMX_AUDIO_CONFIG_MUTETYPE amute;
1472 memset(&amute, 0, sizeof(amute));
1473 amute.nSize = sizeof(amute);
1474 amute.nVersion.nVersion = OMX_VERSION;
1475 amute.nPortIndex = omx_rend_input_port;
1476 amute.bMute = OMX_TRUE;
1477 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1479 if (error != OMX_ErrorNone) {
1480 LogNT::getInstance()->debug(TAG,
1481 "Set OMX_IndexConfigAudioMute failed {:#x} {}", error,
1482 omx_rend_input_port);
1494 int AudioOMX::unMute()
1496 if (!initted) return 0;
1498 LogNT::getInstance()->debug(TAG, "MUTE OFF OFF OFF");
1499 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1503 OMX_AUDIO_CONFIG_MUTETYPE amute;
1504 memset(&amute, 0, sizeof(amute));
1505 amute.nSize = sizeof(amute);
1506 amute.nVersion.nVersion = OMX_VERSION;
1507 amute.nPortIndex = omx_rend_input_port;
1508 amute.bMute = OMX_FALSE;
1509 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1511 if (error != OMX_ErrorNone) {
1512 LogNT::getInstance()->debug(TAG,
1513 "Set OMX_IndexConfigAudioMute failed {:#x} {}", error,
1514 omx_rend_input_port);
1526 int AudioOMX::pause()
1528 if (!initted) return 0;
1529 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1534 int AudioOMX::unPause()
1536 if (!initted) return 0;
1537 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1542 int AudioOMX::reset()
1544 if (!initted) return 0;
1546 LogNT::getInstance()->debug(TAG, "reset called");
1547 DeAllocateCodecsOMX();
1549 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1550 // LogNT::getInstance()->debug(TAG, "reset back");
1551 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1557 int AudioOMX::setVolume(int tvolume)
1559 // parameter: 0 for silence, 20 for full
1560 if ((tvolume < 0) || (tvolume > 20)) return 0;
1562 // volume = 2 * (20 - volume);
1563 // Right, that one was rubbish... 0-10 were almost
1564 // inaudible, 11-20 did what should have been done
1565 // over the whole 0-20 range
1568 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1573 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1574 memset(&avol, 0, sizeof(avol));
1575 avol.nSize = sizeof(avol);
1576 avol.nVersion.nVersion = OMX_VERSION;
1577 avol.nPortIndex = omx_rend_input_port;
1578 avol.bLinear=OMX_FALSE;
1579 avol.sVolume.nValue =(volume-20)*200;
1580 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1582 if (error != OMX_ErrorNone) {
1583 LogNT::getInstance()->debug(TAG,
1584 "Set OMX_IndexConfigAudioVolume failed {:#x} {}", error,
1585 omx_rend_input_port);
1597 int AudioOMX::test()
1600 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1602 /* aud_sync_parms_t a;
1606 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1609 /*OK*/ //printf("Audio sync disable = %i\n", b);
1617 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1619 if (size<=2) return size; // silly;
1620 unsigned int atest=0;
1622 //inspired by libav parsing code
1623 while (atest+1<size) {
1624 if (data[atest]==0xFF && (data[atest+1] &0xe0)==0xe0) {
1625 if ((data[atest+1] & 0x18) == 0x08) {atest++;continue;} //sanity check: mpeg version ID 01 -> reserved
1626 //sanity check inspired by libav
1629 const int sample_rates[4]={44100,48000,32000,0};
1630 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1631 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1632 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1633 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1634 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1635 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1636 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1637 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1640 int layer=4-((data[atest+1]&0x06)>>1);
1641 if (layer==4) {atest++;continue;} //sanity check
1643 int bitrate_index=(data[atest+2]&0xf0)>>4;
1644 if (bitrate_index==0x0f || bitrate_index==0x0) {atest++;continue;} //sanity check
1646 int samplerate_index=(data[atest+2]&0x0C)>>2;
1647 if (samplerate_index==0x03) {atest++;continue;} //sanity check
1649 int padding=(data[atest+2]&2)>>1;
1650 if (0x10 & data[atest+1]) {
1651 lsf=((data[atest+1]) &0x8)?0:1;
1657 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1659 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1661 frame_size=(temp_frame_size*12000)/sample_rate;
1662 frame_size=(frame_size+padding)*4;
1663 } else if (layer==2) {
1664 frame_size=(temp_frame_size*144000)/sample_rate;
1665 frame_size=frame_size+padding;
1667 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1668 frame_size=frame_size+padding;
1670 unsigned int sameheadertest=(data[atest]<<24)|(data[atest+1]<<16) |(data[atest+2]<<8);
1671 const unsigned mask=(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)); // from libav
1672 if (!mp3sameheader) {
1673 mp3sameheader=sameheadertest;
1674 mp3sameheadercount=2;
1676 if ((mp3sameheader& mask)== (sameheadertest &mask)) mp3sameheadercount++;
1677 else mp3sameheadercount=0;
1678 mp3sameheader=sameheadertest;
1680 //LogNT::getInstance()->debug(TAG, "FRAME: {} {} {} {} {} {} {}",lsf,layer,bitrate_index,sample_rate,padding,temp_frame_size, frame_size);
1681 //LogNT::getInstance()->debug(TAG, "FRAME DIAG: {:#x} {:#x} {:#x} {}",data[atest],data[atest+1],data[atest+2],mp3sameheadercount);
1683 if (mp3sameheadercount>4) {
1684 *framesize=frame_size;
1685 return atest; // probably FrameSync
1686 } //skip it if the header changes too frequently
1693 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1695 if (size<=4) return size; // silly;
1696 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1697 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1698 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1699 1152, 1280, 1280, };
1700 unsigned int atest=0;
1701 *framesize=20000; //if we do not find a start code do not decompress
1702 while (atest+4<size) {
1703 if (data[atest]==0x0B && data[atest+1]==0x77) {
1704 // now figure out the length of the frame
1705 unsigned char code=data[atest+4];
1706 unsigned char fscod=(code& 0xC0)>>6;
1707 unsigned char frmsize=(code &0x3f);
1708 if (fscod!=0) LogNT::getInstance()->debug(TAG, "warning we only support 48 KHz sampling rate");
1709 *framesize=frm_size_tab[frmsize]*2;
1710 return atest; // probably FrameSync
1717 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1719 if (size<=4) return size; // silly;
1720 unsigned int atest=0;
1721 *framesize=20000; //if we do not find a start code do not decompress
1722 while (atest+4<size) {
1723 if (data[atest] ==0x56 && (data[atest+1]& 0xe0)==0xe0) {
1724 // now figure out the length of the frame
1725 unsigned int length= ((0x1f & data[atest+1])<<8) | data[atest+2];
1726 *framesize=length+3;
1727 return atest; // probably FrameSync
1735 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist, UINT /* samplepos */)
1737 packet = mplist.front();
1740 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1741 DeliverMediaPacket(packet, buffer, samplepos);
1742 if (*samplepos == packet.length) {
1750 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate)
1752 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
1754 OMX_PARAM_U32TYPE audio_lat;
1755 OMX_ERRORTYPE error;
1756 memset(&audio_lat, 0, sizeof(audio_lat));
1757 audio_lat.nSize = sizeof(audio_lat);
1758 audio_lat.nVersion.nVersion = OMX_VERSION;
1759 audio_lat.nPortIndex = omx_rend_input_port;
1761 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1763 video->UnlockClock();
1764 if (error != OMX_ErrorNone) {
1765 LogNT::getInstance()->debug(TAG,
1766 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
1767 omx_rend_input_port);
1768 return pts; // no correction in case of error
1770 /*LogNT::getInstance()->debug(TAG, "Current audio latency {}",
1773 long long workpts=0;
1774 workpts+=addsamples;
1775 workpts-=audio_lat.nU32;
1776 workpts*=10LL*1000LL*1000LL;
1777 workpts=workpts/((long long)srate); //one second /samplerate
1783 bool AudioOMX::DrainTargetBufferFull()
1785 //Check, if we have OMX output buffers
1787 input_bufs_omx_mutex.lock();
1788 full=(input_bufs_omx_free.size()==0);
1789 input_bufs_omx_mutex.unlock();
1795 UINT AudioOMX::DeliverMediaPacket(MediaPacket mpacket, const UCHAR* buffer,
1797 /*First Check, if we have an audio sample*/
1798 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1800 OMX_ERRORTYPE error;
1801 //Log *logger=Log::getInstance();
1802 if (vw->InIframemode()) {
1805 return 0; //Not in iframe mode!
1808 if (!omx_running) return 0; // if we are not runnig do not do this
1809 if (vw->isClockPaused()) return 0; //Block if we pause
1810 //LogNT::getInstance()->debug(TAG, "DMP mark 1");
1812 //LogNT::getInstance()->debug(TAG, "DeliverMediaPacketOMX time {}",mpacket.presentation_time);
1814 /* if (mpacket.synched && mpacket.presentation_time <= 0) {
1815 *samplepos = mpacket.length;
1816 firstsynched = false;
1818 LogNT::getInstance()->debug(TAG,
1819 "DeliverMediaPacketOMX Frameskip");
1820 return mpacket.length;
1823 //LogNT::getInstance()->debug(TAG, "DMP mark 2");
1825 UINT headerstrip = 0;
1826 if (mpacket.disconti) {
1827 firstsynched = false;
1828 decompress_buffer_filled=0;
1829 if (cur_input_buf_omx) {
1830 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1832 if (error != OMX_ErrorNone) {
1833 LogNT::getInstance()->debug(TAG,
1834 "OMX_EmptyThisBuffer 1 failed {:#x}", error);
1836 cur_input_buf_omx = NULL;
1840 //LogNT::getInstance()->debug(TAG, "DMP mark 3");
1841 if (mpacket.type != lastAType) {//Format Change //Push data out !
1842 firstsynched = false;
1845 LogNT::getInstance()->debug(TAG,"Notice audio type change {} {}", mpacket.type,lastAType);
1846 lastAType = mpacket.type;
1847 decompress_buffer_filled=0;
1849 if (cur_input_buf_omx) {
1850 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1852 if (error != OMX_ErrorNone) {
1853 LogNT::getInstance()->debug(TAG,
1854 "OMX_EmptyThisBuffer 2 failed {:#x}", error);
1856 cur_input_buf_omx = NULL;
1861 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1862 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1864 if (!ChangeAudioPortConfig(true)) {
1865 LogNT::getInstance()->debug(TAG,
1866 "Changing audio port config failed", error);
1869 pthread_setcancelstate(oldcancelstate, NULL);
1870 pthread_setcanceltype(oldcanceltype, NULL);
1874 //LogNT::getInstance()->debug(TAG, "DMP mark 4");
1876 /*Inspect PES-Header */
1877 if (*samplepos == 0 && mpacket.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1878 headerstrip = buffer[mpacket.pos_buffer + 8] + 9;
1879 if (mpacket.type == MPTYPE_AC3)
1880 headerstrip += 4; //skip ac3 bytes
1881 *samplepos += headerstrip;
1882 if (mpacket.synched) {
1883 if (cur_input_buf_omx) {
1884 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1885 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1887 if (error != OMX_ErrorNone) {
1888 LogNT::getInstance()->debug(TAG,
1889 "OMX_EmptyThisBuffer 3 failed {:#x}", error);
1891 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1893 cur_input_buf_omx = NULL;//write out old data
1895 firstsynched = true;
1896 //decompress_buffer_filled=0;
1898 if (!firstsynched) {//
1899 *samplepos = mpacket.length;//if we have not processed at least one
1900 decompress_buffer_filled=0;
1901 //LogNT::getInstance()->debug(TAG, "DMP mark 5");
1902 return mpacket.length;//synched packet ignore it!
1906 if (!cur_input_buf_omx) {
1907 input_bufs_omx_mutex.lock();
1908 if (input_bufs_omx_free.size()==0) {
1909 input_bufs_omx_mutex.unlock();
1910 //LogNT::getInstance()->debug(TAG, "DMP mark 6");
1911 //LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample");
1912 return 0; // we do not have a free media sample
1915 cur_input_buf_omx=input_bufs_omx_free.front();
1916 cur_input_buf_omx->nFilledLen=0;
1917 cur_input_buf_omx->nOffset=0;
1918 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1919 input_bufs_omx_free.pop_front();
1920 input_bufs_omx_mutex.unlock();
1922 //LogNT::getInstance()->debug(TAG, "DMP mark 7");
1924 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1925 if (mpacket.synched) {
1926 //LogNT::getInstance()->debug(TAG,
1927 // "packet synched marker");
1929 //lastreftimePTS=mpacket.pts;
1930 if (omx_first_frame) { // TODO time
1931 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1932 LogNT::getInstance()->debug(TAG, "Starttime");
1933 omx_first_frame = false;
1935 cur_input_buf_omx->nFlags = 0;
1936 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1938 lastreftimeOMX = mpacket.presentation_time;
1939 //LogNT::getInstance()->debug(TAG,
1940 // "Time code {} pts {} dts {}", lastreftimeOMX, mpacket.pts,mpacket.dts);
1941 lastreftimePTS = mpacket.pts;
1942 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1944 // LogNT::getInstance()->debug(TAG,
1945 // "packet NOT synched marker");
1946 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1947 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1950 if (mpacket.disconti || achange) {
1951 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1952 //mp23codec_context_libav->frame_size=-1;
1953 //ac3codec_context_libav->frame_size=-1;
1957 //LogNT::getInstance()->debug(TAG, "DMP mark 8");
1959 if (*samplepos>mpacket.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1960 unsigned int haveToCopy=mpacket.length-*samplepos;
1963 while (haveToCopy>0) {
1964 //LogNT::getInstance()->debug(TAG, "DMP mark 9");
1966 unsigned int gotframesize=0;
1968 switch (mpacket.type) {
1969 case MPTYPE_MPEG_AUDIO:
1970 case MPTYPE_MPEG_AUDIO_LAYER3: {
1971 adv = AdvanceMpAudioSync(buffer+mpacket.pos_buffer+*samplepos,
1972 haveToCopy,&gotframesize);
1976 case MPTYPE_AC3_PRE13: {
1977 adv = AdvanceAc3AudioSync(buffer+mpacket.pos_buffer+*samplepos,
1978 haveToCopy,&gotframesize);
1982 case MPTYPE_AAC_LATM: {
1983 adv = AdvanceAacLatmAudioSync(buffer+mpacket.pos_buffer+*samplepos,
1984 haveToCopy,&gotframesize);
1988 if (adv != (int)haveToCopy) {
1993 *samplepos=mpacket.length; //no ac3 sync byte
1994 //LogNT::getInstance()->debug(TAG, "DMP mark 10");
1995 return mpacket.length;
1998 // so everything is fine now do a memcpy
1999 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
2000 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+mpacket.pos_buffer+*samplepos,cancopy);
2001 haveToCopy-=cancopy;
2002 cur_input_buf_omx->nFilledLen+=cancopy;
2003 *samplepos+=cancopy;
2004 //LogNT::getInstance()->debug(TAG, "DMP mark 11");
2006 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2007 if (error != OMX_ErrorNone) {
2008 LogNT::getInstance()->debug(TAG,
2009 "OMX_EmptyThisBuffer 5 failed {:#x}", error);
2011 cur_input_buf_omx=NULL;
2014 input_bufs_omx_mutex.lock();
2015 if (input_bufs_omx_free.size()==0) {
2016 input_bufs_omx_mutex.unlock();
2017 // LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample2");
2018 return *samplepos; // we do not have a free media sample
2020 cur_input_buf_omx=input_bufs_omx_free.front();
2021 cur_input_buf_omx->nFilledLen=0;
2022 cur_input_buf_omx->nOffset=0;
2023 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2024 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2025 input_bufs_omx_free.pop_front();
2026 input_bufs_omx_mutex.unlock();
2028 //LogNT::getInstance()->debug(TAG, "DMP mark 12");
2031 //LogNT::getInstance()->debug(TAG, "DMP mark 13");
2039 AVCodecContext *current_context;
2040 switch (mpacket.type) {
2041 case MPTYPE_MPEG_AUDIO:
2042 case MPTYPE_MPEG_AUDIO_LAYER3: {
2043 current_context = mp23codec_context_libav;
2044 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2045 else framesize=current_context->frame_size;
2047 case MPTYPE_AAC_LATM: {
2048 current_context = aaclatmcodec_context_libav;
2051 case MPTYPE_AC3_PRE13: {
2052 current_context = ac3codec_context_libav;
2056 if (decompress_buffer_filled) { // have a remaining paket
2057 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2058 memcpy(decompress_buffer+decompress_buffer_filled,
2059 buffer+mpacket.pos_buffer+*samplepos,
2060 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2061 incoming_paket_libav.size = decompress_buffer_filled
2062 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2063 //LogNT::getInstance()->debug(TAG,"Use saved audio buffer {} {} {}",mpacket.type,decompress_buffer_filled,mpacket.synched);
2065 incoming_paket_libav.data =(uint8_t*) buffer+mpacket.pos_buffer+*samplepos;
2066 incoming_paket_libav.size = haveToCopy;
2068 //LogNT::getInstance()->debug(TAG, "DMP mark 18");
2070 while (haveToCopy> 0 && errcount<3) {
2072 //LogNT::getInstance()->debug(TAG,"libav in {} {}",framesize,current_context->frame_size);
2073 //LogNT::getInstance()->debug(TAG, "libav in {} {}",
2074 // framesize, current_context->frame_size);
2076 bool donotdecompress=false;
2077 unsigned int gotframesize=0;
2078 // if (!decompress_buffer_filled) { // only do this if no old data is present
2080 switch (mpacket.type) {
2081 case MPTYPE_MPEG_AUDIO:
2082 case MPTYPE_MPEG_AUDIO_LAYER3: {
2083 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2084 incoming_paket_libav.size,&gotframesize);
2088 case MPTYPE_AC3_PRE13: {
2089 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2090 incoming_paket_libav.size,&gotframesize);
2093 case MPTYPE_AAC_LATM: {
2094 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2095 incoming_paket_libav.size,&gotframesize);
2099 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2100 incoming_paket_libav.data += adv;
2101 incoming_paket_libav.size-=adv;
2104 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2105 else*/ framesize=haveToCopy;
2106 //LogNT::getInstance()->debug(TAG,"Advance by {} {} from {}",adv,mpacket.type,*samplepos );
2107 if (haveToCopy <= 0) {
2108 // LogNT::getInstance()->debug(TAG,"No sync code in packet remove {}",mpacket.type);
2109 *samplepos=mpacket.length;
2110 return mpacket.length;
2116 if (gotframesize>0 && gotframesize>haveToCopy) {
2117 donotdecompress=true;
2118 errcount=100; // exit loop
2120 // else LogNT::getInstance()->debug(TAG,"Loop run");
2122 //LogNT::getInstance()->debug(TAG, "DMP mark 19");
2123 if (!donotdecompress) {
2126 pthread_testcancel();
2127 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2128 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2130 if (!omx_running || !mp23codec_context_libav
2131 || !ac3codec_context_libav) {
2132 libav_mutex.unlock();
2135 libav_mutex.unlock();
2136 // LogNT::getInstance()->debug(TAG,"libav out");
2137 int save_size=incoming_paket_libav.size;
2139 if ((int)gotframesize <= incoming_paket_libav.size) {
2140 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2141 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2142 &gotta, &incoming_paket_libav);
2144 //LogNT::getInstance()->debug(TAG, "FRAME:E {} {}",gotframesize,incoming_paket_libav.size);
2148 //LogNT::getInstance()->debug(TAG, "FRAME:T {}",len);
2149 incoming_paket_libav.size=save_size;
2150 //LogNT::getInstance()->debug(TAG, "libav out1");
2151 pthread_setcancelstate(oldcancelstate, NULL);
2152 pthread_setcanceltype(oldcanceltype, NULL);
2153 pthread_testcancel();
2159 //LogNT::getInstance()->debug(TAG, "libav out2");
2160 //LogNT::getInstance()->debug(TAG, "DMP mark 20");
2162 libav_mutex.unlock();
2166 if (decompress_buffer_filled) { // reset to normal decoding
2168 //LogNT::getInstance()->debug(TAG,"saved audio: {}",len);
2169 haveToCopy -= min(len-decompress_buffer_filled,0);
2170 *samplepos += min(len-decompress_buffer_filled,0);
2171 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2172 /*else*/ framesize=haveToCopy;
2174 framesize=haveToCopy;
2176 incoming_paket_libav.data =(uint8_t*) buffer+mpacket.pos_buffer+*samplepos;
2178 decompress_buffer_filled=0;
2182 incoming_paket_libav.data += len;
2186 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2187 else*/framesize=haveToCopy;
2190 framesize=haveToCopy;
2193 //LogNT::getInstance()->debug(TAG, "DMP mark 21");
2195 incoming_paket_libav.size =framesize;
2197 //LogNT::getInstance()->debug(TAG,
2200 int dsize = av_samples_get_buffer_size(NULL,
2201 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2202 AV_SAMPLE_FMT_S16, 1);
2203 /* int dsize_in = av_samples_get_buffer_size(NULL,
2204 current_context->channels, decode_frame_libav->nb_samples,
2205 current_context->sample_fmt, 1); -- unused */
2206 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2207 if ((cur_input_buf_omx->nFilledLen + dsize)
2208 > cur_input_buf_omx->nAllocLen ) {
2209 // I doubt that this will ever happen
2210 // LogNT::getInstance()->debug(TAG,
2211 // "P 2 Time code {} pts {}", lastreftimeOMX, mpacket.pts);
2212 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2214 if (error != OMX_ErrorNone) {
2215 LogNT::getInstance()->debug(TAG,
2216 "OMX_EmptyThisBuffer 4 failed {:#x}", error);
2218 cur_input_buf_omx = NULL;
2220 if (!cur_input_buf_omx) {
2222 while (count < 10 && omx_running) {
2224 input_bufs_omx_mutex.lock();
2225 if (input_bufs_omx_free.size() == 0) {
2226 input_bufs_omx_mutex.unlock();
2227 // LogNT::getInstance()->debug(TAG,
2228 // "Deliver MediaPacket no free sample");
2230 //LogNT::getInstance()->debug(TAG, "DMP mark22");
2231 if (!omx_running) return *samplepos;
2232 //LogNT::getInstance()->debug(TAG, "DMP mark 23");
2235 cur_input_buf_omx = input_bufs_omx_free.front();
2236 cur_input_buf_omx->nFilledLen = 0;
2237 cur_input_buf_omx->nOffset = 0;
2238 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2239 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2240 input_bufs_omx_free.pop_front();
2241 input_bufs_omx_mutex.unlock();
2244 if (!cur_input_buf_omx) return *samplepos;
2249 //LogNT::getInstance()->debug(TAG,"memcpy in {} {} {}" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2252 av_opt_set_int(resam_con_libav, "in_sample_rate",decode_frame_libav->sample_rate,0);
2253 av_opt_set_int(resam_con_libav, "in_sample_fmt",decode_frame_libav->format,0);
2254 av_opt_set_int(resam_con_libav, "in_channel_layout",decode_frame_libav->channel_layout, 0);
2255 //LogNT::getInstance()->error(TAG, "AV resampledata {} {} {} {}",current_context->channels,current_context->sample_rate,current_context->sample_fmt,current_context->channel_layout);
2256 //LogNT::getInstance()->error(TAG, "AV resampledata2 {} {} {}",decode_frame_libav->sample_rate,decode_frame_libav->format,decode_frame_libav->channel_layout);
2258 int ret = swr_init(resam_con_libav);
2260 LogNT::getInstance()->error(TAG, "Opening AV resample failed {}",ret);
2262 uint8_t *output=cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen;
2265 avresample_convert ( AVAudioResampleContext * avr,
2269 uint8_t *const * input,
2275 avresample_convert(resam_con_libav,
2276 &output, dsize, decode_frame_libav->nb_samples,
2277 decode_frame_libav->extended_data, decode_frame_libav->linesize[0], decode_frame_libav->nb_samples);
2280 swr_convert ( struct SwrContext * s,
2283 const uint8_t ** in,
2288 //LogNT::getInstance()->debug(TAG, "Calling swr_convert");
2290 swr_convert(resam_con_libav, &output, decode_frame_libav->nb_samples, (const uint8_t**)decode_frame_libav->extended_data, decode_frame_libav->nb_samples);
2292 swr_close(resam_con_libav);
2295 //LogNT::getInstance()->debug(TAG,"memcpy out");
2296 cur_input_buf_omx->nFilledLen += dsize;
2298 //LogNT::getInstance()->debug(TAG,"Incomplete mpeg frames in pes packet {} {}",incoming_paket_libav.size,mpacket.length);
2299 /* uint8_t a1=incoming_paket_libav.data[0];
2300 uint8_t a2=incoming_paket_libav.data[1];
2301 uint8_t a3=incoming_paket_libav.data[2];
2302 uint8_t a4=incoming_paket_libav.data[3];*/
2303 // LogNT::getInstance()->debug(TAG,"Header {:#x} {:#x} {:#x} {:#x}",a1,a2,
2308 //LogNT::getInstance()->debug(TAG, "DMP mark 24");
2309 decompress_buffer_filled=0;
2311 //LogNT::getInstance()->debug(TAG,"We can not decompress {} save for later {} {:#x} {:#x}",haveToCopy,mpacket.type,incoming_paket_libav.data,mpacket.pos_buffer);
2312 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2314 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2318 if (cur_input_buf_omx->nFilledLen) {
2319 //LogNT::getInstance()->debug(TAG,
2320 // "P 3 Time code {} pts {}", lastreftimeOMX, mpacket.pts);
2321 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2322 if (error != OMX_ErrorNone) {
2323 LogNT::getInstance()->debug(TAG,
2324 "OMX_EmptyThisBuffer 5 failed {:#x}", error);
2326 //if (mpacket.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2327 cur_input_buf_omx = NULL;
2332 //LogNT::getInstance()->debug(TAG, "DMP mark 25");
2334 *samplepos=mpacket.length;
2335 return mpacket.length;
2339 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync)
2341 VideoOMX* vw = dynamic_cast<VideoOMX*>(Video::getInstance());
2342 return vw->SetStartAudioOffset(curreftime,rsync);
2345 void AudioOMX::ResetTimeOffsets()
2347 VideoOMX* vw = dynamic_cast<VideoOMX*>(Video::getInstance());
2348 vw->ResetTimeOffsets();