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