# mediastrm.h

Go to the documentation of this file.

    00001 /*
    00002  * mediastrm.h
    00003  *
    00004  * Media Stream classes
    00005  *
    00006  * Open Phone Abstraction Library (OPAL)
    00007  * Formally known as the Open H323 project.
    00008  *
    00009  * Copyright (c) 2001 Equivalence Pty. Ltd.
    00010  *
    00011  * The contents of this file are subject to the Mozilla Public License
    00012  * Version 1.0 (the "License"); you may not use this file except in
    00013  * compliance with the License. You may obtain a copy of the License at
    00014  * http://www.mozilla.org/MPL/
    00015  *
    00016  * Software distributed under the License is distributed on an "AS IS"
    00017  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00018  * the License for the specific language governing rights and limitations
    00019  * under the License.
    00020  *
    00021  * The Original Code is Open Phone Abstraction Library.
    00022  *
    00023  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
    00024  *
    00025  * Contributor(s): ______________________________________.
    00026  *
    00027  * $Revision: 29330 $
    00028  * $Author: rjongbloed $
    00029  * $Date: 2013-03-26 19:55:21 -0500 (Tue, 26 Mar 2013) $
    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 <rtp/jitter.h>
    00046 #include <ptlib/safecoll.h>
    00047 #include <ptclib/guid.h>
    00048
    00049
    00050 class OpalRTPSession;
    00051 class OpalMediaPatch;
    00052 class OpalLine;
    00053 class OpalConnection;
    00054 class OpalRTPConnection;
    00055 class OpalMediaStatistics;
    00056
    00057
    00058 typedef PSafePtr<OpalMediaPatch, PSafePtrMultiThreaded> OpalMediaPatchPtr;
    00059
    00060
    00116 class OpalMediaStream : public PSafeObject
    00117 {
    00118     PCLASSINFO(OpalMediaStream, PSafeObject);
    00119   protected:
    00124     OpalMediaStream(
    00125       OpalConnection & conn,
    00126       const OpalMediaFormat & mediaFormat,
    00127       unsigned sessionID,
    00128       bool isSource
    00129     );
    00130
    00131   public:
    00135     ~OpalMediaStream();
    00137
    00138   public:
    00145     void PrintOn(
    00146       ostream & strm
    00147     ) const;
    00149
    00159     virtual OpalMediaFormat GetMediaFormat() const;
    00160
    00167     virtual bool SetMediaFormat(
    00168       const OpalMediaFormat & mediaFormat
    00169     );
    00170
    00180     bool UpdateMediaFormat(
    00181       const OpalMediaFormat & mediaFormat
    00182     );
    00183
    00192     virtual PBoolean ExecuteCommand(
    00193       const OpalMediaCommand & command
    00194     );
    00195
    00200     virtual PBoolean Open();
    00201
    00204     virtual bool IsOpen() const;
    00205
    00211     virtual PBoolean Start();
    00212
    00218     virtual PBoolean Close();
    00219
    00223     virtual void OnStartMediaPatch();
    00224
    00228     virtual void OnStopMediaPatch(
    00229       OpalMediaPatch & patch
    00230     );
    00231
    00236     virtual PBoolean WritePackets(
    00237       RTP_DataFrameList & packets
    00238     );
    00239
    00245     virtual PBoolean ReadPacket(
    00246       RTP_DataFrame & packet
    00247     );
    00248
    00254     virtual PBoolean WritePacket(
    00255       RTP_DataFrame & packet
    00256     );
    00257
    00263     virtual PBoolean ReadData(
    00264       BYTE * data,
    00265       PINDEX size,
    00266       PINDEX & length
    00267     );
    00268
    00274     virtual PBoolean WriteData(
    00275       const BYTE * data,
    00276       PINDEX length,
    00277       PINDEX & written
    00278     );
    00279
    00282     bool PushPacket(
    00283       RTP_DataFrame & packet
    00284     );
    00285
    00291     virtual PBoolean SetDataSize(
    00292       PINDEX dataSize,
    00293       PINDEX frameTime
    00294     );
    00295
    00299     PINDEX GetDataSize() const { return defaultDataSize; }
    00300
    00307     virtual PBoolean IsSynchronous() const = 0;
    00308
    00318     virtual PBoolean RequiresPatchThread(
    00319       OpalMediaStream * stream
    00320     ) const;
    00321     virtual PBoolean RequiresPatchThread() const; // For backward compatibility
    00322
    00329     virtual bool EnableJitterBuffer(bool enab = true) const;
    00331
    00336     OpalConnection & GetConnection() const { return connection; }
    00337
    00340     bool IsSource() const { return m_isSource; }
    00341
    00344     bool IsSink() const { return !m_isSource; }
    00345
    00348     unsigned GetSessionID() const { return sessionID; }
    00349
    00352     void SetSessionID(unsigned id) { sessionID = id; }
    00353
    00357     PString GetID() const { return identifier; }
    00358
    00361     unsigned GetTimestamp() const { return timestamp; }
    00362
    00365     void SetTimestamp(unsigned ts) { timestamp = ts; }
    00366
    00369     bool GetMarker() const { return marker; }
    00370
    00373     void SetMarker(bool m) { marker = m; }
    00374
    00377     bool IsPaused() const { return m_paused; }
    00378
    00383     virtual bool SetPaused(
    00384       bool pause,
    00385       bool fromPatch = false
    00386     );
    00387
    00390     virtual PBoolean SetPatch(
    00391       OpalMediaPatch * patch
    00392     );
    00393
    00396     OpalMediaPatchPtr GetPatch() const { return m_mediaPatch; }
    00397
    00400     void AddFilter(
    00401       const PNotifier & filter,
    00402       const OpalMediaFormat & stage = OpalMediaFormat()
    00403     ) const;
    00404
    00407     bool RemoveFilter(
    00408       const PNotifier & filter,
    00409       const OpalMediaFormat & stage = OpalMediaFormat()
    00410     ) const;
    00411
    00412 #if OPAL_STATISTICS
    00413     virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
    00414 #endif
    00415
    00416
    00417     virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & mediaFormat);
    00418
    00419   protected:
    00420     void IncrementTimestamp(PINDEX size);
    00421     bool InternalWriteData(const BYTE * data, PINDEX length, PINDEX & written);
    00422     OpalMediaPatchPtr InternalSetPatchPart1(OpalMediaPatch * newPatch);
    00423     void InternalSetPatchPart2(const OpalMediaPatchPtr & oldPatch);
    00424     virtual bool InternalSetJitterBuffer(const OpalJitterBuffer::Init & init) const;
    00425
    00431     virtual void InternalClose() = 0;
    00432
    00433     OpalConnection & connection;
    00434     unsigned         sessionID;
    00435     PString          identifier;
    00436     OpalMediaFormat  mediaFormat;
    00437     bool             m_paused;
    00438     bool             m_isSource;
    00439     bool             m_isOpen;
    00440     PINDEX           defaultDataSize;
    00441     unsigned         timestamp;
    00442     bool             marker;
    00443
    00444     OpalMediaPatchPtr m_mediaPatch;
    00445
    00446     RTP_DataFrame::PayloadTypes m_payloadType;
    00447     unsigned                    m_frameTime;
    00448     PINDEX                      m_frameSize;
    00449
    00450     typedef OpalMediaPatchPtr PatchPtr; // For backward compatibility
    00451
    00452   private:
    00453     P_REMOVE_VIRTUAL_VOID(OnPatchStart());
    00454     P_REMOVE_VIRTUAL_VOID(OnPatchStop());
    00455     P_REMOVE_VIRTUAL_VOID(OnStopMediaPatch());
    00456     P_REMOVE_VIRTUAL_VOID(RemovePatch(OpalMediaPatch *));
    00457
    00458   friend class OpalMediaPatch;
    00459 };
    00460
    00461 typedef PSafePtr<OpalMediaStream> OpalMediaStreamPtr;
    00462
    00463
    00466 class OpalMediaStreamPacing
    00467 {
    00468   public:
    00469     OpalMediaStreamPacing(
    00470       const OpalMediaFormat & mediaFormat
    00471     );
    00472
    00474     void Pace(
    00475       bool reading,
    00476       PINDEX bytes,
    00477       bool & marker
    00478     );
    00479
    00480     bool UpdateMediaFormat(
    00481       const OpalMediaFormat & mediaFormat
    00482     );
    00483
    00484   protected:
    00485     bool           m_timeOnMarkers;
    00486     unsigned       m_frameTime;
    00487     PINDEX         m_frameSize;
    00488     unsigned       m_timeUnits;
    00489     PAdaptiveDelay m_delay;
    00490 };
    00491
    00492
    00495 class OpalNullMediaStream : public OpalMediaStream, public OpalMediaStreamPacing
    00496 {
    00497     PCLASSINFO(OpalNullMediaStream, OpalMediaStream);
    00498   public:
    00503     OpalNullMediaStream(
    00504       OpalConnection & conn,
    00505       const OpalMediaFormat & mediaFormat,
    00506       unsigned sessionID,
    00507       bool isSource,
    00508       bool isSynchronous = false
    00509     );
    00510     OpalNullMediaStream(
    00511       OpalConnection & conn,
    00512       const OpalMediaFormat & mediaFormat,
    00513       unsigned sessionID,
    00514       bool isSource,
    00515       bool usePacingDelay,
    00516       bool requiresPatchThread
    00517     );
    00519
    00525     virtual PBoolean ReadData(
    00526       BYTE * data,
    00527       PINDEX size,
    00528       PINDEX & length
    00529     );
    00530
    00534     virtual PBoolean WriteData(
    00535       const BYTE * data,
    00536       PINDEX length,
    00537       PINDEX & written
    00538     );
    00539
    00544     virtual bool SetPaused(
    00545       bool pause,
    00546       bool fromPatch = false
    00547     );
    00548
    00552     virtual PBoolean RequiresPatchThread() const;
    00553
    00557     virtual PBoolean IsSynchronous() const;
    00559
    00560   protected:
    00561     virtual void InternalClose() { }
    00562     virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & newMediaFormat);
    00563
    00564     bool m_isSynchronous;
    00565     bool m_requiresPatchThread;
    00566 };
    00567
    00568
    00572 class OpalRTPMediaStream : public OpalMediaStream
    00573 {
    00574     PCLASSINFO(OpalRTPMediaStream, OpalMediaStream);
    00575   public:
    00581     OpalRTPMediaStream(
    00582       OpalRTPConnection & conn,
    00583       const OpalMediaFormat & mediaFormat,
    00584       bool isSource,
    00585       OpalRTPSession & rtpSession
    00586     );
    00587
    00591     ~OpalRTPMediaStream();
    00593
    00600     virtual PBoolean Open();
    00601
    00604     virtual bool IsOpen() const;
    00605
    00609     virtual bool SetPaused(
    00610       bool pause,
    00611       bool fromPatch = false
    00612     );
    00613
    00617     virtual PBoolean ReadPacket(
    00618       RTP_DataFrame & packet
    00619     );
    00620
    00624     virtual PBoolean WritePacket(
    00625       RTP_DataFrame & packet
    00626     );
    00627
    00630     virtual PBoolean SetDataSize(
    00631       PINDEX dataSize,
    00632       PINDEX frameTime
    00633     );
    00634
    00638     virtual PBoolean IsSynchronous() const;
    00639
    00647     virtual PBoolean RequiresPatchThread() const;
    00648
    00651     virtual PBoolean SetPatch(
    00652       OpalMediaPatch * patch
    00653     );
    00654
    00657     virtual OpalRTPSession & GetRtpSession() const
    00658     { return rtpSession; }
    00659
    00660 #if OPAL_STATISTICS
    00661     virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
    00662 #endif
    00663
    00664
    00665   protected:
    00666     virtual void InternalClose();
    00667     virtual bool InternalSetJitterBuffer(const OpalJitterBuffer::Init & init) const;
    00668
    00669     OpalRTPSession & rtpSession;
    00670 #if OPAL_VIDEO
    00671     bool             m_forceIntraFrameFlag;
    00672     PSimpleTimer     m_forceIntraFrameTimer;
    00673 #endif
    00674 };
    00675
    00676
    00677
    00680 class OpalRawMediaStream : public OpalMediaStream
    00681 {
    00682     PCLASSINFO(OpalRawMediaStream, OpalMediaStream);
    00683   protected:
    00688     OpalRawMediaStream(
    00689       OpalConnection & conn,
    00690       const OpalMediaFormat & mediaFormat,
    00691       unsigned sessionID,
    00692       bool isSource,
    00693       PChannel * channel,
    00694       bool autoDelete
    00695     );
    00696
    00699     ~OpalRawMediaStream();
    00701
    00702   public:
    00708     virtual PBoolean ReadData(
    00709       BYTE * data,
    00710       PINDEX size,
    00711       PINDEX & length
    00712     );
    00713
    00717     virtual PBoolean WriteData(
    00718       const BYTE * data,
    00719       PINDEX length,
    00720       PINDEX & written
    00721     );
    00722
    00725     PChannel * GetChannel() { return m_channel; }
    00726
    00729     bool SetChannel(
    00730       PChannel * channel,
    00731       bool autoDelete = true
    00732     );
    00733
    00736     virtual unsigned GetAverageSignalLevel();
    00738
    00739   protected:
    00740     virtual void InternalClose();
    00741
    00742     PChannel * m_channel;
    00743     bool       m_autoDelete;
    00744     PMutex     m_channelMutex;
    00745
    00746     PBYTEArray m_silence;
    00747
    00748     PUInt64    m_averageSignalSum;
    00749     unsigned   m_averageSignalSamples;
    00750     PMutex     m_averagingMutex;
    00751
    00752     void CollectAverage(const BYTE * buffer, PINDEX size);
    00753 };
    00754
    00755
    00756
    00759 class OpalFileMediaStream : public OpalRawMediaStream, public OpalMediaStreamPacing
    00760 {
    00761     PCLASSINFO(OpalFileMediaStream, OpalRawMediaStream);
    00762   public:
    00767     OpalFileMediaStream(
    00768       OpalConnection & conn,
    00769       const OpalMediaFormat & mediaFormat,
    00770       unsigned sessionID,
    00771       bool isSource,
    00772       PFile * file,
    00773       bool autoDelete = true
    00774     );
    00775
    00778     OpalFileMediaStream(
    00779       OpalConnection & conn,
    00780       const OpalMediaFormat & mediaFormat,
    00781       unsigned sessionID,
    00782       bool isSource,
    00783       const PFilePath & path
    00784     );
    00786
    00792     virtual PBoolean IsSynchronous() const;
    00793
    00794     virtual PBoolean ReadData(
    00795       BYTE * data,
    00796       PINDEX size,
    00797       PINDEX & length
    00798     );
    00799
    00803     virtual PBoolean WriteData(
    00804       const BYTE * data,
    00805       PINDEX length,
    00806       PINDEX & written
    00807     );
    00809
    00810   protected:
    00811     PFile file;
    00812 };
    00813
    00814
    00815 #if OPAL_PTLIB_AUDIO
    00816
    00820 class PSoundChannel;
    00821
    00822 class OpalAudioMediaStream : public OpalRawMediaStream
    00823 {
    00824     PCLASSINFO(OpalAudioMediaStream, OpalRawMediaStream);
    00825   public:
    00830     OpalAudioMediaStream(
    00831       OpalConnection & conn,
    00832       const OpalMediaFormat & mediaFormat,
    00833       unsigned sessionID,
    00834       bool isSource,
    00835       PINDEX buffers,
    00836       unsigned bufferTime,
    00837       PSoundChannel * channel,
    00838       bool autoDelete = true
    00839     );
    00840
    00843     OpalAudioMediaStream(
    00844       OpalConnection & conn,
    00845       const OpalMediaFormat & mediaFormat,
    00846       unsigned sessionID,
    00847       bool isSource,
    00848       PINDEX buffers,
    00849       unsigned bufferTime,
    00850       const PString & deviceName
    00851     );
    00853
    00861     virtual PBoolean SetDataSize(
    00862       PINDEX dataSize,
    00863       PINDEX frameTime
    00864     );
    00865
    00869     virtual PBoolean IsSynchronous() const;
    00871
    00872   protected:
    00873     PINDEX   m_soundChannelBuffers;
    00874     unsigned m_soundChannelBufferTime;
    00875 };
    00876
    00877 #endif // OPAL_PTLIB_AUDIO
    00878
    00879 #if OPAL_VIDEO
    00880
    00884 class PVideoInputDevice;
    00885 class PVideoOutputDevice;
    00886
    00887 class OpalVideoMediaStream : public OpalMediaStream
    00888 {
    00889     PCLASSINFO(OpalVideoMediaStream, OpalMediaStream);
    00890   public:
    00895     OpalVideoMediaStream(
    00896       OpalConnection & conn,
    00897       const OpalMediaFormat & mediaFormat,
    00898       unsigned sessionID,
    00899       PVideoInputDevice * inputDevice,
    00900       PVideoOutputDevice * outputDevice,
    00901       bool autoDeleteInput = true,
    00902       bool autoDeleteOutput = true
    00903     );
    00904
    00907     ~OpalVideoMediaStream();
    00909
    00917     virtual PBoolean Open();
    00918
    00926     virtual PBoolean ExecuteCommand(
    00927       const OpalMediaCommand & command
    00928     );
    00929
    00935     virtual PBoolean ReadData(
    00936       BYTE * data,
    00937       PINDEX size,
    00938       PINDEX & length
    00939     );
    00940
    00946     virtual PBoolean WriteData(
    00947       const BYTE * data,
    00948       PINDEX length,
    00949       PINDEX & written
    00950     );
    00951
    00955     virtual PBoolean IsSynchronous() const;
    00956
    00959     virtual PBoolean SetDataSize(
    00960       PINDEX dataSize,
    00961       PINDEX frameTime
    00962     );
    00963
    00966     virtual void SetVideoInputDevice(
    00967       PVideoInputDevice * device,
    00968       bool autoDelete = true
    00969     );
    00970
    00973     virtual PVideoInputDevice * GetVideoInputDevice() const
    00974     {
    00975       return m_inputDevice;
    00976     }
    00977
    00980     virtual void SetVideoOutputDevice(
    00981       PVideoOutputDevice * device,
    00982       bool autoDelete = true
    00983     );
    00984
    00987     virtual PVideoOutputDevice * GetVideoOutputDevice() const
    00988     {
    00989       return m_outputDevice;
    00990     }
    00991
    00993
    00994   protected:
    00995     virtual void InternalClose();
    00996     virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & newMediaFormat);
    00997     bool InternalAdjustDevices();
    00998
    00999     PVideoInputDevice  * m_inputDevice;
    01000     PVideoOutputDevice * m_outputDevice;
    01001     bool                 m_autoDeleteInput;
    01002     bool                 m_autoDeleteOutput;
    01003     PTimeInterval        m_lastGrabTime;
    01004     bool                 m_needKeyFrame;
    01005     PMutex               m_devicesMutex;
    01006 };
    01007
    01008 #endif // OPAL_VIDEO
    01009
    01010 class OpalTransportUDP;
    01011
    01014 class OpalUDPMediaStream : public OpalMediaStream
    01015 {
    01016     PCLASSINFO(OpalUDPMediaStream, OpalMediaStream);
    01017   public:
    01022     OpalUDPMediaStream(
    01023       OpalConnection & conn,
    01024       const OpalMediaFormat & mediaFormat,
    01025       unsigned sessionID,
    01026       bool isSource,
    01027       OpalTransportUDP & transport
    01028     );
    01030
    01031     ~OpalUDPMediaStream();
    01032
    01035
    01039     virtual PBoolean ReadPacket(
    01040       RTP_DataFrame & packet
    01041     );
    01042
    01046     virtual PBoolean WritePacket(
    01047       RTP_DataFrame & packet
    01048     );
    01049
    01053     virtual PBoolean IsSynchronous() const;
    01055
    01056   private:
    01057     virtual void InternalClose();
    01058
    01059     OpalTransportUDP & udpTransport;
    01060 };
    01061
    01062
    01063 #endif //OPAL_OPAL_MEDIASTRM_H
    01064
    01065
    01066 // End of File ///////////////////////////////////////////////////////////////