2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "woptionpane.h"
27 #include "osdopenvg.h"
35 lastAType = MPTYPE_MPEG_AUDIO;
40 canpass_pcm_mch=false;
42 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
49 omx_aud_rend/*dec*/=0;
50 cur_input_buf_omx=NULL;
53 ac3codec_context_libav=NULL;
56 mp23codec_context_libav=NULL;
58 decompress_buffer=NULL;
59 decompress_buffer_size=0;
60 decompress_buffer_filled=0;
68 int AudioOMX::init(UCHAR tstreamType) {
73 streamType = tstreamType;
75 if (!initAllParams()) {
82 decompress_buffer_size=20000;
83 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
84 decompress_buffer_filled=0;
89 av_log_set_flags(AV_LOG_SKIP_REPEATED);
91 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
92 if (ac3codec_libav == NULL) {
93 Log::getInstance()->log("Audio", Log::DEBUG,
94 "Find libav ac3 decoder failed");
98 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
99 if (mp23codec_libav == NULL) {
100 Log::getInstance()->log("Audio", Log::DEBUG,
101 "Find libav mpeg audio decoder failed");
107 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
111 Log::getInstance()->log("Audio", Log::NOTICE,
112 "TV hdmi supports mpeg1 layer 1 and 2");
114 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
118 Log::getInstance()->log("Audio", Log::NOTICE,
119 "TV hdmi supports mpeg1 layer 3");
122 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
125 Log::getInstance()->log("Audio", Log::NOTICE,
126 "TV hdmi supports AC3");
128 canpass_pcm_mch=false;
133 int AudioOMX::initAllParams()
135 return (setStreamType(streamType) && setChannel() && setSource());
138 int AudioOMX::shutdown()
140 if (!initted) return 0;
143 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
144 DeAllocateCodecsOMX();
146 free(decompress_buffer);
147 decompress_buffer=NULL;
148 decompress_buffer_size=0;
149 decompress_buffer_filled=0;
154 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
156 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
157 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
160 if (STRCASECMP(name, "PCM") == 0) {
162 } else if (STRCASECMP(name, "Passthrough") == 0) {
164 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
169 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
172 if (STRCASECMP(name, "PCM") == 0) {
174 } else if (STRCASECMP(name, "Passthrough") == 0) {
176 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
181 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
184 if (STRCASECMP(name, "PCM") == 0) {
186 } else if (STRCASECMP(name, "Passthrough") == 0) {
188 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
193 name = vdr->configLoad("AudioOMX", "AudioOutput");
196 if (STRCASECMP(name, "analog") == 0) {
198 } else if (STRCASECMP(name, "HDMI") == 0) {
208 bool AudioOMX::handleOptionChanges(Option* option)
210 if (Audio::handleOptionChanges(option))
212 switch (option->id) {
214 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
216 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
224 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
226 } else if (STRCASECMP(option->options[option->userSetChoice],
227 "Passthrough") == 0) {
229 } else if (STRCASECMP(option->options[option->userSetChoice],
230 "PCMMultichannel") == 0) {
236 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
238 } else if (STRCASECMP(option->options[option->userSetChoice],
239 "Passthrough") == 0) {
241 } else if (STRCASECMP(option->options[option->userSetChoice],
242 "PCMMultichannel") == 0) {
248 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
250 } else if (STRCASECMP(option->options[option->userSetChoice],
251 "Passthrough") == 0) {
253 } else if (STRCASECMP(option->options[option->userSetChoice],
254 "PCMMultichannel") == 0) {
264 bool AudioOMX::saveOptionstoServer()
267 switch (prefered_ac3) {
269 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
272 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
276 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
281 switch (prefered_mp2) {
283 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
286 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
290 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
295 switch (prefered_mp3) {
297 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
300 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
304 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
310 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
312 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
318 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
319 UINT numChoices, UINT defaultChoice, UINT startInt,
320 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
322 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
324 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
331 static const char* audioopts[]={"analog","HDMI"};
332 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
333 options->push_back(option);
334 pane->addOptionLine(option);
337 char **ac3opts=new char *[3];
339 ac3opts[i]=new char[strlen("PCM")+1];
340 strcpy(ac3opts[i],"PCM");
343 ac3opts[i]=new char[strlen("Passthrough")+1];
344 strcpy(ac3opts[i],"PassThrough");
347 if (canpass_pcm_mch) {
348 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
349 strcpy(ac3opts[i],"PCMMultichannel");
352 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
353 options->push_back(option);
354 pane->addOptionLine(option);
356 char **mp2opts = new char *[3];
358 mp2opts[i] = new char[strlen("PCM") + 1];
359 strcpy(mp2opts[i], "PCM");
362 mp2opts[i] = new char[strlen("Passthrough") + 1];
363 strcpy(mp2opts[i], "PassThrough");
366 if (canpass_pcm_mch) {
367 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
368 strcpy(mp2opts[i], "PCMMultichannel");
371 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
372 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
373 mp2opts, NULL, true, this);
374 options->push_back(option);
375 pane->addOptionLine(option);
377 char **mp3opts = new char *[3];
379 mp3opts[i] = new char[strlen("PCM") + 1];
380 strcpy(mp3opts[i], "PCM");
383 mp3opts[i] = new char[strlen("Passthrough") + 1];
384 strcpy(mp3opts[i], "PassThrough");
387 if (canpass_pcm_mch) {
388 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
389 strcpy(mp3opts[i], "PCMMultichannel");
392 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
393 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
395 options->push_back(option);
396 pane->addOptionLine(option);
409 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
411 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
412 AudioOMX *audio=(AudioOMX *)getInstance();
413 audio->ReturnEmptyOMXBuffer(buffer);
414 return OMX_ErrorNone;
418 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
419 input_bufs_omx_mutex.Lock();
420 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
421 input_bufs_omx_free.push_back(buffer);
422 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
423 input_bufs_omx_mutex.Unlock();
426 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
427 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
428 return OMX_ErrorNone;
433 int AudioOMX::setStreamType(UCHAR type)
435 if (!initted) return 0;
437 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
441 int AudioOMX::setChannel()
443 if (!initted) return 0;
445 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
449 int AudioOMX::setSource()
451 if (!initted) return 0;
453 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
459 if (!initted) return 0;
461 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
465 int AudioOMX::play() {
468 lastAType=MPTYPE_MPEG_AUDIO;
469 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
471 if (!AllocateCodecsOMX()) {
478 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
481 const char * destinations[]={"local","hdmi"};
486 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
487 memset(&auddest,0,sizeof(auddest));
488 auddest.nSize=sizeof(auddest);
489 auddest.nVersion.nVersion=OMX_VERSION;
490 strcpy((char *)auddest.sName, destinations[dest]);
492 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
493 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
494 if (error!=OMX_ErrorNone){
495 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
496 DeAllocateCodecsOMX();
504 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
507 //Ok first fidle a working configuration
508 Log::getInstance()->log("Audio", Log::DEBUG,
509 "ChangeAudioPortConfig");
511 OMX_AUDIO_CODINGTYPE encoding;
514 case MPTYPE_MPEG_AUDIO: {
515 if (prefered_mp2 == 2 && false) { //not supported yet
518 if (prefered_mp2 == 1 && canpass_mp2) {
520 encoding=OMX_AUDIO_CodingMP3;
523 encoding=OMX_AUDIO_CodingPCM;
528 case MPTYPE_AC3_PRE13:
530 if (prefered_ac3 == 2 && false) { //not supported yet
533 Log::getInstance()->log("Audio", Log::DEBUG,
534 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
535 if (prefered_ac3 == 1 && canpass_ac3) {
537 encoding=OMX_AUDIO_CodingDDP;
540 encoding=OMX_AUDIO_CodingPCM;
545 case MPTYPE_MPEG_AUDIO_LAYER3: {
546 if (prefered_mp3 == 2 && false) { //not supported yet
549 if (prefered_mp3 == 1 && canpass_mp2) {
551 encoding=OMX_AUDIO_CodingMP3;
554 encoding=OMX_AUDIO_CodingPCM;
562 encoding=OMX_AUDIO_CodingPCM;
563 //mch=false; // multichannel also false
568 /*OMX_CONFIG_BOOLEANTYPE booly;
569 memset(&booly, 0, sizeof(booly));
570 booly.nSize = sizeof(booly);
571 booly.nVersion.nVersion = OMX_VERSION;
573 booly.bEnabled = OMX_TRUE;
575 booly.bEnabled = OMX_FALSE;
577 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
579 if (error != OMX_ErrorNone) {
580 Log::getInstance()->log("Audio", Log::DEBUG,
581 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
582 DeAllocateCodecsOMX();
585 VideoOMX* video=(VideoOMX*)Video::getInstance();
587 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
588 //DestroyInputBufsOMXwhilePlaying();
589 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
594 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
595 memset(&format, 0, sizeof(format));
596 format.nSize = sizeof(format);
597 format.nVersion.nVersion = OMX_VERSION;
598 format.nPortIndex = omx_rend_input_port;
599 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
601 if (error != OMX_ErrorNone) {
602 Log::getInstance()->log("Audio", Log::DEBUG,
603 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
604 omx_rend_input_port);
609 Log::getInstance()->log("Audio", Log::DEBUG,
610 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
611 format.eEncoding = encoding;
613 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
615 if (error != OMX_ErrorNone) {
616 Log::getInstance()->log("Audio", Log::DEBUG,
617 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
618 omx_rend_input_port,format.eEncoding );
623 case OMX_AUDIO_CodingPCM: {
624 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
625 memset(&audio_pcm, 0, sizeof(audio_pcm));
626 audio_pcm.nSize = sizeof(audio_pcm);
627 audio_pcm.nVersion.nVersion = OMX_VERSION;
628 audio_pcm.nChannels = 2;
629 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
630 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
631 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
632 audio_pcm.eNumData = OMX_NumericalDataSigned;
633 audio_pcm.eEndian = OMX_EndianLittle;
634 audio_pcm.bInterleaved = OMX_TRUE;
635 audio_pcm.nBitPerSample = 16;
636 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
637 audio_pcm.nChannels = 2;
638 audio_pcm.nSamplingRate = 48000;
639 audio_pcm.nPortIndex = omx_rend_input_port;
640 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
642 if (error != OMX_ErrorNone) {
643 Log::getInstance()->log("Audio", Log::DEBUG,
644 "Init OMX_IndexParamAudioPcm failed %x %d", error,
645 omx_rend_input_port);
649 case OMX_AUDIO_CodingDDP: {
650 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
651 memset(&audio_ddp, 0, sizeof(audio_ddp));
652 audio_ddp.nSize = sizeof(audio_ddp);
653 audio_ddp.nVersion.nVersion = OMX_VERSION;
654 audio_ddp.nPortIndex = omx_rend_input_port;
655 audio_ddp.nChannels = 8; //unknown
656 audio_ddp.nBitRate=0;
657 audio_ddp.nSampleRate=48000;
658 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
659 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
660 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
661 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
662 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
663 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
664 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
665 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
666 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
667 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
669 if (error != OMX_ErrorNone) {
670 Log::getInstance()->log("Audio", Log::DEBUG,
671 "Init OMX_IndexParamAudioDdp failed %x %d", error,
672 omx_rend_input_port);
677 default: break; //Make compiler happy
684 //PrepareInputBufsOMX(false);
685 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
695 int AudioOMX::InitDecoderLibAV()
698 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
699 if (!ac3codec_context_libav) {
700 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
704 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
705 ac3codec_context_libav->request_channels=2;
707 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
709 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
710 libav_mutex.Unlock();
714 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
715 if (!ac3codec_context_libav) {
716 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
717 libav_mutex.Unlock();
721 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
722 mp23codec_context_libav->request_channels=2;
724 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
726 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
727 libav_mutex.Unlock();
731 av_init_packet(&incoming_paket_libav);
732 decode_frame_libav=avcodec_alloc_frame();
733 libav_mutex.Unlock();
734 decompress_buffer_filled=0;
741 void AudioOMX::DeinitDecoderLibAV() {
745 if (ac3codec_context_libav) {
746 avcodec_close(ac3codec_context_libav);
747 av_free(ac3codec_context_libav);
748 ac3codec_context_libav = NULL;
749 av_free(decode_frame_libav);
750 avcodec_close(mp23codec_context_libav);
751 av_free(mp23codec_context_libav);
752 mp23codec_context_libav = NULL;
755 libav_mutex.Unlock();
760 int AudioOMX::AllocateCodecsOMX()
763 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
765 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
766 //Clock, move later to audio
767 VideoOMX *video=(VideoOMX*)Video::getInstance();
769 if (!InitDecoderLibAV()) return 0;;
772 OMX_PORT_PARAM_TYPE p_param;
773 memset(&p_param,0,sizeof(p_param));
774 p_param.nSize=sizeof(p_param);
775 p_param.nVersion.nVersion=OMX_VERSION;
778 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
779 return 0;// get the clock and init it if necessary
783 if (!video->idleClock()) {
788 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
789 if (error != OMX_ErrorNone) {
790 Log::getInstance()->log("Audio", Log::DEBUG,
791 "Init OMX audio rend failed %x", error);
792 video->UnlockClock();
793 DeAllocateCodecsOMX();
797 if (!ChangeAudioDestination()) {
798 video->UnlockClock();
799 DeAllocateCodecsOMX();
803 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
804 if (error != OMX_ErrorNone) {
805 Log::getInstance()->log("Audio", Log::DEBUG,
806 "Init OMX audio rend OMX_GetParameter failed %x", error);
807 video->UnlockClock();
808 DeAllocateCodecsOMX();
811 omx_rend_input_port = p_param.nStartPortNumber;
813 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
814 if (error != OMX_ErrorNone) {
815 Log::getInstance()->log("Audio", Log::DEBUG,
816 "Init OMX aud rend OMX_GetParameter failed %x", error);
817 video->UnlockClock();
818 DeAllocateCodecsOMX();
821 // buggy return value
822 omx_rend_clock_port = p_param.nStartPortNumber;
825 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
827 if (error!=OMX_ErrorNone){
828 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
829 video->UnlockClock();
830 DeAllocateCodecsOMX();
834 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
835 if (error!=OMX_ErrorNone){
836 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
837 video->UnlockClock();
838 DeAllocateCodecsOMX();
841 omx_codec_input_port=p_param.nStartPortNumber;
842 omx_codec_output_port=p_param.nStartPortNumber+1;
844 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
845 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
846 video->UnlockClock();
847 DeAllocateCodecsOMX();
854 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
855 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
856 video->UnlockClock();
857 DeAllocateCodecsOMX();
861 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
862 Log::getInstance()->log("Audio", Log::DEBUG,
863 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
864 video->UnlockClock();
865 DeAllocateCodecsOMX();
875 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
876 if (error!=OMX_ErrorNone){
877 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel clock to rend failed %x %d %d", error,omx_clock_output_port,omx_rend_clock_port);
878 video->UnlockClock();
879 DeAllocateCodecsOMX();
883 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
885 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
886 video->UnlockClock();
887 DeAllocateCodecsOMX();
891 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
892 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
893 video->UnlockClock();
894 DeAllocateCodecsOMX();
901 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
902 video->UnlockClock();
903 DeAllocateCodecsOMX();
907 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
908 video->UnlockClock();
909 DeAllocateCodecsOMX();
915 if (!ChangeAudioPortConfig(false)){
916 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
917 video->UnlockClock();
918 DeAllocateCodecsOMX();
922 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
923 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
924 DeAllocateCodecsOMX();
930 if (!PrepareInputBufsOMX(true)) {
931 video->UnlockClock();
932 DeAllocateCodecsOMX();
938 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
939 if (error!=OMX_ErrorNone){
940 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
941 video->UnlockClock();
942 DeAllocateCodecsOMX();
948 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
950 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
951 video->UnlockClock();
952 DeAllocateCodecsOMX();
956 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
957 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
958 video->UnlockClock();
959 DeAllocateCodecsOMX();
963 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
964 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
965 video->UnlockClock();
966 DeAllocateCodecsOMX();
971 video->UnlockClock();
977 if (!video->setClockExecutingandRunning()) return 0;
979 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
987 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
989 VideoOMX *video=(VideoOMX*)Video::getInstance();
991 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
992 memset(&port_def_type,0,sizeof(port_def_type));
993 port_def_type.nSize=sizeof(port_def_type);
994 port_def_type.nVersion.nVersion=OMX_VERSION;
995 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
997 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
999 if (error!=OMX_ErrorNone){
1000 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1005 port_def_type.nBufferCountActual=2;
1006 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1008 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1010 if (error!=OMX_ErrorNone){
1011 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1016 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1017 if (error!=OMX_ErrorNone){
1018 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1022 input_bufs_omx_mutex.Lock();
1023 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1024 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1025 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1026 if (error!=OMX_ErrorNone){
1027 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1028 input_bufs_omx_mutex.Unlock();
1031 input_bufs_omx_all.push_back(buf_head);
1032 input_bufs_omx_free.push_back(buf_head);
1034 omx_first_frame=true;
1037 cur_input_buf_omx=NULL;
1038 input_bufs_omx_mutex.Unlock();
1040 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1047 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1049 OMX_ERRORTYPE error;
1051 cur_input_buf_omx=NULL;
1052 input_bufs_omx_mutex.Lock();
1053 for (int i=0; i< input_bufs_omx_all.size();i++) {
1054 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1055 if (error!=OMX_ErrorNone){
1056 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1057 input_bufs_omx_mutex.Unlock();
1062 input_bufs_omx_all.clear();
1063 input_bufs_omx_free.clear();
1064 input_bufs_omx_mutex.Unlock();
1068 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1070 OMX_ERRORTYPE error;
1072 cur_input_buf_omx=NULL;
1073 input_bufs_omx_mutex.Lock();
1074 while (input_bufs_omx_all.size()>0) {
1075 if (input_bufs_omx_free.size()>0) {
1076 // Destroy one buffer
1077 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1078 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1079 for (; itty!= input_bufs_omx_all.end();itty++) {
1080 if ((*itty)==cur_buf) {
1081 input_bufs_omx_all.erase(itty);
1082 input_bufs_omx_free.pop_front();
1087 input_bufs_omx_mutex.Unlock();
1089 input_bufs_omx_mutex.Lock();
1093 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1094 input_bufs_omx_mutex.Unlock();
1099 int AudioOMX::DeAllocateCodecsOMX()
1101 OMX_ERRORTYPE error;
1103 VideoOMX *video=(VideoOMX*)Video::getInstance();
1104 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1108 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1109 if (cur_input_buf_omx) {
1110 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1111 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1112 if (error!=OMX_ErrorNone) {
1113 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1116 cur_input_buf_omx=NULL;//write out old data
1118 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1121 if (omx_aud_rend/*dec*/) {
1122 // first stop the omx elements
1123 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1124 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1126 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1128 video->UnlockClock();
1129 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1131 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1134 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1135 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1138 // TODO proper deinit sequence
1139 // first flush all buffers
1141 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1142 if (error!=OMX_ErrorNone) {
1143 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1147 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1148 if (error!=OMX_ErrorNone){
1149 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1154 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1155 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1160 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1161 if (error!=OMX_ErrorNone){
1162 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1166 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1167 if (error!=OMX_ErrorNone){
1168 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1171 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1173 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1174 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1175 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1178 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1179 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1180 DeinitDecoderLibAV();
1181 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1184 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1185 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1188 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1189 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1192 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1193 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1197 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1198 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1201 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1202 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1207 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1208 if (error!=OMX_ErrorNone) {
1209 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1215 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1216 if (error!=OMX_ErrorNone) {
1217 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1221 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1222 if (error!=OMX_ErrorNone) {
1223 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1227 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1228 if (error!=OMX_ErrorNone) {
1229 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1232 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1235 //error=OMX_FreeHandle(omx_aud_dec);
1236 error=OMX_FreeHandle(omx_aud_rend);
1237 video->UnlockClock();
1238 video->destroyClock();
1239 omx_aud_rend/*dec*/=NULL;
1240 if (error!=OMX_ErrorNone) {
1241 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1245 video->UnlockClock();
1246 DeinitDecoderLibAV();
1248 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1255 int AudioOMX::stop()
1257 if (!initted) return 0;
1259 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1260 DeAllocateCodecsOMX();
1261 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1265 int AudioOMX::mute() {
1268 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1270 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1272 OMX_AUDIO_CONFIG_MUTETYPE amute;
1273 memset(&amute, 0, sizeof(amute));
1274 amute.nSize = sizeof(amute);
1275 amute.nVersion.nVersion = OMX_VERSION;
1276 amute.nPortIndex = omx_rend_input_port;
1277 amute.bMute = OMX_TRUE;
1278 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1280 if (error != OMX_ErrorNone) {
1281 Log::getInstance()->log("Audio", Log::DEBUG,
1282 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1283 omx_rend_input_port);
1293 int AudioOMX::unMute()
1295 if (!initted) return 0;
1297 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1299 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1301 OMX_AUDIO_CONFIG_MUTETYPE amute;
1302 memset(&amute, 0, sizeof(amute));
1303 amute.nSize = sizeof(amute);
1304 amute.nVersion.nVersion = OMX_VERSION;
1305 amute.nPortIndex = omx_rend_input_port;
1306 amute.bMute = OMX_FALSE;
1307 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1309 if (error != OMX_ErrorNone) {
1310 Log::getInstance()->log("Audio", Log::DEBUG,
1311 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1312 omx_rend_input_port);
1322 int AudioOMX::pause() {
1327 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1330 OMX_ERRORTYPE error;
1331 error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1332 omx_rend_input_port, NULL);
1333 if (error != OMX_ErrorNone) {
1334 Log::getInstance()->log("Audio", Log::DEBUG,
1335 "OMX_Flush rend in failed %x", error);
1338 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1339 Log::getInstance()->log("Audio", Log::DEBUG, " pause aud_rend idle ChangeComponentState");
1348 int AudioOMX::unPause()
1350 if (!initted) return 0;
1352 paused=false; // may be also change omx clock
1353 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1355 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1356 Log::getInstance()->log("Audio", Log::DEBUG, " unpause aud_rend idle ChangeComponentState");
1364 int AudioOMX::reset()
1366 if (!initted) return 0;
1368 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1369 DeAllocateCodecsOMX();
1371 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1372 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1373 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1379 int AudioOMX::setVolume(int tvolume)
1381 // parameter: 0 for silence, 20 for full
1382 if ((tvolume < 0) || (tvolume > 20)) return 0;
1384 // volume = 2 * (20 - volume);
1385 // Right, that one was rubbish... 0-10 were almost
1386 // inaudible, 11-20 did what should have been done
1387 // over the whole 0-20 range
1393 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1395 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1396 memset(&avol, 0, sizeof(avol));
1397 avol.nSize = sizeof(avol);
1398 avol.nVersion.nVersion = OMX_VERSION;
1399 avol.nPortIndex = omx_rend_input_port;
1400 avol.bLinear=OMX_FALSE;
1401 avol.sVolume.nValue =(volume-20)*200;
1402 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1404 if (error != OMX_ErrorNone) {
1405 Log::getInstance()->log("Audio", Log::DEBUG,
1406 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1407 omx_rend_input_port);
1417 int AudioOMX::test()
1420 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1422 /* aud_sync_parms_t a;
1426 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1429 /*OK*/ //printf("Audio sync disable = %i\n", b);
1437 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1439 if (size<=2) return size; // silly;
1440 unsigned int test=0;
1442 while (test+1<size) {
1443 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1449 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1451 if (size<=4) return size; // silly;
1452 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1453 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1454 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1455 1152, 1280, 1280, };
1456 unsigned int test=0;
1457 *framesize=20000; //if we do not find a start code do not decompress
1458 while (test+4<size) {
1459 if (data[test]==0x0B && data[test+1]==0x77) {
1460 // now figure out the length of the frame
1461 unsigned char code=data[test+4];
1462 unsigned char fscod=(code& 0xC0)>>6;
1463 unsigned char frmsize=(code &0x3f);
1464 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1465 *framesize=frm_size_tab[frmsize]*2;
1466 return test; // probably FrameSync
1474 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1476 packet = mplist.front();
1479 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1480 DeliverMediaPacket(packet, buffer, samplepos);
1481 if (*samplepos == packet.length) {
1489 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1491 VideoOMX *video = (VideoOMX*) Video::getInstance();
1493 OMX_PARAM_U32TYPE audio_lat;
1494 OMX_ERRORTYPE error;
1495 memset(&audio_lat, 0, sizeof(audio_lat));
1496 audio_lat.nSize = sizeof(audio_lat);
1497 audio_lat.nVersion.nVersion = OMX_VERSION;
1498 audio_lat.nPortIndex = omx_rend_input_port;
1500 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1502 video->UnlockClock();
1503 if (error != OMX_ErrorNone) {
1504 Log::getInstance()->log("Audio", Log::DEBUG,
1505 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1506 omx_rend_input_port);
1507 return pts; // no correction in case of error
1509 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1512 long long workpts=0;
1513 workpts+=addsamples;
1514 workpts-=audio_lat.nU32;
1515 workpts*=10LL*1000LL*1000LL;
1516 workpts=workpts/((long long)srate); //one second /samplerate
1524 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1526 /*First Check, if we have an audio sample*/
1527 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1529 OMX_ERRORTYPE error;
1530 Log *logger=Log::getInstance();
1531 if (vw->InIframemode()) {
1534 return 0; //Not in iframe mode!
1537 if (!omx_running) return 0; // if we are not runnig do not do this
1538 if (paused) return 0; //Block if we pause
1540 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1542 if (packet.synched && packet.presentation_time <= 0) {
1543 *samplepos = packet.length;
1544 firstsynched = false;
1546 Log::getInstance()->log("Audio", Log::DEBUG,
1547 "DeliverMediaPacketOMX Frameskip");
1548 return packet.length;
1553 UINT headerstrip = 0;
1554 if (packet.disconti) {
1555 firstsynched = false;
1556 decompress_buffer_filled=0;
1557 if (cur_input_buf_omx) {
1558 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1560 if (error != OMX_ErrorNone) {
1561 Log::getInstance()->log("Audio", Log::DEBUG,
1562 "OMX_EmptyThisBuffer 1 failed %x", error);
1564 cur_input_buf_omx = NULL;
1569 if (packet.type != lastAType) {//Format Change //Push data out !
1570 firstsynched = false;
1572 lastAType = packet.type;
1573 decompress_buffer_filled=0;
1575 if (cur_input_buf_omx) {
1576 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1578 if (error != OMX_ErrorNone) {
1579 Log::getInstance()->log("Audio", Log::DEBUG,
1580 "OMX_EmptyThisBuffer 2 failed %x", error);
1582 cur_input_buf_omx = NULL;
1585 if (!ChangeAudioPortConfig(true)) {
1586 Log::getInstance()->log("Audio", Log::DEBUG,
1587 "Changing audio port config failed", error);
1594 /*Inspect PES-Header */
1595 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1596 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1597 if (packet.type == MPTYPE_AC3)
1598 headerstrip += 4; //skip ac3 bytes
1599 *samplepos += headerstrip;
1600 if (packet.synched) {
1601 if (cur_input_buf_omx) {
1602 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1603 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1605 if (error != OMX_ErrorNone) {
1606 Log::getInstance()->log("Audio", Log::DEBUG,
1607 "OMX_EmptyThisBuffer 3 failed %x", error);
1609 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1611 cur_input_buf_omx = NULL;//write out old data
1613 firstsynched = true;
1614 //decompress_buffer_filled=0;
1616 if (!firstsynched) {//
1617 *samplepos = packet.length;//if we have not processed at least one
1618 decompress_buffer_filled=0;
1619 return packet.length;//synched packet ignore it!
1623 if (!cur_input_buf_omx) {
1624 input_bufs_omx_mutex.Lock();
1625 if (input_bufs_omx_free.size()==0) {
1626 input_bufs_omx_mutex.Unlock();
1627 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1628 return 0; // we do not have a free media sample
1631 cur_input_buf_omx=input_bufs_omx_free.front();
1632 cur_input_buf_omx->nFilledLen=0;
1633 cur_input_buf_omx->nOffset=0;
1634 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1635 input_bufs_omx_free.pop_front();
1636 input_bufs_omx_mutex.Unlock();
1639 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1640 if (packet.synched) {
1641 //Log::getInstance()->log("Audio", Log::DEBUG,
1642 // "packet synched marker");
1644 //lastreftimePTS=packet.pts;
1645 if (omx_first_frame) { // TODO time
1646 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1647 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1648 omx_first_frame = false;
1650 cur_input_buf_omx->nFlags = 0;
1651 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1653 lastreftimeOMX = packet.presentation_time;
1654 // Log::getInstance()->log("Audio", Log::DEBUG,
1655 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1656 lastreftimePTS = packet.pts;
1657 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1659 // Log::getInstance()->log("Audio", Log::DEBUG,
1660 // "packet NOT synched marker");
1661 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1662 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1665 if (packet.disconti || achange) {
1666 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1667 //mp23codec_context_libav->frame_size=-1;
1668 //ac3codec_context_libav->frame_size=-1;
1673 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1674 unsigned int haveToCopy=packet.length-*samplepos;
1677 while (haveToCopy>0) {
1679 unsigned int gotframesize=0;
1681 switch (packet.type) {
1682 case MPTYPE_MPEG_AUDIO:
1683 case MPTYPE_MPEG_AUDIO_LAYER3: {
1684 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1685 haveToCopy,&gotframesize);
1689 case MPTYPE_AC3_PRE13: {
1690 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1691 haveToCopy,&gotframesize);
1695 if (adv!=haveToCopy) {
1700 *samplepos=packet.length; //no ac3 sync byte
1701 return packet.length;
1704 // so everything is fine now do a memcpy
1705 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1706 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1707 haveToCopy-=cancopy;
1708 cur_input_buf_omx->nFilledLen+=cancopy;
1709 *samplepos+=cancopy;
1711 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1712 if (error != OMX_ErrorNone) {
1713 Log::getInstance()->log("Audio", Log::DEBUG,
1714 "OMX_EmptyThisBuffer 5 failed %x", error);
1716 cur_input_buf_omx=NULL;
1719 input_bufs_omx_mutex.Lock();
1720 if (input_bufs_omx_free.size()==0) {
1721 input_bufs_omx_mutex.Unlock();
1722 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
1723 return *samplepos; // we do not have a free media sample
1725 cur_input_buf_omx=input_bufs_omx_free.front();
1726 cur_input_buf_omx->nFilledLen=0;
1727 cur_input_buf_omx->nOffset=0;
1728 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1729 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1730 input_bufs_omx_free.pop_front();
1731 input_bufs_omx_mutex.Unlock();
1743 AVCodecContext *current_context;
1744 switch (packet.type) {
1745 case MPTYPE_MPEG_AUDIO:
1746 case MPTYPE_MPEG_AUDIO_LAYER3: {
1747 current_context = mp23codec_context_libav;
1748 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1749 else framesize=current_context->frame_size;
1752 case MPTYPE_AC3_PRE13: {
1753 current_context = ac3codec_context_libav;
1757 if (decompress_buffer_filled) { // have a remaining paket
1758 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1759 memcpy(decompress_buffer+decompress_buffer_filled,
1760 buffer+packet.pos_buffer+*samplepos,
1761 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1762 incoming_paket_libav.size = decompress_buffer_filled
1763 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1764 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1766 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1767 incoming_paket_libav.size = haveToCopy;
1770 while (haveToCopy> 0 && errcount<3) {
1772 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1773 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1774 // framesize, current_context->frame_size);
1776 bool donotdecompress=false;
1777 unsigned int gotframesize=0;
1778 if (!decompress_buffer_filled) { // only do this if no old data is present
1780 switch (packet.type) {
1781 case MPTYPE_MPEG_AUDIO:
1782 case MPTYPE_MPEG_AUDIO_LAYER3: {
1783 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1784 incoming_paket_libav.size,&gotframesize);
1788 case MPTYPE_AC3_PRE13: {
1789 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1790 incoming_paket_libav.size,&gotframesize);
1795 incoming_paket_libav.data += adv;
1796 incoming_paket_libav.size-=adv;
1799 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1800 else*/ framesize=haveToCopy;
1801 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1802 if (haveToCopy <= 0) {
1803 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1804 *samplepos=packet.length;
1805 return packet.length;
1811 if (gotframesize>0 && gotframesize>haveToCopy) {
1812 donotdecompress=true;
1813 errcount=100; // exit loop
1815 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1818 if (!donotdecompress) {
1821 pthread_testcancel();
1822 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1823 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1825 if (!omx_running || !mp23codec_context_libav
1826 || !ac3codec_context_libav) {
1827 libav_mutex.Unlock();
1830 libav_mutex.Unlock();
1831 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1832 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1833 &gotta, &incoming_paket_libav);
1834 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1835 pthread_setcancelstate(oldcancelstate, NULL);
1836 pthread_setcanceltype(oldcanceltype, NULL);
1837 pthread_testcancel();
1843 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1845 libav_mutex.Unlock();
1849 if (decompress_buffer_filled) { // reset to normal decoding
1851 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1852 haveToCopy -= min(len-decompress_buffer_filled,0);
1853 *samplepos += min(len-decompress_buffer_filled,0);
1854 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1855 /*else*/ framesize=haveToCopy;
1857 framesize=haveToCopy;
1859 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1861 decompress_buffer_filled=0;
1865 incoming_paket_libav.data += len;
1869 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1870 else*/framesize=haveToCopy;
1873 framesize=haveToCopy;
1877 incoming_paket_libav.size =framesize;
1879 //Log::getInstance()->log("Audio", Log::DEBUG,
1881 int dsize = av_samples_get_buffer_size(NULL,
1882 current_context->channels, decode_frame_libav->nb_samples,
1883 current_context->sample_fmt, 1);
1884 if ((cur_input_buf_omx->nFilledLen + dsize)
1885 > cur_input_buf_omx->nAllocLen ) {
1886 // I doubt that this will ever happen
1887 // Log::getInstance()->log("Audio", Log::DEBUG,
1888 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1889 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1891 if (error != OMX_ErrorNone) {
1892 Log::getInstance()->log("Audio", Log::DEBUG,
1893 "OMX_EmptyThisBuffer 4 failed %x", error);
1895 cur_input_buf_omx = NULL;
1897 if (!cur_input_buf_omx) {
1899 while (count < 10 && omx_running) {
1901 input_bufs_omx_mutex.Lock();
1902 if (input_bufs_omx_free.size() == 0) {
1903 input_bufs_omx_mutex.Unlock();
1904 // Log::getInstance()->log("Audio", Log::DEBUG,
1905 // "Deliver MediaPacket no free sample");
1907 if (!omx_running) return *samplepos;
1910 cur_input_buf_omx = input_bufs_omx_free.front();
1911 cur_input_buf_omx->nFilledLen = 0;
1912 cur_input_buf_omx->nOffset = 0;
1913 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1914 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1915 input_bufs_omx_free.pop_front();
1916 input_bufs_omx_mutex.Unlock();
1919 if (!cur_input_buf_omx) return *samplepos;
1924 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1925 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1926 decode_frame_libav->data[0], dsize);
1927 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1928 cur_input_buf_omx->nFilledLen += dsize;
1930 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1931 /* uint8_t a1=incoming_paket_libav.data[0];
1932 uint8_t a2=incoming_paket_libav.data[1];
1933 uint8_t a3=incoming_paket_libav.data[2];
1934 uint8_t a4=incoming_paket_libav.data[3];*/
1935 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1940 decompress_buffer_filled=0;
1942 Log::getInstance()->log("Audio", Log::DEBUG,"We can not decompress %d save for later %d %x %x",haveToCopy,packet.type,incoming_paket_libav.data,packet.pos_buffer);
1943 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1945 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1949 if (cur_input_buf_omx->nFilledLen) {
1950 //Log::getInstance()->log("Audio", Log::DEBUG,
1951 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1952 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1953 if (error != OMX_ErrorNone) {
1954 Log::getInstance()->log("Audio", Log::DEBUG,
1955 "OMX_EmptyThisBuffer 5 failed %x", error);
1957 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1958 cur_input_buf_omx = NULL;
1965 *samplepos=packet.length;
1966 return packet.length;
1972 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1973 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1974 return vw->SetStartAudioOffset(curreftime,rsync);
1977 void AudioOMX::ResetTimeOffsets() {
1978 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1979 vw->ResetTimeOffsets();