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
00315 void NotifyCommand(
00316 OpalMediaCommand & command
00317 ) const { if (commandNotifier != PNotifier()) commandNotifier(command, m_sessionID); }
00318
00320 unsigned GetSessionID() const { return m_sessionID; }
00321
00323 void SetSessionID(unsigned id) { m_sessionID = id; }
00324
00327 virtual void SetInstanceID(
00328 const BYTE * instance,
00329 unsigned instanceLen
00330 );
00331
00332 RTP_DataFrame::PayloadTypes GetPayloadType(
00333 PBoolean input
00334 ) const;
00335
00336 virtual bool AcceptComfortNoise() const { return false; }
00337 virtual bool AcceptEmptyPayload() const { return acceptEmptyPayload; }
00338 virtual bool AcceptOtherPayloads() const { return acceptOtherPayloads; }
00339
00340 #if OPAL_STATISTICS
00341 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00342 #endif
00343
00344
00345 protected:
00346 PINDEX maxOutputSize;
00347 PNotifier commandNotifier;
00348 PMutex updateMutex;
00349
00350 unsigned m_sessionID;
00351 bool outputIsRTP, inputIsRTP;
00352 bool acceptEmptyPayload;
00353 bool acceptOtherPayloads;
00354 };
00355
00356
00364 class OpalFramedTranscoder : public OpalTranscoder
00365 {
00366 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00367 public:
00372 OpalFramedTranscoder(
00373 const OpalMediaFormat & inputMediaFormat,
00374 const OpalMediaFormat & outputMediaFormat
00375 );
00377
00393 virtual bool UpdateMediaFormats(
00394 const OpalMediaFormat & inputMediaFormat,
00395 const OpalMediaFormat & outputMediaFormat
00396 );
00397
00404 virtual PINDEX GetOptimalDataFrameSize(
00405 PBoolean input
00406 ) const;
00407
00414 virtual PBoolean Convert(
00415 const RTP_DataFrame & input,
00416 RTP_DataFrame & output
00417 );
00418
00422 virtual PBoolean ConvertFrame(
00423 const BYTE * input,
00424 BYTE * output
00425 );
00426 virtual PBoolean ConvertFrame(
00427 const BYTE * input,
00428 PINDEX & consumed,
00429 BYTE * output,
00430 PINDEX & created
00431 );
00432 virtual PBoolean ConvertSilentFrame(
00433 BYTE * output
00434 );
00436
00437 protected:
00438 void CalculateSizes();
00439
00440 PINDEX inputBytesPerFrame;
00441 PINDEX outputBytesPerFrame;
00442 PINDEX maxOutputDataSize;
00443 };
00444
00445
00453 class OpalStreamedTranscoder : public OpalTranscoder
00454 {
00455 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00456 public:
00461 OpalStreamedTranscoder(
00462 const OpalMediaFormat & inputMediaFormat,
00463 const OpalMediaFormat & outputMediaFormat,
00464 unsigned inputBits,
00465 unsigned outputBits
00466 );
00468
00477 virtual PINDEX GetOptimalDataFrameSize(
00478 PBoolean input
00479 ) const;
00480
00487 virtual PBoolean Convert(
00488 const RTP_DataFrame & input,
00489 RTP_DataFrame & output
00490 );
00491
00498 virtual int ConvertOne(int sample) const = 0;
00500
00501 protected:
00502 unsigned inputBitsPerSample;
00503 unsigned outputBitsPerSample;
00504 };
00505
00506
00508
00509 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00510 public:
00511 Opal_Linear16Mono_PCM();
00512 virtual int ConvertOne(int sample) const;
00513 };
00514
00515
00517
00518 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00519 public:
00520 Opal_PCM_Linear16Mono();
00521 virtual int ConvertOne(int sample) const;
00522 };
00523
00524
00526
00527 #define OPAL_REGISTER_L16_MONO() \
00528 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00529 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00530
00531
00532 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00533 {
00534 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00535 public:
00536 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00537 : OpalFramedTranscoder(inFormat, outFormat)
00538 { }
00539
00540 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00541 { return PFalse; }
00542 };
00543
00544 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00545 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00546 { \
00547 public: \
00548 Opal_Empty_##fmt##_Encoder() \
00549 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00550 { } \
00551 }; \
00552 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00553 { \
00554 public: \
00555 Opal_Empty_##fmt##_Decoder() \
00556 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00557 { } \
00558 }; \
00559
00560 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00561 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00562 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00563
00564 #endif // OPAL_OPAL_TRANSCODERS_H
00565
00566
00567