OPAL
Version 3.10.4
|
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 ///////////////////////////////////////////////////////////////