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_MEDIASTRM_H
00033 #define __OPAL_MEDIASTRM_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039 #include <ptclib/delaychan.h>
00040
00041 #include <opal/buildopts.h>
00042 #include <opal/mediafmt.h>
00043 #include <opal/mediacmd.h>
00044 #include <ptlib/safecoll.h>
00045 #include <ptclib/guid.h>
00046
00047
00048 class RTP_Session;
00049 class OpalMediaPatch;
00050 class OpalLine;
00051 class OpalConnection;
00052 class OpalRTPConnection;
00053 class OpalMediaStatistics;
00054
00055
00061 class OpalMediaStream : public PSafeObject
00062 {
00063 PCLASSINFO(OpalMediaStream, PSafeObject);
00064 protected:
00069 OpalMediaStream(
00070 OpalConnection & conn,
00071 const OpalMediaFormat & mediaFormat,
00072 unsigned sessionID,
00073 bool isSource
00074 );
00075
00076 public:
00080 ~OpalMediaStream();
00082
00083 public:
00090 void PrintOn(
00091 ostream & strm
00092 ) const;
00094
00104 virtual OpalMediaFormat GetMediaFormat() const;
00105
00115 virtual bool UpdateMediaFormat(
00116 const OpalMediaFormat & mediaFormat,
00117 bool fromPatch = false
00118 );
00119
00126 virtual PBoolean ExecuteCommand(
00127 const OpalMediaCommand & command
00128 );
00129
00137 virtual void SetCommandNotifier(
00138 const PNotifier & notifier
00139 );
00140
00145 virtual PBoolean Open();
00146
00152 virtual PBoolean Start();
00153
00158 virtual PBoolean Close();
00159
00163 virtual void OnPatchStart();
00164
00168 virtual void OnPatchStop();
00169
00174 virtual PBoolean WritePackets(
00175 RTP_DataFrameList & packets
00176 );
00177
00183 virtual PBoolean ReadPacket(
00184 RTP_DataFrame & packet
00185 );
00186
00192 virtual PBoolean WritePacket(
00193 RTP_DataFrame & packet
00194 );
00195
00201 virtual PBoolean ReadData(
00202 BYTE * data,
00203 PINDEX size,
00204 PINDEX & length
00205 );
00206
00212 virtual PBoolean WriteData(
00213 const BYTE * data,
00214 PINDEX length,
00215 PINDEX & written
00216 );
00217
00220 bool PushPacket(
00221 RTP_DataFrame & packet
00222 );
00223
00229 virtual PBoolean SetDataSize(
00230 PINDEX dataSize
00231 );
00232
00236 PINDEX GetDataSize() const { return defaultDataSize; }
00237
00244 virtual PBoolean IsSynchronous() const = 0;
00245
00255 virtual PBoolean RequiresPatchThread(
00256 OpalMediaStream * sinkStream
00257 ) const;
00258 virtual PBoolean RequiresPatchThread() const;
00259
00264 virtual void EnableJitterBuffer() const;
00266
00271 OpalConnection & GetConnection() const { return connection; }
00272
00275 bool IsSource() const { return isSource; }
00276
00279 bool IsSink() const { return !isSource; }
00280
00283 unsigned GetSessionID() const { return sessionID; }
00284
00288 PString GetID() const { return identifier; }
00289
00292 unsigned GetTimestamp() const { return timestamp; }
00293
00296 void SetTimestamp(unsigned ts) { timestamp = ts; }
00297
00300 bool GetMarker() const { return marker; }
00301
00304 void SetMarker(bool m) { marker = m; }
00305
00308 bool IsPaused() const { return paused; }
00309
00313 virtual void SetPaused(
00314 bool pause
00315 );
00316
00319 bool IsOpen() { return isOpen; }
00320
00323 virtual PBoolean SetPatch(
00324 OpalMediaPatch * patch
00325 );
00326
00333 virtual void RemovePatch(OpalMediaPatch * patch);
00334
00337 OpalMediaPatch * GetPatch() const { return mediaPatch; }
00338
00341 void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage = OpalMediaFormat());
00342
00345 bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00346
00347 #ifdef OPAL_STATISTICS
00348 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00349 #endif
00350
00351
00352 protected:
00353 OpalConnection & connection;
00354 unsigned sessionID;
00355 PString identifier;
00356 OpalMediaFormat mediaFormat;
00357 bool paused;
00358 bool isSource;
00359 bool isOpen;
00360 PINDEX defaultDataSize;
00361 unsigned timestamp;
00362 bool marker;
00363 unsigned mismatchedPayloadTypes;
00364
00365 OpalMediaPatch * mediaPatch;
00366 PNotifier commandNotifier;
00367 };
00368
00369 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00370
00371
00374 class OpalMediaStreamPacing
00375 {
00376 public:
00377 OpalMediaStreamPacing(
00378 const OpalMediaFormat & mediaFormat
00379 );
00380
00382 void Pace(
00383 bool reading,
00384 PINDEX bytes,
00385 bool & marker
00386 );
00387
00388 protected:
00389 bool m_isAudio;
00390 unsigned m_frameTime;
00391 PINDEX m_frameSize;
00392 unsigned m_timeUnits;
00393 PAdaptiveDelay m_delay;
00394 };
00395
00396
00399 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00400 {
00401 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00402 public:
00407 OpalNullMediaStream(
00408 OpalConnection & conn,
00409 const OpalMediaFormat & mediaFormat,
00410 unsigned sessionID,
00411 bool isSource,
00412 bool isSynchronous = false
00413 );
00415
00421 virtual PBoolean ReadData(
00422 BYTE * data,
00423 PINDEX size,
00424 PINDEX & length
00425 );
00426
00430 virtual PBoolean WriteData(
00431 const BYTE * data,
00432 PINDEX length,
00433 PINDEX & written
00434 );
00435
00439 virtual PBoolean RequiresPatchThread() const;
00440
00444 virtual PBoolean IsSynchronous() const;
00446
00447 protected:
00448 bool m_isSynchronous;
00449 };
00450
00451
00455 class OpalRTPMediaStream : public OpalMediaStream
00456 {
00457 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00458 public:
00464 OpalRTPMediaStream(
00465 OpalRTPConnection & conn,
00466 const OpalMediaFormat & mediaFormat,
00467 bool isSource,
00468 RTP_Session & rtpSession,
00469 unsigned minAudioJitterDelay,
00470 unsigned maxAudioJitterDelay
00471 );
00472
00476 ~OpalRTPMediaStream();
00478
00485 virtual PBoolean Open();
00486
00491 virtual PBoolean Close();
00492
00496 virtual PBoolean ReadPacket(
00497 RTP_DataFrame & packet
00498 );
00499
00503 virtual PBoolean WritePacket(
00504 RTP_DataFrame & packet
00505 );
00506
00509 virtual PBoolean SetDataSize(
00510 PINDEX dataSize
00511 );
00512
00516 virtual PBoolean IsSynchronous() const;
00517
00522 virtual void EnableJitterBuffer() const;
00523
00526 virtual RTP_Session & GetRtpSession() const
00527 { return rtpSession; }
00528
00529 #ifdef OPAL_STATISTICS
00530 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00531 #endif
00532
00533
00534 protected:
00535 RTP_Session & rtpSession;
00536 unsigned minAudioJitterDelay;
00537 unsigned maxAudioJitterDelay;
00538 };
00539
00540
00541
00544 class OpalRawMediaStream : public OpalMediaStream
00545 {
00546 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00547 protected:
00552 OpalRawMediaStream(
00553 OpalConnection & conn,
00554 const OpalMediaFormat & mediaFormat,
00555 unsigned sessionID,
00556 bool isSource,
00557 PChannel * channel,
00558 bool autoDelete
00559 );
00560
00563 ~OpalRawMediaStream();
00565
00566 public:
00572 virtual PBoolean ReadData(
00573 BYTE * data,
00574 PINDEX size,
00575 PINDEX & length
00576 );
00577
00581 virtual PBoolean WriteData(
00582 const BYTE * data,
00583 PINDEX length,
00584 PINDEX & written
00585 );
00586
00589 PChannel * GetChannel() { return channel; }
00590
00595 virtual PBoolean Close();
00596
00599 virtual unsigned GetAverageSignalLevel();
00601
00602 protected:
00603 PChannel * channel;
00604 bool autoDelete;
00605
00606 PUInt64 averageSignalSum;
00607 unsigned averageSignalSamples;
00608 PMutex averagingMutex;
00609
00610 void CollectAverage(const BYTE * buffer, PINDEX size);
00611 };
00612
00613
00614
00617 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00618 {
00619 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00620 public:
00625 OpalFileMediaStream(
00626 OpalConnection &,
00627 const OpalMediaFormat & mediaFormat,
00628 unsigned sessionID,
00629 bool isSource,
00630 PFile * file,
00631 bool autoDelete = true
00632 );
00633
00636 OpalFileMediaStream(
00637 OpalConnection & ,
00638 const OpalMediaFormat & mediaFormat,
00639 unsigned sessionID,
00640 bool isSource,
00641 const PFilePath & path
00642 );
00644
00650 virtual PBoolean IsSynchronous() const;
00652
00653 virtual PBoolean ReadData(
00654 BYTE * data,
00655 PINDEX size,
00656 PINDEX & length
00657 );
00658
00662 virtual PBoolean WriteData(
00663 const BYTE * data,
00664 PINDEX length,
00665 PINDEX & written
00666 );
00667
00668 protected:
00669 PFile file;
00670 };
00671
00672
00673 #if P_AUDIO
00674
00678 class PSoundChannel;
00679
00680 class OpalAudioMediaStream : public OpalRawMediaStream
00681 {
00682 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00683 public:
00688 OpalAudioMediaStream(
00689 OpalConnection & conn,
00690 const OpalMediaFormat & mediaFormat,
00691 unsigned sessionID,
00692 bool isSource,
00693 PINDEX buffers,
00694 PSoundChannel * channel,
00695 bool autoDelete = true
00696 );
00697
00700 OpalAudioMediaStream(
00701 OpalConnection & conn,
00702 const OpalMediaFormat & mediaFormat,
00703 unsigned sessionID,
00704 bool isSource,
00705 PINDEX buffers,
00706 const PString & deviceName
00707 );
00709
00717 virtual PBoolean SetDataSize(
00718 PINDEX dataSize
00719 );
00720
00724 virtual PBoolean IsSynchronous() const;
00726
00727 protected:
00728 PINDEX soundChannelBuffers;
00729 };
00730
00731 #endif // P_AUDIO
00732
00733 #if OPAL_VIDEO
00734
00738 class PVideoInputDevice;
00739 class PVideoOutputDevice;
00740
00741 class OpalVideoMediaStream : public OpalMediaStream
00742 {
00743 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00744 public:
00749 OpalVideoMediaStream(
00750 OpalConnection & conn,
00751 const OpalMediaFormat & mediaFormat,
00752 unsigned sessionID,
00753 PVideoInputDevice * inputDevice,
00754 PVideoOutputDevice * outputDevice,
00755 bool autoDelete = true
00756 );
00757
00760 ~OpalVideoMediaStream();
00762
00770 virtual PBoolean Open();
00771
00776 virtual PBoolean Close();
00777
00783 virtual PBoolean ReadData(
00784 BYTE * data,
00785 PINDEX size,
00786 PINDEX & length
00787 );
00788
00794 virtual PBoolean WriteData(
00795 const BYTE * data,
00796 PINDEX length,
00797 PINDEX & written
00798 );
00799
00803 virtual PBoolean IsSynchronous() const;
00804
00807 virtual PBoolean SetDataSize(
00808 PINDEX dataSize
00809 );
00810
00813 virtual PVideoInputDevice * GetVideoInputDevice() const {
00814 return inputDevice;
00815 }
00816
00819 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00820 return outputDevice;
00821 }
00822
00824
00825 protected:
00826 PVideoInputDevice * inputDevice;
00827 PVideoOutputDevice * outputDevice;
00828 bool autoDelete;
00829 PTimeInterval lastGrabTime;
00830 };
00831
00832 #endif // OPAL_VIDEO
00833
00834 class OpalTransportUDP;
00835
00838 class OpalUDPMediaStream : public OpalMediaStream
00839 {
00840 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00841 public:
00846 OpalUDPMediaStream(
00847 OpalConnection & conn,
00848 const OpalMediaFormat & mediaFormat,
00849 unsigned sessionID,
00850 bool isSource,
00851 OpalTransportUDP & transport
00852 );
00854
00857
00861 virtual PBoolean ReadPacket(
00862 RTP_DataFrame & packet
00863 );
00864
00868 virtual PBoolean WritePacket(
00869 RTP_DataFrame & packet
00870 );
00871
00875 virtual PBoolean IsSynchronous() const;
00876
00880 virtual PBoolean Close();
00881
00883
00884 private:
00885 OpalTransportUDP & udpTransport;
00886 };
00887
00888
00889 #endif //__OPAL_MEDIASTRM_H
00890
00891
00892