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 PFACTORY_CREATE(OpalTranscoderFactory, cls, MakeOpalTranscoderKey(input, output), false)
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
00242 static bool SelectFormats(
00243 const OpalMediaType & mediaType,
00244 const OpalMediaFormatList & srcFormats,
00245 const OpalMediaFormatList & dstFormats,
00246 const OpalMediaFormatList & allFormats,
00247 OpalMediaFormat & srcFormat,
00248 OpalMediaFormat & dstFormat
00249 );
00250
00263 static bool FindIntermediateFormat(
00264 const OpalMediaFormat & srcFormat,
00265 const OpalMediaFormat & dstFormat,
00266 OpalMediaFormat & intermediateFormat
00267 );
00268
00271 static OpalMediaFormatList GetDestinationFormats(
00272 const OpalMediaFormat & srcFormat
00273 );
00274
00277 static OpalMediaFormatList GetSourceFormats(
00278 const OpalMediaFormat & dstFormat
00279 );
00280
00283 static OpalMediaFormatList GetPossibleFormats(
00284 const OpalMediaFormatList & formats
00285 );
00287
00292 PINDEX GetMaxOutputSize() const { return maxOutputSize; }
00293
00296 void SetMaxOutputSize(
00297 PINDEX size
00298 ) { maxOutputSize = size; }
00299
00304 void SetCommandNotifier(
00305 const PNotifier & notifier
00306 ) { commandNotifier = notifier; }
00307
00312 const PNotifier & GetCommandNotifier() const { return commandNotifier; }
00313
00316 virtual void SetInstanceID(
00317 const BYTE * instance,
00318 unsigned instanceLen
00319 );
00320
00321 RTP_DataFrame::PayloadTypes GetPayloadType(
00322 PBoolean input
00323 ) const;
00324
00325 virtual bool AcceptComfortNoise() const { return false; }
00326 virtual bool AcceptEmptyPayload() const { return acceptEmptyPayload; }
00327 virtual bool AcceptOtherPayloads() const { return acceptOtherPayloads; }
00328
00329 #if OPAL_STATISTICS
00330 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00331 #endif
00332
00333
00334 protected:
00335 PINDEX maxOutputSize;
00336 PNotifier commandNotifier;
00337 PMutex updateMutex;
00338
00339 PBoolean outputIsRTP, inputIsRTP;
00340 bool acceptEmptyPayload;
00341 bool acceptOtherPayloads;
00342 };
00343
00344
00352 class OpalFramedTranscoder : public OpalTranscoder
00353 {
00354 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00355 public:
00360 OpalFramedTranscoder(
00361 const OpalMediaFormat & inputMediaFormat,
00362 const OpalMediaFormat & outputMediaFormat,
00363 PINDEX inputBytesPerFrame,
00364 PINDEX outputBytesPerFrame
00365 );
00367
00383 virtual bool UpdateMediaFormats(
00384 const OpalMediaFormat & inputMediaFormat,
00385 const OpalMediaFormat & outputMediaFormat
00386 );
00387
00394 virtual PINDEX GetOptimalDataFrameSize(
00395 PBoolean input
00396 ) const;
00397
00404 virtual PBoolean Convert(
00405 const RTP_DataFrame & input,
00406 RTP_DataFrame & output
00407 );
00408
00412 virtual PBoolean ConvertFrame(
00413 const BYTE * input,
00414 BYTE * output
00415 );
00416 virtual PBoolean ConvertFrame(
00417 const BYTE * input,
00418 PINDEX & consumed,
00419 BYTE * output,
00420 PINDEX & created
00421 );
00422 virtual PBoolean ConvertSilentFrame(
00423 BYTE * output
00424 );
00426
00427 protected:
00428 PINDEX inputBytesPerFrame;
00429 PINDEX outputBytesPerFrame;
00430 PINDEX maxOutputDataSize;
00431 };
00432
00433
00441 class OpalStreamedTranscoder : public OpalTranscoder
00442 {
00443 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00444 public:
00449 OpalStreamedTranscoder(
00450 const OpalMediaFormat & inputMediaFormat,
00451 const OpalMediaFormat & outputMediaFormat,
00452 unsigned inputBits,
00453 unsigned outputBits
00454 );
00456
00465 virtual PINDEX GetOptimalDataFrameSize(
00466 PBoolean input
00467 ) const;
00468
00475 virtual PBoolean Convert(
00476 const RTP_DataFrame & input,
00477 RTP_DataFrame & output
00478 );
00479
00486 virtual int ConvertOne(int sample) const = 0;
00488
00489 protected:
00490 unsigned inputBitsPerSample;
00491 unsigned outputBitsPerSample;
00492 };
00493
00494
00496
00497 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00498 public:
00499 Opal_Linear16Mono_PCM();
00500 virtual int ConvertOne(int sample) const;
00501 };
00502
00503
00505
00506 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00507 public:
00508 Opal_PCM_Linear16Mono();
00509 virtual int ConvertOne(int sample) const;
00510 };
00511
00512
00514
00515 #define OPAL_REGISTER_L16_MONO() \
00516 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00517 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00518
00519
00520 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00521 {
00522 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00523 public:
00524 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00525 : OpalFramedTranscoder(inFormat, outFormat, 100, 100)
00526 { }
00527
00528 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00529 { return PFalse; }
00530 };
00531
00532 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00533 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00534 { \
00535 public: \
00536 Opal_Empty_##fmt##_Encoder() \
00537 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00538 { } \
00539 }; \
00540 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00541 { \
00542 public: \
00543 Opal_Empty_##fmt##_Decoder() \
00544 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00545 { } \
00546 }; \
00547
00548 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00549 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00550 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00551
00552 #endif // OPAL_OPAL_TRANSCODERS_H
00553
00554
00555