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_TRANSCODERS_H
00033 #define __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
00165 virtual bool UpdateMediaFormats(
00166 const OpalMediaFormat & inputMediaFormat,
00167 const OpalMediaFormat & outputMediaFormat
00168 );
00169
00176 virtual PBoolean ExecuteCommand(
00177 const OpalMediaCommand & command
00178 );
00179
00186 virtual PINDEX GetOptimalDataFrameSize(
00187 PBoolean input
00188 ) const = 0;
00189
00200 virtual PBoolean ConvertFrames(
00201 const RTP_DataFrame & input,
00202 RTP_DataFrameList & output
00203 );
00204
00211 virtual PBoolean Convert(
00212 const RTP_DataFrame & input,
00213 RTP_DataFrame & output
00214 ) = 0;
00215
00220 static OpalTranscoder * Create(
00221 const OpalMediaFormat & srcFormat,
00222 const OpalMediaFormat & dstFormat,
00223 const BYTE * instance = NULL,
00224 unsigned instanceLen = 0
00225 );
00226
00238 static bool SelectFormats(
00239 unsigned sessionID,
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 void SetRTPPayloadMap(const RTP_DataFrame::PayloadMapType & v)
00318 { payloadTypeMap = v; }
00319
00320 void AddRTPPayloadMapping(RTP_DataFrame::PayloadTypes from, RTP_DataFrame::PayloadTypes to)
00321 { payloadTypeMap.insert(RTP_DataFrame::PayloadMapType::value_type(from, to)); }
00322
00323 RTP_DataFrame::PayloadTypes GetPayloadType(
00324 PBoolean input
00325 ) const;
00326
00327 virtual bool AcceptComfortNoise() const { return false; }
00328 virtual bool AcceptEmptyPayload() const { return acceptEmptyPayload; }
00329
00330 #ifdef OPAL_STATISTICS
00331 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00332 #endif
00333
00334
00335 protected:
00336 PINDEX maxOutputSize;
00337 PNotifier commandNotifier;
00338 PMutex updateMutex;
00339
00340 RTP_DataFrame::PayloadMapType payloadTypeMap;
00341
00342 PBoolean outputIsRTP, inputIsRTP;
00343 bool acceptEmptyPayload;
00344 };
00345
00346
00354 class OpalFramedTranscoder : public OpalTranscoder
00355 {
00356 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00357 public:
00362 OpalFramedTranscoder(
00363 const OpalMediaFormat & inputMediaFormat,
00364 const OpalMediaFormat & outputMediaFormat,
00365 PINDEX inputBytesPerFrame,
00366 PINDEX outputBytesPerFrame
00367 );
00369
00384 virtual bool UpdateMediaFormats(
00385 const OpalMediaFormat & inputMediaFormat,
00386 const OpalMediaFormat & outputMediaFormat
00387 );
00388
00395 virtual PINDEX GetOptimalDataFrameSize(
00396 PBoolean input
00397 ) const;
00398
00405 virtual PBoolean Convert(
00406 const RTP_DataFrame & input,
00407 RTP_DataFrame & output
00408 );
00409
00413 virtual PBoolean ConvertFrame(
00414 const BYTE * input,
00415 BYTE * output
00416 );
00417 virtual PBoolean ConvertFrame(
00418 const BYTE * input,
00419 PINDEX & consumed,
00420 BYTE * output,
00421 PINDEX & created
00422 );
00423 virtual PBoolean ConvertSilentFrame(
00424 BYTE * output
00425 );
00427
00428 protected:
00429 PINDEX inputBytesPerFrame;
00430 PINDEX outputBytesPerFrame;
00431
00432
00433 };
00434
00435
00443 class OpalStreamedTranscoder : public OpalTranscoder
00444 {
00445 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00446 public:
00451 OpalStreamedTranscoder(
00452 const OpalMediaFormat & inputMediaFormat,
00453 const OpalMediaFormat & outputMediaFormat,
00454 unsigned inputBits,
00455 unsigned outputBits
00456 );
00458
00467 virtual PINDEX GetOptimalDataFrameSize(
00468 PBoolean input
00469 ) const;
00470
00477 virtual PBoolean Convert(
00478 const RTP_DataFrame & input,
00479 RTP_DataFrame & output
00480 );
00481
00488 virtual int ConvertOne(int sample) const = 0;
00490
00491 protected:
00492 unsigned inputBitsPerSample;
00493 unsigned outputBitsPerSample;
00494 };
00495
00496
00498
00499 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00500 public:
00501 Opal_Linear16Mono_PCM();
00502 virtual int ConvertOne(int sample) const;
00503 };
00504
00505
00507
00508 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00509 public:
00510 Opal_PCM_Linear16Mono();
00511 virtual int ConvertOne(int sample) const;
00512 };
00513
00514
00516
00517 #define OPAL_REGISTER_L16_MONO() \
00518 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00519 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00520
00521
00522 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00523 {
00524 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00525 public:
00526 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00527 : OpalFramedTranscoder(inFormat, outFormat, 100, 100)
00528 { }
00529
00530 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00531 { return PFalse; }
00532 };
00533
00534 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00535 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00536 { \
00537 public: \
00538 Opal_Empty_##fmt##_Encoder() \
00539 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00540 { } \
00541 }; \
00542 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00543 { \
00544 public: \
00545 Opal_Empty_##fmt##_Decoder() \
00546 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00547 { } \
00548 }; \
00549
00550 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00551 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00552 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00553
00554 #endif // __OPAL_TRANSCODERS_H
00555
00556
00557