]> git.vomp.tv Git - vompclient.git/blob - audioomx.cc
Fix major Bug in demuxer, fix audio playback on some channels
[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() //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         VideoOMX *video=(VideoOMX*)Video::getInstance();
546
547
548         if (!omx_running) {
549                 if (passthrough) {
550                         // TODO coding
551                 } else {
552
553                         OMX_AUDIO_PARAM_PCMMODETYPE audio_pcm;
554                         memset(&audio_pcm, 0, sizeof(audio_pcm));
555                         audio_pcm.nSize = sizeof(audio_pcm);
556                         audio_pcm.nVersion.nVersion = OMX_VERSION;
557                         audio_pcm.nChannels = 2;
558                         audio_pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
559                         audio_pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
560                         //audio_pcm.eChannelMapping[2]=OMX_AUDIO_ChannelMax;
561                         audio_pcm.eNumData = OMX_NumericalDataSigned;
562                         audio_pcm.eEndian = OMX_EndianLittle;
563                         audio_pcm.bInterleaved = OMX_TRUE;
564                         audio_pcm.nBitPerSample = 16;
565                         audio_pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
566                         audio_pcm.nChannels = 2;
567                         audio_pcm.nSamplingRate = 48000;
568                         audio_pcm.nPortIndex = omx_rend_input_port;
569                         error = OMX_SetParameter(omx_aud_rend, OMX_IndexParamAudioPcm,
570                                         &audio_pcm);
571                         if (error != OMX_ErrorNone) {
572                                 Log::getInstance()->log("Audio", Log::DEBUG,
573                                                 "Init OMX_IndexParamAudioPcm failed %x %d", error,
574                                                 omx_rend_input_port);
575                                 DeAllocateCodecsOMX();
576                                 return 0;
577                         }
578
579                 }
580         }
581
582
583
584         return 1;
585
586
587
588 }
589 int AudioOMX::InitDecoderLibAV()
590 {
591         libav_mutex.Lock();
592         ac3codec_context_libav = avcodec_alloc_context3(ac3codec_libav);
593         if (!ac3codec_context_libav) {
594                 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for ac3 decoding context failed!");
595                 return 0;
596         }
597
598         ac3codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
599         ac3codec_context_libav->request_channels=2;
600
601         int avc_ret = avcodec_open2(ac3codec_context_libav, ac3codec_libav, NULL);
602         if (avc_ret < 0) {
603                 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec  failed \n");
604                 libav_mutex.Unlock();
605                 return 0;
606         }
607
608         mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
609         if (!ac3codec_context_libav) {
610                 Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
611                 libav_mutex.Unlock();
612                 return 0;
613         }
614
615         mp23codec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
616         mp23codec_context_libav->request_channels=2;
617
618         avc_ret = avcodec_open2(mp23codec_context_libav, mp23codec_libav, NULL);
619         if (avc_ret < 0) {
620                 Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec  failed \n");
621                 libav_mutex.Unlock();
622                 return 0;
623         }
624
625          av_init_packet(&incoming_paket_libav);
626          decode_frame_libav=avcodec_alloc_frame();
627          libav_mutex.Unlock();
628          decompress_buffer_filled=0;
629
630
631
632         return 1;
633 }
634
635 void AudioOMX::DeinitDecoderLibAV() {
636
637
638         libav_mutex.Lock();
639         if (ac3codec_context_libav) {
640                 avcodec_close(ac3codec_context_libav);
641                 av_free(ac3codec_context_libav);
642                 ac3codec_context_libav = NULL;
643                 av_free(decode_frame_libav);
644                 avcodec_close(mp23codec_context_libav);
645                 av_free(mp23codec_context_libav);
646                 mp23codec_context_libav = NULL;
647
648         }
649         libav_mutex.Unlock();
650
651 }
652
653
654 int AudioOMX::AllocateCodecsOMX()
655 {
656         OMX_ERRORTYPE error;
657         static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
658
659         Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX");
660         //Clock, move later to audio
661         VideoOMX *video=(VideoOMX*)Video::getInstance();
662
663         if (!InitDecoderLibAV()) return 0;;
664
665
666         OMX_PORT_PARAM_TYPE p_param;
667         memset(&p_param,0,sizeof(p_param));
668         p_param.nSize=sizeof(p_param);
669         p_param.nVersion.nVersion=OMX_VERSION;
670
671
672         if (!video->getClockAudioandInit(&omx_clock,&omx_clock_output_port)){
673                 return 0;// get the clock and init it if necessary
674         }
675
676         /* TODO end */
677         if (!video->idleClock()) {
678                 return 0;
679         }
680         video->LockClock();
681
682         error = OMX_GetHandle(&omx_aud_rend, VPE_OMX_AUDIO_REND, NULL, &callbacks);
683         if (error != OMX_ErrorNone) {
684                 Log::getInstance()->log("Audio", Log::DEBUG,
685                                 "Init OMX audio rend failed %x", error);
686                 video->UnlockClock();
687                 DeAllocateCodecsOMX();
688                 return 0;
689         }
690
691         if (!ChangeAudioDestination()) {
692                 video->UnlockClock();
693                 DeAllocateCodecsOMX();
694                 return 0;
695         }
696
697         error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamAudioInit, &p_param);
698         if (error != OMX_ErrorNone) {
699                 Log::getInstance()->log("Audio", Log::DEBUG,
700                                 "Init OMX audio rend OMX_GetParameter failed %x", error);
701                 video->UnlockClock();
702                 DeAllocateCodecsOMX();
703                 return 0;
704         }
705         omx_rend_input_port = p_param.nStartPortNumber;
706
707         error = OMX_GetParameter(omx_aud_rend, OMX_IndexParamOtherInit, &p_param);
708         if (error != OMX_ErrorNone) {
709                 Log::getInstance()->log("Audio", Log::DEBUG,
710                                 "Init OMX aud rend OMX_GetParameter failed %x", error);
711                 video->UnlockClock();
712                 DeAllocateCodecsOMX();
713                 return 0;
714         }
715         // buggy return value
716         omx_rend_clock_port = p_param.nStartPortNumber;
717
718
719 /*      error=OMX_GetHandle(&omx_aud_dec,VPE_OMX_AUDIO_DECODER,NULL,&callbacks);
720
721         if (error!=OMX_ErrorNone){
722                 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder failed %x", error);
723                 video->UnlockClock();
724                 DeAllocateCodecsOMX();
725                 return 0;
726         }
727
728         error=OMX_GetParameter(omx_aud_dec,OMX_IndexParamAudioInit,&p_param);
729         if (error!=OMX_ErrorNone){
730                 Log::getInstance()->log("Audio", Log::DEBUG, "Init OMX audio decoder OMX_GetParameter failed %x", error);
731                 video->UnlockClock();
732                 DeAllocateCodecsOMX();
733             return 0;
734         }
735         omx_codec_input_port=p_param.nStartPortNumber;
736         omx_codec_output_port=p_param.nStartPortNumber+1;
737
738         if (!video->DisablePort(omx_aud_dec,omx_codec_input_port) || !video->DisablePort(omx_aud_dec,omx_codec_output_port)) {
739                 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio decoder failed");
740                 video->UnlockClock();
741                 DeAllocateCodecsOMX();
742                 return 0;
743         }*/
744
745
746
747
748         if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true) ) {
749                 Log::getInstance()->log("Audio", Log::DEBUG, "Disable Ports OMX audio rend failed %d",omx_rend_input_port);
750                 video->UnlockClock();
751                 DeAllocateCodecsOMX();
752                 return 0;
753         }
754
755         if ( !video->DisablePort(omx_aud_rend, omx_rend_clock_port, true)) {
756                 Log::getInstance()->log("Audio", Log::DEBUG,
757                                 "Disable Ports OMX rend clock port failed %d",omx_rend_clock_port);
758                 video->UnlockClock();
759                 DeAllocateCodecsOMX();
760                 return 0;
761         }
762
763
764
765
766         //Setuo chain
767
768
769         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_aud_rend,omx_rend_clock_port);
770         if (error!=OMX_ErrorNone){
771                 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);
772                 video->UnlockClock();
773                 DeAllocateCodecsOMX();
774                 return 0;
775         }
776
777         if (!video->EnablePort(omx_clock,omx_clock_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_clock_port,false)
778                                         ) {
779                 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX clock rend failed");
780                 video->UnlockClock();
781                 DeAllocateCodecsOMX();
782                 return 0;
783         }
784
785         if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
786                 Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend idle ChangeComponentState");
787                 video->UnlockClock();
788                 DeAllocateCodecsOMX();
789                 return 0;
790         }
791
792
793
794
795         if ( !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_clock_port)) {
796                 video->UnlockClock();
797                 DeAllocateCodecsOMX();
798                 return 0;
799         }
800
801         if ( !video->CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
802                 video->UnlockClock();
803                 DeAllocateCodecsOMX();
804                 return 0;
805         }
806
807
808
809         if (!ChangeAudioPortConfig()){
810                     Log::getInstance()->log("Audio", Log::NOTICE, "Change AudioPortConfig failed");
811                     video->UnlockClock();
812                     DeAllocateCodecsOMX();
813                         return 0;
814         }
815
816 /*      if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
817                 Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
818                 DeAllocateCodecsOMX();
819                 return 0;
820         }*/
821
822
823
824         if (!PrepareInputBufsOMX()) {
825                 video->UnlockClock();
826                 DeAllocateCodecsOMX();
827                 return 0;
828         }
829
830
831
832 /*      error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
833         if (error!=OMX_ErrorNone){
834                 Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
835                  video->UnlockClock();
836                 DeAllocateCodecsOMX();
837                 return 0;
838         }*/
839
840
841
842 /*      if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
843                                                 ) {
844                 Log::getInstance()->log("Audio", Log::DEBUG, "Enable Ports OMX codec rend failed");
845                  video->UnlockClock();
846                 DeAllocateCodecsOMX();
847                 return 0;
848         }*/
849
850 /*      if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
851                         || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
852                          video->UnlockClock();
853                 DeAllocateCodecsOMX();
854                 return 0;
855         }*/
856
857         if (!video->ChangeComponentState(omx_aud_rend,OMX_StateExecuting)) {
858                 Log::getInstance()->log("Audio", Log::DEBUG, "omx_aud_rend ChangeComponentState Execute");
859                  video->UnlockClock();
860                 DeAllocateCodecsOMX();
861                 return 0;
862         }
863
864
865         video->UnlockClock();
866         paused=false;
867         omx_running=true;
868
869
870         if (!video->setClockExecutingandRunning()) return 0;
871
872         Log::getInstance()->log("Audio", Log::NOTICE, "Allocate Codecs OMX finished");
873
874         return 1;
875 }
876
877
878
879
880 int AudioOMX::PrepareInputBufsOMX() //needs to be called with locvke omx clock mutex
881 {
882         VideoOMX *video=(VideoOMX*)Video::getInstance();
883         OMX_ERRORTYPE error;
884         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
885         memset(&port_def_type,0,sizeof(port_def_type));
886         port_def_type.nSize=sizeof(port_def_type);
887         port_def_type.nVersion.nVersion=OMX_VERSION;
888         port_def_type.nPortIndex=omx_rend_input_port;//omx_codec_input_port;
889
890         error=OMX_GetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
891
892         if (error!=OMX_ErrorNone){
893                         Log::getInstance()->log("Audio", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
894         }
895
896
897         port_def_type.nBufferCountActual=2;
898         port_def_type.nBufferSize=max(port_def_type.nBufferSize,50000); // for transcoder important
899
900         error=OMX_SetParameter(omx_aud_rend/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
901
902         if (error!=OMX_ErrorNone){
903                         Log::getInstance()->log("Audio", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
904         }
905
906
907         error=OMX_SendCommand(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port/*codec*/,0);
908         if (error!=OMX_ErrorNone){
909                 Log::getInstance()->log("Audio", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
910                 return 0;
911         }
912
913         input_bufs_omx_mutex.Lock();
914         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
915                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
916                 error=OMX_AllocateBuffer(omx_aud_rend/*dec*/,&buf_head,omx_rend_input_port/*codec*/,NULL,port_def_type.nBufferSize);
917                 if (error!=OMX_ErrorNone){
918                         Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
919                                 input_bufs_omx_mutex.Unlock();
920                         return 0;
921                 }
922                 input_bufs_omx_all.push_back(buf_head);
923                 input_bufs_omx_free.push_back(buf_head);
924         }
925         omx_first_frame=true;
926
927         firstsynched=false;
928         cur_input_buf_omx=NULL;
929         input_bufs_omx_mutex.Unlock();
930
931         if (!video->CommandFinished(omx_aud_rend/*dec*/,OMX_CommandPortEnable,omx_rend_input_port /*codec*/)) {
932                 return 0;
933         }
934
935         return 1;
936 }
937
938 int AudioOMX::DestroyInputBufsOMX() //call with clock mutex locked
939 {
940         OMX_ERRORTYPE error;
941
942         cur_input_buf_omx=NULL;
943         input_bufs_omx_mutex.Lock();
944         for (int i=0; i< input_bufs_omx_all.size();i++) {
945                 error=OMX_FreeBuffer(omx_aud_rend/*dec*/,omx_rend_input_port/*codec*/,input_bufs_omx_all[i]);
946                 if (error!=OMX_ErrorNone){
947                         Log::getInstance()->log("Audio", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
948                         input_bufs_omx_mutex.Unlock();
949                         return 0;
950                 }
951
952         }
953         input_bufs_omx_all.clear();
954         input_bufs_omx_free.clear();
955         input_bufs_omx_mutex.Unlock();
956
957 }
958
959
960 int AudioOMX::DeAllocateCodecsOMX()
961 {
962         OMX_ERRORTYPE error;
963         omx_running=false;
964         VideoOMX *video=(VideoOMX*)Video::getInstance();
965          Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
966
967
968
969    Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
970    if (cur_input_buf_omx) {
971                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
972                 OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
973                 if (error!=OMX_ErrorNone) {
974                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
975                 }
976
977                 cur_input_buf_omx=NULL;//write out old data
978         }
979    Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
980
981    video->LockClock();
982         if (omx_aud_rend/*dec*/) {
983                 // first stop the omx elements
984         /*      if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
985                         Log::getInstance()->log("Audio", Log::DEBUG, "aud_dec ChangeComponentState");
986                 }*/
987                  Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 3");
988
989                 video->UnlockClock();
990                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 4");
991                 video->idleClock();
992                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 5");
993                  video->LockClock();
994
995                 if (!video->ChangeComponentState(omx_aud_rend,OMX_StateIdle)) {
996                         Log::getInstance()->log("Audio", Log::DEBUG, "aud_rend ChangeComponentState");
997                 }
998
999         // TODO proper deinit sequence
1000                 // first flush all buffers
1001
1002                 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1003                 if (error!=OMX_ErrorNone) {
1004                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1005
1006                 }
1007
1008         /*      error=OMX_SendCommand(omx_aud_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1009                 if (error!=OMX_ErrorNone){
1010                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1011
1012                 }*/
1013
1014
1015         /*      if (!video->CommandFinished(omx_aud_dec,OMX_CommandFlush,omx_codec_input_port)) {
1016                         Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd codec input failed");
1017                 }*/
1018
1019
1020
1021                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1022                 if (error!=OMX_ErrorNone){
1023                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1024
1025                 }
1026
1027                 error=OMX_SendCommand(omx_aud_rend,OMX_CommandFlush, omx_rend_clock_port, NULL);
1028                 if (error!=OMX_ErrorNone){
1029                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Flush rend clock failed %x", error);
1030
1031                 }
1032                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6");
1033
1034                 if (!video->CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1035                         !video->CommandFinished(omx_aud_rend,OMX_CommandFlush,omx_rend_clock_port)) {
1036                                 Log::getInstance()->log("Audio", Log::DEBUG, "flush cmd clock shed failed");
1037                 }
1038
1039                 DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
1040                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 6a");
1041                 DeinitDecoderLibAV();
1042                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 7");
1043
1044                 //todo flushing
1045                 if (!video->DisablePort(omx_aud_rend,omx_rend_input_port,true)) {
1046                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 1");
1047                 }
1048
1049         /*      if (!video->DisablePort(omx_aud_dec,omx_codec_output_port,true)) {
1050                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 6");
1051                 }
1052
1053                 if (!video->DisablePort(omx_aud_dec,omx_codec_input_port,true)) {
1054                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 7");
1055                 }*/
1056
1057
1058                 if (!video->DisablePort(omx_aud_rend,omx_rend_clock_port,true)) {
1059                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 4");
1060                 }
1061
1062                 if (!video->DisablePort(omx_clock,omx_clock_output_port,true)) {
1063                         Log::getInstance()->log("Audio", Log::DEBUG, "Disable Tunnel Port failed 5");
1064                 }
1065
1066
1067
1068         /*      error=OMX_SetupTunnel(omx_aud_dec,omx_codec_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
1075
1076                 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_input_port,NULL,NULL);
1077                 if (error!=OMX_ErrorNone) {
1078                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1079
1080                 }
1081
1082                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1083                 if (error!=OMX_ErrorNone) {
1084                         Log::getInstance()->log("Audio", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1085
1086                 }
1087
1088                 error=OMX_SetupTunnel(omx_aud_rend,omx_rend_clock_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                 Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 8");
1094
1095
1096                 //error=OMX_FreeHandle(omx_aud_dec);
1097                 error=OMX_FreeHandle(omx_aud_rend);
1098                 video->UnlockClock();
1099                 video->destroyClock();
1100                 omx_aud_rend/*dec*/=NULL;
1101                 if (error!=OMX_ErrorNone) {
1102                         Log::getInstance()->log("Audio", Log::DEBUG, "FreeHandle failed %d", error);
1103                 }
1104         } else  {
1105
1106                 video->UnlockClock();
1107                 DeinitDecoderLibAV();
1108         }
1109           Log::getInstance()->log("Audio", Log::DEBUG, "leave deallocate codecs OMX");
1110
1111         return 1;
1112 }
1113
1114
1115
1116 int AudioOMX::stop()
1117 {
1118   if (!initted) return 0;
1119
1120   Log::getInstance()->log("Audio", Log::DEBUG, "Audio stop called");
1121   DeAllocateCodecsOMX();
1122   //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1123   return 1;
1124 }
1125
1126 int AudioOMX::mute()
1127 {
1128   if (!initted) return 0;
1129
1130 //  if (ioctl(fdAudio, AV_SET_AUD_MUTE, 1) != 0) return 0;
1131   Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
1132
1133   muted = 1;
1134   return 1;
1135 }
1136
1137 int AudioOMX::unMute()
1138 {
1139   if (!initted) return 0;
1140
1141 //  if (ioctl(fdAudio, AV_SET_AUD_MUTE, 0) != 0) return 0;
1142   Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
1143
1144   muted = 0;
1145   return 1;
1146 }
1147
1148 int AudioOMX::pause() {
1149         if (!initted)
1150                 return 0;
1151         if (!paused) {
1152                 paused = true;
1153                 VideoOMX *vw = (VideoOMX*) Video::getInstance();
1154                 vw->LockClock();
1155                 OMX_ERRORTYPE error;
1156                 error = OMX_SendCommand(omx_aud_rend, OMX_CommandFlush,
1157                                 omx_rend_input_port, NULL);
1158                 if (error != OMX_ErrorNone) {
1159                         Log::getInstance()->log("Audio", Log::DEBUG,
1160                                         "OMX_Flush rend in failed %x", error);
1161
1162                 }
1163                 vw->UnlockClock();
1164                 vw->clockPause();
1165         }
1166         return 1;
1167 }
1168
1169 int AudioOMX::unPause()
1170 {
1171   if (!initted) return 0;
1172   if (paused) {
1173           paused=false; // may be also change omx clock
1174          VideoOMX *vw = (VideoOMX*) Video::getInstance();
1175           vw->clockUnpause();
1176   }
1177   return 1;
1178 }
1179
1180 int AudioOMX::reset()
1181 {
1182   if (!initted) return 0;
1183 //test();
1184   Log::getInstance()->log("Audio", Log::DEBUG, "reset called");
1185   DeAllocateCodecsOMX();
1186
1187 //  if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
1188 //  Log::getInstance()->log("Audio", Log::DEBUG, "reset back");
1189  // if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
1190
1191   doMuting();
1192   return 1;
1193 }
1194
1195 int AudioOMX::setVolume(int tvolume)
1196 {
1197   // parameter: 0 for silence, 20 for full
1198   if ((tvolume < 0) || (tvolume > 20)) return 0;
1199
1200 // volume = 2 * (20 - volume);
1201 // Right, that one was rubbish... 0-10 were almost
1202 // inaudible, 11-20 did what should have been done
1203 // over the whole 0-20 range
1204
1205   tvolume = 20 - tvolume;
1206
1207   audio_volume Avolume;
1208   Avolume.frontleft = tvolume + Aoffset.frontleft;
1209   Avolume.frontright = tvolume + Aoffset.frontright;
1210   Avolume.rearleft = tvolume + Aoffset.rearleft;
1211   Avolume.rearright = tvolume + Aoffset.rearright;
1212   Avolume.center = tvolume + Aoffset.center;
1213   Avolume.lfe = tvolume + Aoffset.lfe;
1214
1215 //  if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &Avolume) != 0) return 0;
1216
1217 //  unsigned long vol = (tvolume << 24) | (tvolume << 16);
1218 //
1219 //  Log::getInstance()->log("Audio", Log::DEBUG, "%lx", vol);
1220 //  Log::getInstance()->log("Audio", Log::DEBUG, "%i", tvolume);
1221
1222 //  if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &vol) != 0) return 0;
1223   return 1;
1224 }
1225
1226 #ifdef DEV
1227 int AudioOMX::test()
1228 {
1229 //  ULLONG stc = 0;
1230 //  return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
1231
1232 /*  aud_sync_parms_t a;
1233   a.parm1 = 0;
1234   a.parm2 = 0;
1235 */
1236 //  int b = ioctl(fdAudio, AV_SET_AUD_DISABLE_SYNC, &a);
1237
1238
1239   /*OK*/ //printf("Audio sync disable = %i\n", b);
1240
1241   return 1;
1242
1243
1244 }
1245 #endif
1246
1247 unsigned int AudioOMX::AdvanceMpAudioSync(UCHAR *data,unsigned int size)
1248 {
1249         if (size<=2) return size; // silly;
1250         unsigned int test=0;
1251         while (test+1<size) {
1252                 if (data[test]==0xFF && (data[test+1] &0xe0)==0xe0) return test; // probably FrameSync
1253                 test++;
1254         }
1255         return size;
1256 }
1257
1258 unsigned int AudioOMX::AdvanceAc3AudioSync(UCHAR *data,unsigned int size)
1259 {
1260         if (size<=2) return size; // silly;
1261         unsigned int test=0;
1262         while (test+1<size) {
1263                 if (data[test]==0x0B && data[test+1]==0x77) return test; // probably FrameSync
1264                 test++;
1265         }
1266         return size;
1267 }
1268
1269
1270 void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1271 {
1272   packet = mplist.front();
1273 }
1274
1275 UINT AudioOMX::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) {
1276         DeliverMediaPacket(packet, buffer, samplepos);
1277         if (*samplepos == packet.length) {
1278                 *samplepos = 0;
1279                 return 1;
1280         } else
1281                 return 0;
1282 }
1283
1284
1285 long long AudioOMX::correctAudioLatency(long long pts,int addsamples,int srate) {
1286
1287         VideoOMX *video = (VideoOMX*) Video::getInstance();
1288         video->LockClock();
1289         OMX_PARAM_U32TYPE audio_lat;
1290         OMX_ERRORTYPE error;
1291         memset(&audio_lat, 0, sizeof(audio_lat));
1292         audio_lat.nSize = sizeof(audio_lat);
1293         audio_lat.nVersion.nVersion = OMX_VERSION;
1294         audio_lat.nPortIndex = omx_rend_input_port;
1295
1296         error = OMX_GetConfig(omx_aud_rend, OMX_IndexConfigAudioRenderingLatency,
1297                         &audio_lat);
1298          video->UnlockClock();
1299         if (error != OMX_ErrorNone) {
1300                 Log::getInstance()->log("Audio", Log::DEBUG,
1301                                 "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error,
1302                                 omx_rend_input_port);
1303                 return pts; // no correction in case of error
1304         }
1305         /*Log::getInstance()->log("Audio", Log::DEBUG, "Current audio latency %d",
1306                         audio_lat.nU32);*/
1307
1308         long long workpts=0;
1309         workpts+=addsamples;
1310         workpts-=audio_lat.nU32;
1311         workpts*=10LL*1000LL*1000LL;
1312         workpts=workpts/((long long)srate); //one second /samplerate
1313         workpts+=pts;
1314
1315         return workpts;
1316 }
1317
1318
1319
1320 UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
1321                 UINT *samplepos) {
1322         /*First Check, if we have an audio sample*/
1323         VideoOMX *vw = (VideoOMX*) Video::getInstance();
1324         bool achange=false;
1325         OMX_ERRORTYPE error;
1326         Log *logger=Log::getInstance();
1327         if (vw->InIframemode()) {
1328                 samplepos = 0;
1329                 MILLISLEEP(10);
1330                 return 0; //Not in iframe mode!
1331         }
1332
1333         if (!omx_running) return 0; // if we are not runnig do not do this
1334         if (paused) return 0; //Block if we pause
1335
1336         UINT headerstrip = 0;
1337         if (packet.disconti) {
1338                 firstsynched = false;
1339                 decompress_buffer_filled=0;
1340                 if (cur_input_buf_omx) {
1341                         OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1342                                         cur_input_buf_omx);
1343                         if (error != OMX_ErrorNone) {
1344                                 Log::getInstance()->log("Audio", Log::DEBUG,
1345                                                 "OMX_EmptyThisBuffer 1 failed %x", error);
1346                         }
1347                         cur_input_buf_omx = NULL;
1348                 }
1349         }
1350
1351         if (packet.type != lastAType) {//Format Change //Push data out !
1352                 firstsynched = false;
1353                 achange=true;
1354                 lastAType = packet.type;
1355                 decompress_buffer_filled=0;
1356
1357                 if (cur_input_buf_omx) {
1358                         OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1359                                         cur_input_buf_omx);
1360                         if (error != OMX_ErrorNone) {
1361                                 Log::getInstance()->log("Audio", Log::DEBUG,
1362                                                 "OMX_EmptyThisBuffer 2 failed %x", error);
1363                         }
1364                         cur_input_buf_omx = NULL;
1365                 }
1366                 vw->LockClock();
1367                 if (!ChangeAudioPortConfig()) {
1368                         Log::getInstance()->log("Audio", Log::DEBUG,
1369                                         "Changing audio port config failed", error);
1370                 }
1371                 vw->UnlockClock();
1372
1373         }
1374
1375         /*Inspect PES-Header */
1376         if (*samplepos == 0 && packet.type != MPTYPE_MPEG_AUDIO_LAYER3) {//stripheader
1377                 headerstrip = buffer[packet.pos_buffer + 8] + 9;
1378                 if (packet.type == MPTYPE_AC3)
1379                         headerstrip += 4; //skip ac3 bytes
1380                 *samplepos += headerstrip;
1381                 if (packet.synched) {
1382                         if (cur_input_buf_omx) {
1383                                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1384                                 OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1385                                                 cur_input_buf_omx);
1386                                 if (error != OMX_ErrorNone) {
1387                                         Log::getInstance()->log("Audio", Log::DEBUG,
1388                                                         "OMX_EmptyThisBuffer 3 failed %x", error);
1389                                 }
1390                                 //FrameWaitforDisplay(lastreftimeOMX);
1391                                  vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1392
1393                                 cur_input_buf_omx = NULL;//write out old data
1394                         }
1395                         firstsynched = true;
1396                         //decompress_buffer_filled=0;
1397                 } else {
1398                         if (!firstsynched) {//
1399                                 *samplepos = packet.length;//if we have not processed at least one
1400                                 decompress_buffer_filled=0;
1401                                 return packet.length;//synched packet ignore it!
1402                         }
1403                 }
1404         }
1405         if (!cur_input_buf_omx) {
1406                 input_bufs_omx_mutex.Lock();
1407                 if (input_bufs_omx_free.size()==0) {
1408                         input_bufs_omx_mutex.Unlock();
1409                         //Log::getInstance()->log("Audio", Log::DEBUG, "Deliver MediaPacket no free sample");
1410                         return 0; // we do not have a free media sample
1411
1412                 }
1413                 cur_input_buf_omx=input_bufs_omx_free.front();
1414                 cur_input_buf_omx->nFilledLen=0;
1415                 cur_input_buf_omx->nOffset=0;
1416                 cur_input_buf_omx->nTimeStamp=0;
1417                 input_bufs_omx_free.pop_front();
1418                 input_bufs_omx_mutex.Unlock();
1419         }
1420
1421
1422         if (cur_input_buf_omx->nFilledLen == 0) {//will only be changed on first packet
1423                 if (packet.synched) {
1424                         //Log::getInstance()->log("Audio", Log::DEBUG,
1425                         //              "packet synched marker");
1426
1427                         //lastreftimePTS=packet.pts;
1428                         if (omx_first_frame) { // TODO time
1429                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1430                                 Log::getInstance()->log("Audio", Log::DEBUG, "Starttime");
1431                                 omx_first_frame = false;
1432                         } else {
1433                                 cur_input_buf_omx->nFlags = 0;
1434                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1435                         }
1436                         lastreftimeOMX = packet.presentation_time;
1437                 //      Log::getInstance()->log("Audio", Log::DEBUG,
1438                 //                      "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts);
1439                         lastreftimePTS = packet.pts;
1440                         cur_input_buf_omx->nTimeStamp =0;// lastreftimeOMX; // the clock component is faulty;
1441                 } else {
1442                 //      Log::getInstance()->log("Audio", Log::DEBUG,
1443                         //                                      "packet NOT synched marker");
1444                         cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
1445                         cur_input_buf_omx->nTimeStamp = 0;
1446
1447                 }
1448                 if (packet.disconti || achange) {
1449                         cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
1450                         //mp23codec_context_libav->frame_size=-1;
1451                         //ac3codec_context_libav->frame_size=-1;
1452                 }
1453
1454         }
1455
1456         unsigned int haveToCopy=packet.length-*samplepos;
1457         if (passthrough) {
1458                 //TODO
1459         } else {
1460                 int len;
1461                 int gotta;
1462                 int framesize=0;
1463                 int errcount=0;
1464
1465                 AVCodecContext *current_context;
1466                 switch (packet.type) {
1467                 case MPTYPE_MPEG_AUDIO:
1468                 case MPTYPE_MPEG_AUDIO_LAYER3: {
1469                         current_context = mp23codec_context_libav;
1470                         if (current_context->frame_size<0) framesize=1152; //Maximum framesize
1471                         else framesize=current_context->frame_size;
1472                 }break;
1473                 case MPTYPE_AC3:
1474                 case MPTYPE_AC3_PRE13: {
1475                         current_context = ac3codec_context_libav;
1476                 }break;
1477                 };
1478
1479                 if (decompress_buffer_filled) { // have a remaining paket
1480                         incoming_paket_libav.data =(uint8_t*) decompress_buffer;
1481                         memcpy(decompress_buffer+decompress_buffer_filled,
1482                                         buffer+packet.pos_buffer+*samplepos,
1483                                         min(haveToCopy,decompress_buffer_size-decompress_buffer_filled));
1484                         incoming_paket_libav.size = decompress_buffer_filled
1485                                         +min(haveToCopy,decompress_buffer_size-decompress_buffer_filled);
1486                         //Log::getInstance()->log("Audio", Log::DEBUG,"Use saved audio buffer %d",packet.type);
1487                 } else {
1488                         incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1489                         incoming_paket_libav.size = haveToCopy;
1490                 }
1491
1492                 while (haveToCopy> 0 && errcount<3) {
1493
1494                         //Log::getInstance()->log("Audio", Log::DEBUG,"libav in %d %d",framesize,current_context->frame_size);
1495                         //Log::getInstance()->log("Audio", Log::DEBUG, "libav in %d %d",
1496                                 //      framesize, current_context->frame_size);
1497
1498                         if (!decompress_buffer_filled) { // only do this if no old data is present
1499                                 int adv = 0;
1500                                 switch (packet.type) {
1501                                 case MPTYPE_MPEG_AUDIO:
1502                                 case MPTYPE_MPEG_AUDIO_LAYER3: {
1503                                         adv = AdvanceMpAudioSync(incoming_paket_libav.data,
1504                                                         incoming_paket_libav.size);
1505                                 }
1506                                         break;
1507                                 case MPTYPE_AC3:
1508                                 case MPTYPE_AC3_PRE13: {
1509                                         adv = AdvanceAc3AudioSync(incoming_paket_libav.data,
1510                                                         incoming_paket_libav.size);
1511                                 }
1512                                         break;
1513                                 };
1514                                 if (adv > 0) {
1515                                         incoming_paket_libav.data += adv;
1516                                         haveToCopy -= adv;
1517                                         *samplepos += adv;
1518                                         if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1519                                         else framesize=haveToCopy;
1520                                         //Log::getInstance()->log("Audio", Log::DEBUG,"Advance by %d %d from %d",adv,packet.type,*samplepos );
1521                                         if (haveToCopy <= 0) {
1522                                         //       Log::getInstance()->log("Audio", Log::DEBUG,"No sync code in packet remove %d",packet.type);
1523                                                  *samplepos=packet.length;
1524                                                  return packet.length;
1525                                         }
1526                                                 break;
1527                                 } //
1528                         //      else Log::getInstance()->log("Audio", Log::DEBUG,"Loop run" );
1529                         }
1530
1531                         int oldcancelstate;
1532                         int oldcanceltype;
1533                         pthread_testcancel();
1534                         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
1535                         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
1536                         libav_mutex.Lock();
1537                         if (!omx_running || !mp23codec_context_libav
1538                                         || !ac3codec_context_libav) {
1539                                 libav_mutex.Unlock();
1540                                 return *samplepos;
1541                         }
1542                         libav_mutex.Unlock();
1543                         //      Log::getInstance()->log("Audio", Log::DEBUG,"libav out");
1544                         len = avcodec_decode_audio4(current_context, decode_frame_libav,
1545                                         &gotta, &incoming_paket_libav);
1546                         //Log::getInstance()->log("Audio", Log::DEBUG, "libav out1");
1547                         pthread_setcancelstate(oldcancelstate, NULL);
1548                         pthread_setcanceltype(oldcanceltype, NULL);
1549                         pthread_testcancel();
1550
1551                         //Log::getInstance()->log("Audio", Log::DEBUG, "libav out2");
1552                         if (!omx_running) {
1553                                 libav_mutex.Unlock();
1554                                 return *samplepos;
1555                         }
1556
1557                         if (decompress_buffer_filled) { // reset to normal decoding
1558                                 if (len>0) {
1559                                         Log::getInstance()->log("Audio", Log::DEBUG,"saved audio: %d",len);
1560                                         haveToCopy -= min(len-decompress_buffer_filled,0);
1561                                         *samplepos += min(len-decompress_buffer_filled,0);
1562                                         if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1563                                         else framesize=haveToCopy;
1564                                 } else {
1565                                         framesize=haveToCopy;
1566                                 }
1567                                 incoming_paket_libav.data =(uint8_t*) buffer+packet.pos_buffer+*samplepos;
1568                                 errcount=0;
1569                                 decompress_buffer_filled=0;
1570                         } else {
1571
1572                                 if (len>0) {
1573                                         incoming_paket_libav.data += len;
1574                                         haveToCopy -= len;
1575                                         *samplepos += len;
1576                                         errcount=0;
1577                                         if (current_context->frame_size>0) framesize=min(current_context->frame_size,haveToCopy);
1578                                         else framesize=haveToCopy;
1579                                 } else {
1580                                         errcount++;
1581                                         framesize=haveToCopy;
1582                                 }
1583                         }
1584
1585                         incoming_paket_libav.size =framesize;
1586                         if (gotta) {
1587                                 //Log::getInstance()->log("Audio", Log::DEBUG,
1588                                 //                                      "Got a frame");
1589                                 int dsize = av_samples_get_buffer_size(NULL,
1590                                                 current_context->channels, decode_frame_libav->nb_samples,
1591                                                 current_context->sample_fmt, 1);
1592                                 if ((cur_input_buf_omx->nFilledLen + dsize)
1593                                                 > cur_input_buf_omx->nAllocLen ) {
1594                                         // I doubt that this will ever happen
1595                                 //      Log::getInstance()->log("Audio", Log::DEBUG,
1596                                         //                                      "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1597                                         OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
1598                                                         cur_input_buf_omx);
1599                                         if (error != OMX_ErrorNone) {
1600                                                 Log::getInstance()->log("Audio", Log::DEBUG,
1601                                                                 "OMX_EmptyThisBuffer 4 failed %x", error);
1602                                         }
1603                                         cur_input_buf_omx = NULL;
1604
1605                                         if (!cur_input_buf_omx) {
1606                                                 int count = 0;
1607                                                 while (count < 10 && omx_running) {
1608                                                         count++;
1609                                                         input_bufs_omx_mutex.Lock();
1610                                                         if (input_bufs_omx_free.size() == 0) {
1611                                                                 input_bufs_omx_mutex.Unlock();
1612                                                         //      Log::getInstance()->log("Audio", Log::DEBUG,
1613                                                                 //              "Deliver MediaPacket no free sample");
1614                                                                 MILLISLEEP(5);
1615                                                                 if (!omx_running) return *samplepos;
1616                                                                 continue;
1617                                                         }
1618                                                         cur_input_buf_omx = input_bufs_omx_free.front();
1619                                                         cur_input_buf_omx->nFilledLen = 0;
1620                                                         cur_input_buf_omx->nOffset = 0;
1621                                                         cur_input_buf_omx->nTimeStamp = 0;
1622                                                         input_bufs_omx_free.pop_front();
1623                                                         input_bufs_omx_mutex.Unlock();
1624                                                         break;
1625                                                 }
1626                                                 if (!cur_input_buf_omx) return *samplepos;
1627                                         }
1628
1629                                 }
1630
1631                                 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy in %d %d %d" ,dsize,current_context->sample_rate,cur_input_buf_omx->nFilledLen);
1632                                 memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
1633                                                 decode_frame_libav->data[0], dsize);
1634                                 //Log::getInstance()->log("Audio", Log::DEBUG,"memcpy out");
1635                                 cur_input_buf_omx->nFilledLen += dsize;
1636                         } else {
1637                                 //Log::getInstance()->log("Audio", Log::DEBUG,"Incomplete mpeg frames in pes packet %d %d",incoming_paket_libav.size,packet.length);
1638                         /*      uint8_t a1=incoming_paket_libav.data[0];
1639                                 uint8_t a2=incoming_paket_libav.data[1];
1640                                 uint8_t a3=incoming_paket_libav.data[2];
1641                                 uint8_t a4=incoming_paket_libav.data[3];*/
1642                         //      Log::getInstance()->log("Audio", Log::DEBUG,"Header %x %x %x %x",a1,a2,
1643                                 //              a3,a4);
1644                         }
1645
1646                 }
1647
1648         }
1649         decompress_buffer_filled=0;
1650         if (haveToCopy ) {
1651                 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);
1652                 memcpy(decompress_buffer,incoming_paket_libav.data,min(haveToCopy,decompress_buffer_size));
1653
1654             decompress_buffer_filled=min(haveToCopy,decompress_buffer_size);
1655
1656         }
1657
1658         if (cur_input_buf_omx->nFilledLen) {
1659                 //Log::getInstance()->log("Audio", Log::DEBUG,
1660                         //                                                              "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
1661                 error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
1662                 if (error != OMX_ErrorNone) {
1663                         Log::getInstance()->log("Audio", Log::DEBUG,
1664                                         "OMX_EmptyThisBuffer 5 failed %x", error);
1665                 }
1666                 if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000));
1667                 cur_input_buf_omx = NULL;
1668         }
1669
1670
1671
1672
1673         *samplepos=packet.length;
1674         return packet.length;
1675
1676 }
1677
1678
1679
1680 long long AudioOMX::SetStartOffset(long long curreftime, bool *rsync){
1681   VideoOMX *vw=(VideoOMX*)Video::getInstance();
1682   return vw->SetStartAudioOffset(curreftime,rsync);
1683 }
1684
1685 void AudioOMX::ResetTimeOffsets() {
1686   VideoOMX *vw=(VideoOMX*)Video::getInstance();
1687   vw->ResetTimeOffsets();
1688 }
1689
1690