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"
33 lastAType = MPTYPE_MPEG_AUDIO;
38 canpass_pcm_mch=false;
40 prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
47 omx_aud_rend/*dec*/=0;
48 cur_input_buf_omx=NULL;
51 ac3codec_context_libav=NULL;
54 mp23codec_context_libav=NULL;
56 decompress_buffer=NULL;
57 decompress_buffer_size=0;
58 decompress_buffer_filled=0;
66 int AudioOMX::init(UCHAR tstreamType) {
71 streamType = tstreamType;
73 if (!initAllParams()) {
80 decompress_buffer_size=20000;
81 decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
82 decompress_buffer_filled=0;
87 av_log_set_flags(AV_LOG_SKIP_REPEATED);
89 ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
90 if (ac3codec_libav == NULL) {
91 Log::getInstance()->log("Audio", Log::DEBUG,
92 "Find libav ac3 decoder failed");
96 mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
97 if (mp23codec_libav == NULL) {
98 Log::getInstance()->log("Audio", Log::DEBUG,
99 "Find libav mpeg audio decoder failed");
106 int AudioOMX::initAllParams()
108 return (setStreamType(streamType) && setChannel() && setSource());
111 int AudioOMX::shutdown()
113 if (!initted) return 0;
116 Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
117 DeAllocateCodecsOMX();
119 free(decompress_buffer);
120 decompress_buffer=NULL;
121 decompress_buffer_size=0;
122 decompress_buffer_filled=0;
127 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
129 Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
130 char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
133 if (STRCASECMP(name, "PCM") == 0) {
135 } else if (STRCASECMP(name, "Passthrough") == 0) {
137 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
142 name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
145 if (STRCASECMP(name, "PCM") == 0) {
147 } else if (STRCASECMP(name, "Passthrough") == 0) {
149 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
154 name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
157 if (STRCASECMP(name, "PCM") == 0) {
159 } else if (STRCASECMP(name, "Passthrough") == 0) {
161 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
166 name = vdr->configLoad("AudioOMX", "AudioOutput");
169 if (STRCASECMP(name, "analog") == 0) {
171 } else if (STRCASECMP(name, "HDMI") == 0) {
181 bool AudioOMX::handleOptionChanges(Option* option)
183 if (Audio::handleOptionChanges(option))
185 switch (option->id) {
187 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
189 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
197 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
199 } else if (STRCASECMP(option->options[option->userSetChoice],
200 "Passthrough") == 0) {
202 } else if (STRCASECMP(option->options[option->userSetChoice],
203 "PCMMultichannel") == 0) {
209 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
211 } else if (STRCASECMP(option->options[option->userSetChoice],
212 "Passthrough") == 0) {
214 } else if (STRCASECMP(option->options[option->userSetChoice],
215 "PCMMultichannel") == 0) {
221 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
223 } else if (STRCASECMP(option->options[option->userSetChoice],
224 "Passthrough") == 0) {
226 } else if (STRCASECMP(option->options[option->userSetChoice],
227 "PCMMultichannel") == 0) {
237 bool AudioOMX::saveOptionstoServer()
240 switch (prefered_ac3) {
242 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
245 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
249 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
254 switch (prefered_mp2) {
256 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
259 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
263 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
268 switch (prefered_mp3) {
270 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
273 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
277 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
283 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
285 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
291 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
292 UINT numChoices, UINT defaultChoice, UINT startInt,
293 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
295 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
297 if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
304 static const char* audioopts[]={"analog","HDMI"};
305 option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
306 options->push_back(option);
307 pane->addOptionLine(option);
310 char **ac3opts=new char *[3];
312 ac3opts[i]=new char[strlen("PCM")+1];
313 strcpy(ac3opts[i],"PCM");
316 ac3opts[i]=new char[strlen("Passthrough")+1];
317 strcpy(ac3opts[i],"PassThrough");
320 if (canpass_pcm_mch) {
321 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
322 strcpy(ac3opts[i],"PCMMultichannel");
325 option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
326 options->push_back(option);
327 pane->addOptionLine(option);
329 char **mp2opts = new char *[3];
331 mp2opts[i] = new char[strlen("PCM") + 1];
332 strcpy(mp2opts[i], "PCM");
335 mp2opts[i] = new char[strlen("Passthrough") + 1];
336 strcpy(mp2opts[i], "PassThrough");
339 if (canpass_pcm_mch) {
340 mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
341 strcpy(mp2opts[i], "PCMMultichannel");
344 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
345 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
346 mp2opts, NULL, true, this);
347 options->push_back(option);
348 pane->addOptionLine(option);
350 char **mp3opts = new char *[3];
352 mp3opts[i] = new char[strlen("PCM") + 1];
353 strcpy(mp3opts[i], "PCM");
356 mp3opts[i] = new char[strlen("Passthrough") + 1];
357 strcpy(mp3opts[i], "PassThrough");
360 if (canpass_pcm_mch) {
361 mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
362 strcpy(mp3opts[i], "PCMMultichannel");
365 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
366 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
368 options->push_back(option);
369 pane->addOptionLine(option);
382 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
384 //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
385 AudioOMX *audio=(AudioOMX *)getInstance();
386 audio->ReturnEmptyOMXBuffer(buffer);
387 return OMX_ErrorNone;
391 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
392 input_bufs_omx_mutex.Lock();
393 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
394 input_bufs_omx_free.push_back(buffer);
395 //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
396 input_bufs_omx_mutex.Unlock();
399 OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
400 Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
401 return OMX_ErrorNone;
406 int AudioOMX::setStreamType(UCHAR type)
408 if (!initted) return 0;
410 // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
414 int AudioOMX::setChannel()
416 if (!initted) return 0;
418 // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
422 int AudioOMX::setSource()
424 if (!initted) return 0;
426 // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
432 if (!initted) return 0;
434 // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
438 int AudioOMX::play() {
441 lastAType=MPTYPE_MPEG_AUDIO;
442 Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
444 if (!AllocateCodecsOMX()) {
451 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
454 const char * destinations[]={"local","hdmi"};
459 OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
460 memset(&auddest,0,sizeof(auddest));
461 auddest.nSize=sizeof(auddest);
462 auddest.nVersion.nVersion=OMX_VERSION;
463 strcpy((char *)auddest.sName, destinations[dest]);
465 Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
466 error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
467 if (error!=OMX_ErrorNone){
468 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
469 DeAllocateCodecsOMX();
477 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
480 //Ok first fidle a working configuration
481 Log::getInstance()->log("Audio", Log::DEBUG,
482 "ChangeAudioPortConfig");
484 OMX_AUDIO_CODINGTYPE encoding;
487 case MPTYPE_MPEG_AUDIO: {
488 if (prefered_mp2 == 3 && false) { //not supported yet
491 if (prefered_mp2 == 2 && canpass_mp2) {
493 encoding=OMX_AUDIO_CodingMP3;
496 encoding=OMX_AUDIO_CodingPCM;
501 case MPTYPE_AC3_PRE13:
503 if (prefered_ac3 == 3 && false) { //not supported yet
506 if (prefered_ac3 == 2 && canpass_ac3) {
508 encoding=OMX_AUDIO_CodingDDP;
511 encoding=OMX_AUDIO_CodingPCM;
516 case MPTYPE_MPEG_AUDIO_LAYER3: {
517 if (prefered_mp3 == 3 && false) { //not supported yet
520 if (prefered_mp3 == 2 && canpass_mp2) {
522 encoding=OMX_AUDIO_CodingMP3;
525 encoding=OMX_AUDIO_CodingPCM;
533 encoding=OMX_AUDIO_CodingPCM;
534 //mch=false; // multichannel also false
539 /*OMX_CONFIG_BOOLEANTYPE booly;
540 memset(&booly, 0, sizeof(booly));
541 booly.nSize = sizeof(booly);
542 booly.nVersion.nVersion = OMX_VERSION;
544 booly.bEnabled = OMX_TRUE;
546 booly.bEnabled = OMX_FALSE;
548 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
550 if (error != OMX_ErrorNone) {
551 Log::getInstance()->log("Audio", Log::DEBUG,
552 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
553 DeAllocateCodecsOMX();
560 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
561 memset(&format, 0, sizeof(format));
562 format.nSize = sizeof(format);
563 format.nVersion.nVersion = OMX_VERSION;
564 format.nPortIndex = omx_rend_input_port;
565 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
567 if (error != OMX_ErrorNone) {
568 Log::getInstance()->log("Audio", Log::DEBUG,
569 "Get OMX_IndexParamAudioPortFormat failed %x %d", error,
570 omx_rend_input_port);
574 format.eEncoding = encoding;
576 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat,
578 if (error != OMX_ErrorNone) {
579 Log::getInstance()->log("Audio", Log::DEBUG,
580 "Set OMX_IndexParamAudioPortFormat failed %x %d", error,
581 omx_rend_input_port);
586 case OMX_AUDIO_CodingPCM: {
587 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
588 memset(&audio_pcm, 0, sizeof(audio_pcm));
589 audio_pcm.nSize = sizeof(audio_pcm);
590 audio_pcm.nVersion.nVersion = OMX_VERSION;
591 audio_pcm.nChannels = 2;
592 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
593 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
594 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
595 audio_pcm.eNumData = OMX_NumericalDataSigned;
596 audio_pcm.eEndian = OMX_EndianLittle;
597 audio_pcm.bInterleaved = OMX_TRUE;
598 audio_pcm.nBitPerSample = 16;
599 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
600 audio_pcm.nChannels = 2;
601 audio_pcm.nSamplingRate = 48000;
602 audio_pcm.nPortIndex = omx_rend_input_port;
603 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
605 if (error != OMX_ErrorNone) {
606 Log::getInstance()->log("Audio", Log::DEBUG,
607 "Init OMX_IndexParamAudioPcm failed %x %d", error,
608 omx_rend_input_port);
612 case OMX_AUDIO_CodingDDP: {
613 OMX_AUDIO_PARAM_DDPTYPE audio_ddp;
614 memset(&audio_ddp, 0, sizeof(audio_ddp));
615 audio_ddp.nSize = sizeof(audio_ddp);
616 audio_ddp.nVersion.nVersion = OMX_VERSION;
617 audio_ddp.nPortIndex = omx_rend_input_port;
618 audio_ddp.nChannels = 8; //unknown
619 audio_ddp.nBitRate=0;
620 audio_ddp.nSampleRate=48000;
621 audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF;
622 audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF;
623 audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF;
624 audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE;
625 audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR;
626 audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR;
627 audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS;
628 audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS;
629 audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS;
630 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp,
632 if (error != OMX_ErrorNone) {
633 Log::getInstance()->log("Audio", Log::DEBUG,
634 "Init OMX_IndexParamAudioDdp failed %x %d", error,
635 omx_rend_input_port);
652 int AudioOMX::InitDecoderLibAV()
655 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
656 if (!ac3codec_context_libav) {
657 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
661 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
662 ac3codec_context_libav->request_channels=2;
664 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
666 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
667 libav_mutex.Unlock();
671 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
672 if (!ac3codec_context_libav) {
673 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
674 libav_mutex.Unlock();
678 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
679 mp23codec_context_libav->request_channels=2;
681 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
683 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
684 libav_mutex.Unlock();
688 av_init_packet(&incoming_paket_libav);
689 decode_frame_libav=avcodec_alloc_frame();
690 libav_mutex.Unlock();
691 decompress_buffer_filled=0;
698 void AudioOMX::DeinitDecoderLibAV() {
702 if (ac3codec_context_libav) {
703 avcodec_close(ac3codec_context_libav);
704 av_free(ac3codec_context_libav);
705 ac3codec_context_libav = NULL;
706 av_free(decode_frame_libav);
707 avcodec_close(mp23codec_context_libav);
708 av_free(mp23codec_context_libav);
709 mp23codec_context_libav = NULL;
712 libav_mutex.Unlock();
717 int AudioOMX::AllocateCodecsOMX()
720 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
722 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
723 //Clock, move later to audio
724 VideoOMX *video=(VideoOMX*)Video::getInstance();
726 if (!InitDecoderLibAV()) return 0;;
729 OMX_PORT_PARAM_TYPE p_param;
730 memset(&p_param,0,sizeof(p_param));
731 p_param.nSize=sizeof(p_param);
732 p_param.nVersion.nVersion=OMX_VERSION;
735 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
736 return 0;// get the clock and init it if necessary
740 if (!video->idleClock()) {
745 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
746 if (error != OMX_ErrorNone) {
747 Log::getInstance()->log("Audio", Log::DEBUG,
748 "Init OMX audio rend failed %x", error);
749 video->UnlockClock();
750 DeAllocateCodecsOMX();
754 if (!ChangeAudioDestination()) {
755 video->UnlockClock();
756 DeAllocateCodecsOMX();
760 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
761 if (error != OMX_ErrorNone) {
762 Log::getInstance()->log("Audio", Log::DEBUG,
763 "Init OMX audio rend OMX_GetParameter failed %x", error);
764 video->UnlockClock();
765 DeAllocateCodecsOMX();
768 omx_rend_input_port = p_param.nStartPortNumber;
770 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
771 if (error != OMX_ErrorNone) {
772 Log::getInstance()->log("Audio", Log::DEBUG,
773 "Init OMX aud rend OMX_GetParameter failed %x", error);
774 video->UnlockClock();
775 DeAllocateCodecsOMX();
778 // buggy return value
779 omx_rend_clock_port = p_param.nStartPortNumber;
782 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
784 if (error!=OMX_ErrorNone){
785 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
786 video->UnlockClock();
787 DeAllocateCodecsOMX();
791 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
792 if (error!=OMX_ErrorNone){
793 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
794 video->UnlockClock();
795 DeAllocateCodecsOMX();
798 omx_codec_input_port=p_param.nStartPortNumber;
799 omx_codec_output_port=p_param.nStartPortNumber+1;
801 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
802 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
803 video->UnlockClock();
804 DeAllocateCodecsOMX();
811 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
812 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
813 video->UnlockClock();
814 DeAllocateCodecsOMX();
818 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
819 Log::getInstance()->log("Audio", Log::DEBUG,
820 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
821 video->UnlockClock();
822 DeAllocateCodecsOMX();
832 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
833 if (error!=OMX_ErrorNone){
834 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);
835 video->UnlockClock();
836 DeAllocateCodecsOMX();
840 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
842 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
843 video->UnlockClock();
844 DeAllocateCodecsOMX();
848 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
849 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
850 video->UnlockClock();
851 DeAllocateCodecsOMX();
858 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
859 video->UnlockClock();
860 DeAllocateCodecsOMX();
864 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
865 video->UnlockClock();
866 DeAllocateCodecsOMX();
872 if (!ChangeAudioPortConfig(false)){
873 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
874 video->UnlockClock();
875 DeAllocateCodecsOMX();
879 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
880 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
881 DeAllocateCodecsOMX();
887 if (!PrepareInputBufsOMX()) {
888 video->UnlockClock();
889 DeAllocateCodecsOMX();
895 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
896 if (error!=OMX_ErrorNone){
897 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
898 video->UnlockClock();
899 DeAllocateCodecsOMX();
905 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
907 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
908 video->UnlockClock();
909 DeAllocateCodecsOMX();
913 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
914 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
915 video->UnlockClock();
916 DeAllocateCodecsOMX();
920 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
921 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
922 video->UnlockClock();
923 DeAllocateCodecsOMX();
928 video->UnlockClock();
934 if (!video->setClockExecutingandRunning()) return 0;
936 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
944 int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock mutex
946 VideoOMX *video=(VideoOMX*)Video::getInstance();
948 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
949 memset(&port_def_type,0,sizeof(port_def_type));
950 port_def_type.nSize=sizeof(port_def_type);
951 port_def_type.nVersion.nVersion=OMX_VERSION;
952 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
954 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
956 if (error!=OMX_ErrorNone){
957 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
961 port_def_type.nBufferCountActual=2;
962 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
964 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
966 if (error!=OMX_ErrorNone){
967 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
971 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
972 if (error!=OMX_ErrorNone){
973 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
977 input_bufs_omx_mutex.Lock();
978 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
979 OMX_BUFFERHEADERTYPE *buf_head=NULL;
980 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
981 if (error!=OMX_ErrorNone){
982 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
983 input_bufs_omx_mutex.Unlock();
986 input_bufs_omx_all.push_back(buf_head);
987 input_bufs_omx_free.push_back(buf_head);
989 omx_first_frame=true;
992 cur_input_buf_omx=NULL;
993 input_bufs_omx_mutex.Unlock();
995 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
1002 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1004 OMX_ERRORTYPE error;
1006 cur_input_buf_omx=NULL;
1007 input_bufs_omx_mutex.Lock();
1008 for (int i=0; i< input_bufs_omx_all.size();i++) {
1009 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1010 if (error!=OMX_ErrorNone){
1011 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1012 input_bufs_omx_mutex.Unlock();
1017 input_bufs_omx_all.clear();
1018 input_bufs_omx_free.clear();
1019 input_bufs_omx_mutex.Unlock();
1024 int AudioOMX::DeAllocateCodecsOMX()
1026 OMX_ERRORTYPE error;
1028 VideoOMX *video=(VideoOMX*)Video::getInstance();
1029 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1033 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1034 if (cur_input_buf_omx) {
1035 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1036 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1037 if (error!=OMX_ErrorNone) {
1038 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1041 cur_input_buf_omx=NULL;//write out old data
1043 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1046 if (omx_aud_rend/*dec*/) {
1047 // first stop the omx elements
1048 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1049 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1051 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1053 video->UnlockClock();
1054 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1056 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1059 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1060 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1063 // TODO proper deinit sequence
1064 // first flush all buffers
1066 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1067 if (error!=OMX_ErrorNone) {
1068 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1072 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1073 if (error!=OMX_ErrorNone){
1074 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1079 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1080 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1085 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1086 if (error!=OMX_ErrorNone){
1087 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1091 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1092 if (error!=OMX_ErrorNone){
1093 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1096 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1098 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1099 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1100 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1103 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1104 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1105 DeinitDecoderLibAV();
1106 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1109 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1110 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1113 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1114 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1117 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1118 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1122 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1123 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1126 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1127 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1132 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1133 if (error!=OMX_ErrorNone) {
1134 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1140 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1141 if (error!=OMX_ErrorNone) {
1142 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1146 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1147 if (error!=OMX_ErrorNone) {
1148 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1152 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1153 if (error!=OMX_ErrorNone) {
1154 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1157 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1160 //error=OMX_FreeHandle(omx_aud_dec);
1161 error=OMX_FreeHandle(omx_aud_rend);
1162 video->UnlockClock();
1163 video->destroyClock();
1164 omx_aud_rend/*dec*/=NULL;
1165 if (error!=OMX_ErrorNone) {
1166 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1170 video->UnlockClock();
1171 DeinitDecoderLibAV();
1173 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1180 int AudioOMX::stop()
1182 if (!initted) return 0;
1184 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1185 DeAllocateCodecsOMX();
1186 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1190 int AudioOMX::mute() {
1193 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1195 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1197 OMX_AUDIO_CONFIG_MUTETYPE amute;
1198 memset(&amute, 0, sizeof(amute));
1199 amute.nSize = sizeof(amute);
1200 amute.nVersion.nVersion = OMX_VERSION;
1201 amute.nPortIndex = omx_rend_input_port;
1202 amute.bMute = OMX_TRUE;
1203 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1205 if (error != OMX_ErrorNone) {
1206 Log::getInstance()->log("Audio", Log::DEBUG,
1207 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1208 omx_rend_input_port);
1218 int AudioOMX::unMute()
1220 if (!initted) return 0;
1222 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1224 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1226 OMX_AUDIO_CONFIG_MUTETYPE amute;
1227 memset(&amute, 0, sizeof(amute));
1228 amute.nSize = sizeof(amute);
1229 amute.nVersion.nVersion = OMX_VERSION;
1230 amute.nPortIndex = omx_rend_input_port;
1231 amute.bMute = OMX_FALSE;
1232 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1234 if (error != OMX_ErrorNone) {
1235 Log::getInstance()->log("Audio", Log::DEBUG,
1236 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1237 omx_rend_input_port);
1247 int AudioOMX::pause() {
1252 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1255 OMX_ERRORTYPE error;
1256 error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1257 omx_rend_input_port, NULL);
1258 if (error != OMX_ErrorNone) {
1259 Log::getInstance()->log("Audio", Log::DEBUG,
1260 "OMX_Flush rend in failed %x", error);
1263 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1264 Log::getInstance()->log("Audio", Log::DEBUG, " pause aud_rend idle ChangeComponentState");
1273 int AudioOMX::unPause()
1275 if (!initted) return 0;
1277 paused=false; // may be also change omx clock
1278 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1280 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1281 Log::getInstance()->log("Audio", Log::DEBUG, " unpause aud_rend idle ChangeComponentState");
1289 int AudioOMX::reset()
1291 if (!initted) return 0;
1293 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1294 DeAllocateCodecsOMX();
1296 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1297 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1298 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1304 int AudioOMX::setVolume(int tvolume)
1306 // parameter: 0 for silence, 20 for full
1307 if ((tvolume < 0) || (tvolume > 20)) return 0;
1309 // volume = 2 * (20 - volume);
1310 // Right, that one was rubbish... 0-10 were almost
1311 // inaudible, 11-20 did what should have been done
1312 // over the whole 0-20 range
1318 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1320 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1321 memset(&avol, 0, sizeof(avol));
1322 avol.nSize = sizeof(avol);
1323 avol.nVersion.nVersion = OMX_VERSION;
1324 avol.nPortIndex = omx_rend_input_port;
1325 avol.bLinear=OMX_FALSE;
1326 avol.sVolume.nValue =(volume-20)*200;
1327 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1329 if (error != OMX_ErrorNone) {
1330 Log::getInstance()->log("Audio", Log::DEBUG,
1331 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1332 omx_rend_input_port);
1342 int AudioOMX::test()
1345 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1347 /* aud_sync_parms_t a;
1351 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1354 /*OK*/ //printf("Audio sync disable = %i\n", b);
1362 unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1364 if (size<=2) return size; // silly;
1365 unsigned int test=0;
1367 while (test+1<size) {
1368 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1374 unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1376 if (size<=4) return size; // silly;
1377 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1378 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1379 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1380 1152, 1280, 1280, };
1381 unsigned int test=0;
1382 *framesize=20000; //if we do not find a start code do not decompress
1383 while (test+4<size) {
1384 if (data[test]==0x0B && data[test+1]==0x77) {
1385 // now figure out the length of the frame
1386 unsigned char code=data[test+4];
1387 unsigned char fscod=(code& 0xC0)>>6;
1388 unsigned char frmsize=(code &0x3f);
1389 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1390 *framesize=frm_size_tab[frmsize]*2;
1391 return test; // probably FrameSync
1399 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1401 packet = mplist.front();
1404 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1405 DeliverMediaPacket(packet, buffer, samplepos);
1406 if (*samplepos == packet.length) {
1414 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1416 VideoOMX *video = (VideoOMX*) Video::getInstance();
1418 OMX_PARAM_U32TYPE audio_lat;
1419 OMX_ERRORTYPE error;
1420 memset(&audio_lat, 0, sizeof(audio_lat));
1421 audio_lat.nSize = sizeof(audio_lat);
1422 audio_lat.nVersion.nVersion = OMX_VERSION;
1423 audio_lat.nPortIndex = omx_rend_input_port;
1425 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1427 video->UnlockClock();
1428 if (error != OMX_ErrorNone) {
1429 Log::getInstance()->log("Audio", Log::DEBUG,
1430 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1431 omx_rend_input_port);
1432 return pts; // no correction in case of error
1434 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1437 long long workpts=0;
1438 workpts+=addsamples;
1439 workpts-=audio_lat.nU32;
1440 workpts*=10LL*1000LL*1000LL;
1441 workpts=workpts/((long long)srate); //one second /samplerate
1449 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1451 /*First Check, if we have an audio sample*/
1452 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1454 OMX_ERRORTYPE error;
1455 Log *logger=Log::getInstance();
1456 if (vw->InIframemode()) {
1459 return 0; //Not in iframe mode!
1462 if (!omx_running) return 0; // if we are not runnig do not do this
1463 if (paused) return 0; //Block if we pause
1465 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1467 if (packet.synched && packet.presentation_time <= 0) {
1468 *samplepos = packet.length;
1469 firstsynched = false;
1470 Log::getInstance()->log("Audio", Log::DEBUG,
1471 "DeliverMediaPacketOMX Frameskip");
1472 return packet.length;
1477 UINT headerstrip = 0;
1478 if (packet.disconti) {
1479 firstsynched = false;
1480 decompress_buffer_filled=0;
1481 if (cur_input_buf_omx) {
1482 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1484 if (error != OMX_ErrorNone) {
1485 Log::getInstance()->log("Audio", Log::DEBUG,
1486 "OMX_EmptyThisBuffer 1 failed %x", error);
1488 cur_input_buf_omx = NULL;
1492 if (packet.type != lastAType) {//Format Change //Push data out !
1493 firstsynched = false;
1495 lastAType = packet.type;
1496 decompress_buffer_filled=0;
1498 if (cur_input_buf_omx) {
1499 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1501 if (error != OMX_ErrorNone) {
1502 Log::getInstance()->log("Audio", Log::DEBUG,
1503 "OMX_EmptyThisBuffer 2 failed %x", error);
1505 cur_input_buf_omx = NULL;
1508 if (!ChangeAudioPortConfig(true)) {
1509 Log::getInstance()->log("Audio", Log::DEBUG,
1510 "Changing audio port config failed", error);
1516 /*Inspect PES-Header */
1517 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1518 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1519 if (packet.type == MPTYPE_AC3)
1520 headerstrip += 4; //skip ac3 bytes
1521 *samplepos += headerstrip;
1522 if (packet.synched) {
1523 if (cur_input_buf_omx) {
1524 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1525 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1527 if (error != OMX_ErrorNone) {
1528 Log::getInstance()->log("Audio", Log::DEBUG,
1529 "OMX_EmptyThisBuffer 3 failed %x", error);
1531 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1533 cur_input_buf_omx = NULL;//write out old data
1535 firstsynched = true;
1536 //decompress_buffer_filled=0;
1538 if (!firstsynched) {//
1539 *samplepos = packet.length;//if we have not processed at least one
1540 decompress_buffer_filled=0;
1541 return packet.length;//synched packet ignore it!
1545 if (!cur_input_buf_omx) {
1546 input_bufs_omx_mutex.Lock();
1547 if (input_bufs_omx_free.size()==0) {
1548 input_bufs_omx_mutex.Unlock();
1549 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1550 return 0; // we do not have a free media sample
1553 cur_input_buf_omx=input_bufs_omx_free.front();
1554 cur_input_buf_omx->nFilledLen=0;
1555 cur_input_buf_omx->nOffset=0;
1556 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1557 input_bufs_omx_free.pop_front();
1558 input_bufs_omx_mutex.Unlock();
1561 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1562 if (packet.synched) {
1563 //Log::getInstance()->log("Audio", Log::DEBUG,
1564 // "packet synched marker");
1566 //lastreftimePTS=packet.pts;
1567 if (omx_first_frame) { // TODO time
1568 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1569 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1570 omx_first_frame = false;
1572 cur_input_buf_omx->nFlags = 0;
1573 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1575 lastreftimeOMX = packet.presentation_time;
1576 // Log::getInstance()->log("Audio", Log::DEBUG,
1577 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1578 lastreftimePTS = packet.pts;
1579 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1581 // Log::getInstance()->log("Audio", Log::DEBUG,
1582 // "packet NOT synched marker");
1583 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1584 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1587 if (packet.disconti || achange) {
1588 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1589 //mp23codec_context_libav->frame_size=-1;
1590 //ac3codec_context_libav->frame_size=-1;
1595 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1596 unsigned int haveToCopy=packet.length-*samplepos;
1605 AVCodecContext *current_context;
1606 switch (packet.type) {
1607 case MPTYPE_MPEG_AUDIO:
1608 case MPTYPE_MPEG_AUDIO_LAYER3: {
1609 current_context = mp23codec_context_libav;
1610 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1611 else framesize=current_context->frame_size;
1614 case MPTYPE_AC3_PRE13: {
1615 current_context = ac3codec_context_libav;
1619 if (decompress_buffer_filled) { // have a remaining paket
1620 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1621 memcpy(decompress_buffer+decompress_buffer_filled,
1622 buffer+packet.pos_buffer+*samplepos,
1623 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1624 incoming_paket_libav.size = decompress_buffer_filled
1625 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1626 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1628 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1629 incoming_paket_libav.size = haveToCopy;
1632 while (haveToCopy> 0 && errcount<3) {
1634 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1635 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1636 // framesize, current_context->frame_size);
1638 bool donotdecompress=false;
1639 unsigned int gotframesize=0;
1640 if (!decompress_buffer_filled) { // only do this if no old data is present
1642 switch (packet.type) {
1643 case MPTYPE_MPEG_AUDIO:
1644 case MPTYPE_MPEG_AUDIO_LAYER3: {
1645 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1646 incoming_paket_libav.size,&gotframesize);
1650 case MPTYPE_AC3_PRE13: {
1651 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1652 incoming_paket_libav.size,&gotframesize);
1657 incoming_paket_libav.data += adv;
1658 incoming_paket_libav.size-=adv;
1661 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1662 else*/ framesize=haveToCopy;
1663 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1664 if (haveToCopy <= 0) {
1665 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1666 *samplepos=packet.length;
1667 return packet.length;
1673 if (gotframesize>0 && gotframesize>haveToCopy) {
1674 donotdecompress=true;
1675 errcount=100; // exit loop
1677 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1680 if (!donotdecompress) {
1683 pthread_testcancel();
1684 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1685 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1687 if (!omx_running || !mp23codec_context_libav
1688 || !ac3codec_context_libav) {
1689 libav_mutex.Unlock();
1692 libav_mutex.Unlock();
1693 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1694 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1695 &gotta, &incoming_paket_libav);
1696 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1697 pthread_setcancelstate(oldcancelstate, NULL);
1698 pthread_setcanceltype(oldcanceltype, NULL);
1699 pthread_testcancel();
1705 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1707 libav_mutex.Unlock();
1711 if (decompress_buffer_filled) { // reset to normal decoding
1713 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1714 haveToCopy -= min(len-decompress_buffer_filled,0);
1715 *samplepos += min(len-decompress_buffer_filled,0);
1716 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1717 /*else*/ framesize=haveToCopy;
1719 framesize=haveToCopy;
1721 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1723 decompress_buffer_filled=0;
1727 incoming_paket_libav.data += len;
1731 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1732 else*/framesize=haveToCopy;
1735 framesize=haveToCopy;
1739 incoming_paket_libav.size =framesize;
1741 //Log::getInstance()->log("Audio", Log::DEBUG,
1743 int dsize = av_samples_get_buffer_size(NULL,
1744 current_context->channels, decode_frame_libav->nb_samples,
1745 current_context->sample_fmt, 1);
1746 if ((cur_input_buf_omx->nFilledLen + dsize)
1747 > cur_input_buf_omx->nAllocLen ) {
1748 // I doubt that this will ever happen
1749 // Log::getInstance()->log("Audio", Log::DEBUG,
1750 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1751 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1753 if (error != OMX_ErrorNone) {
1754 Log::getInstance()->log("Audio", Log::DEBUG,
1755 "OMX_EmptyThisBuffer 4 failed %x", error);
1757 cur_input_buf_omx = NULL;
1759 if (!cur_input_buf_omx) {
1761 while (count < 10 && omx_running) {
1763 input_bufs_omx_mutex.Lock();
1764 if (input_bufs_omx_free.size() == 0) {
1765 input_bufs_omx_mutex.Unlock();
1766 // Log::getInstance()->log("Audio", Log::DEBUG,
1767 // "Deliver MediaPacket no free sample");
1769 if (!omx_running) return *samplepos;
1772 cur_input_buf_omx = input_bufs_omx_free.front();
1773 cur_input_buf_omx->nFilledLen = 0;
1774 cur_input_buf_omx->nOffset = 0;
1775 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1776 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1777 input_bufs_omx_free.pop_front();
1778 input_bufs_omx_mutex.Unlock();
1781 if (!cur_input_buf_omx) return *samplepos;
1786 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1787 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1788 decode_frame_libav->data[0], dsize);
1789 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1790 cur_input_buf_omx->nFilledLen += dsize;
1792 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1793 /* uint8_t a1=incoming_paket_libav.data[0];
1794 uint8_t a2=incoming_paket_libav.data[1];
1795 uint8_t a3=incoming_paket_libav.data[2];
1796 uint8_t a4=incoming_paket_libav.data[3];*/
1797 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1804 decompress_buffer_filled=0;
1806 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);
1807 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1809 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1813 if (cur_input_buf_omx->nFilledLen) {
1814 //Log::getInstance()->log("Audio", Log::DEBUG,
1815 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1816 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1817 if (error != OMX_ErrorNone) {
1818 Log::getInstance()->log("Audio", Log::DEBUG,
1819 "OMX_EmptyThisBuffer 5 failed %x", error);
1821 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1822 cur_input_buf_omx = NULL;
1828 *samplepos=packet.length;
1829 return packet.length;
1835 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1836 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1837 return vw->SetStartAudioOffset(curreftime,rsync);
1840 void AudioOMX::ResetTimeOffsets() {
1841 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1842 vw->ResetTimeOffsets();