OPAL  Version 3.10.4
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: 26728 $
00028  * $Author: rjongbloed $
00029  * $Date: 2011-12-01 22:59:14 -0600 (Thu, 01 Dec 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     bool UpdateMediaFormat(
00166       const OpalMediaFormat & mediaFormat   
00167     );
00168     virtual bool InternalUpdateMediaFormat(
00169       const OpalMediaFormat & mediaFormat   
00170     );
00171 
00180     virtual PBoolean ExecuteCommand(
00181       const OpalMediaCommand & command    
00182     );
00183 
00188     virtual PBoolean Open();
00189 
00195     virtual PBoolean Start();
00196 
00201     virtual PBoolean Close();
00202 
00206     virtual void OnStartMediaPatch();
00207 
00211     virtual void OnStopMediaPatch(
00212       OpalMediaPatch & patch    
00213     );
00214 
00219     virtual PBoolean WritePackets(
00220       RTP_DataFrameList & packets
00221     );
00222 
00228     virtual PBoolean ReadPacket(
00229       RTP_DataFrame & packet
00230     );
00231 
00237     virtual PBoolean WritePacket(
00238       RTP_DataFrame & packet
00239     );
00240 
00246     virtual PBoolean ReadData(
00247       BYTE * data,      
00248       PINDEX size,      
00249       PINDEX & length   
00250     );
00251 
00257     virtual PBoolean WriteData(
00258       const BYTE * data,   
00259       PINDEX length,       
00260       PINDEX & written     
00261     );
00262 
00265     bool PushPacket(
00266       RTP_DataFrame & packet
00267     );
00268 
00274     virtual PBoolean SetDataSize(
00275       PINDEX dataSize,  
00276       PINDEX frameTime  
00277     );
00278 
00282     PINDEX GetDataSize() const { return defaultDataSize; }
00283 
00290     virtual PBoolean IsSynchronous() const = 0;
00291 
00301     virtual PBoolean RequiresPatchThread(
00302       OpalMediaStream * stream  
00303     ) const;
00304     virtual PBoolean RequiresPatchThread() const; // For backward compatibility
00305 
00312     virtual bool EnableJitterBuffer(bool enab = true) const;
00314 
00319     OpalConnection & GetConnection() const { return connection; }
00320 
00323     bool IsSource() const { return isSource; }
00324 
00327     bool IsSink() const { return !isSource; }
00328 
00331     unsigned GetSessionID() const { return sessionID; }
00332 
00335     void SetSessionID(unsigned id) { sessionID = id; }
00336 
00340     PString GetID() const { return identifier; }
00341 
00344     unsigned GetTimestamp() const { return timestamp; }
00345 
00348     void SetTimestamp(unsigned ts) { timestamp = ts; }
00349 
00352     bool GetMarker() const { return marker; }
00353 
00356     void SetMarker(bool m) { marker = m; }
00357 
00360     bool IsPaused() const { return m_paused; }
00361 
00366     virtual bool SetPaused(
00367       bool pause,             
00368       bool fromPatch = false  
00369     );
00370 
00373     bool IsOpen() const { return isOpen; }
00374     
00377     virtual PBoolean SetPatch(
00378       OpalMediaPatch * patch  
00379     );
00380 
00383     OpalMediaPatch * GetPatch() const { return mediaPatch; }
00384 
00387     void AddFilter(
00388       const PNotifier & filter,   
00389       const OpalMediaFormat & stage = OpalMediaFormat() 
00390     ) const;
00391 
00394     bool RemoveFilter(
00395       const PNotifier & filter,   
00396       const OpalMediaFormat & stage = OpalMediaFormat() 
00397     ) const;
00398 
00399 #if OPAL_STATISTICS
00400     virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00401 #endif
00402 
00403 
00404   protected:
00405     void IncrementTimestamp(PINDEX size);
00406     bool InternalWriteData(const BYTE * data, PINDEX length, PINDEX & written);
00407 
00408     OpalConnection & connection;
00409     unsigned         sessionID;
00410     PString          identifier;
00411     OpalMediaFormat  mediaFormat;
00412     bool             m_paused;
00413     bool             isSource;
00414     bool             isOpen;
00415     PINDEX           defaultDataSize;
00416     unsigned         timestamp;
00417     bool             marker;
00418     unsigned         mismatchedPayloadTypes;
00419 
00420     OpalMediaPatch * mediaPatch;
00421 
00422     RTP_DataFrame::PayloadTypes m_payloadType;
00423     unsigned                    m_frameTime;
00424     PINDEX                      m_frameSize;
00425 
00426   private:
00427     P_REMOVE_VIRTUAL_VOID(OnPatchStart());
00428     P_REMOVE_VIRTUAL_VOID(OnPatchStop());
00429     P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
00430     P_REMOVE_VIRTUAL_VOID(RemovePatch(OpalMediaPatch *));
00431 };
00432 
00433 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00434 
00435 
00438 class OpalMediaStreamPacing
00439 {
00440   public:
00441     OpalMediaStreamPacing(
00442       const OpalMediaFormat & mediaFormat 
00443     );
00444 
00446     void Pace(
00447       bool reading,     
00448       PINDEX bytes,     
00449       bool & marker     
00450     );
00451 
00452   protected:
00453     bool           m_isAudio;
00454     unsigned       m_frameTime;
00455     PINDEX         m_frameSize;
00456     unsigned       m_timeUnits;
00457     PAdaptiveDelay m_delay;
00458 };
00459 
00460 
00463 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00464 {
00465     PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00466   public:
00471     OpalNullMediaStream(
00472       OpalConnection & conn,               
00473       const OpalMediaFormat & mediaFormat, 
00474       unsigned sessionID,                  
00475       bool isSource,                       
00476       bool isSynchronous = false           
00477     );
00478     OpalNullMediaStream(
00479       OpalConnection & conn,               
00480       const OpalMediaFormat & mediaFormat, 
00481       unsigned sessionID,                  
00482       bool isSource,                       
00483       bool usePacingDelay,                 
00484       bool requiresPatchThread             
00485     );
00487 
00493     virtual PBoolean ReadData(
00494       BYTE * data,      
00495       PINDEX size,      
00496       PINDEX & length   
00497     );
00498 
00502     virtual PBoolean WriteData(
00503       const BYTE * data,   
00504       PINDEX length,       
00505       PINDEX & written     
00506     );
00507         
00511     virtual PBoolean RequiresPatchThread() const;
00512 
00516     virtual PBoolean IsSynchronous() const;
00518 
00519   protected:
00520     bool m_isSynchronous;
00521     bool m_requiresPatchThread;
00522 };
00523 
00524 
00528 class OpalRTPMediaStream : public OpalMediaStream
00529 {
00530     PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00531   public:
00537     OpalRTPMediaStream(
00538       OpalRTPConnection & conn,            
00539       const OpalMediaFormat & mediaFormat, 
00540       bool isSource,                       
00541       RTP_Session & rtpSession,            
00542       unsigned minAudioJitterDelay,        
00543       unsigned maxAudioJitterDelay         
00544     );
00545 
00549     ~OpalRTPMediaStream();
00551 
00558     virtual PBoolean Open();
00559 
00564     virtual PBoolean Close();
00565 
00569     virtual bool SetPaused(
00570       bool pause,             
00571       bool fromPatch = false  
00572     );
00573 
00577     virtual PBoolean ReadPacket(
00578       RTP_DataFrame & packet
00579     );
00580 
00584     virtual PBoolean WritePacket(
00585       RTP_DataFrame & packet
00586     );
00587 
00590     virtual PBoolean SetDataSize(
00591       PINDEX dataSize,  
00592       PINDEX frameTime  
00593     );
00594 
00598     virtual PBoolean IsSynchronous() const;
00599 
00607     virtual PBoolean RequiresPatchThread() const;
00608 
00616     virtual bool EnableJitterBuffer(bool enab = true) const;
00617 
00620     virtual PBoolean SetPatch(
00621       OpalMediaPatch * patch  
00622     );
00623 
00626     virtual RTP_Session & GetRtpSession() const
00627     { return rtpSession; }
00628 
00629 #if OPAL_STATISTICS
00630     virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00631 #endif
00632 
00633 
00634   protected:
00635     RTP_Session & rtpSession;
00636     unsigned      minAudioJitterDelay;
00637     unsigned      maxAudioJitterDelay;
00638 };
00639 
00640 
00641 
00644 class OpalRawMediaStream : public OpalMediaStream
00645 {
00646     PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00647   protected:
00652     OpalRawMediaStream(
00653       OpalConnection & conn,               
00654       const OpalMediaFormat & mediaFormat, 
00655       unsigned sessionID,                  
00656       bool isSource,                       
00657       PChannel * channel,                  
00658       bool autoDelete                      
00659     );
00660 
00663     ~OpalRawMediaStream();
00665 
00666   public:
00672     virtual PBoolean ReadData(
00673       BYTE * data,      
00674       PINDEX size,      
00675       PINDEX & length   
00676     );
00677 
00681     virtual PBoolean WriteData(
00682       const BYTE * data,   
00683       PINDEX length,       
00684       PINDEX & written     
00685     );
00686 
00689     PChannel * GetChannel() { return m_channel; }
00690 
00693     bool SetChannel(
00694       PChannel * channel,     
00695       bool autoDelete = true  
00696     );
00697 
00702     virtual PBoolean Close();
00703 
00706     virtual unsigned GetAverageSignalLevel();
00708 
00709   protected:
00710     PChannel * m_channel;
00711     bool       m_autoDelete;
00712     PMutex     m_channelMutex;
00713 
00714     PBYTEArray m_silence;
00715 
00716     PUInt64    m_averageSignalSum;
00717     unsigned   m_averageSignalSamples;
00718     PMutex     m_averagingMutex;
00719 
00720     void CollectAverage(const BYTE * buffer, PINDEX size);
00721 };
00722 
00723 
00724 
00727 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00728 {
00729     PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00730   public:
00735     OpalFileMediaStream(
00736       OpalConnection & conn,               
00737       const OpalMediaFormat & mediaFormat, 
00738       unsigned sessionID,                  
00739       bool isSource,                       
00740       PFile * file,                        
00741       bool autoDelete = true               
00742     );
00743 
00746     OpalFileMediaStream(
00747       OpalConnection & conn,               
00748       const OpalMediaFormat & mediaFormat, 
00749       unsigned sessionID,                  
00750       bool isSource,                       
00751       const PFilePath & path               
00752     );
00754 
00760     virtual PBoolean IsSynchronous() const;
00761 
00762     virtual PBoolean ReadData(
00763       BYTE * data,      
00764       PINDEX size,      
00765       PINDEX & length   
00766     );
00767 
00771     virtual PBoolean WriteData(
00772       const BYTE * data,   
00773       PINDEX length,       
00774       PINDEX & written     
00775     );
00777 
00778   protected:
00779     PFile file;
00780 };
00781 
00782 
00783 #if OPAL_PTLIB_AUDIO
00784 
00788 class PSoundChannel;
00789 
00790 class OpalAudioMediaStream : public OpalRawMediaStream
00791 {
00792     PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00793   public:
00798     OpalAudioMediaStream(
00799       OpalConnection & conn,               
00800       const OpalMediaFormat & mediaFormat, 
00801       unsigned sessionID,                  
00802       bool isSource,                       
00803       PINDEX buffers,                      
00804       unsigned bufferTime,                 
00805       PSoundChannel * channel,             
00806       bool autoDelete = true               
00807     );
00808 
00811     OpalAudioMediaStream(
00812       OpalConnection & conn,               
00813       const OpalMediaFormat & mediaFormat, 
00814       unsigned sessionID,                  
00815       bool isSource,                       
00816       PINDEX buffers,                      
00817       unsigned bufferTime,                 
00818       const PString & deviceName           
00819     );
00821 
00829     virtual PBoolean SetDataSize(
00830       PINDEX dataSize,  
00831       PINDEX frameTime  
00832     );
00833 
00837     virtual PBoolean IsSynchronous() const;
00839 
00840   protected:
00841     PINDEX   m_soundChannelBuffers;
00842     unsigned m_soundChannelBufferTime;
00843 };
00844 
00845 #endif // OPAL_PTLIB_AUDIO
00846 
00847 #if OPAL_VIDEO
00848 
00852 class PVideoInputDevice;
00853 class PVideoOutputDevice;
00854 
00855 class OpalVideoMediaStream : public OpalMediaStream
00856 {
00857     PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00858   public:
00863     OpalVideoMediaStream(
00864       OpalConnection & conn,               
00865       const OpalMediaFormat & mediaFormat, 
00866       unsigned sessionID,                  
00867       PVideoInputDevice * inputDevice,     
00868       PVideoOutputDevice * outputDevice,   
00869       bool autoDeleteInput = true,         
00870       bool autoDeleteOutput = true         
00871     );
00872 
00875     ~OpalVideoMediaStream();
00877 
00886     virtual bool InternalUpdateMediaFormat(
00887       const OpalMediaFormat & mediaFormat   
00888     );
00889 
00895     virtual PBoolean Open();
00896 
00901     virtual PBoolean Close();
00902 
00908     virtual PBoolean ReadData(
00909       BYTE * data,      
00910       PINDEX size,      
00911       PINDEX & length   
00912     );
00913 
00919     virtual PBoolean WriteData(
00920       const BYTE * data,   
00921       PINDEX length,       
00922       PINDEX & written     
00923     );
00924 
00928     virtual PBoolean IsSynchronous() const;
00929 
00932     virtual PBoolean SetDataSize(
00933       PINDEX dataSize,  
00934       PINDEX frameTime  
00935     );
00936 
00939     virtual PVideoInputDevice * GetVideoInputDevice() const
00940     {
00941       return m_inputDevice;
00942     }
00943 
00946     virtual PVideoOutputDevice * GetVideoOutputDevice() const
00947     {
00948       return m_outputDevice;
00949     }
00950 
00952 
00953   protected:
00954     PVideoInputDevice  * m_inputDevice;
00955     PVideoOutputDevice * m_outputDevice;
00956     bool                 m_autoDeleteInput;
00957     bool                 m_autoDeleteOutput;
00958     PTimeInterval        m_lastGrabTime;
00959 };
00960 
00961 #endif // OPAL_VIDEO
00962 
00963 class OpalTransportUDP;
00964 
00967 class OpalUDPMediaStream : public OpalMediaStream
00968 {
00969     PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00970   public:
00975     OpalUDPMediaStream(
00976       OpalConnection & conn,               
00977       const OpalMediaFormat & mediaFormat, 
00978       unsigned sessionID,                  
00979       bool isSource,                       
00980       OpalTransportUDP & transport         
00981     );
00983 
00984     ~OpalUDPMediaStream();
00985 
00988 
00992     virtual PBoolean ReadPacket(
00993       RTP_DataFrame & packet
00994     );
00995 
00999     virtual PBoolean WritePacket(
01000       RTP_DataFrame & packet
01001     );
01002 
01006     virtual PBoolean IsSynchronous() const;
01007 
01011     virtual PBoolean Close();
01012 
01014 
01015   private:
01016     OpalTransportUDP & udpTransport;
01017 };
01018 
01019 
01020 #endif //OPAL_OPAL_MEDIASTRM_H
01021 
01022 
01023 // End of File ///////////////////////////////////////////////////////////////