transcoders.h

Go to the documentation of this file.
00001 /*
00002  * transcoders.h
00003  *
00004  * Abstractions for converting media from one format to another.
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 Phone Abstraction Library.
00022  *
00023  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00024  *
00025  * Contributor(s): ______________________________________.
00026  *
00027  * $Log: transcoders.h,v $
00028  * Revision 2.29  2007/10/08 01:45:16  rjongbloed
00029  * Fixed bad virtual function causing uninitialised variable whcih prevented video from working.
00030  * Some more clean ups.
00031  *
00032  * Revision 2.28  2007/09/19 10:43:00  csoutheren
00033  * Exposed G.7231 capability class
00034  * Added macros to create empty transcoders and capabilities
00035  *
00036  * Revision 2.27  2007/09/10 03:15:04  rjongbloed
00037  * Fixed issues in creating and subsequently using correctly unique
00038  *   payload types in OpalMediaFormat instances and transcoders.
00039  *
00040  * Revision 2.26  2007/06/22 05:47:19  rjongbloed
00041  * Fixed setting of output RTP payload types on plug in video codecs.
00042  *
00043  * Revision 2.25  2007/03/29 05:22:32  csoutheren
00044  * Add extra logging
00045  *
00046  * Revision 2.24  2006/11/29 06:28:57  csoutheren
00047  * Add ability call codec control functions on all transcoders
00048  *
00049  * Revision 2.23  2006/04/09 12:12:54  rjongbloed
00050  * Changed the media format option merging to include the transcoder formats.
00051  *
00052  * Revision 2.22  2006/02/02 07:02:57  csoutheren
00053  * Added RTP payload map to transcoders and connections to allow remote SIP endpoints
00054  * to change the payload type used for outgoing RTP.
00055  *
00056  * Revision 2.21  2005/12/30 14:33:12  dsandras
00057  * Added support for Packet Loss Concealment frames for framed codecs supporting it similarly to what was done for OpenH323.
00058  *
00059  * Revision 2.20  2005/11/30 13:35:26  csoutheren
00060  * Changed tags for Doxygen
00061  *
00062  * Revision 2.19  2005/09/06 12:44:49  rjongbloed
00063  * Many fixes to finalise the video processing: merging remote media
00064  *
00065  * Revision 2.18  2005/09/04 06:23:38  rjongbloed
00066  * Added OpalMediaCommand mechanism (via PNotifier) for media streams
00067  *   and media transcoders to send commands back to remote.
00068  *
00069  * Revision 2.17  2005/09/02 14:31:40  csoutheren
00070  * Use inline function to work around compiler foo in gcc
00071  *
00072  * Revision 2.16  2005/08/31 13:19:25  rjongbloed
00073  * Added mechanism for controlling media (especially codecs) including
00074  *   changing the OpalMediaFormat option list (eg bit rate) and a completely
00075  *   new OpalMediaCommand abstraction for things like video fast update.
00076  *
00077  * Revision 2.15  2005/08/28 07:59:17  rjongbloed
00078  * Converted OpalTranscoder to use factory, requiring sme changes in making sure
00079  *   OpalMediaFormat instances are initialised before use.
00080  *
00081  * Revision 2.14  2005/03/19 04:08:10  csoutheren
00082  * Fixed warnings with gcc snapshot 4.1-20050313
00083  * Updated to configure 2.59
00084  *
00085  * Revision 2.13  2005/02/17 03:25:05  csoutheren
00086  * Added support for audio codecs that consume and produce variable size
00087  * frames, such as G.723.1
00088  *
00089  * Revision 2.12  2004/07/11 12:34:48  rjongbloed
00090  * Added function to get a list of all possible media formats that may be used given
00091  *   a list of media and taking into account all of the registered transcoders.
00092  *
00093  * Revision 2.11  2004/03/22 11:32:41  rjongbloed
00094  * Added new codec type for 16 bit Linear PCM as must distinguish between the internal
00095  *   format used by such things as the sound card and the RTP payload format which
00096  *   is always big endian.
00097  *
00098  * Revision 2.10  2004/03/11 06:54:27  csoutheren
00099  * Added ability to disable SIP or H.323 stacks
00100  *
00101  * Revision 2.9  2004/02/17 08:47:38  csoutheren
00102  * Changed codec loading macros to work with Linux
00103  *
00104  * Revision 2.8  2004/01/18 15:35:20  rjongbloed
00105  * More work on video support
00106  *
00107  * Revision 2.7  2003/06/02 02:59:43  rjongbloed
00108  * Changed transcoder search so uses destination list as preference order.
00109  *
00110  * Revision 2.6  2003/03/24 04:32:11  robertj
00111  * Fixed macro for transcoder with parameter (not used yet!)
00112  * Fixed so OPAL_NO_PARAM can be defined in other modules.
00113  *
00114  * Revision 2.5  2003/03/17 10:26:59  robertj
00115  * Added video support.
00116  *
00117  * Revision 2.4  2002/09/16 02:52:35  robertj
00118  * Added #define so can select if #pragma interface/implementation is used on
00119  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00120  *
00121  * Revision 2.3  2002/02/13 02:30:21  robertj
00122  * Added ability for media patch (and transcoders) to handle multiple RTP frames.
00123  *
00124  * Revision 2.2  2002/01/22 05:07:02  robertj
00125  * Added ability to get input and output media format names from transcoder.
00126  *
00127  * Revision 2.1  2001/08/01 05:52:08  robertj
00128  * Made OpalMediaFormatList class global to help with documentation.
00129  * Added functions to aid in determining if a transcoder can be used to get
00130  *   to another media format.
00131  * Fixed problem with streamed transcoder used in G.711.
00132  *
00133  * Revision 2.0  2001/07/27 15:48:24  robertj
00134  * Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
00135  *
00136  */
00137 
00138 #ifndef __OPAL_TRANSCODERS_H
00139 #define __OPAL_TRANSCODERS_H
00140 
00141 #ifdef P_USE_PRAGMA
00142 #pragma interface
00143 #endif
00144 
00145 #include <opal/buildopts.h>
00146 
00147 #include <opal/mediafmt.h>
00148 #include <opal/mediacmd.h>
00149 
00150 #include <rtp/rtp.h>
00151 
00152 class RTP_DataFrame;
00153 class OpalTranscoder;
00154 
00155 
00157 
00161 class OpalMediaFormatPair : public PObject
00162 {
00163     PCLASSINFO(OpalMediaFormatPair, PObject);
00164   public:
00169     OpalMediaFormatPair(
00170       const OpalMediaFormat & inputMediaFormat,  
00171       const OpalMediaFormat & outputMediaFormat  
00172     );
00174 
00181     void PrintOn(
00182       ostream & strm    
00183     ) const;
00184 
00196     virtual Comparison Compare(
00197       const PObject & obj   
00198     ) const;
00200 
00205     const OpalMediaFormat & GetInputFormat() const { return inputMediaFormat; }
00206 
00209     const OpalMediaFormat & GetOutputFormat() const { return outputMediaFormat; }
00211 
00212   protected:
00213     OpalMediaFormat inputMediaFormat;
00214     OpalMediaFormat outputMediaFormat;
00215 };
00216 
00217 
00218 typedef std::pair<PString, PString>                                      OpalTranscoderKey;
00219 typedef PFactory<OpalTranscoder, OpalTranscoderKey>                      OpalTranscoderFactory;
00220 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T           OpalTranscoderList;
00221 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T::iterator OpalTranscoderIterator;
00222 
00223 #define OPAL_REGISTER_TRANSCODER(cls, input, output) \
00224   OpalTranscoderFactory::Worker<cls> OpalTranscoder_##cls(OpalTranscoderKey(input, output))
00225 
00226 
00233 class OpalTranscoder : public OpalMediaFormatPair
00234 {
00235     PCLASSINFO(OpalTranscoder, OpalMediaFormatPair);
00236   public:
00241     OpalTranscoder(
00242       const OpalMediaFormat & inputMediaFormat,  
00243       const OpalMediaFormat & outputMediaFormat  
00244     );
00246 
00257     virtual BOOL UpdateOutputMediaFormat(
00258       const OpalMediaFormat & mediaFormat  
00259     );
00260 
00267     virtual BOOL ExecuteCommand(
00268       const OpalMediaCommand & command    
00269     );
00270 
00277     virtual PINDEX GetOptimalDataFrameSize(
00278       BOOL input      
00279     ) const = 0;
00280 
00291     virtual BOOL ConvertFrames(
00292       const RTP_DataFrame & input,  
00293       RTP_DataFrameList & output    
00294     );
00295 
00302     virtual BOOL Convert(
00303       const RTP_DataFrame & input,  
00304       RTP_DataFrame & output        
00305     ) = 0;
00306 
00311     static OpalTranscoder * Create(
00312       const OpalMediaFormat & srcFormat,  
00313       const OpalMediaFormat & dstFormat,  
00314       const BYTE * instance = NULL,       
00315       unsigned instanceLen = 0            
00316     );
00317 
00329     static BOOL SelectFormats(
00330       unsigned sessionID,               
00331       const OpalMediaFormatList & srcFormats, 
00332       const OpalMediaFormatList & dstFormats, 
00333       OpalMediaFormat & srcFormat,      
00334       OpalMediaFormat & dstFormat       
00335     );
00336 
00345     static BOOL FindIntermediateFormat(
00346       OpalMediaFormat & srcFormat,          
00347       OpalMediaFormat & dstFormat,          
00348       OpalMediaFormat & intermediateFormat  
00349     );
00350 
00353     static OpalMediaFormatList GetDestinationFormats(
00354       const OpalMediaFormat & srcFormat    
00355     );
00356 
00359     static OpalMediaFormatList GetSourceFormats(
00360       const OpalMediaFormat & dstFormat    
00361     );
00362 
00365     static OpalMediaFormatList GetPossibleFormats(
00366       const OpalMediaFormatList & formats    
00367     );
00369 
00374     PINDEX GetMaxOutputSize() const { return maxOutputSize; }
00375 
00378     void SetMaxOutputSize(
00379       PINDEX size
00380     ) { maxOutputSize = size; }
00381 
00386     void SetCommandNotifier(
00387       const PNotifier & notifier    
00388     ) { commandNotifier = notifier; }
00389 
00394     const PNotifier & GetCommandNotifier() const { return commandNotifier; }
00395 
00398     virtual void SetInstanceID(
00399       const BYTE * instance,              
00400       unsigned instanceLen                
00401     );
00402 
00403     void SetRTPPayloadMap(const RTP_DataFrame::PayloadMapType & v)
00404     { payloadTypeMap = v; }
00405 
00406     void AddRTPPayloadMapping(RTP_DataFrame::PayloadTypes from, RTP_DataFrame::PayloadTypes to)
00407     { payloadTypeMap.insert(RTP_DataFrame::PayloadMapType::value_type(from, to)); }
00408 
00409     RTP_DataFrame::PayloadTypes GetPayloadType(
00410       BOOL input      
00411     ) const;
00413 
00414   protected:
00415     PINDEX    maxOutputSize;
00416     bool      outputMediaFormatUpdated;
00417     PNotifier commandNotifier;
00418     PMutex    updateMutex;
00419 
00420     RTP_DataFrame::PayloadMapType payloadTypeMap;
00421 
00422     BOOL outputIsRTP, inputIsRTP;
00423 };
00424 
00425 
00433 class OpalFramedTranscoder : public OpalTranscoder
00434 {
00435     PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00436   public:
00441     OpalFramedTranscoder(
00442       const OpalMediaFormat & inputMediaFormat,  
00443       const OpalMediaFormat & outputMediaFormat, 
00444       PINDEX inputBytesPerFrame,  
00445       PINDEX outputBytesPerFrame  
00446     );
00448 
00457     virtual PINDEX GetOptimalDataFrameSize(
00458       BOOL input      
00459     ) const;
00460 
00467     virtual BOOL Convert(
00468       const RTP_DataFrame & input,  
00469       RTP_DataFrame & output        
00470     );
00471 
00475     virtual BOOL ConvertFrame(
00476       const BYTE * input,   
00477       BYTE * output         
00478     );
00479     virtual BOOL ConvertFrame(
00480       const BYTE * input,   
00481       PINDEX & consumed,    
00482       BYTE * output,        
00483       PINDEX & created      
00484     );
00485     virtual BOOL ConvertSilentFrame(
00486       BYTE * output         
00487     );
00489 
00490   protected:
00491     PINDEX     inputBytesPerFrame;
00492     PINDEX     outputBytesPerFrame;
00493     //PBYTEArray partialFrame;
00494     //PINDEX     partialBytes;
00495 };
00496 
00497 
00505 class OpalStreamedTranscoder : public OpalTranscoder
00506 {
00507     PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00508   public:
00513     OpalStreamedTranscoder(
00514       const OpalMediaFormat & inputMediaFormat,  
00515       const OpalMediaFormat & outputMediaFormat, 
00516       unsigned inputBits,           
00517       unsigned outputBits,          
00518       PINDEX   optimalSamples       
00519     );
00521 
00530     virtual PINDEX GetOptimalDataFrameSize(
00531       BOOL input      
00532     ) const;
00533 
00540     virtual BOOL Convert(
00541       const RTP_DataFrame & input,  
00542       RTP_DataFrame & output        
00543     );
00544 
00551     virtual int ConvertOne(int sample) const = 0;
00553 
00554   protected:
00555     unsigned inputBitsPerSample;
00556     unsigned outputBitsPerSample;
00557     PINDEX   optimalSamples;
00558 };
00559 
00560 
00562 
00563 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00564   public:
00565     Opal_Linear16Mono_PCM();
00566     virtual int ConvertOne(int sample) const;
00567 };
00568 
00569 
00571 
00572 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00573   public:
00574     Opal_PCM_Linear16Mono();
00575     virtual int ConvertOne(int sample) const;
00576 };
00577 
00578 
00580 
00581 #define OPAL_REGISTER_L16_MONO() \
00582   OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00583   OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16,         OpalL16_MONO_8KHZ)
00584 
00585 
00586 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00587 {
00588   PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00589   public:
00590     OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00591       : OpalFramedTranscoder(inFormat, outFormat, 100, 100)
00592     {  }
00593 
00594     BOOL ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00595     { return FALSE; }
00596 };
00597 
00598 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00599 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00600 { \
00601   public: \
00602     Opal_Empty_##fmt##_Encoder() \
00603       : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00604     { } \
00605 }; \
00606 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00607 { \
00608   public: \
00609     Opal_Empty_##fmt##_Decoder() \
00610       : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00611     { } \
00612 }; \
00613 
00614 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00615 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00616 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt,       OpalPCM16); \
00617 
00618 #endif // __OPAL_TRANSCODERS_H
00619 
00620 
00621 // End of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:33:41 2008 for OPAL by  doxygen 1.5.1