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 channel; }
00591
00596 virtual PBoolean Close();
00597
00600 virtual unsigned GetAverageSignalLevel();
00602
00603 protected:
00604 PChannel * channel;
00605 bool autoDelete;
00606
00607 PUInt64 averageSignalSum;
00608 unsigned averageSignalSamples;
00609 PMutex averagingMutex;
00610
00611 void CollectAverage(const BYTE * buffer, PINDEX size);
00612 };
00613
00614
00615
00618 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00619 {
00620 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00621 public:
00626 OpalFileMediaStream(
00627 OpalConnection &,
00628 const OpalMediaFormat & mediaFormat,
00629 unsigned sessionID,
00630 bool isSource,
00631 PFile * file,
00632 bool autoDelete = true
00633 );
00634
00637 OpalFileMediaStream(
00638 OpalConnection & ,
00639 const OpalMediaFormat & mediaFormat,
00640 unsigned sessionID,
00641 bool isSource,
00642 const PFilePath & path
00643 );
00645
00651 virtual PBoolean IsSynchronous() const;
00653
00654 virtual PBoolean ReadData(
00655 BYTE * data,
00656 PINDEX size,
00657 PINDEX & length
00658 );
00659
00663 virtual PBoolean WriteData(
00664 const BYTE * data,
00665 PINDEX length,
00666 PINDEX & written
00667 );
00668
00669 protected:
00670 PFile file;
00671 };
00672
00673
00674 #if OPAL_PTLIB_AUDIO
00675
00679 class PSoundChannel;
00680
00681 class OpalAudioMediaStream : public OpalRawMediaStream
00682 {
00683 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00684 public:
00689 OpalAudioMediaStream(
00690 OpalConnection & conn,
00691 const OpalMediaFormat & mediaFormat,
00692 unsigned sessionID,
00693 bool isSource,
00694 PINDEX buffers,
00695 PSoundChannel * channel,
00696 bool autoDelete = true
00697 );
00698
00701 OpalAudioMediaStream(
00702 OpalConnection & conn,
00703 const OpalMediaFormat & mediaFormat,
00704 unsigned sessionID,
00705 bool isSource,
00706 PINDEX buffers,
00707 const PString & deviceName
00708 );
00710
00718 virtual PBoolean SetDataSize(
00719 PINDEX dataSize
00720 );
00721
00725 virtual PBoolean IsSynchronous() const;
00727
00728 protected:
00729 PINDEX soundChannelBuffers;
00730 };
00731
00732 #endif // OPAL_PTLIB_AUDIO
00733
00734 #if OPAL_VIDEO
00735
00739 class PVideoInputDevice;
00740 class PVideoOutputDevice;
00741
00742 class OpalVideoMediaStream : public OpalMediaStream
00743 {
00744 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00745 public:
00750 OpalVideoMediaStream(
00751 OpalConnection & conn,
00752 const OpalMediaFormat & mediaFormat,
00753 unsigned sessionID,
00754 PVideoInputDevice * inputDevice,
00755 PVideoOutputDevice * outputDevice,
00756 bool autoDelete = true
00757 );
00758
00761 ~OpalVideoMediaStream();
00763
00771 virtual PBoolean Open();
00772
00777 virtual PBoolean Close();
00778
00784 virtual PBoolean ReadData(
00785 BYTE * data,
00786 PINDEX size,
00787 PINDEX & length
00788 );
00789
00795 virtual PBoolean WriteData(
00796 const BYTE * data,
00797 PINDEX length,
00798 PINDEX & written
00799 );
00800
00804 virtual PBoolean IsSynchronous() const;
00805
00808 virtual PBoolean SetDataSize(
00809 PINDEX dataSize
00810 );
00811
00814 virtual PVideoInputDevice * GetVideoInputDevice() const {
00815 return inputDevice;
00816 }
00817
00820 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00821 return outputDevice;
00822 }
00823
00825
00826 protected:
00827 PVideoInputDevice * inputDevice;
00828 PVideoOutputDevice * outputDevice;
00829 bool autoDelete;
00830 PTimeInterval lastGrabTime;
00831 };
00832
00833 #endif // OPAL_VIDEO
00834
00835 class OpalTransportUDP;
00836
00839 class OpalUDPMediaStream : public OpalMediaStream
00840 {
00841 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00842 public:
00847 OpalUDPMediaStream(
00848 OpalConnection & conn,
00849 const OpalMediaFormat & mediaFormat,
00850 unsigned sessionID,
00851 bool isSource,
00852 OpalTransportUDP & transport
00853 );
00855
00858
00862 virtual PBoolean ReadPacket(
00863 RTP_DataFrame & packet
00864 );
00865
00869 virtual PBoolean WritePacket(
00870 RTP_DataFrame & packet
00871 );
00872
00876 virtual PBoolean IsSynchronous() const;
00877
00881 virtual PBoolean Close();
00882
00884
00885 private:
00886 OpalTransportUDP & udpTransport;
00887 };
00888
00889
00890 #endif //OPAL_OPAL_MEDIASTRM_H
00891
00892
00893