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