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
00056
00062 class OpalMediaStream : public PSafeObject
00063 {
00064 PCLASSINFO(OpalMediaStream, PSafeObject);
00065 protected:
00070 OpalMediaStream(
00071 OpalConnection & conn,
00072 const OpalMediaFormat & mediaFormat,
00073 unsigned sessionID,
00074 bool isSource
00075 );
00076
00077 public:
00081 ~OpalMediaStream();
00083
00084 public:
00091 void PrintOn(
00092 ostream & strm
00093 ) const;
00095
00105 virtual OpalMediaFormat GetMediaFormat() const;
00106
00116 virtual bool UpdateMediaFormat(
00117 const OpalMediaFormat & mediaFormat,
00118 bool fromPatch = false
00119 );
00120
00127 virtual PBoolean ExecuteCommand(
00128 const OpalMediaCommand & command
00129 );
00130
00138 virtual void SetCommandNotifier(
00139 const PNotifier & notifier
00140 );
00141
00146 virtual PBoolean Open();
00147
00153 virtual PBoolean Start();
00154
00159 virtual PBoolean Close();
00160
00164 virtual void OnStartMediaPatch();
00165
00169 virtual void OnStopMediaPatch(
00170 OpalMediaPatch & patch
00171 );
00172
00177 virtual PBoolean WritePackets(
00178 RTP_DataFrameList & packets
00179 );
00180
00186 virtual PBoolean ReadPacket(
00187 RTP_DataFrame & packet
00188 );
00189
00195 virtual PBoolean WritePacket(
00196 RTP_DataFrame & packet
00197 );
00198
00204 virtual PBoolean ReadData(
00205 BYTE * data,
00206 PINDEX size,
00207 PINDEX & length
00208 );
00209
00215 virtual PBoolean WriteData(
00216 const BYTE * data,
00217 PINDEX length,
00218 PINDEX & written
00219 );
00220
00223 bool PushPacket(
00224 RTP_DataFrame & packet
00225 );
00226
00232 virtual PBoolean SetDataSize(
00233 PINDEX dataSize,
00234 PINDEX frameTime
00235 );
00236
00240 PINDEX GetDataSize() const { return defaultDataSize; }
00241
00248 virtual PBoolean IsSynchronous() const = 0;
00249
00259 virtual PBoolean RequiresPatchThread(
00260 OpalMediaStream * stream
00261 ) const;
00262 virtual PBoolean RequiresPatchThread() const;
00263
00268 virtual void EnableJitterBuffer() const;
00270
00275 OpalConnection & GetConnection() const { return connection; }
00276
00279 bool IsSource() const { return isSource; }
00280
00283 bool IsSink() const { return !isSource; }
00284
00287 unsigned GetSessionID() const { return sessionID; }
00288
00291 void SetSessionID(unsigned id) { sessionID = id; }
00292
00296 PString GetID() const { return identifier; }
00297
00300 unsigned GetTimestamp() const { return timestamp; }
00301
00304 void SetTimestamp(unsigned ts) { timestamp = ts; }
00305
00308 bool GetMarker() const { return marker; }
00309
00312 void SetMarker(bool m) { marker = m; }
00313
00316 bool IsPaused() const { return paused; }
00317
00321 virtual void SetPaused(
00322 bool pause
00323 );
00324
00327 bool IsOpen() const { return isOpen; }
00328
00331 virtual PBoolean SetPatch(
00332 OpalMediaPatch * patch
00333 );
00334
00341 virtual void RemovePatch(OpalMediaPatch * patch);
00342
00345 OpalMediaPatch * GetPatch() const { return mediaPatch; }
00346
00349 void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage = OpalMediaFormat());
00350
00353 bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00354
00355 #if OPAL_STATISTICS
00356 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00357 #endif
00358
00359
00360 protected:
00361 void IncrementTimestamp(PINDEX size);
00362
00363 OpalConnection & connection;
00364 unsigned sessionID;
00365 PString identifier;
00366 OpalMediaFormat mediaFormat;
00367 bool paused;
00368 bool isSource;
00369 bool isOpen;
00370 PINDEX defaultDataSize;
00371 unsigned timestamp;
00372 bool marker;
00373 unsigned mismatchedPayloadTypes;
00374
00375 OpalMediaPatch * mediaPatch;
00376 PNotifier commandNotifier;
00377
00378 RTP_DataFrame::PayloadTypes m_payloadType;
00379 unsigned m_frameTime;
00380 PINDEX m_frameSize;
00381
00382 private:
00383 P_REMOVE_VIRTUAL_VOID(OnPatchStart());
00384 P_REMOVE_VIRTUAL_VOID(OnPatchStop());
00385 P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
00386 };
00387
00388 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00389
00390
00393 class OpalMediaStreamPacing
00394 {
00395 public:
00396 OpalMediaStreamPacing(
00397 const OpalMediaFormat & mediaFormat
00398 );
00399
00401 void Pace(
00402 bool reading,
00403 PINDEX bytes,
00404 bool & marker
00405 );
00406
00407 protected:
00408 bool m_isAudio;
00409 unsigned m_frameTime;
00410 PINDEX m_frameSize;
00411 unsigned m_timeUnits;
00412 PAdaptiveDelay m_delay;
00413 };
00414
00415
00418 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00419 {
00420 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00421 public:
00426 OpalNullMediaStream(
00427 OpalConnection & conn,
00428 const OpalMediaFormat & mediaFormat,
00429 unsigned sessionID,
00430 bool isSource,
00431 bool isSynchronous = false
00432 );
00433 OpalNullMediaStream(
00434 OpalConnection & conn,
00435 const OpalMediaFormat & mediaFormat,
00436 unsigned sessionID,
00437 bool isSource,
00438 bool usePacingDelay,
00439 bool requiresPatchThread
00440 );
00442
00448 virtual PBoolean ReadData(
00449 BYTE * data,
00450 PINDEX size,
00451 PINDEX & length
00452 );
00453
00457 virtual PBoolean WriteData(
00458 const BYTE * data,
00459 PINDEX length,
00460 PINDEX & written
00461 );
00462
00466 virtual PBoolean RequiresPatchThread() const;
00467
00471 virtual PBoolean IsSynchronous() const;
00473
00474 protected:
00475 bool m_isSynchronous;
00476 bool m_requiresPatchThread;
00477 };
00478
00479
00483 class OpalRTPMediaStream : public OpalMediaStream
00484 {
00485 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00486 public:
00492 OpalRTPMediaStream(
00493 OpalRTPConnection & conn,
00494 const OpalMediaFormat & mediaFormat,
00495 bool isSource,
00496 RTP_Session & rtpSession,
00497 unsigned minAudioJitterDelay,
00498 unsigned maxAudioJitterDelay
00499 );
00500
00504 ~OpalRTPMediaStream();
00506
00513 virtual PBoolean Open();
00514
00519 virtual PBoolean Close();
00520
00524 virtual void SetPaused(
00525 bool pause
00526 );
00527
00531 virtual PBoolean ReadPacket(
00532 RTP_DataFrame & packet
00533 );
00534
00538 virtual PBoolean WritePacket(
00539 RTP_DataFrame & packet
00540 );
00541
00544 virtual PBoolean SetDataSize(
00545 PINDEX dataSize,
00546 PINDEX frameTime
00547 );
00548
00552 virtual PBoolean IsSynchronous() const;
00553
00561 virtual PBoolean RequiresPatchThread() const;
00562
00567 virtual void EnableJitterBuffer() const;
00568
00571 virtual PBoolean SetPatch(
00572 OpalMediaPatch * patch
00573 );
00574
00577 virtual RTP_Session & GetRtpSession() const
00578 { return rtpSession; }
00579
00580 #if OPAL_STATISTICS
00581 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00582 #endif
00583
00584
00585 protected:
00586 RTP_Session & rtpSession;
00587 unsigned minAudioJitterDelay;
00588 unsigned maxAudioJitterDelay;
00589 };
00590
00591
00592
00595 class OpalRawMediaStream : public OpalMediaStream
00596 {
00597 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00598 protected:
00603 OpalRawMediaStream(
00604 OpalConnection & conn,
00605 const OpalMediaFormat & mediaFormat,
00606 unsigned sessionID,
00607 bool isSource,
00608 PChannel * channel,
00609 bool autoDelete
00610 );
00611
00614 ~OpalRawMediaStream();
00616
00617 public:
00623 virtual PBoolean ReadData(
00624 BYTE * data,
00625 PINDEX size,
00626 PINDEX & length
00627 );
00628
00632 virtual PBoolean WriteData(
00633 const BYTE * data,
00634 PINDEX length,
00635 PINDEX & written
00636 );
00637
00640 PChannel * GetChannel() { return m_channel; }
00641
00644 bool SetChannel(
00645 PChannel * channel,
00646 bool autoDelete = true
00647 );
00648
00653 virtual PBoolean Close();
00654
00657 virtual unsigned GetAverageSignalLevel();
00659
00660 protected:
00661 PChannel * m_channel;
00662 bool m_autoDelete;
00663 PMutex m_channelMutex;
00664
00665 PBYTEArray m_silence;
00666
00667 PUInt64 m_averageSignalSum;
00668 unsigned m_averageSignalSamples;
00669 PMutex m_averagingMutex;
00670
00671 void CollectAverage(const BYTE * buffer, PINDEX size);
00672 };
00673
00674
00675
00678 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00679 {
00680 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00681 public:
00686 OpalFileMediaStream(
00687 OpalConnection &,
00688 const OpalMediaFormat & mediaFormat,
00689 unsigned sessionID,
00690 bool isSource,
00691 PFile * file,
00692 bool autoDelete = true
00693 );
00694
00697 OpalFileMediaStream(
00698 OpalConnection & ,
00699 const OpalMediaFormat & mediaFormat,
00700 unsigned sessionID,
00701 bool isSource,
00702 const PFilePath & path
00703 );
00705
00711 virtual PBoolean IsSynchronous() const;
00713
00714 virtual PBoolean ReadData(
00715 BYTE * data,
00716 PINDEX size,
00717 PINDEX & length
00718 );
00719
00723 virtual PBoolean WriteData(
00724 const BYTE * data,
00725 PINDEX length,
00726 PINDEX & written
00727 );
00728
00729 protected:
00730 PFile file;
00731 };
00732
00733
00734 #if OPAL_PTLIB_AUDIO
00735
00739 class PSoundChannel;
00740
00741 class OpalAudioMediaStream : public OpalRawMediaStream
00742 {
00743 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00744 public:
00749 OpalAudioMediaStream(
00750 OpalConnection & conn,
00751 const OpalMediaFormat & mediaFormat,
00752 unsigned sessionID,
00753 bool isSource,
00754 PINDEX buffers,
00755 unsigned bufferTime,
00756 PSoundChannel * channel,
00757 bool autoDelete = true
00758 );
00759
00762 OpalAudioMediaStream(
00763 OpalConnection & conn,
00764 const OpalMediaFormat & mediaFormat,
00765 unsigned sessionID,
00766 bool isSource,
00767 PINDEX buffers,
00768 unsigned bufferTime,
00769 const PString & deviceName
00770 );
00772
00780 virtual PBoolean SetDataSize(
00781 PINDEX dataSize,
00782 PINDEX frameTime
00783 );
00784
00788 virtual PBoolean IsSynchronous() const;
00790
00791 protected:
00792 PINDEX m_soundChannelBuffers;
00793 unsigned m_soundChannelBufferTime;
00794 };
00795
00796 #endif // OPAL_PTLIB_AUDIO
00797
00798 #if OPAL_VIDEO
00799
00803 class PVideoInputDevice;
00804 class PVideoOutputDevice;
00805
00806 class OpalVideoMediaStream : public OpalMediaStream
00807 {
00808 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00809 public:
00814 OpalVideoMediaStream(
00815 OpalConnection & conn,
00816 const OpalMediaFormat & mediaFormat,
00817 unsigned sessionID,
00818 PVideoInputDevice * inputDevice,
00819 PVideoOutputDevice * outputDevice,
00820 bool autoDelete = true
00821 );
00822
00825 ~OpalVideoMediaStream();
00827
00835 virtual PBoolean Open();
00836
00841 virtual PBoolean Close();
00842
00848 virtual PBoolean ReadData(
00849 BYTE * data,
00850 PINDEX size,
00851 PINDEX & length
00852 );
00853
00859 virtual PBoolean WriteData(
00860 const BYTE * data,
00861 PINDEX length,
00862 PINDEX & written
00863 );
00864
00868 virtual PBoolean IsSynchronous() const;
00869
00872 virtual PBoolean SetDataSize(
00873 PINDEX dataSize,
00874 PINDEX frameTime
00875 );
00876
00879 virtual PVideoInputDevice * GetVideoInputDevice() const {
00880 return inputDevice;
00881 }
00882
00885 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00886 return outputDevice;
00887 }
00888
00890
00891 protected:
00892 PVideoInputDevice * inputDevice;
00893 PVideoOutputDevice * outputDevice;
00894 bool autoDelete;
00895 PTimeInterval lastGrabTime;
00896 };
00897
00898 #endif // OPAL_VIDEO
00899
00900 class OpalTransportUDP;
00901
00904 class OpalUDPMediaStream : public OpalMediaStream
00905 {
00906 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00907 public:
00912 OpalUDPMediaStream(
00913 OpalConnection & conn,
00914 const OpalMediaFormat & mediaFormat,
00915 unsigned sessionID,
00916 bool isSource,
00917 OpalTransportUDP & transport
00918 );
00920
00921 ~OpalUDPMediaStream();
00922
00925
00929 virtual PBoolean ReadPacket(
00930 RTP_DataFrame & packet
00931 );
00932
00936 virtual PBoolean WritePacket(
00937 RTP_DataFrame & packet
00938 );
00939
00943 virtual PBoolean IsSynchronous() const;
00944
00948 virtual PBoolean Close();
00949
00951
00952 private:
00953 OpalTransportUDP & udpTransport;
00954 };
00955
00956
00957 #endif //OPAL_OPAL_MEDIASTRM_H
00958
00959
00960