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");
486 case MPTYPE_MPEG_AUDIO: {
487 if (prefered_mp2 == 3 && false) { //not supported yet
490 if (prefered_mp2 == 2 && canpass_mp2) {
497 case MPTYPE_AC3_PRE13:
499 if (prefered_ac3 == 3 && false) { //not supported yet
502 if (prefered_ac3 == 2 && canpass_ac3) {
509 case MPTYPE_MPEG_AUDIO_LAYER3: {
510 if (prefered_mp3 == 3 && false) { //not supported yet
513 if (prefered_mp3 == 2 && canpass_mp2) {
523 //mch=false; // multichannel also false
528 /*OMX_CONFIG_BOOLEANTYPE booly;
529 memset(&booly, 0, sizeof(booly));
530 booly.nSize = sizeof(booly);
531 booly.nVersion.nVersion = OMX_VERSION;
533 booly.bEnabled = OMX_TRUE;
535 booly.bEnabled = OMX_FALSE;
537 error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
539 if (error != OMX_ErrorNone) {
540 Log::getInstance()->log("Audio", Log::DEBUG,
541 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
542 DeAllocateCodecsOMX();
552 //VideoOMX* video=(VideoOMX*)Video::getInstance();
555 if (!video->ChangeComponentState(omx_aud_rend, OMX_StateIdle)) {
556 Log::getInstance()->log("Audio", Log::DEBUG,
557 "omx_aud_rend ChangeComponentState Execute CAP");
560 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
561 DestroyInputBufsOMX();
563 OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
564 memset(&audio_pcm, 0, sizeof(audio_pcm));
565 audio_pcm.nSize = sizeof(audio_pcm);
566 audio_pcm.nVersion.nVersion = OMX_VERSION;
567 audio_pcm.nChannels = 2;
568 audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
569 audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
570 //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
571 audio_pcm.eNumData = OMX_NumericalDataSigned;
572 audio_pcm.eEndian = OMX_EndianLittle;
573 audio_pcm.bInterleaved = OMX_TRUE;
574 audio_pcm.nBitPerSample = 16;
575 audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
576 audio_pcm.nChannels = 2;
577 audio_pcm.nSamplingRate = 48000;
578 audio_pcm.nPortIndex = omx_rend_input_port;
579 error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
581 if (error != OMX_ErrorNone) {
582 Log::getInstance()->log("Audio", Log::DEBUG,
583 "Init OMX_IndexParamAudioPcm failed %x %d", error,
584 omx_rend_input_port);
585 //DeAllocateCodecsOMX();
589 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
590 PrepareInputBufsOMX();
591 if (!video->ChangeComponentState(omx_aud_rend, OMX_StateExecuting)) {
592 Log::getInstance()->log("Audio", Log::DEBUG,
593 "omx_aud_rend ChangeComponentState Execute CAP");
609 int AudioOMX::InitDecoderLibAV()
612 ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
613 if (!ac3codec_context_libav) {
614 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
618 ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
619 ac3codec_context_libav->request_channels=2;
621 int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
623 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
624 libav_mutex.Unlock();
628 mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
629 if (!ac3codec_context_libav) {
630 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
631 libav_mutex.Unlock();
635 mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
636 mp23codec_context_libav->request_channels=2;
638 avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
640 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
641 libav_mutex.Unlock();
645 av_init_packet(&incoming_paket_libav);
646 decode_frame_libav=avcodec_alloc_frame();
647 libav_mutex.Unlock();
648 decompress_buffer_filled=0;
655 void AudioOMX::DeinitDecoderLibAV() {
659 if (ac3codec_context_libav) {
660 avcodec_close(ac3codec_context_libav);
661 av_free(ac3codec_context_libav);
662 ac3codec_context_libav = NULL;
663 av_free(decode_frame_libav);
664 avcodec_close(mp23codec_context_libav);
665 av_free(mp23codec_context_libav);
666 mp23codec_context_libav = NULL;
669 libav_mutex.Unlock();
674 int AudioOMX::AllocateCodecsOMX()
677 static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
679 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
680 //Clock, move later to audio
681 VideoOMX *video=(VideoOMX*)Video::getInstance();
683 if (!InitDecoderLibAV()) return 0;;
686 OMX_PORT_PARAM_TYPE p_param;
687 memset(&p_param,0,sizeof(p_param));
688 p_param.nSize=sizeof(p_param);
689 p_param.nVersion.nVersion=OMX_VERSION;
692 if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
693 return 0;// get the clock and init it if necessary
697 if (!video->idleClock()) {
702 error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
703 if (error != OMX_ErrorNone) {
704 Log::getInstance()->log("Audio", Log::DEBUG,
705 "Init OMX audio rend failed %x", error);
706 video->UnlockClock();
707 DeAllocateCodecsOMX();
711 if (!ChangeAudioDestination()) {
712 video->UnlockClock();
713 DeAllocateCodecsOMX();
717 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
718 if (error != OMX_ErrorNone) {
719 Log::getInstance()->log("Audio", Log::DEBUG,
720 "Init OMX audio rend OMX_GetParameter failed %x", error);
721 video->UnlockClock();
722 DeAllocateCodecsOMX();
725 omx_rend_input_port = p_param.nStartPortNumber;
727 error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
728 if (error != OMX_ErrorNone) {
729 Log::getInstance()->log("Audio", Log::DEBUG,
730 "Init OMX aud rend OMX_GetParameter failed %x", error);
731 video->UnlockClock();
732 DeAllocateCodecsOMX();
735 // buggy return value
736 omx_rend_clock_port = p_param.nStartPortNumber;
739 /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
741 if (error!=OMX_ErrorNone){
742 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
743 video->UnlockClock();
744 DeAllocateCodecsOMX();
748 error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
749 if (error!=OMX_ErrorNone){
750 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
751 video->UnlockClock();
752 DeAllocateCodecsOMX();
755 omx_codec_input_port=p_param.nStartPortNumber;
756 omx_codec_output_port=p_param.nStartPortNumber+1;
758 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
759 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
760 video->UnlockClock();
761 DeAllocateCodecsOMX();
768 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
769 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
770 video->UnlockClock();
771 DeAllocateCodecsOMX();
775 if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
776 Log::getInstance()->log("Audio", Log::DEBUG,
777 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
778 video->UnlockClock();
779 DeAllocateCodecsOMX();
789 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
790 if (error!=OMX_ErrorNone){
791 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);
792 video->UnlockClock();
793 DeAllocateCodecsOMX();
797 if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
799 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
800 video->UnlockClock();
801 DeAllocateCodecsOMX();
805 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
806 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
807 video->UnlockClock();
808 DeAllocateCodecsOMX();
815 if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
816 video->UnlockClock();
817 DeAllocateCodecsOMX();
821 if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
822 video->UnlockClock();
823 DeAllocateCodecsOMX();
829 if (!ChangeAudioPortConfig(false)){
830 Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
831 video->UnlockClock();
832 DeAllocateCodecsOMX();
836 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
837 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
838 DeAllocateCodecsOMX();
844 if (!PrepareInputBufsOMX()) {
845 video->UnlockClock();
846 DeAllocateCodecsOMX();
852 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
853 if (error!=OMX_ErrorNone){
854 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
855 video->UnlockClock();
856 DeAllocateCodecsOMX();
862 /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
864 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
865 video->UnlockClock();
866 DeAllocateCodecsOMX();
870 /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
871 || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
872 video->UnlockClock();
873 DeAllocateCodecsOMX();
877 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
878 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
879 video->UnlockClock();
880 DeAllocateCodecsOMX();
885 video->UnlockClock();
890 if (!video->setClockExecutingandRunning()) return 0;
892 Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
900 int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock mutex
902 VideoOMX *video=(VideoOMX*)Video::getInstance();
904 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
905 memset(&port_def_type,0,sizeof(port_def_type));
906 port_def_type.nSize=sizeof(port_def_type);
907 port_def_type.nVersion.nVersion=OMX_VERSION;
908 port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
910 error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
912 if (error!=OMX_ErrorNone){
913 Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
917 port_def_type.nBufferCountActual=2;
918 port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
920 error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
922 if (error!=OMX_ErrorNone){
923 Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
927 error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
928 if (error!=OMX_ErrorNone){
929 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
933 input_bufs_omx_mutex.Lock();
934 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
935 OMX_BUFFERHEADERTYPE *buf_head=NULL;
936 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
937 if (error!=OMX_ErrorNone){
938 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
939 input_bufs_omx_mutex.Unlock();
942 input_bufs_omx_all.push_back(buf_head);
943 input_bufs_omx_free.push_back(buf_head);
945 omx_first_frame=true;
948 cur_input_buf_omx=NULL;
949 input_bufs_omx_mutex.Unlock();
951 if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
958 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
962 cur_input_buf_omx=NULL;
963 input_bufs_omx_mutex.Lock();
964 for (int i=0; i< input_bufs_omx_all.size();i++) {
965 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
966 if (error!=OMX_ErrorNone){
967 Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
968 input_bufs_omx_mutex.Unlock();
973 input_bufs_omx_all.clear();
974 input_bufs_omx_free.clear();
975 input_bufs_omx_mutex.Unlock();
980 int AudioOMX::DeAllocateCodecsOMX()
984 VideoOMX *video=(VideoOMX*)Video::getInstance();
985 Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
989 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
990 if (cur_input_buf_omx) {
991 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
992 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
993 if (error!=OMX_ErrorNone) {
994 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
997 cur_input_buf_omx=NULL;//write out old data
999 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1002 if (omx_aud_rend/*dec*/) {
1003 // first stop the omx elements
1004 /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1005 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1007 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1009 video->UnlockClock();
1010 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1012 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1015 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1016 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1019 // TODO proper deinit sequence
1020 // first flush all buffers
1022 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1023 if (error!=OMX_ErrorNone) {
1024 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1028 /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1029 if (error!=OMX_ErrorNone){
1030 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1035 /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1036 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1041 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1042 if (error!=OMX_ErrorNone){
1043 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1047 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1048 if (error!=OMX_ErrorNone){
1049 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1052 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1054 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1055 !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1056 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1059 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1060 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1061 DeinitDecoderLibAV();
1062 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1065 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1066 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1069 /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1070 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1073 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1074 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1078 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1079 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1082 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1083 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1088 /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1089 if (error!=OMX_ErrorNone) {
1090 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1096 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1097 if (error!=OMX_ErrorNone) {
1098 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1102 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1103 if (error!=OMX_ErrorNone) {
1104 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1108 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1109 if (error!=OMX_ErrorNone) {
1110 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1113 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1116 //error=OMX_FreeHandle(omx_aud_dec);
1117 error=OMX_FreeHandle(omx_aud_rend);
1118 video->UnlockClock();
1119 video->destroyClock();
1120 omx_aud_rend/*dec*/=NULL;
1121 if (error!=OMX_ErrorNone) {
1122 Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1126 video->UnlockClock();
1127 DeinitDecoderLibAV();
1129 Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1136 int AudioOMX::stop()
1138 if (!initted) return 0;
1140 Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1141 DeAllocateCodecsOMX();
1142 //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1146 int AudioOMX::mute()
1148 if (!initted) return 0;
1150 // if (ioctl(fdAudio, AV_SET_AUD_MUTE, 1) != 0) return 0;
1151 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1157 int AudioOMX::unMute()
1159 if (!initted) return 0;
1161 // if (ioctl(fdAudio, AV_SET_AUD_MUTE, 0) != 0) return 0;
1162 Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1168 int AudioOMX::pause() {
1173 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1176 OMX_ERRORTYPE error;
1177 error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1178 omx_rend_input_port, NULL);
1179 if (error != OMX_ErrorNone) {
1180 Log::getInstance()->log("Audio", Log::DEBUG,
1181 "OMX_Flush rend in failed %x", error);
1191 int AudioOMX::unPause()
1193 if (!initted) return 0;
1195 paused=false; // may be also change omx clock
1196 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1202 int AudioOMX::reset()
1204 if (!initted) return 0;
1206 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1207 DeAllocateCodecsOMX();
1209 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1210 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1211 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1217 int AudioOMX::setVolume(int tvolume)
1219 // parameter: 0 for silence, 20 for full
1220 if ((tvolume < 0) || (tvolume > 20)) return 0;
1222 // volume = 2 * (20 - volume);
1223 // Right, that one was rubbish... 0-10 were almost
1224 // inaudible, 11-20 did what should have been done
1225 // over the whole 0-20 range
1227 tvolume = 20 - tvolume;
1229 audio_volume Avolume;
1230 Avolume.frontleft = tvolume + Aoffset.frontleft;
1231 Avolume.frontright = tvolume + Aoffset.frontright;
1232 Avolume.rearleft = tvolume + Aoffset.rearleft;
1233 Avolume.rearright = tvolume + Aoffset.rearright;
1234 Avolume.center = tvolume + Aoffset.center;
1235 Avolume.lfe = tvolume + Aoffset.lfe;
1237 // if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &Avolume) != 0) return 0;
1239 // unsigned long vol = (tvolume << 24) | (tvolume << 16);
1241 // Log::getInstance()->log("Audio", Log::DEBUG, "%lx", vol);
1242 // Log::getInstance()->log("Audio", Log::DEBUG, "%i", tvolume);
1244 // if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &vol) != 0) return 0;
1249 int AudioOMX::test()
1252 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1254 /* aud_sync_parms_t a;
1258 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1261 /*OK*/ //printf("Audio sync disable = %i\n", b);
1269 unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1271 if (size<=2) return size; // silly;
1272 unsigned int test=0;
1274 while (test+1<size) {
1275 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1281 unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1283 if (size<=4) return size; // silly;
1284 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1285 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1286 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1287 1152, 1280, 1280, };
1288 unsigned int test=0;
1289 *framesize=20000; //if we do not find a start code do not decompress
1290 while (test+4<size) {
1291 if (data[test]==0x0B && data[test+1]==0x77) {
1292 // now figure out the length of the frame
1293 unsigned char code=data[test+4];
1294 unsigned char fscod=(code& 0xC0)>>6;
1295 unsigned char frmsize=(code &0x3f);
1296 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1297 *framesize=frm_size_tab[frmsize]*2;
1298 return test; // probably FrameSync
1306 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1308 packet = mplist.front();
1311 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1312 DeliverMediaPacket(packet, buffer, samplepos);
1313 if (*samplepos == packet.length) {
1321 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1323 VideoOMX *video = (VideoOMX*) Video::getInstance();
1325 OMX_PARAM_U32TYPE audio_lat;
1326 OMX_ERRORTYPE error;
1327 memset(&audio_lat, 0, sizeof(audio_lat));
1328 audio_lat.nSize = sizeof(audio_lat);
1329 audio_lat.nVersion.nVersion = OMX_VERSION;
1330 audio_lat.nPortIndex = omx_rend_input_port;
1332 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1334 video->UnlockClock();
1335 if (error != OMX_ErrorNone) {
1336 Log::getInstance()->log("Audio", Log::DEBUG,
1337 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1338 omx_rend_input_port);
1339 return pts; // no correction in case of error
1341 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1344 long long workpts=0;
1345 workpts+=addsamples;
1346 workpts-=audio_lat.nU32;
1347 workpts*=10LL*1000LL*1000LL;
1348 workpts=workpts/((long long)srate); //one second /samplerate
1356 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1358 /*First Check, if we have an audio sample*/
1359 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1361 OMX_ERRORTYPE error;
1362 Log *logger=Log::getInstance();
1363 if (vw->InIframemode()) {
1366 return 0; //Not in iframe mode!
1369 if (!omx_running) return 0; // if we are not runnig do not do this
1370 if (paused) return 0; //Block if we pause
1372 UINT headerstrip = 0;
1373 if (packet.disconti) {
1374 firstsynched = false;
1375 decompress_buffer_filled=0;
1376 if (cur_input_buf_omx) {
1377 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1379 if (error != OMX_ErrorNone) {
1380 Log::getInstance()->log("Audio", Log::DEBUG,
1381 "OMX_EmptyThisBuffer 1 failed %x", error);
1383 cur_input_buf_omx = NULL;
1387 if (packet.type != lastAType) {//Format Change //Push data out !
1388 firstsynched = false;
1390 lastAType = packet.type;
1391 decompress_buffer_filled=0;
1393 if (cur_input_buf_omx) {
1394 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1396 if (error != OMX_ErrorNone) {
1397 Log::getInstance()->log("Audio", Log::DEBUG,
1398 "OMX_EmptyThisBuffer 2 failed %x", error);
1400 cur_input_buf_omx = NULL;
1403 if (!ChangeAudioPortConfig(true)) {
1404 Log::getInstance()->log("Audio", Log::DEBUG,
1405 "Changing audio port config failed", error);
1411 /*Inspect PES-Header */
1412 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1413 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1414 if (packet.type == MPTYPE_AC3)
1415 headerstrip += 4; //skip ac3 bytes
1416 *samplepos += headerstrip;
1417 if (packet.synched) {
1418 if (cur_input_buf_omx) {
1419 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1420 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1422 if (error != OMX_ErrorNone) {
1423 Log::getInstance()->log("Audio", Log::DEBUG,
1424 "OMX_EmptyThisBuffer 3 failed %x", error);
1426 //FrameWaitforDisplay(lastreftimeOMX);
1427 vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1429 cur_input_buf_omx = NULL;//write out old data
1431 firstsynched = true;
1432 //decompress_buffer_filled=0;
1434 if (!firstsynched) {//
1435 *samplepos = packet.length;//if we have not processed at least one
1436 decompress_buffer_filled=0;
1437 return packet.length;//synched packet ignore it!
1441 if (!cur_input_buf_omx) {
1442 input_bufs_omx_mutex.Lock();
1443 if (input_bufs_omx_free.size()==0) {
1444 input_bufs_omx_mutex.Unlock();
1445 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1446 return 0; // we do not have a free media sample
1449 cur_input_buf_omx=input_bufs_omx_free.front();
1450 cur_input_buf_omx->nFilledLen=0;
1451 cur_input_buf_omx->nOffset=0;
1452 cur_input_buf_omx->nTimeStamp=0;
1453 input_bufs_omx_free.pop_front();
1454 input_bufs_omx_mutex.Unlock();
1457 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1458 if (packet.synched) {
1459 //Log::getInstance()->log("Audio", Log::DEBUG,
1460 // "packet synched marker");
1462 //lastreftimePTS=packet.pts;
1463 if (omx_first_frame) { // TODO time
1464 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1465 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1466 omx_first_frame = false;
1468 cur_input_buf_omx->nFlags = 0;
1469 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1471 lastreftimeOMX = packet.presentation_time;
1472 // Log::getInstance()->log("Audio", Log::DEBUG,
1473 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1474 lastreftimePTS = packet.pts;
1475 cur_input_buf_omx->nTimeStamp =0;// lastreftimeOMX; // the clock component is faulty;
1477 // Log::getInstance()->log("Audio", Log::DEBUG,
1478 // "packet NOT synched marker");
1479 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1480 cur_input_buf_omx->nTimeStamp = 0;
1483 if (packet.disconti || achange) {
1484 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1485 //mp23codec_context_libav->frame_size=-1;
1486 //ac3codec_context_libav->frame_size=-1;
1491 unsigned int haveToCopy=packet.length-*samplepos;
1500 AVCodecContext *current_context;
1501 switch (packet.type) {
1502 case MPTYPE_MPEG_AUDIO:
1503 case MPTYPE_MPEG_AUDIO_LAYER3: {
1504 current_context = mp23codec_context_libav;
1505 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1506 else framesize=current_context->frame_size;
1509 case MPTYPE_AC3_PRE13: {
1510 current_context = ac3codec_context_libav;
1514 if (decompress_buffer_filled) { // have a remaining paket
1515 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1516 memcpy(decompress_buffer+decompress_buffer_filled,
1517 buffer+packet.pos_buffer+*samplepos,
1518 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1519 incoming_paket_libav.size = decompress_buffer_filled
1520 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1521 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1523 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1524 incoming_paket_libav.size = haveToCopy;
1527 while (haveToCopy> 0 && errcount<3) {
1529 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1530 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1531 // framesize, current_context->frame_size);
1533 bool donotdecompress=false;
1534 unsigned int gotframesize=0;
1535 if (!decompress_buffer_filled) { // only do this if no old data is present
1537 switch (packet.type) {
1538 case MPTYPE_MPEG_AUDIO:
1539 case MPTYPE_MPEG_AUDIO_LAYER3: {
1540 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1541 incoming_paket_libav.size,&gotframesize);
1545 case MPTYPE_AC3_PRE13: {
1546 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1547 incoming_paket_libav.size,&gotframesize);
1552 incoming_paket_libav.data += adv;
1555 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1556 else*/ framesize=haveToCopy;
1557 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1558 if (haveToCopy <= 0) {
1559 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1560 *samplepos=packet.length;
1561 return packet.length;
1567 if (gotframesize>0 && gotframesize>haveToCopy) {
1568 donotdecompress=true;
1569 errcount=100; // exit loop
1571 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1574 if (!donotdecompress) {
1577 pthread_testcancel();
1578 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1579 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1581 if (!omx_running || !mp23codec_context_libav
1582 || !ac3codec_context_libav) {
1583 libav_mutex.Unlock();
1586 libav_mutex.Unlock();
1587 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1588 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1589 &gotta, &incoming_paket_libav);
1590 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1591 pthread_setcancelstate(oldcancelstate, NULL);
1592 pthread_setcanceltype(oldcanceltype, NULL);
1593 pthread_testcancel();
1599 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1601 libav_mutex.Unlock();
1605 if (decompress_buffer_filled) { // reset to normal decoding
1607 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1608 haveToCopy -= min(len-decompress_buffer_filled,0);
1609 *samplepos += min(len-decompress_buffer_filled,0);
1610 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1611 /*else*/ framesize=haveToCopy;
1613 framesize=haveToCopy;
1615 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1617 decompress_buffer_filled=0;
1621 incoming_paket_libav.data += len;
1625 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1626 else*/framesize=haveToCopy;
1629 framesize=haveToCopy;
1633 incoming_paket_libav.size =framesize;
1635 //Log::getInstance()->log("Audio", Log::DEBUG,
1637 int dsize = av_samples_get_buffer_size(NULL,
1638 current_context->channels, decode_frame_libav->nb_samples,
1639 current_context->sample_fmt, 1);
1640 if ((cur_input_buf_omx->nFilledLen + dsize)
1641 > cur_input_buf_omx->nAllocLen ) {
1642 // I doubt that this will ever happen
1643 // Log::getInstance()->log("Audio", Log::DEBUG,
1644 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1645 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1647 if (error != OMX_ErrorNone) {
1648 Log::getInstance()->log("Audio", Log::DEBUG,
1649 "OMX_EmptyThisBuffer 4 failed %x", error);
1651 cur_input_buf_omx = NULL;
1653 if (!cur_input_buf_omx) {
1655 while (count < 10 && omx_running) {
1657 input_bufs_omx_mutex.Lock();
1658 if (input_bufs_omx_free.size() == 0) {
1659 input_bufs_omx_mutex.Unlock();
1660 // Log::getInstance()->log("Audio", Log::DEBUG,
1661 // "Deliver MediaPacket no free sample");
1663 if (!omx_running) return *samplepos;
1666 cur_input_buf_omx = input_bufs_omx_free.front();
1667 cur_input_buf_omx->nFilledLen = 0;
1668 cur_input_buf_omx->nOffset = 0;
1669 cur_input_buf_omx->nTimeStamp = 0;
1670 input_bufs_omx_free.pop_front();
1671 input_bufs_omx_mutex.Unlock();
1674 if (!cur_input_buf_omx) return *samplepos;
1679 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1680 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1681 decode_frame_libav->data[0], dsize);
1682 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1683 cur_input_buf_omx->nFilledLen += dsize;
1685 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1686 /* uint8_t a1=incoming_paket_libav.data[0];
1687 uint8_t a2=incoming_paket_libav.data[1];
1688 uint8_t a3=incoming_paket_libav.data[2];
1689 uint8_t a4=incoming_paket_libav.data[3];*/
1690 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1697 decompress_buffer_filled=0;
1699 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);
1700 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1702 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1706 if (cur_input_buf_omx->nFilledLen) {
1707 //Log::getInstance()->log("Audio", Log::DEBUG,
1708 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1709 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1710 if (error != OMX_ErrorNone) {
1711 Log::getInstance()->log("Audio", Log::DEBUG,
1712 "OMX_EmptyThisBuffer 5 failed %x", error);
1714 if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1715 cur_input_buf_omx = NULL;
1721 *samplepos=packet.length;
1722 return packet.length;
1728 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1729 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1730 return vw->SetStartAudioOffset(curreftime,rsync);
1733 void AudioOMX::ResetTimeOffsets() {
1734 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1735 vw->ResetTimeOffsets();