OPAL  Version 3.10.4
mediafmt.h
Go to the documentation of this file.
00001 /*
00002  * mediafmt.h
00003  *
00004  * Media Format descriptions
00005  *
00006  * Open Phone Abstraction Library (OPAL)
00007  * Formally known as the Open H323 project.
00008  *
00009  * Copyright (c) 2001 Equivalence Pty. Ltd.
00010  *
00011  * The contents of this file are subject to the Mozilla Public License
00012  * Version 1.0 (the "License"); you may not use this file except in
00013  * compliance with the License. You may obtain a copy of the License at
00014  * http://www.mozilla.org/MPL/
00015  *
00016  * Software distributed under the License is distributed on an "AS IS"
00017  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00018  * the License for the specific language governing rights and limitations
00019  * under the License.
00020  *
00021  * The Original Code is Open H323 Library.
00022  *
00023  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00024  *
00025  * Contributor(s): ______________________________________.
00026  *
00027  * $Revision: 26920 $
00028  * $Author: rjongbloed $
00029  * $Date: 2012-01-31 23:02:10 -0600 (Tue, 31 Jan 2012) $
00030  */
00031 
00032 #ifndef OPAL_OPAL_MEDIAFMT_H
00033 #define OPAL_OPAL_MEDIAFMT_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #ifdef _MSC_VER
00040 #if _MSC_VER < 1300   
00041 #pragma warning(disable:4663)
00042 #endif
00043 #endif
00044 
00045 #include <opal/buildopts.h>
00046 
00047 #include <opal/mediatype.h>
00048 #include <rtp/rtp.h>
00049 
00050 #if OPAL_VIDEO
00051 #include <ptlib/videoio.h>
00052 #endif
00053 
00054 #include <limits>
00055 
00056 #ifdef min
00057 #undef min
00058 #endif
00059 #ifdef max
00060 #undef max
00061 #endif
00062 
00063 class OpalMediaFormat;
00064 
00065 
00067 
00068 PLIST(OpalMediaFormatBaseList, OpalMediaFormat);
00069 
00072 class OpalMediaFormatList : public OpalMediaFormatBaseList
00073 {
00074   PCLASSINFO(OpalMediaFormatList, OpalMediaFormatBaseList);
00075   public:
00080     OpalMediaFormatList();
00081 
00084     OpalMediaFormatList(
00085       const OpalMediaFormat & format    
00086     );
00087 
00090     OpalMediaFormatList(const OpalMediaFormatList & l) : OpalMediaFormatBaseList(l) { }
00092 
00098     OpalMediaFormatList & operator+=(
00099       const char * wildcard    
00100     ) { PConstString s(wildcard); return operator+=(s); }
00101 
00105     OpalMediaFormatList & operator+=(
00106       const PString & wildcard    
00107     );
00108 
00112     OpalMediaFormatList & operator+=(
00113       const OpalMediaFormat & format    
00114     );
00115 
00119     OpalMediaFormatList & operator+=(
00120       const OpalMediaFormatList & formats    
00121     );
00122 
00126     OpalMediaFormatList & operator-=(
00127       const OpalMediaFormat & format    
00128     );
00129 
00133     OpalMediaFormatList & operator-=(
00134       const OpalMediaFormatList & formats    
00135     );
00136 
00142     const_iterator FindFormat(
00143       RTP_DataFrame::PayloadTypes rtpPayloadType, 
00144       const unsigned clockRate,                   
00145       const char * rtpEncodingName = NULL,        
00146       const char * protocol = NULL,               
00147       const_iterator start = const_iterator()     
00148     ) const;
00149 
00166     const_iterator FindFormat(
00167       const PString & wildcard,    
00168       const_iterator start = const_iterator() 
00169     ) const;
00170 
00173     PBoolean HasFormat(
00174       RTP_DataFrame::PayloadTypes rtpPayloadType 
00175     ) const { return FindFormat(rtpPayloadType) != end(); }
00176 
00182     PBoolean HasFormat(
00183       const PString & wildcard    
00184     ) const { return FindFormat(wildcard) != end(); }
00185 
00204     void Remove(
00205       const PStringArray & mask
00206     );
00207 
00223     void Reorder(
00224       const PStringArray & order
00225     );
00226 
00229     bool HasType(
00230       const OpalMediaType & type,
00231       bool mustBeTransportable = true
00232     ) const;
00234 
00235   private:
00236     virtual PINDEX Append(PObject *) { return P_MAX_INDEX; }
00237     virtual PINDEX Insert(const PObject &, PObject *) { return P_MAX_INDEX; }
00238     virtual PINDEX InsertAt(PINDEX, PObject *) { return P_MAX_INDEX; }
00239     virtual PBoolean SetAt(PINDEX, PObject *) { return false; }
00240 };
00241 
00242 
00244 
00247 class OpalMediaOption : public PObject
00248 {
00249     PCLASSINFO(OpalMediaOption, PObject);
00250   public:
00251     // Note the below enum must be identical to PluginCodec_OptionMerge in opalplugin.h
00252     enum MergeType {
00253       NoMerge,
00254       MinMerge,
00255       MaxMerge,
00256       EqualMerge,
00257       NotEqualMerge,
00258       AlwaysMerge,
00259       CustomMerge,
00260       IntersectionMerge, // Set intersection, applies to numeric (bit wise AND) or string (common substrings)
00261 
00262       // Synonyms
00263       AndMerge = MinMerge,  // Applies to Boolean option or Enum with two elements
00264       OrMerge  = MaxMerge   // Applies to Boolean option or Enum with two elements
00265     };
00266 
00267   protected:
00268     OpalMediaOption(
00269       const PString & name
00270     );
00271     OpalMediaOption(
00272       const char * name,
00273       bool readOnly,
00274       MergeType merge
00275     );
00276 
00277   public:
00278     virtual Comparison Compare(const PObject & obj) const;
00279 
00280     virtual bool Merge(
00281       const OpalMediaOption & option
00282     );
00283 
00284     virtual bool ValidateMerge(
00285       const OpalMediaOption & option
00286     ) const;
00287 
00288     virtual Comparison CompareValue(
00289       const OpalMediaOption & option
00290     ) const = 0;
00291     virtual void Assign(
00292       const OpalMediaOption & option
00293     ) = 0;
00294 
00295     PString AsString() const;
00296     bool FromString(const PString & value);
00297 
00298     const PString & GetName() const { return m_name; }
00299 
00300     bool IsReadOnly() const { return m_readOnly; }
00301     void SetReadOnly(bool readOnly) { m_readOnly = readOnly; }
00302 
00303     MergeType GetMerge() const { return m_merge; }
00304     void SetMerge(MergeType merge) { m_merge = merge; }
00305 
00306 #if OPAL_SIP
00307     const PString & GetFMTPName() const { return m_FMTPName; }
00308     void SetFMTPName(const char * name) { m_FMTPName = name; }
00309 
00310     const PString & GetFMTPDefault() const { return m_FMTPDefault; }
00311     void SetFMTPDefault(const char * value) { m_FMTPDefault = value; }
00312 #endif // OPAL_SIP
00313 
00314 #if OPAL_H323
00315     struct H245GenericInfo {
00316       H245GenericInfo() { memset(this, 0, sizeof(*this)); }
00317       unsigned ordinal:16;
00318       enum Modes {
00319         None,
00320         Collapsing,
00321         NonCollapsing
00322       } mode:3;
00323       enum IntegerTypes {
00324         UnsignedInt,
00325         Unsigned32,
00326         BooleanArray
00327       } integerType:3;
00328       bool excludeTCS:1;
00329       bool excludeOLC:1;
00330       bool excludeReqMode:1;
00331     };
00332 
00333     const H245GenericInfo & GetH245Generic() const { return m_H245Generic; }
00334     void SetH245Generic(const H245GenericInfo & genericInfo) { m_H245Generic = genericInfo; }
00335 #endif // OPAL_H323
00336 
00337   protected:
00338     PCaselessString m_name;
00339     bool            m_readOnly;
00340     MergeType       m_merge;
00341 
00342 #if OPAL_SIP
00343     PCaselessString m_FMTPName;
00344     PString         m_FMTPDefault;
00345 #endif // OPAL_SIP
00346 
00347 #if OPAL_H323
00348     H245GenericInfo m_H245Generic;
00349 #endif // OPAL_H323
00350 };
00351 
00352 
00353 template <typename T>
00354 class OpalMediaOptionValue : public OpalMediaOption
00355 {
00356     PCLASSINFO(OpalMediaOptionValue, OpalMediaOption);
00357   public:
00358     OpalMediaOptionValue(
00359       const char * name,
00360       bool readOnly,
00361       OpalMediaOption::MergeType merge = OpalMediaOption::MinMerge,
00362       T value = T()
00363     )
00364       : OpalMediaOption(name, readOnly, merge)
00365       , m_value(value)
00366     {
00367     }
00368 
00369     virtual PObject * Clone() const
00370     {
00371       return new OpalMediaOptionValue(*this);
00372     }
00373 
00374     virtual void PrintOn(ostream & strm) const
00375     {
00376       strm << m_value;
00377     }
00378 
00379     virtual void ReadFrom(istream & strm)
00380     {
00381       strm >> m_value;
00382     }
00383 
00384     virtual bool Merge(const OpalMediaOption & option)
00385     {
00386       if (m_merge != IntersectionMerge)
00387         return OpalMediaOption::Merge(option);
00388 
00389       const OpalMediaOptionValue * otherOption = PDownCast(const OpalMediaOptionValue, &option);
00390       if (otherOption == NULL)
00391         return false;
00392 
00393       m_value &= otherOption->m_value;
00394       return true;
00395     }
00396 
00397     virtual Comparison CompareValue(const OpalMediaOption & option) const
00398     {
00399       const OpalMediaOptionValue * otherOption = PDownCast(const OpalMediaOptionValue, &option);
00400       if (otherOption == NULL)
00401         return GreaterThan;
00402       if (m_value < otherOption->m_value)
00403         return LessThan;
00404       if (m_value > otherOption->m_value)
00405         return GreaterThan;
00406       return EqualTo;
00407     }
00408 
00409     virtual void Assign(const OpalMediaOption & option)
00410     {
00411       const OpalMediaOptionValue * otherOption = PDownCast(const OpalMediaOptionValue, &option);
00412       if (otherOption != NULL)
00413         m_value = otherOption->m_value;
00414     }
00415 
00416     T GetValue() const
00417     {
00418       return m_value;
00419     }
00420 
00421     void SetValue(T value)
00422     {
00423       m_value = value;
00424     }
00425 
00426   protected:
00427     T m_value;
00428 };
00429 
00430 
00431 template <typename T>
00432 class OpalMediaOptionNumericalValue : public OpalMediaOptionValue<T>
00433 {
00434     typedef OpalMediaOptionValue<T> BaseClass;
00435     PCLASSINFO(OpalMediaOptionNumericalValue, BaseClass);
00436   public:
00437     OpalMediaOptionNumericalValue(
00438       const char * name,
00439       bool readOnly,
00440       OpalMediaOption::MergeType merge = OpalMediaOption::MinMerge,
00441       T value = 0,
00442       T minimum = std::numeric_limits<T>::min(),
00443       T maximum = std::numeric_limits<T>::max()
00444     )
00445       : BaseClass(name, readOnly, merge, value)
00446       , m_minimum(minimum)
00447       , m_maximum(maximum)
00448     {
00449     }
00450 
00451     virtual PObject * Clone() const
00452     {
00453       return new OpalMediaOptionNumericalValue(*this);
00454     }
00455 
00456     virtual void ReadFrom(istream & strm)
00457     {
00458       T temp = 0;
00459       strm >> temp;
00460       if (strm.fail())
00461         return;
00462       if (temp >= m_minimum && temp <= m_maximum)
00463         this->m_value = temp;
00464       else
00465         strm.setstate(ios::badbit);
00466     }
00467 
00468     void SetValue(T value)
00469     {
00470       if (value < m_minimum)
00471         this->m_value = m_minimum;
00472       else if (value > m_maximum)
00473         this->m_value = m_maximum;
00474       else
00475         this->m_value = value;
00476     }
00477 
00478     void SetMinimum(T m)
00479     {
00480       this->m_minimum = m;
00481     }
00482 
00483     void SetMaximum(T m)
00484     {
00485       this->m_maximum = m;
00486     }
00487 
00488   protected:
00489     T m_minimum;
00490     T m_maximum;
00491 };
00492 
00493 
00494 typedef OpalMediaOptionNumericalValue<bool>     OpalMediaOptionBoolean;
00495 typedef OpalMediaOptionNumericalValue<int>      OpalMediaOptionInteger;
00496 typedef OpalMediaOptionNumericalValue<unsigned> OpalMediaOptionUnsigned;
00497 
00498 // Wrapper class so we can implement intersection (&= operator) for floating point
00499 class OpalMediaOptionRealValue
00500 {
00501     double m_value;
00502   public:
00503     OpalMediaOptionRealValue(double value = 0) : m_value(value) { }
00504     operator double() const { return m_value; }
00505     void operator&=(double other) { if (m_value > other) m_value = other; }
00506     friend ostream & operator<<(ostream & strm, const OpalMediaOptionRealValue & value) { return strm << value.m_value; }
00507     friend istream & operator>>(istream & strm,       OpalMediaOptionRealValue & value) { return strm >> value.m_value; }
00508 };
00509 
00510 typedef OpalMediaOptionNumericalValue<OpalMediaOptionRealValue> OpalMediaOptionReal;
00511 
00512 
00513 class OpalMediaOptionEnum : public OpalMediaOption
00514 {
00515     PCLASSINFO(OpalMediaOptionEnum, OpalMediaOption);
00516   public:
00517     OpalMediaOptionEnum(
00518       const char * name,
00519       bool readOnly
00520     );
00521     OpalMediaOptionEnum(
00522       const char * name,
00523       bool readOnly,
00524       const char * const * enumerations,
00525       PINDEX count,
00526       MergeType merge = EqualMerge,
00527       PINDEX value = 0
00528     );
00529 
00530     virtual PObject * Clone() const;
00531     virtual void PrintOn(ostream & strm) const;
00532     virtual void ReadFrom(istream & strm);
00533 
00534     virtual Comparison CompareValue(const OpalMediaOption & option) const;
00535     virtual void Assign(const OpalMediaOption & option);
00536 
00537     PINDEX GetValue() const { return m_value; }
00538     void SetValue(PINDEX value);
00539 
00540     const PStringArray & GetEnumerations() const { return m_enumerations; }
00541     void SetEnumerations(const PStringArray & e)
00542     {
00543       m_enumerations = e;
00544     }
00545 
00546   protected:
00547     PStringArray m_enumerations;
00548     PINDEX       m_value;
00549 };
00550 
00551 
00552 class OpalMediaOptionString : public OpalMediaOption
00553 {
00554     PCLASSINFO(OpalMediaOptionString, OpalMediaOption);
00555   public:
00556     OpalMediaOptionString(
00557       const char * name,
00558       bool readOnly
00559     );
00560     OpalMediaOptionString(
00561       const char * name,
00562       bool readOnly,
00563       const PString & value
00564     );
00565 
00566     virtual PObject * Clone() const;
00567     virtual void PrintOn(ostream & strm) const;
00568     virtual void ReadFrom(istream & strm);
00569 
00570     virtual bool Merge(const OpalMediaOption & option);
00571     virtual Comparison CompareValue(const OpalMediaOption & option) const;
00572     virtual void Assign(const OpalMediaOption & option);
00573 
00574     const PString & GetValue() const { return m_value; }
00575     void SetValue(const PString & value);
00576 
00577   protected:
00578     PString m_value;
00579 };
00580 
00581 
00582 class OpalMediaOptionOctets : public OpalMediaOption
00583 {
00584     PCLASSINFO(OpalMediaOptionOctets, OpalMediaOption);
00585   public:
00586     OpalMediaOptionOctets(
00587       const char * name,
00588       bool readOnly,
00589       bool base64 = false
00590     );
00591     OpalMediaOptionOctets(
00592       const char * name,
00593       bool readOnly,
00594       bool base64,
00595       const PBYTEArray & value
00596     );
00597     OpalMediaOptionOctets(
00598       const char * name,
00599       bool readOnly,
00600       bool base64,
00601       const BYTE * data,
00602       PINDEX length
00603     );
00604 
00605     virtual PObject * Clone() const;
00606     virtual void PrintOn(ostream & strm) const;
00607     virtual void ReadFrom(istream & strm);
00608 
00609     virtual Comparison CompareValue(const OpalMediaOption & option) const;
00610     virtual void Assign(const OpalMediaOption & option);
00611 
00612     const PBYTEArray & GetValue() const { return m_value; }
00613     void SetValue(const PBYTEArray & value);
00614     void SetValue(const BYTE * data, PINDEX length);
00615 
00616     void SetBase64(bool b)
00617     {
00618       m_base64 = b;
00619     }
00620 
00621   protected:
00622     PBYTEArray m_value;
00623     bool       m_base64;
00624 };
00625 
00626 
00628 
00629 class OpalMediaFormatInternal : public PObject
00630 {
00631     PCLASSINFO(OpalMediaFormatInternal, PObject);
00632   public:
00633     OpalMediaFormatInternal(
00634       const char * fullName,
00635       const OpalMediaType & mediaType,
00636       RTP_DataFrame::PayloadTypes rtpPayloadType,
00637       const char * encodingName,
00638       PBoolean     needsJitter,
00639       unsigned bandwidth,
00640       PINDEX   frameSize,
00641       unsigned frameTime,
00642       unsigned clockRate,
00643       time_t timeStamp
00644     );
00645 
00646     const PCaselessString & GetName() const { return formatName; }
00647 
00648     virtual PObject * Clone() const;
00649     virtual void PrintOn(ostream & strm) const;
00650 
00651     virtual bool IsValid() const;
00652     virtual bool IsTransportable() const;
00653 
00654     virtual PStringToString GetOptions() const;
00655     virtual bool GetOptionValue(const PString & name, PString & value) const;
00656     virtual bool SetOptionValue(const PString & name, const PString & value);
00657     virtual bool GetOptionBoolean(const PString & name, bool dflt) const;
00658     virtual bool SetOptionBoolean(const PString & name, bool value);
00659     virtual int GetOptionInteger(const PString & name, int dflt) const;
00660     virtual bool SetOptionInteger(const PString & name, int value);
00661     virtual double GetOptionReal(const PString & name, double dflt) const;
00662     virtual bool SetOptionReal(const PString & name, double value);
00663     virtual PINDEX GetOptionEnum(const PString & name, PINDEX dflt) const;
00664     virtual bool SetOptionEnum(const PString & name, PINDEX value);
00665     virtual PString GetOptionString(const PString & name, const PString & dflt) const;
00666     virtual bool SetOptionString(const PString & name, const PString & value);
00667     virtual bool GetOptionOctets(const PString & name, PBYTEArray & octets) const;
00668     virtual bool SetOptionOctets(const PString & name, const PBYTEArray & octets);
00669     virtual bool SetOptionOctets(const PString & name, const BYTE * data, PINDEX length);
00670     virtual bool AddOption(OpalMediaOption * option, PBoolean overwrite = false);
00671     virtual OpalMediaOption * FindOption(const PString & name) const;
00672 
00673     virtual bool ToNormalisedOptions();
00674     virtual bool ToCustomisedOptions();
00675     virtual bool Merge(const OpalMediaFormatInternal & mediaFormat);
00676 
00677     virtual bool ValidateMerge(const OpalMediaFormatInternal & mediaFormat) const;
00678 
00679     virtual bool IsValidForProtocol(const PString & protocol) const;
00680 
00681   protected:
00682     PCaselessString              formatName;
00683     RTP_DataFrame::PayloadTypes  rtpPayloadType;
00684     PString                      rtpEncodingName;
00685     OpalMediaType                mediaType;
00686     PMutex                       media_format_mutex;
00687     PSortedList<OpalMediaOption> options;
00688     time_t                       codecVersionTime;
00689     bool                         forceIsTransportable;
00690     int                          m_channels;
00691 
00692   friend bool operator==(const char * other, const OpalMediaFormat & fmt);
00693   friend bool operator!=(const char * other, const OpalMediaFormat & fmt);
00694   friend bool operator==(const PString & other, const OpalMediaFormat & fmt);
00695   friend bool operator!=(const PString & other, const OpalMediaFormat & fmt);
00696 
00697   friend class OpalMediaFormat;
00698   friend class OpalMediaFormatList;
00699   friend class OpalAudioFormatInternal;
00700 };
00701 
00702 
00704 
00710 class OpalMediaFormat : public PContainer
00711 {
00712     PCLASSINFO(OpalMediaFormat, PContainer)
00713   public:
00714     OpalMediaFormat(const OpalMediaFormat & c);
00715     virtual ~OpalMediaFormat();
00716     OpalMediaFormat & operator=(const OpalMediaFormat & c)     { AssignContents(c); return *this; }
00717     virtual PBoolean MakeUnique();
00718   protected:
00719     virtual void DestroyContents();
00720     virtual void AssignContents(const PContainer & c);
00721 
00722   public:
00725     OpalMediaFormat(
00726       OpalMediaFormatInternal * info = NULL
00727     );
00728 
00742     OpalMediaFormat(
00743       const char * fullName,                      
00744       const OpalMediaType & mediaType,            
00745       RTP_DataFrame::PayloadTypes rtpPayloadType, 
00746       const char * encodingName,                  
00747       PBoolean     needsJitter,                   
00748       unsigned bandwidth,                         
00749       PINDEX   frameSize,                         
00750       unsigned frameTime,                         
00751       unsigned clockRate,                         
00752       time_t timeStamp = 0                        
00753     );
00754 
00764     OpalMediaFormat(
00765       RTP_DataFrame::PayloadTypes rtpPayloadType, 
00766       unsigned clockRate,                         
00767       const char * rtpEncodingName = NULL,        
00768       const char * protocol = NULL                
00769     );
00770 
00784     OpalMediaFormat(
00785       const char * wildcard  
00786     );
00787 
00801     OpalMediaFormat(
00802       const PString & wildcard  
00803     );
00804     
00808     OpalMediaFormat & operator=(
00809       RTP_DataFrame::PayloadTypes rtpPayloadType 
00810     );
00811 
00815     OpalMediaFormat & operator=(
00816       const char * wildcard  
00817     );
00818 
00822     OpalMediaFormat & operator=(
00823       const PString & wildcard  
00824     );
00825 
00828     virtual PObject * Clone() const;
00829 
00832     virtual Comparison Compare(const PObject & obj) const;
00833 
00838     virtual void PrintOn(ostream & strm) const;
00839 
00842     virtual void ReadFrom(istream & strm);
00843 
00848     bool ToNormalisedOptions();
00849 
00853     bool ToCustomisedOptions();
00854 
00857     bool Update(
00858       const OpalMediaFormat & mediaFormat
00859     );
00860 
00871     bool Merge(
00872       const OpalMediaFormat & mediaFormat
00873     );
00876     bool ValidateMerge(
00877       const OpalMediaFormat & mediaFormat
00878     ) const;
00879 
00882     PString GetName() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? "" : m_info->formatName; }
00883 
00888     PBoolean IsValid() const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->IsValid(); }
00889 
00893     PBoolean IsTransportable() const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->IsTransportable(); }
00894 
00900     RTP_DataFrame::PayloadTypes GetPayloadType() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? RTP_DataFrame::IllegalPayloadType : m_info->rtpPayloadType; }
00901     void SetPayloadType(RTP_DataFrame::PayloadTypes type) { PWaitAndSignal m(m_mutex); MakeUnique(); if (m_info != NULL) m_info->rtpPayloadType = type; }
00902 
00905     const char * GetEncodingName() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? "" : m_info->rtpEncodingName.GetPointer(); }
00906 
00909     OpalMediaType GetMediaType() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? OpalMediaType() : m_info->mediaType; }
00910 
00914     bool NeedsJitterBuffer() const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->GetOptionBoolean(NeedsJitterOption(), false); }
00915     static const PString & NeedsJitterOption();
00916 
00919     unsigned GetBandwidth() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->GetOptionInteger(MaxBitRateOption(), 0); }
00920     static const PString & MaxBitRateOption();
00921     static const PString & TargetBitRateOption();
00922 
00927     PINDEX GetFrameSize() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->GetOptionInteger(MaxFrameSizeOption(), 0); }
00928     static const PString & MaxFrameSizeOption();
00929 
00933     unsigned GetFrameTime() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->GetOptionInteger(FrameTimeOption(), 0); }
00934     static const PString & FrameTimeOption();
00935 
00938     unsigned GetTimeUnits() const { return GetClockRate()/1000; }
00939 
00940     enum StandardClockRate {
00941       AudioClockRate = 8000,  
00942       VideoClockRate = 90000  
00943     };
00944 
00947     unsigned GetClockRate() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->GetOptionInteger(ClockRateOption(), 1000); }
00948     static const PString & ClockRateOption();
00949 
00952     static const PString & ProtocolOption();
00953 
00960     static const PString & MaxTxPacketSizeOption();
00961 
00965     PStringToString GetOptions() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? PStringToString() : m_info->GetOptions(); }
00966 
00969     PINDEX GetOptionCount() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->options.GetSize(); }
00970 
00974     const OpalMediaOption & GetOption(
00975       PINDEX index   
00976     ) const { PWaitAndSignal m(m_mutex); return m_info->options[index]; }
00977 
00982     bool GetOptionValue(
00983       const PString & name,   
00984       PString & value         
00985     ) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->GetOptionValue(name, value); }
00986 
00993     bool SetOptionValue(
00994       const PString & name,   
00995       const PString & value   
00996     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionValue(name, value); }
00997 
01001     bool GetOptionBoolean(
01002       const PString & name,   
01003       bool dflt = false       
01004     ) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->GetOptionBoolean(name, dflt); }
01005 
01012     bool SetOptionBoolean(
01013       const PString & name,   
01014       bool value              
01015     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionBoolean(name, value); }
01016 
01020     int GetOptionInteger(
01021       const PString & name,   
01022       int dflt = 0            
01023     ) const { PWaitAndSignal m(m_mutex); return m_info == NULL ? dflt : m_info->GetOptionInteger(name, dflt); }
01024 
01032     bool SetOptionInteger(
01033       const PString & name,   
01034       int value               
01035     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionInteger(name, value); }
01036 
01040     double GetOptionReal(
01041       const PString & name,   
01042       double dflt = 0         
01043     ) const { PWaitAndSignal m(m_mutex); return m_info == NULL ? dflt : m_info->GetOptionReal(name, dflt); }
01044 
01051     bool SetOptionReal(
01052       const PString & name,   
01053       double value            
01054     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionReal(name, value); }
01055 
01060     PINDEX GetOptionEnum(
01061       const PString & name,   
01062       PINDEX dflt = 0         
01063     ) const { PWaitAndSignal m(m_mutex); return m_info == NULL ? dflt : m_info->GetOptionEnum(name, dflt); }
01064 
01071     bool SetOptionEnum(
01072       const PString & name,   
01073       PINDEX value            
01074     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionEnum(name, value); }
01075 
01079     PString GetOptionString(
01080       const PString & name,                   
01081       const PString & dflt = PString::Empty() 
01082     ) const { PWaitAndSignal m(m_mutex); return m_info == NULL ? dflt : m_info->GetOptionString(name, dflt); }
01083 
01090     bool SetOptionString(
01091       const PString & name,   
01092       const PString & value   
01093     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionString(name, value); }
01094 
01098     bool GetOptionOctets(
01099       const PString & name, 
01100       PBYTEArray & octets   
01101     ) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->GetOptionOctets(name, octets); }
01102 
01109     bool SetOptionOctets(
01110       const PString & name,       
01111       const PBYTEArray & octets   
01112     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionOctets(name, octets); }
01113     bool SetOptionOctets(
01114       const PString & name,       
01115       const BYTE * data,          
01116       PINDEX length               
01117     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->SetOptionOctets(name, data, length); }
01118 
01121     static OpalMediaFormatList GetAllRegisteredMediaFormats();
01122     static void GetAllRegisteredMediaFormats(
01123       OpalMediaFormatList & copy    
01124     );
01125 
01129     static bool SetRegisteredMediaFormat(
01130       const OpalMediaFormat & mediaFormat  
01131     );
01132 
01136     static bool RemoveRegisteredMediaFormat(
01137       const OpalMediaFormat & mediaFormat  
01138     );
01139 
01143     bool AddOption(
01144       OpalMediaOption * option,
01145       PBoolean overwrite = false
01146     ) { PWaitAndSignal m(m_mutex); MakeUnique(); return m_info != NULL && m_info->AddOption(option, overwrite); }
01147 
01151     bool HasOption(const PString & name) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->FindOption(name) != NULL; }
01152 
01156     OpalMediaOption * FindOption(
01157       const PString & name
01158     ) const { PWaitAndSignal m(m_mutex); return m_info == NULL ? NULL : m_info->FindOption(name); }
01159 
01163     template <class T> T * FindOptionAs(
01164       const PString & name
01165     ) const { return dynamic_cast<T *>(FindOption(name)); }
01166 
01172     bool IsValidForProtocol(const PString & protocol) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->IsValidForProtocol(protocol); }
01173 
01174     time_t GetCodecVersionTime() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? 0 : m_info->codecVersionTime; }
01175 
01176     ostream & PrintOptions(ostream & strm) const
01177     {
01178       PWaitAndSignal m(m_mutex);
01179       if (m_info != NULL)
01180         strm << setw(-1) << *m_info;
01181       return strm;
01182     }
01183 
01184 #if OPAL_VIDEO
01185 
01187     void AdjustVideoArgs(
01188       PVideoDevice::OpenArgs & args  
01189     ) const;
01190 #endif
01191 
01192     // Backward compatibility
01193     virtual PBoolean IsEmpty() const { PWaitAndSignal m(m_mutex); return m_info == NULL || !m_info->IsValid(); }
01194     operator PString() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? "" : m_info->formatName; }
01195     operator const char *() const { PWaitAndSignal m(m_mutex); return m_info == NULL ? "" : m_info->formatName; }
01196     bool operator==(const char * other) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->formatName == other; }
01197     bool operator!=(const char * other) const { PWaitAndSignal m(m_mutex); return m_info == NULL || m_info->formatName != other; }
01198     bool operator==(const PString & other) const { PWaitAndSignal m(m_mutex); return m_info != NULL && m_info->formatName == other; }
01199     bool operator!=(const PString & other) const { PWaitAndSignal m(m_mutex); return m_info == NULL || m_info->formatName != other; }
01200     bool operator==(const OpalMediaFormat & other) const { PWaitAndSignal m(m_mutex); return Compare(other) == EqualTo; }
01201     bool operator!=(const OpalMediaFormat & other) const { PWaitAndSignal m(m_mutex); return Compare(other) != EqualTo; }
01202     friend bool operator==(const char * other, const OpalMediaFormat & fmt) { return fmt.m_info != NULL && fmt.m_info->formatName == other; }
01203     friend bool operator!=(const char * other, const OpalMediaFormat & fmt) { return fmt.m_info == NULL || fmt.m_info->formatName != other; }
01204     friend bool operator==(const PString & other, const OpalMediaFormat & fmt) { return fmt.m_info != NULL && fmt.m_info->formatName == other; }
01205     friend bool operator!=(const PString & other, const OpalMediaFormat & fmt) { return fmt.m_info == NULL || fmt.m_info->formatName != other; }
01206 
01207 #if OPAL_H323
01208     static const PString & MediaPacketizationOption();
01209     static const PString & MediaPacketizationsOption();
01210 #endif
01211 
01212   private:
01213     PBoolean SetSize(PINDEX) { return true; }
01214 
01215   protected:
01216     void Construct(OpalMediaFormatInternal * info);
01217 
01218     OpalMediaFormatInternal * m_info;
01219     PMutex                    m_mutex;
01220 
01221   friend class OpalMediaFormatInternal;
01222   friend class OpalMediaFormatList;
01223 };
01224 
01225 
01226 class OpalAudioFormatInternal : public OpalMediaFormatInternal
01227 {
01228   public:
01229     OpalAudioFormatInternal(
01230       const char * fullName,
01231       RTP_DataFrame::PayloadTypes rtpPayloadType,
01232       const char * encodingName,
01233       PINDEX   frameSize,
01234       unsigned frameTime,
01235       unsigned rxFrames,
01236       unsigned txFrames,
01237       unsigned maxFrames,
01238       unsigned clockRate,
01239       time_t timeStamp
01240     );
01241     virtual PObject * Clone() const;
01242     virtual bool Merge(const OpalMediaFormatInternal & mediaFormat);
01243 };
01244 
01245 class OpalAudioFormat : public OpalMediaFormat
01246 {
01247     PCLASSINFO(OpalAudioFormat, OpalMediaFormat);
01248   public:
01249     OpalAudioFormat(
01250       OpalMediaFormatInternal * info = NULL
01251     ) : OpalMediaFormat(info) { }
01252     OpalAudioFormat(
01253       const char * fullName,    
01254       RTP_DataFrame::PayloadTypes rtpPayloadType, 
01255       const char * encodingName,
01256       PINDEX   frameSize,       
01257       unsigned frameTime,       
01258       unsigned rxFrames,        
01259       unsigned txFrames,        
01260       unsigned maxFrames = 256, 
01261       unsigned clockRate = 8000, 
01262       time_t timeStamp = 0       
01263     );
01264 
01265     static const PString & RxFramesPerPacketOption();
01266     static const PString & TxFramesPerPacketOption();
01267     static const PString & MaxFramesPerPacketOption();
01268     static const PString & ChannelsOption();
01269 };
01270 
01271 #if OPAL_VIDEO
01272 class OpalVideoFormatInternal : public OpalMediaFormatInternal
01273 {
01274   public:
01275     OpalVideoFormatInternal(
01276       const char * fullName,
01277       RTP_DataFrame::PayloadTypes rtpPayloadType,
01278       const char * encodingName,
01279       unsigned maxFrameWidth,
01280       unsigned maxFrameHeight,
01281       unsigned maxFrameRate,
01282       unsigned maxBitRate,
01283       time_t timeStamp
01284     );
01285     virtual PObject * Clone() const;
01286     virtual bool Merge(const OpalMediaFormatInternal & mediaFormat);
01287 };
01288 
01289 
01290 class OpalVideoFormat : public OpalMediaFormat
01291 {
01292     PCLASSINFO(OpalVideoFormat, OpalMediaFormat);
01293   public:
01294     OpalVideoFormat(
01295       OpalMediaFormatInternal * info = NULL
01296     ) : OpalMediaFormat(info) { }
01297     OpalVideoFormat(
01298       const char * fullName,    
01299       RTP_DataFrame::PayloadTypes rtpPayloadType, 
01300       const char * encodingName,
01301       unsigned maxFrameWidth,   
01302       unsigned maxFrameHeight,  
01303       unsigned maxFrameRate,    
01304       unsigned maxBitRate,      
01305       time_t timeStamp = 0      
01306     );
01307 
01308     static const PString & FrameWidthOption();
01309     static const PString & FrameHeightOption();
01310     static const PString & MinRxFrameWidthOption();
01311     static const PString & MinRxFrameHeightOption();
01312     static const PString & MaxRxFrameWidthOption();
01313     static const PString & MaxRxFrameHeightOption();
01314     static const PString & TemporalSpatialTradeOffOption();
01315     static const PString & TxKeyFramePeriodOption();
01316     static const PString & RateControlEnableOption();
01317     static const PString & RateControllerOption();
01318     static const PString & RateControllerBitRateScalerOption();
01319 
01330     enum ContentRole {
01331       eNoRole,
01332       ePresentation,
01333       eMainRole,
01334       eSpeaker,
01335       eSignLanguage,
01336       eNumRoles
01337     };
01338     enum { ContentRoleMask = 15 };
01339     __inline static unsigned ContentRoleBit(ContentRole contentRole) { return contentRole != eNoRole ? (1<<(contentRole-1)) : 0; }
01340     static const PString & ContentRoleOption();
01341     static const PString & ContentRoleMaskOption();
01342 };
01343 #endif
01344 
01345 // List of known media formats
01346 
01347 #define OPAL_PCM16          "PCM-16"
01348 #define OPAL_PCM16S         "PCM-16S"
01349 #define OPAL_PCM16_16KHZ    "PCM-16-16kHz"
01350 #define OPAL_PCM16S_16KHZ   "PCM-16S-16kHz"
01351 #define OPAL_PCM16_32KHZ    "PCM-16-32kHz"
01352 #define OPAL_PCM16S_32KHZ   "PCM-16S-32kHz"
01353 #define OPAL_PCM16_48KHZ    "PCM-16-48kHz"
01354 #define OPAL_PCM16S_48KHZ   "PCM-16S-48kHz"
01355 #define OPAL_L16_MONO_8KHZ  "Linear-16-Mono-8kHz"
01356 #define OPAL_L16_STEREO_8KHZ "Linear-16-Stereo-8kHz"
01357 #define OPAL_L16_MONO_16KHZ "Linear-16-Mono-16kHz"
01358 #define OPAL_L16_STEREO_16KHZ "Linear-16-Stereo-16kHz"
01359 #define OPAL_L16_MONO_32KHZ "Linear-16-Mono-32kHz"
01360 #define OPAL_L16_STEREO_32KHZ "Linear-16-Stereo-32kHz"
01361 #define OPAL_L16_MONO_48KHZ "Linear-16-Mono-48kHz"
01362 #define OPAL_L16_STEREO_48KHZ "Linear-16-Stereo-48kHz"
01363 #define OPAL_G711_ULAW_64K  "G.711-uLaw-64k"
01364 #define OPAL_G711_ALAW_64K  "G.711-ALaw-64k"
01365 #define OPAL_G722           "G.722"
01366 #define OPAL_G7221          "G.722.1"
01367 #define OPAL_G7222          "G.722.2"
01368 #define OPAL_G726_40K       "G.726-40K"
01369 #define OPAL_G726_32K       "G.726-32K"
01370 #define OPAL_G726_24K       "G.726-24K"
01371 #define OPAL_G726_16K       "G.726-16K"
01372 #define OPAL_G728           "G.728"
01373 #define OPAL_G729           "G.729"
01374 #define OPAL_G729A          "G.729A"
01375 #define OPAL_G729B          "G.729B"
01376 #define OPAL_G729AB         "G.729A/B"
01377 #define OPAL_G7231          "G.723.1"
01378 #define OPAL_G7231_6k3      OPAL_G7231
01379 #define OPAL_G7231_5k3      "G.723.1(5.3k)"
01380 #define OPAL_G7231A_6k3     "G.723.1A(6.3k)"
01381 #define OPAL_G7231A_5k3     "G.723.1A(5.3k)"
01382 #define OPAL_GSM0610        "GSM-06.10"
01383 #define OPAL_GSMAMR         "GSM-AMR"
01384 #define OPAL_iLBC           "iLBC"
01385 #define OPAL_H261           "H.261"
01386 #define OPAL_H263           "H.263"
01387 #define OPAL_H264           "H.264"
01388 #define OPAL_H264_MODE0     "H.264-0"
01389 #define OPAL_H264_MODE1     "H.264-1"
01390 #define OPAL_MPEG4          "MPEG4"
01391 #define OPAL_RFC2833        "UserInput/RFC2833"
01392 #define OPAL_CISCONSE       "NamedSignalEvent"
01393 #define OPAL_T38            "T.38"
01394 
01395 extern const OpalAudioFormat & GetOpalPCM16();
01396 extern const OpalAudioFormat & GetOpalPCM16S();
01397 extern const OpalAudioFormat & GetOpalPCM16_16KHZ();
01398 extern const OpalAudioFormat & GetOpalPCM16S_16KHZ();
01399 extern const OpalAudioFormat & GetOpalPCM16_32KHZ();
01400 extern const OpalAudioFormat & GetOpalPCM16S_32KHZ();
01401 extern const OpalAudioFormat & GetOpalPCM16_48KHZ();
01402 extern const OpalAudioFormat & GetOpalPCM16S_48KHZ();
01403 extern const OpalAudioFormat & GetOpalL16_MONO_8KHZ();
01404 extern const OpalAudioFormat & GetOpalL16_STEREO_8KHZ();
01405 extern const OpalAudioFormat & GetOpalL16_MONO_16KHZ();
01406 extern const OpalAudioFormat & GetOpalL16_STEREO_16KHZ();
01407 extern const OpalAudioFormat & GetOpalL16_MONO_32KHZ();
01408 extern const OpalAudioFormat & GetOpalL16_STEREO_32KHZ();
01409 extern const OpalAudioFormat & GetOpalL16_MONO_48KHZ();
01410 extern const OpalAudioFormat & GetOpalL16_STEREO_48KHZ();
01411 extern const OpalAudioFormat & GetOpalG711_ULAW_64K();
01412 extern const OpalAudioFormat & GetOpalG711_ALAW_64K();
01413 extern const OpalAudioFormat & GetOpalG722();
01414 extern const OpalAudioFormat & GetOpalG7221();
01415 extern const OpalAudioFormat & GetOpalG7222();
01416 extern const OpalAudioFormat & GetOpalG726_40K();
01417 extern const OpalAudioFormat & GetOpalG726_32K();
01418 extern const OpalAudioFormat & GetOpalG726_24K();
01419 extern const OpalAudioFormat & GetOpalG726_16K();
01420 extern const OpalAudioFormat & GetOpalG728();
01421 extern const OpalAudioFormat & GetOpalG729();
01422 extern const OpalAudioFormat & GetOpalG729A();
01423 extern const OpalAudioFormat & GetOpalG729B();
01424 extern const OpalAudioFormat & GetOpalG729AB();
01425 extern const OpalAudioFormat & GetOpalG7231_6k3();
01426 extern const OpalAudioFormat & GetOpalG7231_5k3();
01427 extern const OpalAudioFormat & GetOpalG7231A_6k3();
01428 extern const OpalAudioFormat & GetOpalG7231A_5k3();
01429 extern const OpalAudioFormat & GetOpalGSM0610();
01430 extern const OpalAudioFormat & GetOpalGSMAMR();
01431 extern const OpalAudioFormat & GetOpaliLBC();
01432 
01433 extern const OpalMediaFormat & GetOpalRFC2833();
01434 
01435 #if OPAL_T38_CAPABILITY
01436 extern const OpalMediaFormat & GetOpalCiscoNSE();
01437 extern const OpalMediaFormat & GetOpalT38();
01438 #endif
01439 
01440 
01441 #define OpalPCM16          GetOpalPCM16()
01442 #define OpalPCM16S         GetOpalPCM16S()
01443 #define OpalPCM16_16KHZ    GetOpalPCM16_16KHZ()
01444 #define OpalPCM16S_16KHZ   GetOpalPCM16S_16KHZ()
01445 #define OpalPCM16_32KHZ    GetOpalPCM16_32KHZ()
01446 #define OpalPCM16S_32KHZ   GetOpalPCM16S_32KHZ()
01447 #define OpalPCM16_48KHZ    GetOpalPCM16_48KHZ()
01448 #define OpalPCM16S_48KHZ   GetOpalPCM16S_48KHZ()
01449 #define OpalL16_MONO_8KHZ  GetOpalL16_MONO_8KHZ()
01450 #define OpalL16_STEREO_8KHZ GetOpalL16_STEREO_8KHZ()
01451 #define OpalL16_MONO_16KHZ GetOpalL16_MONO_16KHZ()
01452 #define OpalL16_STEREO_16KHZ GetOpalL16_STEREO_16KHZ()
01453 #define OpalL16_MONO_32KHZ GetOpalL16_MONO_32KHZ()
01454 #define OpalL16_STEREO_32KHZ GetOpalL16_STEREO_32KHZ()
01455 #define OpalL16_MONO_48KHZ GetOpalL16_MONO_48KHZ()
01456 #define OpalL16_STEREO_48KHZ GetOpalL16_STEREO_48KHZ()
01457 #define OpalG711_ULAW_64K  GetOpalG711_ULAW_64K()
01458 #define OpalG711_ALAW_64K  GetOpalG711_ALAW_64K()
01459 #define OpalG722           GetOpalG722()
01460 #define OpalG7221          GetOpalG7221()
01461 #define OpalG7222          GetOpalG7222()
01462 #define OpalG726_40K       GetOpalG726_40K()
01463 #define OpalG726_32K       GetOpalG726_32K()
01464 #define OpalG726_24K       GetOpalG726_24K()
01465 #define OpalG726_16K       GetOpalG726_16K()
01466 #define OpalG728           GetOpalG728()
01467 #define OpalG729           GetOpalG729()
01468 #define OpalG729A          GetOpalG729A()
01469 #define OpalG729B          GetOpalG729B()
01470 #define OpalG729AB         GetOpalG729AB()
01471 #define OpalG7231_6k3      GetOpalG7231_6k3()
01472 #define OpalG7231_5k3      GetOpalG7231_5k3()
01473 #define OpalG7231A_6k3     GetOpalG7231A_6k3()
01474 #define OpalG7231A_5k3     GetOpalG7231A_5k3()
01475 #define OpalGSM0610        GetOpalGSM0610()
01476 #define OpalGSMAMR         GetOpalGSMAMR()
01477 #define OpaliLBC           GetOpaliLBC()
01478 #define OpalRFC2833        GetOpalRFC2833()
01479 #define OpalCiscoNSE       GetOpalCiscoNSE()
01480 #define OpalT38            GetOpalT38()
01481 
01482 #define OpalL16Mono8kHz    OpalL16_MONO_8KHZ
01483 #define OpalL16Mono16kHz   OpalL16_MONO_16KHZ
01484 #define OpalG711uLaw       OpalG711_ULAW_64K
01485 #define OpalG711ALaw       OpalG711_ALAW_64K
01486 
01487 #define OPAL_T140             "T.140"
01488 #define OpalT140              GetOpalT140()
01489 extern const OpalMediaFormat & GetOpalT140();
01490 
01491 #if OPAL_HAS_MSRP
01492 #define OPAL_MSRP           "MSRP"
01493 #define OpalMSRP            GetOpalMSRP()
01494 extern const OpalMediaFormat & GetOpalMSRP();
01495 #endif
01496 
01497 #if OPAL_HAS_SIPIM
01498 #define OPAL_SIPIM             "SIP-IM"
01499 #define OpalSIPIM              GetOpalSIPIM()
01500 extern const OpalMediaFormat & GetOpalSIPIM();
01501 #endif
01502 
01503 #ifdef _MSC_VER
01504 #if _MSC_VER < 1300
01505 #pragma warning(default:4663)
01506 #endif
01507 #endif
01508 
01509 #endif  // OPAL_OPAL_MEDIAFMT_H
01510 
01511 
01512 // End of File ///////////////////////////////////////////////////////////////