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 #include <opal/mediasession.h>
00044
00045 #include <rtp/rtp.h>
00046
00047 class RTP_DataFrame;
00048 class OpalTranscoder;
00049
00050
00052
00056 class OpalMediaFormatPair : public PObject
00057 {
00058 PCLASSINFO(OpalMediaFormatPair, PObject);
00059 public:
00064 OpalMediaFormatPair(
00065 const OpalMediaFormat & inputMediaFormat,
00066 const OpalMediaFormat & outputMediaFormat
00067 );
00069
00076 void PrintOn(
00077 ostream & strm
00078 ) const;
00079
00091 virtual Comparison Compare(
00092 const PObject & obj
00093 ) const;
00095
00100 const OpalMediaFormat & GetInputFormat() const { return inputMediaFormat; }
00101
00104 const OpalMediaFormat & GetOutputFormat() const { return outputMediaFormat; }
00106
00107 protected:
00108 OpalMediaFormat inputMediaFormat;
00109 OpalMediaFormat outputMediaFormat;
00110 };
00111
00112
00113 typedef std::pair<PString, PString> OpalTranscoderKey;
00114 typedef PFactory<OpalTranscoder, OpalTranscoderKey> OpalTranscoderFactory;
00115 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T OpalTranscoderList;
00116 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T::iterator OpalTranscoderIterator;
00117
00118 __inline OpalTranscoderKey MakeOpalTranscoderKey(const OpalMediaFormat & from, const OpalMediaFormat & to)
00119 {
00120 return OpalTranscoderKey(from.GetName(), to.GetName());
00121 }
00122
00123 __inline OpalTranscoderKey MakeOpalTranscoderKey(const char * from, const char * to)
00124 {
00125 return OpalTranscoderKey(from, to);
00126 }
00127
00128 #define OPAL_REGISTER_TRANSCODER(cls, input, output) \
00129 PFACTORY_CREATE(OpalTranscoderFactory, cls, MakeOpalTranscoderKey(input, output), false)
00130
00131
00138 class OpalTranscoder : public OpalMediaFormatPair
00139 {
00140 PCLASSINFO(OpalTranscoder, OpalMediaFormatPair);
00141 public:
00146 OpalTranscoder(
00147 const OpalMediaFormat & inputMediaFormat,
00148 const OpalMediaFormat & outputMediaFormat
00149 );
00151
00167 virtual bool UpdateMediaFormats(
00168 const OpalMediaFormat & inputMediaFormat,
00169 const OpalMediaFormat & outputMediaFormat
00170 );
00171
00180 virtual PBoolean ExecuteCommand(
00181 const OpalMediaCommand & command
00182 );
00183
00190 virtual PINDEX GetOptimalDataFrameSize(
00191 PBoolean input
00192 ) const = 0;
00193
00204 virtual PBoolean ConvertFrames(
00205 const RTP_DataFrame & input,
00206 RTP_DataFrameList & output
00207 );
00208
00215 virtual PBoolean Convert(
00216 const RTP_DataFrame & input,
00217 RTP_DataFrame & output
00218 ) = 0;
00219
00224 static OpalTranscoder * Create(
00225 const OpalMediaFormat & srcFormat,
00226 const OpalMediaFormat & dstFormat,
00227 const BYTE * instance = NULL,
00228 unsigned instanceLen = 0
00229 );
00230
00245 static bool SelectFormats(
00246 const OpalMediaType & mediaType,
00247 const OpalMediaFormatList & srcFormats,
00248 const OpalMediaFormatList & dstFormats,
00249 const OpalMediaFormatList & allFormats,
00250 OpalMediaFormat & srcFormat,
00251 OpalMediaFormat & dstFormat
00252 );
00253
00266 static bool FindIntermediateFormat(
00267 const OpalMediaFormat & srcFormat,
00268 const OpalMediaFormat & dstFormat,
00269 OpalMediaFormat & intermediateFormat
00270 );
00271
00274 static OpalMediaFormatList GetDestinationFormats(
00275 const OpalMediaFormat & srcFormat
00276 );
00277
00280 static OpalMediaFormatList GetSourceFormats(
00281 const OpalMediaFormat & dstFormat
00282 );
00283
00286 static OpalMediaFormatList GetPossibleFormats(
00287 const OpalMediaFormatList & formats
00288 );
00290
00295 PINDEX GetMaxOutputSize() const { return maxOutputSize; }
00296
00299 void SetMaxOutputSize(
00300 PINDEX size
00301 ) { maxOutputSize = size; }
00302
00307 void SetCommandNotifier(
00308 const PNotifier & notifier
00309 ) { commandNotifier = notifier; }
00310
00315 const PNotifier & GetCommandNotifier() const { return commandNotifier; }
00316
00318 void NotifyCommand(
00319 const OpalMediaCommand & command
00320 ) const;
00321
00323 unsigned GetSessionID() const { return m_sessionID; }
00324
00326 void SetSessionID(unsigned id) { m_sessionID = id; }
00327
00330 virtual void SetInstanceID(
00331 const BYTE * instance,
00332 unsigned instanceLen
00333 );
00334
00335 RTP_DataFrame::PayloadTypes GetPayloadType(
00336 PBoolean input
00337 ) const;
00338
00339 virtual bool AcceptComfortNoise() const { return false; }
00340 virtual bool AcceptEmptyPayload() const { return acceptEmptyPayload; }
00341 virtual bool AcceptOtherPayloads() const { return acceptOtherPayloads; }
00342
00343 #if OPAL_STATISTICS
00344 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00345 #endif
00346
00347 void CopyTimestamp(RTP_DataFrame & dst, const RTP_DataFrame & src, bool inToOut) const;
00349
00350 protected:
00351 PINDEX maxOutputSize;
00352 PNotifier commandNotifier;
00353 PMutex updateMutex;
00354
00355 unsigned m_sessionID;
00356 bool outputIsRTP, inputIsRTP;
00357 bool acceptEmptyPayload;
00358 bool acceptOtherPayloads;
00359 unsigned m_inClockRate;
00360 unsigned m_outClockRate;
00361 };
00362
00363
00371 class OpalFramedTranscoder : public OpalTranscoder
00372 {
00373 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00374 public:
00379 OpalFramedTranscoder(
00380 const OpalMediaFormat & inputMediaFormat,
00381 const OpalMediaFormat & outputMediaFormat
00382 );
00384
00400 virtual bool UpdateMediaFormats(
00401 const OpalMediaFormat & inputMediaFormat,
00402 const OpalMediaFormat & outputMediaFormat
00403 );
00404
00411 virtual PINDEX GetOptimalDataFrameSize(
00412 PBoolean input
00413 ) const;
00414
00421 virtual PBoolean Convert(
00422 const RTP_DataFrame & input,
00423 RTP_DataFrame & output
00424 );
00425
00429 virtual PBoolean ConvertFrame(
00430 const BYTE * input,
00431 BYTE * output
00432 );
00433 virtual PBoolean ConvertFrame(
00434 const BYTE * input,
00435 PINDEX & consumed,
00436 BYTE * output,
00437 PINDEX & created
00438 );
00439 virtual PBoolean ConvertSilentFrame(
00440 BYTE * output
00441 );
00443
00444 protected:
00445 void CalculateSizes();
00446
00447 PINDEX inputBytesPerFrame;
00448 PINDEX outputBytesPerFrame;
00449 PINDEX maxOutputDataSize;
00450 };
00451
00452
00460 class OpalStreamedTranscoder : public OpalTranscoder
00461 {
00462 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00463 public:
00468 OpalStreamedTranscoder(
00469 const OpalMediaFormat & inputMediaFormat,
00470 const OpalMediaFormat & outputMediaFormat,
00471 unsigned inputBits,
00472 unsigned outputBits
00473 );
00475
00484 virtual PINDEX GetOptimalDataFrameSize(
00485 PBoolean input
00486 ) const;
00487
00494 virtual PBoolean Convert(
00495 const RTP_DataFrame & input,
00496 RTP_DataFrame & output
00497 );
00498
00505 virtual int ConvertOne(int sample) const = 0;
00507
00508 protected:
00509 unsigned inputBitsPerSample;
00510 unsigned outputBitsPerSample;
00511 };
00512
00513
00515
00516 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00517 public:
00518 Opal_Linear16Mono_PCM();
00519 virtual int ConvertOne(int sample) const;
00520 };
00521
00522
00524
00525 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00526 public:
00527 Opal_PCM_Linear16Mono();
00528 virtual int ConvertOne(int sample) const;
00529 };
00530
00531
00533
00534 #define OPAL_REGISTER_L16_MONO() \
00535 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00536 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00537
00538
00539 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00540 {
00541 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00542 public:
00543 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00544 : OpalFramedTranscoder(inFormat, outFormat)
00545 { }
00546
00547 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00548 { return false; }
00549 };
00550
00551 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00552 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00553 { \
00554 public: \
00555 Opal_Empty_##fmt##_Encoder() \
00556 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00557 { } \
00558 }; \
00559 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00560 { \
00561 public: \
00562 Opal_Empty_##fmt##_Decoder() \
00563 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00564 { } \
00565 }; \
00566
00567 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00568 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00569 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00570
00571 #endif // OPAL_OPAL_TRANSCODERS_H
00572
00573
00574