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);
588 //VideoOMX* video=(VideoOMX*)Video::getInstance();
591 if (!video->ChangeComponentState(omx_aud_rend, OMX_StateIdle)) {
592 Log::getInstance()->log("Audio", Log::DEBUG,
593 "omx_aud_rend ChangeComponentState Execute CAP");
596 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
597 DestroyInputBufsOMX();
602 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
603 memset(&audio_pcm, 0, sizeof(audio_pcm));
604 audio_pcm.nSize = sizeof(audio_pcm);
605 audio_pcm.nVersion.nVersion = OMX_VERSION;
606 audio_pcm.nChannels = 2;
607 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
608 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
609 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
610 audio_pcm.eNumData = OMX_NumericalDataSigned;
611 audio_pcm.eEndian = OMX_EndianLittle;
612 audio_pcm.bInterleaved = OMX_TRUE;
613 audio_pcm.nBitPerSample = 16;
614 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
615 audio_pcm.nChannels = 2;
616 audio_pcm.nSamplingRate = 48000;
617 audio_pcm.nPortIndex = omx_rend_input_port;
618 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
620 if (error != OMX_ErrorNone) {
621 Log::getInstance()->log("Audio", Log::DEBUG,
622 "Init OMX_IndexParamAudioPcm failed %x %d", error,
623 omx_rend_input_port);
627 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
628 PrepareInputBufsOMX();
629 if (!video->ChangeComponentState(omx_aud_rend, OMX_StateExecuting)) {
630 Log::getInstance()->log("Audio", Log::DEBUG,
631 "omx_aud_rend ChangeComponentState Execute CAP");
647 int AudioOMX::InitDecoderLibAV()
650 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
651 if (!ac3codec_context_libav) {
652 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
656 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
657 ac3codec_context_libav->request_channels=2;
659 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
661 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
662 libav_mutex.Unlock();
666 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
667 if (!ac3codec_context_libav) {
668 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
669 libav_mutex.Unlock();
673 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
674 mp23codec_context_libav->request_channels=2;
676 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
678 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
679 libav_mutex.Unlock();
683 av_init_packet(&incoming_paket_libav);
684 decode_frame_libav=avcodec_alloc_frame();
685 libav_mutex.Unlock();
686 decompress_buffer_filled=0;
693 void AudioOMX::DeinitDecoderLibAV() {
697 if (ac3codec_context_libav) {
698 avcodec_close(ac3codec_context_libav);
699 av_free(ac3codec_context_libav);
700 ac3codec_context_libav = NULL;
701 av_free(decode_frame_libav);
702 avcodec_close(mp23codec_context_libav);
703 av_free(mp23codec_context_libav);
704 mp23codec_context_libav = NULL;
707 libav_mutex.Unlock();
712 int AudioOMX::AllocateCodecsOMX()
715 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
717 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
718 //Clock, move later to audio
719 VideoOMX *video=(VideoOMX*)Video::getInstance();
721 if (!InitDecoderLibAV()) return 0;;
724 OMX_PORT_PARAM_TYPE p_param;
725 memset(&p_param,0,sizeof(p_param));
726 p_param.nSize=sizeof(p_param);
727 p_param.nVersion.nVersion=OMX_VERSION;
730 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
731 return 0;// get the clock and init it if necessary
735 if (!video->idleClock()) {
740 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
741 if (error != OMX_ErrorNone) {
742 Log::getInstance()->log("Audio", Log::DEBUG,
743 "Init OMX audio rend failed %x", error);
744 video->UnlockClock();
745 DeAllocateCodecsOMX();
749 if (!ChangeAudioDestination()) {
750 video->UnlockClock();
751 DeAllocateCodecsOMX();
755 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
756 if (error != OMX_ErrorNone) {
757 Log::getInstance()->log("Audio", Log::DEBUG,
758 "Init OMX audio rend OMX_GetParameter failed %x", error);
759 video->UnlockClock();
760 DeAllocateCodecsOMX();
763 omx_rend_input_port = p_param.nStartPortNumber;
765 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
766 if (error != OMX_ErrorNone) {
767 Log::getInstance()->log("Audio", Log::DEBUG,
768 "Init OMX aud rend OMX_GetParameter failed %x", error);
769 video->UnlockClock();
770 DeAllocateCodecsOMX();
773 // buggy return value
774 omx_rend_clock_port = p_param.nStartPortNumber;
777 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
779 if (error!=OMX_ErrorNone){
780 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
781 video->UnlockClock();
782 DeAllocateCodecsOMX();
786 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
787 if (error!=OMX_ErrorNone){
788 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
789 video->UnlockClock();
790 DeAllocateCodecsOMX();
793 omx_codec_input_port=p_param.nStartPortNumber;
794 omx_codec_output_port=p_param.nStartPortNumber+1;
796 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
797 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
798 video->UnlockClock();
799 DeAllocateCodecsOMX();
806 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
807 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
808 video->UnlockClock();
809 DeAllocateCodecsOMX();
813 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
814 Log::getInstance()->log("Audio", Log::DEBUG,
815 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
816 video->UnlockClock();
817 DeAllocateCodecsOMX();
827 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
828 if (error!=OMX_ErrorNone){
829 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);
830 video->UnlockClock();
831 DeAllocateCodecsOMX();
835 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
837 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
838 video->UnlockClock();
839 DeAllocateCodecsOMX();
843 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
844 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
845 video->UnlockClock();
846 DeAllocateCodecsOMX();
853 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
854 video->UnlockClock();
855 DeAllocateCodecsOMX();
859 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
860 video->UnlockClock();
861 DeAllocateCodecsOMX();
867 if (!ChangeAudioPortConfig(false)){
868 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
869 video->UnlockClock();
870 DeAllocateCodecsOMX();
874 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
875 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
876 DeAllocateCodecsOMX();
882 if (!PrepareInputBufsOMX()) {
883 video->UnlockClock();
884 DeAllocateCodecsOMX();
890 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
891 if (error!=OMX_ErrorNone){
892 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
893 video->UnlockClock();
894 DeAllocateCodecsOMX();
900 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
902 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
903 video->UnlockClock();
904 DeAllocateCodecsOMX();
908 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
909 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
910 video->UnlockClock();
911 DeAllocateCodecsOMX();
915 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
916 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
917 video->UnlockClock();
918 DeAllocateCodecsOMX();
923 video->UnlockClock();
929 if (!video->setClockExecutingandRunning()) return 0;
931 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
939 int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock mutex
941 VideoOMX *video=(VideoOMX*)Video::getInstance();
943 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
944 memset(&port_def_type,0,sizeof(port_def_type));
945 port_def_type.nSize=sizeof(port_def_type);
946 port_def_type.nVersion.nVersion=OMX_VERSION;
947 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
949 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
951 if (error!=OMX_ErrorNone){
952 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
956 port_def_type.nBufferCountActual=2;
957 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
959 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
961 if (error!=OMX_ErrorNone){
962 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
966 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
967 if (error!=OMX_ErrorNone){
968 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
972 input_bufs_omx_mutex.Lock();
973 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
974 OMX_BUFFERHEADERTYPE *buf_head=NULL;
975 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
976 if (error!=OMX_ErrorNone){
977 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
978 input_bufs_omx_mutex.Unlock();
981 input_bufs_omx_all.push_back(buf_head);
982 input_bufs_omx_free.push_back(buf_head);
984 omx_first_frame=true;
987 cur_input_buf_omx=NULL;
988 input_bufs_omx_mutex.Unlock();
990 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
997 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
1001 cur_input_buf_omx=NULL;
1002 input_bufs_omx_mutex.Lock();
1003 for (int i=0; i< input_bufs_omx_all.size();i++) {
1004 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
1005 if (error!=OMX_ErrorNone){
1006 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1007 input_bufs_omx_mutex.Unlock();
1012 input_bufs_omx_all.clear();
1013 input_bufs_omx_free.clear();
1014 input_bufs_omx_mutex.Unlock();
1019 int AudioOMX::DeAllocateCodecsOMX()
1021 OMX_ERRORTYPE error;
1023 VideoOMX *video=(VideoOMX*)Video::getInstance();
1024 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
1028 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
1029 if (cur_input_buf_omx) {
1030 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1031 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
1032 if (error!=OMX_ErrorNone) {
1033 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
1036 cur_input_buf_omx=NULL;//write out old data
1038 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1041 if (omx_aud_rend/*dec*/) {
1042 // first stop the omx elements
1043 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1044 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1046 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1048 video->UnlockClock();
1049 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1051 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1054 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1055 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1058 // TODO proper deinit sequence
1059 // first flush all buffers
1061 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1062 if (error!=OMX_ErrorNone) {
1063 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1067 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1068 if (error!=OMX_ErrorNone){
1069 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1074 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1075 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1080 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1081 if (error!=OMX_ErrorNone){
1082 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1086 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1087 if (error!=OMX_ErrorNone){
1088 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1091 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1093 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1094 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1095 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1098 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1099 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1100 DeinitDecoderLibAV();
1101 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1104 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1105 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1108 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1109 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1112 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1113 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1117 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1118 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1121 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1122 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1127 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1128 if (error!=OMX_ErrorNone) {
1129 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1135 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1136 if (error!=OMX_ErrorNone) {
1137 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1141 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1142 if (error!=OMX_ErrorNone) {
1143 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1147 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1148 if (error!=OMX_ErrorNone) {
1149 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1152 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1155 //error=OMX_FreeHandle(omx_aud_dec);
1156 error=OMX_FreeHandle(omx_aud_rend);
1157 video->UnlockClock();
1158 video->destroyClock();
1159 omx_aud_rend/*dec*/=NULL;
1160 if (error!=OMX_ErrorNone) {
1161 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1165 video->UnlockClock();
1166 DeinitDecoderLibAV();
1168 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1175 int AudioOMX::stop()
1177 if (!initted) return 0;
1179 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1180 DeAllocateCodecsOMX();
1181 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1185 int AudioOMX::mute() {
1188 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1190 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1192 OMX_AUDIO_CONFIG_MUTETYPE amute;
1193 memset(&amute, 0, sizeof(amute));
1194 amute.nSize = sizeof(amute);
1195 amute.nVersion.nVersion = OMX_VERSION;
1196 amute.nPortIndex = omx_rend_input_port;
1197 amute.bMute = OMX_TRUE;
1198 OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1200 if (error != OMX_ErrorNone) {
1201 Log::getInstance()->log("Audio", Log::DEBUG,
1202 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1203 omx_rend_input_port);
1213 int AudioOMX::unMute()
1215 if (!initted) return 0;
1217 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1219 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1221 OMX_AUDIO_CONFIG_MUTETYPE amute;
1222 memset(&amute, 0, sizeof(amute));
1223 amute.nSize = sizeof(amute);
1224 amute.nVersion.nVersion = OMX_VERSION;
1225 amute.nPortIndex = omx_rend_input_port;
1226 amute.bMute = OMX_FALSE;
1227 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute,
1229 if (error != OMX_ErrorNone) {
1230 Log::getInstance()->log("Audio", Log::DEBUG,
1231 "Set OMX_IndexConfigAudioMute failed %x %d", error,
1232 omx_rend_input_port);
1242 int AudioOMX::pause() {
1247 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1250 OMX_ERRORTYPE error;
1251 error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1252 omx_rend_input_port, NULL);
1253 if (error != OMX_ErrorNone) {
1254 Log::getInstance()->log("Audio", Log::DEBUG,
1255 "OMX_Flush rend in failed %x", error);
1258 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1259 Log::getInstance()->log("Audio", Log::DEBUG, " pause aud_rend idle ChangeComponentState");
1268 int AudioOMX::unPause()
1270 if (!initted) return 0;
1272 paused=false; // may be also change omx clock
1273 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1275 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1276 Log::getInstance()->log("Audio", Log::DEBUG, " unpause aud_rend idle ChangeComponentState");
1284 int AudioOMX::reset()
1286 if (!initted) return 0;
1288 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1289 DeAllocateCodecsOMX();
1291 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1292 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1293 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1299 int AudioOMX::setVolume(int tvolume)
1301 // parameter: 0 for silence, 20 for full
1302 if ((tvolume < 0) || (tvolume > 20)) return 0;
1304 // volume = 2 * (20 - volume);
1305 // Right, that one was rubbish... 0-10 were almost
1306 // inaudible, 11-20 did what should have been done
1307 // over the whole 0-20 range
1313 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1315 OMX_AUDIO_CONFIG_VOLUMETYPE avol;
1316 memset(&avol, 0, sizeof(avol));
1317 avol.nSize = sizeof(avol);
1318 avol.nVersion.nVersion = OMX_VERSION;
1319 avol.nPortIndex = omx_rend_input_port;
1320 avol.bLinear=OMX_FALSE;
1321 avol.sVolume.nValue =(volume-20)*200;
1322 OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume,
1324 if (error != OMX_ErrorNone) {
1325 Log::getInstance()->log("Audio", Log::DEBUG,
1326 "Set OMX_IndexConfigAudioVolume failed %x %d", error,
1327 omx_rend_input_port);
1337 int AudioOMX::test()
1340 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1342 /* aud_sync_parms_t a;
1346 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1349 /*OK*/ //printf("Audio sync disable = %i\n", b);
1357 unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1359 if (size<=2) return size; // silly;
1360 unsigned int test=0;
1362 while (test+1<size) {
1363 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1369 unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1371 if (size<=4) return size; // silly;
1372 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1373 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1374 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1375 1152, 1280, 1280, };
1376 unsigned int test=0;
1377 *framesize=20000; //if we do not find a start code do not decompress
1378 while (test+4<size) {
1379 if (data[test]==0x0B && data[test+1]==0x77) {
1380 // now figure out the length of the frame
1381 unsigned char code=data[test+4];
1382 unsigned char fscod=(code& 0xC0)>>6;
1383 unsigned char frmsize=(code &0x3f);
1384 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1385 *framesize=frm_size_tab[frmsize]*2;
1386 return test; // probably FrameSync
1394 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1396 packet = mplist.front();
1399 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1400 DeliverMediaPacket(packet, buffer, samplepos);
1401 if (*samplepos == packet.length) {
1409 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1411 VideoOMX *video = (VideoOMX*) Video::getInstance();
1413 OMX_PARAM_U32TYPE audio_lat;
1414 OMX_ERRORTYPE error;
1415 memset(&audio_lat, 0, sizeof(audio_lat));
1416 audio_lat.nSize = sizeof(audio_lat);
1417 audio_lat.nVersion.nVersion = OMX_VERSION;
1418 audio_lat.nPortIndex = omx_rend_input_port;
1420 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1422 video->UnlockClock();
1423 if (error != OMX_ErrorNone) {
1424 Log::getInstance()->log("Audio", Log::DEBUG,
1425 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1426 omx_rend_input_port);
1427 return pts; // no correction in case of error
1429 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1432 long long workpts=0;
1433 workpts+=addsamples;
1434 workpts-=audio_lat.nU32;
1435 workpts*=10LL*1000LL*1000LL;
1436 workpts=workpts/((long long)srate); //one second /samplerate
1444 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1446 /*First Check, if we have an audio sample*/
1447 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1449 OMX_ERRORTYPE error;
1450 Log *logger=Log::getInstance();
1451 if (vw->InIframemode()) {
1454 return 0; //Not in iframe mode!
1457 if (!omx_running) return 0; // if we are not runnig do not do this
1458 if (paused) return 0; //Block if we pause
1460 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1462 if (packet.synched && packet.presentation_time <= 0) {
1463 *samplepos = packet.length;
1464 firstsynched = false;
1465 Log::getInstance()->log("Audio", Log::DEBUG,
1466 "DeliverMediaPacketOMX Frameskip");
1467 return packet.length;
1472 UINT headerstrip = 0;
1473 if (packet.disconti) {
1474 firstsynched = false;
1475 decompress_buffer_filled=0;
1476 if (cur_input_buf_omx) {
1477 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1479 if (error != OMX_ErrorNone) {
1480 Log::getInstance()->log("Audio", Log::DEBUG,
1481 "OMX_EmptyThisBuffer 1 failed %x", error);
1483 cur_input_buf_omx = NULL;
1487 if (packet.type != lastAType) {//Format Change //Push data out !
1488 firstsynched = false;
1490 lastAType = packet.type;
1491 decompress_buffer_filled=0;
1493 if (cur_input_buf_omx) {
1494 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1496 if (error != OMX_ErrorNone) {
1497 Log::getInstance()->log("Audio", Log::DEBUG,
1498 "OMX_EmptyThisBuffer 2 failed %x", error);
1500 cur_input_buf_omx = NULL;
1503 if (!ChangeAudioPortConfig(true)) {
1504 Log::getInstance()->log("Audio", Log::DEBUG,
1505 "Changing audio port config failed", error);
1511 /*Inspect PES-Header */
1512 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1513 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1514 if (packet.type == MPTYPE_AC3)
1515 headerstrip += 4; //skip ac3 bytes
1516 *samplepos += headerstrip;
1517 if (packet.synched) {
1518 if (cur_input_buf_omx) {
1519 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1520 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1522 if (error != OMX_ErrorNone) {
1523 Log::getInstance()->log("Audio", Log::DEBUG,
1524 "OMX_EmptyThisBuffer 3 failed %x", error);
1526 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1528 cur_input_buf_omx = NULL;//write out old data
1530 firstsynched = true;
1531 //decompress_buffer_filled=0;
1533 if (!firstsynched) {//
1534 *samplepos = packet.length;//if we have not processed at least one
1535 decompress_buffer_filled=0;
1536 return packet.length;//synched packet ignore it!
1540 if (!cur_input_buf_omx) {
1541 input_bufs_omx_mutex.Lock();
1542 if (input_bufs_omx_free.size()==0) {
1543 input_bufs_omx_mutex.Unlock();
1544 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1545 return 0; // we do not have a free media sample
1548 cur_input_buf_omx=input_bufs_omx_free.front();
1549 cur_input_buf_omx->nFilledLen=0;
1550 cur_input_buf_omx->nOffset=0;
1551 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1552 input_bufs_omx_free.pop_front();
1553 input_bufs_omx_mutex.Unlock();
1556 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1557 if (packet.synched) {
1558 //Log::getInstance()->log("Audio", Log::DEBUG,
1559 // "packet synched marker");
1561 //lastreftimePTS=packet.pts;
1562 if (omx_first_frame) { // TODO time
1563 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1564 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1565 omx_first_frame = false;
1567 cur_input_buf_omx->nFlags = 0;
1568 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1570 lastreftimeOMX = packet.presentation_time;
1571 // Log::getInstance()->log("Audio", Log::DEBUG,
1572 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1573 lastreftimePTS = packet.pts;
1574 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1576 // Log::getInstance()->log("Audio", Log::DEBUG,
1577 // "packet NOT synched marker");
1578 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1579 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1582 if (packet.disconti || achange) {
1583 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1584 //mp23codec_context_libav->frame_size=-1;
1585 //ac3codec_context_libav->frame_size=-1;
1590 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1591 unsigned int haveToCopy=packet.length-*samplepos;
1600 AVCodecContext *current_context;
1601 switch (packet.type) {
1602 case MPTYPE_MPEG_AUDIO:
1603 case MPTYPE_MPEG_AUDIO_LAYER3: {
1604 current_context = mp23codec_context_libav;
1605 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1606 else framesize=current_context->frame_size;
1609 case MPTYPE_AC3_PRE13: {
1610 current_context = ac3codec_context_libav;
1614 if (decompress_buffer_filled) { // have a remaining paket
1615 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1616 memcpy(decompress_buffer+decompress_buffer_filled,
1617 buffer+packet.pos_buffer+*samplepos,
1618 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1619 incoming_paket_libav.size = decompress_buffer_filled
1620 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1621 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1623 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1624 incoming_paket_libav.size = haveToCopy;
1627 while (haveToCopy> 0 && errcount<3) {
1629 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1630 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1631 // framesize, current_context->frame_size);
1633 bool donotdecompress=false;
1634 unsigned int gotframesize=0;
1635 if (!decompress_buffer_filled) { // only do this if no old data is present
1637 switch (packet.type) {
1638 case MPTYPE_MPEG_AUDIO:
1639 case MPTYPE_MPEG_AUDIO_LAYER3: {
1640 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1641 incoming_paket_libav.size,&gotframesize);
1645 case MPTYPE_AC3_PRE13: {
1646 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1647 incoming_paket_libav.size,&gotframesize);
1652 incoming_paket_libav.data += adv;
1653 incoming_paket_libav.size-=adv;
1656 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1657 else*/ framesize=haveToCopy;
1658 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1659 if (haveToCopy <= 0) {
1660 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1661 *samplepos=packet.length;
1662 return packet.length;
1668 if (gotframesize>0 && gotframesize>haveToCopy) {
1669 donotdecompress=true;
1670 errcount=100; // exit loop
1672 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1675 if (!donotdecompress) {
1678 pthread_testcancel();
1679 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1680 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1682 if (!omx_running || !mp23codec_context_libav
1683 || !ac3codec_context_libav) {
1684 libav_mutex.Unlock();
1687 libav_mutex.Unlock();
1688 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1689 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1690 &gotta, &incoming_paket_libav);
1691 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1692 pthread_setcancelstate(oldcancelstate, NULL);
1693 pthread_setcanceltype(oldcanceltype, NULL);
1694 pthread_testcancel();
1700 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1702 libav_mutex.Unlock();
1706 if (decompress_buffer_filled) { // reset to normal decoding
1708 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1709 haveToCopy -= min(len-decompress_buffer_filled,0);
1710 *samplepos += min(len-decompress_buffer_filled,0);
1711 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1712 /*else*/ framesize=haveToCopy;
1714 framesize=haveToCopy;
1716 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1718 decompress_buffer_filled=0;
1722 incoming_paket_libav.data += len;
1726 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1727 else*/framesize=haveToCopy;
1730 framesize=haveToCopy;
1734 incoming_paket_libav.size =framesize;
1736 //Log::getInstance()->log("Audio", Log::DEBUG,
1738 int dsize = av_samples_get_buffer_size(NULL,
1739 current_context->channels, decode_frame_libav->nb_samples,
1740 current_context->sample_fmt, 1);
1741 if ((cur_input_buf_omx->nFilledLen + dsize)
1742 > cur_input_buf_omx->nAllocLen ) {
1743 // I doubt that this will ever happen
1744 // Log::getInstance()->log("Audio", Log::DEBUG,
1745 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1746 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1748 if (error != OMX_ErrorNone) {
1749 Log::getInstance()->log("Audio", Log::DEBUG,
1750 "OMX_EmptyThisBuffer 4 failed %x", error);
1752 cur_input_buf_omx = NULL;
1754 if (!cur_input_buf_omx) {
1756 while (count < 10 && omx_running) {
1758 input_bufs_omx_mutex.Lock();
1759 if (input_bufs_omx_free.size() == 0) {
1760 input_bufs_omx_mutex.Unlock();
1761 // Log::getInstance()->log("Audio", Log::DEBUG,
1762 // "Deliver MediaPacket no free sample");
1764 if (!omx_running) return *samplepos;
1767 cur_input_buf_omx = input_bufs_omx_free.front();
1768 cur_input_buf_omx->nFilledLen = 0;
1769 cur_input_buf_omx->nOffset = 0;
1770 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1771 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1772 input_bufs_omx_free.pop_front();
1773 input_bufs_omx_mutex.Unlock();
1776 if (!cur_input_buf_omx) return *samplepos;
1781 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1782 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1783 decode_frame_libav->data[0], dsize);
1784 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1785 cur_input_buf_omx->nFilledLen += dsize;
1787 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1788 /* uint8_t a1=incoming_paket_libav.data[0];
1789 uint8_t a2=incoming_paket_libav.data[1];
1790 uint8_t a3=incoming_paket_libav.data[2];
1791 uint8_t a4=incoming_paket_libav.data[3];*/
1792 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1799 decompress_buffer_filled=0;
1801 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);
1802 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1804 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1808 if (cur_input_buf_omx->nFilledLen) {
1809 //Log::getInstance()->log("Audio", Log::DEBUG,
1810 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1811 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1812 if (error != OMX_ErrorNone) {
1813 Log::getInstance()->log("Audio", Log::DEBUG,
1814 "OMX_EmptyThisBuffer 5 failed %x", error);
1816 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1817 cur_input_buf_omx = NULL;
1823 *samplepos=packet.length;
1824 return packet.length;
1830 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1831 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1832 return vw->SetStartAudioOffset(curreftime,rsync);
1835 void AudioOMX::ResetTimeOffsets() {
1836 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1837 vw->ResetTimeOffsets();