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 OnPatchStart();
00165
00169 virtual void OnPatchStop();
00170
00175 virtual PBoolean WritePackets(
00176 RTP_DataFrameList & packets
00177 );
00178
00184 virtual PBoolean ReadPacket(
00185 RTP_DataFrame & packet
00186 );
00187
00193 virtual PBoolean WritePacket(
00194 RTP_DataFrame & packet
00195 );
00196
00202 virtual PBoolean ReadData(
00203 BYTE * data,
00204 PINDEX size,
00205 PINDEX & length
00206 );
00207
00213 virtual PBoolean WriteData(
00214 const BYTE * data,
00215 PINDEX length,
00216 PINDEX & written
00217 );
00218
00221 bool PushPacket(
00222 RTP_DataFrame & packet
00223 );
00224
00230 virtual PBoolean SetDataSize(
00231 PINDEX dataSize
00232 );
00233
00237 PINDEX GetDataSize() const { return defaultDataSize; }
00238
00245 virtual PBoolean IsSynchronous() const = 0;
00246
00256 virtual PBoolean RequiresPatchThread(
00257 OpalMediaStream * sinkStream
00258 ) const;
00259 virtual PBoolean RequiresPatchThread() const;
00260
00265 virtual void EnableJitterBuffer() const;
00267
00272 OpalConnection & GetConnection() const { return connection; }
00273
00276 bool IsSource() const { return isSource; }
00277
00280 bool IsSink() const { return !isSource; }
00281
00284 unsigned GetSessionID() const { return sessionID; }
00285
00289 PString GetID() const { return identifier; }
00290
00293 unsigned GetTimestamp() const { return timestamp; }
00294
00297 void SetTimestamp(unsigned ts) { timestamp = ts; }
00298
00301 bool GetMarker() const { return marker; }
00302
00305 void SetMarker(bool m) { marker = m; }
00306
00309 bool IsPaused() const { return paused; }
00310
00314 virtual void SetPaused(
00315 bool pause
00316 );
00317
00320 bool IsOpen() { return isOpen; }
00321
00324 virtual PBoolean SetPatch(
00325 OpalMediaPatch * patch
00326 );
00327
00334 virtual void RemovePatch(OpalMediaPatch * patch);
00335
00338 OpalMediaPatch * GetPatch() const { return mediaPatch; }
00339
00342 void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage = OpalMediaFormat());
00343
00346 bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00347
00348 #if OPAL_STATISTICS
00349 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00350 #endif
00351
00352
00353 protected:
00354 OpalConnection & connection;
00355 unsigned sessionID;
00356 PString identifier;
00357 OpalMediaFormat mediaFormat;
00358 bool paused;
00359 bool isSource;
00360 bool isOpen;
00361 PINDEX defaultDataSize;
00362 unsigned timestamp;
00363 bool marker;
00364 unsigned mismatchedPayloadTypes;
00365
00366 OpalMediaPatch * mediaPatch;
00367 PNotifier commandNotifier;
00368 };
00369
00370 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00371
00372
00375 class OpalMediaStreamPacing
00376 {
00377 public:
00378 OpalMediaStreamPacing(
00379 const OpalMediaFormat & mediaFormat
00380 );
00381
00383 void Pace(
00384 bool reading,
00385 PINDEX bytes,
00386 bool & marker
00387 );
00388
00389 protected:
00390 bool m_isAudio;
00391 unsigned m_frameTime;
00392 PINDEX m_frameSize;
00393 unsigned m_timeUnits;
00394 PAdaptiveDelay m_delay;
00395 };
00396
00397
00400 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00401 {
00402 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00403 public:
00408 OpalNullMediaStream(
00409 OpalConnection & conn,
00410 const OpalMediaFormat & mediaFormat,
00411 unsigned sessionID,
00412 bool isSource,
00413 bool isSynchronous = false
00414 );
00416
00422 virtual PBoolean ReadData(
00423 BYTE * data,
00424 PINDEX size,
00425 PINDEX & length
00426 );
00427
00431 virtual PBoolean WriteData(
00432 const BYTE * data,
00433 PINDEX length,
00434 PINDEX & written
00435 );
00436
00440 virtual PBoolean RequiresPatchThread() const;
00441
00445 virtual PBoolean IsSynchronous() const;
00447
00448 protected:
00449 bool m_isSynchronous;
00450 };
00451
00452
00456 class OpalRTPMediaStream : public OpalMediaStream
00457 {
00458 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00459 public:
00465 OpalRTPMediaStream(
00466 OpalRTPConnection & conn,
00467 const OpalMediaFormat & mediaFormat,
00468 bool isSource,
00469 RTP_Session & rtpSession,
00470 unsigned minAudioJitterDelay,
00471 unsigned maxAudioJitterDelay
00472 );
00473
00477 ~OpalRTPMediaStream();
00479
00486 virtual PBoolean Open();
00487
00492 virtual PBoolean Close();
00493
00497 virtual PBoolean ReadPacket(
00498 RTP_DataFrame & packet
00499 );
00500
00504 virtual PBoolean WritePacket(
00505 RTP_DataFrame & packet
00506 );
00507
00510 virtual PBoolean SetDataSize(
00511 PINDEX dataSize
00512 );
00513
00517 virtual PBoolean IsSynchronous() const;
00518
00523 virtual void EnableJitterBuffer() const;
00524
00527 virtual RTP_Session & GetRtpSession() const
00528 { return rtpSession; }
00529
00530 #if OPAL_STATISTICS
00531 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00532 #endif
00533
00534
00535 protected:
00536 RTP_Session & rtpSession;
00537 unsigned minAudioJitterDelay;
00538 unsigned maxAudioJitterDelay;
00539 };
00540
00541
00542
00545 class OpalRawMediaStream : public OpalMediaStream
00546 {
00547 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00548 protected:
00553 OpalRawMediaStream(
00554 OpalConnection & conn,
00555 const OpalMediaFormat & mediaFormat,
00556 unsigned sessionID,
00557 bool isSource,
00558 PChannel * channel,
00559 bool autoDelete
00560 );
00561
00564 ~OpalRawMediaStream();
00566
00567 public:
00573 virtual PBoolean ReadData(
00574 BYTE * data,
00575 PINDEX size,
00576 PINDEX & length
00577 );
00578
00582 virtual PBoolean WriteData(
00583 const BYTE * data,
00584 PINDEX length,
00585 PINDEX & written
00586 );
00587
00590 PChannel * GetChannel() { return m_channel; }
00591
00594 bool SetChannel(
00595 PChannel * channel,
00596 bool autoDelete = true
00597 );
00598
00603 virtual PBoolean Close();
00604
00607 virtual unsigned GetAverageSignalLevel();
00609
00610 protected:
00611 PChannel * m_channel;
00612 bool m_autoDelete;
00613 PMutex m_channelMutex;
00614
00615 PBYTEArray m_silence;
00616
00617 PUInt64 m_averageSignalSum;
00618 unsigned m_averageSignalSamples;
00619 PMutex m_averagingMutex;
00620
00621 void CollectAverage(const BYTE * buffer, PINDEX size);
00622 };
00623
00624
00625
00628 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00629 {
00630 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00631 public:
00636 OpalFileMediaStream(
00637 OpalConnection &,
00638 const OpalMediaFormat & mediaFormat,
00639 unsigned sessionID,
00640 bool isSource,
00641 PFile * file,
00642 bool autoDelete = true
00643 );
00644
00647 OpalFileMediaStream(
00648 OpalConnection & ,
00649 const OpalMediaFormat & mediaFormat,
00650 unsigned sessionID,
00651 bool isSource,
00652 const PFilePath & path
00653 );
00655
00661 virtual PBoolean IsSynchronous() const;
00663
00664 virtual PBoolean ReadData(
00665 BYTE * data,
00666 PINDEX size,
00667 PINDEX & length
00668 );
00669
00673 virtual PBoolean WriteData(
00674 const BYTE * data,
00675 PINDEX length,
00676 PINDEX & written
00677 );
00678
00679 protected:
00680 PFile file;
00681 };
00682
00683
00684 #if OPAL_PTLIB_AUDIO
00685
00689 class PSoundChannel;
00690
00691 class OpalAudioMediaStream : public OpalRawMediaStream
00692 {
00693 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00694 public:
00699 OpalAudioMediaStream(
00700 OpalConnection & conn,
00701 const OpalMediaFormat & mediaFormat,
00702 unsigned sessionID,
00703 bool isSource,
00704 PINDEX buffers,
00705 PSoundChannel * channel,
00706 bool autoDelete = true
00707 );
00708
00711 OpalAudioMediaStream(
00712 OpalConnection & conn,
00713 const OpalMediaFormat & mediaFormat,
00714 unsigned sessionID,
00715 bool isSource,
00716 PINDEX buffers,
00717 const PString & deviceName
00718 );
00720
00728 virtual PBoolean SetDataSize(
00729 PINDEX dataSize
00730 );
00731
00735 virtual PBoolean IsSynchronous() const;
00737
00738 protected:
00739 PINDEX soundChannelBuffers;
00740 };
00741
00742 #endif // OPAL_PTLIB_AUDIO
00743
00744 #if OPAL_VIDEO
00745
00749 class PVideoInputDevice;
00750 class PVideoOutputDevice;
00751
00752 class OpalVideoMediaStream : public OpalMediaStream
00753 {
00754 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00755 public:
00760 OpalVideoMediaStream(
00761 OpalConnection & conn,
00762 const OpalMediaFormat & mediaFormat,
00763 unsigned sessionID,
00764 PVideoInputDevice * inputDevice,
00765 PVideoOutputDevice * outputDevice,
00766 bool autoDelete = true
00767 );
00768
00771 ~OpalVideoMediaStream();
00773
00781 virtual PBoolean Open();
00782
00787 virtual PBoolean Close();
00788
00794 virtual PBoolean ReadData(
00795 BYTE * data,
00796 PINDEX size,
00797 PINDEX & length
00798 );
00799
00805 virtual PBoolean WriteData(
00806 const BYTE * data,
00807 PINDEX length,
00808 PINDEX & written
00809 );
00810
00814 virtual PBoolean IsSynchronous() const;
00815
00818 virtual PBoolean SetDataSize(
00819 PINDEX dataSize
00820 );
00821
00824 virtual PVideoInputDevice * GetVideoInputDevice() const {
00825 return inputDevice;
00826 }
00827
00830 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00831 return outputDevice;
00832 }
00833
00835
00836 protected:
00837 PVideoInputDevice * inputDevice;
00838 PVideoOutputDevice * outputDevice;
00839 bool autoDelete;
00840 PTimeInterval lastGrabTime;
00841 };
00842
00843 #endif // OPAL_VIDEO
00844
00845 class OpalTransportUDP;
00846
00849 class OpalUDPMediaStream : public OpalMediaStream
00850 {
00851 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00852 public:
00857 OpalUDPMediaStream(
00858 OpalConnection & conn,
00859 const OpalMediaFormat & mediaFormat,
00860 unsigned sessionID,
00861 bool isSource,
00862 OpalTransportUDP & transport
00863 );
00865
00868
00872 virtual PBoolean ReadPacket(
00873 RTP_DataFrame & packet
00874 );
00875
00879 virtual PBoolean WritePacket(
00880 RTP_DataFrame & packet
00881 );
00882
00886 virtual PBoolean IsSynchronous() const;
00887
00891 virtual PBoolean Close();
00892
00894
00895 private:
00896 OpalTransportUDP & udpTransport;
00897 };
00898
00899
00900 #endif //OPAL_OPAL_MEDIASTRM_H
00901
00902
00903