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
00520 virtual PBoolean RequiresPatchThread() const;
00521
00525 virtual PBoolean IsSynchronous() const;
00527
00528 protected:
00529 virtual void InternalClose() { }
00530
00531 bool m_isSynchronous;
00532 bool m_requiresPatchThread;
00533 };
00534
00535
00539 class OpalRTPMediaStream : public OpalMediaStream
00540 {
00541 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00542 public:
00548 OpalRTPMediaStream(
00549 OpalRTPConnection & conn,
00550 const OpalMediaFormat & mediaFormat,
00551 bool isSource,
00552 RTP_Session & rtpSession,
00553 unsigned minAudioJitterDelay,
00554 unsigned maxAudioJitterDelay
00555 );
00556
00560 ~OpalRTPMediaStream();
00562
00569 virtual PBoolean Open();
00570
00574 virtual bool SetPaused(
00575 bool pause,
00576 bool fromPatch = false
00577 );
00578
00582 virtual PBoolean ReadPacket(
00583 RTP_DataFrame & packet
00584 );
00585
00589 virtual PBoolean WritePacket(
00590 RTP_DataFrame & packet
00591 );
00592
00595 virtual PBoolean SetDataSize(
00596 PINDEX dataSize,
00597 PINDEX frameTime
00598 );
00599
00603 virtual PBoolean IsSynchronous() const;
00604
00612 virtual PBoolean RequiresPatchThread() const;
00613
00621 virtual bool EnableJitterBuffer(bool enab = true) const;
00622
00625 virtual PBoolean SetPatch(
00626 OpalMediaPatch * patch
00627 );
00628
00631 virtual RTP_Session & GetRtpSession() const
00632 { return rtpSession; }
00633
00634 #if OPAL_STATISTICS
00635 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00636 #endif
00637
00638
00639 protected:
00640 virtual void InternalClose();
00641
00642 RTP_Session & rtpSession;
00643 unsigned minAudioJitterDelay;
00644 unsigned maxAudioJitterDelay;
00645 };
00646
00647
00648
00651 class OpalRawMediaStream : public OpalMediaStream
00652 {
00653 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00654 protected:
00659 OpalRawMediaStream(
00660 OpalConnection & conn,
00661 const OpalMediaFormat & mediaFormat,
00662 unsigned sessionID,
00663 bool isSource,
00664 PChannel * channel,
00665 bool autoDelete
00666 );
00667
00670 ~OpalRawMediaStream();
00672
00673 public:
00679 virtual PBoolean ReadData(
00680 BYTE * data,
00681 PINDEX size,
00682 PINDEX & length
00683 );
00684
00688 virtual PBoolean WriteData(
00689 const BYTE * data,
00690 PINDEX length,
00691 PINDEX & written
00692 );
00693
00696 PChannel * GetChannel() { return m_channel; }
00697
00700 bool SetChannel(
00701 PChannel * channel,
00702 bool autoDelete = true
00703 );
00704
00707 virtual unsigned GetAverageSignalLevel();
00709
00710 protected:
00711 virtual void InternalClose();
00712
00713 PChannel * m_channel;
00714 bool m_autoDelete;
00715 PMutex m_channelMutex;
00716
00717 PBYTEArray m_silence;
00718
00719 PUInt64 m_averageSignalSum;
00720 unsigned m_averageSignalSamples;
00721 PMutex m_averagingMutex;
00722
00723 void CollectAverage(const BYTE * buffer, PINDEX size);
00724 };
00725
00726
00727
00730 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00731 {
00732 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00733 public:
00738 OpalFileMediaStream(
00739 OpalConnection & conn,
00740 const OpalMediaFormat & mediaFormat,
00741 unsigned sessionID,
00742 bool isSource,
00743 PFile * file,
00744 bool autoDelete = true
00745 );
00746
00749 OpalFileMediaStream(
00750 OpalConnection & conn,
00751 const OpalMediaFormat & mediaFormat,
00752 unsigned sessionID,
00753 bool isSource,
00754 const PFilePath & path
00755 );
00757
00763 virtual PBoolean IsSynchronous() const;
00764
00765 virtual PBoolean ReadData(
00766 BYTE * data,
00767 PINDEX size,
00768 PINDEX & length
00769 );
00770
00774 virtual PBoolean WriteData(
00775 const BYTE * data,
00776 PINDEX length,
00777 PINDEX & written
00778 );
00780
00781 protected:
00782 PFile file;
00783 };
00784
00785
00786 #if OPAL_PTLIB_AUDIO
00787
00791 class PSoundChannel;
00792
00793 class OpalAudioMediaStream : public OpalRawMediaStream
00794 {
00795 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00796 public:
00801 OpalAudioMediaStream(
00802 OpalConnection & conn,
00803 const OpalMediaFormat & mediaFormat,
00804 unsigned sessionID,
00805 bool isSource,
00806 PINDEX buffers,
00807 unsigned bufferTime,
00808 PSoundChannel * channel,
00809 bool autoDelete = true
00810 );
00811
00814 OpalAudioMediaStream(
00815 OpalConnection & conn,
00816 const OpalMediaFormat & mediaFormat,
00817 unsigned sessionID,
00818 bool isSource,
00819 PINDEX buffers,
00820 unsigned bufferTime,
00821 const PString & deviceName
00822 );
00824
00832 virtual PBoolean SetDataSize(
00833 PINDEX dataSize,
00834 PINDEX frameTime
00835 );
00836
00840 virtual PBoolean IsSynchronous() const;
00842
00843 protected:
00844 PINDEX m_soundChannelBuffers;
00845 unsigned m_soundChannelBufferTime;
00846 };
00847
00848 #endif // OPAL_PTLIB_AUDIO
00849
00850 #if OPAL_VIDEO
00851
00855 class PVideoInputDevice;
00856 class PVideoOutputDevice;
00857
00858 class OpalVideoMediaStream : public OpalMediaStream
00859 {
00860 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00861 public:
00866 OpalVideoMediaStream(
00867 OpalConnection & conn,
00868 const OpalMediaFormat & mediaFormat,
00869 unsigned sessionID,
00870 PVideoInputDevice * inputDevice,
00871 PVideoOutputDevice * outputDevice,
00872 bool autoDeleteInput = true,
00873 bool autoDeleteOutput = true
00874 );
00875
00878 ~OpalVideoMediaStream();
00880
00889 virtual bool InternalUpdateMediaFormat(
00890 const OpalMediaFormat & mediaFormat
00891 );
00892
00898 virtual PBoolean Open();
00899
00905 virtual PBoolean ReadData(
00906 BYTE * data,
00907 PINDEX size,
00908 PINDEX & length
00909 );
00910
00916 virtual PBoolean WriteData(
00917 const BYTE * data,
00918 PINDEX length,
00919 PINDEX & written
00920 );
00921
00925 virtual PBoolean IsSynchronous() const;
00926
00929 virtual PBoolean SetDataSize(
00930 PINDEX dataSize,
00931 PINDEX frameTime
00932 );
00933
00936 virtual PVideoInputDevice * GetVideoInputDevice() const
00937 {
00938 return m_inputDevice;
00939 }
00940
00943 virtual PVideoOutputDevice * GetVideoOutputDevice() const
00944 {
00945 return m_outputDevice;
00946 }
00947
00949
00950 protected:
00951 virtual void InternalClose();
00952
00953 PVideoInputDevice * m_inputDevice;
00954 PVideoOutputDevice * m_outputDevice;
00955 bool m_autoDeleteInput;
00956 bool m_autoDeleteOutput;
00957 PTimeInterval m_lastGrabTime;
00958 };
00959
00960 #endif // OPAL_VIDEO
00961
00962 class OpalTransportUDP;
00963
00966 class OpalUDPMediaStream : public OpalMediaStream
00967 {
00968 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00969 public:
00974 OpalUDPMediaStream(
00975 OpalConnection & conn,
00976 const OpalMediaFormat & mediaFormat,
00977 unsigned sessionID,
00978 bool isSource,
00979 OpalTransportUDP & transport
00980 );
00982
00983 ~OpalUDPMediaStream();
00984
00987
00991 virtual PBoolean ReadPacket(
00992 RTP_DataFrame & packet
00993 );
00994
00998 virtual PBoolean WritePacket(
00999 RTP_DataFrame & packet
01000 );
01001
01005 virtual PBoolean IsSynchronous() const;
01007
01008 private:
01009 virtual void InternalClose();
01010
01011 OpalTransportUDP & udpTransport;
01012 };
01013
01014
01015 #endif //OPAL_OPAL_MEDIASTRM_H
01016
01017
01018