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_PATCH_H
00033 #define __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
00044 #include <list>
00045
00046
00047 class OpalTranscoder;
00048
00049
00061 class OpalMediaPatch : public PObject
00062 {
00063 PCLASSINFO(OpalMediaPatch, PObject);
00064 public:
00070 OpalMediaPatch(
00071 OpalMediaStream & source
00072 );
00073
00076 ~OpalMediaPatch();
00078
00085 void PrintOn(
00086 ostream & strm
00087 ) const;
00089
00095 virtual void Start();
00096
00102 virtual void Close();
00103
00108 PBoolean AddSink(
00109 const OpalMediaStreamPtr & stream
00110 );
00111
00116 void RemoveSink(
00117 const OpalMediaStreamPtr & stream
00118 );
00119
00122 OpalMediaStream & GetSource() const { return source; }
00123
00126 OpalMediaStreamPtr GetSink(PINDEX i = 0) const;
00127
00130 OpalMediaFormat GetSinkFormat(PINDEX i = 0) const;
00131
00136 void AddFilter(
00137 const PNotifier & filter,
00138 const OpalMediaFormat & stage = OpalMediaFormat()
00139 );
00140
00143 PBoolean RemoveFilter(
00144 const PNotifier & filter,
00145 const OpalMediaFormat & stage = OpalMediaFormat()
00146 );
00147
00150 virtual void FilterFrame(
00151 RTP_DataFrame & frame,
00152 const OpalMediaFormat & mediaFormat
00153 );
00154
00164 virtual PBoolean UpdateMediaFormat(
00165 const OpalMediaFormat & mediaFormat,
00166 PBoolean fromSink
00167 );
00168
00176 virtual PBoolean ExecuteCommand(
00177 const OpalMediaCommand & command,
00178 PBoolean fromSink
00179 );
00180
00188 virtual void SetCommandNotifier(
00189 const PNotifier & notifier,
00190 PBoolean fromSink
00191 );
00192
00193 virtual PBoolean PushFrame(RTP_DataFrame & ) { return PFalse; };
00194
00197 virtual OpalTranscoder * GetAndLockSinkTranscoder(PINDEX i = 0) const;
00198 virtual void UnLockSinkTranscoder() const;
00199
00200 #ifdef OPAL_STATISTICS
00201 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00202 #endif
00203
00204
00205 protected:
00206
00208 virtual void Main();
00209 bool DispatchFrame(RTP_DataFrame & frame);
00210
00211 OpalMediaStream & source;
00212
00213 class Sink : public PObject {
00214 PCLASSINFO(Sink, PObject);
00215 public:
00216 Sink(OpalMediaPatch & p, const OpalMediaStreamPtr & s);
00217 ~Sink();
00218 bool UpdateMediaFormat(const OpalMediaFormat & mediaFormat);
00219 bool ExecuteCommand(const OpalMediaCommand & command);
00220 void SetCommandNotifier(const PNotifier & notifier);
00221 bool WriteFrame(RTP_DataFrame & sourceFrame);
00222 #ifdef OPAL_STATISTICS
00223 void GetStatistics(OpalMediaStatistics & statistics) const;
00224 #endif
00225
00226 OpalMediaPatch & patch;
00227 OpalMediaStreamPtr stream;
00228 OpalTranscoder * primaryCodec;
00229 OpalTranscoder * secondaryCodec;
00230 RTP_DataFrameList intermediateFrames;
00231 RTP_DataFrameList finalFrames;
00232 bool writeSuccessful;
00233
00234 #if OPAL_VIDEO
00235 void SetRateControlParameters(const OpalMediaFormat & mediaFormat);
00236 bool RateControlExceeded(const PTimeInterval & currentTime);
00237
00238 bool rcEnabled;
00239 unsigned rcByteRate;
00240 unsigned rcWindowSize;
00241 unsigned rcMaxConsecutiveFramesSkip;
00242 unsigned rcConsecutiveFramesSkipped;
00243 PTimeInterval rcLastTime;
00244 PINDEX rcTotalSize;
00245
00246 struct FrameInfo {
00247 PTimeInterval time;
00248 PINDEX size;
00249 };
00250 std::list<FrameInfo> frameInfoList;
00251 #endif
00252 };
00253 PList<Sink> sinks;
00254
00255 class Filter : public PObject {
00256 PCLASSINFO(Filter, PObject);
00257 public:
00258 Filter(const PNotifier & n, const OpalMediaFormat & s) : notifier(n), stage(s) { }
00259 PNotifier notifier;
00260 OpalMediaFormat stage;
00261 };
00262 PList<Filter> filters;
00263
00264 class Thread : public PThread {
00265 PCLASSINFO(Thread, PThread);
00266 public:
00267 Thread(OpalMediaPatch & p);
00268 virtual void Main() { patch.Main(); };
00269 OpalMediaPatch & patch;
00270 };
00271
00272 Thread * patchThread;
00273 PMutex patchThreadMutex;
00274 mutable PReadWriteMutex inUse;
00275 };
00276
00284 class OpalPassiveMediaPatch : public OpalMediaPatch
00285 {
00286 PCLASSINFO(OpalPassiveMediaPatch, OpalMediaPatch);
00287 public:
00288
00289 OpalPassiveMediaPatch(
00290 OpalMediaStream & source
00291 );
00292
00293 virtual void Start();
00294 virtual PBoolean PushFrame(RTP_DataFrame & frame);
00295 };
00296
00297
00298 #endif // __OPAL_PATCH_H
00299
00300
00301