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 PSafeObject
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
00186 virtual PBoolean ExecuteCommand(
00187 const OpalMediaCommand & command,
00188 PBoolean fromSink
00189 );
00190
00193 virtual bool SetPaused(
00194 bool pause
00195 );
00196
00199 virtual PBoolean PushFrame(
00200 RTP_DataFrame & frame
00201 );
00202
00222 bool SetBypassPatch(
00223 OpalMediaPatch * patch
00224 );
00225
00228 virtual OpalTranscoder * GetAndLockSinkTranscoder(PINDEX i = 0) const;
00229 virtual void UnLockSinkTranscoder() const;
00230
00231 #if OPAL_STATISTICS
00232 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromSink) const;
00233 #endif
00234
00235
00236 PDECLARE_NOTIFIER(OpalMediaCommand, OpalMediaPatch, OnMediaCommand);
00237
00238 protected:
00239
00241 virtual void Main();
00242 void StopThread();
00243 bool DispatchFrame(RTP_DataFrame & frame);
00244 bool EnableJitterBuffer();
00245
00246 OpalMediaStream & source;
00247
00248 class Sink : public PObject {
00249 PCLASSINFO(Sink, PObject);
00250 public:
00251 Sink(OpalMediaPatch & p, const OpalMediaStreamPtr & s);
00252 ~Sink();
00253 bool UpdateMediaFormat(const OpalMediaFormat & mediaFormat);
00254 bool ExecuteCommand(const OpalMediaCommand & command);
00255 bool WriteFrame(RTP_DataFrame & sourceFrame);
00256 #if OPAL_STATISTICS
00257 void GetStatistics(OpalMediaStatistics & statistics, bool fromSource) const;
00258 #endif
00259
00260 OpalMediaPatch & patch;
00261 OpalMediaStreamPtr stream;
00262 OpalTranscoder * primaryCodec;
00263 OpalTranscoder * secondaryCodec;
00264 RTP_DataFrameList intermediateFrames;
00265 RTP_DataFrameList finalFrames;
00266 bool writeSuccessful;
00267
00268 RTP_DataFrame::PayloadTypes m_lastPayloadType;
00269 unsigned m_consecutivePayloadTypeMismatches;
00270 bool CannotTranscodeFrame(OpalTranscoder & codec, RTP_DataFrame & frame);
00271
00272 #if OPAL_VIDEO
00273 void SetRateControlParameters(const OpalMediaFormat & mediaFormat);
00274 bool RateControlExceeded(bool & forceIFrame);
00275 OpalVideoRateController * rateController;
00276 #endif
00277 };
00278 PList<Sink> sinks;
00279
00280 class Filter : public PObject {
00281 PCLASSINFO(Filter, PObject);
00282 public:
00283 Filter(const PNotifier & n, const OpalMediaFormat & s) : notifier(n), stage(s) { }
00284 PNotifier notifier;
00285 OpalMediaFormat stage;
00286 };
00287 PList<Filter> filters;
00288
00289 OpalMediaPatch * m_bypassToPatch;
00290 OpalMediaPatch * m_bypassFromPatch;
00291 PSyncPoint m_bypassEnded;
00292
00293 class Thread : public PThread {
00294 PCLASSINFO(Thread, PThread);
00295 public:
00296 Thread(OpalMediaPatch & p);
00297 virtual void Main() { patch.Main(); };
00298 OpalMediaPatch & patch;
00299 };
00300
00301 Thread * patchThread;
00302 PMutex patchThreadMutex;
00303
00304 private:
00305 P_REMOVE_VIRTUAL(bool, OnPatchStart(), false);
00306 };
00307
00315 class OpalPassiveMediaPatch : public OpalMediaPatch
00316 {
00317 PCLASSINFO(OpalPassiveMediaPatch, OpalMediaPatch);
00318 public:
00319
00320 OpalPassiveMediaPatch(
00321 OpalMediaStream & source
00322 );
00323
00324 virtual void Start();
00325
00326 protected:
00327 bool m_started;
00328 };
00329
00330
00331 #endif // OPAL_OPAL_PATCH_H
00332
00333
00334