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/>.
25 #include "woptionpane.h"
26 #include "osdopenvg.h"
30 #include "libavutil/channel_layout.h"
31 #include "libavutil/opt.h"
36 static const char* TAG = "AudioOMX";
44 lastAType = MPTYPE_MPEG_AUDIO;
50 canpass_pcm_mch=false;
52 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
60 omx_aud_rend/*dec*/=0;
61 cur_input_buf_omx=NULL;
64 ac3codec_context_libav=NULL;
67 mp23codec_context_libav=NULL;
73 decompress_buffer=NULL;
74 decompress_buffer_size=0;
75 decompress_buffer_filled=0;
79 strcpy(L_VPE_OMX_AUDIO_REND, VPE_OMX_AUDIO_REND);
86 int AudioOMX::init(UCHAR tstreamType) {
91 streamType = tstreamType;
93 if (!initAllParams()) {
100 decompress_buffer_size=20000;
101 decompress_buffer=static_cast<UCHAR*>(malloc(decompress_buffer_size));
102 decompress_buffer_filled=0;
104 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
108 av_log_set_flags(AV_LOG_SKIP_REPEATED);
110 ac3codec_libav = avcodec_find_decoder(AV_CODEC_ID_AC3);
111 if (ac3codec_libav == NULL) {
112 LogNT::getInstance()->debug(TAG,
113 "Find libav ac3 decoder failed");
117 mp23codec_libav = avcodec_find_decoder(AV_CODEC_ID_MP3);
118 if (mp23codec_libav == NULL) {
119 LogNT::getInstance()->debug(TAG,
120 "Find libav mpeg audio decoder failed");
124 aaclatmcodec_libav = avcodec_find_decoder(AV_CODEC_ID_AAC_LATM);
125 if (aaclatmcodec_libav == NULL) {
126 LogNT::getInstance()->debug(TAG,
127 "Find libav aac latm decoder failed");
133 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
137 LogNT::getInstance()->info(TAG,
138 "TV hdmi supports mpeg1 layer 1 and 2");
140 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
144 LogNT::getInstance()->info(TAG,
145 "TV hdmi supports mpeg1 layer 3");
148 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
151 LogNT::getInstance()->info(TAG,
152 "TV hdmi supports AC3");
154 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
158 LogNT::getInstance()->info(TAG,
159 "TV hdmi supports AAC");
162 canpass_pcm_mch=false;
167 int AudioOMX::initAllParams()
169 return (setStreamType(streamType) && setChannel() && setSource());
172 int AudioOMX::shutdown()
174 if (!initted) return 0;
177 LogNT::getInstance()->debug(TAG, "audio shutdown called");
178 DeAllocateCodecsOMX();
180 free(decompress_buffer);
181 decompress_buffer=NULL;
182 decompress_buffer_size=0;
183 decompress_buffer_filled=0;
188 bool AudioOMX::loadOptionsFromServer(VDR* vdr)
190 LogNT::getInstance()->debug(TAG, "AudioOMX config load");
191 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
194 if (STRCASECMP(name, "PCM") == 0) {
196 } else if (STRCASECMP(name, "Passthrough") == 0) {
198 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
204 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
207 if (STRCASECMP(name, "PCM") == 0) {
209 } else if (STRCASECMP(name, "Passthrough") == 0) {
211 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
217 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
220 if (STRCASECMP(name, "PCM") == 0) {
222 } else if (STRCASECMP(name, "Passthrough") == 0) {
224 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
230 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
233 if (STRCASECMP(name, "PCM") == 0) {
235 } else if (STRCASECMP(name, "Passthrough") == 0) {
237 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
243 name = vdr->configLoad("AudioOMX", "AudioOutput");
246 if (STRCASECMP(name, "analog") == 0) {
248 } else if (STRCASECMP(name, "HDMI") == 0) {
259 bool AudioOMX::handleOptionChanges(Option* option)
261 if (Audio::handleOptionChanges(option))
263 switch (option->id) {
265 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
267 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
275 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
277 } else if (STRCASECMP(option->options[option->userSetChoice],
278 "Passthrough") == 0) {
280 } else if (STRCASECMP(option->options[option->userSetChoice],
281 "PCMMultichannel") == 0) {
287 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
289 } else if (STRCASECMP(option->options[option->userSetChoice],
290 "Passthrough") == 0) {
292 } else if (STRCASECMP(option->options[option->userSetChoice],
293 "PCMMultichannel") == 0) {
299 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
301 } else if (STRCASECMP(option->options[option->userSetChoice],
302 "Passthrough") == 0) {
304 } else if (STRCASECMP(option->options[option->userSetChoice],
305 "PCMMultichannel") == 0) {
311 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
313 } else if (STRCASECMP(option->options[option->userSetChoice],
314 "Passthrough") == 0) {
316 } else if (STRCASECMP(option->options[option->userSetChoice],
317 "PCMMultichannel") == 0) {
327 bool AudioOMX::saveOptionstoServer()
330 switch (prefered_ac3) {
332 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
335 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
339 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
344 switch (prefered_aac) {
346 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
349 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
353 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
358 switch (prefered_mp2) {
360 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
363 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
367 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
372 switch (prefered_mp3) {
374 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
377 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
381 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
387 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
389 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
395 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
396 UINT numChoices, UINT defaultChoice, UINT startInt,
397 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
399 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
401 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
408 static const char* audioopts[]={"analog","HDMI"};
409 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
410 options->push_back(option);
411 pane->addOptionLine(option);
414 char **ac3opts=new char *[3];
416 ac3opts[i]=new char[strlen("PCM")+1];
417 strcpy(ac3opts[i],"PCM");
420 ac3opts[i]=new char[strlen("Passthrough")+1];
421 strcpy(ac3opts[i],"PassThrough");
424 if (canpass_pcm_mch) {
425 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
426 strcpy(ac3opts[i],"PCMMultichannel");
429 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
430 options->push_back(option);
431 pane->addOptionLine(option);
433 /* char **aacopts = new char *[3];
435 aacopts[i] = new char[strlen("PCM") + 1];
436 strcpy(mp2opts[i], "PCM");
439 aacopts[i] = new char[strlen("Passthrough") + 1];
440 strcpy(aacopts[i], "PassThrough");
443 if (canpass_pcm_mch) {
444 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
445 strcpy(aacopts[i], "PCMMultichannel");
448 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
449 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
450 aacopts, NULL, true, this);
451 options->push_back(option);
452 pane->addOptionLine(option);
455 char **mp2opts = new char *[3];
457 mp2opts[i] = new char[strlen("PCM") + 1];
458 strcpy(mp2opts[i], "PCM");
461 mp2opts[i] = new char[strlen("Passthrough") + 1];
462 strcpy(mp2opts[i], "PassThrough");
465 if (canpass_pcm_mch) {
466 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
467 strcpy(mp2opts[i], "PCMMultichannel");
470 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
471 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
472 mp2opts, NULL, true, this);
473 options->push_back(option);
474 pane->addOptionLine(option);
476 char **mp3opts = new char *[3];
478 mp3opts[i] = new char[strlen("PCM") + 1];
479 strcpy(mp3opts[i], "PCM");
482 mp3opts[i] = new char[strlen("Passthrough") + 1];
483 strcpy(mp3opts[i], "PassThrough");
486 if (canpass_pcm_mch) {
487 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
488 strcpy(mp3opts[i], "PCMMultichannel");
491 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
492 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
494 options->push_back(option);
495 pane->addOptionLine(option);*/
496 // Comment unsupported modes out
505 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /* hcomp */, OMX_IN OMX_PTR /* appdata */, OMX_IN OMX_BUFFERHEADERTYPE* buffer)
507 //LogNT::getInstance()->info(TAG, "EmptyBufferDone");
508 AudioOMX* audio = static_cast<AudioOMX*>(getInstance());
509 audio->ReturnEmptyOMXBuffer(buffer);
510 return OMX_ErrorNone;
513 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer)
515 input_bufs_omx_mutex.lock();
516 //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
517 input_bufs_omx_free.push_back(buffer);
518 //LogNT::getInstance()->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
519 input_bufs_omx_mutex.unlock();
520 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
524 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /* hcomp */, OMX_IN OMX_PTR /* appdata */, OMX_IN OMX_BUFFERHEADERTYPE* /* buffer */)
526 LogNT::getInstance()->info(TAG, "FillBufferDone");
527 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
529 return OMX_ErrorNone;
532 int AudioOMX::setStreamType(UCHAR /* type */)
534 if (!initted) return 0;
536 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
540 int AudioOMX::setChannel()
542 if (!initted) return 0;
544 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
548 int AudioOMX::setSource()
550 if (!initted) return 0;
552 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
558 if (!initted) return 0;
560 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
564 int AudioOMX::play() {
567 lastAType=MPTYPE_MPEG_AUDIO;
568 LogNT::getInstance()->debug(TAG, "enter play");
570 static_cast<VideoOMX*>(Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
572 if (!AllocateCodecsOMX()) {
579 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
582 const char * destinations[]={"local","hdmi"};
587 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
588 memset(&auddest,0,sizeof(auddest));
589 auddest.nSize=sizeof(auddest);
590 auddest.nVersion.nVersion=OMX_VERSION;
591 strcpy((char *)auddest.sName, destinations[dest]);
593 LogNT::getInstance()->debug(TAG, "setting destination to: {}",auddest.sName);
594 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
595 if (error!=OMX_ErrorNone){
596 LogNT::getInstance()->debug(TAG, "Init OMX_IndexConfigBrcmAudioDestination failed {:#x} {:#x} {}", error,omx_aud_rend,auddest.sName);
597 DeAllocateCodecsOMX();
605 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
608 //Ok first fidle a working configuration
609 LogNT::getInstance()->debug(TAG,
610 "ChangeAudioPortConfig");
612 OMX_AUDIO_CODINGTYPE encoding;
615 case MPTYPE_MPEG_AUDIO: {
616 if (prefered_mp2 == 2 && false) { //not supported yet
619 if (prefered_mp2 == 1 && canpass_mp2) {
621 encoding=OMX_AUDIO_CodingMP3;
624 encoding=OMX_AUDIO_CodingPCM;
629 case MPTYPE_AAC_LATM: {
630 if (prefered_aac == 2 && false) { //not supported yet
633 LogNT::getInstance()->debug(TAG,
634 "ChangeAudioPortConfig debug {} {}",prefered_aac,canpass_aac);
635 if (prefered_aac == 1 && canpass_aac) {
637 encoding=OMX_AUDIO_CodingAAC;
640 encoding=OMX_AUDIO_CodingPCM;
645 case MPTYPE_AC3_PRE13:
647 if (prefered_ac3 == 2 && false) { //not supported yet
650 LogNT::getInstance()->debug(TAG,
651 "ChangeAudioPortConfig debug {} {}",prefered_ac3,canpass_ac3);
652 if (prefered_ac3 == 1 && canpass_ac3) {
654 encoding=OMX_AUDIO_CodingDDP;
657 encoding=OMX_AUDIO_CodingPCM;
662 case MPTYPE_MPEG_AUDIO_LAYER3: {
663 if (prefered_mp3 == 2 && false) { //not supported yet
666 if (prefered_mp3 == 1 && canpass_mp2) {
668 encoding=OMX_AUDIO_CodingMP3;
671 encoding=OMX_AUDIO_CodingPCM;
679 encoding=OMX_AUDIO_CodingPCM;
680 //mch=false; // multichannel also false
685 /*OMX_CONFIG_BOOLEANTYPE booly;
686 memset(&booly, 0, sizeof(booly));
687 booly.nSize = sizeof(booly);
688 booly.nVersion.nVersion = OMX_VERSION;
690 booly.bEnabled = OMX_TRUE;
692 booly.bEnabled = OMX_FALSE;
694 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
696 if (error != OMX_ErrorNone) {
697 LogNT::getInstance()->debug(TAG,
698 "Init OMX_IndexParamBrcmDecoderPassThrough failed {:#x}", error);
699 DeAllocateCodecsOMX();
702 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
704 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
705 //DestroyInputBufsOMXwhilePlaying();
706 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
711 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
712 memset(&format, 0, sizeof(format));
713 format.nSize = sizeof(format);
714 format.nVersion.nVersion = OMX_VERSION;
715 format.nPortIndex = omx_rend_input_port;
716 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
718 if (error != OMX_ErrorNone) {
719 LogNT::getInstance()->debug(TAG,
720 "Get OMX_IndexParamAudioPortFormat failed {:#x} {}", error,
721 omx_rend_input_port);
726 LogNT::getInstance()->debug(TAG,
727 "Get OMX_IndexParamAudioPortFormat returned {}",format.eEncoding );
728 format.eEncoding = encoding;
730 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
732 if (error != OMX_ErrorNone) {
733 LogNT::getInstance()->debug(TAG,
734 "Set OMX_IndexParamAudioPortFormat failed {:#x} {} {}", error,
735 omx_rend_input_port,format.eEncoding );
740 case OMX_AUDIO_CodingPCM: {
741 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
742 memset(&audio_pcm, 0, sizeof(audio_pcm));
743 audio_pcm.nSize = sizeof(audio_pcm);
744 audio_pcm.nVersion.nVersion = OMX_VERSION;
745 audio_pcm.nChannels = 2;
746 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
747 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
748 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
749 audio_pcm.eNumData = OMX_NumericalDataSigned;
750 audio_pcm.eEndian = OMX_EndianLittle;
751 audio_pcm.bInterleaved = OMX_TRUE;
752 audio_pcm.nBitPerSample = 16;
753 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
754 audio_pcm.nChannels = 2;
755 audio_pcm.nSamplingRate = 48000;
756 audio_pcm.nPortIndex = omx_rend_input_port;
757 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
759 if (error != OMX_ErrorNone) {
760 LogNT::getInstance()->debug(TAG,
761 "Init OMX_IndexParamAudioPcm failed {:#x} {}", error,
762 omx_rend_input_port);
766 case OMX_AUDIO_CodingDDP: {
767 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
768 memset(&audio_ddp, 0, sizeof(audio_ddp));
769 audio_ddp.nSize = sizeof(audio_ddp);
770 audio_ddp.nVersion.nVersion = OMX_VERSION;
771 audio_ddp.nPortIndex = omx_rend_input_port;
772 audio_ddp.nChannels = 8; //unknown
773 audio_ddp.nBitRate=0;
774 audio_ddp.nSampleRate=48000;
775 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
776 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
777 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
778 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
779 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
780 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
781 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
782 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
783 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
784 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
786 if (error != OMX_ErrorNone) {
787 LogNT::getInstance()->debug(TAG,
788 "Init OMX_IndexParamAudioDdp failed {:#x} {}", error,
789 omx_rend_input_port);
794 default: break; //Make compiler happy
801 //PrepareInputBufsOMX(false);
802 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
812 int AudioOMX::InitDecoderLibAV()
815 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
816 if (!ac3codec_context_libav) {
817 LogNT::getInstance()->debug(TAG, "Alloc avcodec for ac3 decoding context failed!");
821 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1)
822 ac3codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED;
824 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
827 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
828 ac3codec_context_libav->request_channel_layout=2;
830 ac3codec_context_libav->request_channels=2;
833 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
835 LogNT::getInstance()->debug(TAG, "Opening libav codec failed");
836 libav_mutex.unlock();
840 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
841 if (!aaclatmcodec_context_libav) {
842 LogNT::getInstance()->debug(TAG, "Alloc avcodec for aac decoding context failed!");
846 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1)
847 aaclatmcodec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED;
849 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
852 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
853 aaclatmcodec_context_libav->request_channel_layout=2;
855 aaclatmcodec_context_libav->request_channels=2;
858 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
860 LogNT::getInstance()->debug(TAG, "Opening libav codec failed");
861 libav_mutex.unlock();
866 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
867 if (!ac3codec_context_libav) {
868 LogNT::getInstance()->debug(TAG, "Alloc avcodec for mp23 decoding context failed!");
869 libav_mutex.unlock();
873 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1)
874 mp23codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED;
876 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
879 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
880 mp23codec_context_libav->request_channel_layout=2;
882 mp23codec_context_libav->request_channels=2;
885 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
887 LogNT::getInstance()->debug(TAG, "Opening libav codec failed");
888 libav_mutex.unlock();
892 resam_con_libav = swr_alloc();
893 if (resam_con_libav == NULL) {
894 LogNT::getInstance()->debug(TAG,
895 "Alloc resample context failed");
899 av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format
900 av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0);
901 av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0);
902 av_opt_set_int(resam_con_libav, "matrix_encoding",AV_MATRIX_ENCODING_DPLII,0);
904 av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0);
905 av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0);
906 av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example
909 av_init_packet(&incoming_paket_libav);
910 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101)
911 decode_frame_libav=av_frame_alloc();
913 decode_frame_libav=avcodec_alloc_frame();
915 libav_mutex.unlock();
916 decompress_buffer_filled=0;
923 void AudioOMX::DeinitDecoderLibAV() {
927 if (ac3codec_context_libav) {
928 avcodec_close(ac3codec_context_libav);
929 av_free(ac3codec_context_libav);
930 ac3codec_context_libav = NULL;
932 avcodec_close(aaclatmcodec_context_libav);
933 av_free(aaclatmcodec_context_libav);
934 aaclatmcodec_context_libav = NULL;
936 av_free(decode_frame_libav);
938 avcodec_close(mp23codec_context_libav);
939 av_free(mp23codec_context_libav);
940 mp23codec_context_libav = NULL;
942 swr_free(&resam_con_libav);
943 resam_con_libav=NULL;
947 libav_mutex.unlock();
952 int AudioOMX::AllocateCodecsOMX()
955 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
957 LogNT::getInstance()->info(TAG, "Allocate Codecs OMX");
958 //Clock, move later to audio
959 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
961 if (!InitDecoderLibAV()) return 0;;
964 OMX_PORT_PARAM_TYPE p_param;
965 memset(&p_param,0,sizeof(p_param));
966 p_param.nSize=sizeof(p_param);
967 p_param.nVersion.nVersion=OMX_VERSION;
970 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
971 return 0;// get the clock and init it if necessary
975 if (!video->idleClock()) {
980 error = OMX_GetHandle(&omx_aud_rend, L_VPE_OMX_AUDIO_REND, NULL, &callbacks);
981 if (error != OMX_ErrorNone) {
982 LogNT::getInstance()->debug(TAG,
983 "Init OMX audio rend failed {:#x}", error);
984 video->UnlockClock();
985 DeAllocateCodecsOMX();
989 if (!ChangeAudioDestination()) {
990 video->UnlockClock();
991 DeAllocateCodecsOMX();
995 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
996 if (error != OMX_ErrorNone) {
997 LogNT::getInstance()->debug(TAG,
998 "Init OMX audio rend OMX_GetParameter failed {:#x}", error);
999 video->UnlockClock();
1000 DeAllocateCodecsOMX();
1003 omx_rend_input_port = p_param.nStartPortNumber;
1009 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
1010 if (error != OMX_ErrorNone) {
1011 LogNT::getInstance()->debug(TAG,
1012 "Init OMX aud rend OMX_GetParameter failed {:#x}", error);
1013 video->UnlockClock();
1014 DeAllocateCodecsOMX();
1017 // buggy return value
1018 omx_rend_clock_port = p_param.nStartPortNumber;
1023 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
1025 if (error!=OMX_ErrorNone){
1026 LogNT::getInstance()->debug(TAG, "Init OMX audio decoder failed {:#x}", error);
1027 video->UnlockClock();
1028 DeAllocateCodecsOMX();
1032 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
1033 if (error!=OMX_ErrorNone){
1034 LogNT::getInstance()->debug(TAG, "Init OMX audio decoder OMX_GetParameter failed {:#x}", error);
1035 video->UnlockClock();
1036 DeAllocateCodecsOMX();
1039 omx_codec_input_port=p_param.nStartPortNumber;
1040 omx_codec_output_port=p_param.nStartPortNumber+1;
1042 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
1043 LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio decoder failed");
1044 video->UnlockClock();
1045 DeAllocateCodecsOMX();
1052 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
1053 LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio rend failed {}",omx_rend_input_port);
1054 video->UnlockClock();
1055 DeAllocateCodecsOMX();
1059 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
1060 LogNT::getInstance()->debug(TAG,
1061 "Disable Ports OMX rend clock port failed {}",omx_rend_clock_port);
1062 video->UnlockClock();
1063 DeAllocateCodecsOMX();
1073 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
1074 if (error!=OMX_ErrorNone){
1075 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel clock to rend failed {:#x} {} {}", error,omx_clock_output_port,omx_rend_clock_port);
1076 video->UnlockClock();
1077 DeAllocateCodecsOMX();
1081 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1083 LogNT::getInstance()->debug(TAG, "Enable Ports OMX clock rend failed");
1084 video->UnlockClock();
1085 DeAllocateCodecsOMX();
1089 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1090 LogNT::getInstance()->debug(TAG, "aud_rend idle ChangeComponentState");
1091 video->UnlockClock();
1092 DeAllocateCodecsOMX();
1099 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1100 video->UnlockClock();
1101 DeAllocateCodecsOMX();
1105 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1106 video->UnlockClock();
1107 DeAllocateCodecsOMX();
1113 if (!ChangeAudioPortConfig(false)){
1114 LogNT::getInstance()->info(TAG, "Change AudioPortConfig failed");
1115 video->UnlockClock();
1116 DeAllocateCodecsOMX();
1120 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1121 LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState");
1122 DeAllocateCodecsOMX();
1128 if (!PrepareInputBufsOMX(true)) {
1129 video->UnlockClock();
1130 DeAllocateCodecsOMX();
1136 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1137 if (error!=OMX_ErrorNone){
1138 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel dec to render failed {:#x}", error);
1139 video->UnlockClock();
1140 DeAllocateCodecsOMX();
1146 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1148 LogNT::getInstance()->debug(TAG, "Enable Ports OMX codec rend failed");
1149 video->UnlockClock();
1150 DeAllocateCodecsOMX();
1154 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1155 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1156 video->UnlockClock();
1157 DeAllocateCodecsOMX();
1161 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1162 LogNT::getInstance()->debug(TAG, "omx_aud_rend ChangeComponentState Execute");
1163 video->UnlockClock();
1164 DeAllocateCodecsOMX();
1169 video->UnlockClock();
1173 video->clockUnpause();
1176 if (!video->setClockExecutingandRunning()) return 0;
1178 LogNT::getInstance()->info(TAG, "Allocate Codecs OMX finished");
1183 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1185 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
1187 OMX_ERRORTYPE error;
1188 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1189 memset(&port_def_type,0,sizeof(port_def_type));
1190 port_def_type.nSize=sizeof(port_def_type);
1191 port_def_type.nVersion.nVersion=OMX_VERSION;
1192 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1194 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1196 if (error!=OMX_ErrorNone){
1197 LogNT::getInstance()->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1202 port_def_type.nBufferCountActual=2;
1203 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1205 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1207 if (error!=OMX_ErrorNone){
1208 LogNT::getInstance()->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1213 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1214 if (error!=OMX_ErrorNone){
1215 LogNT::getInstance()->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
1219 input_bufs_omx_mutex.lock();
1220 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1221 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1222 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1223 if (error!=OMX_ErrorNone){
1224 LogNT::getInstance()->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
1225 input_bufs_omx_mutex.unlock();
1228 input_bufs_omx_all.push_back(buf_head);
1229 input_bufs_omx_free.push_back(buf_head);
1231 omx_first_frame=true;
1234 cur_input_buf_omx=NULL;
1235 input_bufs_omx_mutex.unlock();
1237 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1244 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1246 OMX_ERRORTYPE error;
1248 cur_input_buf_omx=NULL;
1249 input_bufs_omx_mutex.lock();
1250 for (UINT i=0; i< input_bufs_omx_all.size();i++) {
1251 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1252 if (error!=OMX_ErrorNone){
1253 LogNT::getInstance()->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
1254 input_bufs_omx_mutex.unlock();
1259 input_bufs_omx_all.clear();
1260 input_bufs_omx_free.clear();
1261 input_bufs_omx_mutex.unlock();
1266 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1268 //OMX_ERRORTYPE error;
1270 cur_input_buf_omx=NULL;
1271 input_bufs_omx_mutex.lock();
1272 while (input_bufs_omx_all.size()>0) {
1273 if (input_bufs_omx_free.size()>0) {
1274 // Destroy one buffer
1275 std::vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1276 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1277 for (; itty!= input_bufs_omx_all.end();itty++) {
1278 if ((*itty)==cur_buf) {
1279 input_bufs_omx_all.erase(itty);
1280 input_bufs_omx_free.pop_front();
1285 input_bufs_omx_mutex.unlock();
1287 input_bufs_omx_mutex.lock();
1291 LogNT::getInstance()->debug(TAG, "DestroyInputBufsOMXwhilePlaying {} {}", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1292 input_bufs_omx_mutex.unlock();
1297 int AudioOMX::DeAllocateCodecsOMX()
1299 OMX_ERRORTYPE error;
1301 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
1302 LogNT::getInstance()->debug(TAG, "enter deallocatecodecsomx");
1305 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 1");
1306 if (cur_input_buf_omx) {
1307 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1308 error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1309 if (error!=OMX_ErrorNone) {
1310 LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 6 failed {:#x}", error);
1313 cur_input_buf_omx=NULL;//write out old data
1315 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 2");
1318 if (omx_aud_rend/*dec*/) {
1319 // first stop the omx elements
1320 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1321 LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState");
1323 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 3");
1325 video->UnlockClock();
1326 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 4");
1328 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 5");
1331 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1332 LogNT::getInstance()->debug(TAG, "aud_rend ChangeComponentState");
1335 // TODO proper deinit sequence
1336 // first flush all buffers
1338 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1339 if (error!=OMX_ErrorNone) {
1340 LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
1344 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1345 if (error!=OMX_ErrorNone){
1346 LogNT::getInstance()->debug(TAG, "OMX_Flush codec out failed {:#x}", error);
1351 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1352 LogNT::getInstance()->debug(TAG, "flush cmd codec input failed");
1357 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1358 if (error!=OMX_ErrorNone){
1359 LogNT::getInstance()->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
1363 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1364 if (error!=OMX_ErrorNone){
1365 LogNT::getInstance()->debug(TAG, "OMX_Flush rend clock failed {:#x}", error);
1368 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6");
1370 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1371 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1372 LogNT::getInstance()->debug(TAG, "flush cmd clock shed failed");
1375 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1376 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6a");
1377 DeinitDecoderLibAV();
1378 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 7");
1381 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1382 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 1");
1385 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1386 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 6");
1389 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1390 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 7");
1394 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1395 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 4");
1398 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1399 LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 5");
1404 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1405 if (error!=OMX_ErrorNone) {
1406 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1412 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,0);
1413 if (error!=OMX_ErrorNone) {
1414 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1418 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
1419 if (error!=OMX_ErrorNone) {
1420 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1424 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,0);
1425 if (error!=OMX_ErrorNone) {
1426 LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
1429 LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 8");
1432 //error=OMX_FreeHandle(omx_aud_dec);
1433 error=OMX_FreeHandle(omx_aud_rend);
1434 video->UnlockClock();
1435 video->destroyClock();
1436 omx_aud_rend/*dec*/=NULL;
1437 if (error!=OMX_ErrorNone) {
1438 LogNT::getInstance()->debug(TAG, "FreeHandle failed {}", error);
1442 video->UnlockClock();
1443 DeinitDecoderLibAV();
1445 LogNT::getInstance()->debug(TAG, "leave deallocate codecs OMX");
1452 int AudioOMX::stop()
1454 if (!initted) return 0;
1456 LogNT::getInstance()->debug(TAG, "Audio stop called");
1457 DeAllocateCodecsOMX();
1458 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1462 int AudioOMX::mute() {
1465 LogNT::getInstance()->debug(TAG, "MUTE MUTE MUTE");
1466 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1470 OMX_AUDIO_CONFIG_MUTETYPE amute;
1471 memset(&amute, 0, sizeof(amute));
1472 amute.nSize = sizeof(amute);
1473 amute.nVersion.nVersion = OMX_VERSION;
1474 amute.nPortIndex = omx_rend_input_port;
1475 amute.bMute = OMX_TRUE;
1476 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1478 if (error != OMX_ErrorNone) {
1479 LogNT::getInstance()->debug(TAG,
1480 "Set OMX_IndexConfigAudioMute failed {:#x} {}", error,
1481 omx_rend_input_port);
1493 int AudioOMX::unMute()
1495 if (!initted) return 0;
1497 LogNT::getInstance()->debug(TAG, "MUTE OFF OFF OFF");
1498 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1502 OMX_AUDIO_CONFIG_MUTETYPE amute;
1503 memset(&amute, 0, sizeof(amute));
1504 amute.nSize = sizeof(amute);
1505 amute.nVersion.nVersion = OMX_VERSION;
1506 amute.nPortIndex = omx_rend_input_port;
1507 amute.bMute = OMX_FALSE;
1508 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1510 if (error != OMX_ErrorNone) {
1511 LogNT::getInstance()->debug(TAG,
1512 "Set OMX_IndexConfigAudioMute failed {:#x} {}", error,
1513 omx_rend_input_port);
1525 int AudioOMX::pause()
1527 if (!initted) return 0;
1528 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1533 int AudioOMX::unPause()
1535 if (!initted) return 0;
1536 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1541 int AudioOMX::reset()
1543 if (!initted) return 0;
1545 LogNT::getInstance()->debug(TAG, "reset called");
1546 DeAllocateCodecsOMX();
1548 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1549 // LogNT::getInstance()->debug(TAG, "reset back");
1550 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1556 int AudioOMX::setVolume(int tvolume)
1558 // parameter: 0 for silence, 20 for full
1559 if ((tvolume < 0) || (tvolume > 20)) return 0;
1561 // volume = 2 * (20 - volume);
1562 // Right, that one was rubbish... 0-10 were almost
1563 // inaudible, 11-20 did what should have been done
1564 // over the whole 0-20 range
1567 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1572 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1573 memset(&avol, 0, sizeof(avol));
1574 avol.nSize = sizeof(avol);
1575 avol.nVersion.nVersion = OMX_VERSION;
1576 avol.nPortIndex = omx_rend_input_port;
1577 avol.bLinear=OMX_FALSE;
1578 avol.sVolume.nValue =(volume-20)*200;
1579 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1581 if (error != OMX_ErrorNone) {
1582 LogNT::getInstance()->debug(TAG,
1583 "Set OMX_IndexConfigAudioVolume failed {:#x} {}", error,
1584 omx_rend_input_port);
1596 int AudioOMX::test()
1599 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1601 /* aud_sync_parms_t a;
1605 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1608 /*OK*/ //printf("Audio sync disable = %i\n", b);
1616 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1618 if (size<=2) return size; // silly;
1619 unsigned int atest=0;
1621 //inspired by libav parsing code
1622 while (atest+1<size) {
1623 if (data[atest]==0xFF && (data[atest+1] &0xe0)==0xe0) {
1624 if ((data[atest+1] & 0x18) == 0x08) {atest++;continue;} //sanity check: mpeg version ID 01 -> reserved
1625 //sanity check inspired by libav
1628 const int sample_rates[4]={44100,48000,32000,0};
1629 const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160,
1630 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48,
1631 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, {
1632 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224,
1633 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1634 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56,
1635 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40,
1636 48, 56, 64, 80, 96, 112, 128, 144, 160 } } };
1639 int layer=4-((data[atest+1]&0x06)>>1);
1640 if (layer==4) {atest++;continue;} //sanity check
1642 int bitrate_index=(data[atest+2]&0xf0)>>4;
1643 if (bitrate_index==0x0f || bitrate_index==0x0) {atest++;continue;} //sanity check
1645 int samplerate_index=(data[atest+2]&0x0C)>>2;
1646 if (samplerate_index==0x03) {atest++;continue;} //sanity check
1648 int padding=(data[atest+2]&2)>>1;
1649 if (0x10 & data[atest+1]) {
1650 lsf=((data[atest+1]) &0x8)?0:1;
1656 int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2);
1658 int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index];
1660 frame_size=(temp_frame_size*12000)/sample_rate;
1661 frame_size=(frame_size+padding)*4;
1662 } else if (layer==2) {
1663 frame_size=(temp_frame_size*144000)/sample_rate;
1664 frame_size=frame_size+padding;
1666 frame_size=(temp_frame_size*144000)/(sample_rate<<lsf);
1667 frame_size=frame_size+padding;
1669 unsigned int sameheadertest=(data[atest]<<24)|(data[atest+1]<<16) |(data[atest+2]<<8);
1670 const unsigned mask=(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)); // from libav
1671 if (!mp3sameheader) {
1672 mp3sameheader=sameheadertest;
1673 mp3sameheadercount=2;
1675 if ((mp3sameheader& mask)== (sameheadertest &mask)) mp3sameheadercount++;
1676 else mp3sameheadercount=0;
1677 mp3sameheader=sameheadertest;
1679 //LogNT::getInstance()->debug(TAG, "FRAME: {} {} {} {} {} {} {}",lsf,layer,bitrate_index,sample_rate,padding,temp_frame_size, frame_size);
1680 //LogNT::getInstance()->debug(TAG, "FRAME DIAG: {:#x} {:#x} {:#x} {}",data[atest],data[atest+1],data[atest+2],mp3sameheadercount);
1682 if (mp3sameheadercount>4) {
1683 *framesize=frame_size;
1684 return atest; // probably FrameSync
1685 } //skip it if the header changes too frequently
1692 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1694 if (size<=4) return size; // silly;
1695 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1696 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1697 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1698 1152, 1280, 1280, };
1699 unsigned int atest=0;
1700 *framesize=20000; //if we do not find a start code do not decompress
1701 while (atest+4<size) {
1702 if (data[atest]==0x0B && data[atest+1]==0x77) {
1703 // now figure out the length of the frame
1704 unsigned char code=data[atest+4];
1705 unsigned char fscod=(code& 0xC0)>>6;
1706 unsigned char frmsize=(code &0x3f);
1707 if (fscod!=0) LogNT::getInstance()->debug(TAG, "warning we only support 48 KHz sampling rate");
1708 *framesize=frm_size_tab[frmsize]*2;
1709 return atest; // probably FrameSync
1716 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1718 if (size<=4) return size; // silly;
1719 unsigned int atest=0;
1720 *framesize=20000; //if we do not find a start code do not decompress
1721 while (atest+4<size) {
1722 if (data[atest] ==0x56 && (data[atest+1]& 0xe0)==0xe0) {
1723 // now figure out the length of the frame
1724 unsigned int length= ((0x1f & data[atest+1])<<8) | data[atest+2];
1725 *framesize=length+3;
1726 return atest; // probably FrameSync
1734 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist, UINT /* samplepos */)
1736 packet = mplist.front();
1739 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1740 DeliverMediaPacket(packet, buffer, samplepos);
1741 if (*samplepos == packet.length) {
1749 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate)
1751 VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
1753 OMX_PARAM_U32TYPE audio_lat;
1754 OMX_ERRORTYPE error;
1755 memset(&audio_lat, 0, sizeof(audio_lat));
1756 audio_lat.nSize = sizeof(audio_lat);
1757 audio_lat.nVersion.nVersion = OMX_VERSION;
1758 audio_lat.nPortIndex = omx_rend_input_port;
1760 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1762 video->UnlockClock();
1763 if (error != OMX_ErrorNone) {
1764 LogNT::getInstance()->debug(TAG,
1765 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
1766 omx_rend_input_port);
1767 return pts; // no correction in case of error
1769 /*LogNT::getInstance()->debug(TAG, "Current audio latency {}",
1772 long long workpts=0;
1773 workpts+=addsamples;
1774 workpts-=audio_lat.nU32;
1775 workpts*=10LL*1000LL*1000LL;
1776 workpts=workpts/((long long)srate); //one second /samplerate
1782 bool AudioOMX::DrainTargetBufferFull()
1784 //Check, if we have OMX output buffers
1786 input_bufs_omx_mutex.lock();
1787 full=(input_bufs_omx_free.size()==0);
1788 input_bufs_omx_mutex.unlock();
1794 UINT AudioOMX::DeliverMediaPacket(MediaPacket mpacket, const UCHAR* buffer,
1796 /*First Check, if we have an audio sample*/
1797 VideoOMX* vw = static_cast<VideoOMX*>(Video::getInstance());
1799 OMX_ERRORTYPE error;
1800 //Log *logger=Log::getInstance();
1801 if (vw->InIframemode()) {
1804 return 0; //Not in iframe mode!
1807 if (!omx_running) return 0; // if we are not runnig do not do this
1808 if (vw->isClockPaused()) return 0; //Block if we pause
1809 //LogNT::getInstance()->debug(TAG, "DMP mark 1");
1811 //LogNT::getInstance()->debug(TAG, "DeliverMediaPacketOMX time {}",mpacket.presentation_time);
1813 /* if (mpacket.synched && mpacket.presentation_time <= 0) {
1814 *samplepos = mpacket.length;
1815 firstsynched = false;
1817 LogNT::getInstance()->debug(TAG,
1818 "DeliverMediaPacketOMX Frameskip");
1819 return mpacket.length;
1822 //LogNT::getInstance()->debug(TAG, "DMP mark 2");
1824 UINT headerstrip = 0;
1825 if (mpacket.disconti) {
1826 firstsynched = false;
1827 decompress_buffer_filled=0;
1828 if (cur_input_buf_omx) {
1829 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1831 if (error != OMX_ErrorNone) {
1832 LogNT::getInstance()->debug(TAG,
1833 "OMX_EmptyThisBuffer 1 failed {:#x}", error);
1835 cur_input_buf_omx = NULL;
1839 //LogNT::getInstance()->debug(TAG, "DMP mark 3");
1840 if (mpacket.type != lastAType) {//Format Change //Push data out !
1841 firstsynched = false;
1844 LogNT::getInstance()->debug(TAG,"Notice audio type change {} {}", mpacket.type,lastAType);
1845 lastAType = mpacket.type;
1846 decompress_buffer_filled=0;
1848 if (cur_input_buf_omx) {
1849 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1851 if (error != OMX_ErrorNone) {
1852 LogNT::getInstance()->debug(TAG,
1853 "OMX_EmptyThisBuffer 2 failed {:#x}", error);
1855 cur_input_buf_omx = NULL;
1860 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1861 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1863 if (!ChangeAudioPortConfig(true)) {
1864 LogNT::getInstance()->debug(TAG,
1865 "Changing audio port config failed", error);
1868 pthread_setcancelstate(oldcancelstate, NULL);
1869 pthread_setcanceltype(oldcanceltype, NULL);
1873 //LogNT::getInstance()->debug(TAG, "DMP mark 4");
1875 /*Inspect PES-Header */
1876 if (*samplepos == 0 && mpacket.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1877 headerstrip = buffer[mpacket.pos_buffer + 8] + 9;
1878 if (mpacket.type == MPTYPE_AC3)
1879 headerstrip += 4; //skip ac3 bytes
1880 *samplepos += headerstrip;
1881 if (mpacket.synched) {
1882 if (cur_input_buf_omx) {
1883 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1884 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1886 if (error != OMX_ErrorNone) {
1887 LogNT::getInstance()->debug(TAG,
1888 "OMX_EmptyThisBuffer 3 failed {:#x}", error);
1890 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1892 cur_input_buf_omx = NULL;//write out old data
1894 firstsynched = true;
1895 //decompress_buffer_filled=0;
1897 if (!firstsynched) {//
1898 *samplepos = mpacket.length;//if we have not processed at least one
1899 decompress_buffer_filled=0;
1900 //LogNT::getInstance()->debug(TAG, "DMP mark 5");
1901 return mpacket.length;//synched packet ignore it!
1905 if (!cur_input_buf_omx) {
1906 input_bufs_omx_mutex.lock();
1907 if (input_bufs_omx_free.size()==0) {
1908 input_bufs_omx_mutex.unlock();
1909 //LogNT::getInstance()->debug(TAG, "DMP mark 6");
1910 //LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample");
1911 return 0; // we do not have a free media sample
1914 cur_input_buf_omx=input_bufs_omx_free.front();
1915 cur_input_buf_omx->nFilledLen=0;
1916 cur_input_buf_omx->nOffset=0;
1917 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1918 input_bufs_omx_free.pop_front();
1919 input_bufs_omx_mutex.unlock();
1921 //LogNT::getInstance()->debug(TAG, "DMP mark 7");
1923 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1924 if (mpacket.synched) {
1925 //LogNT::getInstance()->debug(TAG,
1926 // "packet synched marker");
1928 //lastreftimePTS=mpacket.pts;
1929 if (omx_first_frame) { // TODO time
1930 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1931 LogNT::getInstance()->debug(TAG, "Starttime");
1932 omx_first_frame = false;
1934 cur_input_buf_omx->nFlags = 0;
1935 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1937 lastreftimeOMX = mpacket.presentation_time;
1938 //LogNT::getInstance()->debug(TAG,
1939 // "Time code {} pts {} dts {}", lastreftimeOMX, mpacket.pts,mpacket.dts);
1940 lastreftimePTS = mpacket.pts;
1941 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1943 // LogNT::getInstance()->debug(TAG,
1944 // "packet NOT synched marker");
1945 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1946 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1949 if (mpacket.disconti || achange) {
1950 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1951 //mp23codec_context_libav->frame_size=-1;
1952 //ac3codec_context_libav->frame_size=-1;
1956 //LogNT::getInstance()->debug(TAG, "DMP mark 8");
1958 if (*samplepos>mpacket.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1959 unsigned int haveToCopy=mpacket.length-*samplepos;
1962 while (haveToCopy>0) {
1963 //LogNT::getInstance()->debug(TAG, "DMP mark 9");
1965 unsigned int gotframesize=0;
1967 switch (mpacket.type) {
1968 case MPTYPE_MPEG_AUDIO:
1969 case MPTYPE_MPEG_AUDIO_LAYER3: {
1970 adv = AdvanceMpAudioSync(buffer+mpacket.pos_buffer+*samplepos,
1971 haveToCopy,&gotframesize);
1975 case MPTYPE_AC3_PRE13: {
1976 adv = AdvanceAc3AudioSync(buffer+mpacket.pos_buffer+*samplepos,
1977 haveToCopy,&gotframesize);
1981 case MPTYPE_AAC_LATM: {
1982 adv = AdvanceAacLatmAudioSync(buffer+mpacket.pos_buffer+*samplepos,
1983 haveToCopy,&gotframesize);
1987 if (adv != (int)haveToCopy) {
1992 *samplepos=mpacket.length; //no ac3 sync byte
1993 //LogNT::getInstance()->debug(TAG, "DMP mark 10");
1994 return mpacket.length;
1997 // so everything is fine now do a memcpy
1998 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1999 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+mpacket.pos_buffer+*samplepos,cancopy);
2000 haveToCopy-=cancopy;
2001 cur_input_buf_omx->nFilledLen+=cancopy;
2002 *samplepos+=cancopy;
2003 //LogNT::getInstance()->debug(TAG, "DMP mark 11");
2005 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2006 if (error != OMX_ErrorNone) {
2007 LogNT::getInstance()->debug(TAG,
2008 "OMX_EmptyThisBuffer 5 failed {:#x}", error);
2010 cur_input_buf_omx=NULL;
2013 input_bufs_omx_mutex.lock();
2014 if (input_bufs_omx_free.size()==0) {
2015 input_bufs_omx_mutex.unlock();
2016 // LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample2");
2017 return *samplepos; // we do not have a free media sample
2019 cur_input_buf_omx=input_bufs_omx_free.front();
2020 cur_input_buf_omx->nFilledLen=0;
2021 cur_input_buf_omx->nOffset=0;
2022 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2023 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
2024 input_bufs_omx_free.pop_front();
2025 input_bufs_omx_mutex.unlock();
2027 //LogNT::getInstance()->debug(TAG, "DMP mark 12");
2030 //LogNT::getInstance()->debug(TAG, "DMP mark 13");
2038 AVCodecContext *current_context;
2039 switch (mpacket.type) {
2040 case MPTYPE_MPEG_AUDIO:
2041 case MPTYPE_MPEG_AUDIO_LAYER3: {
2042 current_context = mp23codec_context_libav;
2043 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
2044 else framesize=current_context->frame_size;
2046 case MPTYPE_AAC_LATM: {
2047 current_context = aaclatmcodec_context_libav;
2050 case MPTYPE_AC3_PRE13: {
2051 current_context = ac3codec_context_libav;
2055 if (decompress_buffer_filled) { // have a remaining paket
2056 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
2057 memcpy(decompress_buffer+decompress_buffer_filled,
2058 buffer+mpacket.pos_buffer+*samplepos,
2059 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
2060 incoming_paket_libav.size = decompress_buffer_filled
2061 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
2062 //LogNT::getInstance()->debug(TAG,"Use saved audio buffer {} {} {}",mpacket.type,decompress_buffer_filled,mpacket.synched);
2064 incoming_paket_libav.data =(uint8_t*) buffer+mpacket.pos_buffer+*samplepos;
2065 incoming_paket_libav.size = haveToCopy;
2067 //LogNT::getInstance()->debug(TAG, "DMP mark 18");
2069 while (haveToCopy> 0 && errcount<3) {
2071 //LogNT::getInstance()->debug(TAG,"libav in {} {}",framesize,current_context->frame_size);
2072 //LogNT::getInstance()->debug(TAG, "libav in {} {}",
2073 // framesize, current_context->frame_size);
2075 bool donotdecompress=false;
2076 unsigned int gotframesize=0;
2077 // if (!decompress_buffer_filled) { // only do this if no old data is present
2079 switch (mpacket.type) {
2080 case MPTYPE_MPEG_AUDIO:
2081 case MPTYPE_MPEG_AUDIO_LAYER3: {
2082 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
2083 incoming_paket_libav.size,&gotframesize);
2087 case MPTYPE_AC3_PRE13: {
2088 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
2089 incoming_paket_libav.size,&gotframesize);
2092 case MPTYPE_AAC_LATM: {
2093 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
2094 incoming_paket_libav.size,&gotframesize);
2098 if (adv > 0 /*&& !decompress_buffer_filled*/) {
2099 incoming_paket_libav.data += adv;
2100 incoming_paket_libav.size-=adv;
2103 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2104 else*/ framesize=haveToCopy;
2105 //LogNT::getInstance()->debug(TAG,"Advance by {} {} from {}",adv,mpacket.type,*samplepos );
2106 if (haveToCopy <= 0) {
2107 // LogNT::getInstance()->debug(TAG,"No sync code in packet remove {}",mpacket.type);
2108 *samplepos=mpacket.length;
2109 return mpacket.length;
2115 if (gotframesize>0 && gotframesize>haveToCopy) {
2116 donotdecompress=true;
2117 errcount=100; // exit loop
2119 // else LogNT::getInstance()->debug(TAG,"Loop run");
2121 //LogNT::getInstance()->debug(TAG, "DMP mark 19");
2122 if (!donotdecompress) {
2125 pthread_testcancel();
2126 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2127 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2129 if (!omx_running || !mp23codec_context_libav
2130 || !ac3codec_context_libav) {
2131 libav_mutex.unlock();
2134 libav_mutex.unlock();
2135 // LogNT::getInstance()->debug(TAG,"libav out");
2136 int save_size=incoming_paket_libav.size;
2138 if ((int)gotframesize <= incoming_paket_libav.size) {
2139 if (gotframesize>0) incoming_paket_libav.size=gotframesize;
2140 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2141 &gotta, &incoming_paket_libav);
2143 //LogNT::getInstance()->debug(TAG, "FRAME:E {} {}",gotframesize,incoming_paket_libav.size);
2147 //LogNT::getInstance()->debug(TAG, "FRAME:T {}",len);
2148 incoming_paket_libav.size=save_size;
2149 //LogNT::getInstance()->debug(TAG, "libav out1");
2150 pthread_setcancelstate(oldcancelstate, NULL);
2151 pthread_setcanceltype(oldcanceltype, NULL);
2152 pthread_testcancel();
2158 //LogNT::getInstance()->debug(TAG, "libav out2");
2159 //LogNT::getInstance()->debug(TAG, "DMP mark 20");
2161 libav_mutex.unlock();
2165 if (decompress_buffer_filled) { // reset to normal decoding
2167 //LogNT::getInstance()->debug(TAG,"saved audio: {}",len);
2168 haveToCopy -= min(len-decompress_buffer_filled,0);
2169 *samplepos += min(len-decompress_buffer_filled,0);
2170 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2171 /*else*/ framesize=haveToCopy;
2173 framesize=haveToCopy;
2175 incoming_paket_libav.data =(uint8_t*) buffer+mpacket.pos_buffer+*samplepos;
2177 decompress_buffer_filled=0;
2181 incoming_paket_libav.data += len;
2185 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2186 else*/framesize=haveToCopy;
2189 framesize=haveToCopy;
2192 //LogNT::getInstance()->debug(TAG, "DMP mark 21");
2194 incoming_paket_libav.size =framesize;
2196 //LogNT::getInstance()->debug(TAG,
2199 int dsize = av_samples_get_buffer_size(NULL,
2200 /*current_context->channels*/2, decode_frame_libav->nb_samples,
2201 AV_SAMPLE_FMT_S16, 1);
2202 /* int dsize_in = av_samples_get_buffer_size(NULL,
2203 current_context->channels, decode_frame_libav->nb_samples,
2204 current_context->sample_fmt, 1); -- unused */
2205 //if (current_context->channels==1) dsize*=2; // we convert mono to stereo
2206 if ((cur_input_buf_omx->nFilledLen + dsize)
2207 > cur_input_buf_omx->nAllocLen ) {
2208 // I doubt that this will ever happen
2209 // LogNT::getInstance()->debug(TAG,
2210 // "P 2 Time code {} pts {}", lastreftimeOMX, mpacket.pts);
2211 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2213 if (error != OMX_ErrorNone) {
2214 LogNT::getInstance()->debug(TAG,
2215 "OMX_EmptyThisBuffer 4 failed {:#x}", error);
2217 cur_input_buf_omx = NULL;
2219 if (!cur_input_buf_omx) {
2221 while (count < 10 && omx_running) {
2223 input_bufs_omx_mutex.lock();
2224 if (input_bufs_omx_free.size() == 0) {
2225 input_bufs_omx_mutex.unlock();
2226 // LogNT::getInstance()->debug(TAG,
2227 // "Deliver MediaPacket no free sample");
2229 //LogNT::getInstance()->debug(TAG, "DMP mark22");
2230 if (!omx_running) return *samplepos;
2231 //LogNT::getInstance()->debug(TAG, "DMP mark 23");
2234 cur_input_buf_omx = input_bufs_omx_free.front();
2235 cur_input_buf_omx->nFilledLen = 0;
2236 cur_input_buf_omx->nOffset = 0;
2237 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2238 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2239 input_bufs_omx_free.pop_front();
2240 input_bufs_omx_mutex.unlock();
2243 if (!cur_input_buf_omx) return *samplepos;
2248 //LogNT::getInstance()->debug(TAG,"memcpy in {} {} {}" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2251 av_opt_set_int(resam_con_libav, "in_sample_rate",decode_frame_libav->sample_rate,0);
2252 av_opt_set_int(resam_con_libav, "in_sample_fmt",decode_frame_libav->format,0);
2253 av_opt_set_int(resam_con_libav, "in_channel_layout",decode_frame_libav->channel_layout, 0);
2254 //LogNT::getInstance()->error(TAG, "AV resampledata {} {} {} {}",current_context->channels,current_context->sample_rate,current_context->sample_fmt,current_context->channel_layout);
2255 //LogNT::getInstance()->error(TAG, "AV resampledata2 {} {} {}",decode_frame_libav->sample_rate,decode_frame_libav->format,decode_frame_libav->channel_layout);
2257 int ret = swr_init(resam_con_libav);
2259 LogNT::getInstance()->error(TAG, "Opening AV resample failed {}",ret);
2261 uint8_t *output=cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen;
2264 avresample_convert ( AVAudioResampleContext * avr,
2268 uint8_t *const * input,
2274 avresample_convert(resam_con_libav,
2275 &output, dsize, decode_frame_libav->nb_samples,
2276 decode_frame_libav->extended_data, decode_frame_libav->linesize[0], decode_frame_libav->nb_samples);
2279 swr_convert ( struct SwrContext * s,
2282 const uint8_t ** in,
2287 //LogNT::getInstance()->debug(TAG, "Calling swr_convert");
2289 swr_convert(resam_con_libav, &output, decode_frame_libav->nb_samples, (const uint8_t**)decode_frame_libav->extended_data, decode_frame_libav->nb_samples);
2291 swr_close(resam_con_libav);
2294 //LogNT::getInstance()->debug(TAG,"memcpy out");
2295 cur_input_buf_omx->nFilledLen += dsize;
2297 //LogNT::getInstance()->debug(TAG,"Incomplete mpeg frames in pes packet {} {}",incoming_paket_libav.size,mpacket.length);
2298 /* uint8_t a1=incoming_paket_libav.data[0];
2299 uint8_t a2=incoming_paket_libav.data[1];
2300 uint8_t a3=incoming_paket_libav.data[2];
2301 uint8_t a4=incoming_paket_libav.data[3];*/
2302 // LogNT::getInstance()->debug(TAG,"Header {:#x} {:#x} {:#x} {:#x}",a1,a2,
2307 //LogNT::getInstance()->debug(TAG, "DMP mark 24");
2308 decompress_buffer_filled=0;
2310 //LogNT::getInstance()->debug(TAG,"We can not decompress {} save for later {} {:#x} {:#x}",haveToCopy,mpacket.type,incoming_paket_libav.data,mpacket.pos_buffer);
2311 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2313 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2317 if (cur_input_buf_omx->nFilledLen) {
2318 //LogNT::getInstance()->debug(TAG,
2319 // "P 3 Time code {} pts {}", lastreftimeOMX, mpacket.pts);
2320 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2321 if (error != OMX_ErrorNone) {
2322 LogNT::getInstance()->debug(TAG,
2323 "OMX_EmptyThisBuffer 5 failed {:#x}", error);
2325 //if (mpacket.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2326 cur_input_buf_omx = NULL;
2331 //LogNT::getInstance()->debug(TAG, "DMP mark 25");
2333 *samplepos=mpacket.length;
2334 return mpacket.length;
2338 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync)
2340 VideoOMX* vw = dynamic_cast<VideoOMX*>(Video::getInstance());
2341 return vw->SetStartAudioOffset(curreftime,rsync);
2344 void AudioOMX::ResetTimeOffsets()
2346 VideoOMX* vw = dynamic_cast<VideoOMX*>(Video::getInstance());
2347 vw->ResetTimeOffsets();