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