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 virtual bool UpdateMediaFormat(
00166 const OpalMediaFormat & mediaFormat,
00167 bool fromPatch = false
00168 );
00169
00176 virtual PBoolean ExecuteCommand(
00177 const OpalMediaCommand & command
00178 );
00179
00187 virtual void SetCommandNotifier(
00188 const PNotifier & notifier
00189 );
00190
00195 virtual PBoolean Open();
00196
00202 virtual PBoolean Start();
00203
00208 virtual PBoolean Close();
00209
00213 virtual void OnStartMediaPatch();
00214
00218 virtual void OnStopMediaPatch(
00219 OpalMediaPatch & patch
00220 );
00221
00226 virtual PBoolean WritePackets(
00227 RTP_DataFrameList & packets
00228 );
00229
00235 virtual PBoolean ReadPacket(
00236 RTP_DataFrame & packet
00237 );
00238
00244 virtual PBoolean WritePacket(
00245 RTP_DataFrame & packet
00246 );
00247
00253 virtual PBoolean ReadData(
00254 BYTE * data,
00255 PINDEX size,
00256 PINDEX & length
00257 );
00258
00264 virtual PBoolean WriteData(
00265 const BYTE * data,
00266 PINDEX length,
00267 PINDEX & written
00268 );
00269
00272 bool PushPacket(
00273 RTP_DataFrame & packet
00274 );
00275
00281 virtual PBoolean SetDataSize(
00282 PINDEX dataSize,
00283 PINDEX frameTime
00284 );
00285
00289 PINDEX GetDataSize() const { return defaultDataSize; }
00290
00297 virtual PBoolean IsSynchronous() const = 0;
00298
00308 virtual PBoolean RequiresPatchThread(
00309 OpalMediaStream * stream
00310 ) const;
00311 virtual PBoolean RequiresPatchThread() const;
00312
00319 virtual bool EnableJitterBuffer(bool enab = true) const;
00321
00326 OpalConnection & GetConnection() const { return connection; }
00327
00330 bool IsSource() const { return isSource; }
00331
00334 bool IsSink() const { return !isSource; }
00335
00338 unsigned GetSessionID() const { return sessionID; }
00339
00342 void SetSessionID(unsigned id) { sessionID = id; }
00343
00347 PString GetID() const { return identifier; }
00348
00351 unsigned GetTimestamp() const { return timestamp; }
00352
00355 void SetTimestamp(unsigned ts) { timestamp = ts; }
00356
00359 bool GetMarker() const { return marker; }
00360
00363 void SetMarker(bool m) { marker = m; }
00364
00367 bool IsPaused() const { return paused; }
00368
00372 virtual void SetPaused(
00373 bool pause
00374 );
00375
00378 bool IsOpen() const { return isOpen; }
00379
00382 virtual PBoolean SetPatch(
00383 OpalMediaPatch * patch
00384 );
00385
00388 OpalMediaPatch * GetPatch() const { return mediaPatch; }
00389
00392 void AddFilter(
00393 const PNotifier & filter,
00394 const OpalMediaFormat & stage = OpalMediaFormat()
00395 ) const;
00396
00399 bool RemoveFilter(
00400 const PNotifier & filter,
00401 const OpalMediaFormat & stage = OpalMediaFormat()
00402 ) const;
00403
00404 #if OPAL_STATISTICS
00405 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00406 #endif
00407
00408
00409 protected:
00410 void IncrementTimestamp(PINDEX size);
00411
00412 OpalConnection & connection;
00413 unsigned sessionID;
00414 PString identifier;
00415 OpalMediaFormat mediaFormat;
00416 bool paused;
00417 bool isSource;
00418 bool isOpen;
00419 PINDEX defaultDataSize;
00420 unsigned timestamp;
00421 bool marker;
00422 unsigned mismatchedPayloadTypes;
00423
00424 OpalMediaPatch * mediaPatch;
00425 PNotifier commandNotifier;
00426
00427 RTP_DataFrame::PayloadTypes m_payloadType;
00428 unsigned m_frameTime;
00429 PINDEX m_frameSize;
00430
00431 private:
00432 P_REMOVE_VIRTUAL_VOID(OnPatchStart());
00433 P_REMOVE_VIRTUAL_VOID(OnPatchStop());
00434 P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
00435 P_REMOVE_VIRTUAL_VOID(RemovePatch(OpalMediaPatch *));
00436 };
00437
00438 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00439
00440
00443 class OpalMediaStreamPacing
00444 {
00445 public:
00446 OpalMediaStreamPacing(
00447 const OpalMediaFormat & mediaFormat
00448 );
00449
00451 void Pace(
00452 bool reading,
00453 PINDEX bytes,
00454 bool & marker
00455 );
00456
00457 protected:
00458 bool m_isAudio;
00459 unsigned m_frameTime;
00460 PINDEX m_frameSize;
00461 unsigned m_timeUnits;
00462 PAdaptiveDelay m_delay;
00463 };
00464
00465
00468 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00469 {
00470 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00471 public:
00476 OpalNullMediaStream(
00477 OpalConnection & conn,
00478 const OpalMediaFormat & mediaFormat,
00479 unsigned sessionID,
00480 bool isSource,
00481 bool isSynchronous = false
00482 );
00483 OpalNullMediaStream(
00484 OpalConnection & conn,
00485 const OpalMediaFormat & mediaFormat,
00486 unsigned sessionID,
00487 bool isSource,
00488 bool usePacingDelay,
00489 bool requiresPatchThread
00490 );
00492
00498 virtual PBoolean ReadData(
00499 BYTE * data,
00500 PINDEX size,
00501 PINDEX & length
00502 );
00503
00507 virtual PBoolean WriteData(
00508 const BYTE * data,
00509 PINDEX length,
00510 PINDEX & written
00511 );
00512
00516 virtual PBoolean RequiresPatchThread() const;
00517
00521 virtual PBoolean IsSynchronous() const;
00523
00524 protected:
00525 bool m_isSynchronous;
00526 bool m_requiresPatchThread;
00527 };
00528
00529
00533 class OpalRTPMediaStream : public OpalMediaStream
00534 {
00535 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00536 public:
00542 OpalRTPMediaStream(
00543 OpalRTPConnection & conn,
00544 const OpalMediaFormat & mediaFormat,
00545 bool isSource,
00546 RTP_Session & rtpSession,
00547 unsigned minAudioJitterDelay,
00548 unsigned maxAudioJitterDelay
00549 );
00550
00554 ~OpalRTPMediaStream();
00556
00563 virtual PBoolean Open();
00564
00569 virtual PBoolean Close();
00570
00574 virtual void SetPaused(
00575 bool pause
00576 );
00577
00581 virtual PBoolean ReadPacket(
00582 RTP_DataFrame & packet
00583 );
00584
00588 virtual PBoolean WritePacket(
00589 RTP_DataFrame & packet
00590 );
00591
00594 virtual PBoolean SetDataSize(
00595 PINDEX dataSize,
00596 PINDEX frameTime
00597 );
00598
00602 virtual PBoolean IsSynchronous() const;
00603
00611 virtual PBoolean RequiresPatchThread() const;
00612
00620 virtual bool EnableJitterBuffer(bool enab = true) const;
00621
00624 virtual PBoolean SetPatch(
00625 OpalMediaPatch * patch
00626 );
00627
00630 virtual RTP_Session & GetRtpSession() const
00631 { return rtpSession; }
00632
00633 #if OPAL_STATISTICS
00634 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00635 #endif
00636
00637
00638 protected:
00639 RTP_Session & rtpSession;
00640 unsigned minAudioJitterDelay;
00641 unsigned maxAudioJitterDelay;
00642 };
00643
00644
00645
00648 class OpalRawMediaStream : public OpalMediaStream
00649 {
00650 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00651 protected:
00656 OpalRawMediaStream(
00657 OpalConnection & conn,
00658 const OpalMediaFormat & mediaFormat,
00659 unsigned sessionID,
00660 bool isSource,
00661 PChannel * channel,
00662 bool autoDelete
00663 );
00664
00667 ~OpalRawMediaStream();
00669
00670 public:
00676 virtual PBoolean ReadData(
00677 BYTE * data,
00678 PINDEX size,
00679 PINDEX & length
00680 );
00681
00685 virtual PBoolean WriteData(
00686 const BYTE * data,
00687 PINDEX length,
00688 PINDEX & written
00689 );
00690
00693 PChannel * GetChannel() { return m_channel; }
00694
00697 bool SetChannel(
00698 PChannel * channel,
00699 bool autoDelete = true
00700 );
00701
00706 virtual PBoolean Close();
00707
00710 virtual unsigned GetAverageSignalLevel();
00712
00713 protected:
00714 PChannel * m_channel;
00715 bool m_autoDelete;
00716 PMutex m_channelMutex;
00717
00718 PBYTEArray m_silence;
00719
00720 PUInt64 m_averageSignalSum;
00721 unsigned m_averageSignalSamples;
00722 PMutex m_averagingMutex;
00723
00724 void CollectAverage(const BYTE * buffer, PINDEX size);
00725 };
00726
00727
00728
00731 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00732 {
00733 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00734 public:
00739 OpalFileMediaStream(
00740 OpalConnection & conn,
00741 const OpalMediaFormat & mediaFormat,
00742 unsigned sessionID,
00743 bool isSource,
00744 PFile * file,
00745 bool autoDelete = true
00746 );
00747
00750 OpalFileMediaStream(
00751 OpalConnection & conn,
00752 const OpalMediaFormat & mediaFormat,
00753 unsigned sessionID,
00754 bool isSource,
00755 const PFilePath & path
00756 );
00758
00764 virtual PBoolean IsSynchronous() const;
00766
00767 virtual PBoolean ReadData(
00768 BYTE * data,
00769 PINDEX size,
00770 PINDEX & length
00771 );
00772
00776 virtual PBoolean WriteData(
00777 const BYTE * data,
00778 PINDEX length,
00779 PINDEX & written
00780 );
00781
00782 protected:
00783 PFile file;
00784 };
00785
00786
00787 #if OPAL_PTLIB_AUDIO
00788
00792 class PSoundChannel;
00793
00794 class OpalAudioMediaStream : public OpalRawMediaStream
00795 {
00796 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00797 public:
00802 OpalAudioMediaStream(
00803 OpalConnection & conn,
00804 const OpalMediaFormat & mediaFormat,
00805 unsigned sessionID,
00806 bool isSource,
00807 PINDEX buffers,
00808 unsigned bufferTime,
00809 PSoundChannel * channel,
00810 bool autoDelete = true
00811 );
00812
00815 OpalAudioMediaStream(
00816 OpalConnection & conn,
00817 const OpalMediaFormat & mediaFormat,
00818 unsigned sessionID,
00819 bool isSource,
00820 PINDEX buffers,
00821 unsigned bufferTime,
00822 const PString & deviceName
00823 );
00825
00833 virtual PBoolean SetDataSize(
00834 PINDEX dataSize,
00835 PINDEX frameTime
00836 );
00837
00841 virtual PBoolean IsSynchronous() const;
00843
00844 protected:
00845 PINDEX m_soundChannelBuffers;
00846 unsigned m_soundChannelBufferTime;
00847 };
00848
00849 #endif // OPAL_PTLIB_AUDIO
00850
00851 #if OPAL_VIDEO
00852
00856 class PVideoInputDevice;
00857 class PVideoOutputDevice;
00858
00859 class OpalVideoMediaStream : public OpalMediaStream
00860 {
00861 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00862 public:
00867 OpalVideoMediaStream(
00868 OpalConnection & conn,
00869 const OpalMediaFormat & mediaFormat,
00870 unsigned sessionID,
00871 PVideoInputDevice * inputDevice,
00872 PVideoOutputDevice * outputDevice,
00873 bool autoDelete = true
00874 );
00875
00878 ~OpalVideoMediaStream();
00880
00888 virtual PBoolean Open();
00889
00894 virtual PBoolean Close();
00895
00901 virtual PBoolean ReadData(
00902 BYTE * data,
00903 PINDEX size,
00904 PINDEX & length
00905 );
00906
00912 virtual PBoolean WriteData(
00913 const BYTE * data,
00914 PINDEX length,
00915 PINDEX & written
00916 );
00917
00921 virtual PBoolean IsSynchronous() const;
00922
00925 virtual PBoolean SetDataSize(
00926 PINDEX dataSize,
00927 PINDEX frameTime
00928 );
00929
00932 virtual PVideoInputDevice * GetVideoInputDevice() const {
00933 return inputDevice;
00934 }
00935
00938 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00939 return outputDevice;
00940 }
00941
00943
00944 protected:
00945 PVideoInputDevice * inputDevice;
00946 PVideoOutputDevice * outputDevice;
00947 bool autoDelete;
00948 PTimeInterval lastGrabTime;
00949 };
00950
00951 #endif // OPAL_VIDEO
00952
00953 class OpalTransportUDP;
00954
00957 class OpalUDPMediaStream : public OpalMediaStream
00958 {
00959 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00960 public:
00965 OpalUDPMediaStream(
00966 OpalConnection & conn,
00967 const OpalMediaFormat & mediaFormat,
00968 unsigned sessionID,
00969 bool isSource,
00970 OpalTransportUDP & transport
00971 );
00973
00974 ~OpalUDPMediaStream();
00975
00978
00982 virtual PBoolean ReadPacket(
00983 RTP_DataFrame & packet
00984 );
00985
00989 virtual PBoolean WritePacket(
00990 RTP_DataFrame & packet
00991 );
00992
00996 virtual PBoolean IsSynchronous() const;
00997
01001 virtual PBoolean Close();
01002
01004
01005 private:
01006 OpalTransportUDP & udpTransport;
01007 };
01008
01009
01010 #endif //OPAL_OPAL_MEDIASTRM_H
01011
01012
01013