OPAL Version 3.10.2
mediastrm.h
Go to the documentation of this file.
00001 /*
00002  * mediastrm.h
00003  *
00004  * Media Stream classes
00005  *
00006  * Open Phone Abstraction Library (OPAL)
00007  * Formally known as the Open H323 project.
00008  *
00009  * Copyright (c) 2001 Equivalence Pty. Ltd.
00010  *
00011  * The contents of this file are subject to the Mozilla Public License
00012  * Version 1.0 (the "License"); you may not use this file except in
00013  * compliance with the License. You may obtain a copy of the License at
00014  * http://www.mozilla.org/MPL/
00015  *
00016  * Software distributed under the License is distributed on an "AS IS"
00017  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00018  * the License for the specific language governing rights and limitations
00019  * under the License.
00020  *
00021  * The Original Code is Open Phone Abstraction Library.
00022  *
00023  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00024  *
00025  * Contributor(s): ______________________________________.
00026  *
00027  * $Revision: 25806 $
00028  * $Author: rjongbloed $
00029  * $Date: 2011-05-19 00:14:31 -0500 (Thu, 19 May 2011) $
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 
00111 class OpalMediaStream : public PSafeObject
00112 {
00113     PCLASSINFO(OpalMediaStream, PSafeObject);
00114   protected:
00119     OpalMediaStream(
00120       OpalConnection & conn,               
00121       const OpalMediaFormat & mediaFormat, 
00122       unsigned sessionID,                  
00123       bool isSource                        
00124     );
00125 
00126   public:
00130     ~OpalMediaStream();
00132 
00133   public:
00140     void PrintOn(
00141       ostream & strm    
00142     ) const;
00144 
00154     virtual OpalMediaFormat GetMediaFormat() const;
00155 
00165     virtual bool UpdateMediaFormat(
00166       const OpalMediaFormat & mediaFormat,  
00167       bool fromPatch = false                
00168     );
00169 
00176     virtual PBoolean ExecuteCommand(
00177       const OpalMediaCommand & command    
00178     );
00179 
00187     virtual void SetCommandNotifier(
00188       const PNotifier & notifier    
00189     );
00190 
00195     virtual PBoolean Open();
00196 
00202     virtual PBoolean Start();
00203 
00208     virtual PBoolean Close();
00209 
00213     virtual void OnStartMediaPatch();
00214 
00218     virtual void OnStopMediaPatch(
00219       OpalMediaPatch & patch    
00220     );
00221 
00226     virtual PBoolean WritePackets(
00227       RTP_DataFrameList & packets
00228     );
00229 
00235     virtual PBoolean ReadPacket(
00236       RTP_DataFrame & packet
00237     );
00238 
00244     virtual PBoolean WritePacket(
00245       RTP_DataFrame & packet
00246     );
00247 
00253     virtual PBoolean ReadData(
00254       BYTE * data,      
00255       PINDEX size,      
00256       PINDEX & length   
00257     );
00258 
00264     virtual PBoolean WriteData(
00265       const BYTE * data,   
00266       PINDEX length,       
00267       PINDEX & written     
00268     );
00269 
00272     bool PushPacket(
00273       RTP_DataFrame & packet
00274     );
00275 
00281     virtual PBoolean SetDataSize(
00282       PINDEX dataSize,  
00283       PINDEX frameTime  
00284     );
00285 
00289     PINDEX GetDataSize() const { return defaultDataSize; }
00290 
00297     virtual PBoolean IsSynchronous() const = 0;
00298 
00308     virtual PBoolean RequiresPatchThread(
00309       OpalMediaStream * stream  
00310     ) const;
00311     virtual PBoolean RequiresPatchThread() const; // For backward compatibility
00312 
00319     virtual bool EnableJitterBuffer(bool enab = true) const;
00321 
00326     OpalConnection & GetConnection() const { return connection; }
00327 
00330     bool IsSource() const { return isSource; }
00331 
00334     bool IsSink() const { return !isSource; }
00335 
00338     unsigned GetSessionID() const { return sessionID; }
00339 
00342     void SetSessionID(unsigned id) { sessionID = id; }
00343 
00347     PString GetID() const { return identifier; }
00348 
00351     unsigned GetTimestamp() const { return timestamp; }
00352 
00355     void SetTimestamp(unsigned ts) { timestamp = ts; }
00356 
00359     bool GetMarker() const { return marker; }
00360 
00363     void SetMarker(bool m) { marker = m; }
00364 
00367     bool IsPaused() const { return m_paused; }
00368 
00373     virtual bool SetPaused(
00374       bool pause,             
00375       bool fromPatch = false  
00376     );
00377 
00380     bool IsOpen() const { return isOpen; }
00381     
00384     virtual PBoolean SetPatch(
00385       OpalMediaPatch * patch  
00386     );
00387 
00390     OpalMediaPatch * GetPatch() const { return mediaPatch; }
00391 
00394     void AddFilter(
00395       const PNotifier & filter,   
00396       const OpalMediaFormat & stage = OpalMediaFormat() 
00397     ) const;
00398 
00401     bool RemoveFilter(
00402       const PNotifier & filter,   
00403       const OpalMediaFormat & stage = OpalMediaFormat() 
00404     ) const;
00405 
00406 #if OPAL_STATISTICS
00407     virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00408 #endif
00409 
00410 
00411   protected:
00412     void IncrementTimestamp(PINDEX size);
00413     bool InternalWriteData(const BYTE * data, PINDEX length, PINDEX & written);
00414 
00415     OpalConnection & connection;
00416     unsigned         sessionID;
00417     PString          identifier;
00418     OpalMediaFormat  mediaFormat;
00419     bool             m_paused;
00420     bool             isSource;
00421     bool             isOpen;
00422     PINDEX           defaultDataSize;
00423     unsigned         timestamp;
00424     bool             marker;
00425     unsigned         mismatchedPayloadTypes;
00426 
00427     OpalMediaPatch * mediaPatch;
00428     PNotifier        commandNotifier;
00429 
00430     RTP_DataFrame::PayloadTypes m_payloadType;
00431     unsigned                    m_frameTime;
00432     PINDEX                      m_frameSize;
00433 
00434   private:
00435     P_REMOVE_VIRTUAL_VOID(OnPatchStart());
00436     P_REMOVE_VIRTUAL_VOID(OnPatchStop());
00437     P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
00438     P_REMOVE_VIRTUAL_VOID(RemovePatch(OpalMediaPatch *));
00439 };
00440 
00441 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00442 
00443 
00446 class OpalMediaStreamPacing
00447 {
00448   public:
00449     OpalMediaStreamPacing(
00450       const OpalMediaFormat & mediaFormat 
00451     );
00452 
00454     void Pace(
00455       bool reading,     
00456       PINDEX bytes,     
00457       bool & marker     
00458     );
00459 
00460   protected:
00461     bool           m_isAudio;
00462     unsigned       m_frameTime;
00463     PINDEX         m_frameSize;
00464     unsigned       m_timeUnits;
00465     PAdaptiveDelay m_delay;
00466 };
00467 
00468 
00471 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00472 {
00473     PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00474   public:
00479     OpalNullMediaStream(
00480       OpalConnection & conn,               
00481       const OpalMediaFormat & mediaFormat, 
00482       unsigned sessionID,                  
00483       bool isSource,                       
00484       bool isSynchronous = false           
00485     );
00486     OpalNullMediaStream(
00487       OpalConnection & conn,               
00488       const OpalMediaFormat & mediaFormat, 
00489       unsigned sessionID,                  
00490       bool isSource,                       
00491       bool usePacingDelay,                 
00492       bool requiresPatchThread             
00493     );
00495 
00501     virtual PBoolean ReadData(
00502       BYTE * data,      
00503       PINDEX size,      
00504       PINDEX & length   
00505     );
00506 
00510     virtual PBoolean WriteData(
00511       const BYTE * data,   
00512       PINDEX length,       
00513       PINDEX & written     
00514     );
00515         
00519     virtual PBoolean RequiresPatchThread() const;
00520 
00524     virtual PBoolean IsSynchronous() const;
00526 
00527   protected:
00528     bool m_isSynchronous;
00529     bool m_requiresPatchThread;
00530 };
00531 
00532 
00536 class OpalRTPMediaStream : public OpalMediaStream
00537 {
00538     PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00539   public:
00545     OpalRTPMediaStream(
00546       OpalRTPConnection & conn,            
00547       const OpalMediaFormat & mediaFormat, 
00548       bool isSource,                       
00549       RTP_Session & rtpSession,            
00550       unsigned minAudioJitterDelay,        
00551       unsigned maxAudioJitterDelay         
00552     );
00553 
00557     ~OpalRTPMediaStream();
00559 
00566     virtual PBoolean Open();
00567 
00572     virtual PBoolean Close();
00573 
00577     virtual bool SetPaused(
00578       bool pause,             
00579       bool fromPatch = false  
00580     );
00581 
00585     virtual PBoolean ReadPacket(
00586       RTP_DataFrame & packet
00587     );
00588 
00592     virtual PBoolean WritePacket(
00593       RTP_DataFrame & packet
00594     );
00595 
00598     virtual PBoolean SetDataSize(
00599       PINDEX dataSize,  
00600       PINDEX frameTime  
00601     );
00602 
00606     virtual PBoolean IsSynchronous() const;
00607 
00615     virtual PBoolean RequiresPatchThread() const;
00616 
00624     virtual bool EnableJitterBuffer(bool enab = true) const;
00625 
00628     virtual PBoolean SetPatch(
00629       OpalMediaPatch * patch  
00630     );
00631 
00634     virtual RTP_Session & GetRtpSession() const
00635     { return rtpSession; }
00636 
00637 #if OPAL_STATISTICS
00638     virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00639 #endif
00640 
00641 
00642   protected:
00643     RTP_Session & rtpSession;
00644     unsigned      minAudioJitterDelay;
00645     unsigned      maxAudioJitterDelay;
00646 };
00647 
00648 
00649 
00652 class OpalRawMediaStream : public OpalMediaStream
00653 {
00654     PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00655   protected:
00660     OpalRawMediaStream(
00661       OpalConnection & conn,               
00662       const OpalMediaFormat & mediaFormat, 
00663       unsigned sessionID,                  
00664       bool isSource,                       
00665       PChannel * channel,                  
00666       bool autoDelete                      
00667     );
00668 
00671     ~OpalRawMediaStream();
00673 
00674   public:
00680     virtual PBoolean ReadData(
00681       BYTE * data,      
00682       PINDEX size,      
00683       PINDEX & length   
00684     );
00685 
00689     virtual PBoolean WriteData(
00690       const BYTE * data,   
00691       PINDEX length,       
00692       PINDEX & written     
00693     );
00694 
00697     PChannel * GetChannel() { return m_channel; }
00698 
00701     bool SetChannel(
00702       PChannel * channel,     
00703       bool autoDelete = true  
00704     );
00705 
00710     virtual PBoolean Close();
00711 
00714     virtual unsigned GetAverageSignalLevel();
00716 
00717   protected:
00718     PChannel * m_channel;
00719     bool       m_autoDelete;
00720     PMutex     m_channelMutex;
00721 
00722     PBYTEArray m_silence;
00723 
00724     PUInt64    m_averageSignalSum;
00725     unsigned   m_averageSignalSamples;
00726     PMutex     m_averagingMutex;
00727 
00728     void CollectAverage(const BYTE * buffer, PINDEX size);
00729 };
00730 
00731 
00732 
00735 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00736 {
00737     PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00738   public:
00743     OpalFileMediaStream(
00744       OpalConnection & conn,               
00745       const OpalMediaFormat & mediaFormat, 
00746       unsigned sessionID,                  
00747       bool isSource,                       
00748       PFile * file,                        
00749       bool autoDelete = true               
00750     );
00751 
00754     OpalFileMediaStream(
00755       OpalConnection & conn,               
00756       const OpalMediaFormat & mediaFormat, 
00757       unsigned sessionID,                  
00758       bool isSource,                       
00759       const PFilePath & path               
00760     );
00762 
00768     virtual PBoolean IsSynchronous() const;
00769 
00770     virtual PBoolean ReadData(
00771       BYTE * data,      
00772       PINDEX size,      
00773       PINDEX & length   
00774     );
00775 
00779     virtual PBoolean WriteData(
00780       const BYTE * data,   
00781       PINDEX length,       
00782       PINDEX & written     
00783     );
00785 
00786   protected:
00787     PFile file;
00788 };
00789 
00790 
00791 #if OPAL_PTLIB_AUDIO
00792 
00796 class PSoundChannel;
00797 
00798 class OpalAudioMediaStream : public OpalRawMediaStream
00799 {
00800     PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00801   public:
00806     OpalAudioMediaStream(
00807       OpalConnection & conn,               
00808       const OpalMediaFormat & mediaFormat, 
00809       unsigned sessionID,                  
00810       bool isSource,                       
00811       PINDEX buffers,                      
00812       unsigned bufferTime,                 
00813       PSoundChannel * channel,             
00814       bool autoDelete = true               
00815     );
00816 
00819     OpalAudioMediaStream(
00820       OpalConnection & conn,               
00821       const OpalMediaFormat & mediaFormat, 
00822       unsigned sessionID,                  
00823       bool isSource,                       
00824       PINDEX buffers,                      
00825       unsigned bufferTime,                 
00826       const PString & deviceName           
00827     );
00829 
00837     virtual PBoolean SetDataSize(
00838       PINDEX dataSize,  
00839       PINDEX frameTime  
00840     );
00841 
00845     virtual PBoolean WriteData(
00846       const BYTE * data,   
00847       PINDEX length,       
00848       PINDEX & written     
00849     );
00850 
00854     virtual PBoolean IsSynchronous() const;
00856 
00857   protected:
00858     PINDEX   m_soundChannelBuffers;
00859     unsigned m_soundChannelBufferTime;
00860 
00861     unsigned       m_failSafeRate;
00862     PAdaptiveDelay m_failSafeDelay;
00863 };
00864 
00865 #endif // OPAL_PTLIB_AUDIO
00866 
00867 #if OPAL_VIDEO
00868 
00872 class PVideoInputDevice;
00873 class PVideoOutputDevice;
00874 
00875 class OpalVideoMediaStream : public OpalMediaStream
00876 {
00877     PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00878   public:
00883     OpalVideoMediaStream(
00884       OpalConnection & conn,               
00885       const OpalMediaFormat & mediaFormat, 
00886       unsigned sessionID,                  
00887       PVideoInputDevice * inputDevice,     
00888       PVideoOutputDevice * outputDevice,   
00889       bool autoDeleteInput = true,         
00890       bool autoDeleteOutput = true         
00891     );
00892 
00895     ~OpalVideoMediaStream();
00897 
00905     virtual PBoolean Open();
00906 
00911     virtual PBoolean Close();
00912 
00918     virtual PBoolean ReadData(
00919       BYTE * data,      
00920       PINDEX size,      
00921       PINDEX & length   
00922     );
00923 
00929     virtual PBoolean WriteData(
00930       const BYTE * data,   
00931       PINDEX length,       
00932       PINDEX & written     
00933     );
00934 
00938     virtual PBoolean IsSynchronous() const;
00939 
00942     virtual PBoolean SetDataSize(
00943       PINDEX dataSize,  
00944       PINDEX frameTime  
00945     );
00946 
00949     virtual PVideoInputDevice * GetVideoInputDevice() const
00950     {
00951       return m_inputDevice;
00952     }
00953 
00956     virtual PVideoOutputDevice * GetVideoOutputDevice() const
00957     {
00958       return m_outputDevice;
00959     }
00960 
00962 
00963   protected:
00964     PVideoInputDevice  * m_inputDevice;
00965     PVideoOutputDevice * m_outputDevice;
00966     bool                 m_autoDeleteInput;
00967     bool                 m_autoDeleteOutput;
00968     PTimeInterval        m_lastGrabTime;
00969 };
00970 
00971 #endif // OPAL_VIDEO
00972 
00973 class OpalTransportUDP;
00974 
00977 class OpalUDPMediaStream : public OpalMediaStream
00978 {
00979     PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00980   public:
00985     OpalUDPMediaStream(
00986       OpalConnection & conn,               
00987       const OpalMediaFormat & mediaFormat, 
00988       unsigned sessionID,                  
00989       bool isSource,                       
00990       OpalTransportUDP & transport         
00991     );
00993 
00994     ~OpalUDPMediaStream();
00995 
00998 
01002     virtual PBoolean ReadPacket(
01003       RTP_DataFrame & packet
01004     );
01005 
01009     virtual PBoolean WritePacket(
01010       RTP_DataFrame & packet
01011     );
01012 
01016     virtual PBoolean IsSynchronous() const;
01017 
01021     virtual PBoolean Close();
01022 
01024 
01025   private:
01026     OpalTransportUDP & udpTransport;
01027 };
01028 
01029 
01030 #endif //OPAL_OPAL_MEDIASTRM_H
01031 
01032 
01033 // End of File ///////////////////////////////////////////////////////////////