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 <rtp/jitter.h>
00046 #include <ptlib/safecoll.h>
00047 #include <ptclib/guid.h>
00048
00049
00050 class OpalRTPSession;
00051 class OpalMediaPatch;
00052 class OpalLine;
00053 class OpalConnection;
00054 class OpalRTPConnection;
00055 class OpalMediaStatistics;
00056
00057
00058 typedef PSafePtr<OpalMediaPatch, PSafePtrMultiThreaded> OpalMediaPatchPtr;
00059
00060
00116 class OpalMediaStream : public PSafeObject
00117 {
00118 PCLASSINFO(OpalMediaStream, PSafeObject);
00119 protected:
00124 OpalMediaStream(
00125 OpalConnection & conn,
00126 const OpalMediaFormat & mediaFormat,
00127 unsigned sessionID,
00128 bool isSource
00129 );
00130
00131 public:
00135 ~OpalMediaStream();
00137
00138 public:
00145 void PrintOn(
00146 ostream & strm
00147 ) const;
00149
00159 virtual OpalMediaFormat GetMediaFormat() const;
00160
00167 virtual bool SetMediaFormat(
00168 const OpalMediaFormat & mediaFormat
00169 );
00170
00180 bool UpdateMediaFormat(
00181 const OpalMediaFormat & mediaFormat
00182 );
00183
00192 virtual PBoolean ExecuteCommand(
00193 const OpalMediaCommand & command
00194 );
00195
00200 virtual PBoolean Open();
00201
00204 virtual bool IsOpen() const;
00205
00211 virtual PBoolean Start();
00212
00218 virtual PBoolean Close();
00219
00223 virtual void OnStartMediaPatch();
00224
00228 virtual void OnStopMediaPatch(
00229 OpalMediaPatch & patch
00230 );
00231
00236 virtual PBoolean WritePackets(
00237 RTP_DataFrameList & packets
00238 );
00239
00245 virtual PBoolean ReadPacket(
00246 RTP_DataFrame & packet
00247 );
00248
00254 virtual PBoolean WritePacket(
00255 RTP_DataFrame & packet
00256 );
00257
00263 virtual PBoolean ReadData(
00264 BYTE * data,
00265 PINDEX size,
00266 PINDEX & length
00267 );
00268
00274 virtual PBoolean WriteData(
00275 const BYTE * data,
00276 PINDEX length,
00277 PINDEX & written
00278 );
00279
00282 bool PushPacket(
00283 RTP_DataFrame & packet
00284 );
00285
00291 virtual PBoolean SetDataSize(
00292 PINDEX dataSize,
00293 PINDEX frameTime
00294 );
00295
00299 PINDEX GetDataSize() const { return defaultDataSize; }
00300
00307 virtual PBoolean IsSynchronous() const = 0;
00308
00318 virtual PBoolean RequiresPatchThread(
00319 OpalMediaStream * stream
00320 ) const;
00321 virtual PBoolean RequiresPatchThread() const;
00322
00329 virtual bool EnableJitterBuffer(bool enab = true) const;
00331
00336 OpalConnection & GetConnection() const { return connection; }
00337
00340 bool IsSource() const { return m_isSource; }
00341
00344 bool IsSink() const { return !m_isSource; }
00345
00348 unsigned GetSessionID() const { return sessionID; }
00349
00352 void SetSessionID(unsigned id) { sessionID = id; }
00353
00357 PString GetID() const { return identifier; }
00358
00361 unsigned GetTimestamp() const { return timestamp; }
00362
00365 void SetTimestamp(unsigned ts) { timestamp = ts; }
00366
00369 bool GetMarker() const { return marker; }
00370
00373 void SetMarker(bool m) { marker = m; }
00374
00377 bool IsPaused() const { return m_paused; }
00378
00383 virtual bool SetPaused(
00384 bool pause,
00385 bool fromPatch = false
00386 );
00387
00390 virtual PBoolean SetPatch(
00391 OpalMediaPatch * patch
00392 );
00393
00396 OpalMediaPatchPtr GetPatch() const { return m_mediaPatch; }
00397
00400 void AddFilter(
00401 const PNotifier & filter,
00402 const OpalMediaFormat & stage = OpalMediaFormat()
00403 ) const;
00404
00407 bool RemoveFilter(
00408 const PNotifier & filter,
00409 const OpalMediaFormat & stage = OpalMediaFormat()
00410 ) const;
00411
00412 #if OPAL_STATISTICS
00413 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00414 #endif
00415
00416
00417 virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & mediaFormat);
00418
00419 protected:
00420 void IncrementTimestamp(PINDEX size);
00421 bool InternalWriteData(const BYTE * data, PINDEX length, PINDEX & written);
00422 OpalMediaPatchPtr InternalSetPatchPart1(OpalMediaPatch * newPatch);
00423 void InternalSetPatchPart2(const OpalMediaPatchPtr & oldPatch);
00424 virtual bool InternalSetJitterBuffer(const OpalJitterBuffer::Init & init) const;
00425
00431 virtual void InternalClose() = 0;
00432
00433 OpalConnection & connection;
00434 unsigned sessionID;
00435 PString identifier;
00436 OpalMediaFormat mediaFormat;
00437 bool m_paused;
00438 bool m_isSource;
00439 bool m_isOpen;
00440 PINDEX defaultDataSize;
00441 unsigned timestamp;
00442 bool marker;
00443
00444 OpalMediaPatchPtr m_mediaPatch;
00445
00446 RTP_DataFrame::PayloadTypes m_payloadType;
00447 unsigned m_frameTime;
00448 PINDEX m_frameSize;
00449
00450 typedef OpalMediaPatchPtr PatchPtr;
00451
00452 private:
00453 P_REMOVE_VIRTUAL_VOID(OnPatchStart());
00454 P_REMOVE_VIRTUAL_VOID(OnPatchStop());
00455 P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
00456 P_REMOVE_VIRTUAL_VOID(RemovePatch(OpalMediaPatch *));
00457
00458 friend class OpalMediaPatch;
00459 };
00460
00461 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00462
00463
00466 class OpalMediaStreamPacing
00467 {
00468 public:
00469 OpalMediaStreamPacing(
00470 const OpalMediaFormat & mediaFormat
00471 );
00472
00474 void Pace(
00475 bool reading,
00476 PINDEX bytes,
00477 bool & marker
00478 );
00479
00480 bool UpdateMediaFormat(
00481 const OpalMediaFormat & mediaFormat
00482 );
00483
00484 protected:
00485 bool m_timeOnMarkers;
00486 unsigned m_frameTime;
00487 PINDEX m_frameSize;
00488 unsigned m_timeUnits;
00489 PAdaptiveDelay m_delay;
00490 };
00491
00492
00495 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00496 {
00497 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00498 public:
00503 OpalNullMediaStream(
00504 OpalConnection & conn,
00505 const OpalMediaFormat & mediaFormat,
00506 unsigned sessionID,
00507 bool isSource,
00508 bool isSynchronous = false
00509 );
00510 OpalNullMediaStream(
00511 OpalConnection & conn,
00512 const OpalMediaFormat & mediaFormat,
00513 unsigned sessionID,
00514 bool isSource,
00515 bool usePacingDelay,
00516 bool requiresPatchThread
00517 );
00519
00525 virtual PBoolean ReadData(
00526 BYTE * data,
00527 PINDEX size,
00528 PINDEX & length
00529 );
00530
00534 virtual PBoolean WriteData(
00535 const BYTE * data,
00536 PINDEX length,
00537 PINDEX & written
00538 );
00539
00544 virtual bool SetPaused(
00545 bool pause,
00546 bool fromPatch = false
00547 );
00548
00552 virtual PBoolean RequiresPatchThread() const;
00553
00557 virtual PBoolean IsSynchronous() const;
00559
00560 protected:
00561 virtual void InternalClose() { }
00562 virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & newMediaFormat);
00563
00564 bool m_isSynchronous;
00565 bool m_requiresPatchThread;
00566 };
00567
00568
00572 class OpalRTPMediaStream : public OpalMediaStream
00573 {
00574 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00575 public:
00581 OpalRTPMediaStream(
00582 OpalRTPConnection & conn,
00583 const OpalMediaFormat & mediaFormat,
00584 bool isSource,
00585 OpalRTPSession & rtpSession
00586 );
00587
00591 ~OpalRTPMediaStream();
00593
00600 virtual PBoolean Open();
00601
00604 virtual bool IsOpen() const;
00605
00609 virtual bool SetPaused(
00610 bool pause,
00611 bool fromPatch = false
00612 );
00613
00617 virtual PBoolean ReadPacket(
00618 RTP_DataFrame & packet
00619 );
00620
00624 virtual PBoolean WritePacket(
00625 RTP_DataFrame & packet
00626 );
00627
00630 virtual PBoolean SetDataSize(
00631 PINDEX dataSize,
00632 PINDEX frameTime
00633 );
00634
00638 virtual PBoolean IsSynchronous() const;
00639
00647 virtual PBoolean RequiresPatchThread() const;
00648
00651 virtual PBoolean SetPatch(
00652 OpalMediaPatch * patch
00653 );
00654
00657 virtual OpalRTPSession & GetRtpSession() const
00658 { return rtpSession; }
00659
00660 #if OPAL_STATISTICS
00661 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00662 #endif
00663
00664
00665 protected:
00666 virtual void InternalClose();
00667 virtual bool InternalSetJitterBuffer(const OpalJitterBuffer::Init & init) const;
00668
00669 OpalRTPSession & rtpSession;
00670 #if OPAL_VIDEO
00671 bool m_forceIntraFrameFlag;
00672 PSimpleTimer m_forceIntraFrameTimer;
00673 #endif
00674 };
00675
00676
00677
00680 class OpalRawMediaStream : public OpalMediaStream
00681 {
00682 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00683 protected:
00688 OpalRawMediaStream(
00689 OpalConnection & conn,
00690 const OpalMediaFormat & mediaFormat,
00691 unsigned sessionID,
00692 bool isSource,
00693 PChannel * channel,
00694 bool autoDelete
00695 );
00696
00699 ~OpalRawMediaStream();
00701
00702 public:
00708 virtual PBoolean ReadData(
00709 BYTE * data,
00710 PINDEX size,
00711 PINDEX & length
00712 );
00713
00717 virtual PBoolean WriteData(
00718 const BYTE * data,
00719 PINDEX length,
00720 PINDEX & written
00721 );
00722
00725 PChannel * GetChannel() { return m_channel; }
00726
00729 bool SetChannel(
00730 PChannel * channel,
00731 bool autoDelete = true
00732 );
00733
00736 virtual unsigned GetAverageSignalLevel();
00738
00739 protected:
00740 virtual void InternalClose();
00741
00742 PChannel * m_channel;
00743 bool m_autoDelete;
00744 PMutex m_channelMutex;
00745
00746 PBYTEArray m_silence;
00747
00748 PUInt64 m_averageSignalSum;
00749 unsigned m_averageSignalSamples;
00750 PMutex m_averagingMutex;
00751
00752 void CollectAverage(const BYTE * buffer, PINDEX size);
00753 };
00754
00755
00756
00759 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00760 {
00761 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00762 public:
00767 OpalFileMediaStream(
00768 OpalConnection & conn,
00769 const OpalMediaFormat & mediaFormat,
00770 unsigned sessionID,
00771 bool isSource,
00772 PFile * file,
00773 bool autoDelete = true
00774 );
00775
00778 OpalFileMediaStream(
00779 OpalConnection & conn,
00780 const OpalMediaFormat & mediaFormat,
00781 unsigned sessionID,
00782 bool isSource,
00783 const PFilePath & path
00784 );
00786
00792 virtual PBoolean IsSynchronous() const;
00793
00794 virtual PBoolean ReadData(
00795 BYTE * data,
00796 PINDEX size,
00797 PINDEX & length
00798 );
00799
00803 virtual PBoolean WriteData(
00804 const BYTE * data,
00805 PINDEX length,
00806 PINDEX & written
00807 );
00809
00810 protected:
00811 PFile file;
00812 };
00813
00814
00815 #if OPAL_PTLIB_AUDIO
00816
00820 class PSoundChannel;
00821
00822 class OpalAudioMediaStream : public OpalRawMediaStream
00823 {
00824 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00825 public:
00830 OpalAudioMediaStream(
00831 OpalConnection & conn,
00832 const OpalMediaFormat & mediaFormat,
00833 unsigned sessionID,
00834 bool isSource,
00835 PINDEX buffers,
00836 unsigned bufferTime,
00837 PSoundChannel * channel,
00838 bool autoDelete = true
00839 );
00840
00843 OpalAudioMediaStream(
00844 OpalConnection & conn,
00845 const OpalMediaFormat & mediaFormat,
00846 unsigned sessionID,
00847 bool isSource,
00848 PINDEX buffers,
00849 unsigned bufferTime,
00850 const PString & deviceName
00851 );
00853
00861 virtual PBoolean SetDataSize(
00862 PINDEX dataSize,
00863 PINDEX frameTime
00864 );
00865
00869 virtual PBoolean IsSynchronous() const;
00871
00872 protected:
00873 PINDEX m_soundChannelBuffers;
00874 unsigned m_soundChannelBufferTime;
00875 };
00876
00877 #endif // OPAL_PTLIB_AUDIO
00878
00879 #if OPAL_VIDEO
00880
00884 class PVideoInputDevice;
00885 class PVideoOutputDevice;
00886
00887 class OpalVideoMediaStream : public OpalMediaStream
00888 {
00889 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00890 public:
00895 OpalVideoMediaStream(
00896 OpalConnection & conn,
00897 const OpalMediaFormat & mediaFormat,
00898 unsigned sessionID,
00899 PVideoInputDevice * inputDevice,
00900 PVideoOutputDevice * outputDevice,
00901 bool autoDeleteInput = true,
00902 bool autoDeleteOutput = true
00903 );
00904
00907 ~OpalVideoMediaStream();
00909
00917 virtual PBoolean Open();
00918
00926 virtual PBoolean ExecuteCommand(
00927 const OpalMediaCommand & command
00928 );
00929
00935 virtual PBoolean ReadData(
00936 BYTE * data,
00937 PINDEX size,
00938 PINDEX & length
00939 );
00940
00946 virtual PBoolean WriteData(
00947 const BYTE * data,
00948 PINDEX length,
00949 PINDEX & written
00950 );
00951
00955 virtual PBoolean IsSynchronous() const;
00956
00959 virtual PBoolean SetDataSize(
00960 PINDEX dataSize,
00961 PINDEX frameTime
00962 );
00963
00966 virtual void SetVideoInputDevice(
00967 PVideoInputDevice * device,
00968 bool autoDelete = true
00969 );
00970
00973 virtual PVideoInputDevice * GetVideoInputDevice() const
00974 {
00975 return m_inputDevice;
00976 }
00977
00980 virtual void SetVideoOutputDevice(
00981 PVideoOutputDevice * device,
00982 bool autoDelete = true
00983 );
00984
00987 virtual PVideoOutputDevice * GetVideoOutputDevice() const
00988 {
00989 return m_outputDevice;
00990 }
00991
00993
00994 protected:
00995 virtual void InternalClose();
00996 virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & newMediaFormat);
00997 bool InternalAdjustDevices();
00998
00999 PVideoInputDevice * m_inputDevice;
01000 PVideoOutputDevice * m_outputDevice;
01001 bool m_autoDeleteInput;
01002 bool m_autoDeleteOutput;
01003 PTimeInterval m_lastGrabTime;
01004 bool m_needKeyFrame;
01005 PMutex m_devicesMutex;
01006 };
01007
01008 #endif // OPAL_VIDEO
01009
01010 class OpalTransportUDP;
01011
01014 class OpalUDPMediaStream : public OpalMediaStream
01015 {
01016 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
01017 public:
01022 OpalUDPMediaStream(
01023 OpalConnection & conn,
01024 const OpalMediaFormat & mediaFormat,
01025 unsigned sessionID,
01026 bool isSource,
01027 OpalTransportUDP & transport
01028 );
01030
01031 ~OpalUDPMediaStream();
01032
01035
01039 virtual PBoolean ReadPacket(
01040 RTP_DataFrame & packet
01041 );
01042
01046 virtual PBoolean WritePacket(
01047 RTP_DataFrame & packet
01048 );
01049
01053 virtual PBoolean IsSynchronous() const;
01055
01056 private:
01057 virtual void InternalClose();
01058
01059 OpalTransportUDP & udpTransport;
01060 };
01061
01062
01063 #endif //OPAL_OPAL_MEDIASTRM_H
01064
01065
01066