[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / cores / dvdplayer / DVDPlayerAudio.h
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.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 #pragma once
22 #include "threads/Thread.h"
23
24 #include "DVDAudio.h"
25 #include "DVDClock.h"
26 #include "DVDMessageQueue.h"
27 #include "DVDDemuxers/DVDDemuxUtils.h"
28 #include "DVDStreamInfo.h"
29 #include "utils/BitstreamStats.h"
30
31 #include "cores/AudioEngine/AEAudioFormat.h"
32
33 #include <list>
34 #include <queue>
35
36 class CDVDPlayer;
37 class CDVDAudioCodec;
38 class IAudioCallback;
39 class CDVDAudioCodec;
40
41 enum CodecID;
42
43 #define DECODE_FLAG_DROP    1
44 #define DECODE_FLAG_RESYNC  2
45 #define DECODE_FLAG_ERROR   4
46 #define DECODE_FLAG_ABORT   8
47 #define DECODE_FLAG_TIMEOUT 16
48
49 typedef struct stDVDAudioFrame
50 {
51   BYTE* data;
52   double pts;
53   double duration;
54   unsigned int size;
55
56   int               channel_count;
57   int               encoded_channel_count;
58   CAEChannelInfo    channel_layout;
59   enum AEDataFormat data_format;
60   int               bits_per_sample;
61   int               sample_rate;
62   int               encoded_sample_rate;
63   bool              passthrough;
64 } DVDAudioFrame;
65
66 class CPTSInputQueue
67 {
68 private:
69   typedef std::list<std::pair<int64_t, double> >::iterator IT;
70   std::list<std::pair<int64_t, double> > m_list;
71   CCriticalSection m_sync;
72 public:
73   void   Add(int64_t bytes, double pts);
74   double Get(int64_t bytes, bool consume);
75   void   Flush();
76 };
77
78 class CDVDPlayerAudio : public CThread
79 {
80 public:
81   CDVDPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent);
82   virtual ~CDVDPlayerAudio();
83
84   bool OpenStream(CDVDStreamInfo &hints);
85   void OpenStream(CDVDStreamInfo &hints, CDVDAudioCodec* codec);
86   void CloseStream(bool bWaitForBuffers);
87
88   void RegisterAudioCallback(IAudioCallback* pCallback) { m_dvdAudio.RegisterAudioCallback(pCallback); }
89   void UnRegisterAudioCallback()                        { m_dvdAudio.UnRegisterAudioCallback(); }
90
91   void SetSpeed(int speed);
92   void Flush();
93
94   // waits until all available data has been rendered
95   void WaitForBuffers();
96   bool AcceptsData() const                              { return !m_messageQueue.IsFull(); }
97   bool HasData() const                                  { return m_messageQueue.GetDataSize() > 0; }
98   int  GetLevel() const                                 { return m_messageQueue.GetLevel(); }
99   bool IsInited() const                                 { return m_messageQueue.IsInited(); }
100   void SendMessage(CDVDMsg* pMsg, int priority = 0)     { m_messageQueue.Put(pMsg, priority); }
101
102   //! Switch codec if needed. Called when the sample rate gotten from the
103   //! codec changes, in which case we may want to switch passthrough on/off.
104   bool SwitchCodecIfNeeded();
105
106   void SetVolume(float fVolume)                         { m_dvdAudio.SetVolume(fVolume); }
107   void SetDynamicRangeCompression(long drc)             { m_dvdAudio.SetDynamicRangeCompression(drc); }
108   float GetCurrentAttenuation()                         { return m_dvdAudio.GetCurrentAttenuation(); }
109
110   std::string GetPlayerInfo();
111   int GetAudioBitrate();
112
113   // holds stream information for current playing stream
114   CDVDStreamInfo m_streaminfo;
115
116   CPTSOutputQueue m_ptsOutput;
117   CPTSInputQueue  m_ptsInput;
118
119   double GetCurrentPts()                            { return m_dvdAudio.GetPlayingPts(); }
120
121   bool IsStalled()                                  { return m_stalled;  }
122   bool IsPassthrough() const;
123 protected:
124
125   virtual void OnStartup();
126   virtual void OnExit();
127   virtual void Process();
128
129   int DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket);
130
131   CDVDMessageQueue m_messageQueue;
132   CDVDMessageQueue& m_messageParent;
133
134   double m_audioClock;
135
136   // data for audio decoding
137   struct PacketStatus
138   {
139     PacketStatus()
140     {
141         msg = NULL;
142         Release();
143     }
144
145    ~PacketStatus()
146     {
147         Release();
148     }
149
150     CDVDMsgDemuxerPacket*  msg;
151     BYTE*                  data;
152     int                    size;
153     double                 dts;
154
155     void Attach(CDVDMsgDemuxerPacket* msg2)
156     {
157       if(msg) msg->Release();
158       msg = msg2;
159       msg->Acquire();
160       DemuxPacket* p = msg->GetPacket();
161       data = p->pData;
162       size = p->iSize;
163       dts = p->dts;
164
165     }
166     void Release()
167     {
168       if(msg) msg->Release();
169       msg  = NULL;
170       data = NULL;
171       size = 0;
172       dts  = DVD_NOPTS_VALUE;
173     }
174   } m_decode;
175
176   CDVDAudio m_dvdAudio; // audio output device
177   CDVDClock* m_pClock; // dvd master clock
178   CDVDAudioCodec* m_pAudioCodec; // audio codec
179   BitstreamStats m_audioStats;
180
181   int     m_speed;
182   double  m_droptime;
183   bool    m_stalled;
184   bool    m_started;
185   double  m_duration; // last packets duration
186   bool    m_silence;
187
188   bool OutputPacket(DVDAudioFrame &audioframe);
189
190   //SYNC_DISCON, SYNC_SKIPDUP, SYNC_RESAMPLE
191   int    m_synctype;
192   int    m_setsynctype;
193   int    m_prevsynctype; //so we can print to the log
194
195   double m_error;    //last average error
196
197   int64_t m_errortime; //timestamp of last time we measured
198   int64_t m_freq;
199
200   void   SetSyncType(bool passthrough);
201   void   HandleSyncError(double duration);
202   double m_errorbuff; //place to store average errors
203   int    m_errorcount;//number of errors stored
204   bool   m_syncclock;
205
206   double m_integral; //integral correction for resampler
207   int    m_skipdupcount; //counter for skip/duplicate synctype
208   bool   m_prevskipped;
209   double m_maxspeedadjust;
210   double m_resampleratio; //resample ratio when using SYNC_RESAMPLE, used for the codec info
211 };
212