fixed, Operator '?:' has lower precedence than '*'; '*' will be evaluated first....
[vuplus_xbmc] / xbmc / cores / AudioEngine / Engines / ActiveAE / ActiveAE.cpp
1 /*
2  *      Copyright (C) 2010-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "ActiveAE.h"
22
23 using namespace ActiveAE;
24 #include "ActiveAESound.h"
25 #include "ActiveAEStream.h"
26 #include "Utils/AEUtil.h"
27 #include "Encoders/AEEncoderFFmpeg.h"
28
29 #include "settings/Settings.h"
30 #include "settings/AdvancedSettings.h"
31 #include "windowing/WindowingFactory.h"
32
33 #define MAX_CACHE_LEVEL 0.5   // total cache time of stream in seconds
34 #define MAX_WATER_LEVEL 0.25  // buffered time after stream stages in seconds
35
36 void CEngineStats::Reset(unsigned int sampleRate)
37 {
38   CSingleLock lock(m_lock);
39   m_sinkUpdate = XbmcThreads::SystemClockMillis();
40   m_sinkDelay = 0;
41   m_sinkSampleRate = sampleRate;
42   m_bufferedSamples = 0;
43   m_suspended = false;
44 }
45
46 void CEngineStats::UpdateSinkDelay(double delay, int samples)
47 {
48   CSingleLock lock(m_lock);
49   m_sinkUpdate = XbmcThreads::SystemClockMillis();
50   m_sinkDelay = delay;
51   if (samples > m_bufferedSamples)
52   {
53     CLog::Log(LOGERROR, "CEngineStats::UpdateSinkDelay - inconsistency in buffer time");
54   }
55   else
56     m_bufferedSamples -= samples;
57 }
58
59 void CEngineStats::AddSamples(int samples, std::list<CActiveAEStream*> &streams)
60 {
61   CSingleLock lock(m_lock);
62   m_bufferedSamples += samples;
63
64   //update buffered time of streams
65   std::list<CActiveAEStream*>::iterator it;
66   for(it=streams.begin(); it!=streams.end(); ++it)
67   {
68     float delay = 0;
69     std::deque<CSampleBuffer*>::iterator itBuf;
70     for(itBuf=(*it)->m_processingSamples.begin(); itBuf!=(*it)->m_processingSamples.end(); ++itBuf)
71     {
72       delay += (float)(*itBuf)->pkt->nb_samples / (*itBuf)->pkt->config.sample_rate;
73     }
74     delay += (*it)->m_resampleBuffers->GetDelay();
75     (*it)->m_bufferedTime = delay;
76   }
77 }
78
79 float CEngineStats::GetDelay()
80 {
81   CSingleLock lock(m_lock);
82   unsigned int now = XbmcThreads::SystemClockMillis();
83   float delay = m_sinkDelay - (double)(now-m_sinkUpdate) / 1000;
84   delay += (float)m_bufferedSamples / m_sinkSampleRate;
85
86   if (delay < 0)
87     delay = 0.0;
88
89   return delay;
90 }
91
92 float CEngineStats::GetDelay(CActiveAEStream *stream)
93 {
94   CSingleLock lock(m_lock);
95   unsigned int now = XbmcThreads::SystemClockMillis();
96   float delay = m_sinkDelay - (double)(now-m_sinkUpdate) / 1000;
97   delay += (float)m_bufferedSamples / m_sinkSampleRate;
98
99   if (delay < 0)
100     delay = 0.0;
101
102   delay += stream->m_bufferedTime;
103   return delay;
104 }
105
106 float CEngineStats::GetCacheTime(CActiveAEStream *stream)
107 {
108   CSingleLock lock(m_lock);
109   float delay = (float)m_bufferedSamples / m_sinkSampleRate;
110
111   delay += stream->m_bufferedTime;
112   return delay;
113 }
114
115 float CEngineStats::GetCacheTotal(CActiveAEStream *stream)
116 {
117   return MAX_CACHE_LEVEL + m_sinkCacheTotal;
118 }
119
120 float CEngineStats::GetWaterLevel()
121 {
122   return (float)m_bufferedSamples / m_sinkSampleRate;
123 }
124
125 void CEngineStats::SetSuspended(bool state)
126 {
127   CSingleLock lock(m_lock);
128   m_suspended = state;
129 }
130
131 bool CEngineStats::IsSuspended()
132 {
133   CSingleLock lock(m_lock);
134   return m_suspended;
135 }
136
137 CActiveAE::CActiveAE() :
138   CThread("ActiveAE"),
139   m_controlPort("OutputControlPort", &m_inMsgEvent, &m_outMsgEvent),
140   m_dataPort("OutputDataPort", &m_inMsgEvent, &m_outMsgEvent),
141   m_sink(&m_outMsgEvent)
142 {
143   m_sinkBuffers = NULL;
144   m_silenceBuffers = NULL;
145   m_encoderBuffers = NULL;
146   m_vizBuffers = NULL;
147   m_volume = 1.0;
148   m_aeVolume = 1.0;
149   m_muted = false;
150   m_aeMuted = false;
151   m_mode = MODE_PCM;
152   m_encoder = NULL;
153   m_audioCallback = NULL;
154   m_vizInitialized = false;
155   m_sinkHasVolume = false;
156 }
157
158 CActiveAE::~CActiveAE()
159 {
160   Dispose();
161 }
162
163 void CActiveAE::Dispose()
164 {
165 #if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
166   g_Windowing.Unregister(this);
167 #endif
168
169   m_bStop = true;
170   m_outMsgEvent.Set();
171   StopThread();
172   m_controlPort.Purge();
173   m_dataPort.Purge();
174   m_sink.Dispose();
175
176   m_dllAvFormat.Unload();
177   m_dllAvCodec.Unload();
178   m_dllAvUtil.Unload();
179 }
180
181 //-----------------------------------------------------------------------------
182 // Behavior
183 //-----------------------------------------------------------------------------
184
185 enum AE_STATES
186 {
187   AE_TOP = 0,                      // 0
188   AE_TOP_ERROR,                    // 1
189   AE_TOP_UNCONFIGURED,             // 2
190   AE_TOP_RECONFIGURING,            // 3
191   AE_TOP_CONFIGURED,               // 4
192   AE_TOP_CONFIGURED_SUSPEND,       // 5
193   AE_TOP_CONFIGURED_IDLE,          // 6
194   AE_TOP_CONFIGURED_PLAY,          // 7
195 };
196
197 int AE_parentStates[] = {
198     -1,
199     0, //TOP_ERROR
200     0, //TOP_UNCONFIGURED
201     0, //TOP_CONFIGURED
202     0, //TOP_RECONFIGURING
203     4, //TOP_CONFIGURED_SUSPEND
204     4, //TOP_CONFIGURED_IDLE
205     4, //TOP_CONFIGURED_PLAY
206 };
207
208 void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
209 {
210   for (int state = m_state; ; state = AE_parentStates[state])
211   {
212     switch (state)
213     {
214     case AE_TOP: // TOP
215       if (port == &m_controlPort)
216       {
217         switch (signal)
218         {
219         case CActiveAEControlProtocol::GETSTATE:
220           msg->Reply(CActiveAEControlProtocol::ACC, &m_state, sizeof(m_state));
221           return;
222         case CActiveAEControlProtocol::SOUNDMODE:
223           m_soundMode = *(int*)msg->data;
224           return;
225         case CActiveAEControlProtocol::VOLUME:
226           m_volume = *(float*)msg->data;
227           if (m_sinkHasVolume)
228             m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::VOLUME, &m_volume, sizeof(float));
229           return;
230         case CActiveAEControlProtocol::MUTE:
231           m_muted = *(bool*)msg->data;
232           return;
233         default:
234           break;
235         }
236       }
237       else if (port == &m_dataPort)
238       {
239         switch (signal)
240         {
241         case CActiveAEDataProtocol::NEWSOUND:
242           CActiveAESound *sound;
243           sound = *(CActiveAESound**)msg->data;
244           if (sound)
245           {
246             m_sounds.push_back(sound);
247             ResampleSounds();
248           }
249           return;
250         case CActiveAEDataProtocol::FREESTREAM:
251           CActiveAEStream *stream;
252           stream = *(CActiveAEStream**)msg->data;
253           DiscardStream(stream);
254           return;
255         case CActiveAEDataProtocol::FREESOUND:
256           sound = *(CActiveAESound**)msg->data;
257           DiscardSound(sound);
258           return;
259         case CActiveAEDataProtocol::DRAINSTREAM:
260           stream = *(CActiveAEStream**)msg->data;
261           stream->m_drain = true;
262           stream->m_resampleBuffers->m_drain = true;
263           msg->Reply(CActiveAEDataProtocol::ACC);
264           stream->m_streamPort->SendInMessage(CActiveAEDataProtocol::STREAMDRAINED);
265           return;
266         default:
267           break;
268         }
269       }
270       else if (&m_sink.m_dataPort)
271       {
272         switch (signal)
273         {
274         case CSinkDataProtocol::RETURNSAMPLE:
275           CSampleBuffer **buffer;
276           buffer = (CSampleBuffer**)msg->data;
277           if (buffer)
278           {
279             (*buffer)->Return();
280           }
281           return;
282         default:
283           break;
284         }
285       }
286       {
287         std::string portName = port == NULL ? "timer" : port->portName;
288         CLog::Log(LOGWARNING, "CActiveAE::%s - signal: %d from port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state);
289       }
290       return;
291
292     case AE_TOP_ERROR:
293       if (port == NULL) // timeout
294       {
295         switch (signal)
296         {
297         case CActiveAEControlProtocol::TIMEOUT:
298           m_extError = false;
299           LoadSettings();
300           Configure();
301           if (!m_extError)
302           {
303             m_state = AE_TOP_CONFIGURED_IDLE;
304             m_extTimeout = 0;
305           }
306           else
307           {
308             m_state = AE_TOP_ERROR;
309             m_extTimeout = 500;
310           }
311           return;
312         default:
313           break;
314         }
315       }
316       break;
317
318     case AE_TOP_UNCONFIGURED:
319       if (port == &m_controlPort)
320       {
321         switch (signal)
322         {
323         case CActiveAEControlProtocol::INIT:
324           m_extError = false;
325           m_sink.EnumerateSinkList(false);
326           LoadSettings();
327           Configure();
328           msg->Reply(CActiveAEControlProtocol::ACC);
329           if (!m_extError)
330           {
331             m_state = AE_TOP_CONFIGURED_IDLE;
332             m_extTimeout = 0;
333           }
334           else
335           {
336             m_state = AE_TOP_ERROR;
337             m_extTimeout = 500;
338           }
339           return;
340
341         default:
342           break;
343         }
344       }
345       break;
346
347     case AE_TOP_RECONFIGURING:
348       if (port == NULL) // timeout
349       {
350         switch (signal)
351         {
352         case CActiveAEControlProtocol::TIMEOUT:
353           // drain
354           if (RunStages())
355           {
356             m_extTimeout = 0;
357             return;
358           }
359           if (!m_sinkBuffers->m_inputSamples.empty() || !m_sinkBuffers->m_outputSamples.empty())
360           {
361             m_extTimeout = 100;
362             return;
363           }
364           if (NeedReconfigureSink())
365             DrainSink();
366
367           if (!m_extError)
368             Configure();
369           if (!m_extError)
370           {
371             m_state = AE_TOP_CONFIGURED_PLAY;
372             m_extTimeout = 0;
373           }
374           else
375           {
376             m_state = AE_TOP_ERROR;
377             m_extTimeout = 500;
378           }
379           m_extDeferData = false;
380           return;
381         default:
382           break;
383         }
384       }
385       break;
386
387     case AE_TOP_CONFIGURED:
388       if (port == &m_controlPort)
389       {
390         switch (signal)
391         {
392         case CActiveAEControlProtocol::RECONFIGURE:
393           if (m_streams.empty())
394           {
395             bool silence = false;
396             m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::SILENCEMODE, &silence, sizeof(bool));
397           }
398           LoadSettings();
399           ChangeResamplers();
400           if (!NeedReconfigureBuffers() && !NeedReconfigureSink())
401             return;
402           m_state = AE_TOP_RECONFIGURING;
403           m_extTimeout = 0;
404           // don't accept any data until we are reconfigured
405           m_extDeferData = true;
406           return;
407         case CActiveAEControlProtocol::SUSPEND:
408           UnconfigureSink();
409           m_stats.SetSuspended(true);
410           m_state = AE_TOP_CONFIGURED_SUSPEND;
411           m_extDeferData = true;
412           return;
413         case CActiveAEControlProtocol::DISPLAYLOST:
414           if (m_settings.mode == AUDIO_HDMI)
415           {
416             UnconfigureSink();
417             m_stats.SetSuspended(true);
418             m_state = AE_TOP_CONFIGURED_SUSPEND;
419             m_extDeferData = true;
420           }
421           return;
422         case CActiveAEControlProtocol::PAUSESTREAM:
423           CActiveAEStream *stream;
424           stream = *(CActiveAEStream**)msg->data;
425           if (stream->m_paused != true && m_streams.size() == 1)
426             FlushEngine();
427           stream->m_paused = true;
428           return;
429         case CActiveAEControlProtocol::RESUMESTREAM:
430           stream = *(CActiveAEStream**)msg->data;
431           stream->m_paused = false;
432           m_state = AE_TOP_CONFIGURED_PLAY;
433           m_extTimeout = 0;
434           return;
435         case CActiveAEControlProtocol::FLUSHSTREAM:
436           stream = *(CActiveAEStream**)msg->data;
437           SFlushStream(stream);
438           msg->Reply(CActiveAEControlProtocol::ACC);
439           m_state = AE_TOP_CONFIGURED_PLAY;
440           m_extTimeout = 0;
441           return;
442         case CActiveAEControlProtocol::STREAMAMP:
443           MsgStreamParameter *par;
444           par = (MsgStreamParameter*)msg->data;
445           par->stream->m_limiter.SetAmplification(par->parameter.float_par);
446           par->stream->m_amplify = par->parameter.float_par;
447           return;
448         case CActiveAEControlProtocol::STREAMVOLUME:
449           par = (MsgStreamParameter*)msg->data;
450           par->stream->m_volume = par->parameter.float_par;
451           return;
452         case CActiveAEControlProtocol::STREAMRGAIN:
453           par = (MsgStreamParameter*)msg->data;
454           par->stream->m_rgain = par->parameter.float_par;
455           return;
456         case CActiveAEControlProtocol::STREAMRESAMPLERATIO:
457           par = (MsgStreamParameter*)msg->data;
458           if (par->stream->m_resampleBuffers)
459           {
460             par->stream->m_resampleBuffers->m_resampleRatio = par->parameter.double_par;
461           }
462           return;
463         case CActiveAEControlProtocol::STREAMFADE:
464           MsgStreamFade *fade;
465           fade = (MsgStreamFade*)msg->data;
466           fade->stream->m_fadingBase = fade->from;
467           fade->stream->m_fadingTarget = fade->target;
468           fade->stream->m_fadingTime = fade->millis;
469           fade->stream->m_fadingSamples = -1;
470           return;
471         case CActiveAEControlProtocol::STOPSOUND:
472           CActiveAESound *sound;
473           sound = *(CActiveAESound**)msg->data;
474           SStopSound(sound);
475           return;
476         default:
477           break;
478         }
479       }
480       else if (port == &m_dataPort)
481       {
482         switch (signal)
483         {
484         case CActiveAEDataProtocol::PLAYSOUND:
485           CActiveAESound *sound;
486           sound = *(CActiveAESound**)msg->data;
487           if (m_soundMode == AE_SOUND_OFF ||
488              (m_soundMode == AE_SOUND_IDLE && !m_streams.empty()))
489             return;
490           if (sound)
491           {
492             SoundState st = {sound, 0};
493             m_sounds_playing.push_back(st);
494             m_extTimeout = 0;
495             m_state = AE_TOP_CONFIGURED_PLAY;
496           }
497           return;
498         case CActiveAEDataProtocol::NEWSTREAM:
499           MsgStreamNew *streamMsg;
500           CActiveAEStream *stream;
501           streamMsg = (MsgStreamNew*)msg->data;
502           stream = CreateStream(streamMsg);
503           if(stream)
504           {
505             msg->Reply(CActiveAEDataProtocol::ACC, &stream, sizeof(CActiveAEStream*));
506             LoadSettings();
507             Configure();
508             if (!m_extError)
509             {
510               m_state = AE_TOP_CONFIGURED_PLAY;
511               m_extTimeout = 0;
512             }
513             else
514             {
515               m_state = AE_TOP_ERROR;
516               m_extTimeout = 500;
517             }
518           }
519           else
520             msg->Reply(CActiveAEDataProtocol::ERR);
521           return;
522         case CActiveAEDataProtocol::STREAMSAMPLE:
523           MsgStreamSample *msgData;
524           CSampleBuffer *samples;
525           msgData = (MsgStreamSample*)msg->data;
526           samples = msgData->stream->m_processingSamples.front();
527           msgData->stream->m_processingSamples.pop_front();
528           if (samples != msgData->buffer)
529             CLog::Log(LOGERROR, "CActiveAE - inconsistency in stream sample message");
530           if (msgData->buffer->pkt->nb_samples == 0)
531             msgData->buffer->Return();
532           else
533             msgData->stream->m_resampleBuffers->m_inputSamples.push_back(msgData->buffer);
534           m_extTimeout = 0;
535           m_state = AE_TOP_CONFIGURED_PLAY;
536           return;
537         case CActiveAEDataProtocol::FREESTREAM:
538           stream = *(CActiveAEStream**)msg->data;
539           DiscardStream(stream);
540           if (m_streams.empty())
541           {
542             m_extDrainTimer.Set(m_stats.GetDelay() * 1000);
543             m_extDrain = true;
544           }
545           m_extTimeout = 0;
546           m_state = AE_TOP_CONFIGURED_PLAY;
547           return;
548         case CActiveAEDataProtocol::DRAINSTREAM:
549           stream = *(CActiveAEStream**)msg->data;
550           stream->m_drain = true;
551           stream->m_resampleBuffers->m_drain = true;
552           m_extTimeout = 0;
553           m_state = AE_TOP_CONFIGURED_PLAY;
554           msg->Reply(CActiveAEDataProtocol::ACC);
555           return;
556         default:
557           break;
558         }
559       }
560       else if (&m_sink.m_dataPort)
561       {
562         switch (signal)
563         {
564         case CSinkDataProtocol::RETURNSAMPLE:
565           CSampleBuffer **buffer;
566           buffer = (CSampleBuffer**)msg->data;
567           if (buffer)
568           {
569             (*buffer)->Return();
570           }
571           m_extTimeout = 0;
572           m_state = AE_TOP_CONFIGURED_PLAY;
573           return;
574         default:
575           break;
576         }
577       }
578       break;
579
580     case AE_TOP_CONFIGURED_SUSPEND:
581       if (port == &m_controlPort)
582       {
583         bool displayReset = false;
584         switch (signal)
585         {
586         case CActiveAEControlProtocol::DISPLAYRESET:
587           displayReset = true;
588         case CActiveAEControlProtocol::INIT:
589           m_extError = false;
590           if (!displayReset)
591           {
592             m_sink.EnumerateSinkList(true);
593             LoadSettings();
594           }
595           Configure();
596           if (!displayReset)
597             msg->Reply(CActiveAEControlProtocol::ACC);
598           if (!m_extError)
599           {
600             m_state = AE_TOP_CONFIGURED_PLAY;
601             m_extTimeout = 0;
602           }
603           else
604           {
605             m_state = AE_TOP_ERROR;
606             m_extTimeout = 500;
607           }
608           m_stats.SetSuspended(false);
609           m_extDeferData = false;
610           return;
611         default:
612           break;
613         }
614       }
615       else if (&m_sink.m_dataPort)
616       {
617         switch (signal)
618         {
619         case CSinkDataProtocol::RETURNSAMPLE:
620           CSampleBuffer **buffer;
621           buffer = (CSampleBuffer**)msg->data;
622           if (buffer)
623           {
624             (*buffer)->Return();
625           }
626           return;
627         default:
628           break;
629         }
630       }
631       break;
632
633     case AE_TOP_CONFIGURED_IDLE:
634       if (port == NULL) // timeout
635       {
636         switch (signal)
637         {
638         case CActiveAEControlProtocol::TIMEOUT:
639           ResampleSounds();
640           ClearDiscardedBuffers();
641           if (m_extDrain)
642           {
643             if (m_extDrainTimer.IsTimePast())
644             {
645               Configure();
646               if (!m_extError)
647               {
648                 m_state = AE_TOP_CONFIGURED_PLAY;
649                 m_extTimeout = 0;
650               }
651               else
652               {
653                 m_state = AE_TOP_ERROR;
654                 m_extTimeout = 500;
655               }
656             }
657             else
658               m_extTimeout = m_extDrainTimer.MillisLeft();
659           }
660           else
661             m_extTimeout = 5000;
662           return;
663         default:
664           break;
665         }
666       }
667       break;
668
669     case AE_TOP_CONFIGURED_PLAY:
670       if (port == NULL) // timeout
671       {
672         switch (signal)
673         {
674         case CActiveAEControlProtocol::TIMEOUT:
675           if (m_extError)
676           {
677             m_state = AE_TOP_ERROR;
678             m_extTimeout = 100;
679             return;
680           }
681           if (RunStages())
682           {
683             m_extTimeout = 0;
684             return;
685           }
686           if (!m_extDrain && HasWork())
687           {
688             ResampleSounds();
689             ClearDiscardedBuffers();
690             m_extTimeout = 100;
691             return;
692           }
693           m_extTimeout = 0;
694           m_state = AE_TOP_CONFIGURED_IDLE;
695           return;
696         default:
697           break;
698         }
699       }
700       break;
701
702     default: // we are in no state, should not happen
703       CLog::Log(LOGERROR, "CActiveAE::%s - no valid state: %d", __FUNCTION__, m_state);
704       return;
705     }
706   } // for
707 }
708
709 void CActiveAE::Process()
710 {
711   Message *msg = NULL;
712   Protocol *port = NULL;
713   bool gotMsg;
714
715   m_state = AE_TOP_UNCONFIGURED;
716   m_extTimeout = 1000;
717   m_bStateMachineSelfTrigger = false;
718   m_extDrain = false;
719   m_extDeferData = false;
720
721   // start sink
722   m_sink.Start();
723
724   while (!m_bStop)
725   {
726     gotMsg = false;
727
728     if (m_bStateMachineSelfTrigger)
729     {
730       m_bStateMachineSelfTrigger = false;
731       // self trigger state machine
732       StateMachine(msg->signal, port, msg);
733       if (!m_bStateMachineSelfTrigger)
734       {
735         msg->Release();
736         msg = NULL;
737       }
738       continue;
739     }
740     // check control port
741     else if (m_controlPort.ReceiveOutMessage(&msg))
742     {
743       gotMsg = true;
744       port = &m_controlPort;
745     }
746     // check sink data port
747     else if (m_sink.m_dataPort.ReceiveInMessage(&msg))
748     {
749       gotMsg = true;
750       port = &m_sink.m_dataPort;
751     }
752     else if (!m_extDeferData)
753     {
754       // check data port
755       if (m_dataPort.ReceiveOutMessage(&msg))
756       {
757         gotMsg = true;
758         port = &m_dataPort;
759       }
760       // stream data ports
761       else
762       {
763         std::list<CActiveAEStream*>::iterator it;
764         for(it=m_streams.begin(); it!=m_streams.end(); ++it)
765         {
766           if((*it)->m_streamPort->ReceiveOutMessage(&msg))
767           {
768             gotMsg = true;
769             port = &m_dataPort;
770             break;
771           }
772         }
773       }
774     }
775
776     if (gotMsg)
777     {
778       StateMachine(msg->signal, port, msg);
779       if (!m_bStateMachineSelfTrigger)
780       {
781         msg->Release();
782         msg = NULL;
783       }
784       continue;
785     }
786
787     // wait for message
788     else if (m_outMsgEvent.WaitMSec(m_extTimeout))
789     {
790       continue;
791     }
792     // time out
793     else
794     {
795       msg = m_controlPort.GetMessage();
796       msg->signal = CActiveAEControlProtocol::TIMEOUT;
797       port = 0;
798       // signal timeout to state machine
799       StateMachine(msg->signal, port, msg);
800       if (!m_bStateMachineSelfTrigger)
801       {
802         msg->Release();
803         msg = NULL;
804       }
805     }
806   }
807 }
808
809 AEAudioFormat CActiveAE::GetInputFormat(AEAudioFormat *desiredFmt)
810 {
811   AEAudioFormat inputFormat;
812
813   if (m_streams.empty())
814   {
815     inputFormat.m_dataFormat    = AE_FMT_FLOAT;
816     inputFormat.m_sampleRate    = 44100;
817     inputFormat.m_encodedRate   = 0;
818     inputFormat.m_channelLayout = AE_CH_LAYOUT_2_0;
819     inputFormat.m_frames        = 0;
820     inputFormat.m_frameSamples  = 0;
821     inputFormat.m_frameSize     = 0;
822   }
823   // force input format after unpausing slave
824   else if (desiredFmt != NULL)
825   {
826     inputFormat = *desiredFmt;
827   }
828   // keep format when having multiple streams
829   else if (m_streams.size() > 1 && m_silenceBuffers == NULL)
830   {
831     inputFormat = m_inputFormat;
832   }
833   else
834   {
835     inputFormat = m_streams.front()->m_format;
836     m_inputFormat = inputFormat;
837   }
838
839   return inputFormat;
840 }
841
842 void CActiveAE::Configure(AEAudioFormat *desiredFmt)
843 {
844   bool initSink = false;
845
846   AEAudioFormat sinkInputFormat, inputFormat;
847   AEAudioFormat oldInternalFormat = m_internalFormat;
848
849   inputFormat = GetInputFormat(desiredFmt);
850
851   m_sinkRequestFormat = inputFormat;
852   ApplySettingsToFormat(m_sinkRequestFormat, m_settings, (int*)&m_mode);
853   std::string device = AE_IS_RAW(m_sinkRequestFormat.m_dataFormat) ? m_settings.passthoughdevice : m_settings.device;
854   std::string driver;
855   CAESinkFactory::ParseDevice(device, driver);
856   if (!IsSinkCompatible(m_sinkRequestFormat, device) || m_settings.driver.compare(driver) != 0)
857   {
858     if (!InitSink())
859       return;
860     m_settings.driver = driver;
861     initSink = true;
862     m_stats.Reset(m_sinkFormat.m_sampleRate);
863     m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::VOLUME, &m_volume, sizeof(float));
864   }
865
866   if (m_silenceBuffers)
867   {
868     m_discardBufferPools.push_back(m_silenceBuffers);
869     m_silenceBuffers = NULL;
870   }
871
872   // buffers for driving gui sounds if no streams are active
873   if (m_streams.empty())
874   {
875     inputFormat = m_sinkFormat;
876     inputFormat.m_channelLayout = m_sinkRequestFormat.m_channelLayout;
877     inputFormat.m_channelLayout.ResolveChannels(m_sinkFormat.m_channelLayout);
878     inputFormat.m_dataFormat = AE_FMT_FLOAT;
879     inputFormat.m_frameSize = inputFormat.m_channelLayout.Count() *
880                               (CAEUtil::DataFormatToBits(inputFormat.m_dataFormat) >> 3);
881     m_silenceBuffers = new CActiveAEBufferPool(inputFormat);
882     m_silenceBuffers->Create(MAX_WATER_LEVEL*1000);
883     sinkInputFormat = inputFormat;
884     m_internalFormat = inputFormat;
885
886     bool silence = false;
887     m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::SILENCEMODE, &silence, sizeof(bool));
888
889     delete m_encoder;
890     m_encoder = NULL;
891
892     if (m_encoderBuffers)
893     {
894       m_discardBufferPools.push_back(m_encoderBuffers);
895       m_encoderBuffers = NULL;
896     }
897     if (m_vizBuffers)
898     {
899       m_discardBufferPools.push_back(m_vizBuffers);
900       m_vizBuffers = NULL;
901     }
902   }
903   // resample buffers for streams
904   else
905   {
906     bool silence = true;
907     m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::SILENCEMODE, &silence, sizeof(bool));
908
909     AEAudioFormat outputFormat;
910     if (m_mode == MODE_RAW)
911     {
912       outputFormat = inputFormat;
913       sinkInputFormat = m_sinkFormat;
914     }
915     // transcode everything with more than 2 channels
916     else if (m_mode == MODE_TRANSCODE)
917     {
918       outputFormat = inputFormat;
919       outputFormat.m_dataFormat = AE_FMT_FLOATP;
920       outputFormat.m_sampleRate = 48000;
921
922       // setup encoder
923       if (!m_encoder)
924       {
925         m_encoder = new CAEEncoderFFmpeg();
926         m_encoder->Initialize(outputFormat, true);
927         m_encoderFormat = outputFormat;
928       }
929       else
930         outputFormat = m_encoderFormat;
931
932       outputFormat.m_channelLayout = m_encoderFormat.m_channelLayout;
933       outputFormat.m_frames = m_encoderFormat.m_frames;
934
935       // encoder buffer
936       if (m_encoder->GetCodecID() == AV_CODEC_ID_AC3)
937       {
938         AEAudioFormat format;
939         format.m_channelLayout = AE_CH_LAYOUT_2_0;
940         format.m_dataFormat = AE_FMT_S16NE;
941         format.m_frameSize = 2* (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3);
942         format.m_frames = AC3_FRAME_SIZE;
943         format.m_sampleRate = 48000;
944         if (m_encoderBuffers && initSink)
945         {
946           m_discardBufferPools.push_back(m_encoderBuffers);
947           m_encoderBuffers = NULL;
948         }
949         if (!m_encoderBuffers)
950         {
951           m_encoderBuffers = new CActiveAEBufferPool(format);
952           m_encoderBuffers->Create(MAX_WATER_LEVEL*1000);
953         }
954       }
955
956       sinkInputFormat = m_sinkFormat;
957     }
958     else
959     {
960       outputFormat = m_sinkFormat;
961       outputFormat.m_channelLayout = m_sinkRequestFormat.m_channelLayout;
962       outputFormat.m_channelLayout.ResolveChannels(m_sinkFormat.m_channelLayout);
963       outputFormat.m_dataFormat = AE_FMT_FLOAT;
964       outputFormat.m_frameSize = outputFormat.m_channelLayout.Count() *
965                                  (CAEUtil::DataFormatToBits(outputFormat.m_dataFormat) >> 3);
966       // TODO: adjust to decoder
967       sinkInputFormat = outputFormat;
968     }
969     m_internalFormat = outputFormat;
970
971     std::list<CActiveAEStream*>::iterator it;
972     for(it=m_streams.begin(); it!=m_streams.end(); ++it)
973     {
974       // check if we support input format of stream
975       if (!AE_IS_RAW((*it)->m_format.m_dataFormat) && 
976           CActiveAEResample::GetAVSampleFormat((*it)->m_format.m_dataFormat) == AV_SAMPLE_FMT_FLT &&
977           (*it)->m_format.m_dataFormat != AE_FMT_FLOAT)
978       {
979         (*it)->m_convertFn = CAEConvert::ToFloat((*it)->m_format.m_dataFormat);
980         (*it)->m_format.m_dataFormat = AE_FMT_FLOAT;
981       }
982
983       if (!(*it)->m_inputBuffers)
984       {
985         // align input buffers with period of sink or encoder
986         (*it)->m_format.m_frames = m_internalFormat.m_frames * ((float)(*it)->m_format.m_sampleRate / m_internalFormat.m_sampleRate);
987
988         // create buffer pool
989         (*it)->m_inputBuffers = new CActiveAEBufferPool((*it)->m_format);
990         (*it)->m_inputBuffers->Create(MAX_CACHE_LEVEL*1000);
991       }
992       if (initSink && (*it)->m_resampleBuffers)
993       {
994         m_discardBufferPools.push_back((*it)->m_resampleBuffers);
995         (*it)->m_resampleBuffers = NULL;
996       }
997       if (!(*it)->m_resampleBuffers)
998       {
999         (*it)->m_resampleBuffers = new CActiveAEBufferPoolResample((*it)->m_inputBuffers->m_format, outputFormat, m_settings.resampleQuality);
1000         (*it)->m_resampleBuffers->m_changeResampler = (*it)->m_forceResampler;
1001         (*it)->m_resampleBuffers->Create(MAX_CACHE_LEVEL*1000, false, m_settings.stereoupmix);
1002       }
1003       if (m_mode == MODE_TRANSCODE || m_streams.size() > 1)
1004         (*it)->m_resampleBuffers->m_fillPackets = true;
1005
1006       // amplification
1007       (*it)->m_limiter.SetSamplerate(outputFormat.m_sampleRate);
1008     }
1009
1010     // buffers for viz
1011     if (!AE_IS_RAW(inputFormat.m_dataFormat))
1012     {
1013       if (initSink && m_vizBuffers)
1014       {
1015         m_discardBufferPools.push_back(m_vizBuffers);
1016         m_vizBuffers = NULL;
1017       }
1018       if (!m_vizBuffers)
1019       {
1020         AEAudioFormat vizFormat = m_internalFormat;
1021         vizFormat.m_channelLayout = AE_CH_LAYOUT_2_0;
1022         vizFormat.m_dataFormat = AE_FMT_FLOAT;
1023         m_vizBuffers = new CActiveAEBufferPoolResample(m_internalFormat, vizFormat, m_settings.resampleQuality);
1024         // TODO use cache of sync + water level
1025         m_vizBuffers->Create(2000, false, false);
1026         m_vizInitialized = false;
1027       }
1028     }
1029   }
1030
1031   // resample buffers for sink
1032   if (m_sinkBuffers && 
1033      (!CompareFormat(m_sinkBuffers->m_format,m_sinkFormat) || !CompareFormat(m_sinkBuffers->m_inputFormat, sinkInputFormat)))
1034   {
1035     m_discardBufferPools.push_back(m_sinkBuffers);
1036     m_sinkBuffers = NULL;
1037   }
1038   if (!m_sinkBuffers)
1039   {
1040     m_sinkBuffers = new CActiveAEBufferPoolResample(sinkInputFormat, m_sinkFormat, m_settings.resampleQuality);
1041     m_sinkBuffers->Create(MAX_WATER_LEVEL*1000, true, false);
1042   }
1043
1044   // reset gui sounds
1045   if (!CompareFormat(oldInternalFormat, m_internalFormat))
1046   {
1047     std::vector<CActiveAESound*>::iterator it;
1048     for (it = m_sounds.begin(); it != m_sounds.end(); ++it)
1049     {
1050       (*it)->SetConverted(false);
1051     }
1052   }
1053
1054   ClearDiscardedBuffers();
1055   m_extDrain = false;
1056 }
1057
1058 CActiveAEStream* CActiveAE::CreateStream(MsgStreamNew *streamMsg)
1059 {
1060   // we only can handle a single pass through stream
1061   bool hasRawStream = false;
1062   bool hasStream = false;
1063   std::list<CActiveAEStream*>::iterator it;
1064   for(it = m_streams.begin(); it != m_streams.end(); ++it)
1065   {
1066     if((*it)->IsDrained())
1067       continue;
1068     if(AE_IS_RAW((*it)->m_format.m_dataFormat))
1069       hasRawStream = true;
1070     hasStream = true;
1071   }
1072   if (hasRawStream || (hasStream && AE_IS_RAW(streamMsg->format.m_dataFormat)))
1073   {
1074     return NULL;
1075   }
1076
1077   // create the stream
1078   CActiveAEStream *stream;
1079   stream = new CActiveAEStream(&streamMsg->format);
1080   stream->m_streamPort = new CActiveAEDataProtocol("stream",
1081                              &stream->m_inMsgEvent, &m_outMsgEvent);
1082
1083   // create buffer pool
1084   stream->m_inputBuffers = NULL; // create in Configure when we know the sink format
1085   stream->m_resampleBuffers = NULL; // create in Configure when we know the sink format
1086   stream->m_statsLock = m_stats.GetLock();
1087   stream->m_fadingSamples = 0;
1088   stream->m_started = false;
1089
1090   if (streamMsg->options & AESTREAM_PAUSED)
1091     stream->m_paused = true;
1092
1093   if (streamMsg->options & AESTREAM_FORCE_RESAMPLE)
1094     stream->m_forceResampler = true;
1095
1096   m_streams.push_back(stream);
1097
1098   return stream;
1099 }
1100
1101 void CActiveAE::DiscardStream(CActiveAEStream *stream)
1102 {
1103   std::list<CActiveAEStream*>::iterator it;
1104   for (it=m_streams.begin(); it!=m_streams.end(); )
1105   {
1106     if (stream == (*it))
1107     {
1108       while (!(*it)->m_processingSamples.empty())
1109       {
1110         (*it)->m_processingSamples.front()->Return();
1111         (*it)->m_processingSamples.pop_front();
1112       }
1113       m_discardBufferPools.push_back((*it)->m_inputBuffers);
1114       m_discardBufferPools.push_back((*it)->m_resampleBuffers);
1115       CLog::Log(LOGDEBUG, "CActiveAE::DiscardStream - audio stream deleted");
1116       delete (*it)->m_streamPort;
1117       delete (*it);
1118       it = m_streams.erase(it);
1119     }
1120     else
1121       ++it;
1122   }
1123
1124   ClearDiscardedBuffers();
1125 }
1126
1127 void CActiveAE::SFlushStream(CActiveAEStream *stream)
1128 {
1129   while (!stream->m_processingSamples.empty())
1130   {
1131     stream->m_processingSamples.front()->Return();
1132     stream->m_processingSamples.pop_front();
1133   }
1134   stream->m_resampleBuffers->Flush();
1135   stream->m_streamPort->Purge();
1136   stream->m_bufferedTime = 0.0;
1137   stream->m_paused = false;
1138
1139   // flush the engine if we only have a single stream
1140   if (m_streams.size() == 1)
1141   {
1142     FlushEngine();
1143   }
1144 }
1145
1146 void CActiveAE::FlushEngine()
1147 {
1148   if (m_sinkBuffers)
1149     m_sinkBuffers->Flush();
1150   if (m_vizBuffers)
1151     m_vizBuffers->Flush();
1152
1153   // send message to sink
1154   Message *reply;
1155   if (m_sink.m_controlPort.SendOutMessageSync(CSinkControlProtocol::FLUSH,
1156                                            &reply, 2000))
1157   {
1158     bool success = reply->signal == CSinkControlProtocol::ACC ? true : false;
1159     if (!success)
1160     {
1161       CLog::Log(LOGERROR, "ActiveAE::%s - returned error on flush", __FUNCTION__);
1162       m_extError = true;
1163     }
1164     reply->Release();
1165   }
1166   else
1167   {
1168     CLog::Log(LOGERROR, "ActiveAE::%s - failed to flush", __FUNCTION__);
1169     m_extError = true;
1170   }
1171   m_stats.Reset(m_sinkFormat.m_sampleRate);
1172 }
1173
1174 void CActiveAE::ClearDiscardedBuffers()
1175 {
1176   std::list<CActiveAEBufferPool*>::iterator it;
1177   for (it=m_discardBufferPools.begin(); it!=m_discardBufferPools.end(); ++it)
1178   {
1179     CActiveAEBufferPoolResample *rbuf = dynamic_cast<CActiveAEBufferPoolResample*>(*it);
1180     if (rbuf)
1181     {
1182       rbuf->Flush();
1183     }
1184     // if all buffers have returned, we can delete the buffer pool
1185     if ((*it)->m_allSamples.size() == (*it)->m_freeSamples.size())
1186     {
1187       delete (*it);
1188       CLog::Log(LOGDEBUG, "CActiveAE::ClearDiscardedBuffers - buffer pool deleted");
1189       m_discardBufferPools.erase(it);
1190       return;
1191     }
1192   }
1193 }
1194
1195 void CActiveAE::SStopSound(CActiveAESound *sound)
1196 {
1197   std::list<SoundState>::iterator it;
1198   for (it=m_sounds_playing.begin(); it!=m_sounds_playing.end(); ++it)
1199   {
1200     if (it->sound == sound)
1201     {
1202       m_sounds_playing.erase(it);
1203       return;
1204     }
1205   }
1206 }
1207
1208 void CActiveAE::DiscardSound(CActiveAESound *sound)
1209 {
1210   SStopSound(sound);
1211
1212   std::vector<CActiveAESound*>::iterator it;
1213   for (it=m_sounds.begin(); it!=m_sounds.end(); ++it)
1214   {
1215     if ((*it) == sound)
1216     {
1217       m_sounds.erase(it);
1218       return;
1219     }
1220   }
1221 }
1222
1223 void CActiveAE::ChangeResamplers()
1224 {
1225   std::list<CActiveAEStream*>::iterator it;
1226   for(it=m_streams.begin(); it!=m_streams.end(); ++it)
1227   {
1228     if ((*it)->m_resampleBuffers && (*it)->m_resampleBuffers->m_resampler &&
1229         (((*it)->m_resampleBuffers->m_resampleQuality != m_settings.resampleQuality) ||
1230         ((*it)->m_resampleBuffers->m_stereoUpmix != m_settings.stereoupmix)))
1231     {
1232       (*it)->m_resampleBuffers->m_changeResampler = true;
1233     }
1234     (*it)->m_resampleBuffers->m_resampleQuality = m_settings.resampleQuality;
1235     (*it)->m_resampleBuffers->m_stereoUpmix = m_settings.stereoupmix;
1236   }
1237 }
1238
1239 void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode)
1240 {
1241   if (mode)
1242     *mode = MODE_PCM;
1243
1244   // raw pass through
1245   if (m_settings.mode != AUDIO_ANALOG && AE_IS_RAW(format.m_dataFormat))
1246   {
1247     if ((format.m_dataFormat == AE_FMT_AC3 && !settings.ac3passthrough) ||
1248         (format.m_dataFormat == AE_FMT_EAC3 && !settings.eac3passthrough) ||
1249         (format.m_dataFormat == AE_FMT_TRUEHD && !settings.truehdpassthrough) ||
1250         (format.m_dataFormat == AE_FMT_DTS && !settings.dtspassthrough) ||
1251         (format.m_dataFormat == AE_FMT_DTSHD && !settings.dtshdpassthrough))
1252     {
1253       CLog::Log(LOGERROR, "CActiveAE::ApplySettingsToFormat - input audio format is wrong");
1254     }
1255     if (mode)
1256       *mode = MODE_RAW;
1257   }
1258   // transcode
1259   else if (m_settings.mode != AUDIO_ANALOG && 
1260            settings.ac3passthrough &&
1261            (!settings.multichannellpcm || (m_settings.mode != AUDIO_HDMI)) && 
1262            !m_streams.empty() &&
1263            (format.m_channelLayout.Count() > 2 || settings.stereoupmix))
1264   {
1265     format.m_dataFormat = AE_FMT_AC3;
1266     format.m_sampleRate = 48000;
1267     format.m_channelLayout = AE_CH_LAYOUT_2_0;
1268     if (mode)
1269       *mode = MODE_TRANSCODE;
1270   }
1271   else
1272   {
1273     format.m_dataFormat = AE_FMT_FLOAT;
1274     // consider user channel layout for those cases
1275     // 1. input stream is multichannel
1276     // 2. stereo upmix is selected
1277     // 3. already playing > 2 channels and "audiophile" is not set
1278     //    this is the case if e.g. a stream changes config from 5.1 to 2.0
1279     //    which would cause a short audio drop-out if we changed the sink
1280     if ((format.m_channelLayout.Count() > 2) ||
1281          settings.stereoupmix ||
1282          (m_stats.GetWaterLevel() > 0 && m_internalFormat.m_channelLayout.Count() > 2 && !g_advancedSettings.m_audioAudiophile))
1283     {
1284       CAEChannelInfo stdLayout;
1285       switch (settings.channels)
1286       {
1287         default:
1288         case  0: stdLayout = AE_CH_LAYOUT_2_0; break;
1289         case  1: stdLayout = AE_CH_LAYOUT_2_0; break;
1290         case  2: stdLayout = AE_CH_LAYOUT_2_1; break;
1291         case  3: stdLayout = AE_CH_LAYOUT_3_0; break;
1292         case  4: stdLayout = AE_CH_LAYOUT_3_1; break;
1293         case  5: stdLayout = AE_CH_LAYOUT_4_0; break;
1294         case  6: stdLayout = AE_CH_LAYOUT_4_1; break;
1295         case  7: stdLayout = AE_CH_LAYOUT_5_0; break;
1296         case  8: stdLayout = AE_CH_LAYOUT_5_1; break;
1297         case  9: stdLayout = AE_CH_LAYOUT_7_0; break;
1298         case 10: stdLayout = AE_CH_LAYOUT_7_1; break;
1299       }
1300
1301       if (g_advancedSettings.m_audioAudiophile)
1302         format.m_channelLayout.ResolveChannels(stdLayout);
1303       else
1304         format.m_channelLayout = stdLayout;
1305     }
1306
1307     if (m_settings.mode == AUDIO_IEC958 && format.m_sampleRate > 48000)
1308     {
1309       format.m_sampleRate = 48000;
1310       CLog::Log(LOGINFO, "CActiveAE::ApplySettings - limit samplerate for SPDIF to %d", format.m_sampleRate);
1311     }
1312
1313     if (g_advancedSettings.m_audioResample)
1314     {
1315       format.m_sampleRate = g_advancedSettings.m_audioResample;
1316       CLog::Log(LOGINFO, "CActiveAE::ApplySettings - Forcing samplerate to %d", format.m_sampleRate);
1317     }
1318
1319     // for IEC958 limit to 2 channels
1320     if (m_settings.mode == AUDIO_IEC958)
1321     {
1322       format.m_channelLayout = AE_CH_LAYOUT_2_0;
1323     }
1324
1325     // sinks may not support mono
1326     if (format.m_channelLayout.Count() == 1)
1327     {
1328       format.m_channelLayout = AE_CH_LAYOUT_2_0;
1329     }
1330   }
1331 }
1332
1333 bool CActiveAE::NeedReconfigureBuffers()
1334 {
1335   AEAudioFormat newFormat = GetInputFormat();
1336   ApplySettingsToFormat(newFormat, m_settings);
1337
1338   if (newFormat.m_dataFormat != m_sinkRequestFormat.m_dataFormat ||
1339       newFormat.m_channelLayout != m_sinkRequestFormat.m_channelLayout ||
1340       newFormat.m_sampleRate != m_sinkRequestFormat.m_sampleRate)
1341     return true;
1342
1343   return false;
1344 }
1345
1346 bool CActiveAE::NeedReconfigureSink()
1347 {
1348   AEAudioFormat newFormat = GetInputFormat();
1349   ApplySettingsToFormat(newFormat, m_settings);
1350
1351   std::string device = AE_IS_RAW(newFormat.m_dataFormat) ? m_settings.passthoughdevice : m_settings.device;
1352   std::string driver;
1353   CAESinkFactory::ParseDevice(device, driver);
1354   if (m_settings.driver.compare(driver) != 0)
1355     return true;
1356
1357   if (!IsSinkCompatible(newFormat, device))
1358     return true;
1359
1360   return false;
1361 }
1362
1363 bool CActiveAE::InitSink()
1364 {
1365   SinkConfig config;
1366   config.format = m_sinkRequestFormat;
1367   config.stats = &m_stats;
1368   config.device = AE_IS_RAW(m_sinkRequestFormat.m_dataFormat) ? &m_settings.passthoughdevice :
1369                                                                 &m_settings.device;
1370
1371   // send message to sink
1372   Message *reply;
1373   if (m_sink.m_controlPort.SendOutMessageSync(CSinkControlProtocol::CONFIGURE,
1374                                                  &reply,
1375                                                  5000,
1376                                                  &config, sizeof(config)))
1377   {
1378     bool success = reply->signal == CSinkControlProtocol::ACC ? true : false;
1379     if (!success)
1380     {
1381       reply->Release();
1382       CLog::Log(LOGERROR, "ActiveAE::%s - returned error", __FUNCTION__);
1383       m_extError = true;
1384       return false;
1385     }
1386     AEAudioFormat *data;
1387     data = (AEAudioFormat*)reply->data;
1388     if (data)
1389     {
1390       m_sinkFormat = *data;
1391     }
1392     m_sinkHasVolume = m_sink.HasVolume();
1393     reply->Release();
1394   }
1395   else
1396   {
1397     CLog::Log(LOGERROR, "ActiveAE::%s - failed to init", __FUNCTION__);
1398     m_extError = true;
1399     return false;
1400   }
1401
1402   m_inMsgEvent.Reset();
1403   return true;
1404 }
1405
1406 void CActiveAE::DrainSink()
1407 {
1408   // send message to sink
1409   Message *reply;
1410   if (m_sink.m_dataPort.SendOutMessageSync(CSinkDataProtocol::DRAIN,
1411                                                  &reply,
1412                                                  2000))
1413   {
1414     bool success = reply->signal == CSinkDataProtocol::ACC ? true : false;
1415     if (!success)
1416     {
1417       reply->Release();
1418       CLog::Log(LOGERROR, "ActiveAE::%s - returned error on drain", __FUNCTION__);
1419       m_extError = true;
1420       return;
1421     }
1422     reply->Release();
1423   }
1424   else
1425   {
1426     CLog::Log(LOGERROR, "ActiveAE::%s - failed to drain", __FUNCTION__);
1427     m_extError = true;
1428     return;
1429   }
1430 }
1431
1432 bool CActiveAE::IsSinkCompatible(const AEAudioFormat format, const std::string &device)
1433 {
1434   bool compatible = false;
1435   SinkConfig config;
1436   config.format = format;
1437   config.device = &device;
1438
1439   // send message to sink
1440   Message *reply;
1441   if (m_sink.m_controlPort.SendOutMessageSync(CSinkControlProtocol::ISCOMPATIBLE,
1442                                                  &reply,
1443                                                  1000,
1444                                                  &config, sizeof(config)))
1445   {
1446     bool success = reply->signal == CSinkControlProtocol::ACC ? true : false;
1447     if (!success)
1448     {
1449       reply->Release();
1450       CLog::Log(LOGERROR, "ActiveAE::%s - returned error", __FUNCTION__);
1451       m_extError = true;
1452       return false;
1453     }
1454     compatible = *(bool*)reply->data;
1455     reply->Release();
1456   }
1457   else
1458   {
1459     CLog::Log(LOGERROR, "ActiveAE::%s - failed to query compatibility", __FUNCTION__);
1460     m_extError = true;
1461     return false;
1462   }
1463   return compatible;
1464 }
1465
1466 void CActiveAE::UnconfigureSink()
1467 {
1468   // send message to sink
1469   Message *reply;
1470   if (m_sink.m_controlPort.SendOutMessageSync(CSinkControlProtocol::UNCONFIGURE,
1471                                                  &reply,
1472                                                  2000))
1473   {
1474     bool success = reply->signal == CSinkControlProtocol::ACC ? true : false;
1475     if (!success)
1476     {
1477       CLog::Log(LOGERROR, "ActiveAE::%s - returned error", __FUNCTION__);
1478       m_extError = true;
1479     }
1480     reply->Release();
1481   }
1482   else
1483   {
1484     CLog::Log(LOGERROR, "ActiveAE::%s - failed to unconfigure", __FUNCTION__);
1485     m_extError = true;
1486   }
1487
1488   m_inMsgEvent.Reset();
1489 }
1490
1491
1492 bool CActiveAE::RunStages()
1493 {
1494   bool busy = false;
1495
1496   // serve input streams
1497   std::list<CActiveAEStream*>::iterator it;
1498   for (it = m_streams.begin(); it != m_streams.end(); ++it)
1499   {
1500     if ((*it)->m_resampleBuffers && !(*it)->m_paused)
1501       busy = (*it)->m_resampleBuffers->ResampleBuffers();
1502     else if ((*it)->m_resampleBuffers && 
1503             ((*it)->m_resampleBuffers->m_inputSamples.size() > (*it)->m_resampleBuffers->m_allSamples.size() * 0.5))
1504     {
1505       CSingleLock lock((*it)->m_streamLock);
1506       (*it)->m_streamIsBuffering = false;
1507     }
1508
1509     // provide buffers to stream
1510     float time = m_stats.GetCacheTime((*it));
1511     CSampleBuffer *buffer;
1512     if (!(*it)->m_drain)
1513     {
1514       while (time < MAX_CACHE_LEVEL && !(*it)->m_inputBuffers->m_freeSamples.empty())
1515       {
1516         buffer = (*it)->m_inputBuffers->GetFreeBuffer();
1517         (*it)->m_processingSamples.push_back(buffer);
1518         (*it)->m_streamPort->SendInMessage(CActiveAEDataProtocol::STREAMBUFFER, &buffer, sizeof(CSampleBuffer*));
1519         (*it)->IncFreeBuffers();
1520         time += (float)buffer->pkt->max_nb_samples / buffer->pkt->config.sample_rate;
1521       }
1522     }
1523     else
1524     {
1525       if ((*it)->m_resampleBuffers->m_inputSamples.empty() &&
1526           (*it)->m_resampleBuffers->m_outputSamples.empty() &&
1527           (*it)->m_processingSamples.empty())
1528       {
1529         (*it)->m_streamPort->SendInMessage(CActiveAEDataProtocol::STREAMDRAINED);
1530         (*it)->m_drain = false;
1531         (*it)->m_resampleBuffers->m_drain = false;
1532         (*it)->m_started = false;
1533
1534         // set variables being polled via stream interface
1535         CSingleLock lock((*it)->m_streamLock);
1536         if ((*it)->m_streamSlave)
1537         {
1538           CActiveAEStream *slave = (CActiveAEStream*)((*it)->m_streamSlave);
1539           slave->m_paused = false;
1540
1541           // TODO: find better solution for this
1542           // gapless bites audiophile
1543           if (g_advancedSettings.m_audioAudiophile)
1544             Configure(&slave->m_format);
1545
1546           (*it)->m_streamSlave = NULL;
1547         }
1548         (*it)->m_streamDrained = true;
1549         (*it)->m_streamDraining = false;
1550         (*it)->m_streamFading = false;
1551       }
1552     }
1553   }
1554
1555   if (m_stats.GetWaterLevel() < MAX_WATER_LEVEL &&
1556      (m_mode != MODE_TRANSCODE || (m_encoderBuffers && !m_encoderBuffers->m_freeSamples.empty())))
1557   {
1558     // mix streams and sounds sounds
1559     if (m_mode != MODE_RAW)
1560     {
1561       CSampleBuffer *out = NULL;
1562       if (!m_sounds_playing.empty() && m_streams.empty())
1563       {
1564         if (m_silenceBuffers && !m_silenceBuffers->m_freeSamples.empty())
1565         {
1566           out = m_silenceBuffers->GetFreeBuffer();
1567           for (int i=0; i<out->pkt->planes; i++)
1568           {
1569             memset(out->pkt->data[i], 0, out->pkt->linesize);
1570           }
1571           out->pkt->nb_samples = out->pkt->max_nb_samples;
1572         }
1573       }
1574
1575       // mix streams
1576       std::list<CActiveAEStream*>::iterator it;
1577
1578       // if we deal with more than a single stream, all streams
1579       // must provide samples for mixing
1580       bool allStreamsReady = true;
1581       for (it = m_streams.begin(); it != m_streams.end(); ++it)
1582       {
1583         if ((*it)->m_paused || !(*it)->m_started || !(*it)->m_resampleBuffers)
1584           continue;
1585
1586         if ((*it)->m_resampleBuffers->m_outputSamples.empty())
1587           allStreamsReady = false;
1588       }
1589
1590       bool needClamp = false;
1591       for (it = m_streams.begin(); it != m_streams.end() && allStreamsReady; ++it)
1592       {
1593         if ((*it)->m_paused || !(*it)->m_resampleBuffers)
1594           continue;
1595
1596         if (!(*it)->m_resampleBuffers->m_outputSamples.empty())
1597         {
1598           (*it)->m_started = true;
1599
1600           if (!out)
1601           {
1602             out = (*it)->m_resampleBuffers->m_outputSamples.front();
1603             (*it)->m_resampleBuffers->m_outputSamples.pop_front();
1604
1605             int nb_floats = out->pkt->nb_samples * out->pkt->config.channels / out->pkt->planes;
1606             int nb_loops = 1;
1607             float fadingStep = 0.0f;
1608
1609             // fading
1610             if ((*it)->m_fadingSamples == -1)
1611             {
1612               (*it)->m_fadingSamples = m_internalFormat.m_sampleRate * (float)(*it)->m_fadingTime / 1000.0f;
1613               (*it)->m_volume = (*it)->m_fadingBase;
1614             }
1615             if ((*it)->m_fadingSamples > 0)
1616             {
1617               nb_floats = out->pkt->config.channels / out->pkt->planes;
1618               nb_loops = out->pkt->nb_samples;
1619               float delta = (*it)->m_fadingTarget - (*it)->m_fadingBase;
1620               int samples = m_internalFormat.m_sampleRate * (float)(*it)->m_fadingTime / 1000.0f;
1621               fadingStep = delta / samples;
1622             }
1623
1624             // for stream amplification we need to run on a per sample basis
1625             if ((*it)->m_amplify != 1.0)
1626             {
1627               nb_floats = out->pkt->config.channels / out->pkt->planes;
1628               nb_loops = out->pkt->nb_samples;
1629             }
1630
1631             for(int i=0; i<nb_loops; i++)
1632             {
1633               if ((*it)->m_fadingSamples > 0)
1634               {
1635                 (*it)->m_volume += fadingStep;
1636                 (*it)->m_fadingSamples--;
1637
1638                 if ((*it)->m_fadingSamples == 0)
1639                 {
1640                   // set variables being polled via stream interface
1641                   CSingleLock lock((*it)->m_streamLock);
1642                   (*it)->m_streamFading = false;
1643                 }
1644               }
1645
1646               // volume for stream
1647               float volume = (*it)->m_volume * (*it)->m_rgain;
1648               if(nb_loops > 1)
1649                 volume *= (*it)->m_limiter.Run((float**)out->pkt->data, out->pkt->config.channels, i*nb_floats, out->pkt->planes > 1);
1650
1651               for(int j=0; j<out->pkt->planes; j++)
1652               {
1653 #ifdef __SSE__
1654                 CAEUtil::SSEMulArray((float*)out->pkt->data[j]+i*nb_floats, m_muted ? 0.0 : volume, nb_floats);
1655 #else
1656                 float* fbuffer = (float*) out->pkt->data[j]+i*nb_floats;
1657                 for (int k = 0; k < nb_floats; ++k)
1658                 {
1659                   fbuffer[k] *= m_muted ? 0.0 : volume;
1660                 }
1661 #endif
1662               }
1663             }
1664           }
1665           else
1666           {
1667             CSampleBuffer *mix = NULL;
1668             mix = (*it)->m_resampleBuffers->m_outputSamples.front();
1669             (*it)->m_resampleBuffers->m_outputSamples.pop_front();
1670
1671             int nb_floats = mix->pkt->nb_samples * mix->pkt->config.channels / mix->pkt->planes;
1672             int nb_loops = 1;
1673             float fadingStep = 0.0f;
1674
1675             // fading
1676             if ((*it)->m_fadingSamples == -1)
1677             {
1678               (*it)->m_fadingSamples = m_internalFormat.m_sampleRate * (float)(*it)->m_fadingTime / 1000.0f;
1679               (*it)->m_volume = (*it)->m_fadingBase;
1680             }
1681             if ((*it)->m_fadingSamples > 0)
1682             {
1683               nb_floats = mix->pkt->config.channels / mix->pkt->planes;
1684               nb_loops = mix->pkt->nb_samples;
1685               float delta = (*it)->m_fadingTarget - (*it)->m_fadingBase;
1686               int samples = m_internalFormat.m_sampleRate * (float)(*it)->m_fadingTime / 1000.0f;
1687               fadingStep = delta / samples;
1688             }
1689
1690             // for stream amplification we need to run on a per sample basis
1691             if ((*it)->m_amplify != 1.0)
1692             {
1693               nb_floats = out->pkt->config.channels / out->pkt->planes;
1694               nb_loops = out->pkt->nb_samples;
1695             }
1696
1697             for(int i=0; i<nb_loops; i++)
1698             {
1699               if ((*it)->m_fadingSamples > 0)
1700               {
1701                 (*it)->m_volume += fadingStep;
1702                 (*it)->m_fadingSamples--;
1703
1704                 if ((*it)->m_fadingSamples == 0)
1705                 {
1706                   // set variables being polled via stream interface
1707                   CSingleLock lock((*it)->m_streamLock);
1708                   (*it)->m_streamFading = false;
1709                 }
1710               }
1711
1712               // volume for stream
1713               float volume = (*it)->m_volume * (*it)->m_rgain;
1714               if(nb_loops > 1)
1715                 volume *= (*it)->m_limiter.Run((float**)mix->pkt->data, mix->pkt->config.channels, i*nb_floats, mix->pkt->planes > 1);
1716
1717               for(int j=0; j<out->pkt->planes && j<mix->pkt->planes; j++)
1718               {
1719                 float *dst = (float*)out->pkt->data[j]+i*nb_floats;
1720                 float *src = (float*)mix->pkt->data[j]+i*nb_floats;
1721 #ifdef __SSE__
1722                 CAEUtil::SSEMulAddArray(dst, src, m_muted ? 0.0 : volume, nb_floats);
1723                 for (int k = 0; k < nb_floats; ++k)
1724                 {
1725                   if (fabs(dst[k]) > 1.0f)
1726                   {
1727                     needClamp = true;
1728                     break;
1729                   }
1730                 }
1731 #else
1732                 for (int k = 0; k < nb_floats; ++k)
1733                 {
1734                   dst[k] += src[k] * (m_muted ? 0.0 : volume);
1735                   if (fabs(dst[k]) > 1.0f)
1736                     needClamp = true;
1737                 }
1738 #endif
1739               }
1740             }
1741             mix->Return();
1742           }
1743           busy = true;
1744         }
1745       }// for
1746
1747       // finally clamp samples
1748       if(out && needClamp)
1749       {
1750         int nb_floats = out->pkt->nb_samples * out->pkt->config.channels / out->pkt->planes;
1751         for(int i=0; i<out->pkt->planes; i++)
1752         {
1753           CAEUtil::ClampArray((float*)out->pkt->data[i], nb_floats);
1754         }
1755       }
1756
1757       // process output buffer, gui sounds, encode, viz
1758       CSampleBuffer *viz = NULL;
1759       if (out)
1760       {
1761         // mix gui sounds
1762         MixSounds(*(out->pkt));
1763         if (!m_sinkHasVolume)
1764           Deamplify(*(out->pkt));
1765
1766         // encode and backup out buffer for viz
1767         viz = out;
1768         if (m_mode == MODE_TRANSCODE && m_encoder)
1769         {
1770           CSampleBuffer *buf = m_encoderBuffers->GetFreeBuffer();
1771           m_encoder->Encode(out->pkt->data[0], out->pkt->planes*out->pkt->linesize,
1772                             buf->pkt->data[0], buf->pkt->planes*buf->pkt->linesize);
1773           buf->pkt->nb_samples = buf->pkt->max_nb_samples;
1774           out = buf;
1775         }
1776
1777         busy = true;
1778       }
1779
1780       // viz
1781       {
1782         CSingleLock lock(m_vizLock);
1783         if (m_audioCallback && m_vizBuffers && !m_streams.empty())
1784         {
1785           if (!m_vizInitialized)
1786           {
1787             m_audioCallback->OnInitialize(2, m_vizBuffers->m_format.m_sampleRate, 32);
1788             m_vizInitialized = true;
1789           }
1790
1791           // if viz has no free buffer, it won't return current buffer "viz"
1792           if (!m_vizBuffers->m_freeSamples.empty())
1793           {
1794             if (viz)
1795             {
1796               viz->Acquire();
1797               m_vizBuffers->m_inputSamples.push_back(viz);
1798             }
1799           }
1800           else
1801             CLog::Log(LOGWARNING,"ActiveAE::%s - viz ran out of free buffers", __FUNCTION__);
1802           unsigned int now = XbmcThreads::SystemClockMillis();
1803           unsigned int timestamp = now + m_stats.GetDelay() * 1000;
1804           busy |= m_vizBuffers->ResampleBuffers(timestamp);
1805           while(!m_vizBuffers->m_outputSamples.empty())
1806           {
1807             CSampleBuffer *buf = m_vizBuffers->m_outputSamples.front();
1808             if ((now - buf->timestamp) & 0x80000000)
1809               break;
1810             else
1811             {
1812               int submitted = 0;
1813               int samples;
1814               while(submitted < buf->pkt->nb_samples)
1815               {
1816                 samples = std::min(512, buf->pkt->nb_samples-submitted);
1817                 m_audioCallback->OnAudioData((float*)(buf->pkt->data[0]+2*submitted), samples);
1818                 submitted += samples;
1819               }
1820               buf->Return();
1821               m_vizBuffers->m_outputSamples.pop_front();
1822             }
1823           }
1824         }
1825         else if (m_vizBuffers)
1826           m_vizBuffers->Flush();
1827       }
1828       // update stats
1829       if(out)
1830       {
1831         m_stats.AddSamples(out->pkt->nb_samples, m_streams);
1832         m_sinkBuffers->m_inputSamples.push_back(out);
1833         if(viz && (viz != out))
1834           viz->Return();
1835       }
1836     }
1837     // pass through
1838     else
1839     {
1840       std::list<CActiveAEStream*>::iterator it;
1841       CSampleBuffer *buffer;
1842       for (it = m_streams.begin(); it != m_streams.end(); ++it)
1843       {
1844         if (!(*it)->m_resampleBuffers->m_outputSamples.empty())
1845         {
1846           buffer =  (*it)->m_resampleBuffers->m_outputSamples.front();
1847           (*it)->m_resampleBuffers->m_outputSamples.pop_front();
1848           m_stats.AddSamples(buffer->pkt->nb_samples, m_streams);
1849           m_sinkBuffers->m_inputSamples.push_back(buffer);
1850         }
1851       }
1852     }
1853
1854     // serve sink buffers
1855     busy = m_sinkBuffers->ResampleBuffers();
1856     while(!m_sinkBuffers->m_outputSamples.empty())
1857     {
1858       CSampleBuffer *out = NULL;
1859       out = m_sinkBuffers->m_outputSamples.front();
1860       m_sinkBuffers->m_outputSamples.pop_front();
1861       m_sink.m_dataPort.SendOutMessage(CSinkDataProtocol::SAMPLE,
1862           &out, sizeof(CSampleBuffer*));
1863       busy = true;
1864     }
1865   }
1866
1867   return busy;
1868 }
1869
1870 bool CActiveAE::HasWork()
1871 {
1872   if (!m_sounds_playing.empty())
1873     return true;
1874   if (!m_sinkBuffers->m_inputSamples.empty())
1875     return true;
1876   if (!m_sinkBuffers->m_outputSamples.empty())
1877     return true;
1878
1879   std::list<CActiveAEStream*>::iterator it;
1880   for (it = m_streams.begin(); it != m_streams.end(); ++it)
1881   {
1882     if (!(*it)->m_resampleBuffers->m_inputSamples.empty())
1883       return true;
1884     if (!(*it)->m_resampleBuffers->m_outputSamples.empty())
1885       return true;
1886     if (!(*it)->m_processingSamples.empty())
1887       return true;
1888   }
1889
1890   return false;
1891 }
1892
1893 void CActiveAE::MixSounds(CSoundPacket &dstSample)
1894 {
1895   if (m_sounds_playing.empty())
1896     return;
1897
1898   float volume;
1899   float *out;
1900   float *sample_buffer;
1901   int max_samples = dstSample.nb_samples;
1902
1903   std::list<SoundState>::iterator it;
1904   for (it = m_sounds_playing.begin(); it != m_sounds_playing.end(); )
1905   {
1906     if (!it->sound->IsConverted())
1907       ResampleSound(it->sound);
1908     int available_samples = it->sound->GetSound(false)->nb_samples - it->samples_played;
1909     int mix_samples = std::min(max_samples, available_samples);
1910     int start = it->samples_played *
1911                 m_dllAvUtil.av_get_bytes_per_sample(it->sound->GetSound(false)->config.fmt) *
1912                 it->sound->GetSound(false)->config.channels /
1913                 it->sound->GetSound(false)->planes;
1914
1915     for(int j=0; j<dstSample.planes; j++)
1916     {
1917       volume = it->sound->GetVolume();
1918       out = (float*)dstSample.data[j];
1919       sample_buffer = (float*)(it->sound->GetSound(false)->data[j]+start);
1920       int nb_floats = mix_samples * dstSample.config.channels / dstSample.planes;
1921 #ifdef __SSE__
1922       CAEUtil::SSEMulAddArray(out, sample_buffer, volume, nb_floats);
1923 #else
1924       for (int k = 0; k < nb_floats; ++k)
1925         *out++ += *sample_buffer++ * volume;
1926 #endif
1927     }
1928
1929     it->samples_played += mix_samples;
1930
1931     // no more frames, so remove it from the list
1932     if (it->samples_played >= it->sound->GetSound(false)->nb_samples)
1933     {
1934       it = m_sounds_playing.erase(it);
1935       continue;
1936     }
1937     ++it;
1938   }
1939 }
1940
1941 void CActiveAE::Deamplify(CSoundPacket &dstSample)
1942 {
1943   if (m_volume < 1.0)
1944   {
1945     float *buffer;
1946     int nb_floats = dstSample.nb_samples * dstSample.config.channels / dstSample.planes;
1947
1948     for(int j=0; j<dstSample.planes; j++)
1949     {
1950       buffer = (float*)dstSample.data[j];
1951 #ifdef __SSE__
1952       CAEUtil::SSEMulArray(buffer, m_muted ? 0.0 : m_volume, nb_floats);
1953 #else
1954       float *fbuffer = buffer;
1955       for (int i = 0; i < nb_floats; i++)
1956         *fbuffer++ *= m_volume;
1957 #endif
1958     }
1959   }
1960 }
1961
1962 //-----------------------------------------------------------------------------
1963 // Configuration
1964 //-----------------------------------------------------------------------------
1965
1966 void CActiveAE::LoadSettings()
1967 {
1968   m_settings.device = CSettings::Get().GetString("audiooutput.audiodevice");
1969   m_settings.passthoughdevice = CSettings::Get().GetString("audiooutput.passthroughdevice");
1970
1971   m_settings.mode = CSettings::Get().GetInt("audiooutput.mode");
1972   m_settings.channels = CSettings::Get().GetInt("audiooutput.channels");
1973
1974   m_settings.stereoupmix = CSettings::Get().GetBool("audiooutput.stereoupmix");
1975   m_settings.ac3passthrough = CSettings::Get().GetBool("audiooutput.ac3passthrough");
1976   m_settings.eac3passthrough = CSettings::Get().GetBool("audiooutput.eac3passthrough");
1977   m_settings.truehdpassthrough = CSettings::Get().GetBool("audiooutput.truehdpassthrough");
1978   m_settings.dtspassthrough = CSettings::Get().GetBool("audiooutput.dtspassthrough");
1979   m_settings.dtshdpassthrough = CSettings::Get().GetBool("audiooutput.dtshdpassthrough");
1980   m_settings.aacpassthrough = CSettings::Get().GetBool("audiooutput.passthroughaac");
1981   m_settings.multichannellpcm = CSettings::Get().GetBool("audiooutput.multichannellpcm");
1982
1983   m_settings.resampleQuality = static_cast<AEQuality>(CSettings::Get().GetInt("audiooutput.processquality"));
1984 }
1985
1986 bool CActiveAE::Initialize()
1987 {
1988   if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load())
1989   {
1990     CLog::Log(LOGERROR,"CActiveAE::Initialize - failed to load ffmpeg libraries");
1991     return false;
1992   }
1993   m_dllAvFormat.av_register_all();
1994
1995   Create();
1996   Message *reply;
1997   if (m_controlPort.SendOutMessageSync(CActiveAEControlProtocol::INIT,
1998                                                  &reply,
1999                                                  5000))
2000   {
2001     bool success = reply->signal == CActiveAEControlProtocol::ACC ? true : false;
2002     reply->Release();
2003     if (!success)
2004     {
2005       CLog::Log(LOGERROR, "ActiveAE::%s - returned error", __FUNCTION__);
2006       Dispose();
2007       return false;
2008     }
2009   }
2010   else
2011   {
2012     CLog::Log(LOGERROR, "ActiveAE::%s - failed to init", __FUNCTION__);
2013     Dispose();
2014     return false;
2015   }
2016
2017   // hook into windowing for receiving display reset events
2018 #if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
2019   g_Windowing.Register(this);
2020 #endif
2021
2022   m_inMsgEvent.Reset();
2023   return true;
2024 }
2025
2026 void CActiveAE::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
2027 {
2028   m_sink.EnumerateOutputDevices(devices, passthrough);
2029 }
2030
2031 std::string CActiveAE::GetDefaultDevice(bool passthrough)
2032 {
2033   return m_sink.GetDefaultDevice(passthrough);
2034 }
2035
2036 void CActiveAE::OnSettingsChange(const std::string& setting)
2037 {
2038   if (setting == "audiooutput.passthroughdevice" ||
2039       setting == "audiooutput.audiodevice"       ||
2040       setting == "audiooutput.mode"              ||
2041       setting == "audiooutput.ac3passthrough"    ||
2042       setting == "audiooutput.eac3passthrough"   ||
2043       setting == "audiooutput.dtspassthrough"    ||
2044       setting == "audiooutput.passthroughaac"    ||
2045       setting == "audiooutput.truehdpassthrough" ||
2046       setting == "audiooutput.dtshdpassthrough"  ||
2047       setting == "audiooutput.channels"          ||
2048       setting == "audiooutput.multichannellpcm"  ||
2049       setting == "audiooutput.stereoupmix"       ||
2050       setting == "audiooutput.streamsilence"     ||
2051       setting == "audiooutput.processquality")
2052   {
2053     m_controlPort.SendOutMessage(CActiveAEControlProtocol::RECONFIGURE);
2054   }
2055 }
2056
2057 bool CActiveAE::SupportsRaw()
2058 {
2059   return true;
2060 }
2061
2062 bool CActiveAE::SupportsDrain()
2063 {
2064   return true;
2065 }
2066
2067 bool CActiveAE::SupportsQualityLevel(enum AEQuality level)
2068 {
2069   if (level == AE_QUALITY_LOW || level == AE_QUALITY_MID || level == AE_QUALITY_HIGH)
2070     return true;
2071
2072   return false;
2073 }
2074
2075 void CActiveAE::Shutdown()
2076 {
2077   Dispose();
2078 }
2079
2080 bool CActiveAE::Suspend()
2081 {
2082   return m_controlPort.SendOutMessage(CActiveAEControlProtocol::SUSPEND);
2083 }
2084
2085 bool CActiveAE::Resume()
2086 {
2087   Message *reply;
2088   if (m_controlPort.SendOutMessageSync(CActiveAEControlProtocol::INIT,
2089                                                  &reply,
2090                                                  5000))
2091   {
2092     bool success = reply->signal == CActiveAEControlProtocol::ACC ? true : false;
2093     reply->Release();
2094     if (!success)
2095     {
2096       CLog::Log(LOGERROR, "ActiveAE::%s - returned error", __FUNCTION__);
2097       return false;
2098     }
2099   }
2100   else
2101   {
2102     CLog::Log(LOGERROR, "ActiveAE::%s - failed to init", __FUNCTION__);
2103     return false;
2104   }
2105
2106   m_inMsgEvent.Reset();
2107   return true;
2108 }
2109
2110 bool CActiveAE::IsSuspended()
2111 {
2112   return m_stats.IsSuspended();
2113 }
2114
2115 float CActiveAE::GetVolume()
2116 {
2117   return m_aeVolume;
2118 }
2119
2120 void CActiveAE::SetVolume(const float volume)
2121 {
2122   m_aeVolume = std::max( 0.0f, std::min(1.0f, volume));
2123   m_controlPort.SendOutMessage(CActiveAEControlProtocol::VOLUME, &m_aeVolume, sizeof(float));
2124 }
2125
2126 void CActiveAE::SetMute(const bool enabled)
2127 {
2128   m_aeMuted = enabled;
2129   m_controlPort.SendOutMessage(CActiveAEControlProtocol::MUTE, &m_aeMuted, sizeof(bool));
2130 }
2131
2132 bool CActiveAE::IsMuted()
2133 {
2134   return m_aeMuted;
2135 }
2136
2137 void CActiveAE::SetSoundMode(const int mode)
2138 {
2139   int soundmode = mode;
2140   m_controlPort.SendOutMessage(CActiveAEControlProtocol::SOUNDMODE, &soundmode, sizeof(int));
2141 }
2142
2143
2144 void CActiveAE::OnLostDevice()
2145 {
2146 //  m_controlPort.SendOutMessage(CActiveAEControlProtocol::DISPLAYLOST);
2147 }
2148
2149 void CActiveAE::OnResetDevice()
2150 {
2151 //  m_controlPort.SendOutMessage(CActiveAEControlProtocol::DISPLAYRESET);
2152 }
2153
2154 //-----------------------------------------------------------------------------
2155 // Utils
2156 //-----------------------------------------------------------------------------
2157
2158 uint8_t **CActiveAE::AllocSoundSample(SampleConfig &config, int &samples, int &bytes_per_sample, int &planes, int &linesize)
2159 {
2160   uint8_t **buffer;
2161   planes = m_dllAvUtil.av_sample_fmt_is_planar(config.fmt) ? config.channels : 1;
2162   buffer = new uint8_t*[planes];
2163
2164   // align buffer to 16 in order to be compatible with sse in CAEConvert
2165   m_dllAvUtil.av_samples_alloc(buffer, &linesize, config.channels,
2166                                  samples, config.fmt, 16);
2167   bytes_per_sample = m_dllAvUtil.av_get_bytes_per_sample(config.fmt);
2168   return buffer;
2169 }
2170
2171 void CActiveAE::FreeSoundSample(uint8_t **data)
2172 {
2173   m_dllAvUtil.av_freep(data);
2174   delete [] data;
2175 }
2176
2177 bool CActiveAE::CompareFormat(AEAudioFormat &lhs, AEAudioFormat &rhs)
2178 {
2179   if (lhs.m_channelLayout != rhs.m_channelLayout ||
2180       lhs.m_dataFormat != rhs.m_dataFormat ||
2181       lhs.m_sampleRate != rhs.m_sampleRate ||
2182       lhs.m_frames != rhs.m_frames)
2183     return false;
2184   else
2185     return true;
2186 }
2187
2188 //-----------------------------------------------------------------------------
2189 // GUI Sounds
2190 //-----------------------------------------------------------------------------
2191
2192 /**
2193  * load sound from an audio file and store original format
2194  * register the sound in ActiveAE
2195  * later when the engine is idle it will convert the sound to sink format
2196  */
2197
2198 #define SOUNDBUFFER_SIZE 20480
2199
2200 IAESound *CActiveAE::MakeSound(const std::string& file)
2201 {
2202   AVFormatContext *fmt_ctx = NULL;
2203   AVCodecContext *dec_ctx = NULL;
2204   AVIOContext *io_ctx;
2205   AVInputFormat *io_fmt;
2206   AVCodec *dec = NULL;
2207   CActiveAESound *sound = NULL;
2208   SampleConfig config;
2209
2210   sound = new CActiveAESound(file);
2211   if (!sound->Prepare())
2212   {
2213     delete sound;
2214     return NULL;
2215   }
2216   int fileSize = sound->GetFileSize();
2217
2218   fmt_ctx = m_dllAvFormat.avformat_alloc_context();
2219   unsigned char* buffer = (unsigned char*)m_dllAvUtil.av_malloc(SOUNDBUFFER_SIZE+FF_INPUT_BUFFER_PADDING_SIZE);
2220   io_ctx = m_dllAvFormat.avio_alloc_context(buffer, SOUNDBUFFER_SIZE, 0,
2221                                             sound, CActiveAESound::Read, NULL, CActiveAESound::Seek);
2222   io_ctx->max_packet_size = sound->GetChunkSize();
2223   if(io_ctx->max_packet_size)
2224     io_ctx->max_packet_size *= SOUNDBUFFER_SIZE / io_ctx->max_packet_size;
2225
2226   if(!sound->IsSeekPosible())
2227     io_ctx->seekable = 0;
2228
2229   fmt_ctx->pb = io_ctx;
2230
2231   m_dllAvFormat.av_probe_input_buffer(io_ctx, &io_fmt, file.c_str(), NULL, 0, 0);
2232   if (!io_fmt)
2233   {
2234     m_dllAvFormat.avformat_close_input(&fmt_ctx);
2235     delete sound;
2236     return NULL;
2237   }
2238
2239   // find decoder
2240   if (m_dllAvFormat.avformat_open_input(&fmt_ctx, file.c_str(), NULL, NULL) == 0)
2241   {
2242     fmt_ctx->flags |= AVFMT_FLAG_NOPARSE;
2243     if (m_dllAvFormat.avformat_find_stream_info(fmt_ctx, NULL) >= 0)
2244     {
2245       dec_ctx = fmt_ctx->streams[0]->codec;
2246       dec = m_dllAvCodec.avcodec_find_decoder(dec_ctx->codec_id);
2247       config.sample_rate = dec_ctx->sample_rate;
2248       config.channels = dec_ctx->channels;
2249       config.channel_layout = dec_ctx->channel_layout;
2250     }
2251   }
2252   if (dec == NULL)
2253   {
2254     m_dllAvFormat.avformat_close_input(&fmt_ctx);
2255     delete sound;
2256     return NULL;
2257   }
2258
2259   dec_ctx = m_dllAvCodec.avcodec_alloc_context3(dec);
2260   dec_ctx->sample_rate = config.sample_rate;
2261   dec_ctx->channels = config.channels;
2262   if (!config.channel_layout)
2263     config.channel_layout = m_dllAvUtil.av_get_default_channel_layout(config.channels);
2264   dec_ctx->channel_layout = config.channel_layout;
2265
2266   AVPacket avpkt;
2267   AVFrame *decoded_frame = NULL;
2268   decoded_frame = m_dllAvCodec.avcodec_alloc_frame();
2269
2270   if (m_dllAvCodec.avcodec_open2(dec_ctx, dec, NULL) >= 0)
2271   {
2272     bool init = false;
2273
2274     // decode until eof
2275     m_dllAvCodec.av_init_packet(&avpkt);
2276     int len;
2277     while (m_dllAvFormat.av_read_frame(fmt_ctx, &avpkt) >= 0)
2278     {
2279       int got_frame = 0;
2280       len = m_dllAvCodec.avcodec_decode_audio4(dec_ctx, decoded_frame, &got_frame, &avpkt);
2281       if (len < 0)
2282       {
2283         m_dllAvCodec.avcodec_close(dec_ctx);
2284         m_dllAvUtil.av_free(dec_ctx);
2285         m_dllAvUtil.av_free(&decoded_frame);
2286         m_dllAvFormat.avformat_close_input(&fmt_ctx);
2287         delete sound;
2288         return NULL;
2289       }
2290       if (got_frame)
2291       {
2292         if (!init)
2293         {
2294           int samples = fileSize / m_dllAvUtil.av_get_bytes_per_sample(dec_ctx->sample_fmt) / config.channels;
2295           config.fmt = dec_ctx->sample_fmt;
2296           config.bits_per_sample = dec_ctx->bits_per_coded_sample;
2297           sound->InitSound(true, config, samples);
2298           init = true;
2299         }
2300         sound->StoreSound(true, decoded_frame->extended_data,
2301                           decoded_frame->nb_samples, decoded_frame->linesize[0]);
2302       }
2303     }
2304     m_dllAvCodec.avcodec_close(dec_ctx);
2305   }
2306
2307   m_dllAvUtil.av_free(dec_ctx);
2308   m_dllAvUtil.av_free(decoded_frame);
2309   m_dllAvFormat.avformat_close_input(&fmt_ctx);
2310
2311   sound->Finish();
2312
2313   // register sound
2314   m_dataPort.SendOutMessage(CActiveAEDataProtocol::NEWSOUND, &sound, sizeof(CActiveAESound*));
2315
2316   return sound;
2317 }
2318
2319 void CActiveAE::FreeSound(IAESound *sound)
2320 {
2321   m_dataPort.SendOutMessage(CActiveAEDataProtocol::FREESOUND, &sound, sizeof(CActiveAESound*));
2322 }
2323
2324 void CActiveAE::PlaySound(CActiveAESound *sound)
2325 {
2326   m_dataPort.SendOutMessage(CActiveAEDataProtocol::PLAYSOUND, &sound, sizeof(CActiveAESound*));
2327 }
2328
2329 void CActiveAE::StopSound(CActiveAESound *sound)
2330 {
2331   m_controlPort.SendOutMessage(CActiveAEControlProtocol::STOPSOUND, &sound, sizeof(CActiveAESound*));
2332 }
2333
2334 /**
2335  * resample sounds to destination format for mixing
2336  * destination format is either format of stream or
2337  * default sink format when no stream is playing
2338  */
2339 void CActiveAE::ResampleSounds()
2340 {
2341   std::vector<CActiveAESound*>::iterator it;
2342   for (it = m_sounds.begin(); it != m_sounds.end(); ++it)
2343   {
2344     if (!(*it)->IsConverted())
2345     {
2346       ResampleSound(*it);
2347       // only do one sound, then yield to main loop
2348       break;
2349     }
2350   }
2351 }
2352
2353 bool CActiveAE::ResampleSound(CActiveAESound *sound)
2354 {
2355   SampleConfig orig_config, dst_config;
2356   uint8_t **dst_buffer;
2357   int dst_samples;
2358
2359   if (m_mode == MODE_RAW || m_internalFormat.m_dataFormat == AE_FMT_INVALID)
2360     return false;
2361
2362   if (!sound->GetSound(true))
2363     return false;
2364
2365   orig_config = sound->GetSound(true)->config;
2366
2367   dst_config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_internalFormat.m_channelLayout);
2368   dst_config.channels = m_internalFormat.m_channelLayout.Count();
2369   dst_config.sample_rate = m_internalFormat.m_sampleRate;
2370   dst_config.fmt = CActiveAEResample::GetAVSampleFormat(m_internalFormat.m_dataFormat);
2371   dst_config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_internalFormat.m_dataFormat);
2372
2373   CActiveAEResample *resampler = new CActiveAEResample();
2374   resampler->Init(dst_config.channel_layout,
2375                   dst_config.channels,
2376                   dst_config.sample_rate,
2377                   dst_config.fmt,
2378                   dst_config.bits_per_sample,
2379                   orig_config.channel_layout,
2380                   orig_config.channels,
2381                   orig_config.sample_rate,
2382                   orig_config.fmt,
2383                   orig_config.bits_per_sample,
2384                   false,
2385                   NULL,
2386                   AE_QUALITY_MID);
2387
2388   dst_samples = resampler->CalcDstSampleCount(sound->GetSound(true)->nb_samples,
2389                                               m_internalFormat.m_sampleRate,
2390                                               orig_config.sample_rate);
2391
2392   dst_buffer = sound->InitSound(false, dst_config, dst_samples);
2393   if (!dst_buffer)
2394   {
2395     delete resampler;
2396     return false;
2397   }
2398   int samples = resampler->Resample(dst_buffer, dst_samples,
2399                                     sound->GetSound(true)->data,
2400                                     sound->GetSound(true)->nb_samples,
2401                                     1.0);
2402
2403   sound->GetSound(false)->nb_samples = samples;
2404
2405   delete resampler;
2406   sound->SetConverted(true);
2407   return true;
2408 }
2409
2410 //-----------------------------------------------------------------------------
2411 // Streams
2412 //-----------------------------------------------------------------------------
2413
2414 IAEStream *CActiveAE::MakeStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options)
2415 {
2416   //TODO: pass number of samples in audio packet
2417
2418   AEAudioFormat format;
2419   format.m_dataFormat = dataFormat;
2420   format.m_sampleRate = sampleRate;
2421   format.m_encodedRate = encodedSampleRate;
2422   format.m_channelLayout = channelLayout;
2423   format.m_frames = format.m_sampleRate / 10;
2424   format.m_frameSize = format.m_channelLayout.Count() *
2425                        (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3);
2426
2427   MsgStreamNew msg;
2428   msg.format = format;
2429   msg.options = options;
2430
2431   Message *reply;
2432   if (m_dataPort.SendOutMessageSync(CActiveAEDataProtocol::NEWSTREAM,
2433                                     &reply,10000,
2434                                     &msg, sizeof(MsgStreamNew)))
2435   {
2436     bool success = reply->signal == CActiveAEControlProtocol::ACC ? true : false;
2437     if (success)
2438     {
2439       CActiveAEStream *stream = *(CActiveAEStream**)reply->data;
2440       reply->Release();
2441       return stream;
2442     }
2443     reply->Release();
2444   }
2445
2446   CLog::Log(LOGERROR, "ActiveAE::%s - could not create stream", __FUNCTION__);
2447   return NULL;
2448 }
2449
2450 IAEStream *CActiveAE::FreeStream(IAEStream *stream)
2451 {
2452   m_dataPort.SendOutMessage(CActiveAEDataProtocol::FREESTREAM, &stream, sizeof(IAEStream*));
2453   return NULL;
2454 }
2455
2456 void CActiveAE::FlushStream(CActiveAEStream *stream)
2457 {
2458   Message *reply;
2459   if (m_controlPort.SendOutMessageSync(CActiveAEControlProtocol::FLUSHSTREAM,
2460                                        &reply,1000,
2461                                        &stream, sizeof(CActiveAEStream*)))
2462   {
2463     bool success = reply->signal == CActiveAEControlProtocol::ACC ? true : false;
2464     reply->Release();
2465     if (!success)
2466     {
2467       CLog::Log(LOGERROR, "CActiveAE::FlushStream - failed");
2468     }
2469   }
2470 }
2471
2472 void CActiveAE::PauseStream(CActiveAEStream *stream, bool pause)
2473 {
2474   // TODO pause sink, needs api change
2475   if (pause)
2476     m_controlPort.SendOutMessage(CActiveAEControlProtocol::PAUSESTREAM,
2477                                    &stream, sizeof(CActiveAEStream*));
2478   else
2479     m_controlPort.SendOutMessage(CActiveAEControlProtocol::RESUMESTREAM,
2480                                    &stream, sizeof(CActiveAEStream*));
2481 }
2482
2483 void CActiveAE::SetStreamAmplification(CActiveAEStream *stream, float amplify)
2484 {
2485   MsgStreamParameter msg;
2486   msg.stream = stream;
2487   msg.parameter.float_par = amplify;
2488   m_controlPort.SendOutMessage(CActiveAEControlProtocol::STREAMAMP,
2489                                      &msg, sizeof(MsgStreamParameter));
2490 }
2491
2492 void CActiveAE::SetStreamReplaygain(CActiveAEStream *stream, float rgain)
2493 {
2494   MsgStreamParameter msg;
2495   msg.stream = stream;
2496   msg.parameter.float_par = rgain;
2497   m_controlPort.SendOutMessage(CActiveAEControlProtocol::STREAMRGAIN,
2498                                      &msg, sizeof(MsgStreamParameter));
2499 }
2500
2501 void CActiveAE::SetStreamVolume(CActiveAEStream *stream, float volume)
2502 {
2503   MsgStreamParameter msg;
2504   msg.stream = stream;
2505   msg.parameter.float_par = volume;
2506   m_controlPort.SendOutMessage(CActiveAEControlProtocol::STREAMVOLUME,
2507                                      &msg, sizeof(MsgStreamParameter));
2508 }
2509
2510 void CActiveAE::SetStreamResampleRatio(CActiveAEStream *stream, double ratio)
2511 {
2512   MsgStreamParameter msg;
2513   msg.stream = stream;
2514   msg.parameter.double_par = ratio;
2515   m_controlPort.SendOutMessage(CActiveAEControlProtocol::STREAMRESAMPLERATIO,
2516                                      &msg, sizeof(MsgStreamParameter));
2517 }
2518
2519 void CActiveAE::SetStreamFade(CActiveAEStream *stream, float from, float target, unsigned int millis)
2520 {
2521   MsgStreamFade msg;
2522   msg.stream = stream;
2523   msg.from = from;
2524   msg.target = target;
2525   msg.millis = millis;
2526   m_controlPort.SendOutMessage(CActiveAEControlProtocol::STREAMFADE,
2527                                      &msg, sizeof(MsgStreamFade));
2528 }
2529
2530 void CActiveAE::RegisterAudioCallback(IAudioCallback* pCallback)
2531 {
2532   CSingleLock lock(m_vizLock);
2533   m_audioCallback = pCallback;
2534   m_vizInitialized = false;
2535 }
2536
2537 void CActiveAE::UnregisterAudioCallback()
2538 {
2539   CSingleLock lock(m_vizLock);
2540   m_audioCallback = NULL;
2541 }