00001 #ifndef MYTHRAOPCONNECTION_H
00002 #define MYTHRAOPCONNECTION_H
00003
00004 #include <QObject>
00005 #include <QMap>
00006 #include <QHash>
00007 #include <QHostAddress>
00008 #include <QStringList>
00009
00010 #include <openssl/rsa.h>
00011 #include <openssl/pem.h>
00012 #include <openssl/aes.h>
00013
00014 extern "C" {
00015 #include "libavcodec/avcodec.h"
00016 #include "libavformat/avformat.h"
00017 }
00018
00019 class QTcpSocket;
00020 class QUdpSocket;
00021 class QTimer;
00022 class AudioOutput;
00023 class ServerPool;
00024 class NetStream;
00025
00026 typedef QHash<QString,QString> RawHash;
00027
00028 struct AudioData
00029 {
00030 uint8_t *data;
00031 int32_t length;
00032 int32_t frames;
00033 };
00034
00035 struct AudioPacket
00036 {
00037 uint16_t seq;
00038 QList<AudioData> *data;
00039 };
00040
00041 class MythRAOPConnection : public QObject
00042 {
00043 Q_OBJECT
00044
00045 friend class MythRAOPDevice;
00046
00047 public:
00048 MythRAOPConnection(QObject *parent, QTcpSocket* socket, QByteArray id,
00049 int port);
00050 ~MythRAOPConnection();
00051 bool Init(void);
00052 QTcpSocket* GetSocket() { return m_socket; }
00053 int GetDataPort() { return m_dataPort; }
00054 bool HasAudio() { return m_audio; }
00055 static QMap<QString,QString> decodeDMAP(const QByteArray &dmap);
00056
00057 public slots:
00058 void readClient(void);
00059 void udpDataReady(QByteArray buf, QHostAddress peer, quint16 port);
00060 void timeout(void);
00061 void audioRetry(void);
00062
00063 protected:
00064 static RSA* LoadKey(void);
00065
00066 private:
00067 void ProcessSync(const QByteArray &buf);
00068 void SendResendRequest(uint64_t timestamp,
00069 uint16_t expected, uint16_t got);
00070 void ExpireResendRequests(uint64_t timestamp);
00071 uint32_t decodeAudioPacket(uint8_t type, const QByteArray *buf,
00072 QList<AudioData> *dest);
00073 int ExpireAudio(uint64_t timestamp);
00074 void ResetAudio(void);
00075 void ProcessRequest(const QStringList &header,
00076 const QByteArray &content);
00077 void StartResponse(NetStream *stream,
00078 QString &option, QString &cseq);
00079 void FinishResponse(NetStream *stream, QTcpSocket *socket,
00080 QString &option, QString &cseq);
00081 RawHash FindTags(const QStringList &lines);
00082 bool CreateDecoder(void);
00083 void DestroyDecoder(void);
00084 bool OpenAudioDevice(void);
00085 void CloseAudioDevice(void);
00086 void StartAudioTimer(void);
00087 void StopAudioTimer(void);
00088
00089
00090 void SendTimeRequest(void);
00091 void ProcessTimeResponse(const QByteArray &buf);
00092 uint64_t NTPToLocal(uint32_t sec, uint32_t ticks);
00093
00094
00095 bool GetPacketType(const QByteArray &buf, uint8_t &type,
00096 uint16_t &seq, uint64_t ×tamp);
00097
00098
00099 int64_t AudioCardLatency(void);
00100 QStringList splitLines(const QByteArray &lines);
00101 QString stringFromSeconds(int seconds);
00102 uint64_t framesToMs(uint64_t frames);
00103
00104 QTimer *m_watchdogTimer;
00105
00106 QTcpSocket *m_socket;
00107 NetStream *m_textStream;
00108 QByteArray m_hardwareId;
00109 QStringList m_incomingHeaders;
00110 QByteArray m_incomingContent;
00111 bool m_incomingPartial;
00112 int32_t m_incomingSize;
00113 QHostAddress m_peerAddress;
00114 ServerPool *m_dataSocket;
00115 int m_dataPort;
00116 ServerPool *m_clientControlSocket;
00117 int m_clientControlPort;
00118 ServerPool *m_clientTimingSocket;
00119 int m_clientTimingPort;
00120
00121
00122 QMap<uint16_t,uint64_t> m_resends;
00123
00124 QByteArray m_AESIV;
00125 AES_KEY m_aesKey;
00126 static RSA *g_rsa;
00127
00128 AudioOutput *m_audio;
00129 AVCodec *m_codec;
00130 AVCodecContext *m_codeccontext;
00131 QList<int> m_audioFormat;
00132 int m_channels;
00133 int m_sampleSize;
00134 int m_frameRate;
00135 int m_framesPerPacket;
00136 QTimer *m_dequeueAudioTimer;
00137
00138 QMap<uint64_t, AudioPacket> m_audioQueue;
00139 uint32_t m_queueLength;
00140 bool m_streamingStarted;
00141 bool m_allowVolumeControl;
00142
00143
00144 uint16_t m_seqNum;
00145
00146 uint16_t m_lastSequence;
00147 uint64_t m_lastTimestamp;
00148 uint64_t m_currentTimestamp;
00149 uint16_t m_nextSequence;
00150 uint64_t m_nextTimestamp;
00151 uint64_t m_bufferLength;
00152 uint64_t m_timeLastSync;
00153 int64_t m_cardLatency;
00154 int64_t m_adjustedLatency;
00155 bool m_audioStarted;
00156
00157
00158 uint64_t m_masterTimeStamp;
00159 uint64_t m_deviceTimeStamp;
00160 uint64_t m_networkLatency;
00161 int64_t m_clockSkew;
00162
00163
00164 QTimer *m_audioTimer;
00165
00166
00167 uint32_t m_progressStart;
00168 uint32_t m_progressCurrent;
00169 uint32_t m_progressEnd;
00170 QByteArray m_artwork;
00171 QByteArray m_dmap;
00172
00173 private slots:
00174 void ProcessAudio(void);
00175 };
00176
00177 #endif // MYTHRAOPCONNECTION_H