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 #ifndef OPAL_CODEC_OPALPLUGINMGR_H
00032 #define OPAL_CODEC_OPALPLUGINMGR_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #include <ptlib/object.h>
00039
00040 #include <opal/buildopts.h>
00041
00042 #include <ptlib/pluginmgr.h>
00043 #include <ptlib/pfactory.h>
00044 #include <codec/opalplugin.h>
00045 #include <opal/mediafmt.h>
00046 #include <opal/transcoders.h>
00047
00048 #if OPAL_H323
00049 #include <h323/h323caps.h>
00050 #endif
00051
00052 #if OPAL_VIDEO
00053 #include <codec/vidcodec.h>
00054 #endif
00055
00056
00058
00059 class H323Capability;
00060
00061 class H323StaticPluginCodec
00062 {
00063 public:
00064 virtual ~H323StaticPluginCodec() { }
00065 virtual PluginCodec_GetAPIVersionFunction Get_GetAPIFn() = 0;
00066 virtual PluginCodec_GetCodecFunction Get_GetCodecFn() = 0;
00067 };
00068
00069 typedef PFactory<H323StaticPluginCodec> H323StaticPluginCodecFactory;
00070
00071
00073
00074 class OpalPluginCodecManager;
00075
00076 PFACTORY_LOAD(OpalPluginCodecManager);
00077
00078 class OpalPluginCodecHandler : public PObject
00079 {
00080 PCLASSINFO(OpalPluginCodecHandler, PObject);
00081 public:
00082 OpalPluginCodecHandler();
00083
00084 static int GetChannelCount(const PluginCodec_Definition * codeDefn);
00085
00086 virtual OpalMediaFormatInternal * OnCreateAudioFormat(OpalPluginCodecManager & mgr,
00087 const PluginCodec_Definition * codecDefn,
00088 const char * fmtName,
00089 const char * rtpEncodingName,
00090 unsigned frameTime,
00091 unsigned timeUnits,
00092 time_t timeStamp);
00093
00094 #if OPAL_VIDEO
00095 virtual OpalMediaFormatInternal * OnCreateVideoFormat(OpalPluginCodecManager & mgr,
00096 const PluginCodec_Definition * codecDefn,
00097 const char * fmtName,
00098 const char * rtpEncodingName,
00099 time_t timeStamp);
00100 virtual void RegisterVideoTranscoder(const PString & src, const PString & dst, const PluginCodec_Definition * codec, bool v);
00101 #endif
00102
00103 #if OPAL_T38_CAPABILITY
00104 virtual OpalMediaFormatInternal * OnCreateFaxFormat(OpalPluginCodecManager & mgr,
00105 const PluginCodec_Definition * codecDefn,
00106 const char * fmtName,
00107 const char * rtpEncodingName,
00108 unsigned frameTime,
00109 unsigned timeUnits,
00110 time_t timeStamp);
00111 #endif
00112 };
00113
00114
00115 class OpalPluginCodecManager : public PPluginModuleManager
00116 {
00117 PCLASSINFO(OpalPluginCodecManager, PPluginModuleManager);
00118 public:
00119 OpalPluginCodecManager(PPluginManager * pluginMgr = NULL);
00120 ~OpalPluginCodecManager();
00121
00122 PFACTORY_GET_SINGLETON(PFactory<PPluginModuleManager>, OpalPluginCodecManager);
00123
00124 void RegisterStaticCodec(const H323StaticPluginCodecFactory::Key_T & name,
00125 PluginCodec_GetAPIVersionFunction getApiVerFn,
00126 PluginCodec_GetCodecFunction getCodecFn);
00127
00128 void OnLoadPlugin(PDynaLink & dll, INT code);
00129
00130 virtual void OnShutdown();
00131
00132 #if OPAL_H323
00133 H323Capability * CreateCapability(
00134 const PString & _mediaFormat,
00135 const PString & _baseName,
00136 unsigned maxFramesPerPacket,
00137 unsigned recommendedFramesPerPacket,
00138 unsigned _pluginSubType);
00139 #endif
00140
00141 protected:
00142
00143 PList<OpalMediaFormat> mediaFormatsOnHeap;
00144
00145 void RegisterCodecPlugins (unsigned int count, const PluginCodec_Definition * codecList, OpalPluginCodecHandler * handler);
00146 void UnregisterCodecPlugins(unsigned int count, const PluginCodec_Definition * codecList, OpalPluginCodecHandler * handler);
00147
00148 bool AddMediaFormat(OpalPluginCodecHandler * handler, const PTime & timeNow, const PluginCodec_Definition * codecDefn, const char * fmtName);
00149 #if OPAL_H323
00150 void RegisterCapability(const PluginCodec_Definition * codecDefn);
00151 #endif
00152 };
00153
00154
00156
00157 class OpalPluginControl
00158 {
00159 public:
00160 OpalPluginControl(const PluginCodec_Definition * def, const char * name);
00161
00162 bool Exists() const
00163 {
00164 return controlDef != NULL;
00165 }
00166
00167 int Call(void * parm, unsigned * parmLen, void * context = NULL) const
00168 {
00169 return controlDef != NULL ? (*controlDef->control)(codecDef, context, fnName, parm, parmLen) : -1;
00170 }
00171
00172 int Call(void * parm, unsigned parmLen, void * context = NULL) const
00173 {
00174 return Call(parm, &parmLen, context);
00175 }
00176
00177 const char * GetName() const { return fnName; }
00178
00179 protected:
00180 const PluginCodec_Definition * codecDef;
00181 const char * fnName;
00182 const PluginCodec_ControlDefn * controlDef;
00183 };
00184
00185
00187
00188 class OpalPluginMediaFormatInternal
00189 {
00190 public:
00191 OpalPluginMediaFormatInternal(const PluginCodec_Definition * defn);
00192
00193 bool AdjustOptions(OpalMediaFormatInternal & fmt, OpalPluginControl & control) const;
00194 void PopulateOptions(OpalMediaFormatInternal & format);
00195 void SetOldStyleOption(OpalMediaFormatInternal & format, const PString & _key, const PString & _val, const PString & type);
00196 bool IsValidForProtocol(const PString & _protocol) const;
00197
00198 const PluginCodec_Definition * codecDef;
00199 OpalPluginControl getOptionsControl;
00200 OpalPluginControl freeOptionsControl;
00201 OpalPluginControl validForProtocolControl;
00202 OpalPluginControl toNormalisedControl;
00203 OpalPluginControl toCustomisedControl;
00204 };
00205
00206
00207 class OpalPluginMediaFormat : public OpalMediaFormat
00208 {
00209 public:
00210 OpalPluginMediaFormat(OpalMediaFormatInternal * info)
00211 : OpalMediaFormat(info)
00212 {
00213 }
00214
00215 OpalPluginMediaFormatInternal * GetInfo() const { return dynamic_cast<OpalPluginMediaFormatInternal *>(m_info); }
00216 };
00217
00218
00219 class OpalPluginTranscoder
00220 {
00221 public:
00222 OpalPluginTranscoder(const PluginCodec_Definition * defn, bool isEnc);
00223 ~OpalPluginTranscoder();
00224
00225 bool UpdateOptions(const OpalMediaFormat & fmt);
00226 bool ExecuteCommand(const OpalMediaCommand & command);
00227 bool Transcode(const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned * flags) const
00228 {
00229 return codecDef != NULL && codecDef->codecFunction != NULL &&
00230 (codecDef->codecFunction)(codecDef, context, from, fromLen, to, toLen, flags) != 0;
00231 }
00232
00233 protected:
00234 const PluginCodec_Definition * codecDef;
00235 bool isEncoder;
00236 void * context;
00237
00238 OpalPluginControl setCodecOptions;
00239 OpalPluginControl getOutputDataSizeControl;
00240 };
00241
00242
00244
00245 class OpalPluginAudioFormatInternal : public OpalAudioFormatInternal, public OpalPluginMediaFormatInternal
00246 {
00247 public:
00248 friend class OpalPluginCodecManager;
00249
00250 OpalPluginAudioFormatInternal(
00251 const PluginCodec_Definition * codecDefn,
00252 const char * fmtName,
00253 const char * rtpEncodingName,
00254 unsigned frameTime,
00255 unsigned timeUnits,
00256 time_t timeStamp
00257 );
00258 virtual PObject * Clone() const;
00259 virtual bool IsValidForProtocol(const PString & protocol) const;
00260 virtual bool ToNormalisedOptions();
00261 virtual bool ToCustomisedOptions();
00262 };
00263
00264
00265 class OpalPluginFramedAudioTranscoder : public OpalFramedTranscoder, public OpalPluginTranscoder
00266 {
00267 PCLASSINFO(OpalPluginFramedAudioTranscoder, OpalFramedTranscoder);
00268 public:
00269 OpalPluginFramedAudioTranscoder(const PluginCodec_Definition * codecDefn, bool isEncoder);
00270 bool UpdateMediaFormats(const OpalMediaFormat & input, const OpalMediaFormat & output);
00271 PBoolean ExecuteCommand(const OpalMediaCommand & command);
00272 PBoolean ConvertFrame(const BYTE * input, PINDEX & consumed, BYTE * output, PINDEX & created);
00273 virtual PBoolean ConvertSilentFrame(BYTE * buffer);
00274 virtual bool AcceptComfortNoise() const { return comfortNoise; }
00275 protected:
00276 bool comfortNoise;
00277 };
00278
00279
00280 class OpalPluginStreamedAudioTranscoder : public OpalStreamedTranscoder, public OpalPluginTranscoder
00281 {
00282 PCLASSINFO(OpalPluginStreamedAudioTranscoder, OpalStreamedTranscoder);
00283 public:
00284 OpalPluginStreamedAudioTranscoder(const PluginCodec_Definition * codec, bool isEncoder);
00285 bool UpdateMediaFormats(const OpalMediaFormat & input, const OpalMediaFormat & output);
00286 PBoolean ExecuteCommand(const OpalMediaCommand & command);
00287 virtual bool AcceptComfortNoise() const { return comfortNoise; }
00288 virtual int ConvertOne(int from) const;
00289 protected:
00290 bool comfortNoise;
00291 };
00292
00293
00295
00296 #if OPAL_VIDEO
00297
00298 class OpalPluginVideoFormatInternal : public OpalVideoFormatInternal, public OpalPluginMediaFormatInternal
00299 {
00300 public:
00301 OpalPluginVideoFormatInternal(
00302 const PluginCodec_Definition * codec,
00303 const char * fmtName,
00304 const char * rtpEncodingName,
00305 time_t timeStamp
00306 );
00307 virtual PObject * Clone() const;
00308 virtual bool IsValidForProtocol(const PString & protocol) const;
00309 virtual bool ToNormalisedOptions();
00310 virtual bool ToCustomisedOptions();
00311 };
00312
00313
00314 class OpalPluginVideoTranscoder : public OpalVideoTranscoder, public OpalPluginTranscoder
00315 {
00316 PCLASSINFO(OpalPluginVideoTranscoder, OpalVideoTranscoder);
00317 public:
00318 OpalPluginVideoTranscoder(const PluginCodec_Definition * codec, bool isEncoder);
00319 ~OpalPluginVideoTranscoder();
00320
00321 PBoolean ConvertFrames(const RTP_DataFrame & src, RTP_DataFrameList & dstList);
00322 bool UpdateMediaFormats(const OpalMediaFormat & input, const OpalMediaFormat & output);
00323 PBoolean ExecuteCommand(const OpalMediaCommand & command);
00324
00325 protected:
00326 bool EncodeFrames(const RTP_DataFrame & src, RTP_DataFrameList & dstList);
00327 bool DecodeFrames(const RTP_DataFrame & src, RTP_DataFrameList & dstList);
00328 bool DecodeFrame(const RTP_DataFrame & src, RTP_DataFrameList & dstList);
00329
00330 RTP_DataFrame * m_bufferRTP;
00331 DWORD m_lastDecodedTimestamp;
00332 DWORD m_lastMarkerTimestamp;
00333 bool m_badMarkers;
00334 PSimpleTimer m_videoPictureLossTimer;
00335
00336 #if PTRACING
00337 unsigned m_consecutiveIntraFrames;
00338 #endif
00339 };
00340
00341 #endif
00342
00344
00345 #if OPAL_T38_CAPABILITY
00346
00347 class OpalPluginFaxFormatInternal : public OpalMediaFormatInternal, public OpalPluginMediaFormatInternal
00348 {
00349 public:
00350 OpalPluginFaxFormatInternal(
00351 const PluginCodec_Definition * codec,
00352 const char * fmtName,
00353 const char * rtpEncodingName,
00354 unsigned frameTime,
00355 unsigned ,
00356 time_t timeStamp
00357 );
00358 virtual PObject * Clone() const;
00359 virtual bool IsValidForProtocol(const PString & protocol) const;
00360 };
00361
00362 #endif // OPAL_T38_CAPABILITY
00363
00364
00366
00367
00368
00369
00377 class OpalFactoryCodec : public PObject {
00378 PCLASSINFO(OpalFactoryCodec, PObject)
00379 public:
00381 virtual const struct PluginCodec_Definition * GetDefinition()
00382 { return NULL; }
00383
00385 virtual PString GetInputFormat() const = 0;
00386
00388 virtual PString GetOutputFormat() const = 0;
00389
00391 virtual int Encode(const void * from,
00392 unsigned * fromLen,
00393 void * to,
00394 unsigned * toLen,
00395 unsigned int * flag
00396 ) = 0;
00397
00399 virtual unsigned int GetSampleRate() const = 0;
00400
00402 virtual unsigned int GetBitsPerSec() const = 0;
00403
00405 virtual unsigned int GetFrameTime() const = 0;
00406
00408 virtual unsigned int GetSamplesPerFrame() const = 0;
00409
00411 virtual unsigned int GetBytesPerFrame() const = 0;
00412
00414 virtual unsigned int GetRecommendedFramesPerPacket() const = 0;
00415
00417 virtual unsigned int GetMaxFramesPerPacket() const = 0;
00418
00420 virtual BYTE GetRTPPayload() const = 0;
00421
00423 virtual PString GetSDPFormat() const = 0;
00424 };
00425
00427
00428 template<class TranscoderClass>
00429 class OpalPluginTranscoderFactory : public OpalTranscoderFactory
00430 {
00431 public:
00432 class Worker : public OpalTranscoderFactory::WorkerBase
00433 {
00434 public:
00435 Worker(const OpalTranscoderKey & key, const PluginCodec_Definition * codec, bool enc)
00436 : OpalTranscoderFactory::WorkerBase(), codecDefn(codec), isEncoder(enc)
00437 { OpalTranscoderFactory::Register(key, this); }
00438
00439 protected:
00440 virtual OpalTranscoder * Create(const OpalTranscoderKey &) const
00441 { return new TranscoderClass(codecDefn, isEncoder); }
00442
00443 const PluginCodec_Definition * codecDefn;
00444 bool isEncoder;
00445 };
00446 };
00447
00449
00450
00451
00452
00453 class H323PluginCapabilityInfo
00454 {
00455 public:
00456 H323PluginCapabilityInfo(const PluginCodec_Definition * codecDefn, const OpalMediaFormat & mediaFormat);
00457
00458
00459
00460 const PString & GetFormatName() const
00461 { return m_capabilityFormatName; }
00462
00463 protected:
00464 const PluginCodec_Definition * m_codecDefn;
00465 PString m_capabilityFormatName;
00466 };
00467
00468 #if OPAL_H323
00469
00471
00472
00473
00474
00475 class H323AudioPluginCapability : public H323AudioCapability,
00476 public H323PluginCapabilityInfo
00477 {
00478 PCLASSINFO(H323AudioPluginCapability, H323AudioCapability);
00479 public:
00480 H323AudioPluginCapability(const PluginCodec_Definition * codecDefn,
00481 const OpalMediaFormat & mediaFormat,
00482 unsigned pluginSubType);
00483
00484 virtual PObject * Clone() const;
00485
00486 virtual PString GetFormatName() const;
00487
00488 virtual unsigned GetSubType() const;
00489
00490 protected:
00491 unsigned pluginSubType;
00492 };
00493
00494 #define OPAL_DECLARE_EMPTY_AUDIO_CAPABILITY(fmt, type) \
00495 class fmt##_CapabilityRegisterer { \
00496 public: \
00497 fmt##_CapabilityRegisterer() \
00498 { H323CapabilityFactory::Register(fmt, new H323AudioPluginCapability(fmt, fmt, type)); } \
00499 }; \
00500
00501 #define OPAL_DEFINE_EMPTY_AUDIO_CAPABILITY(fmt) \
00502 static fmt##_CapabilityRegisterer fmt##_CapabilityRegisterer_instance; \
00503
00505 //
00506
00507
00508
00509 class H323PluginG7231Capability : public H323AudioPluginCapability
00510 {
00511 PCLASSINFO(H323PluginG7231Capability, H323AudioPluginCapability);
00512 public:
00513 H323PluginG7231Capability(const PluginCodec_Definition * codecDefn,
00514 const OpalMediaFormat & mediaFormat);
00515
00516 virtual PObject * Clone() const;
00517 virtual PBoolean OnSendingPDU(H245_AudioCapability & cap, unsigned packetSize) const;
00518 virtual PBoolean OnReceivedPDU(const H245_AudioCapability & cap, unsigned & packetSize);
00519 };
00520
00521 #define OPAL_DECLARE_EMPTY_G7231_CAPABILITY(fmt, annex) \
00522 class fmt##_CapabilityRegisterer { \
00523 public: \
00524 fmt##_CapabilityRegisterer() \
00525 { H323CapabilityFactory::Register(fmt, new H323PluginG7231Capability(fmt, annex)); } \
00526 }; \
00527
00528 #define OPAL_DEFINE_EMPTY_G7231_CAPABILITY(fmt) \
00529 static fmt##_CapabilityRegisterer fmt##_CapabilityRegisterer_instance; \
00530
00532 //
00533
00534
00535
00536 class H323CodecPluginNonStandardAudioCapability : public H323NonStandardAudioCapability,
00537 public H323PluginCapabilityInfo
00538 {
00539 PCLASSINFO(H323CodecPluginNonStandardAudioCapability, H323NonStandardAudioCapability);
00540 public:
00541 H323CodecPluginNonStandardAudioCapability(const PluginCodec_Definition * codecDefn,
00542 const OpalMediaFormat & mediaFormat,
00543 H323NonStandardCapabilityInfo::CompareFuncType compareFunc,
00544 const unsigned char * data, unsigned dataLen);
00545
00546 H323CodecPluginNonStandardAudioCapability(const PluginCodec_Definition * codecDefn,
00547 const OpalMediaFormat & mediaFormat,
00548 const unsigned char * data, unsigned dataLen);
00549
00550 virtual PObject * Clone() const;
00551
00552 virtual PString GetFormatName() const;
00553 };
00554
00556
00557
00558
00559
00560 class H323CodecPluginGenericAudioCapability : public H323GenericAudioCapability,
00561 public H323PluginCapabilityInfo
00562 {
00563 PCLASSINFO(H323CodecPluginGenericAudioCapability, H323GenericAudioCapability);
00564 public:
00565 H323CodecPluginGenericAudioCapability(const PluginCodec_Definition * codecDefn,
00566 const OpalMediaFormat & mediaFormat,
00567 const PluginCodec_H323GenericCodecData * data);
00568
00569 virtual PObject * Clone() const;
00570 virtual PString GetFormatName() const;
00571 };
00572
00573
00574 #if OPAL_VIDEO
00575
00577
00578
00579
00580
00581 class H323VideoPluginCapability : public H323VideoCapability,
00582 public H323PluginCapabilityInfo
00583 {
00584 PCLASSINFO(H323VideoPluginCapability, H323VideoCapability);
00585 public:
00586 H323VideoPluginCapability(const PluginCodec_Definition * codecDefn,
00587 const OpalMediaFormat & mediaFormat,
00588 unsigned _pluginSubType);
00589
00590 virtual PString GetFormatName() const;
00591
00592 virtual unsigned GetSubType() const;
00593
00594 static bool SetOptionsFromMPI(OpalMediaFormat & mediaFormat, int frameWidth, int frameHeight, int frameRate);
00595
00596 virtual void PrintOn(std::ostream & strm) const;
00597
00598 protected:
00599 unsigned pluginSubType;
00600 unsigned h323subType;
00601 };
00602
00604
00605
00606
00607
00608 class H323CodecPluginNonStandardVideoCapability : public H323NonStandardVideoCapability,
00609 public H323PluginCapabilityInfo
00610 {
00611 PCLASSINFO(H323CodecPluginNonStandardVideoCapability, H323NonStandardVideoCapability);
00612 public:
00613 H323CodecPluginNonStandardVideoCapability(const PluginCodec_Definition * codecDefn,
00614 const OpalMediaFormat & mediaFormat,
00615 H323NonStandardCapabilityInfo::CompareFuncType compareFunc,
00616 const unsigned char * data, unsigned dataLen);
00617
00618 H323CodecPluginNonStandardVideoCapability(const PluginCodec_Definition * codecDefn,
00619 const OpalMediaFormat & mediaFormat,
00620 const unsigned char * data, unsigned dataLen);
00621
00622 virtual PObject * Clone() const;
00623
00624 virtual PString GetFormatName() const;
00625 };
00626
00628
00629
00630
00631
00632 class H323CodecPluginGenericVideoCapability : public H323GenericVideoCapability,
00633 public H323PluginCapabilityInfo
00634 {
00635 PCLASSINFO(H323CodecPluginGenericVideoCapability, H323GenericVideoCapability);
00636 public:
00637 H323CodecPluginGenericVideoCapability(const PluginCodec_Definition * codecDefn,
00638 const OpalMediaFormat & mediaFormat,
00639 const PluginCodec_H323GenericCodecData * data);
00640
00641 virtual PObject * Clone() const;
00642
00643 virtual PString GetFormatName() const;
00644 };
00645
00647
00648
00649
00650
00651 class H323H261PluginCapability : public H323VideoPluginCapability
00652 {
00653 PCLASSINFO(H323H261PluginCapability, H323VideoPluginCapability);
00654 public:
00655 H323H261PluginCapability(const PluginCodec_Definition * codecDefn, const OpalMediaFormat & mediaFormat);
00656
00657 Comparison Compare(const PObject & obj) const;
00658
00659 virtual PObject * Clone() const;
00660
00661 virtual PBoolean OnSendingPDU(
00662 H245_VideoCapability & pdu
00663 ) const;
00664
00665 virtual PBoolean OnSendingPDU(
00666 H245_VideoMode & pdu
00667 ) const;
00668
00669 virtual PBoolean OnReceivedPDU(
00670 const H245_VideoCapability & pdu
00671 );
00672 };
00673
00675
00676
00677
00678
00679 class H323H263PluginCapability : public H323VideoPluginCapability
00680 {
00681 PCLASSINFO(H323H263PluginCapability, H323VideoPluginCapability);
00682 public:
00683 H323H263PluginCapability(const PluginCodec_Definition * codecDefn, const OpalMediaFormat & mediaFormat);
00684
00685 Comparison Compare(const PObject & obj) const;
00686
00687 virtual PObject * Clone() const;
00688
00689 virtual PBoolean OnSendingPDU(
00690 H245_VideoCapability & pdu
00691 ) const;
00692
00693 virtual PBoolean OnSendingPDU(
00694 H245_VideoMode & pdu
00695 ) const;
00696
00697 virtual PBoolean OnReceivedPDU(
00698 const H245_VideoCapability & pdu
00699 );
00700 virtual PBoolean IsMatch(
00701 const PASN_Choice & subTypePDU,
00702 const PString & mediaPacketization
00703 ) const;
00704 };
00705
00706 #endif // OPAL_VIDEO
00707 #endif // OPAL_H323
00708
00709 #endif // OPAL_CODEC_OPALPLUGINMGR_H