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
00179 virtual PBoolean ExecuteCommand(
00180 const OpalMediaCommand & command
00181 );
00182
00189 virtual PINDEX GetOptimalDataFrameSize(
00190 PBoolean input
00191 ) const = 0;
00192
00203 virtual PBoolean ConvertFrames(
00204 const RTP_DataFrame & input,
00205 RTP_DataFrameList & output
00206 );
00207
00214 virtual PBoolean Convert(
00215 const RTP_DataFrame & input,
00216 RTP_DataFrame & output
00217 ) = 0;
00218
00223 static OpalTranscoder * Create(
00224 const OpalMediaFormat & srcFormat,
00225 const OpalMediaFormat & dstFormat,
00226 const BYTE * instance = NULL,
00227 unsigned instanceLen = 0
00228 );
00229
00244 static bool SelectFormats(
00245 const OpalMediaType & mediaType,
00246 const OpalMediaFormatList & srcFormats,
00247 const OpalMediaFormatList & dstFormats,
00248 const OpalMediaFormatList & allFormats,
00249 OpalMediaFormat & srcFormat,
00250 OpalMediaFormat & dstFormat
00251 );
00252
00265 static bool FindIntermediateFormat(
00266 const OpalMediaFormat & srcFormat,
00267 const OpalMediaFormat & dstFormat,
00268 OpalMediaFormat & intermediateFormat
00269 );
00270
00273 static OpalMediaFormatList GetDestinationFormats(
00274 const OpalMediaFormat & srcFormat
00275 );
00276
00279 static OpalMediaFormatList GetSourceFormats(
00280 const OpalMediaFormat & dstFormat
00281 );
00282
00285 static OpalMediaFormatList GetPossibleFormats(
00286 const OpalMediaFormatList & formats
00287 );
00289
00294 PINDEX GetMaxOutputSize() const { return maxOutputSize; }
00295
00298 void SetMaxOutputSize(
00299 PINDEX size
00300 ) { maxOutputSize = size; }
00301
00306 void SetCommandNotifier(
00307 const PNotifier & notifier
00308 ) { commandNotifier = notifier; }
00309
00314 const PNotifier & GetCommandNotifier() const { return commandNotifier; }
00315
00317 void NotifyCommand(
00318 const OpalMediaCommand & command
00319 ) const;
00320
00322 unsigned GetSessionID() const { return m_sessionID; }
00323
00325 void SetSessionID(unsigned id) { m_sessionID = id; }
00326
00329 virtual void SetInstanceID(
00330 const BYTE * instance,
00331 unsigned instanceLen
00332 );
00333
00334 RTP_DataFrame::PayloadTypes GetPayloadType(
00335 PBoolean input
00336 ) const;
00337
00338 virtual bool AcceptComfortNoise() const { return false; }
00339 virtual bool AcceptEmptyPayload() const { return acceptEmptyPayload; }
00340 virtual bool AcceptOtherPayloads() const { return acceptOtherPayloads; }
00341
00342 #if OPAL_STATISTICS
00343 virtual void GetStatistics(OpalMediaStatistics & statistics) const;
00344 #endif
00345
00346 void CopyTimestamp(RTP_DataFrame & dst, const RTP_DataFrame & src, bool inToOut) const;
00348
00349 protected:
00350 PINDEX maxOutputSize;
00351 PNotifier commandNotifier;
00352 PMutex updateMutex;
00353
00354 unsigned m_sessionID;
00355 bool outputIsRTP, inputIsRTP;
00356 bool acceptEmptyPayload;
00357 bool acceptOtherPayloads;
00358 unsigned m_inClockRate;
00359 unsigned m_outClockRate;
00360 };
00361
00362
00370 class OpalFramedTranscoder : public OpalTranscoder
00371 {
00372 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00373 public:
00378 OpalFramedTranscoder(
00379 const OpalMediaFormat & inputMediaFormat,
00380 const OpalMediaFormat & outputMediaFormat
00381 );
00383
00399 virtual bool UpdateMediaFormats(
00400 const OpalMediaFormat & inputMediaFormat,
00401 const OpalMediaFormat & outputMediaFormat
00402 );
00403
00410 virtual PINDEX GetOptimalDataFrameSize(
00411 PBoolean input
00412 ) const;
00413
00420 virtual PBoolean Convert(
00421 const RTP_DataFrame & input,
00422 RTP_DataFrame & output
00423 );
00424
00428 virtual PBoolean ConvertFrame(
00429 const BYTE * input,
00430 BYTE * output
00431 );
00432 virtual PBoolean ConvertFrame(
00433 const BYTE * input,
00434 PINDEX & consumed,
00435 BYTE * output,
00436 PINDEX & created
00437 );
00438 virtual PBoolean ConvertSilentFrame(
00439 BYTE * output
00440 );
00442
00443 protected:
00444 void CalculateSizes();
00445
00446 PINDEX inputBytesPerFrame;
00447 PINDEX outputBytesPerFrame;
00448 PINDEX maxOutputDataSize;
00449 };
00450
00451
00459 class OpalStreamedTranscoder : public OpalTranscoder
00460 {
00461 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00462 public:
00467 OpalStreamedTranscoder(
00468 const OpalMediaFormat & inputMediaFormat,
00469 const OpalMediaFormat & outputMediaFormat,
00470 unsigned inputBits,
00471 unsigned outputBits
00472 );
00474
00483 virtual PINDEX GetOptimalDataFrameSize(
00484 PBoolean input
00485 ) const;
00486
00493 virtual PBoolean Convert(
00494 const RTP_DataFrame & input,
00495 RTP_DataFrame & output
00496 );
00497
00504 virtual int ConvertOne(int sample) const = 0;
00506
00507 protected:
00508 unsigned inputBitsPerSample;
00509 unsigned outputBitsPerSample;
00510 };
00511
00512
00514
00515 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00516 public:
00517 Opal_Linear16Mono_PCM();
00518 virtual int ConvertOne(int sample) const;
00519 };
00520
00521
00523
00524 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00525 public:
00526 Opal_PCM_Linear16Mono();
00527 virtual int ConvertOne(int sample) const;
00528 };
00529
00530
00532
00533 #define OPAL_REGISTER_L16_MONO() \
00534 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00535 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00536
00537
00538 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00539 {
00540 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00541 public:
00542 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00543 : OpalFramedTranscoder(inFormat, outFormat)
00544 { }
00545
00546 PBoolean ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00547 { return false; }
00548 };
00549
00550 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00551 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00552 { \
00553 public: \
00554 Opal_Empty_##fmt##_Encoder() \
00555 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00556 { } \
00557 }; \
00558 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00559 { \
00560 public: \
00561 Opal_Empty_##fmt##_Decoder() \
00562 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00563 { } \
00564 }; \
00565
00566 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00567 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00568 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00569
00570 #endif // OPAL_OPAL_TRANSCODERS_H
00571
00572
00573