added: audio synctypes
[xbmc:xbmc-antiquated.git] / XBMC / xbmc / cores / dvdplayer / DVDPlayerAudio.h
1 /*
2  *      Copyright (C) 2005-2008 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, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #pragma once
23 #include "../../utils/Thread.h"
24
25 #include "DVDAudio.h"
26 #include "DVDClock.h"
27 #include "DVDMessageQueue.h"
28 #include "DVDDemuxers/DVDDemuxUtils.h"
29 #include "DVDStreamInfo.h"
30 #include "BitstreamStats.h"
31 #include "DVDPlayerAudioResampler.h"
32
33 class CDVDPlayer;
34 class CDVDAudioCodec;
35 class IAudioCallback;
36 class CDVDAudioCodec;
37
38 enum CodecID;
39
40 #define DECODE_FLAG_DROP    1
41 #define DECODE_FLAG_RESYNC  2
42 #define DECODE_FLAG_ERROR   4
43 #define DECODE_FLAG_ABORT   8
44 #define DECODE_FLAG_TIMEOUT 16
45
46 typedef struct stDVDAudioFrame
47 {
48   BYTE* data;
49   double pts;
50   double duration;
51   unsigned int size;
52
53   int channels;
54   int bits_per_sample;
55   int sample_rate;
56   bool passthrough;
57 } DVDAudioFrame;
58
59 class CPTSOutputQueue
60 {
61 private:
62   typedef struct {double pts; double timestamp; double duration;} TPTSItem;
63   TPTSItem m_current;
64   std::queue<TPTSItem> m_queue;
65   CCriticalSection m_sync;
66
67 public:
68   CPTSOutputQueue();
69   void Add(double pts, double delay, double duration);
70   void Flush();
71   double Current();
72 };
73
74 class CPTSInputQueue
75 {
76 private:
77   typedef std::list<std::pair<__int64, double> >::iterator IT;
78   std::list<std::pair<__int64, double> > m_list;
79   CCriticalSection m_sync;
80 public:
81   void   Add(__int64 bytes, double pts);
82   double Get(__int64 bytes, bool consume);
83   void   Flush();
84 };
85
86 class CDVDPlayerAudio : public CThread
87 {
88 public:
89   CDVDPlayerAudio(CDVDClock* pClock);
90   virtual ~CDVDPlayerAudio();
91
92   void RegisterAudioCallback(IAudioCallback* pCallback) { m_dvdAudio.RegisterAudioCallback(pCallback); }
93   void UnRegisterAudioCallback()                        { m_dvdAudio.UnRegisterAudioCallback(); }
94
95   bool OpenStream(CDVDStreamInfo &hints);
96   void CloseStream(bool bWaitForBuffers);
97   
98   void SetSpeed(int speed);
99   void Flush();
100
101   // waits until all available data has been rendered  
102   void WaitForBuffers();
103   bool AcceptsData()                                    { return !m_messageQueue.IsFull(); }
104   void SendMessage(CDVDMsg* pMsg)                       { m_messageQueue.Put(pMsg); }
105   
106   void SetVolume(long nVolume)                          { m_dvdAudio.SetVolume(nVolume); }
107   void SetDynamicRangeCompression(long drc)             { m_dvdAudio.SetDynamicRangeCompression(drc); }
108
109   std::string GetPlayerInfo();
110   int GetAudioBitrate();
111
112   // holds stream information for current playing stream
113   CDVDStreamInfo m_streaminfo;
114   
115   CDVDMessageQueue m_messageQueue;
116   CPTSOutputQueue m_ptsOutput;
117   CPTSInputQueue  m_ptsInput;
118
119   double GetCurrentPts()                            { return m_ptsOutput.Current(); }
120
121   bool IsStalled()                                  { return m_stalled 
122                                                           && m_messageQueue.GetDataSize() == 0;  }
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   // tries to open a decoder for the given data. 
132   bool OpenDecoder(CDVDStreamInfo &hint, BYTE* buffer = NULL, unsigned int size = 0);
133
134   double m_audioClock;
135   
136   // data for audio decoding
137   struct
138   {
139     CDVDMsgDemuxerPacket*  msg;
140     BYTE*                  data;
141     int                    size;
142     double                 dts;
143
144     void Attach(CDVDMsgDemuxerPacket* msg2)
145     {
146       msg = msg2;
147       msg->Acquire();
148       DemuxPacket* p = msg->GetPacket();      
149       data = p->pData;
150       size = p->iSize;
151       dts = p->dts;
152
153     }
154     void Release()
155     {
156       if(msg) msg->Release();
157       msg  = NULL;
158       data = NULL;
159       size = 0;
160       dts  = DVD_NOPTS_VALUE;
161     }
162   } m_decode;
163
164   CDVDAudio m_dvdAudio; // audio output device
165   CDVDClock* m_pClock; // dvd master clock
166   CDVDAudioCodec* m_pAudioCodec; // audio codec
167   BitstreamStats m_audioStats;
168
169   int     m_speed;
170   double  m_droptime;
171   bool    m_stalled;
172   bool    m_started;
173   
174   CDVDPlayerResampler m_resampler;
175   
176   bool OutputPacket(DVDAudioFrame &audioframe);
177   
178   //SYNC_DISCON, SYNC_SKIPDUP, SYNC_RESAMPLE
179   int    m_synctype;
180   int    m_setsynctype;
181   
182   double m_error;    //last average error
183   
184   LARGE_INTEGER m_errortime; //timestamp of last time we measured
185   LARGE_INTEGER m_freq;
186
187   void   HandleSyncError(double duration);
188   double m_errorbuff; //place to store average errors
189   int    m_errorcount;//number of errors stored
190   bool   m_syncclock;
191   
192   double m_integral; //integral correction for resampler
193   int    m_skipdupcount; //counter for skip/duplicate synctype
194   bool   m_prevskipped;
195   
196   CRITICAL_SECTION m_critCodecSection;
197 };
198