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 const OpalMediaCommand & command
00317 ) const;
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 unsigned m_inClockRate;
00355 unsigned m_outClockRate;
00356 };
00357
00358
00366 class OpalFramedTranscoder : public OpalTranscoder
00367 {
00368 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00369 public:
00374 OpalFramedTranscoder(
00375 const OpalMediaFormat & inputMediaFormat,
00376 const OpalMediaFormat & outputMediaFormat
00377 );
00379
00395 virtual bool UpdateMediaFormats(
00396 const OpalMediaFormat & inputMediaFormat,
00397 const OpalMediaFormat & outputMediaFormat
00398 );
00399
00406 virtual PINDEX GetOptimalDataFrameSize(
00407 PBoolean input
00408 ) const;
00409
00416 virtual PBoolean Convert(
00417 const RTP_DataFrame & input,
00418 RTP_DataFrame & output
00419 );
00420
00424 virtual PBoolean ConvertFrame(
00425 const BYTE * input,
00426 BYTE * output
00427 );
00428 virtual PBoolean ConvertFrame(
00429 const BYTE * input,
00430 PINDEX & consumed,
00431 BYTE * output,
00432 PINDEX & created
00433 );
00434 virtual PBoolean ConvertSilentFrame(
00435 BYTE * output
00436 );
00438
00439 protected:
00440 void CalculateSizes();
00441
00442 PINDEX inputBytesPerFrame;
00443 PINDEX outputBytesPerFrame;
00444 PINDEX maxOutputDataSize;
00445 };
00446
00447
00455 class OpalStreamedTranscoder : public OpalTranscoder
00456 {
00457 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00458 public:
00463 OpalStreamedTranscoder(
00464 const OpalMediaFormat & inputMediaFormat,
00465 const OpalMediaFormat & outputMediaFormat,
00466 unsigned inputBits,
00467 unsigned outputBits
00468 );
00470
00479 virtual PINDEX GetOptimalDataFrameSize(
00480 PBoolean input
00481 ) const;
00482
00489 virtual PBoolean Convert(
00490 const RTP_DataFrame & input,
00491 RTP_DataFrame & output
00492 );
00493
00500 virtual int ConvertOne(int sample) const = 0;
00502
00503 protected:
00504 unsigned inputBitsPerSample;
00505 unsigned outputBitsPerSample;
00506 };
00507
00508
00510
00511 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00512 public:
00513 Opal_Linear16Mono_PCM();
00514 virtual int ConvertOne(int sample) const;
00515 };
00516
00517
00519
00520 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00521 public:
00522 Opal_PCM_Linear16Mono();
00523 virtual int ConvertOne(int sample) const;
00524 };
00525
00526
00528
00529 #define OPAL_REGISTER_L16_MONO() \
00530 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00531 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00532
00533
00534 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00535 {
00536 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00537 public:
00538 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00539 : OpalFramedTranscoder(inFormat, outFormat)
00540 { }
00541
00542 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00543 { return false; }
00544 };
00545
00546 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00547 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00548 { \
00549 public: \
00550 Opal_Empty_##fmt##_Encoder() \
00551 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00552 { } \
00553 }; \
00554 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00555 { \
00556 public: \
00557 Opal_Empty_##fmt##_Decoder() \
00558 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00559 { } \
00560 }; \
00561
00562 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00563 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00564 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00565
00566 #endif // OPAL_OPAL_TRANSCODERS_H
00567
00568
00569