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 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
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
00239 static bool SelectFormats(
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 RTP_DataFrame::PayloadTypes GetPayloadType(
00318 PBoolean input
00319 ) const;
00320
00321 virtual bool AcceptComfortNoise() const { return false; }
00322 virtual bool AcceptEmptyPayload() const { return acceptEmptyPayload; }
00323 virtual bool AcceptOtherPayloads() const { return acceptOtherPayloads; }
00324
00325 #if OPAL_STATISTICS
00326 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00327 #endif
00328
00329
00330 protected:
00331 PINDEX maxOutputSize;
00332 PNotifier commandNotifier;
00333 PMutex updateMutex;
00334
00335 PBoolean outputIsRTP, inputIsRTP;
00336 bool acceptEmptyPayload;
00337 bool acceptOtherPayloads;
00338 };
00339
00340
00348 class OpalFramedTranscoder : public OpalTranscoder
00349 {
00350 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00351 public:
00356 OpalFramedTranscoder(
00357 const OpalMediaFormat & inputMediaFormat,
00358 const OpalMediaFormat & outputMediaFormat,
00359 PINDEX inputBytesPerFrame,
00360 PINDEX outputBytesPerFrame
00361 );
00363
00379 virtual bool UpdateMediaFormats(
00380 const OpalMediaFormat & inputMediaFormat,
00381 const OpalMediaFormat & outputMediaFormat
00382 );
00383
00390 virtual PINDEX GetOptimalDataFrameSize(
00391 PBoolean input
00392 ) const;
00393
00400 virtual PBoolean Convert(
00401 const RTP_DataFrame & input,
00402 RTP_DataFrame & output
00403 );
00404
00408 virtual PBoolean ConvertFrame(
00409 const BYTE * input,
00410 BYTE * output
00411 );
00412 virtual PBoolean ConvertFrame(
00413 const BYTE * input,
00414 PINDEX & consumed,
00415 BYTE * output,
00416 PINDEX & created
00417 );
00418 virtual PBoolean ConvertSilentFrame(
00419 BYTE * output
00420 );
00422
00423 protected:
00424 PINDEX inputBytesPerFrame;
00425 PINDEX outputBytesPerFrame;
00426 PINDEX maxOutputDataSize;
00427 };
00428
00429
00437 class OpalStreamedTranscoder : public OpalTranscoder
00438 {
00439 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00440 public:
00445 OpalStreamedTranscoder(
00446 const OpalMediaFormat & inputMediaFormat,
00447 const OpalMediaFormat & outputMediaFormat,
00448 unsigned inputBits,
00449 unsigned outputBits
00450 );
00452
00461 virtual PINDEX GetOptimalDataFrameSize(
00462 PBoolean input
00463 ) const;
00464
00471 virtual PBoolean Convert(
00472 const RTP_DataFrame & input,
00473 RTP_DataFrame & output
00474 );
00475
00482 virtual int ConvertOne(int sample) const = 0;
00484
00485 protected:
00486 unsigned inputBitsPerSample;
00487 unsigned outputBitsPerSample;
00488 };
00489
00490
00492
00493 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00494 public:
00495 Opal_Linear16Mono_PCM();
00496 virtual int ConvertOne(int sample) const;
00497 };
00498
00499
00501
00502 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00503 public:
00504 Opal_PCM_Linear16Mono();
00505 virtual int ConvertOne(int sample) const;
00506 };
00507
00508
00510
00511 #define OPAL_REGISTER_L16_MONO() \
00512 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00513 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00514
00515
00516 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00517 {
00518 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00519 public:
00520 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00521 : OpalFramedTranscoder(inFormat, outFormat, 100, 100)
00522 { }
00523
00524 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00525 { return PFalse; }
00526 };
00527
00528 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00529 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00530 { \
00531 public: \
00532 Opal_Empty_##fmt##_Encoder() \
00533 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00534 { } \
00535 }; \
00536 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00537 { \
00538 public: \
00539 Opal_Empty_##fmt##_Decoder() \
00540 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00541 { } \
00542 }; \
00543
00544 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00545 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00546 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00547
00548 #endif // OPAL_OPAL_TRANSCODERS_H
00549
00550
00551