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_OPAL_MEDIASTRM_H
00033 #define OPAL_OPAL_MEDIASTRM_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #include <opal/buildopts.h>
00040 
00041 #include <ptclib/delaychan.h>
00042 
00043 #include <opal/mediafmt.h>
00044 #include <opal/mediacmd.h>
00045 #include <ptlib/safecoll.h>
00046 #include <ptclib/guid.h>
00047 
00048 
00049 class RTP_Session;
00050 class OpalMediaPatch;
00051 class OpalLine;
00052 class OpalConnection;
00053 class OpalRTPConnection;
00054 class OpalMediaStatistics;
00055 
00056 
00062 class OpalMediaStream : public PSafeObject
00063 {
00064     PCLASSINFO(OpalMediaStream, PSafeObject);
00065   protected:
00070     OpalMediaStream(
00071       OpalConnection & conn,
00072       const OpalMediaFormat & mediaFormat, 
00073       unsigned sessionID,                  
00074       bool isSource                        
00075     );
00076 
00077   public:
00081     ~OpalMediaStream();
00083 
00084   public:
00091     void PrintOn(
00092       ostream & strm    
00093     ) const;
00095 
00105     virtual OpalMediaFormat GetMediaFormat() const;
00106 
00116     virtual bool UpdateMediaFormat(
00117       const OpalMediaFormat & mediaFormat,  
00118       bool fromPatch = false                
00119     );
00120 
00127     virtual PBoolean ExecuteCommand(
00128       const OpalMediaCommand & command    
00129     );
00130 
00138     virtual void SetCommandNotifier(
00139       const PNotifier & notifier    
00140     );
00141 
00146     virtual PBoolean Open();
00147 
00153     virtual PBoolean Start();
00154 
00159     virtual PBoolean Close();
00160 
00164     virtual void OnPatchStart();
00165 
00169     virtual void OnPatchStop();
00170 
00175     virtual PBoolean WritePackets(
00176       RTP_DataFrameList & packets
00177     );
00178 
00184     virtual PBoolean ReadPacket(
00185       RTP_DataFrame & packet
00186     );
00187 
00193     virtual PBoolean WritePacket(
00194       RTP_DataFrame & packet
00195     );
00196 
00202     virtual PBoolean ReadData(
00203       BYTE * data,      
00204       PINDEX size,      
00205       PINDEX & length   
00206     );
00207 
00213     virtual PBoolean WriteData(
00214       const BYTE * data,   
00215       PINDEX length,       
00216       PINDEX & written     
00217     );
00218 
00221     bool PushPacket(
00222       RTP_DataFrame & packet
00223     );
00224 
00230     virtual PBoolean SetDataSize(
00231       PINDEX dataSize  
00232     );
00233 
00237     PINDEX GetDataSize() const { return defaultDataSize; }
00238 
00245     virtual PBoolean IsSynchronous() const = 0;
00246 
00256     virtual PBoolean RequiresPatchThread(
00257       OpalMediaStream * sinkStream  
00258     ) const;
00259     virtual PBoolean RequiresPatchThread() const; 
00260 
00265     virtual void EnableJitterBuffer() const;
00267 
00272     OpalConnection & GetConnection() const { return connection; }
00273 
00276     bool IsSource() const { return isSource; }
00277 
00280     bool IsSink() const { return !isSource; }
00281 
00284     unsigned GetSessionID() const { return sessionID; }
00285 
00289     PString GetID() const { return identifier; }
00290 
00293     unsigned GetTimestamp() const { return timestamp; }
00294 
00297     void SetTimestamp(unsigned ts) { timestamp = ts; }
00298 
00301     bool GetMarker() const { return marker; }
00302 
00305     void SetMarker(bool m) { marker = m; }
00306 
00309     bool IsPaused() const { return paused; }
00310 
00314     virtual void SetPaused(
00315       bool pause    
00316     );
00317 
00320     bool IsOpen() { return isOpen; }
00321     
00324     virtual PBoolean SetPatch(
00325       OpalMediaPatch * patch  
00326     );
00327 
00334     virtual void RemovePatch(OpalMediaPatch * patch);
00335 
00338     OpalMediaPatch * GetPatch() const { return mediaPatch; }
00339 
00342     void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage =  OpalMediaFormat());
00343 
00346     bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00347 
00348 #if OPAL_STATISTICS
00349     virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00350 #endif
00351 
00352 
00353   protected:
00354     OpalConnection & connection;
00355     unsigned         sessionID;
00356     PString          identifier;
00357     OpalMediaFormat  mediaFormat;
00358     bool             paused;
00359     bool             isSource;
00360     bool             isOpen;
00361     PINDEX           defaultDataSize;
00362     unsigned         timestamp;
00363     bool             marker;
00364     unsigned         mismatchedPayloadTypes;
00365 
00366     OpalMediaPatch * mediaPatch;
00367     PNotifier        commandNotifier;
00368 };
00369 
00370 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00371 
00372 
00375 class OpalMediaStreamPacing
00376 {
00377   public:
00378     OpalMediaStreamPacing(
00379       const OpalMediaFormat & mediaFormat 
00380     );
00381 
00383     void Pace(
00384       bool reading,     
00385       PINDEX bytes,     
00386       bool & marker     
00387     );
00388 
00389   protected:
00390     bool           m_isAudio;
00391     unsigned       m_frameTime;
00392     PINDEX         m_frameSize;
00393     unsigned       m_timeUnits;
00394     PAdaptiveDelay m_delay;
00395 };
00396 
00397 
00400 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00401 {
00402     PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00403   public:
00408     OpalNullMediaStream(
00409       OpalConnection & conn,
00410       const OpalMediaFormat & mediaFormat, 
00411       unsigned sessionID,                  
00412       bool isSource,                       
00413       bool isSynchronous = false           
00414     );
00416 
00422     virtual PBoolean ReadData(
00423       BYTE * data,      
00424       PINDEX size,      
00425       PINDEX & length   
00426     );
00427 
00431     virtual PBoolean WriteData(
00432       const BYTE * data,   
00433       PINDEX length,       
00434       PINDEX & written     
00435     );
00436         
00440     virtual PBoolean RequiresPatchThread() const;
00441 
00445     virtual PBoolean IsSynchronous() const;
00447 
00448   protected:
00449     bool           m_isSynchronous;
00450 };
00451 
00452 
00456 class OpalRTPMediaStream : public OpalMediaStream
00457 {
00458     PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00459   public:
00465     OpalRTPMediaStream(
00466       OpalRTPConnection & conn,
00467       const OpalMediaFormat & mediaFormat, 
00468       bool isSource,                       
00469       RTP_Session & rtpSession,            
00470       unsigned minAudioJitterDelay,        
00471       unsigned maxAudioJitterDelay         
00472     );
00473 
00477     ~OpalRTPMediaStream();
00479 
00486     virtual PBoolean Open();
00487 
00492     virtual PBoolean Close();
00493 
00497     virtual PBoolean ReadPacket(
00498       RTP_DataFrame & packet
00499     );
00500 
00504     virtual PBoolean WritePacket(
00505       RTP_DataFrame & packet
00506     );
00507 
00510     virtual PBoolean SetDataSize(
00511       PINDEX dataSize  
00512     );
00513 
00517     virtual PBoolean IsSynchronous() const;
00518 
00523     virtual void EnableJitterBuffer() const;
00524 
00527     virtual RTP_Session & GetRtpSession() const
00528     { return rtpSession; }
00529 
00530 #if OPAL_STATISTICS
00531     virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00532 #endif
00533 
00534 
00535   protected:
00536     RTP_Session & rtpSession;
00537     unsigned      minAudioJitterDelay;
00538     unsigned      maxAudioJitterDelay;
00539 };
00540 
00541 
00542 
00545 class OpalRawMediaStream : public OpalMediaStream
00546 {
00547     PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00548   protected:
00553     OpalRawMediaStream(
00554       OpalConnection & conn,
00555       const OpalMediaFormat & mediaFormat, 
00556       unsigned sessionID,                  
00557       bool isSource,                       
00558       PChannel * channel,                  
00559       bool autoDelete                      
00560     );
00561 
00564     ~OpalRawMediaStream();
00566 
00567   public:
00573     virtual PBoolean ReadData(
00574       BYTE * data,      
00575       PINDEX size,      
00576       PINDEX & length   
00577     );
00578 
00582     virtual PBoolean WriteData(
00583       const BYTE * data,   
00584       PINDEX length,       
00585       PINDEX & written     
00586     );
00587 
00590     PChannel * GetChannel() { return channel; }
00591     
00596     virtual PBoolean Close();
00597 
00600     virtual unsigned GetAverageSignalLevel();
00602 
00603   protected:
00604     PChannel * channel;
00605     bool       autoDelete;
00606 
00607     PUInt64    averageSignalSum;
00608     unsigned   averageSignalSamples;
00609     PMutex     averagingMutex;
00610 
00611     void CollectAverage(const BYTE * buffer, PINDEX size);
00612 };
00613 
00614 
00615 
00618 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00619 {
00620     PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00621   public:
00626     OpalFileMediaStream(
00627       OpalConnection &,
00628       const OpalMediaFormat & mediaFormat, 
00629       unsigned sessionID,                  
00630       bool isSource,                       
00631       PFile * file,                        
00632       bool autoDelete = true               
00633     );
00634 
00637     OpalFileMediaStream(
00638       OpalConnection & ,
00639       const OpalMediaFormat & mediaFormat, 
00640       unsigned sessionID,                  
00641       bool isSource,                       
00642       const PFilePath & path               
00643     );
00645 
00651     virtual PBoolean IsSynchronous() const;
00653 
00654     virtual PBoolean ReadData(
00655       BYTE * data,      
00656       PINDEX size,      
00657       PINDEX & length   
00658     );
00659 
00663     virtual PBoolean WriteData(
00664       const BYTE * data,   
00665       PINDEX length,       
00666       PINDEX & written     
00667     );
00668 
00669   protected:
00670     PFile file;
00671 };
00672 
00673 
00674 #if OPAL_PTLIB_AUDIO
00675 
00679 class PSoundChannel;
00680 
00681 class OpalAudioMediaStream : public OpalRawMediaStream
00682 {
00683     PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00684   public:
00689     OpalAudioMediaStream(
00690       OpalConnection & conn,
00691       const OpalMediaFormat & mediaFormat, 
00692       unsigned sessionID,                  
00693       bool isSource,                       
00694       PINDEX buffers,                      
00695       PSoundChannel * channel,             
00696       bool autoDelete = true               
00697     );
00698 
00701     OpalAudioMediaStream(
00702       OpalConnection & conn,
00703       const OpalMediaFormat & mediaFormat, 
00704       unsigned sessionID,                  
00705       bool isSource,                       
00706       PINDEX buffers,                      
00707       const PString & deviceName           
00708     );
00710 
00718     virtual PBoolean SetDataSize(
00719       PINDEX dataSize  
00720     );
00721 
00725     virtual PBoolean IsSynchronous() const;
00727 
00728   protected:
00729     PINDEX soundChannelBuffers;
00730 };
00731 
00732 #endif // OPAL_PTLIB_AUDIO
00733 
00734 #if OPAL_VIDEO
00735 
00739 class PVideoInputDevice;
00740 class PVideoOutputDevice;
00741 
00742 class OpalVideoMediaStream : public OpalMediaStream
00743 {
00744     PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00745   public:
00750     OpalVideoMediaStream(
00751       OpalConnection & conn,
00752       const OpalMediaFormat & mediaFormat, 
00753       unsigned sessionID,                  
00754       PVideoInputDevice * inputDevice,     
00755       PVideoOutputDevice * outputDevice,   
00756       bool autoDelete = true               
00757     );
00758 
00761     ~OpalVideoMediaStream();
00763 
00771     virtual PBoolean Open();
00772 
00777     virtual PBoolean Close();
00778 
00784     virtual PBoolean ReadData(
00785       BYTE * data,      
00786       PINDEX size,      
00787       PINDEX & length   
00788     );
00789 
00795     virtual PBoolean WriteData(
00796       const BYTE * data,   
00797       PINDEX length,       
00798       PINDEX & written     
00799     );
00800 
00804     virtual PBoolean IsSynchronous() const;
00805 
00808     virtual PBoolean SetDataSize(
00809      PINDEX dataSize  
00810     );
00811 
00814     virtual PVideoInputDevice * GetVideoInputDevice() const {
00815       return inputDevice;
00816     }
00817 
00820     virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00821       return outputDevice;
00822     }
00823 
00825 
00826   protected:
00827     PVideoInputDevice  * inputDevice;
00828     PVideoOutputDevice * outputDevice;
00829     bool                 autoDelete;
00830     PTimeInterval        lastGrabTime;
00831 };
00832 
00833 #endif // OPAL_VIDEO
00834 
00835 class OpalTransportUDP;
00836 
00839 class OpalUDPMediaStream : public OpalMediaStream
00840 {
00841     PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00842   public:
00847     OpalUDPMediaStream(
00848       OpalConnection & conn,
00849       const OpalMediaFormat & mediaFormat, 
00850       unsigned sessionID,                  
00851       bool isSource,                       
00852       OpalTransportUDP & transport         
00853     );
00855 
00858 
00862     virtual PBoolean ReadPacket(
00863       RTP_DataFrame & packet
00864     );
00865 
00869     virtual PBoolean WritePacket(
00870       RTP_DataFrame & packet
00871     );
00872 
00876     virtual PBoolean IsSynchronous() const;
00877 
00881     virtual PBoolean Close();
00882 
00884 
00885   private:
00886     OpalTransportUDP & udpTransport;
00887 };
00888 
00889 
00890 #endif //OPAL_OPAL_MEDIASTRM_H
00891 
00892 
00893