]> git.vomp.tv Git - vompclient.git/blob - audioomx.cc
Fix segfault in audioomx
[vompclient.git] / audioomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "audioomx.h"
22 #include "videoomx.h"
23 #include "log.h"
24 #include "vdr.h"
25 #include "woptionpane.h"
26
27 AudioOMX::AudioOMX()
28 {
29   initted = 0;
30   streamType = 0;
31   volume = 20;
32   muted = 0;
33   lastAType = MPTYPE_MPEG_AUDIO;
34
35   canpass_ac3=false;
36   canpass_mp2=false;
37   canpass_mp3=false;
38   canpass_pcm_mch=false;
39
40   prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
41   prefered_mp2=0;
42   prefered_mp3=0;
43   hdmi=true;
44
45   omx_running=false;
46
47   omx_aud_rend/*dec*/=0;
48   cur_input_buf_omx=NULL;
49
50   ac3codec_libav=NULL;
51   ac3codec_context_libav=NULL;
52
53   mp23codec_libav=NULL;
54   mp23codec_context_libav=NULL;
55
56   decompress_buffer=NULL;
57   decompress_buffer_size=0;
58   decompress_buffer_filled=0;
59
60 }
61
62 AudioOMX::~AudioOMX()
63 {
64 }
65
66 int AudioOMX::init(UCHAR tstreamType) {
67         if (initted)
68                 return 0;
69         initted = 1;
70
71         streamType = tstreamType;
72
73         if (!initAllParams()) {
74                 shutdown();
75                 return 0;
76         }
77
78         unMute();
79
80         decompress_buffer_size=20000;
81         decompress_buffer=(UCHAR*)malloc(decompress_buffer_size);
82         decompress_buffer_filled=0;
83
84
85
86         av_register_all();
87         av_log_set_flags(AV_LOG_SKIP_REPEATED);
88
89         ac3codec_libav = avcodec_find_decoder(CODEC_ID_AC3);
90         if (ac3codec_libav == NULL) {
91                 Log::getInstance()->log("Audio", Log::DEBUG,
92                                 "Find libav ac3 decoder failed");
93                 return 0;
94         }
95
96         mp23codec_libav = avcodec_find_decoder(CODEC_ID_MP3);
97         if (mp23codec_libav == NULL) {
98                 Log::getInstance()->log("Audio", Log::DEBUG,
99                                 "Find libav mpeg audio decoder failed");
100                 return 0;
101         }
102
103         return 1;
104 }
105
106 int AudioOMX::initAllParams()
107 {
108   return (setStreamType(streamType) && setChannel() && setSource());
109 }
110
111 int AudioOMX::shutdown()
112 {
113   if (!initted) return 0;
114   initted = 0;
115
116   Log::getInstance()->log("Audio", Log::DEBUG, "audio shutdown called");
117   DeAllocateCodecsOMX();
118
119   free(decompress_buffer);
120   decompress_buffer=NULL;
121   decompress_buffer_size=0;
122   decompress_buffer_filled=0;
123
124   return 1;
125 }
126
127 bool AudioOMX::loadOptionsfromServer(VDR* vdr)
128 {
129           Log::getInstance()->log("Audio", Log::DEBUG, "AudioOMX config load");
130     char *name=vdr->configLoad("AudioOMX","AC3DecodingMode");
131
132     if (name != NULL) {
133                 if (STRCASECMP(name, "PCM") == 0) {
134                         prefered_ac3 = 0;
135                 } else if (STRCASECMP(name, "Passthrough") == 0) {
136                         prefered_ac3 = 1;
137                 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
138                         prefered_ac3 = 2;
139                 }
140         }
141
142     name = vdr->configLoad("AudioOMX", "Mp2DecodingMode");
143
144         if (name != NULL) {
145                 if (STRCASECMP(name, "PCM") == 0) {
146                         prefered_mp2 = 0;
147                 } else if (STRCASECMP(name, "Passthrough") == 0) {
148                         prefered_mp2 = 1;
149                 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
150                         prefered_mp2 = 2;
151                 }
152         }
153
154         name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
155
156         if (name != NULL) {
157                 if (STRCASECMP(name, "PCM") == 0) {
158                         prefered_mp3 = 0;
159                 } else if (STRCASECMP(name, "Passthrough") == 0) {
160                         prefered_mp3 = 1;
161                 } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
162                         prefered_mp3 = 2;
163                 }
164         }
165
166         name = vdr->configLoad("AudioOMX", "AudioOutput");
167
168         if (name != NULL) {
169                 if (STRCASECMP(name, "analog") == 0) {
170                         hdmi = false;
171                 } else if (STRCASECMP(name, "HDMI") == 0) {
172                         hdmi = true;
173                 }
174         }
175
176
177    return true;
178
179 }
180
181 bool AudioOMX::handleOptionChanges(Option* option)
182 {
183     if (Audio::handleOptionChanges(option))
184                 return true;
185         switch (option->id) {
186         case 4: {
187                 if (STRCASECMP(option->options[option->userSetChoice], "analog") == 0) {
188                         hdmi = false;
189                 } else if (STRCASECMP(option->options[option->userSetChoice], "HDMI")
190                                 == 0) {
191                         hdmi = true;
192                 }
193                 return true;
194         }
195                 break;
196         case 1: {
197                 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
198                         prefered_ac3 = 0;
199                 } else if (STRCASECMP(option->options[option->userSetChoice],
200                                 "Passthrough") == 0) {
201                         prefered_ac3 = 1;
202                 } else if (STRCASECMP(option->options[option->userSetChoice],
203                                 "PCMMultichannel") == 0) {
204                         prefered_ac3 = 2;
205                 }
206         }
207                 break;
208         case 2: {
209                 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
210                         prefered_mp2 = 0;
211                 } else if (STRCASECMP(option->options[option->userSetChoice],
212                                 "Passthrough") == 0) {
213                         prefered_mp2 = 1;
214                 } else if (STRCASECMP(option->options[option->userSetChoice],
215                                 "PCMMultichannel") == 0) {
216                         prefered_mp2 = 2;
217                 }
218         }
219                 break;
220         case 3: {
221                 if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
222                         prefered_mp3 = 0;
223                 } else if (STRCASECMP(option->options[option->userSetChoice],
224                                 "Passthrough") == 0) {
225                         prefered_mp3 = 1;
226                 } else if (STRCASECMP(option->options[option->userSetChoice],
227                                 "PCMMultichannel") == 0) {
228                         prefered_mp3 = 2;
229                 }
230         }
231                 break;
232         };
233         return false;
234
235 }
236
237 bool AudioOMX::saveOptionstoServer()
238 {
239
240     switch (prefered_ac3) {
241         case 0:
242                 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode", "PCM");
243                 break;
244         case 1:
245                 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
246                                 "Passthrough");
247                 break;
248         case 2:
249                 VDR::getInstance()->configSave("AudioOMX", "AC3DecodingMode",
250                                 "PCMMultichannel");
251                 break;
252         };
253
254         switch (prefered_mp2) {
255         case 0:
256                 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
257                 break;
258         case 1:
259                 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
260                                 "Passthrough");
261                 break;
262         case 2:
263                 VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode",
264                                 "PCMMultichannel");
265                 break;
266         };
267
268         switch (prefered_mp3) {
269         case 0:
270                 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode", "PCM");
271                 break;
272         case 1:
273                 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
274                                 "Passthrough");
275                 break;
276         case 2:
277                 VDR::getInstance()->configSave("AudioOMX", "Mp3DecodingMode",
278                                 "PCMMultichannel");
279                 break;
280         };
281
282         if (!hdmi)
283                 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "analog");
284         else
285                 VDR::getInstance()->configSave("AudioOMX", "AudioOutput", "HDMI");
286
287
288     return true;
289 }
290
291 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
292            UINT numChoices, UINT defaultChoice, UINT startInt,
293            const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
294
295 bool AudioOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
296 {
297     if (!Audio::addOptionsToPanes(panenumber,options,pane)) return false;
298
299
300     Option* option;
301     if (panenumber == 2)
302     {
303
304         static const char* audioopts[]={"analog","HDMI"};
305         option = new Option(4,tr("Audio Output"), "AudioOMX","AudioOutput",Option::TYPE_TEXT,2,0,0,audioopts,NULL,false,this);
306         options->push_back(option);
307         pane->addOptionLine(option);
308
309
310         char **ac3opts=new char *[3];
311         int i=0;
312         ac3opts[i]=new char[strlen("PCM")+1];
313         strcpy(ac3opts[i],"PCM");
314         i++;
315         if (canpass_ac3) {
316                 ac3opts[i]=new char[strlen("Passthrough")+1];
317             strcpy(ac3opts[i],"PassThrough");
318             i++;
319         }
320         if (canpass_pcm_mch) {
321                 ac3opts[i]=new char[strlen("PCMMultichannel")+1];
322             strcpy(ac3opts[i],"PCMMultichannel");
323             i++;
324         }
325         option = new Option(1 ,tr("AC3 HDMI Mode"), "AudioOMX", "AC3DecodingMode", Option::TYPE_TEXT, i, 0, 0, ac3opts,NULL,true, this);
326         options->push_back(option);
327         pane->addOptionLine(option);
328
329         char **mp2opts = new char *[3];
330                 i = 0;
331                 mp2opts[i] = new char[strlen("PCM") + 1];
332                 strcpy(mp2opts[i], "PCM");
333                 i++;
334                 if (canpass_mp2) {
335                         mp2opts[i] = new char[strlen("Passthrough") + 1];
336                         strcpy(mp2opts[i], "PassThrough");
337                         i++;
338                 }
339                 if (canpass_pcm_mch) {
340                         mp2opts[i] = new char[strlen("PCMMultichannel") + 1];
341                         strcpy(mp2opts[i], "PCMMultichannel");
342                         i++;
343                 }
344                 option = new Option(2, tr("Mp2 HDMI Mode"), "AudioOMX",
345                                 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0,
346                                 mp2opts, NULL, true, this);
347                 options->push_back(option);
348                 pane->addOptionLine(option);
349
350                 char **mp3opts = new char *[3];
351                 i = 0;
352                 mp3opts[i] = new char[strlen("PCM") + 1];
353                 strcpy(mp3opts[i], "PCM");
354                 i++;
355                 if (canpass_mp3) {
356                         mp3opts[i] = new char[strlen("Passthrough") + 1];
357                         strcpy(mp3opts[i], "PassThrough");
358                         i++;
359                 }
360                 if (canpass_pcm_mch) {
361                         mp3opts[i] = new char[strlen("PCMMultichannel") + 1];
362                         strcpy(mp3opts[i], "PCMMultichannel");
363                         i++;
364                 }
365                 option = new Option(3, tr("Mp3 HDMI Mode"), "AudioOMX",
366                                 "Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
367                                 NULL, true, this);
368                 options->push_back(option);
369                 pane->addOptionLine(option);
370
371
372     }
373
374     return true;
375 }
376
377
378
379
380
381
382 OMX_ERRORTYPE AudioOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
383
384         //Log::getInstance()->log("Audio", Log::NOTICE, "EmptyBufferDone");
385         AudioOMX *audio=(AudioOMX *)getInstance();
386         audio->ReturnEmptyOMXBuffer(buffer);
387         return OMX_ErrorNone;
388
389 }
390
391 void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
392         input_bufs_omx_mutex.Lock();
393         //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
394         input_bufs_omx_free.push_back(buffer);
395         //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
396         input_bufs_omx_mutex.Unlock();
397 }
398
399  OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
400          Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone");
401         return OMX_ErrorNone;
402 }
403
404
405
406 int AudioOMX::setStreamType(UCHAR type)
407 {
408   if (!initted) return 0;
409
410  // if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
411   return 1;
412 }
413
414 int AudioOMX::setChannel()
415 {
416   if (!initted) return 0;
417
418  // if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
419   return 1;
420 }
421
422 int AudioOMX::setSource()
423 {
424   if (!initted) return 0;
425
426  // if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
427   return 1;
428 }
429
430 int AudioOMX::sync()
431 {
432   if (!initted) return 0;
433
434  // if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
435   return 1;
436 }
437
438 int AudioOMX::play() {
439         if (!initted)
440                 return 0;
441         lastAType=MPTYPE_MPEG_AUDIO;
442         Log::getInstance()->log("Audio", Log::DEBUG, "enter play");
443
444         if (!AllocateCodecsOMX()) {
445                 return 0;
446         }
447         return 1;
448 }
449
450
451 int AudioOMX::ChangeAudioDestination() //clock aka omx mutex needs to be locked
452 {
453         OMX_ERRORTYPE error;
454         const char * destinations[]={"local","hdmi"};
455         int dest=0;
456         if (hdmi) dest=1;
457         else dest=0;
458
459         OMX_CONFIG_BRCMAUDIODESTINATIONTYPE auddest;
460         memset(&auddest,0,sizeof(auddest));
461         auddest.nSize=sizeof(auddest);
462         auddest.nVersion.nVersion=OMX_VERSION;
463         strcpy((char *)auddest.sName, destinations[dest]);
464
465         Log::getInstance()->log("Audio", Log::DEBUG, "setting destination to: %s",auddest.sName);
466         error=OMX_SetConfig(omx_aud_rend,OMX_IndexConfigBrcmAudioDestination,&auddest);
467         if (error!=OMX_ErrorNone){
468                 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX_IndexConfigBrcmAudioDestination failed %x %x %s", error,omx_aud_rend,auddest.sName);
469                 DeAllocateCodecsOMX();
470                 return 0;
471         }
472         return 1;
473
474
475 }
476
477 int AudioOMX::ChangeAudioPortConfig(bool disport) //clock aka omx mutex needs to be locked
478 {
479         OMX_ERRORTYPE error;
480         //Ok first fidle a working configuration
481         Log::getInstance()->log("Audio", Log::DEBUG,
482                                                         "ChangeAudioPortConfig");
483
484         if (hdmi) {
485                 switch (lastAType) {
486                 case MPTYPE_MPEG_AUDIO: {
487                         if (prefered_mp2 == 3 && false) { //not supported yet
488
489                         } else {
490                                 if (prefered_mp2 == 2 && canpass_mp2) {
491                                         passthrough = true;
492                                 } else
493                                         passthrough = false;
494                         }
495                 }
496                         break;
497                 case MPTYPE_AC3_PRE13:
498                 case MPTYPE_AC3: {
499                         if (prefered_ac3 == 3 && false) { //not supported yet
500
501                         } else {
502                                 if (prefered_ac3 == 2 && canpass_ac3) {
503                                         passthrough = true;
504                                 } else
505                                         passthrough = false;
506                         }
507                 }
508                         break;
509                 case MPTYPE_MPEG_AUDIO_LAYER3: {
510                         if (prefered_mp3 == 3 && false) { //not supported yet
511
512                         } else {
513                                 if (prefered_mp3 == 2 && canpass_mp2) {
514                                         passthrough = true;
515                                 } else
516                                         passthrough = false;
517                         }
518                 }
519                         break;
520                 };
521         } else {
522                  passthrough=false;
523                  //mch=false; // multichannel also false
524         }
525
526
527
528         /*OMX_CONFIG_BOOLEANTYPE booly;
529         memset(&booly, 0, sizeof(booly));
530         booly.nSize = sizeof(booly);
531         booly.nVersion.nVersion = OMX_VERSION;
532         if (passthrough)
533                 booly.bEnabled = OMX_TRUE;
534         else
535                 booly.bEnabled = OMX_FALSE;
536
537         error = OMX_SetParameter(omx_aud_dec, OMX_IndexParamBrcmDecoderPassThrough,
538                         &booly);
539         if (error != OMX_ErrorNone) {
540                 Log::getInstance()->log("Audio", Log::DEBUG,
541                                 "Init OMX_IndexParamBrcmDecoderPassThrough failed %x", error);
542                 DeAllocateCodecsOMX();
543                 return 0;
544         }*/
545
546
547
548         if (!omx_running) {
549                 if (passthrough) {
550                         // TODO coding
551                 } else {
552                         //VideoOMX* video=(VideoOMX*)Video::getInstance();
553
554                         /*if (disport) {
555                                 if (!video->ChangeComponentState(omx_aud_rend, OMX_StateIdle)) {
556                                         Log::getInstance()->log("Audio", Log::DEBUG,
557                                                         "omx_aud_rend ChangeComponentState Execute CAP");
558                                         return 0;
559                                 }
560                                 video->DisablePort(omx_aud_rend,omx_rend_input_port,false);
561                                 DestroyInputBufsOMX();
562                         }*/
563                         OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
564                         memset(&audio_pcm, 0, sizeof(audio_pcm));
565                         audio_pcm.nSize = sizeof(audio_pcm);
566                         audio_pcm.nVersion.nVersion = OMX_VERSION;
567                         audio_pcm.nChannels = 2;
568                         audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
569                         audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
570                         //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
571                         audio_pcm.eNumData = OMX_NumericalDataSigned;
572                         audio_pcm.eEndian = OMX_EndianLittle;
573                         audio_pcm.bInterleaved = OMX_TRUE;
574                         audio_pcm.nBitPerSample = 16;
575                         audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
576                         audio_pcm.nChannels = 2;
577                         audio_pcm.nSamplingRate = 48000;
578                         audio_pcm.nPortIndex = omx_rend_input_port;
579                         error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
580                                         &audio_pcm);
581                         if (error != OMX_ErrorNone) {
582                                 Log::getInstance()->log("Audio", Log::DEBUG,
583                                                 "Init OMX_IndexParamAudioPcm failed %x %d", error,
584                                                 omx_rend_input_port);
585                                 //DeAllocateCodecsOMX();
586                                 return 0;
587                         }
588                         /*if (disport) {
589                                 video->EnablePort(omx_aud_rend,omx_rend_input_port,false);
590                                 PrepareInputBufsOMX();
591                                 if (!video->ChangeComponentState(omx_aud_rend, OMX_StateExecuting)) {
592                                         Log::getInstance()->log("Audio", Log::DEBUG,
593                                                         "omx_aud_rend ChangeComponentState Execute CAP");
594                                         return 0;
595                                 }
596
597                         }*/
598
599                 }
600         }
601
602
603
604         return 1;
605
606
607
608 }
609 int AudioOMX::InitDecoderLibAV()
610 {
611         libav_mutex.Lock();
612         ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
613         if (!ac3codec_context_libav) {
614                 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
615                 return 0;
616         }
617
618         ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
619         ac3codec_context_libav->request_channels=2;
620
621         int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
622         if (avc_ret < 0) {
623                 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec  failed \n");
624                 libav_mutex.Unlock();
625                 return 0;
626         }
627
628         mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
629         if (!ac3codec_context_libav) {
630                 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
631                 libav_mutex.Unlock();
632                 return 0;
633         }
634
635         mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
636         mp23codec_context_libav->request_channels=2;
637
638         avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
639         if (avc_ret < 0) {
640                 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec  failed \n");
641                 libav_mutex.Unlock();
642                 return 0;
643         }
644
645          av_init_packet(&incoming_paket_libav);
646          decode_frame_libav=avcodec_alloc_frame();
647          libav_mutex.Unlock();
648          decompress_buffer_filled=0;
649
650
651
652         return 1;
653 }
654
655 void AudioOMX::DeinitDecoderLibAV() {
656
657
658         libav_mutex.Lock();
659         if (ac3codec_context_libav) {
660                 avcodec_close(ac3codec_context_libav);
661                 av_free(ac3codec_context_libav);
662                 ac3codec_context_libav = NULL;
663                 av_free(decode_frame_libav);
664                 avcodec_close(mp23codec_context_libav);
665                 av_free(mp23codec_context_libav);
666                 mp23codec_context_libav = NULL;
667
668         }
669         libav_mutex.Unlock();
670
671 }
672
673
674 int AudioOMX::AllocateCodecsOMX()
675 {
676         OMX_ERRORTYPE error;
677         static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
678
679         Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
680         //Clock, move later to audio
681         VideoOMX *video=(VideoOMX*)Video::getInstance();
682
683         if (!InitDecoderLibAV()) return 0;;
684
685
686         OMX_PORT_PARAM_TYPE p_param;
687         memset(&p_param,0,sizeof(p_param));
688         p_param.nSize=sizeof(p_param);
689         p_param.nVersion.nVersion=OMX_VERSION;
690
691
692         if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
693                 return 0;// get the clock and init it if necessary
694         }
695
696         /* TODO end */
697         if (!video->idleClock()) {
698                 return 0;
699         }
700         video->LockClock();
701
702         error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
703         if (error != OMX_ErrorNone) {
704                 Log::getInstance()->log("Audio", Log::DEBUG,
705                                 "Init OMX audio rend failed %x", error);
706                 video->UnlockClock();
707                 DeAllocateCodecsOMX();
708                 return 0;
709         }
710
711         if (!ChangeAudioDestination()) {
712                 video->UnlockClock();
713                 DeAllocateCodecsOMX();
714                 return 0;
715         }
716
717         error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
718         if (error != OMX_ErrorNone) {
719                 Log::getInstance()->log("Audio", Log::DEBUG,
720                                 "Init OMX audio rend OMX_GetParameter failed %x", error);
721                 video->UnlockClock();
722                 DeAllocateCodecsOMX();
723                 return 0;
724         }
725         omx_rend_input_port = p_param.nStartPortNumber;
726
727         error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
728         if (error != OMX_ErrorNone) {
729                 Log::getInstance()->log("Audio", Log::DEBUG,
730                                 "Init OMX aud rend OMX_GetParameter failed %x", error);
731                 video->UnlockClock();
732                 DeAllocateCodecsOMX();
733                 return 0;
734         }
735         // buggy return value
736         omx_rend_clock_port = p_param.nStartPortNumber;
737
738
739 /*      error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
740
741         if (error!=OMX_ErrorNone){
742                 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
743                 video->UnlockClock();
744                 DeAllocateCodecsOMX();
745                 return 0;
746         }
747
748         error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
749         if (error!=OMX_ErrorNone){
750                 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
751                 video->UnlockClock();
752                 DeAllocateCodecsOMX();
753             return 0;
754         }
755         omx_codec_input_port=p_param.nStartPortNumber;
756         omx_codec_output_port=p_param.nStartPortNumber+1;
757
758         if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
759                 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
760                 video->UnlockClock();
761                 DeAllocateCodecsOMX();
762                 return 0;
763         }*/
764
765
766
767
768         if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
769                 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
770                 video->UnlockClock();
771                 DeAllocateCodecsOMX();
772                 return 0;
773         }
774
775         if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
776                 Log::getInstance()->log("Audio", Log::DEBUG,
777                                 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
778                 video->UnlockClock();
779                 DeAllocateCodecsOMX();
780                 return 0;
781         }
782
783
784
785
786         //Setuo chain
787
788
789         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
790         if (error!=OMX_ErrorNone){
791                 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel clock to rend failed %x %d %d", error,omx_clock_output_port,omx_rend_clock_port);
792                 video->UnlockClock();
793                 DeAllocateCodecsOMX();
794                 return 0;
795         }
796
797         if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
798                                         ) {
799                 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
800                 video->UnlockClock();
801                 DeAllocateCodecsOMX();
802                 return 0;
803         }
804
805         if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
806                 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
807                 video->UnlockClock();
808                 DeAllocateCodecsOMX();
809                 return 0;
810         }
811
812
813
814
815         if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
816                 video->UnlockClock();
817                 DeAllocateCodecsOMX();
818                 return 0;
819         }
820
821         if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
822                 video->UnlockClock();
823                 DeAllocateCodecsOMX();
824                 return 0;
825         }
826
827
828
829         if (!ChangeAudioPortConfig(false)){
830                     Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
831                     video->UnlockClock();
832                     DeAllocateCodecsOMX();
833                         return 0;
834         }
835
836 /*      if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
837                 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
838                 DeAllocateCodecsOMX();
839                 return 0;
840         }*/
841
842
843
844         if (!PrepareInputBufsOMX()) {
845                 video->UnlockClock();
846                 DeAllocateCodecsOMX();
847                 return 0;
848         }
849
850
851
852 /*      error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
853         if (error!=OMX_ErrorNone){
854                 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
855                  video->UnlockClock();
856                 DeAllocateCodecsOMX();
857                 return 0;
858         }*/
859
860
861
862 /*      if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
863                                                 ) {
864                 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
865                  video->UnlockClock();
866                 DeAllocateCodecsOMX();
867                 return 0;
868         }*/
869
870 /*      if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
871                         || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
872                          video->UnlockClock();
873                 DeAllocateCodecsOMX();
874                 return 0;
875         }*/
876
877         if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
878                 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
879                  video->UnlockClock();
880                 DeAllocateCodecsOMX();
881                 return 0;
882         }
883
884
885         video->UnlockClock();
886         paused=false;
887         omx_running=true;
888
889
890         if (!video->setClockExecutingandRunning()) return 0;
891
892         Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
893
894         return 1;
895 }
896
897
898
899
900 int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock mutex
901 {
902         VideoOMX *video=(VideoOMX*)Video::getInstance();
903         OMX_ERRORTYPE error;
904         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
905         memset(&port_def_type,0,sizeof(port_def_type));
906         port_def_type.nSize=sizeof(port_def_type);
907         port_def_type.nVersion.nVersion=OMX_VERSION;
908         port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
909
910         error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
911
912         if (error!=OMX_ErrorNone){
913                         Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
914         }
915
916
917         port_def_type.nBufferCountActual=2;
918         port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
919
920         error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
921
922         if (error!=OMX_ErrorNone){
923                         Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
924         }
925
926
927         error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
928         if (error!=OMX_ErrorNone){
929                 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
930                 return 0;
931         }
932
933         input_bufs_omx_mutex.Lock();
934         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
935                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
936                 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
937                 if (error!=OMX_ErrorNone){
938                         Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
939                                 input_bufs_omx_mutex.Unlock();
940                         return 0;
941                 }
942                 input_bufs_omx_all.push_back(buf_head);
943                 input_bufs_omx_free.push_back(buf_head);
944         }
945         omx_first_frame=true;
946
947         firstsynched=false;
948         cur_input_buf_omx=NULL;
949         input_bufs_omx_mutex.Unlock();
950
951         if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
952                 return 0;
953         }
954
955         return 1;
956 }
957
958 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
959 {
960         OMX_ERRORTYPE error;
961
962         cur_input_buf_omx=NULL;
963         input_bufs_omx_mutex.Lock();
964         for (int i=0; i< input_bufs_omx_all.size();i++) {
965                 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
966                 if (error!=OMX_ErrorNone){
967                         Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
968                         input_bufs_omx_mutex.Unlock();
969                         return 0;
970                 }
971
972         }
973         input_bufs_omx_all.clear();
974         input_bufs_omx_free.clear();
975         input_bufs_omx_mutex.Unlock();
976
977 }
978
979
980 int AudioOMX::DeAllocateCodecsOMX()
981 {
982         OMX_ERRORTYPE error;
983         omx_running=false;
984         VideoOMX *video=(VideoOMX*)Video::getInstance();
985          Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
986
987
988
989    Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
990    if (cur_input_buf_omx) {
991                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
992                 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
993                 if (error!=OMX_ErrorNone) {
994                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
995                 }
996
997                 cur_input_buf_omx=NULL;//write out old data
998         }
999    Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
1000
1001    video->LockClock();
1002         if (omx_aud_rend/*dec*/) {
1003                 // first stop the omx elements
1004         /*      if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
1005                         Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
1006                 }*/
1007                  Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
1008
1009                 video->UnlockClock();
1010                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
1011                 video->idleClock();
1012                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
1013                  video->LockClock();
1014
1015                 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
1016                         Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
1017                 }
1018
1019         // TODO proper deinit sequence
1020                 // first flush all buffers
1021
1022                 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1023                 if (error!=OMX_ErrorNone) {
1024                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1025
1026                 }
1027
1028         /*      error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1029                 if (error!=OMX_ErrorNone){
1030                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1031
1032                 }*/
1033
1034
1035         /*      if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1036                         Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1037                 }*/
1038
1039
1040
1041                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1042                 if (error!=OMX_ErrorNone){
1043                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1044
1045                 }
1046
1047                 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1048                 if (error!=OMX_ErrorNone){
1049                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1050
1051                 }
1052                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1053
1054                 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1055                         !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1056                                 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1057                 }
1058
1059                 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1060                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1061                 DeinitDecoderLibAV();
1062                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1063
1064                 //todo flushing
1065                 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1066                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1067                 }
1068
1069         /*      if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1070                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1071                 }
1072
1073                 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1074                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1075                 }*/
1076
1077
1078                 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1079                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1080                 }
1081
1082                 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1083                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1084                 }
1085
1086
1087
1088         /*      error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,NULL,NULL);
1089                 if (error!=OMX_ErrorNone) {
1090                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1091
1092                 }*/
1093
1094
1095
1096                 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1097                 if (error!=OMX_ErrorNone) {
1098                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1099
1100                 }
1101
1102                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1103                 if (error!=OMX_ErrorNone) {
1104                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1105
1106                 }
1107
1108                 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_port,NULL,NULL);
1109                 if (error!=OMX_ErrorNone) {
1110                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1111
1112                 }
1113                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1114
1115
1116                 //error=OMX_FreeHandle(omx_aud_dec);
1117                 error=OMX_FreeHandle(omx_aud_rend);
1118                 video->UnlockClock();
1119                 video->destroyClock();
1120                 omx_aud_rend/*dec*/=NULL;
1121                 if (error!=OMX_ErrorNone) {
1122                         Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1123                 }
1124         } else  {
1125
1126                 video->UnlockClock();
1127                 DeinitDecoderLibAV();
1128         }
1129           Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1130
1131         return 1;
1132 }
1133
1134
1135
1136 int AudioOMX::stop()
1137 {
1138   if (!initted) return 0;
1139
1140   Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1141   DeAllocateCodecsOMX();
1142   //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1143   return 1;
1144 }
1145
1146 int AudioOMX::mute()
1147 {
1148   if (!initted) return 0;
1149
1150 //  if (ioctl(fdAudio, AV_SET_AUD_MUTE, 1) != 0) return 0;
1151   Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1152
1153   muted = 1;
1154   return 1;
1155 }
1156
1157 int AudioOMX::unMute()
1158 {
1159   if (!initted) return 0;
1160
1161 //  if (ioctl(fdAudio, AV_SET_AUD_MUTE, 0) != 0) return 0;
1162   Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1163
1164   muted = 0;
1165   return 1;
1166 }
1167
1168 int AudioOMX::pause() {
1169         if (!initted)
1170                 return 0;
1171         if (!paused) {
1172                 paused = true;
1173                 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1174                 vw->LockClock();
1175                 if (omx_running) {
1176                         OMX_ERRORTYPE error;
1177                         error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1178                                         omx_rend_input_port, NULL);
1179                         if (error != OMX_ErrorNone) {
1180                                 Log::getInstance()->log("Audio", Log::DEBUG,
1181                                                 "OMX_Flush rend in failed %x", error);
1182
1183                         }
1184                 }
1185                 vw->UnlockClock();
1186                 vw->clockPause();
1187         }
1188         return 1;
1189 }
1190
1191 int AudioOMX::unPause()
1192 {
1193   if (!initted) return 0;
1194   if (paused) {
1195           paused=false; // may be also change omx clock
1196          VideoOMX *vw = (VideoOMX*) Video::getInstance();
1197           vw->clockUnpause();
1198   }
1199   return 1;
1200 }
1201
1202 int AudioOMX::reset()
1203 {
1204   if (!initted) return 0;
1205 //test();
1206   Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1207   DeAllocateCodecsOMX();
1208
1209 //  if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1210 //  Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1211  // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1212
1213   doMuting();
1214   return 1;
1215 }
1216
1217 int AudioOMX::setVolume(int tvolume)
1218 {
1219   // parameter: 0 for silence, 20 for full
1220   if ((tvolume < 0) || (tvolume > 20)) return 0;
1221
1222 // volume = 2 * (20 - volume);
1223 // Right, that one was rubbish... 0-10 were almost
1224 // inaudible, 11-20 did what should have been done
1225 // over the whole 0-20 range
1226
1227   tvolume = 20 - tvolume;
1228
1229   audio_volume Avolume;
1230   Avolume.frontleft = tvolume + Aoffset.frontleft;
1231   Avolume.frontright = tvolume + Aoffset.frontright;
1232   Avolume.rearleft = tvolume + Aoffset.rearleft;
1233   Avolume.rearright = tvolume + Aoffset.rearright;
1234   Avolume.center = tvolume + Aoffset.center;
1235   Avolume.lfe = tvolume + Aoffset.lfe;
1236
1237 //  if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &Avolume) != 0) return 0;
1238
1239 //  unsigned long vol = (tvolume << 24) | (tvolume << 16);
1240 //
1241 //  Log::getInstance()->log("Audio", Log::DEBUG, "%lx", vol);
1242 //  Log::getInstance()->log("Audio", Log::DEBUG, "%i", tvolume);
1243
1244 //  if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &vol) != 0) return 0;
1245   return 1;
1246 }
1247
1248 #ifdef DEV
1249 int AudioOMX::test()
1250 {
1251 //  ULLONG stc = 0;
1252 //  return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1253
1254 /*  aud_sync_parms_t a;
1255   a.parm1 = 0;
1256   a.parm2 = 0;
1257 */
1258 //  int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1259
1260
1261   /*OK*/ //printf("Audio sync disable = %i\n", b);
1262
1263   return 1;
1264
1265
1266 }
1267 #endif
1268
1269 unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1270 {
1271         if (size<=2) return size; // silly;
1272         unsigned int test=0;
1273         *framesize=0;
1274         while (test+1<size) {
1275                 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1276                 test++;
1277         }
1278         return size;
1279 }
1280
1281 unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size,unsigned int *framesize)
1282 {
1283         if (size<=4) return size; // silly;
1284         const int frm_size_tab[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128,
1285                         160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448,
1286                         448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152,
1287                         1152, 1280, 1280, };
1288         unsigned int test=0;
1289         *framesize=20000; //if we do not find a start code do not decompress
1290         while (test+4<size) {
1291                 if (data[test]==0x0B && data[test+1]==0x77) {
1292                         // now figure out the length of the frame
1293                         unsigned char code=data[test+4];
1294                         unsigned char fscod=(code& 0xC0)>>6;
1295                         unsigned char frmsize=(code &0x3f);
1296                         if (fscod!=0) Log::getInstance()->log("Audio", Log::DEBUG, "warning we only support 48 KHz sampling rate");
1297                         *framesize=frm_size_tab[frmsize]*2;
1298                         return test; // probably FrameSync
1299                 }
1300                 test++;
1301         }
1302         return size;
1303 }
1304
1305
1306 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1307 {
1308   packet = mplist.front();
1309 }
1310
1311 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1312         DeliverMediaPacket(packet, buffer, samplepos);
1313         if (*samplepos == packet.length) {
1314                 *samplepos = 0;
1315                 return 1;
1316         } else
1317                 return 0;
1318 }
1319
1320
1321 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1322
1323         VideoOMX *video = (VideoOMX*) Video::getInstance();
1324         video->LockClock();
1325         OMX_PARAM_U32TYPE audio_lat;
1326         OMX_ERRORTYPE error;
1327         memset(&audio_lat, 0, sizeof(audio_lat));
1328         audio_lat.nSize = sizeof(audio_lat);
1329         audio_lat.nVersion.nVersion = OMX_VERSION;
1330         audio_lat.nPortIndex = omx_rend_input_port;
1331
1332         error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1333                         &audio_lat);
1334          video->UnlockClock();
1335         if (error != OMX_ErrorNone) {
1336                 Log::getInstance()->log("Audio", Log::DEBUG,
1337                                 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1338                                 omx_rend_input_port);
1339                 return pts; // no correction in case of error
1340         }
1341         /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1342                         audio_lat.nU32);*/
1343
1344         long long workpts=0;
1345         workpts+=addsamples;
1346         workpts-=audio_lat.nU32;
1347         workpts*=10LL*1000LL*1000LL;
1348         workpts=workpts/((long long)srate); //one second /samplerate
1349         workpts+=pts;
1350
1351         return workpts;
1352 }
1353
1354
1355
1356 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1357                 UINT *samplepos) {
1358         /*First Check, if we have an audio sample*/
1359         VideoOMX *vw = (VideoOMX*) Video::getInstance();
1360         bool achange=false;
1361         OMX_ERRORTYPE error;
1362         Log *logger=Log::getInstance();
1363         if (vw->InIframemode()) {
1364                 samplepos = 0;
1365                 MILLISLEEP(10);
1366                 return 0; //Not in iframe mode!
1367         }
1368
1369         if (!omx_running) return 0; // if we are not runnig do not do this
1370         if (paused) return 0; //Block if we pause
1371
1372         UINT headerstrip = 0;
1373         if (packet.disconti) {
1374                 firstsynched = false;
1375                 decompress_buffer_filled=0;
1376                 if (cur_input_buf_omx) {
1377                         OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1378                                         cur_input_buf_omx);
1379                         if (error != OMX_ErrorNone) {
1380                                 Log::getInstance()->log("Audio", Log::DEBUG,
1381                                                 "OMX_EmptyThisBuffer 1 failed %x", error);
1382                         }
1383                         cur_input_buf_omx = NULL;
1384                 }
1385         }
1386
1387         if (packet.type != lastAType) {//Format Change //Push data out !
1388                 firstsynched = false;
1389                 achange=true;
1390                 lastAType = packet.type;
1391                 decompress_buffer_filled=0;
1392
1393                 if (cur_input_buf_omx) {
1394                         OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1395                                         cur_input_buf_omx);
1396                         if (error != OMX_ErrorNone) {
1397                                 Log::getInstance()->log("Audio", Log::DEBUG,
1398                                                 "OMX_EmptyThisBuffer 2 failed %x", error);
1399                         }
1400                         cur_input_buf_omx = NULL;
1401                 }
1402                 vw->LockClock();
1403                 if (!ChangeAudioPortConfig(true)) {
1404                         Log::getInstance()->log("Audio", Log::DEBUG,
1405                                         "Changing audio port config failed", error);
1406                 }
1407                 vw->UnlockClock();
1408
1409         }
1410
1411         /*Inspect PES-Header */
1412         if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1413                 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1414                 if (packet.type == MPTYPE_AC3)
1415                         headerstrip += 4; //skip ac3 bytes
1416                 *samplepos += headerstrip;
1417                 if (packet.synched) {
1418                         if (cur_input_buf_omx) {
1419                                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1420                                 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1421                                                 cur_input_buf_omx);
1422                                 if (error != OMX_ErrorNone) {
1423                                         Log::getInstance()->log("Audio", Log::DEBUG,
1424                                                         "OMX_EmptyThisBuffer 3 failed %x", error);
1425                                 }
1426                                 //FrameWaitforDisplay(lastreftimeOMX);
1427                                  vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1428
1429                                 cur_input_buf_omx = NULL;//write out old data
1430                         }
1431                         firstsynched = true;
1432                         //decompress_buffer_filled=0;
1433                 } else {
1434                         if (!firstsynched) {//
1435                                 *samplepos = packet.length;//if we have not processed at least one
1436                                 decompress_buffer_filled=0;
1437                                 return packet.length;//synched packet ignore it!
1438                         }
1439                 }
1440         }
1441         if (!cur_input_buf_omx) {
1442                 input_bufs_omx_mutex.Lock();
1443                 if (input_bufs_omx_free.size()==0) {
1444                         input_bufs_omx_mutex.Unlock();
1445                         //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1446                         return 0; // we do not have a free media sample
1447
1448                 }
1449                 cur_input_buf_omx=input_bufs_omx_free.front();
1450                 cur_input_buf_omx->nFilledLen=0;
1451                 cur_input_buf_omx->nOffset=0;
1452                 cur_input_buf_omx->nTimeStamp=0;
1453                 input_bufs_omx_free.pop_front();
1454                 input_bufs_omx_mutex.Unlock();
1455         }
1456
1457         if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1458                 if (packet.synched) {
1459                         //Log::getInstance()->log("Audio", Log::DEBUG,
1460                         //              "packet synched marker");
1461
1462                         //lastreftimePTS=packet.pts;
1463                         if (omx_first_frame) { // TODO time
1464                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1465                                 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1466                                 omx_first_frame = false;
1467                         } else {
1468                                 cur_input_buf_omx->nFlags = 0;
1469                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1470                         }
1471                         lastreftimeOMX = packet.presentation_time;
1472                 //      Log::getInstance()->log("Audio", Log::DEBUG,
1473                 //                      "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1474                         lastreftimePTS = packet.pts;
1475                         cur_input_buf_omx->nTimeStamp =0;// lastreftimeOMX; // the clock component is faulty;
1476                 } else {
1477                 //      Log::getInstance()->log("Audio", Log::DEBUG,
1478                         //                                      "packet NOT synched marker");
1479                         cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1480                         cur_input_buf_omx->nTimeStamp = 0;
1481
1482                 }
1483                 if (packet.disconti || achange) {
1484                         cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1485                         //mp23codec_context_libav->frame_size=-1;
1486                         //ac3codec_context_libav->frame_size=-1;
1487                 }
1488
1489         }
1490
1491         if (*samplepos>packet.length) *samplepos=0; //propably the thread got interrupted and sample is not valid any more!
1492         unsigned int haveToCopy=packet.length-*samplepos;
1493         if (passthrough) {
1494                 //TODO
1495         } else {
1496                 int len;
1497                 int gotta;
1498                 int framesize=0;
1499                 int errcount=0;
1500
1501                 AVCodecContext *current_context;
1502                 switch (packet.type) {
1503                 case MPTYPE_MPEG_AUDIO:
1504                 case MPTYPE_MPEG_AUDIO_LAYER3: {
1505                         current_context = mp23codec_context_libav;
1506                         if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1507                         else framesize=current_context->frame_size;
1508                 }break;
1509                 case MPTYPE_AC3:
1510                 case MPTYPE_AC3_PRE13: {
1511                         current_context = ac3codec_context_libav;
1512                 }break;
1513                 };
1514
1515                 if (decompress_buffer_filled) { // have a remaining paket
1516                         incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1517                         memcpy(decompress_buffer+decompress_buffer_filled,
1518                                         buffer+packet.pos_buffer+*samplepos,
1519                                         min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1520                         incoming_paket_libav.size = decompress_buffer_filled
1521                                         +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1522                         //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1523                 } else {
1524                         incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1525                         incoming_paket_libav.size = haveToCopy;
1526                 }
1527
1528                 while (haveToCopy> 0 && errcount<3) {
1529
1530                         //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1531                         //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1532                                 //      framesize, current_context->frame_size);
1533
1534                         bool donotdecompress=false;
1535                         unsigned int gotframesize=0;
1536                         if (!decompress_buffer_filled) { // only do this if no old data is present
1537                                 int adv = 0;
1538                                 switch (packet.type) {
1539                                 case MPTYPE_MPEG_AUDIO:
1540                                 case MPTYPE_MPEG_AUDIO_LAYER3: {
1541                                         adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1542                                                         incoming_paket_libav.size,&gotframesize);
1543                                 }
1544                                 break;
1545                                 case MPTYPE_AC3:
1546                                 case MPTYPE_AC3_PRE13: {
1547                                         adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1548                                                         incoming_paket_libav.size,&gotframesize);
1549                                 }
1550                                 break;
1551                                 };
1552                                 if (adv > 0) {
1553                                         incoming_paket_libav.data += adv;
1554                                         incoming_paket_libav.size-=adv;
1555                                         haveToCopy -= adv;
1556                                         *samplepos += adv;
1557                                         /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1558                                         else*/ framesize=haveToCopy;
1559                                         //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1560                                         if (haveToCopy <= 0) {
1561                                                 //       Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1562                                                 *samplepos=packet.length;
1563                                                 return packet.length;
1564                                         }
1565
1566
1567                                 } //
1568
1569                                 if (gotframesize>0 && gotframesize>haveToCopy) {
1570                                         donotdecompress=true;
1571                                         errcount=100; // exit loop
1572                                 }
1573                                 //      else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1574                         }
1575
1576                         if (!donotdecompress) {
1577                                 int oldcancelstate;
1578                                 int oldcanceltype;
1579                                 pthread_testcancel();
1580                                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1581                                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1582                                 libav_mutex.Lock();
1583                                 if (!omx_running || !mp23codec_context_libav
1584                                                 || !ac3codec_context_libav) {
1585                                         libav_mutex.Unlock();
1586                                         return *samplepos;
1587                                 }
1588                                 libav_mutex.Unlock();
1589                                 //      Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1590                                 len = avcodec_decode_audio4(current_context, decode_frame_libav,
1591                                                 &gotta, &incoming_paket_libav);
1592                                 //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1593                                 pthread_setcancelstate(oldcancelstate, NULL);
1594                                 pthread_setcanceltype(oldcanceltype, NULL);
1595                                 pthread_testcancel();
1596
1597                         } else {
1598                                 gotta=0;
1599                                 len=0;
1600                         }
1601                         //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1602                         if (!omx_running) {
1603                                 libav_mutex.Unlock();
1604                                 return *samplepos;
1605                         }
1606
1607                         if (decompress_buffer_filled) { // reset to normal decoding
1608                                 if (len>0) {
1609                                         Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1610                                         haveToCopy -= min(len-decompress_buffer_filled,0);
1611                                         *samplepos += min(len-decompress_buffer_filled,0);
1612                                         //if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1613                                         /*else*/ framesize=haveToCopy;
1614                                 } else {
1615                                         framesize=haveToCopy;
1616                                 }
1617                                 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1618                                 errcount=0;
1619                                 decompress_buffer_filled=0;
1620                         } else {
1621
1622                                 if (len>0) {
1623                                         incoming_paket_libav.data += len;
1624                                         haveToCopy -= len;
1625                                         *samplepos += len;
1626                                         errcount=0;
1627                                         /*if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1628                                         else*/framesize=haveToCopy;
1629                                 } else {
1630                                         errcount++;
1631                                         framesize=haveToCopy;
1632                                 }
1633                         }
1634
1635                         incoming_paket_libav.size =framesize;
1636                         if (gotta) {
1637                                 //Log::getInstance()->log("Audio", Log::DEBUG,
1638                                 //                                      "Got a frame");
1639                                 int dsize = av_samples_get_buffer_size(NULL,
1640                                                 current_context->channels, decode_frame_libav->nb_samples,
1641                                                 current_context->sample_fmt, 1);
1642                                 if ((cur_input_buf_omx->nFilledLen + dsize)
1643                                                 > cur_input_buf_omx->nAllocLen ) {
1644                                         // I doubt that this will ever happen
1645                                 //      Log::getInstance()->log("Audio", Log::DEBUG,
1646                                         //                                      "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1647                                         OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1648                                                         cur_input_buf_omx);
1649                                         if (error != OMX_ErrorNone) {
1650                                                 Log::getInstance()->log("Audio", Log::DEBUG,
1651                                                                 "OMX_EmptyThisBuffer 4 failed %x", error);
1652                                         }
1653                                         cur_input_buf_omx = NULL;
1654
1655                                         if (!cur_input_buf_omx) {
1656                                                 int count = 0;
1657                                                 while (count < 10 && omx_running) {
1658                                                         count++;
1659                                                         input_bufs_omx_mutex.Lock();
1660                                                         if (input_bufs_omx_free.size() == 0) {
1661                                                                 input_bufs_omx_mutex.Unlock();
1662                                                         //      Log::getInstance()->log("Audio", Log::DEBUG,
1663                                                                 //              "Deliver MediaPacket no free sample");
1664                                                                 MILLISLEEP(5);
1665                                                                 if (!omx_running) return *samplepos;
1666                                                                 continue;
1667                                                         }
1668                                                         cur_input_buf_omx = input_bufs_omx_free.front();
1669                                                         cur_input_buf_omx->nFilledLen = 0;
1670                                                         cur_input_buf_omx->nOffset = 0;
1671                                                         cur_input_buf_omx->nTimeStamp = 0;
1672                                                         input_bufs_omx_free.pop_front();
1673                                                         input_bufs_omx_mutex.Unlock();
1674                                                         break;
1675                                                 }
1676                                                 if (!cur_input_buf_omx) return *samplepos;
1677                                         }
1678
1679                                 }
1680
1681                                 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1682                                 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1683                                                 decode_frame_libav->data[0], dsize);
1684                                 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1685                                 cur_input_buf_omx->nFilledLen += dsize;
1686                         } else {
1687                                 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1688                         /*      uint8_t a1=incoming_paket_libav.data[0];
1689                                 uint8_t a2=incoming_paket_libav.data[1];
1690                                 uint8_t a3=incoming_paket_libav.data[2];
1691                                 uint8_t a4=incoming_paket_libav.data[3];*/
1692                         //      Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1693                                 //              a3,a4);
1694                         }
1695
1696                 }
1697
1698         }
1699         decompress_buffer_filled=0;
1700         if (haveToCopy ) {
1701                 Log::getInstance()->log("Audio", Log::DEBUG,"We can not decompress %d save for later %d %x %x",haveToCopy,packet.type,incoming_paket_libav.data,packet.pos_buffer);
1702                 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1703
1704             decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1705
1706         }
1707
1708         if (cur_input_buf_omx->nFilledLen) {
1709                 //Log::getInstance()->log("Audio", Log::DEBUG,
1710                         //                                                              "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1711                 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1712                 if (error != OMX_ErrorNone) {
1713                         Log::getInstance()->log("Audio", Log::DEBUG,
1714                                         "OMX_EmptyThisBuffer 5 failed %x", error);
1715                 }
1716                 if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1717                 cur_input_buf_omx = NULL;
1718         }
1719
1720
1721
1722
1723         *samplepos=packet.length;
1724         return packet.length;
1725
1726 }
1727
1728
1729
1730 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1731   VideoOMX *vw=(VideoOMX*)Video::getInstance();
1732   return vw->SetStartAudioOffset(curreftime,rsync);
1733 }
1734
1735 void AudioOMX::ResetTimeOffsets() {
1736   VideoOMX *vw=(VideoOMX*)Video::getInstance();
1737   vw->ResetTimeOffsets();
1738 }
1739
1740