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;
41 canpass_pcm_mch=false;
43 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
51 omx_aud_rend/*dec*/=0;
52 cur_input_buf_omx=NULL;
55 ac3codec_context_libav=NULL;
58 mp23codec_context_libav=NULL;
60 decompress_buffer=NULL;
61 decompress_buffer_size=0;
62 decompress_buffer_filled=0;
70 int AudioOMX::init(UCHAR tstreamType) {
75 streamType = tstreamType;
77 if (!initAllParams()) {
84 decompress_buffer_size=20000;
85 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
86 decompress_buffer_filled=0;
91 av_log_set_flags(AV_LOG_SKIP_REPEATED);
93 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
94 if (ac3codec_libav == NULL) {
95 Log::getInstance()->log("Audio", Log::DEBUG,
96 "Find libav ac3 decoder failed");
100 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
101 if (mp23codec_libav == NULL) {
102 Log::getInstance()->log("Audio", Log::DEBUG,
103 "Find libav mpeg audio decoder failed");
107 aaclatmcodec_libav = avcodec_find_decoder(CODEC_ID_AAC_LATM);
108 if (aaclatmcodec_libav == NULL) {
109 Log::getInstance()->log("Audio", Log::DEBUG,
110 "Find libav aac latm decoder failed");
116 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
120 Log::getInstance()->log("Audio", Log::NOTICE,
121 "TV hdmi supports mpeg1 layer 1 and 2");
123 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0);
127 Log::getInstance()->log("Audio", Log::NOTICE,
128 "TV hdmi supports mpeg1 layer 3");
131 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0);
134 Log::getInstance()->log("Audio", Log::NOTICE,
135 "TV hdmi supports AC3");
137 ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
141 Log::getInstance()->log("Audio", Log::NOTICE,
142 "TV hdmi supports AAC");
145 canpass_pcm_mch=false;
150 int AudioOMX::initAllParams()
152 return (setStreamType(streamType) && setChannel() && setSource());
155 int AudioOMX::shutdown()
157 if (!initted) return 0;
160 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
161 DeAllocateCodecsOMX();
163 free(decompress_buffer);
164 decompress_buffer=NULL;
165 decompress_buffer_size=0;
166 decompress_buffer_filled=0;
171 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
173 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
174 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
177 if (STRCASECMP(name, "PCM") == 0) {
179 } else if (STRCASECMP(name, "Passthrough") == 0) {
181 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
186 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
189 if (STRCASECMP(name, "PCM") == 0) {
191 } else if (STRCASECMP(name, "Passthrough") == 0) {
193 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
198 name = vdr->configLoad("AudioOMX", "AACDecodingMode");
201 if (STRCASECMP(name, "PCM") == 0) {
203 } else if (STRCASECMP(name, "Passthrough") == 0) {
205 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
210 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
213 if (STRCASECMP(name, "PCM") == 0) {
215 } else if (STRCASECMP(name, "Passthrough") == 0) {
217 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
222 name = vdr->configLoad("AudioOMX", "AudioOutput");
225 if (STRCASECMP(name, "analog") == 0) {
227 } else if (STRCASECMP(name, "HDMI") == 0) {
237 bool AudioOMX::handleOptionChanges(Option* option)
239 if (Audio::handleOptionChanges(option))
241 switch (option->id) {
243 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
245 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
253 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
255 } else if (STRCASECMP(option->options[option->userSetChoice],
256 "Passthrough") == 0) {
258 } else if (STRCASECMP(option->options[option->userSetChoice],
259 "PCMMultichannel") == 0) {
265 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
267 } else if (STRCASECMP(option->options[option->userSetChoice],
268 "Passthrough") == 0) {
270 } else if (STRCASECMP(option->options[option->userSetChoice],
271 "PCMMultichannel") == 0) {
277 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
279 } else if (STRCASECMP(option->options[option->userSetChoice],
280 "Passthrough") == 0) {
282 } else if (STRCASECMP(option->options[option->userSetChoice],
283 "PCMMultichannel") == 0) {
289 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
291 } else if (STRCASECMP(option->options[option->userSetChoice],
292 "Passthrough") == 0) {
294 } else if (STRCASECMP(option->options[option->userSetChoice],
295 "PCMMultichannel") == 0) {
305 bool AudioOMX::saveOptionstoServer()
308 switch (prefered_ac3) {
310 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
313 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
317 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
322 switch (prefered_aac) {
324 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
327 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
331 VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
336 switch (prefered_mp2) {
338 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
341 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
345 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
350 switch (prefered_mp3) {
352 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
355 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
359 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
365 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
367 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
373 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
374 UINT numChoices, UINT defaultChoice, UINT startInt,
375 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
377 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
379 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
386 static const char* audioopts[]={"analog","HDMI"};
387 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
388 options->push_back(option);
389 pane->addOptionLine(option);
392 char **ac3opts=new char *[3];
394 ac3opts[i]=new char[strlen("PCM")+1];
395 strcpy(ac3opts[i],"PCM");
398 ac3opts[i]=new char[strlen("Passthrough")+1];
399 strcpy(ac3opts[i],"PassThrough");
402 if (canpass_pcm_mch) {
403 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
404 strcpy(ac3opts[i],"PCMMultichannel");
407 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
408 options->push_back(option);
409 pane->addOptionLine(option);
411 /* char **aacopts = new char *[3];
413 aacopts[i] = new char[strlen("PCM") + 1];
414 strcpy(mp2opts[i], "PCM");
417 aacopts[i] = new char[strlen("Passthrough") + 1];
418 strcpy(aacopts[i], "PassThrough");
421 if (canpass_pcm_mch) {
422 aacopts[i] = new char[strlen("PCMMultichannel") + 1];
423 strcpy(aacopts[i], "PCMMultichannel");
426 option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
427 "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
428 aacopts, NULL, true, this);
429 options->push_back(option);
430 pane->addOptionLine(option);
433 char **mp2opts = new char *[3];
435 mp2opts[i] = new char[strlen("PCM") + 1];
436 strcpy(mp2opts[i], "PCM");
439 mp2opts[i] = new char[strlen("Passthrough") + 1];
440 strcpy(mp2opts[i], "PassThrough");
443 if (canpass_pcm_mch) {
444 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
445 strcpy(mp2opts[i], "PCMMultichannel");
448 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
449 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
450 mp2opts, NULL, true, this);
451 options->push_back(option);
452 pane->addOptionLine(option);
454 char **mp3opts = new char *[3];
456 mp3opts[i] = new char[strlen("PCM") + 1];
457 strcpy(mp3opts[i], "PCM");
460 mp3opts[i] = new char[strlen("Passthrough") + 1];
461 strcpy(mp3opts[i], "PassThrough");
464 if (canpass_pcm_mch) {
465 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
466 strcpy(mp3opts[i], "PCMMultichannel");
469 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
470 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
472 options->push_back(option);
473 pane->addOptionLine(option);*/
474 // Comment unsupported modes out
487 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
489 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
490 AudioOMX *audio=(AudioOMX *)getInstance();
491 audio->ReturnEmptyOMXBuffer(buffer);
492 return OMX_ErrorNone;
496 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
497 input_bufs_omx_mutex.Lock();
498 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
499 input_bufs_omx_free.push_back(buffer);
500 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
501 input_bufs_omx_mutex.Unlock();
504 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
505 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
506 return OMX_ErrorNone;
511 int AudioOMX::setStreamType(UCHAR type)
513 if (!initted) return 0;
515 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
519 int AudioOMX::setChannel()
521 if (!initted) return 0;
523 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
527 int AudioOMX::setSource()
529 if (!initted) return 0;
531 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
537 if (!initted) return 0;
539 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
543 int AudioOMX::play() {
546 lastAType=MPTYPE_MPEG_AUDIO;
547 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
549 ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
551 if (!AllocateCodecsOMX()) {
558 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
561 const char * destinations[]={"local","hdmi"};
566 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
567 memset(&auddest,0,sizeof(auddest));
568 auddest.nSize=sizeof(auddest);
569 auddest.nVersion.nVersion=OMX_VERSION;
570 strcpy((char *)auddest.sName, destinations[dest]);
572 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
573 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
574 if (error!=OMX_ErrorNone){
575 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
576 DeAllocateCodecsOMX();
584 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
587 //Ok first fidle a working configuration
588 Log::getInstance()->log("Audio", Log::DEBUG,
589 "ChangeAudioPortConfig");
591 OMX_AUDIO_CODINGTYPE encoding;
594 case MPTYPE_MPEG_AUDIO: {
595 if (prefered_mp2 == 2 && false) { //not supported yet
598 if (prefered_mp2 == 1 && canpass_mp2) {
600 encoding=OMX_AUDIO_CodingMP3;
603 encoding=OMX_AUDIO_CodingPCM;
608 case MPTYPE_AAC_LATM: {
609 if (prefered_aac == 2 && false) { //not supported yet
612 Log::getInstance()->log("Audio", Log::DEBUG,
613 "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
614 if (prefered_aac == 1 && canpass_aac) {
616 encoding=OMX_AUDIO_CodingAAC;
619 encoding=OMX_AUDIO_CodingPCM;
624 case MPTYPE_AC3_PRE13:
626 if (prefered_ac3 == 2 && false) { //not supported yet
629 Log::getInstance()->log("Audio", Log::DEBUG,
630 "ChangeAudioPortConfig debug %d %d",prefered_ac3,canpass_ac3);
631 if (prefered_ac3 == 1 && canpass_ac3) {
633 encoding=OMX_AUDIO_CodingDDP;
636 encoding=OMX_AUDIO_CodingPCM;
641 case MPTYPE_MPEG_AUDIO_LAYER3: {
642 if (prefered_mp3 == 2 && false) { //not supported yet
645 if (prefered_mp3 == 1 && canpass_mp2) {
647 encoding=OMX_AUDIO_CodingMP3;
650 encoding=OMX_AUDIO_CodingPCM;
658 encoding=OMX_AUDIO_CodingPCM;
659 //mch=false; // multichannel also false
664 /*OMX_CONFIG_BOOLEANTYPE booly;
665 memset(&booly, 0, sizeof(booly));
666 booly.nSize = sizeof(booly);
667 booly.nVersion.nVersion = OMX_VERSION;
669 booly.bEnabled = OMX_TRUE;
671 booly.bEnabled = OMX_FALSE;
673 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
675 if (error != OMX_ErrorNone) {
676 Log::getInstance()->log("Audio", Log::DEBUG,
677 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
678 DeAllocateCodecsOMX();
681 VideoOMX* video=(VideoOMX*)Video::getInstance();
683 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
684 //DestroyInputBufsOMXwhilePlaying();
685 //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port);
690 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
691 memset(&format, 0, sizeof(format));
692 format.nSize = sizeof(format);
693 format.nVersion.nVersion = OMX_VERSION;
694 format.nPortIndex = omx_rend_input_port;
695 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
697 if (error != OMX_ErrorNone) {
698 Log::getInstance()->log("Audio", Log::DEBUG,
699 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
700 omx_rend_input_port);
705 Log::getInstance()->log("Audio", Log::DEBUG,
706 "Get OMX_IndexParamAudioPortFormat returned %d",format.eEncoding );
707 format.eEncoding = encoding;
709 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
711 if (error != OMX_ErrorNone) {
712 Log::getInstance()->log("Audio", Log::DEBUG,
713 "Set OMX_IndexParamAudioPortFormat failed %x %d %d", error,
714 omx_rend_input_port,format.eEncoding );
719 case OMX_AUDIO_CodingPCM: {
720 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
721 memset(&audio_pcm, 0, sizeof(audio_pcm));
722 audio_pcm.nSize = sizeof(audio_pcm);
723 audio_pcm.nVersion.nVersion = OMX_VERSION;
724 audio_pcm.nChannels = 2;
725 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
726 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
727 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
728 audio_pcm.eNumData = OMX_NumericalDataSigned;
729 audio_pcm.eEndian = OMX_EndianLittle;
730 audio_pcm.bInterleaved = OMX_TRUE;
731 audio_pcm.nBitPerSample = 16;
732 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
733 audio_pcm.nChannels = 2;
734 audio_pcm.nSamplingRate = 48000;
735 audio_pcm.nPortIndex = omx_rend_input_port;
736 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
738 if (error != OMX_ErrorNone) {
739 Log::getInstance()->log("Audio", Log::DEBUG,
740 "Init OMX_IndexParamAudioPcm failed %x %d", error,
741 omx_rend_input_port);
745 case OMX_AUDIO_CodingDDP: {
746 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
747 memset(&audio_ddp, 0, sizeof(audio_ddp));
748 audio_ddp.nSize = sizeof(audio_ddp);
749 audio_ddp.nVersion.nVersion = OMX_VERSION;
750 audio_ddp.nPortIndex = omx_rend_input_port;
751 audio_ddp.nChannels = 8; //unknown
752 audio_ddp.nBitRate=0;
753 audio_ddp.nSampleRate=48000;
754 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
755 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
756 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
757 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
758 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
759 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
760 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
761 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
762 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
763 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
765 if (error != OMX_ErrorNone) {
766 Log::getInstance()->log("Audio", Log::DEBUG,
767 "Init OMX_IndexParamAudioDdp failed %x %d", error,
768 omx_rend_input_port);
773 default: break; //Make compiler happy
780 //PrepareInputBufsOMX(false);
781 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
791 int AudioOMX::InitDecoderLibAV()
794 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
795 if (!ac3codec_context_libav) {
796 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
800 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
801 ac3codec_context_libav->request_channels=2;
803 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
805 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
806 libav_mutex.Unlock();
810 aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
811 if (!aaclatmcodec_context_libav) {
812 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
816 aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
817 aaclatmcodec_context_libav->request_channels=2;
819 avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
821 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
822 libav_mutex.Unlock();
827 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
828 if (!ac3codec_context_libav) {
829 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
830 libav_mutex.Unlock();
834 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
835 mp23codec_context_libav->request_channels=2;
837 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
839 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
840 libav_mutex.Unlock();
844 av_init_packet(&incoming_paket_libav);
845 decode_frame_libav=avcodec_alloc_frame();
846 libav_mutex.Unlock();
847 decompress_buffer_filled=0;
854 void AudioOMX::DeinitDecoderLibAV() {
858 if (ac3codec_context_libav) {
859 avcodec_close(ac3codec_context_libav);
860 av_free(ac3codec_context_libav);
861 ac3codec_context_libav = NULL;
863 avcodec_close(aaclatmcodec_context_libav);
864 av_free(aaclatmcodec_context_libav);
865 aaclatmcodec_context_libav = NULL;
867 av_free(decode_frame_libav);
869 avcodec_close(mp23codec_context_libav);
870 av_free(mp23codec_context_libav);
871 mp23codec_context_libav = NULL;
874 libav_mutex.Unlock();
879 int AudioOMX::AllocateCodecsOMX()
882 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
884 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
885 //Clock, move later to audio
886 VideoOMX *video=(VideoOMX*)Video::getInstance();
888 if (!InitDecoderLibAV()) return 0;;
891 OMX_PORT_PARAM_TYPE p_param;
892 memset(&p_param,0,sizeof(p_param));
893 p_param.nSize=sizeof(p_param);
894 p_param.nVersion.nVersion=OMX_VERSION;
897 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
898 return 0;// get the clock and init it if necessary
902 if (!video->idleClock()) {
907 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
908 if (error != OMX_ErrorNone) {
909 Log::getInstance()->log("Audio", Log::DEBUG,
910 "Init OMX audio rend failed %x", error);
911 video->UnlockClock();
912 DeAllocateCodecsOMX();
916 if (!ChangeAudioDestination()) {
917 video->UnlockClock();
918 DeAllocateCodecsOMX();
922 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
923 if (error != OMX_ErrorNone) {
924 Log::getInstance()->log("Audio", Log::DEBUG,
925 "Init OMX audio rend OMX_GetParameter failed %x", error);
926 video->UnlockClock();
927 DeAllocateCodecsOMX();
930 omx_rend_input_port = p_param.nStartPortNumber;
932 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
933 if (error != OMX_ErrorNone) {
934 Log::getInstance()->log("Audio", Log::DEBUG,
935 "Init OMX aud rend OMX_GetParameter failed %x", error);
936 video->UnlockClock();
937 DeAllocateCodecsOMX();
940 // buggy return value
941 omx_rend_clock_port = p_param.nStartPortNumber;
944 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
946 if (error!=OMX_ErrorNone){
947 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
948 video->UnlockClock();
949 DeAllocateCodecsOMX();
953 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
954 if (error!=OMX_ErrorNone){
955 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
956 video->UnlockClock();
957 DeAllocateCodecsOMX();
960 omx_codec_input_port=p_param.nStartPortNumber;
961 omx_codec_output_port=p_param.nStartPortNumber+1;
963 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
964 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
965 video->UnlockClock();
966 DeAllocateCodecsOMX();
973 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
974 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
975 video->UnlockClock();
976 DeAllocateCodecsOMX();
980 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
981 Log::getInstance()->log("Audio", Log::DEBUG,
982 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
983 video->UnlockClock();
984 DeAllocateCodecsOMX();
994 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
995 if (error!=OMX_ErrorNone){
996 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);
997 video->UnlockClock();
998 DeAllocateCodecsOMX();
1002 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
1004 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
1005 video->UnlockClock();
1006 DeAllocateCodecsOMX();
1010 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1011 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
1012 video->UnlockClock();
1013 DeAllocateCodecsOMX();
1020 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
1021 video->UnlockClock();
1022 DeAllocateCodecsOMX();
1026 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1027 video->UnlockClock();
1028 DeAllocateCodecsOMX();
1034 if (!ChangeAudioPortConfig(false)){
1035 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
1036 video->UnlockClock();
1037 DeAllocateCodecsOMX();
1041 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1042 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1043 DeAllocateCodecsOMX();
1049 if (!PrepareInputBufsOMX(true)) {
1050 video->UnlockClock();
1051 DeAllocateCodecsOMX();
1057 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
1058 if (error!=OMX_ErrorNone){
1059 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
1060 video->UnlockClock();
1061 DeAllocateCodecsOMX();
1067 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
1069 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
1070 video->UnlockClock();
1071 DeAllocateCodecsOMX();
1075 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
1076 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1077 video->UnlockClock();
1078 DeAllocateCodecsOMX();
1082 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1083 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
1084 video->UnlockClock();
1085 DeAllocateCodecsOMX();
1090 video->UnlockClock();
1096 if (!video->setClockExecutingandRunning()) return 0;
1098 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
1106 int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
1108 VideoOMX *video=(VideoOMX*)Video::getInstance();
1109 OMX_ERRORTYPE error;
1110 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1111 memset(&port_def_type,0,sizeof(port_def_type));
1112 port_def_type.nSize=sizeof(port_def_type);
1113 port_def_type.nVersion.nVersion=OMX_VERSION;
1114 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
1116 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1118 if (error!=OMX_ErrorNone){
1119 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1124 port_def_type.nBufferCountActual=2;
1125 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
1127 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
1129 if (error!=OMX_ErrorNone){
1130 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1135 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
1136 if (error!=OMX_ErrorNone){
1137 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1141 input_bufs_omx_mutex.Lock();
1142 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1143 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1144 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
1145 if (error!=OMX_ErrorNone){
1146 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1147 input_bufs_omx_mutex.Unlock();
1150 input_bufs_omx_all.push_back(buf_head);
1151 input_bufs_omx_free.push_back(buf_head);
1153 omx_first_frame=true;
1156 cur_input_buf_omx=NULL;
1157 input_bufs_omx_mutex.Unlock();
1159 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1166 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1168 OMX_ERRORTYPE error;
1170 cur_input_buf_omx=NULL;
1171 input_bufs_omx_mutex.Lock();
1172 for (int i=0; i< input_bufs_omx_all.size();i++) {
1173 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1174 if (error!=OMX_ErrorNone){
1175 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1176 input_bufs_omx_mutex.Unlock();
1181 input_bufs_omx_all.clear();
1182 input_bufs_omx_free.clear();
1183 input_bufs_omx_mutex.Unlock();
1187 int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
1189 OMX_ERRORTYPE error;
1191 cur_input_buf_omx=NULL;
1192 input_bufs_omx_mutex.Lock();
1193 while (input_bufs_omx_all.size()>0) {
1194 if (input_bufs_omx_free.size()>0) {
1195 // Destroy one buffer
1196 vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
1197 OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
1198 for (; itty!= input_bufs_omx_all.end();itty++) {
1199 if ((*itty)==cur_buf) {
1200 input_bufs_omx_all.erase(itty);
1201 input_bufs_omx_free.pop_front();
1206 input_bufs_omx_mutex.Unlock();
1208 input_bufs_omx_mutex.Lock();
1212 Log::getInstance()->log("Audio", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
1213 input_bufs_omx_mutex.Unlock();
1218 int AudioOMX::DeAllocateCodecsOMX()
1220 OMX_ERRORTYPE error;
1222 VideoOMX *video=(VideoOMX*)Video::getInstance();
1223 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1227 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1228 if (cur_input_buf_omx) {
1229 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1230 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1231 if (error!=OMX_ErrorNone) {
1232 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1235 cur_input_buf_omx=NULL;//write out old data
1237 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1240 if (omx_aud_rend/*dec*/) {
1241 // first stop the omx elements
1242 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1243 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1245 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1247 video->UnlockClock();
1248 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1250 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1253 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1254 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1257 // TODO proper deinit sequence
1258 // first flush all buffers
1260 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1261 if (error!=OMX_ErrorNone) {
1262 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1266 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1267 if (error!=OMX_ErrorNone){
1268 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1273 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1274 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1279 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1280 if (error!=OMX_ErrorNone){
1281 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1285 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1286 if (error!=OMX_ErrorNone){
1287 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1290 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1292 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1293 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1294 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1297 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1298 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1299 DeinitDecoderLibAV();
1300 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1303 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1304 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1307 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1308 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1311 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1312 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1316 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1317 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1320 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1321 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1326 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1327 if (error!=OMX_ErrorNone) {
1328 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1334 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1335 if (error!=OMX_ErrorNone) {
1336 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1340 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1341 if (error!=OMX_ErrorNone) {
1342 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1346 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1347 if (error!=OMX_ErrorNone) {
1348 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1351 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1354 //error=OMX_FreeHandle(omx_aud_dec);
1355 error=OMX_FreeHandle(omx_aud_rend);
1356 video->UnlockClock();
1357 video->destroyClock();
1358 omx_aud_rend/*dec*/=NULL;
1359 if (error!=OMX_ErrorNone) {
1360 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1364 video->UnlockClock();
1365 DeinitDecoderLibAV();
1367 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1374 int AudioOMX::stop()
1376 if (!initted) return 0;
1378 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1379 DeAllocateCodecsOMX();
1380 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1384 int AudioOMX::mute() {
1387 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1389 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1391 OMX_AUDIO_CONFIG_MUTETYPE amute;
1392 memset(&amute, 0, sizeof(amute));
1393 amute.nSize = sizeof(amute);
1394 amute.nVersion.nVersion = OMX_VERSION;
1395 amute.nPortIndex = omx_rend_input_port;
1396 amute.bMute = OMX_TRUE;
1397 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1399 if (error != OMX_ErrorNone) {
1400 Log::getInstance()->log("Audio", Log::DEBUG,
1401 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1402 omx_rend_input_port);
1412 int AudioOMX::unMute()
1414 if (!initted) return 0;
1416 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1418 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1420 OMX_AUDIO_CONFIG_MUTETYPE amute;
1421 memset(&amute, 0, sizeof(amute));
1422 amute.nSize = sizeof(amute);
1423 amute.nVersion.nVersion = OMX_VERSION;
1424 amute.nPortIndex = omx_rend_input_port;
1425 amute.bMute = OMX_FALSE;
1426 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1428 if (error != OMX_ErrorNone) {
1429 Log::getInstance()->log("Audio", Log::DEBUG,
1430 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1431 omx_rend_input_port);
1441 int AudioOMX::pause() {
1446 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1449 OMX_ERRORTYPE error;
1450 error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1451 omx_rend_input_port, NULL);
1452 if (error != OMX_ErrorNone) {
1453 Log::getInstance()->log("Audio", Log::DEBUG,
1454 "OMX_Flush rend in failed %x", error);
1457 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1458 Log::getInstance()->log("Audio", Log::DEBUG, " pause aud_rend idle ChangeComponentState");
1467 int AudioOMX::unPause()
1469 if (!initted) return 0;
1471 paused=false; // may be also change omx clock
1472 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1474 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1475 Log::getInstance()->log("Audio", Log::DEBUG, " unpause aud_rend idle ChangeComponentState");
1483 int AudioOMX::reset()
1485 if (!initted) return 0;
1487 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1488 DeAllocateCodecsOMX();
1490 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1491 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1492 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1498 int AudioOMX::setVolume(int tvolume)
1500 // parameter: 0 for silence, 20 for full
1501 if ((tvolume < 0) || (tvolume > 20)) return 0;
1503 // volume = 2 * (20 - volume);
1504 // Right, that one was rubbish... 0-10 were almost
1505 // inaudible, 11-20 did what should have been done
1506 // over the whole 0-20 range
1512 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1514 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1515 memset(&avol, 0, sizeof(avol));
1516 avol.nSize = sizeof(avol);
1517 avol.nVersion.nVersion = OMX_VERSION;
1518 avol.nPortIndex = omx_rend_input_port;
1519 avol.bLinear=OMX_FALSE;
1520 avol.sVolume.nValue =(volume-20)*200;
1521 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1523 if (error != OMX_ErrorNone) {
1524 Log::getInstance()->log("Audio", Log::DEBUG,
1525 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1526 omx_rend_input_port);
1536 int AudioOMX::test()
1539 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1541 /* aud_sync_parms_t a;
1545 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1548 /*OK*/ //printf("Audio sync disable = %i\n", b);
1556 unsigned int AudioOMX::AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1558 if (size<=2) return size; // silly;
1559 unsigned int test=0;
1561 while (test+1<size) {
1562 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1568 unsigned int AudioOMX::AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1570 if (size<=4) return size; // silly;
1571 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1572 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1573 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1574 1152, 1280, 1280, };
1575 unsigned int test=0;
1576 *framesize=20000; //if we do not find a start code do not decompress
1577 while (test+4<size) {
1578 if (data[test]==0x0B && data[test+1]==0x77) {
1579 // now figure out the length of the frame
1580 unsigned char code=data[test+4];
1581 unsigned char fscod=(code& 0xC0)>>6;
1582 unsigned char frmsize=(code &0x3f);
1583 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1584 *framesize=frm_size_tab[frmsize]*2;
1585 return test; // probably FrameSync
1592 unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
1594 if (size<=4) return size; // silly;
1595 unsigned int test=0;
1596 *framesize=20000; //if we do not find a start code do not decompress
1597 while (test+4<size) {
1598 if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
1599 // now figure out the length of the frame
1600 unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
1602 return test; // probably FrameSync
1610 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1612 packet = mplist.front();
1615 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1616 DeliverMediaPacket(packet, buffer, samplepos);
1617 if (*samplepos == packet.length) {
1625 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1627 VideoOMX *video = (VideoOMX*) Video::getInstance();
1629 OMX_PARAM_U32TYPE audio_lat;
1630 OMX_ERRORTYPE error;
1631 memset(&audio_lat, 0, sizeof(audio_lat));
1632 audio_lat.nSize = sizeof(audio_lat);
1633 audio_lat.nVersion.nVersion = OMX_VERSION;
1634 audio_lat.nPortIndex = omx_rend_input_port;
1636 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1638 video->UnlockClock();
1639 if (error != OMX_ErrorNone) {
1640 Log::getInstance()->log("Audio", Log::DEBUG,
1641 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1642 omx_rend_input_port);
1643 return pts; // no correction in case of error
1645 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1648 long long workpts=0;
1649 workpts+=addsamples;
1650 workpts-=audio_lat.nU32;
1651 workpts*=10LL*1000LL*1000LL;
1652 workpts=workpts/((long long)srate); //one second /samplerate
1660 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1662 /*First Check, if we have an audio sample*/
1663 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1665 OMX_ERRORTYPE error;
1666 Log *logger=Log::getInstance();
1667 if (vw->InIframemode()) {
1670 return 0; //Not in iframe mode!
1673 if (!omx_running) return 0; // if we are not runnig do not do this
1674 if (paused) return 0; //Block if we pause
1675 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 1");
1677 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1679 /* if (packet.synched && packet.presentation_time <= 0) {
1680 *samplepos = packet.length;
1681 firstsynched = false;
1683 Log::getInstance()->log("Audio", Log::DEBUG,
1684 "DeliverMediaPacketOMX Frameskip");
1685 return packet.length;
1688 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 2");
1690 UINT headerstrip = 0;
1691 if (packet.disconti) {
1692 firstsynched = false;
1693 decompress_buffer_filled=0;
1694 if (cur_input_buf_omx) {
1695 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1697 if (error != OMX_ErrorNone) {
1698 Log::getInstance()->log("Audio", Log::DEBUG,
1699 "OMX_EmptyThisBuffer 1 failed %x", error);
1701 cur_input_buf_omx = NULL;
1705 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 3");
1706 if (packet.type != lastAType) {//Format Change //Push data out !
1707 firstsynched = false;
1709 lastAType = packet.type;
1710 decompress_buffer_filled=0;
1712 if (cur_input_buf_omx) {
1713 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1715 if (error != OMX_ErrorNone) {
1716 Log::getInstance()->log("Audio", Log::DEBUG,
1717 "OMX_EmptyThisBuffer 2 failed %x", error);
1719 cur_input_buf_omx = NULL;
1723 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1724 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1726 if (!ChangeAudioPortConfig(true)) {
1727 Log::getInstance()->log("Audio", Log::DEBUG,
1728 "Changing audio port config failed", error);
1731 pthread_setcancelstate(oldcancelstate, NULL);
1732 pthread_setcanceltype(oldcanceltype, NULL);
1736 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 4");
1738 /*Inspect PES-Header */
1739 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1740 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1741 if (packet.type == MPTYPE_AC3)
1742 headerstrip += 4; //skip ac3 bytes
1743 *samplepos += headerstrip;
1744 if (packet.synched) {
1745 if (cur_input_buf_omx) {
1746 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1747 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1749 if (error != OMX_ErrorNone) {
1750 Log::getInstance()->log("Audio", Log::DEBUG,
1751 "OMX_EmptyThisBuffer 3 failed %x", error);
1753 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1755 cur_input_buf_omx = NULL;//write out old data
1757 firstsynched = true;
1758 //decompress_buffer_filled=0;
1760 if (!firstsynched) {//
1761 *samplepos = packet.length;//if we have not processed at least one
1762 decompress_buffer_filled=0;
1763 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 5");
1764 return packet.length;//synched packet ignore it!
1768 if (!cur_input_buf_omx) {
1769 input_bufs_omx_mutex.Lock();
1770 if (input_bufs_omx_free.size()==0) {
1771 input_bufs_omx_mutex.Unlock();
1772 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 6");
1773 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1774 return 0; // we do not have a free media sample
1777 cur_input_buf_omx=input_bufs_omx_free.front();
1778 cur_input_buf_omx->nFilledLen=0;
1779 cur_input_buf_omx->nOffset=0;
1780 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1781 input_bufs_omx_free.pop_front();
1782 input_bufs_omx_mutex.Unlock();
1784 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 7");
1786 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1787 if (packet.synched) {
1788 //Log::getInstance()->log("Audio", Log::DEBUG,
1789 // "packet synched marker");
1791 //lastreftimePTS=packet.pts;
1792 if (omx_first_frame) { // TODO time
1793 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1794 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1795 omx_first_frame = false;
1797 cur_input_buf_omx->nFlags = 0;
1798 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1800 lastreftimeOMX = packet.presentation_time;
1801 // Log::getInstance()->log("Audio", Log::DEBUG,
1802 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1803 lastreftimePTS = packet.pts;
1804 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1806 // Log::getInstance()->log("Audio", Log::DEBUG,
1807 // "packet NOT synched marker");
1808 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1809 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1812 if (packet.disconti || achange) {
1813 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1814 //mp23codec_context_libav->frame_size=-1;
1815 //ac3codec_context_libav->frame_size=-1;
1819 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 8");
1821 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1822 unsigned int haveToCopy=packet.length-*samplepos;
1825 while (haveToCopy>0) {
1826 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 9");
1828 unsigned int gotframesize=0;
1830 switch (packet.type) {
1831 case MPTYPE_MPEG_AUDIO:
1832 case MPTYPE_MPEG_AUDIO_LAYER3: {
1833 adv = AdvanceMpAudioSync(buffer+packet.pos_buffer+*samplepos,
1834 haveToCopy,&gotframesize);
1838 case MPTYPE_AC3_PRE13: {
1839 adv = AdvanceAc3AudioSync(buffer+packet.pos_buffer+*samplepos,
1840 haveToCopy,&gotframesize);
1844 case MPTYPE_AAC_LATM: {
1845 adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
1846 haveToCopy,&gotframesize);
1850 if (adv!=haveToCopy) {
1855 *samplepos=packet.length; //no ac3 sync byte
1856 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 10");
1857 return packet.length;
1860 // so everything is fine now do a memcpy
1861 int cancopy=min(haveToCopy,cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen);
1862 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1863 haveToCopy-=cancopy;
1864 cur_input_buf_omx->nFilledLen+=cancopy;
1865 *samplepos+=cancopy;
1866 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 11");
1868 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1869 if (error != OMX_ErrorNone) {
1870 Log::getInstance()->log("Audio", Log::DEBUG,
1871 "OMX_EmptyThisBuffer 5 failed %x", error);
1873 cur_input_buf_omx=NULL;
1876 input_bufs_omx_mutex.Lock();
1877 if (input_bufs_omx_free.size()==0) {
1878 input_bufs_omx_mutex.Unlock();
1879 // Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample2");
1880 return *samplepos; // we do not have a free media sample
1882 cur_input_buf_omx=input_bufs_omx_free.front();
1883 cur_input_buf_omx->nFilledLen=0;
1884 cur_input_buf_omx->nOffset=0;
1885 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1886 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1887 input_bufs_omx_free.pop_front();
1888 input_bufs_omx_mutex.Unlock();
1890 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 12");
1893 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 13");
1901 AVCodecContext *current_context;
1902 switch (packet.type) {
1903 case MPTYPE_MPEG_AUDIO:
1904 case MPTYPE_MPEG_AUDIO_LAYER3: {
1905 current_context = mp23codec_context_libav;
1906 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1907 else framesize=current_context->frame_size;
1909 case MPTYPE_AAC_LATM: {
1910 current_context = aaclatmcodec_context_libav;
1913 case MPTYPE_AC3_PRE13: {
1914 current_context = ac3codec_context_libav;
1918 if (decompress_buffer_filled) { // have a remaining paket
1919 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1920 memcpy(decompress_buffer+decompress_buffer_filled,
1921 buffer+packet.pos_buffer+*samplepos,
1922 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1923 incoming_paket_libav.size = decompress_buffer_filled
1924 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1925 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1927 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1928 incoming_paket_libav.size = haveToCopy;
1930 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 18");
1932 while (haveToCopy> 0 && errcount<3) {
1934 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1935 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1936 // framesize, current_context->frame_size);
1938 bool donotdecompress=false;
1939 unsigned int gotframesize=0;
1940 if (!decompress_buffer_filled) { // only do this if no old data is present
1942 switch (packet.type) {
1943 case MPTYPE_MPEG_AUDIO:
1944 case MPTYPE_MPEG_AUDIO_LAYER3: {
1945 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1946 incoming_paket_libav.size,&gotframesize);
1950 case MPTYPE_AC3_PRE13: {
1951 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1952 incoming_paket_libav.size,&gotframesize);
1955 case MPTYPE_AAC_LATM: {
1956 adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
1957 incoming_paket_libav.size,&gotframesize);
1962 incoming_paket_libav.data += adv;
1963 incoming_paket_libav.size-=adv;
1966 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1967 else*/ framesize=haveToCopy;
1968 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1969 if (haveToCopy <= 0) {
1970 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1971 *samplepos=packet.length;
1972 return packet.length;
1978 if (gotframesize>0 && gotframesize>haveToCopy) {
1979 donotdecompress=true;
1980 errcount=100; // exit loop
1982 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1984 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 19");
1985 if (!donotdecompress) {
1988 pthread_testcancel();
1989 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1990 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1992 if (!omx_running || !mp23codec_context_libav
1993 || !ac3codec_context_libav) {
1994 libav_mutex.Unlock();
1997 libav_mutex.Unlock();
1998 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1999 len = avcodec_decode_audio4(current_context, decode_frame_libav,
2000 &gotta, &incoming_paket_libav);
2001 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
2002 pthread_setcancelstate(oldcancelstate, NULL);
2003 pthread_setcanceltype(oldcanceltype, NULL);
2004 pthread_testcancel();
2010 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
2011 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 20");
2013 libav_mutex.Unlock();
2017 if (decompress_buffer_filled) { // reset to normal decoding
2019 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
2020 haveToCopy -= min(len-decompress_buffer_filled,0);
2021 *samplepos += min(len-decompress_buffer_filled,0);
2022 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2023 /*else*/ framesize=haveToCopy;
2025 framesize=haveToCopy;
2027 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
2029 decompress_buffer_filled=0;
2033 incoming_paket_libav.data += len;
2037 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
2038 else*/framesize=haveToCopy;
2041 framesize=haveToCopy;
2044 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 21");
2046 incoming_paket_libav.size =framesize;
2048 //Log::getInstance()->log("Audio", Log::DEBUG,
2050 int dsize = av_samples_get_buffer_size(NULL,
2051 current_context->channels, decode_frame_libav->nb_samples,
2052 current_context->sample_fmt, 1);
2053 if ((cur_input_buf_omx->nFilledLen + dsize)
2054 > cur_input_buf_omx->nAllocLen ) {
2055 // I doubt that this will ever happen
2056 // Log::getInstance()->log("Audio", Log::DEBUG,
2057 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2058 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
2060 if (error != OMX_ErrorNone) {
2061 Log::getInstance()->log("Audio", Log::DEBUG,
2062 "OMX_EmptyThisBuffer 4 failed %x", error);
2064 cur_input_buf_omx = NULL;
2066 if (!cur_input_buf_omx) {
2068 while (count < 10 && omx_running) {
2070 input_bufs_omx_mutex.Lock();
2071 if (input_bufs_omx_free.size() == 0) {
2072 input_bufs_omx_mutex.Unlock();
2073 // Log::getInstance()->log("Audio", Log::DEBUG,
2074 // "Deliver MediaPacket no free sample");
2076 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark22");
2077 if (!omx_running) return *samplepos;
2078 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 23");
2081 cur_input_buf_omx = input_bufs_omx_free.front();
2082 cur_input_buf_omx->nFilledLen = 0;
2083 cur_input_buf_omx->nOffset = 0;
2084 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
2085 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2086 input_bufs_omx_free.pop_front();
2087 input_bufs_omx_mutex.Unlock();
2090 if (!cur_input_buf_omx) return *samplepos;
2095 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
2096 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
2097 decode_frame_libav->data[0], dsize);
2098 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
2099 cur_input_buf_omx->nFilledLen += dsize;
2101 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
2102 /* uint8_t a1=incoming_paket_libav.data[0];
2103 uint8_t a2=incoming_paket_libav.data[1];
2104 uint8_t a3=incoming_paket_libav.data[2];
2105 uint8_t a4=incoming_paket_libav.data[3];*/
2106 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
2111 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 24");
2112 decompress_buffer_filled=0;
2114 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);
2115 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
2117 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
2121 if (cur_input_buf_omx->nFilledLen) {
2122 //Log::getInstance()->log("Audio", Log::DEBUG,
2123 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
2124 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
2125 if (error != OMX_ErrorNone) {
2126 Log::getInstance()->log("Audio", Log::DEBUG,
2127 "OMX_EmptyThisBuffer 5 failed %x", error);
2129 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
2130 cur_input_buf_omx = NULL;
2135 //Log::getInstance()->log("Audio", Log::DEBUG, "DMP mark 25");
2137 *samplepos=packet.length;
2138 return packet.length;
2144 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
2145 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2146 return vw->SetStartAudioOffset(curreftime,rsync);
2149 void AudioOMX::ResetTimeOffsets() {
2150 VideoOMX *vw=(VideoOMX*)Video::getInstance();
2151 vw->ResetTimeOffsets();