From dadae076a4f6baaf63065fd2f7b123115781d75a Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Thu, 16 Feb 2023 18:22:54 +0000 Subject: [PATCH] Formatting --- src/audioomx.cc | 4204 +++++++++++++++++++++++++---------------------- src/audioomx.h | 134 +- 2 files changed, 2335 insertions(+), 2003 deletions(-) diff --git a/src/audioomx.cc b/src/audioomx.cc index 1492455..0be7e27 100644 --- a/src/audioomx.cc +++ b/src/audioomx.cc @@ -44,38 +44,36 @@ AudioOMX::AudioOMX() muted = 0; lastAType = MPTYPE_MPEG_AUDIO; - canpass_ac3=false; - canpass_mp2=false; - canpass_mp3=false; - canpass_aac=false; - canpass_pcm_mch=false; + canpass_ac3 = false; + canpass_mp2 = false; + canpass_mp3 = false; + canpass_aac = false; + canpass_pcm_mch = false; - prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM - prefered_mp2=0; - prefered_mp3=0; - prefered_aac=0; - hdmi=true; + prefered_ac3 = 0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM + prefered_mp2 = 0; + prefered_mp3 = 0; + prefered_aac = 0; + hdmi = true; - omx_running=false; + omx_running = false; - omx_aud_rend/*dec*/=0; - cur_input_buf_omx=NULL; + omx_aud_rend/*dec*/ = 0; + cur_input_buf_omx = NULL; - ac3codec_libav=NULL; - ac3codec_context_libav=NULL; + ac3codec_libav = NULL; + ac3codec_context_libav = NULL; - mp23codec_libav=NULL; - mp23codec_context_libav=NULL; + mp23codec_libav = NULL; + mp23codec_context_libav = NULL; - resam_con_libav=NULL; + resam_con_libav = NULL; - - - decompress_buffer=NULL; - decompress_buffer_size=0; - decompress_buffer_filled=0; - mp3sameheader=0; - mp3sameheadercount=0; + decompress_buffer = NULL; + decompress_buffer_size = 0; + decompress_buffer_filled = 0; + mp3sameheader = 0; + mp3sameheadercount = 0; strcpy(L_VPE_OMX_AUDIO_REND, VPE_OMX_AUDIO_REND); } @@ -84,85 +82,97 @@ AudioOMX::~AudioOMX() { } -int AudioOMX::init(u1 tstreamType) { - if (initted) - return 0; - initted = 1; +int AudioOMX::init(u1 tstreamType) +{ + if (initted) + return 0; + + initted = 1; - streamType = tstreamType; + streamType = tstreamType; - if (!initAllParams()) { - shutdown(); - return 0; - } + if (!initAllParams()) + { + shutdown(); + return 0; + } - unMute(); + unMute(); - decompress_buffer_size=20000; - decompress_buffer=static_cast(malloc(decompress_buffer_size)); - decompress_buffer_filled=0; + decompress_buffer_size = 20000; + decompress_buffer = static_cast(malloc(decompress_buffer_size)); + decompress_buffer_filled = 0; #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100) - av_register_all(); + av_register_all(); #endif - av_log_set_flags(AV_LOG_SKIP_REPEATED); - - ac3codec_libav = avcodec_find_decoder(AV_CODEC_ID_AC3); - if (ac3codec_libav == NULL) { - LogNT::getInstance()->debug(TAG, - "Find libav ac3 decoder failed"); - return 0; - } - - mp23codec_libav = avcodec_find_decoder(AV_CODEC_ID_MP3); - if (mp23codec_libav == NULL) { - LogNT::getInstance()->debug(TAG, - "Find libav mpeg audio decoder failed"); - return 0; - } - - aaclatmcodec_libav = avcodec_find_decoder(AV_CODEC_ID_AAC_LATM); - if (aaclatmcodec_libav == NULL) { - LogNT::getInstance()->debug(TAG, - "Find libav aac latm decoder failed"); - return 0; - } - - int ret; - - ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0); - if (ret==0) { - //canpass_mp2=true; - // not implemented - LogNT::getInstance()->info(TAG, - "TV hdmi supports mpeg1 layer 1 and 2"); - } - ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3,2,EDID_AudioSampleRate_e48KHz,0); - if (ret==0) { - //canpass_mp3=true; - // not implemented - LogNT::getInstance()->info(TAG, - "TV hdmi supports mpeg1 layer 3"); - } - - ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3,6,EDID_AudioSampleRate_e48KHz,0); - if (ret==0) { - canpass_ac3=true; - LogNT::getInstance()->info(TAG, - "TV hdmi supports AC3"); - } - ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0); - if (ret==0) { - canpass_aac=true; - //not implemented - LogNT::getInstance()->info(TAG, - "TV hdmi supports AAC"); - } - - canpass_pcm_mch=false; - - return 1; + av_log_set_flags(AV_LOG_SKIP_REPEATED); + + ac3codec_libav = avcodec_find_decoder(AV_CODEC_ID_AC3); + + if (ac3codec_libav == NULL) + { + LogNT::getInstance()->debug(TAG, "Find libav ac3 decoder failed"); + return 0; + } + + mp23codec_libav = avcodec_find_decoder(AV_CODEC_ID_MP3); + + if (mp23codec_libav == NULL) + { + LogNT::getInstance()->debug(TAG, "Find libav mpeg audio decoder failed"); + return 0; + } + + aaclatmcodec_libav = avcodec_find_decoder(AV_CODEC_ID_AAC_LATM); + + if (aaclatmcodec_libav == NULL) + { + LogNT::getInstance()->debug(TAG, "Find libav aac latm decoder failed"); + return 0; + } + + int ret; + + ret = vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1, 2, EDID_AudioSampleRate_e48KHz, 0); + + if (ret == 0) + { + //canpass_mp2=true; + // not implemented + LogNT::getInstance()->info(TAG, "TV hdmi supports mpeg1 layer 1 and 2"); + } + + ret = vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMP3, 2, EDID_AudioSampleRate_e48KHz, 0); + + if (ret == 0) + { + //canpass_mp3=true; + // not implemented + LogNT::getInstance()->info(TAG, "TV hdmi supports mpeg1 layer 3"); + } + + ret = vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAC3, 6, EDID_AudioSampleRate_e48KHz, 0); + + if (ret == 0) + { + canpass_ac3 = true; + LogNT::getInstance()->info(TAG, "TV hdmi supports AC3"); + } + + ret = vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC, 6, EDID_AudioSampleRate_e48KHz, 0); + + if (ret == 0) + { + canpass_aac = true; + //not implemented + LogNT::getInstance()->info(TAG, "TV hdmi supports AAC"); + } + + canpass_pcm_mch = false; + + return 1; } int AudioOMX::initAllParams() @@ -173,336 +183,404 @@ int AudioOMX::initAllParams() int AudioOMX::shutdown() { if (!initted) return 0; + initted = 0; LogNT::getInstance()->debug(TAG, "audio shutdown called"); DeAllocateCodecsOMX(); free(decompress_buffer); - decompress_buffer=NULL; - decompress_buffer_size=0; - decompress_buffer_filled=0; + decompress_buffer = NULL; + decompress_buffer_size = 0; + decompress_buffer_filled = 0; return 1; } bool AudioOMX::loadOptionsFromServer(VDR* vdr) { - LogNT::getInstance()->debug(TAG, "AudioOMX config load"); - char *name=vdr->configLoad("AudioOMX","AC3DecodingMode"); - - if (name != NULL) { - if (STRCASECMP(name, "PCM") == 0) { - prefered_ac3 = 0; - } else if (STRCASECMP(name, "Passthrough") == 0) { - prefered_ac3 = 1; - } else if (STRCASECMP(name, "PCMMultichannel") == 0) { - prefered_ac3 = 2; - } - delete[] name; - } - - name = vdr->configLoad("AudioOMX", "Mp2DecodingMode"); - - if (name != NULL) { - if (STRCASECMP(name, "PCM") == 0) { - prefered_mp2 = 0; - } else if (STRCASECMP(name, "Passthrough") == 0) { - prefered_mp2 = 1; - } else if (STRCASECMP(name, "PCMMultichannel") == 0) { - prefered_mp2 = 2; - } - delete[] name; - } - - name = vdr->configLoad("AudioOMX", "AACDecodingMode"); - - if (name != NULL) { - if (STRCASECMP(name, "PCM") == 0) { - prefered_aac = 0; - } else if (STRCASECMP(name, "Passthrough") == 0) { - prefered_aac = 1; - } else if (STRCASECMP(name, "PCMMultichannel") == 0) { - prefered_aac = 2; - } - delete[] name; - } - - name = vdr->configLoad("AudioOMX", "Mp3DecodingMode"); - - if (name != NULL) { - if (STRCASECMP(name, "PCM") == 0) { - prefered_mp3 = 0; - } else if (STRCASECMP(name, "Passthrough") == 0) { - prefered_mp3 = 1; - } else if (STRCASECMP(name, "PCMMultichannel") == 0) { - prefered_mp3 = 2; - } - delete[] name; - } - - name = vdr->configLoad("AudioOMX", "AudioOutput"); - - if (name != NULL) { - if (STRCASECMP(name, "analog") == 0) { - hdmi = false; - } else if (STRCASECMP(name, "HDMI") == 0) { - hdmi = true; - } - delete[] name; - } - - - return true; + LogNT::getInstance()->debug(TAG, "AudioOMX config load"); + char* name = vdr->configLoad("AudioOMX", "AC3DecodingMode"); + + if (name != NULL) + { + if (STRCASECMP(name, "PCM") == 0) + { + prefered_ac3 = 0; + } + else if (STRCASECMP(name, "Passthrough") == 0) + { + prefered_ac3 = 1; + } + else if (STRCASECMP(name, "PCMMultichannel") == 0) + { + prefered_ac3 = 2; + } + + delete[] name; + } + + name = vdr->configLoad("AudioOMX", "Mp2DecodingMode"); + + if (name != NULL) + { + if (STRCASECMP(name, "PCM") == 0) + { + prefered_mp2 = 0; + } + else if (STRCASECMP(name, "Passthrough") == 0) + { + prefered_mp2 = 1; + } + else if (STRCASECMP(name, "PCMMultichannel") == 0) + { + prefered_mp2 = 2; + } + + delete[] name; + } + + name = vdr->configLoad("AudioOMX", "AACDecodingMode"); + + if (name != NULL) + { + if (STRCASECMP(name, "PCM") == 0) + { + prefered_aac = 0; + } + else if (STRCASECMP(name, "Passthrough") == 0) + { + prefered_aac = 1; + } + else if (STRCASECMP(name, "PCMMultichannel") == 0) + { + prefered_aac = 2; + } + + delete[] name; + } + + name = vdr->configLoad("AudioOMX", "Mp3DecodingMode"); + + if (name != NULL) + { + if (STRCASECMP(name, "PCM") == 0) + { + prefered_mp3 = 0; + } + else if (STRCASECMP(name, "Passthrough") == 0) + { + prefered_mp3 = 1; + } + else if (STRCASECMP(name, "PCMMultichannel") == 0) + { + prefered_mp3 = 2; + } + + delete[] name; + } + + name = vdr->configLoad("AudioOMX", "AudioOutput"); + + if (name != NULL) + { + if (STRCASECMP(name, "analog") == 0) + { + hdmi = false; + } + else if (STRCASECMP(name, "HDMI") == 0) + { + hdmi = true; + } + + delete[] name; + } + + + return true; } bool AudioOMX::handleOptionChanges(Option* option) { - if (Audio::handleOptionChanges(option)) - return true; - switch (option->id) { - case 4: { - if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) { - hdmi = false; - } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI") - == 0) { - hdmi = true; - } - return true; - } - break; - case 1: { - if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) { - prefered_ac3 = 0; - } else if (STRCASECMP(option->options[option->userSetChoice], - "Passthrough") == 0) { - prefered_ac3 = 1; - } else if (STRCASECMP(option->options[option->userSetChoice], - "PCMMultichannel") == 0) { - prefered_ac3 = 2; - } - } - break; - case 2: { - if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) { - prefered_mp2 = 0; - } else if (STRCASECMP(option->options[option->userSetChoice], - "Passthrough") == 0) { - prefered_mp2 = 1; - } else if (STRCASECMP(option->options[option->userSetChoice], - "PCMMultichannel") == 0) { - prefered_mp2 = 2; - } - } - break; - case 3: { - if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) { - prefered_mp3 = 0; - } else if (STRCASECMP(option->options[option->userSetChoice], - "Passthrough") == 0) { - prefered_mp3 = 1; - } else if (STRCASECMP(option->options[option->userSetChoice], - "PCMMultichannel") == 0) { - prefered_mp3 = 2; - } - } - break; - case 5: { - if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) { - prefered_aac = 0; - } else if (STRCASECMP(option->options[option->userSetChoice], - "Passthrough") == 0) { - prefered_aac = 1; - } else if (STRCASECMP(option->options[option->userSetChoice], - "PCMMultichannel") == 0) { - prefered_aac = 2; - } - } - break; - }; - return false; + if (Audio::handleOptionChanges(option)) + return true; + + switch (option->id) + { + case 4: + { + if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) + { + hdmi = false; + } + else if (STRCASECMP(option->options[option->userSetChoice], "HDMI") + == 0) + { + hdmi = true; + } + + return true; + } + break; + + case 1: + { + if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) + { + prefered_ac3 = 0; + } + else if (STRCASECMP(option->options[option->userSetChoice], "Passthrough") == 0) + { + prefered_ac3 = 1; + } + else if (STRCASECMP(option->options[option->userSetChoice], "PCMMultichannel") == 0) + { + prefered_ac3 = 2; + } + } + break; + + case 2: + { + if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) + { + prefered_mp2 = 0; + } + else if (STRCASECMP(option->options[option->userSetChoice], "Passthrough") == 0) + { + prefered_mp2 = 1; + } + else if (STRCASECMP(option->options[option->userSetChoice], "PCMMultichannel") == 0) + { + prefered_mp2 = 2; + } + } + break; + + case 3: + { + if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) + { + prefered_mp3 = 0; + } + else if (STRCASECMP(option->options[option->userSetChoice], "Passthrough") == 0) + { + prefered_mp3 = 1; + } + else if (STRCASECMP(option->options[option->userSetChoice], "PCMMultichannel") == 0) + { + prefered_mp3 = 2; + } + } + break; + + case 5: + { + if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) + { + prefered_aac = 0; + } + else if (STRCASECMP(option->options[option->userSetChoice], "Passthrough") == 0) + { + prefered_aac = 1; + } + else if (STRCASECMP(option->options[option->userSetChoice], "PCMMultichannel") == 0) + { + prefered_aac = 2; + } + } + break; + } + + return false; } bool AudioOMX::saveOptionstoServer() { - switch (prefered_ac3) { - case 0: - VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM"); - break; - case 1: - VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", - "Passthrough"); - break; - case 2: - VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", - "PCMMultichannel"); - break; - }; - - switch (prefered_aac) { - case 0: - VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM"); - break; - case 1: - VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", - "Passthrough"); - break; - case 2: - VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", - "PCMMultichannel"); - break; - }; - - switch (prefered_mp2) { - case 0: - VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM"); - break; - case 1: - VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", - "Passthrough"); - break; - case 2: - VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", - "PCMMultichannel"); - break; - }; - - switch (prefered_mp3) { - case 0: - VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM"); - break; - case 1: - VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", - "Passthrough"); - break; - case 2: - VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", - "PCMMultichannel"); - break; - }; - - if (!hdmi) - VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog"); - else - VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI"); + switch (prefered_ac3) + { + case 0: + VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM"); + break; + case 1: + VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "Passthrough"); + break; - return true; + case 2: + VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCMMultichannel"); + break; + } + + switch (prefered_aac) + { + case 0: + VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM"); + break; + + case 1: + VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "Passthrough"); + break; + + case 2: + VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCMMultichannel"); + break; + } + + switch (prefered_mp2) + { + case 0: + VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM"); + break; + + case 1: + VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "Passthrough"); + break; + + case 2: + VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCMMultichannel"); + break; + } + + switch (prefered_mp3) + { + case 0: + VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM"); + break; + + case 1: + VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "Passthrough"); + break; + + case 2: + VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCMMultichannel"); + break; + } + + if (!hdmi) + VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog"); + else + VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI"); + + + return true; } /*Option(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType, u4 numChoices, u4 defaultChoice, u4 startInt, const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/ -bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane) +bool AudioOMX::addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane) { - if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false; + if (!Audio::addOptionsToPanes(panenumber, options, pane)) return false; + + Option* option; + + if (panenumber == 2) + { + static const char* audioopts[] = {"analog", "HDMI"}; + option = new Option(4, tr("Audio Output"), "AudioOMX", "AudioOutput", Option::TYPE_TEXT, 2, 0, 0, audioopts, NULL, false, this); + options->push_back(option); + pane->addOptionLine(option); - Option* option; - if (panenumber == 2) + char** ac3opts = new char* [3]; + int i = 0; + ac3opts[i] = new char[strlen("PCM") + 1]; + strcpy(ac3opts[i], "PCM"); + i++; + + if (canpass_ac3) + { + ac3opts[i] = new char[strlen("Passthrough") + 1]; + strcpy(ac3opts[i], "PassThrough"); + i++; + } + + if (canpass_pcm_mch) { + ac3opts[i] = new char[strlen("PCMMultichannel") + 1]; + strcpy(ac3opts[i], "PCMMultichannel"); + i++; + } - static const char* audioopts[]={"analog","HDMI"}; - option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this); + option = new Option(1, tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts, NULL, true, this); + options->push_back(option); + pane->addOptionLine(option); + + /* char **aacopts = new char *[3]; + i = 0; + aacopts[i] = new char[strlen("PCM") + 1]; + strcpy(mp2opts[i], "PCM"); + i++; + if (canpass_aac) { + aacopts[i] = new char[strlen("Passthrough") + 1]; + strcpy(aacopts[i], "PassThrough"); + i++; + } + if (canpass_pcm_mch) { + aacopts[i] = new char[strlen("PCMMultichannel") + 1]; + strcpy(aacopts[i], "PCMMultichannel"); + i++; + } + option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX", + "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0, + aacopts, NULL, true, this); + options->push_back(option); + pane->addOptionLine(option); + + + char **mp2opts = new char *[3]; + i = 0; + mp2opts[i] = new char[strlen("PCM") + 1]; + strcpy(mp2opts[i], "PCM"); + i++; + if (canpass_mp2) { + mp2opts[i] = new char[strlen("Passthrough") + 1]; + strcpy(mp2opts[i], "PassThrough"); + i++; + } + if (canpass_pcm_mch) { + mp2opts[i] = new char[strlen("PCMMultichannel") + 1]; + strcpy(mp2opts[i], "PCMMultichannel"); + i++; + } + option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX", + "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, + mp2opts, NULL, true, this); options->push_back(option); pane->addOptionLine(option); + char **mp3opts = new char *[3]; + i = 0; + mp3opts[i] = new char[strlen("PCM") + 1]; + strcpy(mp3opts[i], "PCM"); + i++; + if (canpass_mp3) { + mp3opts[i] = new char[strlen("Passthrough") + 1]; + strcpy(mp3opts[i], "PassThrough"); + i++; + } + if (canpass_pcm_mch) { + mp3opts[i] = new char[strlen("PCMMultichannel") + 1]; + strcpy(mp3opts[i], "PCMMultichannel"); + i++; + } + option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX", + "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts, + NULL, true, this); + options->push_back(option); + pane->addOptionLine(option);*/ + // Comment unsupported modes out - char **ac3opts=new char *[3]; - int i=0; - ac3opts[i]=new char[strlen("PCM")+1]; - strcpy(ac3opts[i],"PCM"); - i++; - if (canpass_ac3) { - ac3opts[i]=new char[strlen("Passthrough")+1]; - strcpy(ac3opts[i],"PassThrough"); - i++; - } - if (canpass_pcm_mch) { - ac3opts[i]=new char[strlen("PCMMultichannel")+1]; - strcpy(ac3opts[i],"PCMMultichannel"); - i++; - } - option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this); - options->push_back(option); - pane->addOptionLine(option); - - /* char **aacopts = new char *[3]; - i = 0; - aacopts[i] = new char[strlen("PCM") + 1]; - strcpy(mp2opts[i], "PCM"); - i++; - if (canpass_aac) { - aacopts[i] = new char[strlen("Passthrough") + 1]; - strcpy(aacopts[i], "PassThrough"); - i++; - } - if (canpass_pcm_mch) { - aacopts[i] = new char[strlen("PCMMultichannel") + 1]; - strcpy(aacopts[i], "PCMMultichannel"); - i++; - } - option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX", - "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0, - aacopts, NULL, true, this); - options->push_back(option); - pane->addOptionLine(option); - - - char **mp2opts = new char *[3]; - i = 0; - mp2opts[i] = new char[strlen("PCM") + 1]; - strcpy(mp2opts[i], "PCM"); - i++; - if (canpass_mp2) { - mp2opts[i] = new char[strlen("Passthrough") + 1]; - strcpy(mp2opts[i], "PassThrough"); - i++; - } - if (canpass_pcm_mch) { - mp2opts[i] = new char[strlen("PCMMultichannel") + 1]; - strcpy(mp2opts[i], "PCMMultichannel"); - i++; - } - option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX", - "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, - mp2opts, NULL, true, this); - options->push_back(option); - pane->addOptionLine(option); - - char **mp3opts = new char *[3]; - i = 0; - mp3opts[i] = new char[strlen("PCM") + 1]; - strcpy(mp3opts[i], "PCM"); - i++; - if (canpass_mp3) { - mp3opts[i] = new char[strlen("Passthrough") + 1]; - strcpy(mp3opts[i], "PassThrough"); - i++; - } - if (canpass_pcm_mch) { - mp3opts[i] = new char[strlen("PCMMultichannel") + 1]; - strcpy(mp3opts[i], "PCMMultichannel"); - i++; - } - option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX", - "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts, - NULL, true, this); - options->push_back(option); - pane->addOptionLine(option);*/ - // Comment unsupported modes out - - - } + } - return true; + return true; } - OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /* hcomp */, OMX_IN OMX_PTR /* appdata */, OMX_IN OMX_BUFFERHEADERTYPE* buffer) { //LogNT::getInstance()->info(TAG, "EmptyBufferDone"); @@ -534,7 +612,7 @@ int AudioOMX::setStreamType(u1 /* type */) { if (!initted) return 0; - // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0; + // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0; return 1; } @@ -542,7 +620,7 @@ int AudioOMX::setChannel() { if (!initted) return 0; - // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0; + // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0; return 1; } @@ -550,7 +628,7 @@ int AudioOMX::setSource() { if (!initted) return 0; - // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0; + // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0; return 1; } @@ -558,898 +636,967 @@ int AudioOMX::sync() { if (!initted) return 0; - // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0; + // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0; return 1; } -int AudioOMX::play() { - if (!initted) - return 0; - lastAType=MPTYPE_MPEG_AUDIO; - LogNT::getInstance()->debug(TAG, "enter play"); +int AudioOMX::play() +{ + if (!initted) return 0; - static_cast(Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary + lastAType = MPTYPE_MPEG_AUDIO; + LogNT::getInstance()->debug(TAG, "enter play"); - if (!AllocateCodecsOMX()) { - return 0; - } - return 1; -} + static_cast(Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary + if (!AllocateCodecsOMX()) + { + return 0; + } + + return 1; +} int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked { - OMX_ERRORTYPE error; - const char * destinations[]={"local","hdmi"}; - int dest=0; - if (hdmi) dest=1; - else dest=0; - - OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest; - memset(&auddest,0,sizeof(auddest)); - auddest.nSize=sizeof(auddest); - auddest.nVersion.nVersion=OMX_VERSION; - strcpy((char *)auddest.sName, destinations[dest]); - - LogNT::getInstance()->debug(TAG, "setting destination to: {}",auddest.sName); - error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Init OMX_IndexConfigBrcmAudioDestination failed {:#x} {:#x} {}", error,omx_aud_rend,auddest.sName); - DeAllocateCodecsOMX(); - return 0; - } - return 1; + OMX_ERRORTYPE error; + const char* destinations[] = {"local", "hdmi"}; + int dest = 0; + + if (hdmi) dest = 1; + else dest = 0; + + OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest; + memset(&auddest, 0, sizeof(auddest)); + auddest.nSize = sizeof(auddest); + auddest.nVersion.nVersion = OMX_VERSION; + strcpy((char*)auddest.sName, destinations[dest]); + LogNT::getInstance()->debug(TAG, "setting destination to: {}", auddest.sName); + error = OMX_SetConfig(omx_aud_rend, OMX_IndexConfigBrcmAudioDestination, &auddest); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Init OMX_IndexConfigBrcmAudioDestination failed {:#x} {:#x} {}", error, omx_aud_rend, auddest.sName); + DeAllocateCodecsOMX(); + return 0; + } + + return 1; } int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked { - OMX_ERRORTYPE error; - //Ok first fidle a working configuration - LogNT::getInstance()->debug(TAG, - "ChangeAudioPortConfig"); - - OMX_AUDIO_CODINGTYPE encoding; - if (hdmi) { - switch (lastAType) { - case MPTYPE_MPEG_AUDIO: { - if (prefered_mp2 == 2 && false) { //not supported yet - - } else { - if (prefered_mp2 == 1 && canpass_mp2) { - passthrough = true; - encoding=OMX_AUDIO_CodingMP3; - } else { - passthrough = false; - encoding=OMX_AUDIO_CodingPCM; - } - } - } - break; - case MPTYPE_AAC_LATM: { - if (prefered_aac == 2 && false) { //not supported yet - - } else { - LogNT::getInstance()->debug(TAG, - "ChangeAudioPortConfig debug {} {}",prefered_aac,canpass_aac); - if (prefered_aac == 1 && canpass_aac) { - passthrough = true; - encoding=OMX_AUDIO_CodingAAC; - } else { - passthrough = false; - encoding=OMX_AUDIO_CodingPCM; - } - } - } - break; - case MPTYPE_AC3_PRE13: - case MPTYPE_AC3: { - if (prefered_ac3 == 2 && false) { //not supported yet - - } else { - LogNT::getInstance()->debug(TAG, - "ChangeAudioPortConfig debug {} {}",prefered_ac3,canpass_ac3); - if (prefered_ac3 == 1 && canpass_ac3) { - passthrough = true; - encoding=OMX_AUDIO_CodingDDP; - } else { - passthrough = false; - encoding=OMX_AUDIO_CodingPCM; - } - } - } - break; - case MPTYPE_MPEG_AUDIO_LAYER3: { - if (prefered_mp3 == 2 && false) { //not supported yet - - } else { - if (prefered_mp3 == 1 && canpass_mp2) { - passthrough = true; - encoding=OMX_AUDIO_CodingMP3; - } else { - passthrough = false; - encoding=OMX_AUDIO_CodingPCM; - } - } - } - break; - }; - } else { - passthrough=false; - encoding=OMX_AUDIO_CodingPCM; - //mch=false; // multichannel also false - } - - - - /*OMX_CONFIG_BOOLEANTYPE booly; - memset(&booly, 0, sizeof(booly)); - booly.nSize = sizeof(booly); - booly.nVersion.nVersion = OMX_VERSION; - if (passthrough) - booly.bEnabled = OMX_TRUE; - else - booly.bEnabled = OMX_FALSE; - - error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough, - &booly); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX_IndexParamBrcmDecoderPassThrough failed {:#x}", error); - DeAllocateCodecsOMX(); - return 0; - }*/ - VideoOMX* video = static_cast(Video::getInstance()); - if (disport) { - video->DisablePort(omx_aud_rend,omx_rend_input_port,false); - //DestroyInputBufsOMXwhilePlaying(); - //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port); - - } - - - OMX_AUDIO_PARAM_PORTFORMATTYPE format; - memset(&format, 0, sizeof(format)); - format.nSize = sizeof(format); - format.nVersion.nVersion = OMX_VERSION; - format.nPortIndex = omx_rend_input_port; - error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, - &format); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Get OMX_IndexParamAudioPortFormat failed {:#x} {}", error, - omx_rend_input_port); - return 0; - } - if (disport) - - LogNT::getInstance()->debug(TAG, - "Get OMX_IndexParamAudioPortFormat returned {}",format.eEncoding ); - format.eEncoding = encoding; - - error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, - &format); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexParamAudioPortFormat failed {:#x} {} {}", error, - omx_rend_input_port,format.eEncoding ); - //return 0; - } - - switch (encoding) { - case OMX_AUDIO_CodingPCM: { - OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm; - memset(&audio_pcm, 0, sizeof(audio_pcm)); - audio_pcm.nSize = sizeof(audio_pcm); - audio_pcm.nVersion.nVersion = OMX_VERSION; - audio_pcm.nChannels = 2; - audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; - audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; - //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax; - audio_pcm.eNumData = OMX_NumericalDataSigned; - audio_pcm.eEndian = OMX_EndianLittle; - audio_pcm.bInterleaved = OMX_TRUE; - audio_pcm.nBitPerSample = 16; - audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; - audio_pcm.nChannels = 2; - audio_pcm.nSamplingRate = 48000; - audio_pcm.nPortIndex = omx_rend_input_port; - error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm, - &audio_pcm); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX_IndexParamAudioPcm failed {:#x} {}", error, - omx_rend_input_port); - return 0; - } - } break; - case OMX_AUDIO_CodingDDP: { - OMX_AUDIO_PARAM_DDPTYPE audio_ddp; - memset(&audio_ddp, 0, sizeof(audio_ddp)); - audio_ddp.nSize = sizeof(audio_ddp); - audio_ddp.nVersion.nVersion = OMX_VERSION; - audio_ddp.nPortIndex = omx_rend_input_port; - audio_ddp.nChannels = 8; //unknown - audio_ddp.nBitRate=0; - audio_ddp.nSampleRate=48000; - audio_ddp.eChannelMapping[0] =OMX_AUDIO_ChannelLF; - audio_ddp.eChannelMapping[1] =OMX_AUDIO_ChannelRF; - audio_ddp.eChannelMapping[2] =OMX_AUDIO_ChannelCF; - audio_ddp.eChannelMapping[3] =OMX_AUDIO_ChannelLFE; - audio_ddp.eChannelMapping[4] =OMX_AUDIO_ChannelLR; - audio_ddp.eChannelMapping[5] =OMX_AUDIO_ChannelRR; - audio_ddp.eChannelMapping[6] =OMX_AUDIO_ChannelLS; - audio_ddp.eChannelMapping[7] =OMX_AUDIO_ChannelRS; - audio_ddp.eChannelMapping[8] =OMX_AUDIO_ChannelCS; - error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp, - &audio_ddp); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX_IndexParamAudioDdp failed {:#x} {}", error, - omx_rend_input_port); - return 0; - } - - } break; - default: break; //Make compiler happy - }; - - - - if (disport) { - - //PrepareInputBufsOMX(false); - video->EnablePort(omx_aud_rend,omx_rend_input_port,false); - } - - - - return 1; + OMX_ERRORTYPE error; + //Ok first fidle a working configuration + LogNT::getInstance()->debug(TAG, "ChangeAudioPortConfig"); + + OMX_AUDIO_CODINGTYPE encoding; + + if (hdmi) + { + switch (lastAType) + { + case MPTYPE_MPEG_AUDIO: + { + if (prefered_mp2 == 2 && false) //not supported yet + { + + } + else + { + if (prefered_mp2 == 1 && canpass_mp2) + { + passthrough = true; + encoding = OMX_AUDIO_CodingMP3; + } + else + { + passthrough = false; + encoding = OMX_AUDIO_CodingPCM; + } + } + } + break; + + case MPTYPE_AAC_LATM: + { + if (prefered_aac == 2 && false) //not supported yet + { + + } + else + { + LogNT::getInstance()->debug(TAG, "ChangeAudioPortConfig debug {} {}", prefered_aac, canpass_aac); + + if (prefered_aac == 1 && canpass_aac) + { + passthrough = true; + encoding = OMX_AUDIO_CodingAAC; + } + else + { + passthrough = false; + encoding = OMX_AUDIO_CodingPCM; + } + } + } + break; + + case MPTYPE_AC3_PRE13: + case MPTYPE_AC3: + { + if (prefered_ac3 == 2 && false) //not supported yet + { + + } + else + { + LogNT::getInstance()->debug(TAG, "ChangeAudioPortConfig debug {} {}", prefered_ac3, canpass_ac3); + + if (prefered_ac3 == 1 && canpass_ac3) + { + passthrough = true; + encoding = OMX_AUDIO_CodingDDP; + } + else + { + passthrough = false; + encoding = OMX_AUDIO_CodingPCM; + } + } + } + break; + + case MPTYPE_MPEG_AUDIO_LAYER3: + { + if (prefered_mp3 == 2 && false) //not supported yet + { + + } + else + { + if (prefered_mp3 == 1 && canpass_mp2) + { + passthrough = true; + encoding = OMX_AUDIO_CodingMP3; + } + else + { + passthrough = false; + encoding = OMX_AUDIO_CodingPCM; + } + } + } + break; + }; + } + else + { + passthrough = false; + encoding = OMX_AUDIO_CodingPCM; + //mch=false; // multichannel also false + } + + /*OMX_CONFIG_BOOLEANTYPE booly; + memset(&booly, 0, sizeof(booly)); + booly.nSize = sizeof(booly); + booly.nVersion.nVersion = OMX_VERSION; + if (passthrough) + booly.bEnabled = OMX_TRUE; + else + booly.bEnabled = OMX_FALSE; + + error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough, + &booly); + if (error != OMX_ErrorNone) { + LogNT::getInstance()->debug(TAG, + "Init OMX_IndexParamBrcmDecoderPassThrough failed {:#x}", error); + DeAllocateCodecsOMX(); + return 0; + }*/ + VideoOMX* video = static_cast(Video::getInstance()); + + if (disport) + { + video->DisablePort(omx_aud_rend, omx_rend_input_port, false); + //DestroyInputBufsOMXwhilePlaying(); + //video->CommandFinished(omx_aud_rend,OMX_CommandPortDisable,omx_rend_input_port); + } + + + OMX_AUDIO_PARAM_PORTFORMATTYPE format; + memset(&format, 0, sizeof(format)); + format.nSize = sizeof(format); + format.nVersion.nVersion = OMX_VERSION; + format.nPortIndex = omx_rend_input_port; + error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, + &format); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Get OMX_IndexParamAudioPortFormat failed {:#x} {}", error, omx_rend_input_port); + return 0; + } + + if (disport) + + LogNT::getInstance()->debug(TAG, "Get OMX_IndexParamAudioPortFormat returned {}", format.eEncoding ); + + format.eEncoding = encoding; + + error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPortFormat, &format); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Set OMX_IndexParamAudioPortFormat failed {:#x} {} {}", error, omx_rend_input_port, format.eEncoding); + //return 0; + } + switch (encoding) + { + case OMX_AUDIO_CodingPCM: + { + OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm; + memset(&audio_pcm, 0, sizeof(audio_pcm)); + audio_pcm.nSize = sizeof(audio_pcm); + audio_pcm.nVersion.nVersion = OMX_VERSION; + audio_pcm.nChannels = 2; + audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF; + audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF; + //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax; + audio_pcm.eNumData = OMX_NumericalDataSigned; + audio_pcm.eEndian = OMX_EndianLittle; + audio_pcm.bInterleaved = OMX_TRUE; + audio_pcm.nBitPerSample = 16; + audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear; + audio_pcm.nChannels = 2; + audio_pcm.nSamplingRate = 48000; + audio_pcm.nPortIndex = omx_rend_input_port; + error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm, &audio_pcm); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Init OMX_IndexParamAudioPcm failed {:#x} {}", error, omx_rend_input_port); + return 0; + } + } + break; + + case OMX_AUDIO_CodingDDP: + { + OMX_AUDIO_PARAM_DDPTYPE audio_ddp; + memset(&audio_ddp, 0, sizeof(audio_ddp)); + audio_ddp.nSize = sizeof(audio_ddp); + audio_ddp.nVersion.nVersion = OMX_VERSION; + audio_ddp.nPortIndex = omx_rend_input_port; + audio_ddp.nChannels = 8; //unknown + audio_ddp.nBitRate = 0; + audio_ddp.nSampleRate = 48000; + audio_ddp.eChannelMapping[0] = OMX_AUDIO_ChannelLF; + audio_ddp.eChannelMapping[1] = OMX_AUDIO_ChannelRF; + audio_ddp.eChannelMapping[2] = OMX_AUDIO_ChannelCF; + audio_ddp.eChannelMapping[3] = OMX_AUDIO_ChannelLFE; + audio_ddp.eChannelMapping[4] = OMX_AUDIO_ChannelLR; + audio_ddp.eChannelMapping[5] = OMX_AUDIO_ChannelRR; + audio_ddp.eChannelMapping[6] = OMX_AUDIO_ChannelLS; + audio_ddp.eChannelMapping[7] = OMX_AUDIO_ChannelRS; + audio_ddp.eChannelMapping[8] = OMX_AUDIO_ChannelCS; + error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioDdp, &audio_ddp); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, + "Init OMX_IndexParamAudioDdp failed {:#x} {}", error, + omx_rend_input_port); + return 0; + } + } + break; + + default: break; //Make compiler happy + }; + + if (disport) + { + + //PrepareInputBufsOMX(false); + video->EnablePort(omx_aud_rend, omx_rend_input_port, false); + } + + return 1; } + int AudioOMX::InitDecoderLibAV() { - libav_mutex.lock(); - ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav); - if (!ac3codec_context_libav) { - LogNT::getInstance()->debug(TAG, "Alloc avcodec for ac3 decoding context failed!"); - return 0; - } + libav_mutex.lock(); + ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav); + + if (!ac3codec_context_libav) + { + LogNT::getInstance()->debug(TAG, "Alloc avcodec for ac3 decoding context failed!"); + return 0; + } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1) - ac3codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED; + ac3codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED; #else - ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED; + ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED; #endif #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101) - ac3codec_context_libav->request_channel_layout=2; + ac3codec_context_libav->request_channel_layout = 2; #else - ac3codec_context_libav->request_channels=2; + ac3codec_context_libav->request_channels = 2; #endif - int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL); - if (avc_ret < 0) { - LogNT::getInstance()->debug(TAG, "Opening libav codec failed"); - libav_mutex.unlock(); - return 0; - } + int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL); + + if (avc_ret < 0) + { + LogNT::getInstance()->debug(TAG, "Opening libav codec failed"); + libav_mutex.unlock(); + return 0; + } + + aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav); - aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav); - if (!aaclatmcodec_context_libav) { - LogNT::getInstance()->debug(TAG, "Alloc avcodec for aac decoding context failed!"); - return 0; - } + if (!aaclatmcodec_context_libav) + { + LogNT::getInstance()->debug(TAG, "Alloc avcodec for aac decoding context failed!"); + return 0; + } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1) - aaclatmcodec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED; + aaclatmcodec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED; #else - aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED; + aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED; #endif #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101) - aaclatmcodec_context_libav->request_channel_layout=2; + aaclatmcodec_context_libav->request_channel_layout = 2; #else - aaclatmcodec_context_libav->request_channels=2; + aaclatmcodec_context_libav->request_channels = 2; #endif - avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL); - if (avc_ret < 0) { - LogNT::getInstance()->debug(TAG, "Opening libav codec failed"); - libav_mutex.unlock(); - return 0; - } + avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL); + + if (avc_ret < 0) + { + LogNT::getInstance()->debug(TAG, "Opening libav codec failed"); + libav_mutex.unlock(); + return 0; + } + mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav); - mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav); - if (!ac3codec_context_libav) { - LogNT::getInstance()->debug(TAG, "Alloc avcodec for mp23 decoding context failed!"); - libav_mutex.unlock(); - return 0; - } + if (!ac3codec_context_libav) + { + LogNT::getInstance()->debug(TAG, "Alloc avcodec for mp23 decoding context failed!"); + libav_mutex.unlock(); + return 0; + } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 1) - mp23codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED; + mp23codec_context_libav->flags |= AV_CODEC_FLAG_TRUNCATED; #else - mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED; + mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED; #endif #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101) - mp23codec_context_libav->request_channel_layout=2; + mp23codec_context_libav->request_channel_layout = 2; #else - mp23codec_context_libav->request_channels=2; + mp23codec_context_libav->request_channels = 2; #endif - avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL); - if (avc_ret < 0) { - LogNT::getInstance()->debug(TAG, "Opening libav codec failed"); - libav_mutex.unlock(); - return 0; - } + avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL); - resam_con_libav = swr_alloc(); - if (resam_con_libav == NULL) { - LogNT::getInstance()->debug(TAG, - "Alloc resample context failed"); - return 0; - } + if (avc_ret < 0) + { + LogNT::getInstance()->debug(TAG, "Opening libav codec failed"); + libav_mutex.unlock(); + return 0; + } - av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format - av_opt_set_int(resam_con_libav, "out_sample_rate",48000,0); - av_opt_set_int(resam_con_libav, "out_sample_fmt",AV_SAMPLE_FMT_S16,0); - av_opt_set_int(resam_con_libav, "matrix_encoding",AV_MATRIX_ENCODING_DPLII,0); + resam_con_libav = swr_alloc(); + + if (resam_con_libav == NULL) + { + LogNT::getInstance()->debug(TAG, "Alloc resample context failed"); + return 0; + } - av_opt_set_int(resam_con_libav, "in_sample_rate",48000,0); - av_opt_set_int(resam_con_libav, "in_sample_fmt",AV_SAMPLE_FMT_S16,0); - av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example + av_opt_set_int(resam_con_libav, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); // our standard format + av_opt_set_int(resam_con_libav, "out_sample_rate", 48000, 0); + av_opt_set_int(resam_con_libav, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + av_opt_set_int(resam_con_libav, "matrix_encoding", AV_MATRIX_ENCODING_DPLII, 0); + av_opt_set_int(resam_con_libav, "in_sample_rate", 48000, 0); + av_opt_set_int(resam_con_libav, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); + av_opt_set_int(resam_con_libav, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); //just an example - av_init_packet(&incoming_paket_libav); + av_init_packet(&incoming_paket_libav); #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101) - decode_frame_libav=av_frame_alloc(); + decode_frame_libav = av_frame_alloc(); #else - decode_frame_libav=avcodec_alloc_frame(); + decode_frame_libav = avcodec_alloc_frame(); #endif - libav_mutex.unlock(); - decompress_buffer_filled=0; - + libav_mutex.unlock(); + decompress_buffer_filled = 0; - - return 1; + return 1; } -void AudioOMX::DeinitDecoderLibAV() { - - - libav_mutex.lock(); - if (ac3codec_context_libav) { - avcodec_close(ac3codec_context_libav); - av_free(ac3codec_context_libav); - ac3codec_context_libav = NULL; - - avcodec_close(aaclatmcodec_context_libav); - av_free(aaclatmcodec_context_libav); - aaclatmcodec_context_libav = NULL; +void AudioOMX::DeinitDecoderLibAV() +{ + libav_mutex.lock(); - av_free(decode_frame_libav); + if (ac3codec_context_libav) + { + avcodec_close(ac3codec_context_libav); + av_free(ac3codec_context_libav); + ac3codec_context_libav = NULL; - avcodec_close(mp23codec_context_libav); - av_free(mp23codec_context_libav); - mp23codec_context_libav = NULL; + avcodec_close(aaclatmcodec_context_libav); + av_free(aaclatmcodec_context_libav); + aaclatmcodec_context_libav = NULL; - swr_free(&resam_con_libav); - resam_con_libav=NULL; + av_free(decode_frame_libav); + avcodec_close(mp23codec_context_libav); + av_free(mp23codec_context_libav); + mp23codec_context_libav = NULL; - } - libav_mutex.unlock(); + swr_free(&resam_con_libav); + resam_con_libav = NULL; + } + libav_mutex.unlock(); } - int AudioOMX::AllocateCodecsOMX() { - OMX_ERRORTYPE error; - static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX}; - - LogNT::getInstance()->info(TAG, "Allocate Codecs OMX"); - //Clock, move later to audio - VideoOMX* video = static_cast(Video::getInstance()); + OMX_ERRORTYPE error; + static OMX_CALLBACKTYPE callbacks = {&VideoOMX::EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX}; - if (!InitDecoderLibAV()) return 0;; + LogNT::getInstance()->info(TAG, "Allocate Codecs OMX"); + //Clock, move later to audio + VideoOMX* video = static_cast(Video::getInstance()); + if (!InitDecoderLibAV()) return 0;; - OMX_PORT_PARAM_TYPE p_param; - memset(&p_param,0,sizeof(p_param)); - p_param.nSize=sizeof(p_param); - p_param.nVersion.nVersion=OMX_VERSION; + OMX_PORT_PARAM_TYPE p_param; + memset(&p_param, 0, sizeof(p_param)); + p_param.nSize = sizeof(p_param); + p_param.nVersion.nVersion = OMX_VERSION; + if (!video->getClockAudioandInit(&omx_clock, &omx_clock_output_port)) + { + return 0;// get the clock and init it if necessary + } - if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){ - return 0;// get the clock and init it if necessary - } + /* TODO end */ + if (!video->idleClock()) + { + return 0; + } - /* TODO end */ - if (!video->idleClock()) { - return 0; - } - video->LockClock(); + video->LockClock(); - error = OMX_GetHandle(&omx_aud_rend, L_VPE_OMX_AUDIO_REND, NULL, &callbacks); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX audio rend failed {:#x}", error); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + error = OMX_GetHandle(&omx_aud_rend, L_VPE_OMX_AUDIO_REND, NULL, &callbacks); - if (!ChangeAudioDestination()) { - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Init OMX audio rend failed {:#x}", error); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX audio rend OMX_GetParameter failed {:#x}", error); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_rend_input_port = p_param.nStartPortNumber; + if (!ChangeAudioDestination()) + { + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Init OMX audio rend OMX_GetParameter failed {:#x}", error); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + omx_rend_input_port = p_param.nStartPortNumber; + error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param); - error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX aud rend OMX_GetParameter failed {:#x}", error); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } - // buggy return value - omx_rend_clock_port = p_param.nStartPortNumber; + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Init OMX aud rend OMX_GetParameter failed {:#x}", error); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + // buggy return value + omx_rend_clock_port = p_param.nStartPortNumber; -/* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks); + /* error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Init OMX audio decoder failed {:#x}", error); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + if (error!=OMX_ErrorNone){ + LogNT::getInstance()->debug(TAG, "Init OMX audio decoder failed {:#x}", error); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Init OMX audio decoder OMX_GetParameter failed {:#x}", error); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } - omx_codec_input_port=p_param.nStartPortNumber; - omx_codec_output_port=p_param.nStartPortNumber+1; + error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param); + if (error!=OMX_ErrorNone){ + LogNT::getInstance()->debug(TAG, "Init OMX audio decoder OMX_GetParameter failed {:#x}", error); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + omx_codec_input_port=p_param.nStartPortNumber; + omx_codec_output_port=p_param.nStartPortNumber+1; - if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) { - LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio decoder failed"); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - }*/ + if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) { + LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio decoder failed"); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + }*/ + if (!video->DisablePort(omx_aud_rend, omx_rend_input_port, true) ) + { + LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio rend failed {}", omx_rend_input_port); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) + { + LogNT::getInstance()->debug(TAG, + "Disable Ports OMX rend clock port failed {}", omx_rend_clock_port); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) { - LogNT::getInstance()->debug(TAG, "Disable Ports OMX audio rend failed {}",omx_rend_input_port); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } - if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) { - LogNT::getInstance()->debug(TAG, - "Disable Ports OMX rend clock port failed {}",omx_rend_clock_port); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + // Setup chain + error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, omx_aud_rend, omx_rend_clock_port); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel clock to rend failed {:#x} {} {}", error, omx_clock_output_port, omx_rend_clock_port); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + if (!video->EnablePort(omx_clock, omx_clock_output_port, false) || !video->EnablePort(omx_aud_rend, omx_rend_clock_port, false)) + { + LogNT::getInstance()->debug(TAG, "Enable Ports OMX clock rend failed"); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - //Setuo chain + if (!video->ChangeComponentState(omx_aud_rend, OMX_StateIdle)) + { + LogNT::getInstance()->debug(TAG, "aud_rend idle ChangeComponentState"); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + if (!video->CommandFinished(omx_aud_rend, OMX_CommandPortEnable, omx_rend_clock_port)) + { + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel clock to rend failed {:#x} {} {}", error,omx_clock_output_port,omx_rend_clock_port); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + if (!video->CommandFinished(omx_clock, OMX_CommandPortEnable, omx_clock_output_port)) + { + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false) - ) { - LogNT::getInstance()->debug(TAG, "Enable Ports OMX clock rend failed"); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + if (!ChangeAudioPortConfig(false)) + { + LogNT::getInstance()->info(TAG, "Change AudioPortConfig failed"); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } - if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) { - LogNT::getInstance()->debug(TAG, "aud_rend idle ChangeComponentState"); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) { + LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState"); + DeAllocateCodecsOMX(); + return 0; + }*/ + if (!PrepareInputBufsOMX(true)) + { + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port); + if (error!=OMX_ErrorNone){ + LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel dec to render failed {:#x}", error); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + }*/ + + /* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false) + ) { + LogNT::getInstance()->debug(TAG, "Enable Ports OMX codec rend failed"); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + }*/ + + /* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port) + || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) { + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + }*/ + + if (!video->ChangeComponentState(omx_aud_rend, OMX_StateExecuting)) + { + LogNT::getInstance()->debug(TAG, "omx_aud_rend ChangeComponentState Execute"); + video->UnlockClock(); + DeAllocateCodecsOMX(); + return 0; + } + video->UnlockClock(); + omx_running = true; + setVolume(volume); + doMuting(); + video->clockUnpause(); - if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) { - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + if (!video->setClockExecutingandRunning()) return 0; - if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) { - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + LogNT::getInstance()->info(TAG, "Allocate Codecs OMX finished"); + return 1; +} +int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex +{ + VideoOMX* video = static_cast(Video::getInstance()); + OMX_ERRORTYPE error; + OMX_PARAM_PORTDEFINITIONTYPE port_def_type; + memset(&port_def_type, 0, sizeof(port_def_type)); + port_def_type.nSize = sizeof(port_def_type); + port_def_type.nVersion.nVersion = OMX_VERSION; + port_def_type.nPortIndex = omx_rend_input_port; //omx_codec_input_port; - if (!ChangeAudioPortConfig(false)){ - LogNT::getInstance()->info(TAG, "Change AudioPortConfig failed"); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + error = OMX_GetParameter(omx_aud_rend/*dec*/, OMX_IndexParamPortDefinition, &port_def_type); -/* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) { - LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState"); - DeAllocateCodecsOMX(); - return 0; - }*/ + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error); + } + if (setportdef) + { + port_def_type.nBufferCountActual = 2; + port_def_type.nBufferSize = std::max(toi4(port_def_type.nBufferSize), 50000); // for transcoder important + error = OMX_SetParameter(omx_aud_rend/*dec*/, OMX_IndexParamPortDefinition, &port_def_type); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error); + } + } - if (!PrepareInputBufsOMX(true)) { - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + error = OMX_SendCommand(omx_aud_rend/*dec*/, OMX_CommandPortEnable, omx_rend_input_port/*codec*/, 0); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error); + return 0; + } + input_bufs_omx_mutex.lock(); + for (unsigned int i = 0; i < port_def_type.nBufferCountActual; i++) + { + OMX_BUFFERHEADERTYPE* buf_head = NULL; + error = OMX_AllocateBuffer(omx_aud_rend/*dec*/, &buf_head, omx_rend_input_port/*codec*/, NULL, port_def_type.nBufferSize); -/* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel dec to render failed {:#x}", error); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - }*/ + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error); + input_bufs_omx_mutex.unlock(); + return 0; + } + input_bufs_omx_all.push_back(buf_head); + input_bufs_omx_free.push_back(buf_head); + } + omx_first_frame = true; -/* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false) - ) { - LogNT::getInstance()->debug(TAG, "Enable Ports OMX codec rend failed"); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - }*/ + firstsynched = false; + cur_input_buf_omx = NULL; + input_bufs_omx_mutex.unlock(); -/* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port) - || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) { - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - }*/ + if (!video->CommandFinished(omx_aud_rend/*dec*/, OMX_CommandPortEnable, omx_rend_input_port /*codec*/)) + { + return 0; + } - if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) { - LogNT::getInstance()->debug(TAG, "omx_aud_rend ChangeComponentState Execute"); - video->UnlockClock(); - DeAllocateCodecsOMX(); - return 0; - } + return 1; +} +int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked +{ + OMX_ERRORTYPE error; - video->UnlockClock(); - omx_running=true; - setVolume(volume); - doMuting(); - video->clockUnpause(); + cur_input_buf_omx = NULL; + input_bufs_omx_mutex.lock(); + for (u4 i = 0; i < input_bufs_omx_all.size(); i++) + { + error = OMX_FreeBuffer(omx_aud_rend/*dec*/, omx_rend_input_port/*codec*/, input_bufs_omx_all[i]); - if (!video->setClockExecutingandRunning()) return 0; + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error); + input_bufs_omx_mutex.unlock(); + return 0; + } + } - LogNT::getInstance()->info(TAG, "Allocate Codecs OMX finished"); + input_bufs_omx_all.clear(); + input_bufs_omx_free.clear(); + input_bufs_omx_mutex.unlock(); - return 1; + return 1; } -int AudioOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex +int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked { - VideoOMX* video = static_cast(Video::getInstance()); - - OMX_ERRORTYPE error; - OMX_PARAM_PORTDEFINITIONTYPE port_def_type; - memset(&port_def_type,0,sizeof(port_def_type)); - port_def_type.nSize=sizeof(port_def_type); - port_def_type.nVersion.nVersion=OMX_VERSION; - port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port; - - error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type); - - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error); - } - - - if (setportdef) { - port_def_type.nBufferCountActual=2; - port_def_type.nBufferSize=std::max(toi4(port_def_type.nBufferSize),50000); // for transcoder important - - error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type); - - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error); - } - } - - - error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error); - return 0; - } - - input_bufs_omx_mutex.lock(); - for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) { - OMX_BUFFERHEADERTYPE *buf_head=NULL; - error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error); - input_bufs_omx_mutex.unlock(); - return 0; - } - input_bufs_omx_all.push_back(buf_head); - input_bufs_omx_free.push_back(buf_head); - } - omx_first_frame=true; - - firstsynched=false; - cur_input_buf_omx=NULL; - input_bufs_omx_mutex.unlock(); - - if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) { - return 0; - } - - return 1; -} + //OMX_ERRORTYPE error; -int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked -{ - OMX_ERRORTYPE error; - - cur_input_buf_omx=NULL; - input_bufs_omx_mutex.lock(); - for (u4 i=0; i< input_bufs_omx_all.size();i++) { - error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error); - input_bufs_omx_mutex.unlock(); - return 0; - } - - } - input_bufs_omx_all.clear(); - input_bufs_omx_free.clear(); - input_bufs_omx_mutex.unlock(); - - return 1; -} + cur_input_buf_omx = NULL; + input_bufs_omx_mutex.lock(); -int AudioOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked -{ - //OMX_ERRORTYPE error; - - cur_input_buf_omx=NULL; - input_bufs_omx_mutex.lock(); - while (input_bufs_omx_all.size()>0) { - if (input_bufs_omx_free.size()>0) { - // Destroy one buffer - std::vector::iterator itty=input_bufs_omx_all.begin(); - OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front(); - for (; itty!= input_bufs_omx_all.end();itty++) { - if ((*itty)==cur_buf) { - input_bufs_omx_all.erase(itty); - input_bufs_omx_free.pop_front(); - break; - } - } - } else { - input_bufs_omx_mutex.unlock(); - MILLISLEEP(5); - input_bufs_omx_mutex.lock(); - } - } - - LogNT::getInstance()->debug(TAG, "DestroyInputBufsOMXwhilePlaying {} {}", input_bufs_omx_all.size(),input_bufs_omx_free.size()); - input_bufs_omx_mutex.unlock(); - return 1; -} + while (input_bufs_omx_all.size() > 0) + { + if (input_bufs_omx_free.size() > 0) + { + // Destroy one buffer + std::vector::iterator itty = input_bufs_omx_all.begin(); + OMX_BUFFERHEADERTYPE* cur_buf = input_bufs_omx_free.front(); + + for (; itty != input_bufs_omx_all.end(); itty++) + { + if ((*itty) == cur_buf) + { + input_bufs_omx_all.erase(itty); + input_bufs_omx_free.pop_front(); + break; + } + } + } + else + { + input_bufs_omx_mutex.unlock(); + MILLISLEEP(5); + input_bufs_omx_mutex.lock(); + } + } + LogNT::getInstance()->debug(TAG, "DestroyInputBufsOMXwhilePlaying {} {}", input_bufs_omx_all.size(), input_bufs_omx_free.size()); + input_bufs_omx_mutex.unlock(); + return 1; +} int AudioOMX::DeAllocateCodecsOMX() { OMX_ERRORTYPE error; - omx_running=false; + omx_running = false; VideoOMX* video = static_cast(Video::getInstance()); LogNT::getInstance()->debug(TAG, "enter deallocatecodecsomx"); + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 1"); - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 1"); - if (cur_input_buf_omx) { - cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS; - error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx); - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 6 failed {:#x}", error); - } - - cur_input_buf_omx=NULL;//write out old data - } - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 2"); - - video->LockClock(); - if (omx_aud_rend/*dec*/) { - // first stop the omx elements - /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) { - LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState"); - }*/ - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 3"); - - video->UnlockClock(); - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 4"); - video->idleClock(); - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 5"); - video->LockClock(); - - if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) { - LogNT::getInstance()->debug(TAG, "aud_rend ChangeComponentState"); - } - - // TODO proper deinit sequence - // first flush all buffers - - error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL); - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error); - - } - - /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "OMX_Flush codec out failed {:#x}", error); + if (cur_input_buf_omx) + { + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_EOS; + error = video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); - }*/ + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 6 failed {:#x}", error); + } + cur_input_buf_omx = NULL; //write out old data + } - /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) { - LogNT::getInstance()->debug(TAG, "flush cmd codec input failed"); - }*/ + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 2"); + video->LockClock(); + if (omx_aud_rend/*dec*/) + { + // first stop the omx elements + /* if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) { + LogNT::getInstance()->debug(TAG, "aud_dec ChangeComponentState"); + }*/ + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 3"); + + video->UnlockClock(); + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 4"); + video->idleClock(); + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 5"); + video->LockClock(); + + if (!video->ChangeComponentState(omx_aud_rend, OMX_StateIdle)) + { + LogNT::getInstance()->debug(TAG, "aud_rend ChangeComponentState"); + } - error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "OMX_Flush clock out failed {:#x}", error); + // TODO proper deinit sequence + // first flush all buffers - } + error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush, omx_rend_input_port, NULL); - error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL); - if (error!=OMX_ErrorNone){ - LogNT::getInstance()->debug(TAG, "OMX_Flush rend clock failed {:#x}", error); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Flush rend in failed {:#x}", error); + } - } - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6"); + /* error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL); + if (error!=OMX_ErrorNone){ + LogNT::getInstance()->debug(TAG, "OMX_Flush codec out failed {:#x}", error); - if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) || - !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) { - LogNT::getInstance()->debug(TAG, "flush cmd clock shed failed"); - } + }*/ - DestroyInputBufsOMX(); //We have to make sure that no buffers are in use - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6a"); - DeinitDecoderLibAV(); - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 7"); - //todo flushing - if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) { - LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 1"); - } + /* if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) { + LogNT::getInstance()->debug(TAG, "flush cmd codec input failed"); + }*/ - /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) { - LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 6"); - } - if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) { - LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 7"); - }*/ + error = OMX_SendCommand(omx_clock, OMX_CommandFlush, omx_clock_output_port, NULL); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Flush clock out failed {:#x}", error); + } - if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) { - LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 4"); - } + error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush, omx_rend_clock_port, NULL); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Flush rend clock failed {:#x}", error); + } - if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) { - LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 5"); - } + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6"); + if (!video->CommandFinished(omx_clock, OMX_CommandFlush, omx_clock_output_port) || + !video->CommandFinished(omx_aud_rend, OMX_CommandFlush, omx_rend_clock_port)) + { + LogNT::getInstance()->debug(TAG, "flush cmd clock shed failed"); + } + DestroyInputBufsOMX(); //We have to make sure that no buffers are in use + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 6a"); + DeinitDecoderLibAV(); + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 7"); - /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL); - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + //todo flushing + if (!video->DisablePort(omx_aud_rend, omx_rend_input_port, true)) + { + LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 1"); + } - }*/ + /* if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) { + LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 6"); + } + if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) { + LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 7"); + }*/ - error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,0); - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + if (!video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) + { + LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 4"); + } - } + if (!video->DisablePort(omx_clock, omx_clock_output_port, true)) + { + LogNT::getInstance()->debug(TAG, "Disable Tunnel Port failed 5"); + } - error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0); - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + /* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL); + if (error!=OMX_ErrorNone) { + LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + }*/ - } + error = OMX_SetupTunnel(omx_aud_rend, omx_rend_input_port, NULL, 0); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,0); - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, NULL, 0); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } - } - LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 8"); + error = OMX_SetupTunnel(omx_aud_rend, omx_rend_clock_port, NULL, 0); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error); + } + LogNT::getInstance()->debug(TAG, "deallocatecodecsomx mark 8"); - //error=OMX_FreeHandle(omx_aud_dec); - error=OMX_FreeHandle(omx_aud_rend); - video->UnlockClock(); - video->destroyClock(); - omx_aud_rend/*dec*/=NULL; - if (error!=OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, "FreeHandle failed {}", error); - } - } else { + //error=OMX_FreeHandle(omx_aud_dec); + error = OMX_FreeHandle(omx_aud_rend); + video->UnlockClock(); + video->destroyClock(); + omx_aud_rend/*dec*/ = NULL; - video->UnlockClock(); - DeinitDecoderLibAV(); - } - LogNT::getInstance()->debug(TAG, "leave deallocate codecs OMX"); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "FreeHandle failed {}", error); + } + } + else + { + video->UnlockClock(); + DeinitDecoderLibAV(); + } - return 1; + LogNT::getInstance()->debug(TAG, "leave deallocate codecs OMX"); + return 1; } - - int AudioOMX::stop() { if (!initted) return 0; @@ -1460,35 +1607,37 @@ int AudioOMX::stop() return 1; } -int AudioOMX::mute() { - if (!initted) - return 0; - LogNT::getInstance()->debug(TAG, "MUTE MUTE MUTE"); - VideoOMX* vw = static_cast(Video::getInstance()); - vw->LockClock(); - if (omx_running) { - - OMX_AUDIO_CONFIG_MUTETYPE amute; - memset(&amute, 0, sizeof(amute)); - amute.nSize = sizeof(amute); - amute.nVersion.nVersion = OMX_VERSION; - amute.nPortIndex = omx_rend_input_port; - amute.bMute = OMX_TRUE; - OMX_ERRORTYPE error= OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute, - &amute); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigAudioMute failed {:#x} {}", error, - omx_rend_input_port); - vw->UnlockClock(); - return 0; - } - - } - vw->UnlockClock(); - - muted = 1; - return 1; +int AudioOMX::mute() +{ + if (!initted) return 0; + + LogNT::getInstance()->debug(TAG, "MUTE MUTE MUTE"); + VideoOMX* vw = static_cast(Video::getInstance()); + vw->LockClock(); + + if (omx_running) + { + OMX_AUDIO_CONFIG_MUTETYPE amute; + memset(&amute, 0, sizeof(amute)); + amute.nSize = sizeof(amute); + amute.nVersion.nVersion = OMX_VERSION; + amute.nPortIndex = omx_rend_input_port; + amute.bMute = OMX_TRUE; + OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute, &amute); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, + "Set OMX_IndexConfigAudioMute failed {:#x} {}", error, omx_rend_input_port); + vw->UnlockClock(); + return 0; + } + } + + vw->UnlockClock(); + + muted = 1; + return 1; } int AudioOMX::unMute() @@ -1498,26 +1647,26 @@ int AudioOMX::unMute() LogNT::getInstance()->debug(TAG, "MUTE OFF OFF OFF"); VideoOMX* vw = static_cast(Video::getInstance()); vw->LockClock(); - if (omx_running) { - - OMX_AUDIO_CONFIG_MUTETYPE amute; - memset(&amute, 0, sizeof(amute)); - amute.nSize = sizeof(amute); - amute.nVersion.nVersion = OMX_VERSION; - amute.nPortIndex = omx_rend_input_port; - amute.bMute = OMX_FALSE; - OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute, - &amute); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigAudioMute failed {:#x} {}", error, - omx_rend_input_port); - vw->UnlockClock(); - return 0; - } - } - vw->UnlockClock(); + if (omx_running) + { + OMX_AUDIO_CONFIG_MUTETYPE amute; + memset(&amute, 0, sizeof(amute)); + amute.nSize = sizeof(amute); + amute.nVersion.nVersion = OMX_VERSION; + amute.nPortIndex = omx_rend_input_port; + amute.bMute = OMX_FALSE; + OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioMute, &amute); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Set OMX_IndexConfigAudioMute failed {:#x} {}", error, omx_rend_input_port); + vw->UnlockClock(); + return 0; + } + } + + vw->UnlockClock(); muted = 0; return 1; @@ -1525,15 +1674,17 @@ int AudioOMX::unMute() int AudioOMX::pause() { - if (!initted) return 0; - VideoOMX* vw = static_cast(Video::getInstance()); - vw->clockPause(); - return 1; + if (!initted) return 0; + + VideoOMX* vw = static_cast(Video::getInstance()); + vw->clockPause(); + return 1; } int AudioOMX::unPause() { if (!initted) return 0; + VideoOMX* vw = static_cast(Video::getInstance()); vw->clockUnpause(); return 1; @@ -1542,13 +1693,14 @@ int AudioOMX::unPause() int AudioOMX::reset() { if (!initted) return 0; -//test(); + + //test(); LogNT::getInstance()->debug(TAG, "reset called"); DeAllocateCodecsOMX(); -// if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0; -// LogNT::getInstance()->debug(TAG, "reset back"); - // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0; + // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0; + // LogNT::getInstance()->debug(TAG, "reset back"); + // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0; doMuting(); return 1; @@ -1559,35 +1711,35 @@ int AudioOMX::setVolume(int tvolume) // parameter: 0 for silence, 20 for full if ((tvolume < 0) || (tvolume > 20)) return 0; -// volume = 2 * (20 - volume); -// Right, that one was rubbish... 0-10 were almost -// inaudible, 11-20 did what should have been done -// over the whole 0-20 range - volume=tvolume; + // volume = 2 * (20 - volume); + // Right, that one was rubbish... 0-10 were almost + // inaudible, 11-20 did what should have been done + // over the whole 0-20 range + volume = tvolume; VideoOMX* vw = static_cast(Video::getInstance()); vw->LockClock(); - if (omx_running) { - - OMX_AUDIO_CONFIG_VOLUMETYPE avol; - memset(&avol, 0, sizeof(avol)); - avol.nSize = sizeof(avol); - avol.nVersion.nVersion = OMX_VERSION; - avol.nPortIndex = omx_rend_input_port; - avol.bLinear=OMX_FALSE; - avol.sVolume.nValue =(volume-20)*200; - OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume, - &avol); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Set OMX_IndexConfigAudioVolume failed {:#x} {}", error, - omx_rend_input_port); - vw->UnlockClock(); - return 0; - } + if (omx_running) + { + OMX_AUDIO_CONFIG_VOLUMETYPE avol; + memset(&avol, 0, sizeof(avol)); + avol.nSize = sizeof(avol); + avol.nVersion.nVersion = OMX_VERSION; + avol.nPortIndex = omx_rend_input_port; + avol.bLinear = OMX_FALSE; + avol.sVolume.nValue = (volume - 20) * 200; + OMX_ERRORTYPE error = OMX_SetParameter(omx_aud_rend, OMX_IndexConfigAudioVolume, &avol); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Set OMX_IndexConfigAudioVolume failed {:#x} {}", error, omx_rend_input_port); + vw->UnlockClock(); + return 0; + } } + vw->UnlockClock(); return 1; @@ -1596,139 +1748,193 @@ int AudioOMX::setVolume(int tvolume) #ifdef DEV int AudioOMX::test() { -// u8 stc = 0; -// return ioctl(fdAudio, AV_SET_AUD_STC, &stc); + // u8 stc = 0; + // return ioctl(fdAudio, AV_SET_AUD_STC, &stc); -/* aud_sync_parms_t a; - a.parm1 = 0; - a.parm2 = 0; -*/ -// int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a); + /* aud_sync_parms_t a; + a.parm1 = 0; + a.parm2 = 0; + */ + // int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a); /*OK*/ //printf("Audio sync disable = %i\n", b); return 1; - - } #endif -unsigned int AudioOMX::AdvanceMpAudioSync(const u1 *data,unsigned int size,unsigned int *framesize) +unsigned int AudioOMX::AdvanceMpAudioSync(const u1* data, unsigned int size, unsigned int* framesize) { - if (size<=2) return size; // silly; - unsigned int atest=0; - *framesize=0; - //inspired by libav parsing code - while (atest+1 reserved - //sanity check inspired by libav - - - const int sample_rates[4]={44100,48000,32000,0}; - const short bitrate_tab[2][3][15] = { { { 0, 32, 64, 96, 128, 160, - 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48, - 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, { - 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, - 256, 320 } }, { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, - 160, 176, 192, 224, 256 }, { 0, 8, 16, 24, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 144, 160 }, { 0, 8, 16, 24, 32, 40, - 48, 56, 64, 80, 96, 112, 128, 144, 160 } } }; - int lsf=0; - int mpeg2=0; - int layer=4-((data[atest+1]&0x06)>>1); - if (layer==4) {atest++;continue;} //sanity check - - int bitrate_index=(data[atest+2]&0xf0)>>4; - if (bitrate_index==0x0f || bitrate_index==0x0) {atest++;continue;} //sanity check - - int samplerate_index=(data[atest+2]&0x0C)>>2; - if (samplerate_index==0x03) {atest++;continue;} //sanity check - - int padding=(data[atest+2]&2)>>1; - if (0x10 & data[atest+1]) { - lsf=((data[atest+1]) &0x8)?0:1; - mpeg2=0; - } else { - lsf=1; - mpeg2=1; - } - int sample_rate=sample_rates[ samplerate_index]>>(lsf+mpeg2); - int frame_size=0; - int temp_frame_size=bitrate_tab[lsf][layer - 1][bitrate_index]; - if (layer==1) { - frame_size=(temp_frame_size*12000)/sample_rate; - frame_size=(frame_size+padding)*4; - } else if (layer==2) { - frame_size=(temp_frame_size*144000)/sample_rate; - frame_size=frame_size+padding; - } else { - frame_size=(temp_frame_size*144000)/(sample_rate<debug(TAG, "FRAME: {} {} {} {} {} {} {}",lsf,layer,bitrate_index,sample_rate,padding,temp_frame_size, frame_size); - //LogNT::getInstance()->debug(TAG, "FRAME DIAG: {:#x} {:#x} {:#x} {}",data[atest],data[atest+1],data[atest+2],mp3sameheadercount); - - if (mp3sameheadercount>4) { - *framesize=frame_size; - return atest; // probably FrameSync - } //skip it if the header changes too frequently - } - atest++; - } - return size; + if (size <= 2) return size; // silly; + + unsigned int atest = 0; + *framesize = 0; + + //inspired by libav parsing code + while (atest + 1 < size) + { + if (data[atest] == 0xFF && (data[atest + 1] & 0xe0) == 0xe0) + { + if ((data[atest + 1] & 0x18) == 0x08) {atest++; continue;} //sanity check: mpeg version ID 01 -> reserved + + //sanity check inspired by libav + + + const int sample_rates[4] = {44100, 48000, 32000, 0}; + const short bitrate_tab[2][3][15] = { { { + 0, 32, 64, 96, 128, 160, + 192, 224, 256, 288, 320, 352, 384, 416, 448 + }, { + 0, 32, 48, + 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 + }, { + 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, + 256, 320 + } + }, { { + 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, + 160, 176, 192, 224, 256 + }, { + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 144, 160 + }, { + 0, 8, 16, 24, 32, 40, + 48, 56, 64, 80, 96, 112, 128, 144, 160 + } + } + }; + int lsf = 0; + int mpeg2 = 0; + int layer = 4 - ((data[atest + 1] & 0x06) >> 1); + + if (layer == 4) {atest++; continue;} //sanity check + + int bitrate_index = (data[atest + 2] & 0xf0) >> 4; + + if (bitrate_index == 0x0f || bitrate_index == 0x0) {atest++; continue;} //sanity check + + int samplerate_index = (data[atest + 2] & 0x0C) >> 2; + + if (samplerate_index == 0x03) {atest++; continue;} //sanity check + + int padding = (data[atest + 2] & 2) >> 1; + + if (0x10 & data[atest + 1]) + { + lsf = ((data[atest + 1]) & 0x8) ? 0 : 1; + mpeg2 = 0; + } + else + { + lsf = 1; + mpeg2 = 1; + } + + int sample_rate = sample_rates[ samplerate_index] >> (lsf + mpeg2); + int frame_size = 0; + int temp_frame_size = bitrate_tab[lsf][layer - 1][bitrate_index]; + + if (layer == 1) + { + frame_size = (temp_frame_size * 12000) / sample_rate; + frame_size = (frame_size + padding) * 4; + } + else if (layer == 2) + { + frame_size = (temp_frame_size * 144000) / sample_rate; + frame_size = frame_size + padding; + } + else + { + frame_size = (temp_frame_size * 144000) / (sample_rate << lsf); + frame_size = frame_size + padding; + } + + unsigned int sameheadertest = (data[atest] << 24) | (data[atest + 1] << 16) | (data[atest + 2] << 8); + const unsigned mask = (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)); // from libav + + if (!mp3sameheader) + { + mp3sameheader = sameheadertest; + mp3sameheadercount = 2; + } + + if ((mp3sameheader & mask) == (sameheadertest & mask)) mp3sameheadercount++; + else mp3sameheadercount = 0; + + mp3sameheader = sameheadertest; + + //LogNT::getInstance()->debug(TAG, "FRAME: {} {} {} {} {} {} {}",lsf,layer,bitrate_index,sample_rate,padding,temp_frame_size, frame_size); + //LogNT::getInstance()->debug(TAG, "FRAME DIAG: {:#x} {:#x} {:#x} {}",data[atest],data[atest+1],data[atest+2],mp3sameheadercount); + + if (mp3sameheadercount > 4) + { + *framesize = frame_size; + return atest; // probably FrameSync + } //skip it if the header changes too frequently + } + + atest++; + } + + return size; } -unsigned int AudioOMX::AdvanceAc3AudioSync(const u1 *data,unsigned int size,unsigned int *framesize) +unsigned int AudioOMX::AdvanceAc3AudioSync(const u1* data, unsigned int size, unsigned int* framesize) { - if (size<=4) return size; // silly; - const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128, - 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448, - 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152, - 1152, 1280, 1280, }; - unsigned int atest=0; - *framesize=20000; //if we do not find a start code do not decompress - while (atest+4>6; - unsigned char frmsize=(code &0x3f); - if (fscod!=0) LogNT::getInstance()->debug(TAG, "warning we only support 48 KHz sampling rate"); - *framesize=frm_size_tab[frmsize]*2; - return atest; // probably FrameSync - } - atest++; - } - return size; + if (size <= 4) return size; // silly; + + const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128, + 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448, + 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152, + 1152, 1280, 1280, + }; + unsigned int atest = 0; + *framesize = 20000; //if we do not find a start code do not decompress + + while (atest + 4 < size) + { + if (data[atest] == 0x0B && data[atest + 1] == 0x77) + { + // now figure out the length of the frame + unsigned char code = data[atest + 4]; + unsigned char fscod = (code & 0xC0) >> 6; + unsigned char frmsize = (code & 0x3f); + + if (fscod != 0) LogNT::getInstance()->debug(TAG, "warning we only support 48 KHz sampling rate"); + + *framesize = frm_size_tab[frmsize] * 2; + return atest; // probably FrameSync + } + + atest++; + } + + return size; } -unsigned int AudioOMX::AdvanceAacLatmAudioSync(const u1 *data,unsigned int size,unsigned int *framesize) +unsigned int AudioOMX::AdvanceAacLatmAudioSync(const u1* data, unsigned int size, unsigned int* framesize) { - if (size<=4) return size; // silly; - unsigned int atest=0; - *framesize=20000; //if we do not find a start code do not decompress - while (atest+4(Video::getInstance()); - video->LockClock(); - OMX_PARAM_U32TYPE audio_lat; - OMX_ERRORTYPE error; - memset(&audio_lat, 0, sizeof(audio_lat)); - audio_lat.nSize = sizeof(audio_lat); - audio_lat.nVersion.nVersion = OMX_VERSION; - audio_lat.nPortIndex = omx_rend_input_port; - - error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency, - &audio_lat); - video->UnlockClock(); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error, - omx_rend_input_port); - return pts; // no correction in case of error - } - /*LogNT::getInstance()->debug(TAG, "Current audio latency {}", - audio_lat.nU32);*/ - - long long workpts=0; - workpts+=addsamples; - workpts-=audio_lat.nU32; - workpts*=10LL*1000LL*1000LL; - workpts=workpts/((long long)srate); //one second /samplerate - workpts+=pts; - - return workpts; + VideoOMX* video = static_cast(Video::getInstance()); + video->LockClock(); + OMX_PARAM_U32TYPE audio_lat; + OMX_ERRORTYPE error; + memset(&audio_lat, 0, sizeof(audio_lat)); + audio_lat.nSize = sizeof(audio_lat); + audio_lat.nVersion.nVersion = OMX_VERSION; + audio_lat.nPortIndex = omx_rend_input_port; + + error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency, + &audio_lat); + video->UnlockClock(); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error, omx_rend_input_port); + return pts; // no correction in case of error + } + + /*LogNT::getInstance()->debug(TAG, "Current audio latency {}", + audio_lat.nU32);*/ + + long long workpts = 0; + workpts += addsamples; + workpts -= audio_lat.nU32; + workpts *= 10LL * 1000LL * 1000LL; + workpts = workpts / ((long long)srate); //one second /samplerate + workpts += pts; + + return workpts; } bool AudioOMX::DrainTargetBufferFull() { - //Check, if we have OMX output buffers - bool full; - input_bufs_omx_mutex.lock(); - full=(input_bufs_omx_free.size()==0); - input_bufs_omx_mutex.unlock(); - return full; - + //Check, if we have OMX output buffers + bool full; + input_bufs_omx_mutex.lock(); + full = (input_bufs_omx_free.size() == 0); + input_bufs_omx_mutex.unlock(); + return full; } +u4 AudioOMX::DeliverMediaPacket(MediaPacket mpacket, const u1* buffer, u4* samplepos) +{ + /*First Check, if we have an audio sample*/ + VideoOMX* vw = static_cast(Video::getInstance()); + bool achange = false; + OMX_ERRORTYPE error; -u4 AudioOMX::DeliverMediaPacket(MediaPacket mpacket, const u1* buffer, - u4 *samplepos) { - /*First Check, if we have an audio sample*/ - VideoOMX* vw = static_cast(Video::getInstance()); - bool achange=false; - OMX_ERRORTYPE error; - //Log *logger=Log::getInstance(); - if (vw->InIframemode()) { - samplepos = 0; - MILLISLEEP(10); - return 0; //Not in iframe mode! - } - - if (!omx_running) return 0; // if we are not runnig do not do this - if (vw->isClockPaused()) return 0; //Block if we pause - //LogNT::getInstance()->debug(TAG, "DMP mark 1"); - - //LogNT::getInstance()->debug(TAG, "DeliverMediaPacketOMX time {}",mpacket.presentation_time); - -/* if (mpacket.synched && mpacket.presentation_time <= 0) { - *samplepos = mpacket.length; - firstsynched = false; - lsync=true; - LogNT::getInstance()->debug(TAG, - "DeliverMediaPacketOMX Frameskip"); - return mpacket.length; - }*/ - - //LogNT::getInstance()->debug(TAG, "DMP mark 2"); - - u4 headerstrip = 0; - if (mpacket.disconti) { - firstsynched = false; - decompress_buffer_filled=0; - if (cur_input_buf_omx) { - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, - cur_input_buf_omx); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer 1 failed {:#x}", error); - } - cur_input_buf_omx = NULL; - } - lsync=true; - } - //LogNT::getInstance()->debug(TAG, "DMP mark 3"); - if (mpacket.type != lastAType) {//Format Change //Push data out ! - firstsynched = false; - achange=true; - mp3sameheader=0; - LogNT::getInstance()->debug(TAG,"Notice audio type change {} {}", mpacket.type,lastAType); - lastAType = mpacket.type; - decompress_buffer_filled=0; - - if (cur_input_buf_omx) { - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, - cur_input_buf_omx); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer 2 failed {:#x}", error); - } - cur_input_buf_omx = NULL; - } - - int oldcancelstate; - int oldcanceltype; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - vw->LockClock(); - if (!ChangeAudioPortConfig(true)) { - LogNT::getInstance()->debug(TAG, - "Changing audio port config failed", error); - } - vw->UnlockClock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - lsync=true; - - } - //LogNT::getInstance()->debug(TAG, "DMP mark 4"); - - /*Inspect PES-Header */ - if (*samplepos == 0 && mpacket.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader - headerstrip = buffer[mpacket.pos_buffer + 8] + 9; - if (mpacket.type == MPTYPE_AC3) - headerstrip += 4; //skip ac3 bytes - *samplepos += headerstrip; - if (mpacket.synched) { - if (cur_input_buf_omx) { - //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, - cur_input_buf_omx); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer 3 failed {:#x}", error); - } - //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); - - cur_input_buf_omx = NULL;//write out old data - } - firstsynched = true; - //decompress_buffer_filled=0; - } else { - if (!firstsynched) {// - *samplepos = mpacket.length;//if we have not processed at least one - decompress_buffer_filled=0; - //LogNT::getInstance()->debug(TAG, "DMP mark 5"); - return mpacket.length;//synched packet ignore it! - } - } - } - if (!cur_input_buf_omx) { - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size()==0) { - input_bufs_omx_mutex.unlock(); - //LogNT::getInstance()->debug(TAG, "DMP mark 6"); - //LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample"); - return 0; // we do not have a free media sample - - } - cur_input_buf_omx=input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen=0; - cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0); - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - } - //LogNT::getInstance()->debug(TAG, "DMP mark 7"); - - if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet - if (mpacket.synched) { - //LogNT::getInstance()->debug(TAG, - // "packet synched marker"); - - //lastreftimePTS=mpacket.pts; - if (omx_first_frame) { // TODO time - cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; - LogNT::getInstance()->debug(TAG, "Starttime"); - omx_first_frame = false; - } else { - cur_input_buf_omx->nFlags = 0; - //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; - } - lastreftimeOMX = mpacket.presentation_time; - //LogNT::getInstance()->debug(TAG, - // "Time code {} pts {} dts {}", lastreftimeOMX, mpacket.pts,mpacket.dts); - lastreftimePTS = mpacket.pts; - cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty; - } else { - // LogNT::getInstance()->debug(TAG, - // "packet NOT synched marker"); - cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; - cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); - - } - if (mpacket.disconti || achange) { - cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY; - //mp23codec_context_libav->frame_size=-1; - //ac3codec_context_libav->frame_size=-1; - } - - } - //LogNT::getInstance()->debug(TAG, "DMP mark 8"); - - if (*samplepos>mpacket.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more! - unsigned int haveToCopy=mpacket.length-*samplepos; - - if (passthrough) { - while (haveToCopy>0) { - //LogNT::getInstance()->debug(TAG, "DMP mark 9"); - if (lsync) { - unsigned int gotframesize=0; - int adv=0; - switch (mpacket.type) { - case MPTYPE_MPEG_AUDIO: - case MPTYPE_MPEG_AUDIO_LAYER3: { - adv = AdvanceMpAudioSync(buffer+mpacket.pos_buffer+*samplepos, - haveToCopy,&gotframesize); - } - break; - case MPTYPE_AC3: - case MPTYPE_AC3_PRE13: { - adv = AdvanceAc3AudioSync(buffer+mpacket.pos_buffer+*samplepos, - haveToCopy,&gotframesize); - } - break; - - case MPTYPE_AAC_LATM: { - adv = AdvanceAacLatmAudioSync(buffer+mpacket.pos_buffer+*samplepos, - haveToCopy,&gotframesize); - } - break; - }; - if (adv != (int)haveToCopy) { - lsync=false; - haveToCopy-=adv; - *samplepos+=adv; - } else { - *samplepos=mpacket.length; //no ac3 sync byte - //LogNT::getInstance()->debug(TAG, "DMP mark 10"); - return mpacket.length; - } - } - // so everything is fine now do a memcpy - int cancopy = std::min(haveToCopy, cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen); - memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, buffer + mpacket.pos_buffer + *samplepos, cancopy); - haveToCopy-=cancopy; - cur_input_buf_omx->nFilledLen+=cancopy; - *samplepos+=cancopy; - //LogNT::getInstance()->debug(TAG, "DMP mark 11"); - - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer 5 failed {:#x}", error); - } - cur_input_buf_omx=NULL; - if (haveToCopy>0) { - // get5 new buffer - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size()==0) { - input_bufs_omx_mutex.unlock(); - // LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample2"); - return *samplepos; // we do not have a free media sample - } - cur_input_buf_omx=input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen=0; - cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; - cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0); - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - } - //LogNT::getInstance()->debug(TAG, "DMP mark 12"); - - } - //LogNT::getInstance()->debug(TAG, "DMP mark 13"); - - } else { - int len; - int gotta; - int framesize=0; - int errcount=0; - - AVCodecContext *current_context; - switch (mpacket.type) { - case MPTYPE_MPEG_AUDIO: - case MPTYPE_MPEG_AUDIO_LAYER3: { - current_context = mp23codec_context_libav; - if (current_context->frame_size<0) framesize=1152; //Maximum framesize - else framesize=current_context->frame_size; - }break; - case MPTYPE_AAC_LATM: { - current_context = aaclatmcodec_context_libav; - } break; - case MPTYPE_AC3: - case MPTYPE_AC3_PRE13: { - current_context = ac3codec_context_libav; - }break; - }; - - if (decompress_buffer_filled) { // have a remaining paket - incoming_paket_libav.data =(uint8_t*) decompress_buffer; - memcpy(decompress_buffer+decompress_buffer_filled, - buffer+mpacket.pos_buffer+*samplepos, - std::min(haveToCopy,decompress_buffer_size-decompress_buffer_filled)); - incoming_paket_libav.size = decompress_buffer_filled - +std::min(haveToCopy,decompress_buffer_size-decompress_buffer_filled); - //LogNT::getInstance()->debug(TAG,"Use saved audio buffer {} {} {}",mpacket.type,decompress_buffer_filled,mpacket.synched); - } else { - incoming_paket_libav.data =(uint8_t*) buffer+mpacket.pos_buffer+*samplepos; - incoming_paket_libav.size = haveToCopy; - } - //LogNT::getInstance()->debug(TAG, "DMP mark 18"); - - while (haveToCopy> 0 && errcount<3) { - - //LogNT::getInstance()->debug(TAG,"libav in {} {}",framesize,current_context->frame_size); - //LogNT::getInstance()->debug(TAG, "libav in {} {}", - // framesize, current_context->frame_size); - - bool donotdecompress=false; - unsigned int gotframesize=0; - // if (!decompress_buffer_filled) { // only do this if no old data is present - int adv = 0; - switch (mpacket.type) { - case MPTYPE_MPEG_AUDIO: - case MPTYPE_MPEG_AUDIO_LAYER3: { - adv = AdvanceMpAudioSync(incoming_paket_libav.data, - incoming_paket_libav.size,&gotframesize); - } - break; - case MPTYPE_AC3: - case MPTYPE_AC3_PRE13: { - adv = AdvanceAc3AudioSync(incoming_paket_libav.data, - incoming_paket_libav.size,&gotframesize); - } - break; - case MPTYPE_AAC_LATM: { - adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data, - incoming_paket_libav.size,&gotframesize); - } - break; - }; - if (adv > 0 /*&& !decompress_buffer_filled*/) { - incoming_paket_libav.data += adv; - incoming_paket_libav.size-=adv; - haveToCopy -= adv; - *samplepos += adv; - /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy); - else*/ framesize=haveToCopy; - //LogNT::getInstance()->debug(TAG,"Advance by {} {} from {}",adv,mpacket.type,*samplepos ); - if (haveToCopy <= 0) { - // LogNT::getInstance()->debug(TAG,"No sync code in packet remove {}",mpacket.type); - *samplepos=mpacket.length; - return mpacket.length; - } - - - // } // - - if (gotframesize>0 && gotframesize>haveToCopy) { - donotdecompress=true; - errcount=100; // exit loop - } - // else LogNT::getInstance()->debug(TAG,"Loop run"); - } - //LogNT::getInstance()->debug(TAG, "DMP mark 19"); - if (!donotdecompress) { - int oldcancelstate; - int oldcanceltype; - pthread_testcancel(); - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); - libav_mutex.lock(); - if (!omx_running || !mp23codec_context_libav - || !ac3codec_context_libav) { - libav_mutex.unlock(); - return *samplepos; - } - libav_mutex.unlock(); - // LogNT::getInstance()->debug(TAG,"libav out"); - int save_size=incoming_paket_libav.size; - - if ((int)gotframesize <= incoming_paket_libav.size) { - if (gotframesize>0) incoming_paket_libav.size=gotframesize; - - // FIXME - // avcodec_decode_audio4 is deprecated - // DO_NOT_USE() works, but assumes all decoded data is returned - // in the first call to avcodec_receive_frame which is - // definitely bad code. - // This all needs reworking to handle this properly. - // Leaving DO_NOT_USE in the code in case we have to switch to it - len = avcodec_decode_audio4(current_context, decode_frame_libav, - &gotta, &incoming_paket_libav); - - //len = DO_NOT_USE(current_context, decode_frame_libav, - // &gotta, &incoming_paket_libav); - - } else { - //LogNT::getInstance()->debug(TAG, "FRAME:E {} {}",gotframesize,incoming_paket_libav.size); - gotta=0; - len=0; - } - //LogNT::getInstance()->debug(TAG, "FRAME:T {}",len); - incoming_paket_libav.size=save_size; - //LogNT::getInstance()->debug(TAG, "libav out1"); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); - pthread_testcancel(); - - } else { - gotta=0; - len=0; - } - //LogNT::getInstance()->debug(TAG, "libav out2"); - //LogNT::getInstance()->debug(TAG, "DMP mark 20"); - if (!omx_running) { - libav_mutex.unlock(); - return *samplepos; - } - - if (decompress_buffer_filled) { // reset to normal decoding - if (len>0) { - - // FIXME - - // len is int - // decompress_buffer_filled is unsigned int - // so if decompress_buffer_filled > len, len can go negative. - - // Why would you use a min function with one of the values hard coded to zero? - // If param1 is positive the result is always 0. - // If param1 is negative the result is always param1. - // However, badMinimumFunction is and always was: int badMinimumFunction(u4 a, int b) - // .. which takes param1 as unsigned. So whatever param1 is, the result is always 0. - - // A guess is that the intention was to try to calculate a positive result, but if - // for some reason len-decompress_buffer_filled < 0, return 0. - // But for that you would use a max() function... - - //haveToCopy -= badMinimumFunction(len - decompress_buffer_filled, 0); - //*samplepos += badMinimumFunction(len - decompress_buffer_filled, 0); - - int result = badMinimumFunction(len - decompress_buffer_filled, 0); - haveToCopy -= result; - *samplepos += result; - - abort(); // When does this run? - - - // len is always either 0 or the result of avcodec_decode_audio4(current_context, decode_frame_libav, &gotta, &incoming_paket_libav); - // the result of avcodec_decode_audio4 can be negative in case of error, but that is filtered out above - - // decompress_buffer_filled appears to be how much of the decompress buffer has already been written to. - // Presumably things can happen in multiple chunks. - - - //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy); - /*else*/ framesize=haveToCopy; - } - else - { - framesize=haveToCopy; - } - incoming_paket_libav.data =(uint8_t*) buffer+mpacket.pos_buffer+*samplepos; - errcount=0; - decompress_buffer_filled=0; - } else { - - if (len>0) { - incoming_paket_libav.data += len; - haveToCopy -= len; - *samplepos += len; - errcount=0; - /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy); - else*/framesize=haveToCopy; - } else { - errcount++; - framesize=haveToCopy; - } - } - //LogNT::getInstance()->debug(TAG, "DMP mark 21"); - - incoming_paket_libav.size =framesize; - if (gotta) { - //LogNT::getInstance()->debug(TAG, - // "Got a frame"); - - int dsize = av_samples_get_buffer_size(NULL, - /*current_context->channels*/2, decode_frame_libav->nb_samples, - AV_SAMPLE_FMT_S16, 1); - /* int dsize_in = av_samples_get_buffer_size(NULL, - current_context->channels, decode_frame_libav->nb_samples, - current_context->sample_fmt, 1); -- unused */ - //if (current_context->channels==1) dsize*=2; // we convert mono to stereo - if ((cur_input_buf_omx->nFilledLen + dsize) - > cur_input_buf_omx->nAllocLen ) { - // I doubt that this will ever happen - // LogNT::getInstance()->debug(TAG, - // "P 2 Time code {} pts {}", lastreftimeOMX, mpacket.pts); - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, - cur_input_buf_omx); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer 4 failed {:#x}", error); - } - cur_input_buf_omx = NULL; - - if (!cur_input_buf_omx) { - int count = 0; - while (count < 10 && omx_running) { - count++; - input_bufs_omx_mutex.lock(); - if (input_bufs_omx_free.size() == 0) { - input_bufs_omx_mutex.unlock(); - // LogNT::getInstance()->debug(TAG, - // "Deliver MediaPacket no free sample"); - MILLISLEEP(5); - //LogNT::getInstance()->debug(TAG, "DMP mark22"); - if (!omx_running) return *samplepos; - //LogNT::getInstance()->debug(TAG, "DMP mark 23"); - continue; - } - cur_input_buf_omx = input_bufs_omx_free.front(); - cur_input_buf_omx->nFilledLen = 0; - cur_input_buf_omx->nOffset = 0; - cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); - cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; - input_bufs_omx_free.pop_front(); - input_bufs_omx_mutex.unlock(); - break; - } - if (!cur_input_buf_omx) return *samplepos; - } - - } - - //LogNT::getInstance()->debug(TAG,"memcpy in {} {} {}" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen); - - - av_opt_set_int(resam_con_libav, "in_sample_rate",decode_frame_libav->sample_rate,0); - av_opt_set_int(resam_con_libav, "in_sample_fmt",decode_frame_libav->format,0); - av_opt_set_int(resam_con_libav, "in_channel_layout",decode_frame_libav->channel_layout, 0); - //LogNT::getInstance()->error(TAG, "AV resampledata {} {} {} {}",current_context->channels,current_context->sample_rate,current_context->sample_fmt,current_context->channel_layout); - //LogNT::getInstance()->error(TAG, "AV resampledata2 {} {} {}",decode_frame_libav->sample_rate,decode_frame_libav->format,decode_frame_libav->channel_layout); - - int ret = swr_init(resam_con_libav); - if (ret<0) { - LogNT::getInstance()->error(TAG, "Opening AV resample failed {}",ret); - } else { - uint8_t *output=cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen; -/* - * old docs: - avresample_convert ( AVAudioResampleContext * avr, - uint8_t ** output, - int out_plane_size, - int out_samples, - uint8_t *const * input, - int in_plane_size, - int in_samples - ) - - old call: - avresample_convert(resam_con_libav, - &output, dsize, decode_frame_libav->nb_samples, - decode_frame_libav->extended_data, decode_frame_libav->linesize[0], decode_frame_libav->nb_samples); - - new docs: - swr_convert ( struct SwrContext * s, - uint8_t ** out, - int out_count, - const uint8_t ** in, - int in_count - ) - new call: - */ - //LogNT::getInstance()->debug(TAG, "Calling swr_convert"); - - swr_convert(resam_con_libav, &output, decode_frame_libav->nb_samples, (const uint8_t**)decode_frame_libav->extended_data, decode_frame_libav->nb_samples); - - swr_close(resam_con_libav); - } - - //LogNT::getInstance()->debug(TAG,"memcpy out"); - cur_input_buf_omx->nFilledLen += dsize; - } else { - //LogNT::getInstance()->debug(TAG,"Incomplete mpeg frames in pes packet {} {}",incoming_paket_libav.size,mpacket.length); - /* uint8_t a1=incoming_paket_libav.data[0]; - uint8_t a2=incoming_paket_libav.data[1]; - uint8_t a3=incoming_paket_libav.data[2]; - uint8_t a4=incoming_paket_libav.data[3];*/ - // LogNT::getInstance()->debug(TAG,"Header {:#x} {:#x} {:#x} {:#x}",a1,a2, - // a3,a4); - } - - } - //LogNT::getInstance()->debug(TAG, "DMP mark 24"); - decompress_buffer_filled=0; - if (haveToCopy ) { - //LogNT::getInstance()->debug(TAG,"We can not decompress {} save for later {} {:#x} {:#x}",haveToCopy,mpacket.type,incoming_paket_libav.data,mpacket.pos_buffer); - memcpy(decompress_buffer,incoming_paket_libav.data, std::min(haveToCopy,decompress_buffer_size)); - - decompress_buffer_filled=std::min(haveToCopy,decompress_buffer_size); - - } - - if (cur_input_buf_omx->nFilledLen) { - //LogNT::getInstance()->debug(TAG, - // "P 3 Time code {} pts {}", lastreftimeOMX, mpacket.pts); - error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); - if (error != OMX_ErrorNone) { - LogNT::getInstance()->debug(TAG, - "OMX_EmptyThisBuffer 5 failed {:#x}", error); - } - //if (mpacket.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); - cur_input_buf_omx = NULL; - } - } - - - //LogNT::getInstance()->debug(TAG, "DMP mark 25"); - - *samplepos=mpacket.length; - return mpacket.length; + //Log *logger=Log::getInstance(); + if (vw->InIframemode()) + { + samplepos = 0; + MILLISLEEP(10); + return 0; //Not in iframe mode! + } + + if (!omx_running) return 0; // if we are not runnig do not do this + + if (vw->isClockPaused()) return 0; //Block if we pause + + //LogNT::getInstance()->debug(TAG, "DMP mark 1"); + + //LogNT::getInstance()->debug(TAG, "DeliverMediaPacketOMX time {}",mpacket.presentation_time); + + /* if (mpacket.synched && mpacket.presentation_time <= 0) { + *samplepos = mpacket.length; + firstsynched = false; + lsync=true; + LogNT::getInstance()->debug(TAG, + "DeliverMediaPacketOMX Frameskip"); + return mpacket.length; + }*/ + + //LogNT::getInstance()->debug(TAG, "DMP mark 2"); + + u4 headerstrip = 0; + + if (mpacket.disconti) + { + firstsynched = false; + decompress_buffer_filled = 0; + + if (cur_input_buf_omx) + { + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 1 failed {:#x}", error); + } + + cur_input_buf_omx = NULL; + } + + lsync = true; + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 3"); + if (mpacket.type != lastAType) //Format Change //Push data out ! + { + firstsynched = false; + achange = true; + mp3sameheader = 0; + LogNT::getInstance()->debug(TAG, "Notice audio type change {} {}", mpacket.type, lastAType); + lastAType = mpacket.type; + decompress_buffer_filled = 0; + + if (cur_input_buf_omx) + { + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, + cur_input_buf_omx); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 2 failed {:#x}", error); + } + + cur_input_buf_omx = NULL; + } + + int oldcancelstate; + int oldcanceltype; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + vw->LockClock(); + + if (!ChangeAudioPortConfig(true)) + { + LogNT::getInstance()->debug(TAG, "Changing audio port config failed", error); + } + + vw->UnlockClock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + lsync = true; + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 4"); + + /*Inspect PES-Header */ + if (*samplepos == 0 && mpacket.type != MPTYPE_MPEG_AUDIO_LAYER3) //stripheader + { + headerstrip = buffer[mpacket.pos_buffer + 8] + 9; + + if (mpacket.type == MPTYPE_AC3) + headerstrip += 4; //skip ac3 bytes + + *samplepos += headerstrip; + + if (mpacket.synched) + { + if (cur_input_buf_omx) + { + //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 3 failed {:#x}", error); + } + + //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); + + cur_input_buf_omx = NULL;//write out old data + } + + firstsynched = true; + //decompress_buffer_filled=0; + } + else + { + if (!firstsynched) // + { + *samplepos = mpacket.length;//if we have not processed at least one + decompress_buffer_filled = 0; + //LogNT::getInstance()->debug(TAG, "DMP mark 5"); + return mpacket.length;//synched packet ignore it! + } + } + } + + if (!cur_input_buf_omx) + { + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + //LogNT::getInstance()->debug(TAG, "DMP mark 6"); + //LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample"); + return 0; // we do not have a free media sample + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 7"); + + if (cur_input_buf_omx->nFilledLen == 0) //will only be changed on first packet + { + if (mpacket.synched) + { + //LogNT::getInstance()->debug(TAG, + // "packet synched marker"); + + //lastreftimePTS=mpacket.pts; + if (omx_first_frame) // TODO time + { + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME; + LogNT::getInstance()->debug(TAG, "Starttime"); + omx_first_frame = false; + } + else + { + cur_input_buf_omx->nFlags = 0; + //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; + } + + lastreftimeOMX = mpacket.presentation_time; + //LogNT::getInstance()->debug(TAG, + // "Time code {} pts {} dts {}", lastreftimeOMX, mpacket.pts,mpacket.dts); + lastreftimePTS = mpacket.pts; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX / 10LL); // the clock component is faulty; + } + else + { + // LogNT::getInstance()->debug(TAG, + // "packet NOT synched marker"); + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); + } + + if (mpacket.disconti || achange) + { + cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY; + //mp23codec_context_libav->frame_size=-1; + //ac3codec_context_libav->frame_size=-1; + } + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 8"); + if (*samplepos > mpacket.length) *samplepos = 0; //propably the thread got interrupted and sample is not valid any more! + + unsigned int haveToCopy = mpacket.length - *samplepos; + + if (passthrough) + { + while (haveToCopy > 0) + { + //LogNT::getInstance()->debug(TAG, "DMP mark 9"); + if (lsync) + { + unsigned int gotframesize = 0; + int adv = 0; + + switch (mpacket.type) + { + case MPTYPE_MPEG_AUDIO: + case MPTYPE_MPEG_AUDIO_LAYER3: + { + adv = AdvanceMpAudioSync(buffer + mpacket.pos_buffer + *samplepos, haveToCopy, &gotframesize); + } + break; + + case MPTYPE_AC3: + case MPTYPE_AC3_PRE13: + { + adv = AdvanceAc3AudioSync(buffer + mpacket.pos_buffer + *samplepos, haveToCopy, &gotframesize); + } + break; + + case MPTYPE_AAC_LATM: + { + adv = AdvanceAacLatmAudioSync(buffer + mpacket.pos_buffer + *samplepos, haveToCopy, &gotframesize); + } + break; + } + + if (adv != (int)haveToCopy) + { + lsync = false; + haveToCopy -= adv; + *samplepos += adv; + } + else + { + *samplepos = mpacket.length; //no ac3 sync byte + //LogNT::getInstance()->debug(TAG, "DMP mark 10"); + return mpacket.length; + } + } + + // so everything is fine now do a memcpy + int cancopy = std::min(haveToCopy, cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen); + memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, buffer + mpacket.pos_buffer + *samplepos, cancopy); + haveToCopy -= cancopy; + cur_input_buf_omx->nFilledLen += cancopy; + *samplepos += cancopy; + //LogNT::getInstance()->debug(TAG, "DMP mark 11"); + + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 5 failed {:#x}", error); + } + + cur_input_buf_omx = NULL; + + if (haveToCopy > 0) + { + // get5 new buffer + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + // LogNT::getInstance()->debug(TAG, "Deliver MediaPacket no free sample2"); + return *samplepos; // we do not have a free media sample + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 12"); + + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 13"); + + } + else + { + int len; + int gotta; + int framesize = 0; + int errcount = 0; + + AVCodecContext* current_context; + + switch (mpacket.type) + { + case MPTYPE_MPEG_AUDIO: + case MPTYPE_MPEG_AUDIO_LAYER3: + { + current_context = mp23codec_context_libav; + + if (current_context->frame_size < 0) framesize = 1152; //Maximum framesize + else framesize = current_context->frame_size; + } break; + + case MPTYPE_AAC_LATM: + { + current_context = aaclatmcodec_context_libav; + } break; + + case MPTYPE_AC3: + case MPTYPE_AC3_PRE13: + { + current_context = ac3codec_context_libav; + } break; + } + + if (decompress_buffer_filled) // have a remaining paket + { + incoming_paket_libav.data = (uint8_t*) decompress_buffer; + memcpy(decompress_buffer + decompress_buffer_filled, + buffer + mpacket.pos_buffer + *samplepos, + std::min(haveToCopy, decompress_buffer_size - decompress_buffer_filled)); + incoming_paket_libav.size = decompress_buffer_filled + + std::min(haveToCopy, decompress_buffer_size - decompress_buffer_filled); + //LogNT::getInstance()->debug(TAG,"Use saved audio buffer {} {} {}",mpacket.type,decompress_buffer_filled,mpacket.synched); + } + else + { + incoming_paket_libav.data = (uint8_t*) buffer + mpacket.pos_buffer + *samplepos; + incoming_paket_libav.size = haveToCopy; + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 18"); + + while (haveToCopy > 0 && errcount < 3) + { + //LogNT::getInstance()->debug(TAG,"libav in {} {}",framesize,current_context->frame_size); + //LogNT::getInstance()->debug(TAG, "libav in {} {}", + // framesize, current_context->frame_size); + + bool donotdecompress = false; + unsigned int gotframesize = 0; + // if (!decompress_buffer_filled) { // only do this if no old data is present + int adv = 0; + + switch (mpacket.type) + { + case MPTYPE_MPEG_AUDIO: + case MPTYPE_MPEG_AUDIO_LAYER3: + { + adv = AdvanceMpAudioSync(incoming_paket_libav.data, + incoming_paket_libav.size, &gotframesize); + } + break; + + case MPTYPE_AC3: + case MPTYPE_AC3_PRE13: + { + adv = AdvanceAc3AudioSync(incoming_paket_libav.data, + incoming_paket_libav.size, &gotframesize); + } + break; + + case MPTYPE_AAC_LATM: + { + adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data, + incoming_paket_libav.size, &gotframesize); + } + break; + } + + if (adv > 0 /*&& !decompress_buffer_filled*/) + { + incoming_paket_libav.data += adv; + incoming_paket_libav.size -= adv; + haveToCopy -= adv; + *samplepos += adv; + /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy); + else*/ framesize = haveToCopy; + + //LogNT::getInstance()->debug(TAG,"Advance by {} {} from {}",adv,mpacket.type,*samplepos ); + if (haveToCopy <= 0) + { + // LogNT::getInstance()->debug(TAG,"No sync code in packet remove {}",mpacket.type); + *samplepos = mpacket.length; + return mpacket.length; + } + + // } // + + if (gotframesize > 0 && gotframesize > haveToCopy) + { + donotdecompress = true; + errcount = 100; // exit loop + } + + // else LogNT::getInstance()->debug(TAG,"Loop run"); + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 19"); + if (!donotdecompress) + { + int oldcancelstate; + int oldcanceltype; + pthread_testcancel(); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + libav_mutex.lock(); + + if (!omx_running || !mp23codec_context_libav + || !ac3codec_context_libav) + { + libav_mutex.unlock(); + return *samplepos; + } + + libav_mutex.unlock(); + // LogNT::getInstance()->debug(TAG,"libav out"); + int save_size = incoming_paket_libav.size; + + if ((int)gotframesize <= incoming_paket_libav.size) + { + if (gotframesize > 0) incoming_paket_libav.size = gotframesize; + + // FIXME + // avcodec_decode_audio4 is deprecated + // DO_NOT_USE() works, but assumes all decoded data is returned + // in the first call to avcodec_receive_frame which is + // definitely bad code. + // This all needs reworking to handle this properly. + // Leaving DO_NOT_USE in the code in case we have to switch to it + len = avcodec_decode_audio4(current_context, decode_frame_libav, + &gotta, &incoming_paket_libav); + + //len = DO_NOT_USE(current_context, decode_frame_libav, + // &gotta, &incoming_paket_libav); + + } + else + { + //LogNT::getInstance()->debug(TAG, "FRAME:E {} {}",gotframesize,incoming_paket_libav.size); + gotta = 0; + len = 0; + } + + //LogNT::getInstance()->debug(TAG, "FRAME:T {}",len); + incoming_paket_libav.size = save_size; + //LogNT::getInstance()->debug(TAG, "libav out1"); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + pthread_testcancel(); + + } + else + { + gotta = 0; + len = 0; + } + + //LogNT::getInstance()->debug(TAG, "libav out2"); + //LogNT::getInstance()->debug(TAG, "DMP mark 20"); + if (!omx_running) + { + libav_mutex.unlock(); + return *samplepos; + } + + if (decompress_buffer_filled) // reset to normal decoding + { + if (len > 0) + { + // FIXME + + // len is int + // decompress_buffer_filled is unsigned int + // so if decompress_buffer_filled > len, len can go negative. + + // Why would you use a min function with one of the values hard coded to zero? + // If param1 is positive the result is always 0. + // If param1 is negative the result is always param1. + // However, badMinimumFunction is and always was: int badMinimumFunction(u4 a, int b) + // .. which takes param1 as unsigned. So whatever param1 is, the result is always 0. + + // A guess is that the intention was to try to calculate a positive result, but if + // for some reason len-decompress_buffer_filled < 0, return 0. + // But for that you would use a max() function... + + //haveToCopy -= badMinimumFunction(len - decompress_buffer_filled, 0); + //*samplepos += badMinimumFunction(len - decompress_buffer_filled, 0); + + int result = badMinimumFunction(len - decompress_buffer_filled, 0); + haveToCopy -= result; + *samplepos += result; + + abort(); // When does this run? + + + // len is always either 0 or the result of avcodec_decode_audio4(current_context, decode_frame_libav, &gotta, &incoming_paket_libav); + // the result of avcodec_decode_audio4 can be negative in case of error, but that is filtered out above + + // decompress_buffer_filled appears to be how much of the decompress buffer has already been written to. + // Presumably things can happen in multiple chunks. + + + //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy); + /*else*/ framesize = haveToCopy; + } + else + { + framesize = haveToCopy; + } + + incoming_paket_libav.data = (uint8_t*) buffer + mpacket.pos_buffer + *samplepos; + errcount = 0; + decompress_buffer_filled = 0; + } + else + { + if (len > 0) + { + incoming_paket_libav.data += len; + haveToCopy -= len; + *samplepos += len; + errcount = 0; + /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy); + else*/framesize = haveToCopy; + } + else + { + errcount++; + framesize = haveToCopy; + } + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 21"); + + incoming_paket_libav.size = framesize; + + if (gotta) + { + //LogNT::getInstance()->debug(TAG, + // "Got a frame"); + + int dsize = av_samples_get_buffer_size(NULL, + /*current_context->channels*/2, decode_frame_libav->nb_samples, + AV_SAMPLE_FMT_S16, 1); + + /* int dsize_in = av_samples_get_buffer_size(NULL, + current_context->channels, decode_frame_libav->nb_samples, + current_context->sample_fmt, 1); -- unused */ + //if (current_context->channels==1) dsize*=2; // we convert mono to stereo + if ((cur_input_buf_omx->nFilledLen + dsize) > cur_input_buf_omx->nAllocLen) + { + // I doubt that this will ever happen + // LogNT::getInstance()->debug(TAG, + // "P 2 Time code {} pts {}", lastreftimeOMX, mpacket.pts); + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 4 failed {:#x}", error); + } + + cur_input_buf_omx = NULL; + + if (!cur_input_buf_omx) + { + int count = 0; + + while (count < 10 && omx_running) + { + count++; + input_bufs_omx_mutex.lock(); + + if (input_bufs_omx_free.size() == 0) + { + input_bufs_omx_mutex.unlock(); + // LogNT::getInstance()->debug(TAG, + // "Deliver MediaPacket no free sample"); + MILLISLEEP(5); + + //LogNT::getInstance()->debug(TAG, "DMP mark22"); + if (!omx_running) return *samplepos; + + //LogNT::getInstance()->debug(TAG, "DMP mark 23"); + continue; + } + + cur_input_buf_omx = input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen = 0; + cur_input_buf_omx->nOffset = 0; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); + cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.unlock(); + break; + } + + if (!cur_input_buf_omx) return *samplepos; + } + } + + //LogNT::getInstance()->debug(TAG,"memcpy in {} {} {}" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen); + + + av_opt_set_int(resam_con_libav, "in_sample_rate", decode_frame_libav->sample_rate, 0); + av_opt_set_int(resam_con_libav, "in_sample_fmt", decode_frame_libav->format, 0); + av_opt_set_int(resam_con_libav, "in_channel_layout", decode_frame_libav->channel_layout, 0); + //LogNT::getInstance()->error(TAG, "AV resampledata {} {} {} {}",current_context->channels,current_context->sample_rate,current_context->sample_fmt,current_context->channel_layout); + //LogNT::getInstance()->error(TAG, "AV resampledata2 {} {} {}",decode_frame_libav->sample_rate,decode_frame_libav->format,decode_frame_libav->channel_layout); + + int ret = swr_init(resam_con_libav); + + if (ret < 0) + { + LogNT::getInstance()->error(TAG, "Opening AV resample failed {}", ret); + } + else + { + uint8_t* output = cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen; + /* + * old docs: + avresample_convert ( AVAudioResampleContext * avr, + uint8_t ** output, + int out_plane_size, + int out_samples, + uint8_t *const * input, + int in_plane_size, + int in_samples + ) + + old call: + avresample_convert(resam_con_libav, + &output, dsize, decode_frame_libav->nb_samples, + decode_frame_libav->extended_data, decode_frame_libav->linesize[0], decode_frame_libav->nb_samples); + + new docs: + swr_convert ( struct SwrContext * s, + uint8_t ** out, + int out_count, + const uint8_t ** in, + int in_count + ) + new call: + */ + //LogNT::getInstance()->debug(TAG, "Calling swr_convert"); + + swr_convert(resam_con_libav, &output, decode_frame_libav->nb_samples, (const uint8_t**)decode_frame_libav->extended_data, decode_frame_libav->nb_samples); + + swr_close(resam_con_libav); + } + + //LogNT::getInstance()->debug(TAG,"memcpy out"); + cur_input_buf_omx->nFilledLen += dsize; + } + else + { + //LogNT::getInstance()->debug(TAG,"Incomplete mpeg frames in pes packet {} {}",incoming_paket_libav.size,mpacket.length); + /* uint8_t a1=incoming_paket_libav.data[0]; + uint8_t a2=incoming_paket_libav.data[1]; + uint8_t a3=incoming_paket_libav.data[2]; + uint8_t a4=incoming_paket_libav.data[3];*/ + // LogNT::getInstance()->debug(TAG,"Header {:#x} {:#x} {:#x} {:#x}",a1,a2, + // a3,a4); + } + + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 24"); + decompress_buffer_filled = 0; + + if (haveToCopy) + { + //LogNT::getInstance()->debug(TAG,"We can not decompress {} save for later {} {:#x} {:#x}",haveToCopy,mpacket.type,incoming_paket_libav.data,mpacket.pos_buffer); + memcpy(decompress_buffer, incoming_paket_libav.data, std::min(haveToCopy, decompress_buffer_size)); + decompress_buffer_filled = std::min(haveToCopy, decompress_buffer_size); + } + + if (cur_input_buf_omx->nFilledLen) + { + //LogNT::getInstance()->debug(TAG, + // "P 3 Time code {} pts {}", lastreftimeOMX, mpacket.pts); + error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); + + if (error != OMX_ErrorNone) + { + LogNT::getInstance()->debug(TAG, "OMX_EmptyThisBuffer 5 failed {:#x}", error); + } + + //if (mpacket.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); + cur_input_buf_omx = NULL; + } + } + + //LogNT::getInstance()->debug(TAG, "DMP mark 25"); + + *samplepos = mpacket.length; + return mpacket.length; } -long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync) +long long AudioOMX::SetStartOffset(long long curreftime, bool* rsync) { VideoOMX* vw = dynamic_cast(Video::getInstance()); - return vw->SetStartAudioOffset(curreftime,rsync); + return vw->SetStartAudioOffset(curreftime, rsync); } void AudioOMX::ResetTimeOffsets() @@ -2403,27 +2739,29 @@ int AudioOMX::badMinimumFunction(u4 a, int b) } int AudioOMX::DO_NOT_USE(AVCodecContext* avctx, // used - sent to avcodec_send_packet - AVFrame* frame, // used - object for receive to write to - int* got_frame_ptr, // out param - const AVPacket* avpkt) // used - sent to avcodec_send_packet + AVFrame* frame, // used - object for receive to write to + int* got_frame_ptr, // out param + const AVPacket* avpkt) // used - sent to avcodec_send_packet { // Set this to error here. Any error point returns -9999 and *got_frame_ptr = 0 *got_frame_ptr = 0; // Replicate old API behaviour int sendReturn = avcodec_send_packet(avctx, avpkt); + if (sendReturn < 0) return -9999; // error, shouldn't happen, just crash out. // Don't use this code // avcodec_receive_frame needs to be called multiple times // to ensure reception of all decoded data int recReturn = avcodec_receive_frame(avctx, frame); + if (recReturn == 0) // success { - // set got_frame_ptr to 1, this is the old behaviour + // set got_frame_ptr to 1, this is the old behaviour *got_frame_ptr = 1; - // return number of bytes consumed - // guessing here that the calling code only ever supplies whole packets - return avpkt->size; + // return number of bytes consumed + // guessing here that the calling code only ever supplies whole packets + return avpkt->size; } // error diff --git a/src/audioomx.h b/src/audioomx.h index a82b1db..d7c354e 100644 --- a/src/audioomx.h +++ b/src/audioomx.h @@ -26,10 +26,11 @@ #include #include -extern "C" { -#include -#include -#include +extern "C" +{ + #include + #include + #include } #include "defines.h" @@ -39,6 +40,7 @@ extern "C" { class AudioOMX : public Audio { friend class VideoOMX; + public: AudioOMX(); virtual ~AudioOMX(); @@ -59,40 +61,39 @@ class AudioOMX : public Audio int mute(); int unMute(); bool supportsAc3() { return true; } - bool maysupportAc3(){return true;} + bool maysupportAc3() {return true;} bool streamTypeSupported(int streamtype) { - switch (streamtype) { - case 0x11: //AAC LATM packaging - case 0x6A://ac3 - case 3: //mpeg 1 layer 1 and 2 - case 4: - return true; - default: - return false; - }; + switch (streamtype) + { + case 0x11: //AAC LATM packaging + case 0x6A://ac3 + case 3: //mpeg 1 layer 1 and 2 + case 4: + return true; + + default: + return false; + }; } - //Writing Data to Audiodevice virtual void PrepareMediaSample(const MediaPacketList&, u4 samplepos); - virtual u4 DeliverMediaSample(u1* buffer, u4 *samplepos); - u4 DeliverMediaPacket(MediaPacket packet, const u1* buffer,u4 *samplepos); + virtual u4 DeliverMediaSample(u1* buffer, u4* samplepos); + u4 DeliverMediaPacket(MediaPacket packet, const u1* buffer, u4* samplepos); - virtual long long SetStartOffset(long long curreftime, bool *rsync); + virtual long long SetStartOffset(long long curreftime, bool* rsync); virtual void ResetTimeOffsets(); virtual bool DrainTargetReady() {return omx_running;}; virtual bool DrainTargetBufferFull(); + u1 getLastAType() {return lastAType;} - u1 getLastAType() {return lastAType;} - - bool loadOptionsFromServer(VDR* vdr); - bool saveOptionstoServer(); - bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane); - bool handleOptionChanges(Option* option); - + bool loadOptionsFromServer(VDR* vdr); + bool saveOptionstoServer(); + bool addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane); + bool handleOptionChanges(Option* option); #ifdef DEV int test(); @@ -101,13 +102,12 @@ class AudioOMX : public Audio private: int initAllParams(); u1 streamType; - u1 lastAType; - bool firstsynched; + u1 lastAType; + bool firstsynched; MediaPacket packet; u4 packetpos; - bool hdmi; // use hdmi as audio output bool passthrough; // use audio passthrough for the current audio type @@ -117,73 +117,68 @@ class AudioOMX : public Audio bool canpass_mp3; bool canpass_pcm_mch; - int prefered_aac; int prefered_ac3; //0 stereo PCM, 1 passthrough 2 Multichannel PCM int prefered_mp2; int prefered_mp3; - - static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); - static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); - + static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata, OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); + static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata, OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); - unsigned int AdvanceAc3AudioSync(const u1 *data,unsigned int size,unsigned int *framesize); - unsigned int AdvanceAacLatmAudioSync(const u1 *data,unsigned int size,unsigned int *framesize); - unsigned int AdvanceMpAudioSync(const u1 *data,unsigned int size,unsigned int *framesize); - + unsigned int AdvanceAc3AudioSync(const u1* data, unsigned int size, unsigned int* framesize); + unsigned int AdvanceAacLatmAudioSync(const u1* data, unsigned int size, unsigned int* framesize); + unsigned int AdvanceMpAudioSync(const u1* data, unsigned int size, unsigned int* framesize); void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver); - // OMX_HANDLETYPE omx_aud_dec; - OMX_HANDLETYPE omx_aud_rend; - OMX_HANDLETYPE omx_clock; + // OMX_HANDLETYPE omx_aud_dec; + OMX_HANDLETYPE omx_aud_rend; + OMX_HANDLETYPE omx_clock; - //OMX_U32 omx_codec_input_port; - //OMX_U32 omx_codec_output_port; - OMX_U32 omx_rend_input_port; - OMX_U32 omx_rend_clock_port; - OMX_U32 omx_clock_output_port; + //OMX_U32 omx_codec_input_port; + //OMX_U32 omx_codec_output_port; + OMX_U32 omx_rend_input_port; + OMX_U32 omx_rend_clock_port; + OMX_U32 omx_clock_output_port; - long long lastreftimeOMX; + long long lastreftimeOMX; u8 lastreftimePTS; + int AllocateCodecsOMX(); + int DeAllocateCodecsOMX(); - int AllocateCodecsOMX(); - int DeAllocateCodecsOMX(); - - int PrepareInputBufsOMX(bool setportdef); - int DestroyInputBufsOMX(); - int DestroyInputBufsOMXwhilePlaying(); + int PrepareInputBufsOMX(bool setportdef); + int DestroyInputBufsOMX(); + int DestroyInputBufsOMXwhilePlaying(); - int ChangeAudioPortConfig(bool disport); - int ChangeAudioDestination(); - long long correctAudioLatency(long long pts,int addsamples,int srate); + int ChangeAudioPortConfig(bool disport); + int ChangeAudioDestination(); + long long correctAudioLatency(long long pts, int addsamples, int srate); - std::vector input_bufs_omx_all; - std::list input_bufs_omx_free; - std::mutex input_bufs_omx_mutex; - OMX_BUFFERHEADERTYPE* cur_input_buf_omx; + std::vector input_bufs_omx_all; + std::list input_bufs_omx_free; + std::mutex input_bufs_omx_mutex; + OMX_BUFFERHEADERTYPE* cur_input_buf_omx; bool omx_running; bool omx_first_frame; std::mutex libav_mutex; - AVCodec *aaclatmcodec_libav; - AVCodecContext *aaclatmcodec_context_libav; - AVCodec *ac3codec_libav; - AVCodecContext *ac3codec_context_libav; - AVCodec *mp23codec_libav; - AVCodecContext *mp23codec_context_libav; + AVCodec* aaclatmcodec_libav; + AVCodecContext* aaclatmcodec_context_libav; + AVCodec* ac3codec_libav; + AVCodecContext* ac3codec_context_libav; + AVCodec* mp23codec_libav; + AVCodecContext* mp23codec_context_libav; AVPacket incoming_paket_libav; - AVFrame *decode_frame_libav; + AVFrame* decode_frame_libav; SwrContext* resam_con_libav; - u1 * decompress_buffer; + u1* decompress_buffer; unsigned int decompress_buffer_size; unsigned int decompress_buffer_filled; bool lsync; @@ -192,12 +187,11 @@ class AudioOMX : public Audio int mp3sameheadercount; - int InitDecoderLibAV(); - void DeinitDecoderLibAV(); + int InitDecoderLibAV(); + void DeinitDecoderLibAV(); char L_VPE_OMX_AUDIO_REND[128]; - int badMinimumFunction(u4 a, int b); int DO_NOT_USE(AVCodecContext* avctx, AVFrame* frame, int* got_frame_ptr, const AVPacket* avpkt); -- 2.39.2