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_PATCH_H
00033 #define OPAL_OPAL_PATCH_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039 #include <opal/buildopts.h>
00040
00041 #include <opal/mediastrm.h>
00042 #include <opal/mediacmd.h>
00043 #include <codec/ratectl.h>
00044
00045 #include <list>
00046
00047 class OpalTranscoder;
00048
00060 class OpalMediaPatch : public PObject
00061 {
00062 PCLASSINFO(OpalMediaPatch, PObject);
00063 public:
00069 OpalMediaPatch(
00070 OpalMediaStream & source
00071 );
00072
00075 ~OpalMediaPatch();
00077
00084 void PrintOn(
00085 ostream & strm
00086 ) const;
00088
00094 virtual void Start();
00095
00104 virtual bool OnStartMediaPatch();
00105
00111 virtual void Close();
00112
00117 PBoolean AddSink(
00118 const OpalMediaStreamPtr & stream
00119 );
00120
00125 void RemoveSink(
00126 const OpalMediaStreamPtr & stream
00127 );
00128
00131 OpalMediaStream & GetSource() const { return source; }
00132
00135 OpalMediaStreamPtr GetSink(PINDEX i = 0) const;
00136
00139 OpalMediaFormat GetSinkFormat(PINDEX i = 0) const;
00140
00145 void AddFilter(
00146 const PNotifier & filter,
00147 const OpalMediaFormat & stage = OpalMediaFormat()
00148 );
00149
00152 bool RemoveFilter(
00153 const PNotifier & filter,
00154 const OpalMediaFormat & stage = OpalMediaFormat()
00155 );
00156
00159 virtual void FilterFrame(
00160 RTP_DataFrame & frame,
00161 const OpalMediaFormat & mediaFormat
00162 );
00163
00173 virtual bool UpdateMediaFormat(
00174 const OpalMediaFormat & mediaFormat
00175 );
00176
00184 virtual PBoolean ExecuteCommand(
00185 const OpalMediaCommand & command,
00186 PBoolean fromSink
00187 );
00188
00196 virtual void SetCommandNotifier(
00197 const PNotifier & notifier,
00198 PBoolean fromSink
00199 );
00200
00203 virtual void SetPaused(
00204 bool pause
00205 );
00206
00209 virtual PBoolean PushFrame(
00210 RTP_DataFrame & frame
00211 );
00212
00232 bool SetBypassPatch(
00233 OpalMediaPatch * patch
00234 );
00235
00238 virtual OpalTranscoder * GetAndLockSinkTranscoder(PINDEX i = 0) const;
00239 virtual void UnLockSinkTranscoder() const;
00240
00241 #if OPAL_STATISTICS
00242 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromSink) const;
00243 #endif
00244
00245
00246 protected:
00247
00249 virtual void Main();
00250 bool DispatchFrame(RTP_DataFrame & frame);
00251 bool EnableJitterBuffer();
00252
00253 OpalMediaStream & source;
00254
00255 class Sink : public PObject {
00256 PCLASSINFO(Sink, PObject);
00257 public:
00258 Sink(OpalMediaPatch & p, const OpalMediaStreamPtr & s);
00259 ~Sink();
00260 bool UpdateMediaFormat(const OpalMediaFormat & mediaFormat);
00261 bool ExecuteCommand(const OpalMediaCommand & command);
00262 void SetCommandNotifier(const PNotifier & notifier);
00263 bool WriteFrame(RTP_DataFrame & sourceFrame);
00264 #if OPAL_STATISTICS
00265 void GetStatistics(OpalMediaStatistics & statistics, bool fromSource) const;
00266 #endif
00267
00268 OpalMediaPatch & patch;
00269 OpalMediaStreamPtr stream;
00270 OpalTranscoder * primaryCodec;
00271 OpalTranscoder * secondaryCodec;
00272 RTP_DataFrameList intermediateFrames;
00273 RTP_DataFrameList finalFrames;
00274 bool writeSuccessful;
00275
00276 RTP_DataFrame::PayloadTypes m_lastPayloadType;
00277 unsigned m_consecutivePayloadTypeMismatches;
00278 bool CannotTranscodeFrame(OpalTranscoder & codec, RTP_DataFrame & frame);
00279
00280 #if OPAL_VIDEO
00281 void SetRateControlParameters(const OpalMediaFormat & mediaFormat);
00282 bool RateControlExceeded(bool & forceIFrame);
00283 OpalVideoRateController * rateController;
00284 #endif
00285 };
00286 PList<Sink> sinks;
00287
00288 class Filter : public PObject {
00289 PCLASSINFO(Filter, PObject);
00290 public:
00291 Filter(const PNotifier & n, const OpalMediaFormat & s) : notifier(n), stage(s) { }
00292 PNotifier notifier;
00293 OpalMediaFormat stage;
00294 };
00295 PList<Filter> filters;
00296
00297 #if OPAL_VIDEO
00298 bool m_videoDecoder;
00299 #endif
00300 bool m_bypassActive;
00301 OpalMediaPatch * m_bypassToPatch;
00302 OpalMediaPatch * m_bypassFromPatch;
00303 PSyncPoint m_bypassEnded;
00304
00305 class Thread : public PThread {
00306 PCLASSINFO(Thread, PThread);
00307 public:
00308 Thread(OpalMediaPatch & p);
00309 virtual void Main() { patch.Main(); };
00310 OpalMediaPatch & patch;
00311 };
00312
00313 Thread * patchThread;
00314 PMutex patchThreadMutex;
00315 mutable PReadWriteMutex inUse;
00316
00317 private:
00318 P_REMOVE_VIRTUAL(bool, OnPatchStart(), false);
00319 };
00320
00328 class OpalPassiveMediaPatch : public OpalMediaPatch
00329 {
00330 PCLASSINFO(OpalPassiveMediaPatch, OpalMediaPatch);
00331 public:
00332
00333 OpalPassiveMediaPatch(
00334 OpalMediaStream & source
00335 );
00336
00337 virtual void Start();
00338 };
00339
00340
00341 #endif // OPAL_OPAL_PATCH_H
00342
00343
00344