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