00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #ifndef __OPAL_MEDIASTRM_H
00033 #define __OPAL_MEDIASTRM_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #include <ptclib/delaychan.h>
00040 
00041 #include <opal/buildopts.h>
00042 #include <opal/mediafmt.h>
00043 #include <opal/mediacmd.h>
00044 #include <ptlib/safecoll.h>
00045 #include <ptclib/guid.h>
00046 
00047 
00048 class RTP_Session;
00049 class OpalMediaPatch;
00050 class OpalLine;
00051 class OpalConnection;
00052 class OpalRTPConnection;
00053 class OpalMediaStatistics;
00054 
00055 
00061 class OpalMediaStream : public PSafeObject
00062 {
00063     PCLASSINFO(OpalMediaStream, PSafeObject);
00064   protected:
00069     OpalMediaStream(
00070       OpalConnection & conn,
00071       const OpalMediaFormat & mediaFormat, 
00072       unsigned sessionID,                  
00073       bool isSource                        
00074     );
00075 
00076   public:
00080     ~OpalMediaStream();
00082 
00083   public:
00090     void PrintOn(
00091       ostream & strm    
00092     ) const;
00094 
00104     virtual OpalMediaFormat GetMediaFormat() const;
00105 
00115     virtual bool UpdateMediaFormat(
00116       const OpalMediaFormat & mediaFormat,  
00117       bool fromPatch = false                
00118     );
00119 
00126     virtual PBoolean ExecuteCommand(
00127       const OpalMediaCommand & command    
00128     );
00129 
00137     virtual void SetCommandNotifier(
00138       const PNotifier & notifier    
00139     );
00140 
00145     virtual PBoolean Open();
00146 
00152     virtual PBoolean Start();
00153 
00158     virtual PBoolean Close();
00159 
00163     virtual void OnPatchStart();
00164 
00168     virtual void OnPatchStop();
00169 
00174     virtual PBoolean WritePackets(
00175       RTP_DataFrameList & packets
00176     );
00177 
00183     virtual PBoolean ReadPacket(
00184       RTP_DataFrame & packet
00185     );
00186 
00192     virtual PBoolean WritePacket(
00193       RTP_DataFrame & packet
00194     );
00195 
00201     virtual PBoolean ReadData(
00202       BYTE * data,      
00203       PINDEX size,      
00204       PINDEX & length   
00205     );
00206 
00212     virtual PBoolean WriteData(
00213       const BYTE * data,   
00214       PINDEX length,       
00215       PINDEX & written     
00216     );
00217 
00220     bool PushPacket(
00221       RTP_DataFrame & packet
00222     );
00223 
00229     virtual PBoolean SetDataSize(
00230       PINDEX dataSize  
00231     );
00232 
00236     PINDEX GetDataSize() const { return defaultDataSize; }
00237 
00244     virtual PBoolean IsSynchronous() const = 0;
00245 
00255     virtual PBoolean RequiresPatchThread(
00256       OpalMediaStream * sinkStream  
00257     ) const;
00258     virtual PBoolean RequiresPatchThread() const; 
00259 
00264     virtual void EnableJitterBuffer() const;
00266 
00271     OpalConnection & GetConnection() const { return connection; }
00272 
00275     bool IsSource() const { return isSource; }
00276 
00279     bool IsSink() const { return !isSource; }
00280 
00283     unsigned GetSessionID() const { return sessionID; }
00284 
00288     PString GetID() const { return identifier; }
00289 
00292     unsigned GetTimestamp() const { return timestamp; }
00293 
00296     void SetTimestamp(unsigned ts) { timestamp = ts; }
00297 
00300     bool GetMarker() const { return marker; }
00301 
00304     void SetMarker(bool m) { marker = m; }
00305 
00308     bool IsPaused() const { return paused; }
00309 
00313     virtual void SetPaused(
00314       bool pause    
00315     );
00316 
00319     bool IsOpen() { return isOpen; }
00320     
00323     virtual PBoolean SetPatch(
00324       OpalMediaPatch * patch  
00325     );
00326 
00333     virtual void RemovePatch(OpalMediaPatch * patch);
00334 
00337     OpalMediaPatch * GetPatch() const { return mediaPatch; }
00338 
00341     void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage =  OpalMediaFormat());
00342 
00345     bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00346 
00347 #ifdef OPAL_STATISTICS
00348     virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00349 #endif
00350 
00351 
00352   protected:
00353     OpalConnection & connection;
00354     unsigned         sessionID;
00355     PString          identifier;
00356     OpalMediaFormat  mediaFormat;
00357     bool             paused;
00358     bool             isSource;
00359     bool             isOpen;
00360     PINDEX           defaultDataSize;
00361     unsigned         timestamp;
00362     bool             marker;
00363     unsigned         mismatchedPayloadTypes;
00364 
00365     OpalMediaPatch * mediaPatch;
00366     PNotifier        commandNotifier;
00367 };
00368 
00369 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00370 
00371 
00374 class OpalMediaStreamPacing
00375 {
00376   public:
00377     OpalMediaStreamPacing(
00378       const OpalMediaFormat & mediaFormat 
00379     );
00380 
00382     void Pace(
00383       bool reading,     
00384       PINDEX bytes,     
00385       bool & marker     
00386     );
00387 
00388   protected:
00389     bool           m_isAudio;
00390     unsigned       m_frameTime;
00391     PINDEX         m_frameSize;
00392     unsigned       m_timeUnits;
00393     PAdaptiveDelay m_delay;
00394 };
00395 
00396 
00399 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00400 {
00401     PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00402   public:
00407     OpalNullMediaStream(
00408       OpalConnection & conn,
00409       const OpalMediaFormat & mediaFormat, 
00410       unsigned sessionID,                  
00411       bool isSource,                       
00412       bool isSynchronous = false           
00413     );
00415 
00421     virtual PBoolean ReadData(
00422       BYTE * data,      
00423       PINDEX size,      
00424       PINDEX & length   
00425     );
00426 
00430     virtual PBoolean WriteData(
00431       const BYTE * data,   
00432       PINDEX length,       
00433       PINDEX & written     
00434     );
00435         
00439     virtual PBoolean RequiresPatchThread() const;
00440 
00444     virtual PBoolean IsSynchronous() const;
00446 
00447   protected:
00448     bool           m_isSynchronous;
00449 };
00450 
00451 
00455 class OpalRTPMediaStream : public OpalMediaStream
00456 {
00457     PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00458   public:
00464     OpalRTPMediaStream(
00465       OpalRTPConnection & conn,
00466       const OpalMediaFormat & mediaFormat, 
00467       bool isSource,                       
00468       RTP_Session & rtpSession,            
00469       unsigned minAudioJitterDelay,        
00470       unsigned maxAudioJitterDelay         
00471     );
00472 
00476     ~OpalRTPMediaStream();
00478 
00485     virtual PBoolean Open();
00486 
00491     virtual PBoolean Close();
00492 
00496     virtual PBoolean ReadPacket(
00497       RTP_DataFrame & packet
00498     );
00499 
00503     virtual PBoolean WritePacket(
00504       RTP_DataFrame & packet
00505     );
00506 
00509     virtual PBoolean SetDataSize(
00510       PINDEX dataSize  
00511     );
00512 
00516     virtual PBoolean IsSynchronous() const;
00517 
00522     virtual void EnableJitterBuffer() const;
00523 
00526     virtual RTP_Session & GetRtpSession() const
00527     { return rtpSession; }
00528 
00529 #ifdef OPAL_STATISTICS
00530     virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00531 #endif
00532 
00533 
00534   protected:
00535     RTP_Session & rtpSession;
00536     unsigned      minAudioJitterDelay;
00537     unsigned      maxAudioJitterDelay;
00538 };
00539 
00540 
00541 
00544 class OpalRawMediaStream : public OpalMediaStream
00545 {
00546     PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00547   protected:
00552     OpalRawMediaStream(
00553       OpalConnection & conn,
00554       const OpalMediaFormat & mediaFormat, 
00555       unsigned sessionID,                  
00556       bool isSource,                       
00557       PChannel * channel,                  
00558       bool autoDelete                      
00559     );
00560 
00563     ~OpalRawMediaStream();
00565 
00566   public:
00572     virtual PBoolean ReadData(
00573       BYTE * data,      
00574       PINDEX size,      
00575       PINDEX & length   
00576     );
00577 
00581     virtual PBoolean WriteData(
00582       const BYTE * data,   
00583       PINDEX length,       
00584       PINDEX & written     
00585     );
00586 
00589     PChannel * GetChannel() { return channel; }
00590     
00595     virtual PBoolean Close();
00596 
00599     virtual unsigned GetAverageSignalLevel();
00601 
00602   protected:
00603     PChannel * channel;
00604     bool       autoDelete;
00605 
00606     PUInt64    averageSignalSum;
00607     unsigned   averageSignalSamples;
00608     PMutex     averagingMutex;
00609 
00610     void CollectAverage(const BYTE * buffer, PINDEX size);
00611 };
00612 
00613 
00614 
00617 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00618 {
00619     PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00620   public:
00625     OpalFileMediaStream(
00626       OpalConnection &,
00627       const OpalMediaFormat & mediaFormat, 
00628       unsigned sessionID,                  
00629       bool isSource,                       
00630       PFile * file,                        
00631       bool autoDelete = true               
00632     );
00633 
00636     OpalFileMediaStream(
00637       OpalConnection & ,
00638       const OpalMediaFormat & mediaFormat, 
00639       unsigned sessionID,                  
00640       bool isSource,                       
00641       const PFilePath & path               
00642     );
00644 
00650     virtual PBoolean IsSynchronous() const;
00652 
00653     virtual PBoolean ReadData(
00654       BYTE * data,      
00655       PINDEX size,      
00656       PINDEX & length   
00657     );
00658 
00662     virtual PBoolean WriteData(
00663       const BYTE * data,   
00664       PINDEX length,       
00665       PINDEX & written     
00666     );
00667 
00668   protected:
00669     PFile file;
00670 };
00671 
00672 
00673 #if P_AUDIO
00674 
00678 class PSoundChannel;
00679 
00680 class OpalAudioMediaStream : public OpalRawMediaStream
00681 {
00682     PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00683   public:
00688     OpalAudioMediaStream(
00689       OpalConnection & conn,
00690       const OpalMediaFormat & mediaFormat, 
00691       unsigned sessionID,                  
00692       bool isSource,                       
00693       PINDEX buffers,                      
00694       PSoundChannel * channel,             
00695       bool autoDelete = true               
00696     );
00697 
00700     OpalAudioMediaStream(
00701       OpalConnection & conn,
00702       const OpalMediaFormat & mediaFormat, 
00703       unsigned sessionID,                  
00704       bool isSource,                       
00705       PINDEX buffers,                      
00706       const PString & deviceName           
00707     );
00709 
00717     virtual PBoolean SetDataSize(
00718       PINDEX dataSize  
00719     );
00720 
00724     virtual PBoolean IsSynchronous() const;
00726 
00727   protected:
00728     PINDEX soundChannelBuffers;
00729 };
00730 
00731 #endif // P_AUDIO
00732 
00733 #if OPAL_VIDEO
00734 
00738 class PVideoInputDevice;
00739 class PVideoOutputDevice;
00740 
00741 class OpalVideoMediaStream : public OpalMediaStream
00742 {
00743     PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00744   public:
00749     OpalVideoMediaStream(
00750       OpalConnection & conn,
00751       const OpalMediaFormat & mediaFormat, 
00752       unsigned sessionID,                  
00753       PVideoInputDevice * inputDevice,     
00754       PVideoOutputDevice * outputDevice,   
00755       bool autoDelete = true               
00756     );
00757 
00760     ~OpalVideoMediaStream();
00762 
00770     virtual PBoolean Open();
00771 
00776     virtual PBoolean Close();
00777 
00783     virtual PBoolean ReadData(
00784       BYTE * data,      
00785       PINDEX size,      
00786       PINDEX & length   
00787     );
00788 
00794     virtual PBoolean WriteData(
00795       const BYTE * data,   
00796       PINDEX length,       
00797       PINDEX & written     
00798     );
00799 
00803     virtual PBoolean IsSynchronous() const;
00804 
00807     virtual PBoolean SetDataSize(
00808      PINDEX dataSize  
00809     );
00810 
00813     virtual PVideoInputDevice * GetVideoInputDevice() const {
00814       return inputDevice;
00815     }
00816 
00819     virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00820       return outputDevice;
00821     }
00822 
00824 
00825   protected:
00826     PVideoInputDevice  * inputDevice;
00827     PVideoOutputDevice * outputDevice;
00828     bool                 autoDelete;
00829     PTimeInterval        lastGrabTime;
00830 };
00831 
00832 #endif // OPAL_VIDEO
00833 
00834 class OpalTransportUDP;
00835 
00838 class OpalUDPMediaStream : public OpalMediaStream
00839 {
00840     PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00841   public:
00846     OpalUDPMediaStream(
00847       OpalConnection & conn,
00848       const OpalMediaFormat & mediaFormat, 
00849       unsigned sessionID,                  
00850       bool isSource,                       
00851       OpalTransportUDP & transport         
00852     );
00854 
00857 
00861     virtual PBoolean ReadPacket(
00862       RTP_DataFrame & packet
00863     );
00864 
00868     virtual PBoolean WritePacket(
00869       RTP_DataFrame & packet
00870     );
00871 
00875     virtual PBoolean IsSynchronous() const;
00876 
00880     virtual PBoolean Close();
00881 
00883 
00884   private:
00885     OpalTransportUDP & udpTransport;
00886 };
00887 
00888 
00889 #endif //__OPAL_MEDIASTRM_H
00890 
00891 
00892