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 PBoolean 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
00252 OpalMediaStream & source;
00253
00254 class Sink : public PObject {
00255 PCLASSINFO(Sink, PObject);
00256 public:
00257 Sink(OpalMediaPatch & p, const OpalMediaStreamPtr & s);
00258 ~Sink();
00259 bool UpdateMediaFormat(const OpalMediaFormat & mediaFormat);
00260 bool ExecuteCommand(const OpalMediaCommand & command);
00261 void SetCommandNotifier(const PNotifier & notifier);
00262 bool WriteFrame(RTP_DataFrame & sourceFrame);
00263 #if OPAL_STATISTICS
00264 void GetStatistics(OpalMediaStatistics & statistics, bool fromSource) const;
00265 #endif
00266
00267 OpalMediaPatch & patch;
00268 OpalMediaStreamPtr stream;
00269 OpalTranscoder * primaryCodec;
00270 OpalTranscoder * secondaryCodec;
00271 RTP_DataFrameList intermediateFrames;
00272 RTP_DataFrameList finalFrames;
00273 bool writeSuccessful;
00274
00275 RTP_DataFrame::PayloadTypes m_lastPayloadType;
00276 unsigned m_consecutivePayloadTypeMismatches;
00277 bool CannotTranscodeFrame(OpalTranscoder & codec, RTP_DataFrame & frame);
00278
00279 #if OPAL_VIDEO
00280 void SetRateControlParameters(const OpalMediaFormat & mediaFormat);
00281 bool RateControlExceeded(bool & forceIFrame);
00282 OpalVideoRateController * rateController;
00283 #endif
00284 };
00285 PList<Sink> sinks;
00286
00287 class Filter : public PObject {
00288 PCLASSINFO(Filter, PObject);
00289 public:
00290 Filter(const PNotifier & n, const OpalMediaFormat & s) : notifier(n), stage(s) { }
00291 PNotifier notifier;
00292 OpalMediaFormat stage;
00293 };
00294 PList<Filter> filters;
00295
00296 #if OPAL_VIDEO
00297 bool m_videoDecoder;
00298 #endif
00299 bool m_bypassActive;
00300 OpalMediaPatch * m_bypassToPatch;
00301 OpalMediaPatch * m_bypassFromPatch;
00302 PSyncPoint m_bypassEnded;
00303
00304 class Thread : public PThread {
00305 PCLASSINFO(Thread, PThread);
00306 public:
00307 Thread(OpalMediaPatch & p);
00308 virtual void Main() { patch.Main(); };
00309 OpalMediaPatch & patch;
00310 };
00311
00312 Thread * patchThread;
00313 PMutex patchThreadMutex;
00314 mutable PReadWriteMutex inUse;
00315
00316 private:
00317 P_REMOVE_VIRTUAL(bool, OnPatchStart(), false);
00318 };
00319
00327 class OpalPassiveMediaPatch : public OpalMediaPatch
00328 {
00329 PCLASSINFO(OpalPassiveMediaPatch, OpalMediaPatch);
00330 public:
00331
00332 OpalPassiveMediaPatch(
00333 OpalMediaStream & source
00334 );
00335
00336 virtual void Start();
00337 };
00338
00339
00340 #endif // OPAL_OPAL_PATCH_H
00341
00342
00343