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
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
00202 virtual PBoolean Close();
00203
00207 virtual void OnStartMediaPatch();
00208
00212 virtual void OnStopMediaPatch(
00213 OpalMediaPatch & patch
00214 );
00215
00220 virtual PBoolean WritePackets(
00221 RTP_DataFrameList & packets
00222 );
00223
00229 virtual PBoolean ReadPacket(
00230 RTP_DataFrame & packet
00231 );
00232
00238 virtual PBoolean WritePacket(
00239 RTP_DataFrame & packet
00240 );
00241
00247 virtual PBoolean ReadData(
00248 BYTE * data,
00249 PINDEX size,
00250 PINDEX & length
00251 );
00252
00258 virtual PBoolean WriteData(
00259 const BYTE * data,
00260 PINDEX length,
00261 PINDEX & written
00262 );
00263
00266 bool PushPacket(
00267 RTP_DataFrame & packet
00268 );
00269
00275 virtual PBoolean SetDataSize(
00276 PINDEX dataSize,
00277 PINDEX frameTime
00278 );
00279
00283 PINDEX GetDataSize() const { return defaultDataSize; }
00284
00291 virtual PBoolean IsSynchronous() const = 0;
00292
00302 virtual PBoolean RequiresPatchThread(
00303 OpalMediaStream * stream
00304 ) const;
00305 virtual PBoolean RequiresPatchThread() const;
00306
00313 virtual bool EnableJitterBuffer(bool enab = true) const;
00315
00320 OpalConnection & GetConnection() const { return connection; }
00321
00324 bool IsSource() const { return isSource; }
00325
00328 bool IsSink() const { return !isSource; }
00329
00332 unsigned GetSessionID() const { return sessionID; }
00333
00336 void SetSessionID(unsigned id) { sessionID = id; }
00337
00341 PString GetID() const { return identifier; }
00342
00345 unsigned GetTimestamp() const { return timestamp; }
00346
00349 void SetTimestamp(unsigned ts) { timestamp = ts; }
00350
00353 bool GetMarker() const { return marker; }
00354
00357 void SetMarker(bool m) { marker = m; }
00358
00361 bool IsPaused() const { return m_paused; }
00362
00367 virtual bool SetPaused(
00368 bool pause,
00369 bool fromPatch = false
00370 );
00371
00374 bool IsOpen() const { return isOpen; }
00375
00378 virtual PBoolean SetPatch(
00379 OpalMediaPatch * patch
00380 );
00381
00384 OpalMediaPatch * GetPatch() const { return m_mediaPatch; }
00385
00388 void AddFilter(
00389 const PNotifier & filter,
00390 const OpalMediaFormat & stage = OpalMediaFormat()
00391 ) const;
00392
00395 bool RemoveFilter(
00396 const PNotifier & filter,
00397 const OpalMediaFormat & stage = OpalMediaFormat()
00398 ) const;
00399
00400 #if OPAL_STATISTICS
00401 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00402 #endif
00403
00404
00405 protected:
00406 void IncrementTimestamp(PINDEX size);
00407 bool InternalWriteData(const BYTE * data, PINDEX length, PINDEX & written);
00408
00414 virtual void InternalClose() = 0;
00415
00416 OpalConnection & connection;
00417 unsigned sessionID;
00418 PString identifier;
00419 OpalMediaFormat mediaFormat;
00420 bool m_paused;
00421 bool isSource;
00422 bool isOpen;
00423 PINDEX defaultDataSize;
00424 unsigned timestamp;
00425 bool marker;
00426 unsigned mismatchedPayloadTypes;
00427
00428 typedef PSafePtr<OpalMediaPatch, PSafePtrMultiThreaded> PatchPtr;
00429 PatchPtr m_mediaPatch;
00430
00431 RTP_DataFrame::PayloadTypes m_payloadType;
00432 unsigned m_frameTime;
00433 PINDEX m_frameSize;
00434
00435 private:
00436 P_REMOVE_VIRTUAL_VOID(OnPatchStart());
00437 P_REMOVE_VIRTUAL_VOID(OnPatchStop());
00438 P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
00439 P_REMOVE_VIRTUAL_VOID(RemovePatch(OpalMediaPatch *));
00440 };
00441
00442 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00443
00444
00447 class OpalMediaStreamPacing
00448 {
00449 public:
00450 OpalMediaStreamPacing(
00451 const OpalMediaFormat & mediaFormat
00452 );
00453
00455 void Pace(
00456 bool reading,
00457 PINDEX bytes,
00458 bool & marker
00459 );
00460
00461 protected:
00462 bool m_isAudio;
00463 unsigned m_frameTime;
00464 PINDEX m_frameSize;
00465 unsigned m_timeUnits;
00466 PAdaptiveDelay m_delay;
00467 };
00468
00469
00472 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00473 {
00474 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00475 public:
00480 OpalNullMediaStream(
00481 OpalConnection & conn,
00482 const OpalMediaFormat & mediaFormat,
00483 unsigned sessionID,
00484 bool isSource,
00485 bool isSynchronous = false
00486 );
00487 OpalNullMediaStream(
00488 OpalConnection & conn,
00489 const OpalMediaFormat & mediaFormat,
00490 unsigned sessionID,
00491 bool isSource,
00492 bool usePacingDelay,
00493 bool requiresPatchThread
00494 );
00496
00502 virtual PBoolean ReadData(
00503 BYTE * data,
00504 PINDEX size,
00505 PINDEX & length
00506 );
00507
00511 virtual PBoolean WriteData(
00512 const BYTE * data,
00513 PINDEX length,
00514 PINDEX & written
00515 );
00516
00521 virtual bool SetPaused(
00522 bool pause,
00523 bool fromPatch = false
00524 );
00525
00529 virtual PBoolean RequiresPatchThread() const;
00530
00534 virtual PBoolean IsSynchronous() const;
00536
00537 protected:
00538 virtual void InternalClose() { }
00539
00540 bool m_isSynchronous;
00541 bool m_requiresPatchThread;
00542 };
00543
00544
00548 class OpalRTPMediaStream : public OpalMediaStream
00549 {
00550 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00551 public:
00557 OpalRTPMediaStream(
00558 OpalRTPConnection & conn,
00559 const OpalMediaFormat & mediaFormat,
00560 bool isSource,
00561 RTP_Session & rtpSession,
00562 unsigned minAudioJitterDelay,
00563 unsigned maxAudioJitterDelay
00564 );
00565
00569 ~OpalRTPMediaStream();
00571
00578 virtual PBoolean Open();
00579
00583 virtual bool SetPaused(
00584 bool pause,
00585 bool fromPatch = false
00586 );
00587
00591 virtual PBoolean ReadPacket(
00592 RTP_DataFrame & packet
00593 );
00594
00598 virtual PBoolean WritePacket(
00599 RTP_DataFrame & packet
00600 );
00601
00604 virtual PBoolean SetDataSize(
00605 PINDEX dataSize,
00606 PINDEX frameTime
00607 );
00608
00612 virtual PBoolean IsSynchronous() const;
00613
00621 virtual PBoolean RequiresPatchThread() const;
00622
00630 virtual bool EnableJitterBuffer(bool enab = true) const;
00631
00634 virtual PBoolean SetPatch(
00635 OpalMediaPatch * patch
00636 );
00637
00640 virtual RTP_Session & GetRtpSession() const
00641 { return rtpSession; }
00642
00643 #if OPAL_STATISTICS
00644 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00645 #endif
00646
00647
00648 protected:
00649 virtual void InternalClose();
00650
00651 RTP_Session & rtpSession;
00652 unsigned minAudioJitterDelay;
00653 unsigned maxAudioJitterDelay;
00654 };
00655
00656
00657
00660 class OpalRawMediaStream : public OpalMediaStream
00661 {
00662 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00663 protected:
00668 OpalRawMediaStream(
00669 OpalConnection & conn,
00670 const OpalMediaFormat & mediaFormat,
00671 unsigned sessionID,
00672 bool isSource,
00673 PChannel * channel,
00674 bool autoDelete
00675 );
00676
00679 ~OpalRawMediaStream();
00681
00682 public:
00688 virtual PBoolean ReadData(
00689 BYTE * data,
00690 PINDEX size,
00691 PINDEX & length
00692 );
00693
00697 virtual PBoolean WriteData(
00698 const BYTE * data,
00699 PINDEX length,
00700 PINDEX & written
00701 );
00702
00705 PChannel * GetChannel() { return m_channel; }
00706
00709 bool SetChannel(
00710 PChannel * channel,
00711 bool autoDelete = true
00712 );
00713
00716 virtual unsigned GetAverageSignalLevel();
00718
00719 protected:
00720 virtual void InternalClose();
00721
00722 PChannel * m_channel;
00723 bool m_autoDelete;
00724 PMutex m_channelMutex;
00725
00726 PBYTEArray m_silence;
00727
00728 PUInt64 m_averageSignalSum;
00729 unsigned m_averageSignalSamples;
00730 PMutex m_averagingMutex;
00731
00732 void CollectAverage(const BYTE * buffer, PINDEX size);
00733 };
00734
00735
00736
00739 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00740 {
00741 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00742 public:
00747 OpalFileMediaStream(
00748 OpalConnection & conn,
00749 const OpalMediaFormat & mediaFormat,
00750 unsigned sessionID,
00751 bool isSource,
00752 PFile * file,
00753 bool autoDelete = true
00754 );
00755
00758 OpalFileMediaStream(
00759 OpalConnection & conn,
00760 const OpalMediaFormat & mediaFormat,
00761 unsigned sessionID,
00762 bool isSource,
00763 const PFilePath & path
00764 );
00766
00772 virtual PBoolean IsSynchronous() const;
00773
00774 virtual PBoolean ReadData(
00775 BYTE * data,
00776 PINDEX size,
00777 PINDEX & length
00778 );
00779
00783 virtual PBoolean WriteData(
00784 const BYTE * data,
00785 PINDEX length,
00786 PINDEX & written
00787 );
00789
00790 protected:
00791 PFile file;
00792 };
00793
00794
00795 #if OPAL_PTLIB_AUDIO
00796
00800 class PSoundChannel;
00801
00802 class OpalAudioMediaStream : public OpalRawMediaStream
00803 {
00804 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00805 public:
00810 OpalAudioMediaStream(
00811 OpalConnection & conn,
00812 const OpalMediaFormat & mediaFormat,
00813 unsigned sessionID,
00814 bool isSource,
00815 PINDEX buffers,
00816 unsigned bufferTime,
00817 PSoundChannel * channel,
00818 bool autoDelete = true
00819 );
00820
00823 OpalAudioMediaStream(
00824 OpalConnection & conn,
00825 const OpalMediaFormat & mediaFormat,
00826 unsigned sessionID,
00827 bool isSource,
00828 PINDEX buffers,
00829 unsigned bufferTime,
00830 const PString & deviceName
00831 );
00833
00841 virtual PBoolean SetDataSize(
00842 PINDEX dataSize,
00843 PINDEX frameTime
00844 );
00845
00849 virtual PBoolean IsSynchronous() const;
00851
00852 protected:
00853 PINDEX m_soundChannelBuffers;
00854 unsigned m_soundChannelBufferTime;
00855 };
00856
00857 #endif // OPAL_PTLIB_AUDIO
00858
00859 #if OPAL_VIDEO
00860
00864 class PVideoInputDevice;
00865 class PVideoOutputDevice;
00866
00867 class OpalVideoMediaStream : public OpalMediaStream
00868 {
00869 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00870 public:
00875 OpalVideoMediaStream(
00876 OpalConnection & conn,
00877 const OpalMediaFormat & mediaFormat,
00878 unsigned sessionID,
00879 PVideoInputDevice * inputDevice,
00880 PVideoOutputDevice * outputDevice,
00881 bool autoDeleteInput = true,
00882 bool autoDeleteOutput = true
00883 );
00884
00887 ~OpalVideoMediaStream();
00889
00898 virtual bool InternalUpdateMediaFormat(
00899 const OpalMediaFormat & mediaFormat
00900 );
00901
00907 virtual PBoolean Open();
00908
00914 virtual PBoolean ReadData(
00915 BYTE * data,
00916 PINDEX size,
00917 PINDEX & length
00918 );
00919
00925 virtual PBoolean WriteData(
00926 const BYTE * data,
00927 PINDEX length,
00928 PINDEX & written
00929 );
00930
00934 virtual PBoolean IsSynchronous() const;
00935
00938 virtual PBoolean SetDataSize(
00939 PINDEX dataSize,
00940 PINDEX frameTime
00941 );
00942
00945 virtual PVideoInputDevice * GetVideoInputDevice() const
00946 {
00947 return m_inputDevice;
00948 }
00949
00952 virtual PVideoOutputDevice * GetVideoOutputDevice() const
00953 {
00954 return m_outputDevice;
00955 }
00956
00958
00959 protected:
00960 virtual void InternalClose();
00961
00962 PVideoInputDevice * m_inputDevice;
00963 PVideoOutputDevice * m_outputDevice;
00964 bool m_autoDeleteInput;
00965 bool m_autoDeleteOutput;
00966 PTimeInterval m_lastGrabTime;
00967 };
00968
00969 #endif // OPAL_VIDEO
00970
00971 class OpalTransportUDP;
00972
00975 class OpalUDPMediaStream : public OpalMediaStream
00976 {
00977 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00978 public:
00983 OpalUDPMediaStream(
00984 OpalConnection & conn,
00985 const OpalMediaFormat & mediaFormat,
00986 unsigned sessionID,
00987 bool isSource,
00988 OpalTransportUDP & transport
00989 );
00991
00992 ~OpalUDPMediaStream();
00993
00996
01000 virtual PBoolean ReadPacket(
01001 RTP_DataFrame & packet
01002 );
01003
01007 virtual PBoolean WritePacket(
01008 RTP_DataFrame & packet
01009 );
01010
01014 virtual PBoolean IsSynchronous() const;
01016
01017 private:
01018 virtual void InternalClose();
01019
01020 OpalTransportUDP & udpTransport;
01021 };
01022
01023
01024 #endif //OPAL_OPAL_MEDIASTRM_H
01025
01026
01027