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
00289 void SetSessionID(unsigned id) { sessionID = id; }
00290
00294 PString GetID() const { return identifier; }
00295
00298 unsigned GetTimestamp() const { return timestamp; }
00299
00302 void SetTimestamp(unsigned ts) { timestamp = ts; }
00303
00306 bool GetMarker() const { return marker; }
00307
00310 void SetMarker(bool m) { marker = m; }
00311
00314 bool IsPaused() const { return paused; }
00315
00319 virtual void SetPaused(
00320 bool pause
00321 );
00322
00325 bool IsOpen() const { return isOpen; }
00326
00329 virtual PBoolean SetPatch(
00330 OpalMediaPatch * patch
00331 );
00332
00339 virtual void RemovePatch(OpalMediaPatch * patch);
00340
00343 OpalMediaPatch * GetPatch() const { return mediaPatch; }
00344
00347 void AddFilter(const PNotifier & Filter, const OpalMediaFormat & Stage = OpalMediaFormat());
00348
00351 bool RemoveFilter(const PNotifier & Filter, const OpalMediaFormat & Stage);
00352
00353 #if OPAL_STATISTICS
00354 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00355 #endif
00356
00357
00358 protected:
00359 OpalConnection & connection;
00360 unsigned sessionID;
00361 PString identifier;
00362 OpalMediaFormat mediaFormat;
00363 bool paused;
00364 bool isSource;
00365 bool isOpen;
00366 PINDEX defaultDataSize;
00367 unsigned timestamp;
00368 bool marker;
00369 unsigned mismatchedPayloadTypes;
00370
00371 OpalMediaPatch * mediaPatch;
00372 PNotifier commandNotifier;
00373 };
00374
00375 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
00376
00377
00380 class OpalMediaStreamPacing
00381 {
00382 public:
00383 OpalMediaStreamPacing(
00384 const OpalMediaFormat & mediaFormat
00385 );
00386
00388 void Pace(
00389 bool reading,
00390 PINDEX bytes,
00391 bool & marker
00392 );
00393
00394 protected:
00395 bool m_isAudio;
00396 unsigned m_frameTime;
00397 PINDEX m_frameSize;
00398 unsigned m_timeUnits;
00399 PAdaptiveDelay m_delay;
00400 };
00401
00402
00405 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
00406 {
00407 PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
00408 public:
00413 OpalNullMediaStream(
00414 OpalConnection & conn,
00415 const OpalMediaFormat & mediaFormat,
00416 unsigned sessionID,
00417 bool isSource,
00418 bool isSynchronous = false
00419 );
00421
00427 virtual PBoolean ReadData(
00428 BYTE * data,
00429 PINDEX size,
00430 PINDEX & length
00431 );
00432
00436 virtual PBoolean WriteData(
00437 const BYTE * data,
00438 PINDEX length,
00439 PINDEX & written
00440 );
00441
00445 virtual PBoolean RequiresPatchThread() const;
00446
00450 virtual PBoolean IsSynchronous() const;
00452
00453 protected:
00454 bool m_isSynchronous;
00455 };
00456
00457
00461 class OpalRTPMediaStream : public OpalMediaStream
00462 {
00463 PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
00464 public:
00470 OpalRTPMediaStream(
00471 OpalRTPConnection & conn,
00472 const OpalMediaFormat & mediaFormat,
00473 bool isSource,
00474 RTP_Session & rtpSession,
00475 unsigned minAudioJitterDelay,
00476 unsigned maxAudioJitterDelay
00477 );
00478
00482 ~OpalRTPMediaStream();
00484
00491 virtual PBoolean Open();
00492
00497 virtual PBoolean Close();
00498
00502 virtual PBoolean ReadPacket(
00503 RTP_DataFrame & packet
00504 );
00505
00509 virtual PBoolean WritePacket(
00510 RTP_DataFrame & packet
00511 );
00512
00515 virtual PBoolean SetDataSize(
00516 PINDEX dataSize,
00517 PINDEX frameTime
00518 );
00519
00523 virtual PBoolean IsSynchronous() const;
00524
00529 virtual void EnableJitterBuffer() const;
00530
00533 virtual RTP_Session & GetRtpSession() const
00534 { return rtpSession; }
00535
00536 #if OPAL_STATISTICS
00537 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00538 #endif
00539
00540
00541 protected:
00542 RTP_Session & rtpSession;
00543 unsigned minAudioJitterDelay;
00544 unsigned maxAudioJitterDelay;
00545 };
00546
00547
00548
00551 class OpalRawMediaStream : public OpalMediaStream
00552 {
00553 PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
00554 protected:
00559 OpalRawMediaStream(
00560 OpalConnection & conn,
00561 const OpalMediaFormat & mediaFormat,
00562 unsigned sessionID,
00563 bool isSource,
00564 PChannel * channel,
00565 bool autoDelete
00566 );
00567
00570 ~OpalRawMediaStream();
00572
00573 public:
00579 virtual PBoolean ReadData(
00580 BYTE * data,
00581 PINDEX size,
00582 PINDEX & length
00583 );
00584
00588 virtual PBoolean WriteData(
00589 const BYTE * data,
00590 PINDEX length,
00591 PINDEX & written
00592 );
00593
00596 PChannel * GetChannel() { return m_channel; }
00597
00600 bool SetChannel(
00601 PChannel * channel,
00602 bool autoDelete = true
00603 );
00604
00609 virtual PBoolean Close();
00610
00613 virtual unsigned GetAverageSignalLevel();
00615
00616 protected:
00617 PChannel * m_channel;
00618 bool m_autoDelete;
00619 PMutex m_channelMutex;
00620
00621 PBYTEArray m_silence;
00622
00623 PUInt64 m_averageSignalSum;
00624 unsigned m_averageSignalSamples;
00625 PMutex m_averagingMutex;
00626
00627 void CollectAverage(const BYTE * buffer, PINDEX size);
00628 };
00629
00630
00631
00634 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
00635 {
00636 PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
00637 public:
00642 OpalFileMediaStream(
00643 OpalConnection &,
00644 const OpalMediaFormat & mediaFormat,
00645 unsigned sessionID,
00646 bool isSource,
00647 PFile * file,
00648 bool autoDelete = true
00649 );
00650
00653 OpalFileMediaStream(
00654 OpalConnection & ,
00655 const OpalMediaFormat & mediaFormat,
00656 unsigned sessionID,
00657 bool isSource,
00658 const PFilePath & path
00659 );
00661
00667 virtual PBoolean IsSynchronous() const;
00669
00670 virtual PBoolean ReadData(
00671 BYTE * data,
00672 PINDEX size,
00673 PINDEX & length
00674 );
00675
00679 virtual PBoolean WriteData(
00680 const BYTE * data,
00681 PINDEX length,
00682 PINDEX & written
00683 );
00684
00685 protected:
00686 PFile file;
00687 };
00688
00689
00690 #if OPAL_PTLIB_AUDIO
00691
00695 class PSoundChannel;
00696
00697 class OpalAudioMediaStream : public OpalRawMediaStream
00698 {
00699 PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
00700 public:
00705 OpalAudioMediaStream(
00706 OpalConnection & conn,
00707 const OpalMediaFormat & mediaFormat,
00708 unsigned sessionID,
00709 bool isSource,
00710 PINDEX buffers,
00711 unsigned bufferTime,
00712 PSoundChannel * channel,
00713 bool autoDelete = true
00714 );
00715
00718 OpalAudioMediaStream(
00719 OpalConnection & conn,
00720 const OpalMediaFormat & mediaFormat,
00721 unsigned sessionID,
00722 bool isSource,
00723 PINDEX buffers,
00724 unsigned bufferTime,
00725 const PString & deviceName
00726 );
00728
00736 virtual PBoolean SetDataSize(
00737 PINDEX dataSize,
00738 PINDEX frameTime
00739 );
00740
00744 virtual PBoolean IsSynchronous() const;
00746
00747 protected:
00748 PINDEX m_soundChannelBuffers;
00749 unsigned m_soundChannelBufferTime;
00750 };
00751
00752 #endif // OPAL_PTLIB_AUDIO
00753
00754 #if OPAL_VIDEO
00755
00759 class PVideoInputDevice;
00760 class PVideoOutputDevice;
00761
00762 class OpalVideoMediaStream : public OpalMediaStream
00763 {
00764 PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
00765 public:
00770 OpalVideoMediaStream(
00771 OpalConnection & conn,
00772 const OpalMediaFormat & mediaFormat,
00773 unsigned sessionID,
00774 PVideoInputDevice * inputDevice,
00775 PVideoOutputDevice * outputDevice,
00776 bool autoDelete = true
00777 );
00778
00781 ~OpalVideoMediaStream();
00783
00791 virtual PBoolean Open();
00792
00797 virtual PBoolean Close();
00798
00804 virtual PBoolean ReadData(
00805 BYTE * data,
00806 PINDEX size,
00807 PINDEX & length
00808 );
00809
00815 virtual PBoolean WriteData(
00816 const BYTE * data,
00817 PINDEX length,
00818 PINDEX & written
00819 );
00820
00824 virtual PBoolean IsSynchronous() const;
00825
00828 virtual PBoolean SetDataSize(
00829 PINDEX dataSize,
00830 PINDEX frameTime
00831 );
00832
00835 virtual PVideoInputDevice * GetVideoInputDevice() const {
00836 return inputDevice;
00837 }
00838
00841 virtual PVideoOutputDevice * GetVideoOutputDevice() const {
00842 return outputDevice;
00843 }
00844
00846
00847 protected:
00848 PVideoInputDevice * inputDevice;
00849 PVideoOutputDevice * outputDevice;
00850 bool autoDelete;
00851 PTimeInterval lastGrabTime;
00852 };
00853
00854 #endif // OPAL_VIDEO
00855
00856 class OpalTransportUDP;
00857
00860 class OpalUDPMediaStream : public OpalMediaStream
00861 {
00862 PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
00863 public:
00868 OpalUDPMediaStream(
00869 OpalConnection & conn,
00870 const OpalMediaFormat & mediaFormat,
00871 unsigned sessionID,
00872 bool isSource,
00873 OpalTransportUDP & transport
00874 );
00876
00877 ~OpalUDPMediaStream();
00878
00881
00885 virtual PBoolean ReadPacket(
00886 RTP_DataFrame & packet
00887 );
00888
00892 virtual PBoolean WritePacket(
00893 RTP_DataFrame & packet
00894 );
00895
00899 virtual PBoolean IsSynchronous() const;
00900
00904 virtual PBoolean Close();
00905
00907
00908 private:
00909 OpalTransportUDP & udpTransport;
00910 };
00911
00912
00913 #endif //OPAL_OPAL_MEDIASTRM_H
00914
00915
00916