Merge pull request #3819 from arnova/subtitles_for_stacks
[vuplus_xbmc] / xbmc / cores / AudioEngine / Engines / ActiveAE / ActiveAE.h
1 #pragma once
2 /*
3  *      Copyright (C) 2010-2013 Team XBMC
4  *      http://xbmc.org
5  *
6  *  This Program 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, or (at your option)
9  *  any later version.
10  *
11  *  This Program 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 XBMC; see the file COPYING.  If not, see
18  *  <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include "system.h"
23 #include "threads/Thread.h"
24
25 #include "ActiveAESink.h"
26 #include "ActiveAEResample.h"
27 #include "cores/AudioEngine/Interfaces/AEStream.h"
28 #include "cores/AudioEngine/Interfaces/AESound.h"
29 #include "cores/AudioEngine/AEFactory.h"
30 #include "guilib/DispResource.h"
31
32 // ffmpeg
33 #include "DllAvFormat.h"
34 #include "DllAvCodec.h"
35 #include "DllAvUtil.h"
36
37 class IAESink;
38 class IAEEncoder;
39
40 namespace ActiveAE
41 {
42
43 class CActiveAESound;
44 class CActiveAEStream;
45
46 struct AudioSettings
47 {
48   std::string device;
49   std::string driver;
50   std::string passthoughdevice;
51   int channels;
52   bool ac3passthrough;
53   bool ac3transcode;
54   bool eac3passthrough;
55   bool dtspassthrough;
56   bool truehdpassthrough;
57   bool dtshdpassthrough;
58   bool stereoupmix;
59   bool normalizelevels;
60   bool passthrough;
61   int config;
62   int guisoundmode;
63   unsigned int samplerate;
64   AEQuality resampleQuality;
65 };
66
67 class CActiveAEControlProtocol : public Protocol
68 {
69 public:
70   CActiveAEControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
71   enum OutSignal
72   {
73     INIT = 0,
74     RECONFIGURE,
75     SUSPEND,
76     MUTE,
77     VOLUME,
78     PAUSESTREAM,
79     RESUMESTREAM,
80     FLUSHSTREAM,
81     STREAMRGAIN,
82     STREAMVOLUME,
83     STREAMAMP,
84     STREAMRESAMPLERATIO,
85     STREAMFADE,
86     STOPSOUND,
87     GETSTATE,
88     DISPLAYLOST,
89     DISPLAYRESET,
90     KEEPCONFIG,
91     TIMEOUT,
92   };
93   enum InSignal
94   {
95     ACC,
96     ERR,
97     STATS,
98   };
99 };
100
101 class CActiveAEDataProtocol : public Protocol
102 {
103 public:
104   CActiveAEDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
105   enum OutSignal
106   {
107     NEWSOUND = 0,
108     PLAYSOUND,
109     FREESOUND,
110     NEWSTREAM,
111     FREESTREAM,
112     STREAMSAMPLE,
113     DRAINSTREAM,
114   };
115   enum InSignal
116   {
117     ACC,
118     ERR,
119     STREAMBUFFER,
120     STREAMDRAINED,
121   };
122 };
123
124 struct MsgStreamNew
125 {
126   AEAudioFormat format;
127   unsigned int options;
128 };
129
130 struct MsgStreamSample
131 {
132   CSampleBuffer *buffer;
133   CActiveAEStream *stream;
134 };
135
136 struct MsgStreamParameter
137 {
138   CActiveAEStream *stream;
139   union
140   {
141     float float_par;
142     double double_par;
143   } parameter;
144 };
145
146 struct MsgStreamFade
147 {
148   CActiveAEStream *stream;
149   float from;
150   float target;
151   unsigned int millis;
152 };
153
154 class CEngineStats
155 {
156 public:
157   void Reset(unsigned int sampleRate);
158   void UpdateSinkDelay(double delay, int samples);
159   void AddSamples(int samples, std::list<CActiveAEStream*> &streams);
160   float GetDelay();
161   float GetDelay(CActiveAEStream *stream);
162   float GetCacheTime(CActiveAEStream *stream);
163   float GetCacheTotal(CActiveAEStream *stream);
164   float GetWaterLevel();
165   void SetSuspended(bool state);
166   void SetSinkCacheTotal(float time) { m_sinkCacheTotal = time; }
167   void SetSinkLatency(float time) { m_sinkLatency = time; }
168   bool IsSuspended();
169   CCriticalSection *GetLock() { return &m_lock; }
170 protected:
171   float m_sinkDelay;
172   float m_sinkCacheTotal;
173   float m_sinkLatency;
174   int m_bufferedSamples;
175   unsigned int m_sinkSampleRate;
176   unsigned int m_sinkUpdate;
177   bool m_suspended;
178   CCriticalSection m_lock;
179 };
180
181 #if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
182 class CActiveAE : public IAE, public IDispResource, private CThread
183 #else
184 class CActiveAE : public IAE, private CThread
185 #endif
186 {
187 protected:
188   friend class ::CAEFactory;
189   friend class CActiveAESound;
190   friend class CActiveAEStream;
191   friend class CSoundPacket;
192   friend class CActiveAEBufferPoolResample;
193   CActiveAE();
194   virtual ~CActiveAE();
195   virtual bool  Initialize();
196
197 public:
198   virtual void   Shutdown();
199   virtual bool   Suspend();
200   virtual bool   Resume();
201   virtual bool   IsSuspended();
202   virtual void   OnSettingsChange(const std::string& setting);
203
204   virtual float GetVolume();
205   virtual void  SetVolume(const float volume);
206   virtual void  SetMute(const bool enabled);
207   virtual bool  IsMuted();
208   virtual void  SetSoundMode(const int mode);
209
210   /* returns a new stream for data in the specified format */
211   virtual IAEStream *MakeStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options = 0);
212   virtual IAEStream *FreeStream(IAEStream *stream);
213
214   /* returns a new sound object */
215   virtual IAESound *MakeSound(const std::string& file);
216   virtual void      FreeSound(IAESound *sound);
217
218   virtual void GarbageCollect() {};
219
220   virtual void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
221   virtual std::string GetDefaultDevice(bool passthrough);
222   virtual bool SupportsRaw(AEDataFormat format);
223   virtual bool SupportsSilenceTimeout();
224   virtual bool SupportsQualityLevel(enum AEQuality level);
225   virtual bool IsSettingVisible(const std::string &settingId);
226   virtual void KeepConfiguration(unsigned int millis);
227
228   virtual void RegisterAudioCallback(IAudioCallback* pCallback);
229   virtual void UnregisterAudioCallback();
230
231   virtual void OnLostDevice();
232   virtual void OnResetDevice();
233
234 protected:
235   void PlaySound(CActiveAESound *sound);
236   uint8_t **AllocSoundSample(SampleConfig &config, int &samples, int &bytes_per_sample, int &planes, int &linesize);
237   void FreeSoundSample(uint8_t **data);
238   float GetDelay(CActiveAEStream *stream) { return m_stats.GetDelay(stream); }
239   float GetCacheTime(CActiveAEStream *stream) { return m_stats.GetCacheTime(stream); }
240   float GetCacheTotal(CActiveAEStream *stream) { return m_stats.GetCacheTotal(stream); }
241   void FlushStream(CActiveAEStream *stream);
242   void PauseStream(CActiveAEStream *stream, bool pause);
243   void StopSound(CActiveAESound *sound);
244   void SetStreamAmplification(CActiveAEStream *stream, float amplify);
245   void SetStreamReplaygain(CActiveAEStream *stream, float rgain);
246   void SetStreamVolume(CActiveAEStream *stream, float volume);
247   void SetStreamResampleRatio(CActiveAEStream *stream, double ratio);
248   void SetStreamFade(CActiveAEStream *stream, float from, float target, unsigned int millis);
249
250 protected:
251   void Process();
252   void StateMachine(int signal, Protocol *port, Message *msg);
253   bool InitSink();
254   void DrainSink();
255   void UnconfigureSink();
256   void Start();
257   void Dispose();
258   void LoadSettings();
259   bool NeedReconfigureBuffers();
260   bool NeedReconfigureSink();
261   void ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode = NULL);
262   void Configure(AEAudioFormat *desiredFmt = NULL);
263   AEAudioFormat GetInputFormat(AEAudioFormat *desiredFmt = NULL);
264   CActiveAEStream* CreateStream(MsgStreamNew *streamMsg);
265   void DiscardStream(CActiveAEStream *stream);
266   void SFlushStream(CActiveAEStream *stream);
267   void FlushEngine();
268   void ClearDiscardedBuffers();
269   void SStopSound(CActiveAESound *sound);
270   void DiscardSound(CActiveAESound *sound);
271   void ChangeResamplers();
272
273   bool RunStages();
274   bool HasWork();
275
276   void ResampleSounds();
277   bool ResampleSound(CActiveAESound *sound);
278   void MixSounds(CSoundPacket &dstSample);
279   void Deamplify(CSoundPacket &dstSample);
280
281   bool CompareFormat(AEAudioFormat &lhs, AEAudioFormat &rhs);
282
283   CEvent m_inMsgEvent;
284   CEvent m_outMsgEvent;
285   CActiveAEControlProtocol m_controlPort;
286   CActiveAEDataProtocol m_dataPort;
287   int m_state;
288   bool m_bStateMachineSelfTrigger;
289   int m_extTimeout;
290   bool m_extError;
291   bool m_extDrain;
292   XbmcThreads::EndTime m_extDrainTimer;
293   unsigned int m_extKeepConfig;
294   bool m_extDeferData;
295
296   enum
297   {
298     MODE_RAW,
299     MODE_TRANSCODE,
300     MODE_PCM
301   }m_mode;
302
303   CActiveAESink m_sink;
304   AEAudioFormat m_sinkFormat;
305   AEAudioFormat m_sinkRequestFormat;
306   AEAudioFormat m_encoderFormat;
307   AEAudioFormat m_internalFormat;
308   AEAudioFormat m_inputFormat;
309   AudioSettings m_settings;
310   CEngineStats m_stats;
311   IAEEncoder *m_encoder;
312   std::string m_currDevice;
313
314   // buffers
315   CActiveAEBufferPoolResample *m_sinkBuffers;
316   CActiveAEBufferPoolResample *m_vizBuffers;
317   CActiveAEBufferPool *m_vizBuffersInput;
318   CActiveAEBufferPool *m_silenceBuffers;  // needed to drive gui sounds if we have no streams
319   CActiveAEBufferPool *m_encoderBuffers;
320
321   // streams
322   std::list<CActiveAEStream*> m_streams;
323   std::list<CActiveAEBufferPool*> m_discardBufferPools;
324
325   // gui sounds
326   struct SoundState
327   {
328     CActiveAESound *sound;
329     int samples_played;
330   };
331   std::list<SoundState> m_sounds_playing;
332   std::vector<CActiveAESound*> m_sounds;
333
334   float m_volume;
335   bool m_muted;
336   bool m_sinkHasVolume;
337
338   // viz
339   IAudioCallback *m_audioCallback;
340   bool m_vizInitialized;
341   CCriticalSection m_vizLock;
342
343   // ffmpeg
344   DllAvFormat m_dllAvFormat;
345   DllAvCodec  m_dllAvCodec;
346   DllAvUtil   m_dllAvUtil;
347
348   // polled via the interface
349   float m_aeVolume;
350   bool m_aeMuted;
351 };
352 };