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
1379 if (packet.synched && packet.presentation_time < 0) {
1380 *samplepos = packet.length;
1381 firstsynched = false;
1382 Log::getInstance()->log("Audio", Log::DEBUG,
1383 "DeliverMediaPacketOMX Frameskip");
1384 return packet.length;
1387 //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
1389 UINT headerstrip = 0;
1390 if (packet.disconti) {
1391 firstsynched = false;
1392 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 1 failed %x", error);
1400 cur_input_buf_omx = NULL;
1404 if (packet.type != lastAType) {//Format Change //Push data out !
1405 firstsynched = false;
1407 lastAType = packet.type;
1408 decompress_buffer_filled=0;
1410 if (cur_input_buf_omx) {
1411 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1413 if (error != OMX_ErrorNone) {
1414 Log::getInstance()->log("Audio", Log::DEBUG,
1415 "OMX_EmptyThisBuffer 2 failed %x", error);
1417 cur_input_buf_omx = NULL;
1420 if (!ChangeAudioPortConfig(true)) {
1421 Log::getInstance()->log("Audio", Log::DEBUG,
1422 "Changing audio port config failed", error);
1428 /*Inspect PES-Header */
1429 if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1430 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1431 if (packet.type == MPTYPE_AC3)
1432 headerstrip += 4; //skip ac3 bytes
1433 *samplepos += headerstrip;
1434 if (packet.synched) {
1435 if (cur_input_buf_omx) {
1436 //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1437 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1439 if (error != OMX_ErrorNone) {
1440 Log::getInstance()->log("Audio", Log::DEBUG,
1441 "OMX_EmptyThisBuffer 3 failed %x", error);
1443 //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1445 cur_input_buf_omx = NULL;//write out old data
1447 firstsynched = true;
1448 //decompress_buffer_filled=0;
1450 if (!firstsynched) {//
1451 *samplepos = packet.length;//if we have not processed at least one
1452 decompress_buffer_filled=0;
1453 return packet.length;//synched packet ignore it!
1457 if (!cur_input_buf_omx) {
1458 input_bufs_omx_mutex.Lock();
1459 if (input_bufs_omx_free.size()==0) {
1460 input_bufs_omx_mutex.Unlock();
1461 //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1462 return 0; // we do not have a free media sample
1465 cur_input_buf_omx=input_bufs_omx_free.front();
1466 cur_input_buf_omx->nFilledLen=0;
1467 cur_input_buf_omx->nOffset=0;
1468 cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0);
1469 input_bufs_omx_free.pop_front();
1470 input_bufs_omx_mutex.Unlock();
1473 if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1474 if (packet.synched) {
1475 //Log::getInstance()->log("Audio", Log::DEBUG,
1476 // "packet synched marker");
1478 //lastreftimePTS=packet.pts;
1479 if (omx_first_frame) { // TODO time
1480 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1481 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1482 omx_first_frame = false;
1484 cur_input_buf_omx->nFlags = 0;
1485 //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1487 lastreftimeOMX = packet.presentation_time;
1488 // Log::getInstance()->log("Audio", Log::DEBUG,
1489 // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1490 lastreftimePTS = packet.pts;
1491 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
1493 // Log::getInstance()->log("Audio", Log::DEBUG,
1494 // "packet NOT synched marker");
1495 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1496 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1499 if (packet.disconti || achange) {
1500 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1501 //mp23codec_context_libav->frame_size=-1;
1502 //ac3codec_context_libav->frame_size=-1;
1507 if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1508 unsigned int haveToCopy=packet.length-*samplepos;
1517 AVCodecContext *current_context;
1518 switch (packet.type) {
1519 case MPTYPE_MPEG_AUDIO:
1520 case MPTYPE_MPEG_AUDIO_LAYER3: {
1521 current_context = mp23codec_context_libav;
1522 if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1523 else framesize=current_context->frame_size;
1526 case MPTYPE_AC3_PRE13: {
1527 current_context = ac3codec_context_libav;
1531 if (decompress_buffer_filled) { // have a remaining paket
1532 incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1533 memcpy(decompress_buffer+decompress_buffer_filled,
1534 buffer+packet.pos_buffer+*samplepos,
1535 min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1536 incoming_paket_libav.size = decompress_buffer_filled
1537 +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1538 //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1540 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1541 incoming_paket_libav.size = haveToCopy;
1544 while (haveToCopy> 0 && errcount<3) {
1546 //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1547 //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1548 // framesize, current_context->frame_size);
1550 bool donotdecompress=false;
1551 unsigned int gotframesize=0;
1552 if (!decompress_buffer_filled) { // only do this if no old data is present
1554 switch (packet.type) {
1555 case MPTYPE_MPEG_AUDIO:
1556 case MPTYPE_MPEG_AUDIO_LAYER3: {
1557 adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1558 incoming_paket_libav.size,&gotframesize);
1562 case MPTYPE_AC3_PRE13: {
1563 adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1564 incoming_paket_libav.size,&gotframesize);
1569 incoming_paket_libav.data += adv;
1570 incoming_paket_libav.size-=adv;
1573 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1574 else*/ framesize=haveToCopy;
1575 //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1576 if (haveToCopy <= 0) {
1577 // Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1578 *samplepos=packet.length;
1579 return packet.length;
1585 if (gotframesize>0 && gotframesize>haveToCopy) {
1586 donotdecompress=true;
1587 errcount=100; // exit loop
1589 // else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1592 if (!donotdecompress) {
1595 pthread_testcancel();
1596 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1597 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1599 if (!omx_running || !mp23codec_context_libav
1600 || !ac3codec_context_libav) {
1601 libav_mutex.Unlock();
1604 libav_mutex.Unlock();
1605 // Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1606 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1607 &gotta, &incoming_paket_libav);
1608 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1609 pthread_setcancelstate(oldcancelstate, NULL);
1610 pthread_setcanceltype(oldcanceltype, NULL);
1611 pthread_testcancel();
1617 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1619 libav_mutex.Unlock();
1623 if (decompress_buffer_filled) { // reset to normal decoding
1625 Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1626 haveToCopy -= min(len-decompress_buffer_filled,0);
1627 *samplepos += min(len-decompress_buffer_filled,0);
1628 //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1629 /*else*/ framesize=haveToCopy;
1631 framesize=haveToCopy;
1633 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1635 decompress_buffer_filled=0;
1639 incoming_paket_libav.data += len;
1643 /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1644 else*/framesize=haveToCopy;
1647 framesize=haveToCopy;
1651 incoming_paket_libav.size =framesize;
1653 //Log::getInstance()->log("Audio", Log::DEBUG,
1655 int dsize = av_samples_get_buffer_size(NULL,
1656 current_context->channels, decode_frame_libav->nb_samples,
1657 current_context->sample_fmt, 1);
1658 if ((cur_input_buf_omx->nFilledLen + dsize)
1659 > cur_input_buf_omx->nAllocLen ) {
1660 // I doubt that this will ever happen
1661 // Log::getInstance()->log("Audio", Log::DEBUG,
1662 // "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1663 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1665 if (error != OMX_ErrorNone) {
1666 Log::getInstance()->log("Audio", Log::DEBUG,
1667 "OMX_EmptyThisBuffer 4 failed %x", error);
1669 cur_input_buf_omx = NULL;
1671 if (!cur_input_buf_omx) {
1673 while (count < 10 && omx_running) {
1675 input_bufs_omx_mutex.Lock();
1676 if (input_bufs_omx_free.size() == 0) {
1677 input_bufs_omx_mutex.Unlock();
1678 // Log::getInstance()->log("Audio", Log::DEBUG,
1679 // "Deliver MediaPacket no free sample");
1681 if (!omx_running) return *samplepos;
1684 cur_input_buf_omx = input_bufs_omx_free.front();
1685 cur_input_buf_omx->nFilledLen = 0;
1686 cur_input_buf_omx->nOffset = 0;
1687 cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0);
1688 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1689 input_bufs_omx_free.pop_front();
1690 input_bufs_omx_mutex.Unlock();
1693 if (!cur_input_buf_omx) return *samplepos;
1698 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1699 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1700 decode_frame_libav->data[0], dsize);
1701 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1702 cur_input_buf_omx->nFilledLen += dsize;
1704 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1705 /* uint8_t a1=incoming_paket_libav.data[0];
1706 uint8_t a2=incoming_paket_libav.data[1];
1707 uint8_t a3=incoming_paket_libav.data[2];
1708 uint8_t a4=incoming_paket_libav.data[3];*/
1709 // Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1716 decompress_buffer_filled=0;
1718 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);
1719 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1721 decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1725 if (cur_input_buf_omx->nFilledLen) {
1726 //Log::getInstance()->log("Audio", Log::DEBUG,
1727 // "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1728 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1729 if (error != OMX_ErrorNone) {
1730 Log::getInstance()->log("Audio", Log::DEBUG,
1731 "OMX_EmptyThisBuffer 5 failed %x", error);
1733 //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1734 cur_input_buf_omx = NULL;
1740 *samplepos=packet.length;
1741 return packet.length;
1747 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1748 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1749 return vw->SetStartAudioOffset(curreftime,rsync);
1752 void AudioOMX::ResetTimeOffsets() {
1753 VideoOMX *vw=(VideoOMX*)Video::getInstance();
1754 vw->ResetTimeOffsets();