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