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 PINDEX frameTime
00233 );
00234
00238 PINDEX GetDataSize() const { return defaultDataSize; }
00239
00246 virtual PBoolean IsSynchronous() const = 0;
00247
00257 virtual PBoolean RequiresPatchThread(
00258 OpalMediaStream * sinkStream
00259 ) const;
00260 virtual PBoolean RequiresPatchThread() const;
00261
00266 virtual void EnableJitterBuffer() const;
00268
00273 OpalConnection & GetConnection() const { return connection; }
00274
00277 bool IsSource() const { return isSource; }
00278
00281 bool IsSink() const { return !isSource; }
00282
00285 unsigned GetSessionID() const { return sessionID; }
00286
00290 PString GetID() const { return identifier; }
00291
00294 unsigned GetTimestamp() const { return timestamp; }
00295
00298 void SetTimestamp(unsigned ts) { timestamp = ts; }
00299
00302 bool GetMarker() const { return marker; }
00303
00306 void SetMarker(bool m) { marker = m; }
00307
00310 bool IsPaused() const { return paused; }
00311
00315 virtual void SetPaused(
00316 bool pause
00317 );
00318
00321 bool IsOpen() const { return isOpen; }
00322
00325 virtual PBoolean SetPatch(
00326 OpalMediaPatch * patch
00327 );
00328
00335 virtual void RemovePatch(OpalMediaPatch * patch);
00336
00339 OpalMediaPatch * GetPatch() const { return mediaPatch; }
00340
00343 void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage = OpalMediaFormat());
00344
00347 bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00348
00349 #if OPAL_STATISTICS
00350 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00351 #endif
00352
00353
00354 protected:
00355 OpalConnection & connection;
00356 unsigned sessionID;
00357 PString identifier;
00358 OpalMediaFormat mediaFormat;
00359 bool paused;
00360 bool isSource;
00361 bool isOpen;
00362 PINDEX defaultDataSize;
00363 unsigned timestamp;
00364 bool marker;
00365 unsigned mismatchedPayloadTypes;
00366
00367 OpalMediaPatch * mediaPatch;
00368 PNotifier commandNotifier;
00369 };
00370
00371 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00372
00373
00376 class OpalMediaStreamPacing
00377 {
00378 public:
00379 OpalMediaStreamPacing(
00380 const OpalMediaFormat & mediaFormat
00381 );
00382
00384 void Pace(
00385 bool reading,
00386 PINDEX bytes,
00387 bool & marker
00388 );
00389
00390 protected:
00391 bool m_isAudio;
00392 unsigned m_frameTime;
00393 PINDEX m_frameSize;
00394 unsigned m_timeUnits;
00395 PAdaptiveDelay m_delay;
00396 };
00397
00398
00401 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00402 {
00403 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00404 public:
00409 OpalNullMediaStream(
00410 OpalConnection & conn,
00411 const OpalMediaFormat & mediaFormat,
00412 unsigned sessionID,
00413 bool isSource,
00414 bool isSynchronous = false
00415 );
00417
00423 virtual PBoolean ReadData(
00424 BYTE * data,
00425 PINDEX size,
00426 PINDEX & length
00427 );
00428
00432 virtual PBoolean WriteData(
00433 const BYTE * data,
00434 PINDEX length,
00435 PINDEX & written
00436 );
00437
00441 virtual PBoolean RequiresPatchThread() const;
00442
00446 virtual PBoolean IsSynchronous() const;
00448
00449 protected:
00450 bool m_isSynchronous;
00451 };
00452
00453
00457 class OpalRTPMediaStream : public OpalMediaStream
00458 {
00459 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00460 public:
00466 OpalRTPMediaStream(
00467 OpalRTPConnection & conn,
00468 const OpalMediaFormat & mediaFormat,
00469 bool isSource,
00470 RTP_Session & rtpSession,
00471 unsigned minAudioJitterDelay,
00472 unsigned maxAudioJitterDelay
00473 );
00474
00478 ~OpalRTPMediaStream();
00480
00487 virtual PBoolean Open();
00488
00493 virtual PBoolean Close();
00494
00498 virtual PBoolean ReadPacket(
00499 RTP_DataFrame & packet
00500 );
00501
00505 virtual PBoolean WritePacket(
00506 RTP_DataFrame & packet
00507 );
00508
00511 virtual PBoolean SetDataSize(
00512 PINDEX dataSize,
00513 PINDEX frameTime
00514 );
00515
00519 virtual PBoolean IsSynchronous() const;
00520
00525 virtual void EnableJitterBuffer() const;
00526
00529 virtual RTP_Session & GetRtpSession() const
00530 { return rtpSession; }
00531
00532 #if OPAL_STATISTICS
00533 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00534 #endif
00535
00536
00537 protected:
00538 RTP_Session & rtpSession;
00539 unsigned minAudioJitterDelay;
00540 unsigned maxAudioJitterDelay;
00541 };
00542
00543
00544
00547 class OpalRawMediaStream : public OpalMediaStream
00548 {
00549 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00550 protected:
00555 OpalRawMediaStream(
00556 OpalConnection & conn,
00557 const OpalMediaFormat & mediaFormat,
00558 unsigned sessionID,
00559 bool isSource,
00560 PChannel * channel,
00561 bool autoDelete
00562 );
00563
00566 ~OpalRawMediaStream();
00568
00569 public:
00575 virtual PBoolean ReadData(
00576 BYTE * data,
00577 PINDEX size,
00578 PINDEX & length
00579 );
00580
00584 virtual PBoolean WriteData(
00585 const BYTE * data,
00586 PINDEX length,
00587 PINDEX & written
00588 );
00589
00592 PChannel * GetChannel() { return m_channel; }
00593
00596 bool SetChannel(
00597 PChannel * channel,
00598 bool autoDelete = true
00599 );
00600
00605 virtual PBoolean Close();
00606
00609 virtual unsigned GetAverageSignalLevel();
00611
00612 protected:
00613 PChannel * m_channel;
00614 bool m_autoDelete;
00615 PMutex m_channelMutex;
00616
00617 PBYTEArray m_silence;
00618
00619 PUInt64 m_averageSignalSum;
00620 unsigned m_averageSignalSamples;
00621 PMutex m_averagingMutex;
00622
00623 void CollectAverage(const BYTE * buffer, PINDEX size);
00624 };
00625
00626
00627
00630 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00631 {
00632 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00633 public:
00638 OpalFileMediaStream(
00639 OpalConnection &,
00640 const OpalMediaFormat & mediaFormat,
00641 unsigned sessionID,
00642 bool isSource,
00643 PFile * file,
00644 bool autoDelete = true
00645 );
00646
00649 OpalFileMediaStream(
00650 OpalConnection & ,
00651 const OpalMediaFormat & mediaFormat,
00652 unsigned sessionID,
00653 bool isSource,
00654 const PFilePath & path
00655 );
00657
00663 virtual PBoolean IsSynchronous() const;
00665
00666 virtual PBoolean ReadData(
00667 BYTE * data,
00668 PINDEX size,
00669 PINDEX & length
00670 );
00671
00675 virtual PBoolean WriteData(
00676 const BYTE * data,
00677 PINDEX length,
00678 PINDEX & written
00679 );
00680
00681 protected:
00682 PFile file;
00683 };
00684
00685
00686 #if OPAL_PTLIB_AUDIO
00687
00691 class PSoundChannel;
00692
00693 class OpalAudioMediaStream : public OpalRawMediaStream
00694 {
00695 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00696 public:
00701 OpalAudioMediaStream(
00702 OpalConnection & conn,
00703 const OpalMediaFormat & mediaFormat,
00704 unsigned sessionID,
00705 bool isSource,
00706 PINDEX buffers,
00707 PSoundChannel * channel,
00708 bool autoDelete = true
00709 );
00710
00713 OpalAudioMediaStream(
00714 OpalConnection & conn,
00715 const OpalMediaFormat & mediaFormat,
00716 unsigned sessionID,
00717 bool isSource,
00718 PINDEX buffers,
00719 const PString & deviceName
00720 );
00722
00730 virtual PBoolean SetDataSize(
00731 PINDEX dataSize,
00732 PINDEX frameTime
00733 );
00734
00738 virtual PBoolean IsSynchronous() const;
00740
00741 protected:
00742 PINDEX soundChannelBuffers;
00743 };
00744
00745 #endif // OPAL_PTLIB_AUDIO
00746
00747 #if OPAL_VIDEO
00748
00752 class PVideoInputDevice;
00753 class PVideoOutputDevice;
00754
00755 class OpalVideoMediaStream : public OpalMediaStream
00756 {
00757 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00758 public:
00763 OpalVideoMediaStream(
00764 OpalConnection & conn,
00765 const OpalMediaFormat & mediaFormat,
00766 unsigned sessionID,
00767 PVideoInputDevice * inputDevice,
00768 PVideoOutputDevice * outputDevice,
00769 bool autoDelete = true
00770 );
00771
00774 ~OpalVideoMediaStream();
00776
00784 virtual PBoolean Open();
00785
00790 virtual PBoolean Close();
00791
00797 virtual PBoolean ReadData(
00798 BYTE * data,
00799 PINDEX size,
00800 PINDEX & length
00801 );
00802
00808 virtual PBoolean WriteData(
00809 const BYTE * data,
00810 PINDEX length,
00811 PINDEX & written
00812 );
00813
00817 virtual PBoolean IsSynchronous() const;
00818
00821 virtual PBoolean SetDataSize(
00822 PINDEX dataSize,
00823 PINDEX frameTime
00824 );
00825
00828 virtual PVideoInputDevice * GetVideoInputDevice() const {
00829 return inputDevice;
00830 }
00831
00834 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00835 return outputDevice;
00836 }
00837
00839
00840 protected:
00841 PVideoInputDevice * inputDevice;
00842 PVideoOutputDevice * outputDevice;
00843 bool autoDelete;
00844 PTimeInterval lastGrabTime;
00845 };
00846
00847 #endif // OPAL_VIDEO
00848
00849 class OpalTransportUDP;
00850
00853 class OpalUDPMediaStream : public OpalMediaStream
00854 {
00855 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00856 public:
00861 OpalUDPMediaStream(
00862 OpalConnection & conn,
00863 const OpalMediaFormat & mediaFormat,
00864 unsigned sessionID,
00865 bool isSource,
00866 OpalTransportUDP & transport
00867 );
00869
00872
00876 virtual PBoolean ReadPacket(
00877 RTP_DataFrame & packet
00878 );
00879
00883 virtual PBoolean WritePacket(
00884 RTP_DataFrame & packet
00885 );
00886
00890 virtual PBoolean IsSynchronous() const;
00891
00895 virtual PBoolean Close();
00896
00898
00899 private:
00900 OpalTransportUDP & udpTransport;
00901 };
00902
00903
00904 #endif //OPAL_OPAL_MEDIASTRM_H
00905
00906
00907