00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #ifndef OPAL_OPAL_TRANSCODERS_H
00033 #define OPAL_OPAL_TRANSCODERS_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #include <opal/buildopts.h>
00040 
00041 #include <opal/mediafmt.h>
00042 #include <opal/mediacmd.h>
00043 
00044 #include <rtp/rtp.h>
00045 
00046 class RTP_DataFrame;
00047 class OpalTranscoder;
00048 
00049 
00051 
00055 class OpalMediaFormatPair : public PObject
00056 {
00057     PCLASSINFO(OpalMediaFormatPair, PObject);
00058   public:
00063     OpalMediaFormatPair(
00064       const OpalMediaFormat & inputMediaFormat,  
00065       const OpalMediaFormat & outputMediaFormat  
00066     );
00068 
00075     void PrintOn(
00076       ostream & strm    
00077     ) const;
00078 
00090     virtual Comparison Compare(
00091       const PObject & obj   
00092     ) const;
00094 
00099     const OpalMediaFormat & GetInputFormat() const { return inputMediaFormat; }
00100 
00103     const OpalMediaFormat & GetOutputFormat() const { return outputMediaFormat; }
00105 
00106   protected:
00107     OpalMediaFormat inputMediaFormat;
00108     OpalMediaFormat outputMediaFormat;
00109 };
00110 
00111 
00112 typedef std::pair<PString, PString>                                      OpalTranscoderKey;
00113 typedef PFactory<OpalTranscoder, OpalTranscoderKey>                      OpalTranscoderFactory;
00114 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T           OpalTranscoderList;
00115 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T::iterator OpalTranscoderIterator;
00116 
00117 __inline OpalTranscoderKey MakeOpalTranscoderKey(const OpalMediaFormat & from, const OpalMediaFormat & to)
00118 {
00119   return OpalTranscoderKey(from.GetName(), to.GetName());
00120 }
00121 
00122 __inline OpalTranscoderKey MakeOpalTranscoderKey(const char * from, const char * to)
00123 {
00124   return OpalTranscoderKey(from, to);
00125 }
00126 
00127 #define OPAL_REGISTER_TRANSCODER(cls, input, output) \
00128   OpalTranscoderFactory::Worker<cls> OpalTranscoder_##cls(MakeOpalTranscoderKey(input, output))
00129 
00130 
00137 class OpalTranscoder : public OpalMediaFormatPair
00138 {
00139     PCLASSINFO(OpalTranscoder, OpalMediaFormatPair);
00140   public:
00145     OpalTranscoder(
00146       const OpalMediaFormat & inputMediaFormat,  
00147       const OpalMediaFormat & outputMediaFormat  
00148     );
00150 
00166     virtual bool UpdateMediaFormats(
00167       const OpalMediaFormat & inputMediaFormat,  
00168       const OpalMediaFormat & outputMediaFormat  
00169     );
00170 
00177     virtual PBoolean ExecuteCommand(
00178       const OpalMediaCommand & command    
00179     );
00180 
00187     virtual PINDEX GetOptimalDataFrameSize(
00188       PBoolean input      
00189     ) const = 0;
00190 
00201     virtual PBoolean ConvertFrames(
00202       const RTP_DataFrame & input,  
00203       RTP_DataFrameList & output    
00204     );
00205 
00212     virtual PBoolean Convert(
00213       const RTP_DataFrame & input,  
00214       RTP_DataFrame & output        
00215     ) = 0;
00216 
00221     static OpalTranscoder * Create(
00222       const OpalMediaFormat & srcFormat,  
00223       const OpalMediaFormat & dstFormat,  
00224       const BYTE * instance = NULL,       
00225       unsigned instanceLen = 0            
00226     );
00227 
00239     static bool SelectFormats(
00240       const OpalMediaFormatList & srcFormats, 
00241       const OpalMediaFormatList & dstFormats, 
00242       const OpalMediaFormatList & allFormats, 
00243       OpalMediaFormat & srcFormat,            
00244       OpalMediaFormat & dstFormat             
00245     );
00246 
00259     static bool FindIntermediateFormat(
00260       const OpalMediaFormat & srcFormat,    
00261       const OpalMediaFormat & dstFormat,    
00262       OpalMediaFormat & intermediateFormat  
00263     );
00264 
00267     static OpalMediaFormatList GetDestinationFormats(
00268       const OpalMediaFormat & srcFormat    
00269     );
00270 
00273     static OpalMediaFormatList GetSourceFormats(
00274       const OpalMediaFormat & dstFormat    
00275     );
00276 
00279     static OpalMediaFormatList GetPossibleFormats(
00280       const OpalMediaFormatList & formats    
00281     );
00283 
00288     PINDEX GetMaxOutputSize() const { return maxOutputSize; }
00289 
00292     void SetMaxOutputSize(
00293       PINDEX size
00294     ) { maxOutputSize = size; }
00295 
00300     void SetCommandNotifier(
00301       const PNotifier & notifier    
00302     ) { commandNotifier = notifier; }
00303 
00308     const PNotifier & GetCommandNotifier() const { return commandNotifier; }
00309 
00312     virtual void SetInstanceID(
00313       const BYTE * instance,              
00314       unsigned instanceLen                
00315     );
00316 
00317     RTP_DataFrame::PayloadTypes GetPayloadType(
00318       PBoolean input      
00319     ) const;
00320 
00321     virtual bool AcceptComfortNoise() const  { return false; }
00322     virtual bool AcceptEmptyPayload() const  { return acceptEmptyPayload; }
00323     virtual bool AcceptOtherPayloads() const { return acceptOtherPayloads; }
00324 
00325 #if OPAL_STATISTICS
00326     virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00327 #endif
00328 
00329 
00330   protected:
00331     PINDEX    maxOutputSize;
00332     PNotifier commandNotifier;
00333     PMutex    updateMutex;
00334 
00335     PBoolean outputIsRTP, inputIsRTP;
00336     bool acceptEmptyPayload;
00337     bool acceptOtherPayloads;
00338 };
00339 
00340 
00348 class OpalFramedTranscoder : public OpalTranscoder
00349 {
00350     PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00351   public:
00356     OpalFramedTranscoder(
00357       const OpalMediaFormat & inputMediaFormat,  
00358       const OpalMediaFormat & outputMediaFormat, 
00359       PINDEX inputBytesPerFrame,  
00360       PINDEX outputBytesPerFrame  
00361     );
00363 
00379     virtual bool UpdateMediaFormats(
00380       const OpalMediaFormat & inputMediaFormat,  
00381       const OpalMediaFormat & outputMediaFormat  
00382     );
00383 
00390     virtual PINDEX GetOptimalDataFrameSize(
00391       PBoolean input      
00392     ) const;
00393 
00400     virtual PBoolean Convert(
00401       const RTP_DataFrame & input,  
00402       RTP_DataFrame & output        
00403     );
00404 
00408     virtual PBoolean ConvertFrame(
00409       const BYTE * input,   
00410       BYTE * output         
00411     );
00412     virtual PBoolean ConvertFrame(
00413       const BYTE * input,   
00414       PINDEX & consumed,    
00415       BYTE * output,        
00416       PINDEX & created      
00417     );
00418     virtual PBoolean ConvertSilentFrame(
00419       BYTE * output         
00420     );
00422 
00423   protected:
00424     PINDEX     inputBytesPerFrame;
00425     PINDEX     outputBytesPerFrame;
00426     PINDEX     maxOutputDataSize;
00427 };
00428 
00429 
00437 class OpalStreamedTranscoder : public OpalTranscoder
00438 {
00439     PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00440   public:
00445     OpalStreamedTranscoder(
00446       const OpalMediaFormat & inputMediaFormat,  
00447       const OpalMediaFormat & outputMediaFormat, 
00448       unsigned inputBits,           
00449       unsigned outputBits           
00450     );
00452 
00461     virtual PINDEX GetOptimalDataFrameSize(
00462       PBoolean input      
00463     ) const;
00464 
00471     virtual PBoolean Convert(
00472       const RTP_DataFrame & input,  
00473       RTP_DataFrame & output        
00474     );
00475 
00482     virtual int ConvertOne(int sample) const = 0;
00484 
00485   protected:
00486     unsigned inputBitsPerSample;
00487     unsigned outputBitsPerSample;
00488 };
00489 
00490 
00492 
00493 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00494   public:
00495     Opal_Linear16Mono_PCM();
00496     virtual int ConvertOne(int sample) const;
00497 };
00498 
00499 
00501 
00502 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00503   public:
00504     Opal_PCM_Linear16Mono();
00505     virtual int ConvertOne(int sample) const;
00506 };
00507 
00508 
00510 
00511 #define OPAL_REGISTER_L16_MONO() \
00512   OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00513   OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16,         OpalL16_MONO_8KHZ)
00514 
00515 
00516 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00517 {
00518   PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00519   public:
00520     OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00521       : OpalFramedTranscoder(inFormat, outFormat, 100, 100)
00522     {  }
00523 
00524     PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00525     { return PFalse; }
00526 };
00527 
00528 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00529 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00530 { \
00531   public: \
00532     Opal_Empty_##fmt##_Encoder() \
00533       : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00534     { } \
00535 }; \
00536 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00537 { \
00538   public: \
00539     Opal_Empty_##fmt##_Decoder() \
00540       : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00541     { } \
00542 }; \
00543 
00544 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00545 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00546 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt,       OpalPCM16); \
00547 
00548 #endif // OPAL_OPAL_TRANSCODERS_H
00549 
00550 
00551