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);
1184 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1185 Log::getInstance()->log("Audio", Log::DEBUG, " pause aud_rend idle ChangeComponentState");
1194 int AudioOMX::unPause()
1196 if (!initted) return 0;
1198 paused=false; // may be also change omx clock
1199 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1201 if (!vw->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
1202 Log::getInstance()->log("Audio", Log::DEBUG, " unpause aud_rend idle ChangeComponentState");
1210 int AudioOMX::reset()
1212 if (!initted) return 0;
1214 Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1215 DeAllocateCodecsOMX();
1217 // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1218 // Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1219 // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1225 int AudioOMX::setVolume(int tvolume)
1227 // parameter: 0 for silence, 20 for full
1228 if ((tvolume < 0) || (tvolume > 20)) return 0;
1230 // volume = 2 * (20 - volume);
1231 // Right, that one was rubbish... 0-10 were almost
1232 // inaudible, 11-20 did what should have been done
1233 // over the whole 0-20 range
1235 tvolume = 20 - tvolume;
1237 audio_volume Avolume;
1238 Avolume.frontleft = tvolume + Aoffset.frontleft;
1239 Avolume.frontright = tvolume + Aoffset.frontright;
1240 Avolume.rearleft = tvolume + Aoffset.rearleft;
1241 Avolume.rearright = tvolume + Aoffset.rearright;
1242 Avolume.center = tvolume + Aoffset.center;
1243 Avolume.lfe = tvolume + Aoffset.lfe;
1245 // if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &Avolume) != 0) return 0;
1247 // unsigned long vol = (tvolume << 24) | (tvolume << 16);
1249 // Log::getInstance()->log("Audio", Log::DEBUG, "%lx", vol);
1250 // Log::getInstance()->log("Audio", Log::DEBUG, "%i", tvolume);
1252 // if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &vol) != 0) return 0;
1257 int AudioOMX::test()
1260 // return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1262 /* aud_sync_parms_t a;
1266 // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1269 /*OK*/ //printf("Audio sync disable = %i\n", b);
1277 unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1279 if (size<=2) return size; // silly;
1280 unsigned int test=0;
1282 while (test+1<size) {
1283 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1289 unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1291 if (size<=4) return size; // silly;
1292 const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1293 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1294 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1295 1152, 1280, 1280, };
1296 unsigned int test=0;
1297 *framesize=20000; //if we do not find a start code do not decompress
1298 while (test+4<size) {
1299 if (data[test]==0x0B && data[test+1]==0x77) {
1300 // now figure out the length of the frame
1301 unsigned char code=data[test+4];
1302 unsigned char fscod=(code& 0xC0)>>6;
1303 unsigned char frmsize=(code &0x3f);
1304 if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1305 *framesize=frm_size_tab[frmsize]*2;
1306 return test; // probably FrameSync
1314 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1316 packet = mplist.front();
1319 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1320 DeliverMediaPacket(packet, buffer, samplepos);
1321 if (*samplepos == packet.length) {
1329 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1331 VideoOMX *video = (VideoOMX*) Video::getInstance();
1333 OMX_PARAM_U32TYPE audio_lat;
1334 OMX_ERRORTYPE error;
1335 memset(&audio_lat, 0, sizeof(audio_lat));
1336 audio_lat.nSize = sizeof(audio_lat);
1337 audio_lat.nVersion.nVersion = OMX_VERSION;
1338 audio_lat.nPortIndex = omx_rend_input_port;
1340 error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1342 video->UnlockClock();
1343 if (error != OMX_ErrorNone) {
1344 Log::getInstance()->log("Audio", Log::DEBUG,
1345 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1346 omx_rend_input_port);
1347 return pts; // no correction in case of error
1349 /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1352 long long workpts=0;
1353 workpts+=addsamples;
1354 workpts-=audio_lat.nU32;
1355 workpts*=10LL*1000LL*1000LL;
1356 workpts=workpts/((long long)srate); //one second /samplerate
1364 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1366 /*First Check, if we have an audio sample*/
1367 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1369 OMX_ERRORTYPE error;
1370 Log *logger=Log::getInstance();
1371 if (vw->InIframemode()) {
1374 return 0; //Not in iframe mode!
1377 if (!omx_running) return 0; // if we are not runnig do not do this
1378 if (paused) return 0; //Block if we pause
1380 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1382 if (packet.synched && packet.presentation_time <= 0) {
1383 *samplepos = packet.length;
1384 firstsynched = false;
1385 Log::getInstance()->log("Audio", Log::DEBUG,
1386 "DeliverMediaPacketOMX Frameskip");
1387 return packet.length;
1392 UINT headerstrip = 0;
1393 if (packet.disconti) {
1394 firstsynched = false;
1395 decompress_buffer_filled=0;
1396 if (cur_input_buf_omx) {
1397 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1399 if (error != OMX_ErrorNone) {
1400 Log::getInstance()->log("Audio", Log::DEBUG,
1401 "OMX_EmptyThisBuffer 1 failed %x", error);
1403 cur_input_buf_omx = NULL;
1407 if (packet.type != lastAType) {//Format Change //Push data out !
1408 firstsynched = false;
1410 lastAType = packet.type;
1411 decompress_buffer_filled=0;
1413 if (cur_input_buf_omx) {
1414 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1416 if (error != OMX_ErrorNone) {
1417 Log::getInstance()->log("Audio", Log::DEBUG,
1418 "OMX_EmptyThisBuffer 2 failed %x", error);
1420 cur_input_buf_omx = NULL;
1423 if (!ChangeAudioPortConfig(true)) {
1424 Log::getInstance()->log("Audio", Log::DEBUG,
1425 "Changing audio port config failed", error);
1431 /*Inspect PES-Header */
1432 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1433 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1434 if (packet.type == MPTYPE_AC3)
1435 headerstrip += 4; //skip ac3 bytes
1436 *samplepos += headerstrip;
1437 if (packet.synched) {
1438 if (cur_input_buf_omx) {
1439 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1440 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1442 if (error != OMX_ErrorNone) {
1443 Log::getInstance()->log("Audio", Log::DEBUG,
1444 "OMX_EmptyThisBuffer 3 failed %x", error);
1446 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1448 cur_input_buf_omx = NULL;//write out old data
1450 firstsynched = true;
1451 //decompress_buffer_filled=0;
1453 if (!firstsynched) {//
1454 *samplepos = packet.length;//if we have not processed at least one
1455 decompress_buffer_filled=0;
1456 return packet.length;//synched packet ignore it!
1460 if (!cur_input_buf_omx) {
1461 input_bufs_omx_mutex.Lock();
1462 if (input_bufs_omx_free.size()==0) {
1463 input_bufs_omx_mutex.Unlock();
1464 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1465 return 0; // we do not have a free media sample
1468 cur_input_buf_omx=input_bufs_omx_free.front();
1469 cur_input_buf_omx->nFilledLen=0;
1470 cur_input_buf_omx->nOffset=0;
1471 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1472 input_bufs_omx_free.pop_front();
1473 input_bufs_omx_mutex.Unlock();
1476 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1477 if (packet.synched) {
1478 //Log::getInstance()->log("Audio", Log::DEBUG,
1479 // "packet synched marker");
1481 //lastreftimePTS=packet.pts;
1482 if (omx_first_frame) { // TODO time
1483 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1484 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1485 omx_first_frame = false;
1487 cur_input_buf_omx->nFlags = 0;
1488 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1490 lastreftimeOMX = packet.presentation_time;
1491 // Log::getInstance()->log("Audio", Log::DEBUG,
1492 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1493 lastreftimePTS = packet.pts;
1494 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1496 // Log::getInstance()->log("Audio", Log::DEBUG,
1497 // "packet NOT synched marker");
1498 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1499 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1502 if (packet.disconti || achange) {
1503 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1504 //mp23codec_context_libav->frame_size=-1;
1505 //ac3codec_context_libav->frame_size=-1;
1510 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1511 unsigned int haveToCopy=packet.length-*samplepos;
1520 AVCodecContext *current_context;
1521 switch (packet.type) {
1522 case MPTYPE_MPEG_AUDIO:
1523 case MPTYPE_MPEG_AUDIO_LAYER3: {
1524 current_context = mp23codec_context_libav;
1525 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1526 else framesize=current_context->frame_size;
1529 case MPTYPE_AC3_PRE13: {
1530 current_context = ac3codec_context_libav;
1534 if (decompress_buffer_filled) { // have a remaining paket
1535 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1536 memcpy(decompress_buffer+decompress_buffer_filled,
1537 buffer+packet.pos_buffer+*samplepos,
1538 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1539 incoming_paket_libav.size = decompress_buffer_filled
1540 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1541 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1543 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1544 incoming_paket_libav.size = haveToCopy;
1547 while (haveToCopy> 0 && errcount<3) {
1549 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1550 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1551 // framesize, current_context->frame_size);
1553 bool donotdecompress=false;
1554 unsigned int gotframesize=0;
1555 if (!decompress_buffer_filled) { // only do this if no old data is present
1557 switch (packet.type) {
1558 case MPTYPE_MPEG_AUDIO:
1559 case MPTYPE_MPEG_AUDIO_LAYER3: {
1560 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1561 incoming_paket_libav.size,&gotframesize);
1565 case MPTYPE_AC3_PRE13: {
1566 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1567 incoming_paket_libav.size,&gotframesize);
1572 incoming_paket_libav.data += adv;
1573 incoming_paket_libav.size-=adv;
1576 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1577 else*/ framesize=haveToCopy;
1578 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1579 if (haveToCopy <= 0) {
1580 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1581 *samplepos=packet.length;
1582 return packet.length;
1588 if (gotframesize>0 && gotframesize>haveToCopy) {
1589 donotdecompress=true;
1590 errcount=100; // exit loop
1592 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1595 if (!donotdecompress) {
1598 pthread_testcancel();
1599 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1600 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1602 if (!omx_running || !mp23codec_context_libav
1603 || !ac3codec_context_libav) {
1604 libav_mutex.Unlock();
1607 libav_mutex.Unlock();
1608 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1609 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1610 &gotta, &incoming_paket_libav);
1611 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1612 pthread_setcancelstate(oldcancelstate, NULL);
1613 pthread_setcanceltype(oldcanceltype, NULL);
1614 pthread_testcancel();
1620 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1622 libav_mutex.Unlock();
1626 if (decompress_buffer_filled) { // reset to normal decoding
1628 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1629 haveToCopy -= min(len-decompress_buffer_filled,0);
1630 *samplepos += min(len-decompress_buffer_filled,0);
1631 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1632 /*else*/ framesize=haveToCopy;
1634 framesize=haveToCopy;
1636 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1638 decompress_buffer_filled=0;
1642 incoming_paket_libav.data += len;
1646 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1647 else*/framesize=haveToCopy;
1650 framesize=haveToCopy;
1654 incoming_paket_libav.size =framesize;
1656 //Log::getInstance()->log("Audio", Log::DEBUG,
1658 int dsize = av_samples_get_buffer_size(NULL,
1659 current_context->channels, decode_frame_libav->nb_samples,
1660 current_context->sample_fmt, 1);
1661 if ((cur_input_buf_omx->nFilledLen + dsize)
1662 > cur_input_buf_omx->nAllocLen ) {
1663 // I doubt that this will ever happen
1664 // Log::getInstance()->log("Audio", Log::DEBUG,
1665 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1666 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1668 if (error != OMX_ErrorNone) {
1669 Log::getInstance()->log("Audio", Log::DEBUG,
1670 "OMX_EmptyThisBuffer 4 failed %x", error);
1672 cur_input_buf_omx = NULL;
1674 if (!cur_input_buf_omx) {
1676 while (count < 10 && omx_running) {
1678 input_bufs_omx_mutex.Lock();
1679 if (input_bufs_omx_free.size() == 0) {
1680 input_bufs_omx_mutex.Unlock();
1681 // Log::getInstance()->log("Audio", Log::DEBUG,
1682 // "Deliver MediaPacket no free sample");
1684 if (!omx_running) return *samplepos;
1687 cur_input_buf_omx = input_bufs_omx_free.front();
1688 cur_input_buf_omx->nFilledLen = 0;
1689 cur_input_buf_omx->nOffset = 0;
1690 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1691 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1692 input_bufs_omx_free.pop_front();
1693 input_bufs_omx_mutex.Unlock();
1696 if (!cur_input_buf_omx) return *samplepos;
1701 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1702 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1703 decode_frame_libav->data[0], dsize);
1704 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1705 cur_input_buf_omx->nFilledLen += dsize;
1707 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1708 /* uint8_t a1=incoming_paket_libav.data[0];
1709 uint8_t a2=incoming_paket_libav.data[1];
1710 uint8_t a3=incoming_paket_libav.data[2];
1711 uint8_t a4=incoming_paket_libav.data[3];*/
1712 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1719 decompress_buffer_filled=0;
1721 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);
1722 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1724 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1728 if (cur_input_buf_omx->nFilledLen) {
1729 //Log::getInstance()->log("Audio", Log::DEBUG,
1730 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1731 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1732 if (error != OMX_ErrorNone) {
1733 Log::getInstance()->log("Audio", Log::DEBUG,
1734 "OMX_EmptyThisBuffer 5 failed %x", error);
1736 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1737 cur_input_buf_omx = NULL;
1743 *samplepos=packet.length;
1744 return packet.length;
1750 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1751 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1752 return vw->SetStartAudioOffset(curreftime,rsync);
1755 void AudioOMX::ResetTimeOffsets() {
1756 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1757 vw->ResetTimeOffsets();