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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 #ifndef __OPAL_TRANSCODERS_H
00139 #define __OPAL_TRANSCODERS_H
00140
00141 #ifdef P_USE_PRAGMA
00142 #pragma interface
00143 #endif
00144
00145 #include <opal/buildopts.h>
00146
00147 #include <opal/mediafmt.h>
00148 #include <opal/mediacmd.h>
00149
00150 #include <rtp/rtp.h>
00151
00152 class RTP_DataFrame;
00153 class OpalTranscoder;
00154
00155
00157
00161 class OpalMediaFormatPair : public PObject
00162 {
00163 PCLASSINFO(OpalMediaFormatPair, PObject);
00164 public:
00169 OpalMediaFormatPair(
00170 const OpalMediaFormat & inputMediaFormat,
00171 const OpalMediaFormat & outputMediaFormat
00172 );
00174
00181 void PrintOn(
00182 ostream & strm
00183 ) const;
00184
00196 virtual Comparison Compare(
00197 const PObject & obj
00198 ) const;
00200
00205 const OpalMediaFormat & GetInputFormat() const { return inputMediaFormat; }
00206
00209 const OpalMediaFormat & GetOutputFormat() const { return outputMediaFormat; }
00211
00212 protected:
00213 OpalMediaFormat inputMediaFormat;
00214 OpalMediaFormat outputMediaFormat;
00215 };
00216
00217
00218 typedef std::pair<PString, PString> OpalTranscoderKey;
00219 typedef PFactory<OpalTranscoder, OpalTranscoderKey> OpalTranscoderFactory;
00220 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T OpalTranscoderList;
00221 typedef PFactory<OpalTranscoder, OpalTranscoderKey>::KeyList_T::iterator OpalTranscoderIterator;
00222
00223 #define OPAL_REGISTER_TRANSCODER(cls, input, output) \
00224 OpalTranscoderFactory::Worker<cls> OpalTranscoder_##cls(OpalTranscoderKey(input, output))
00225
00226
00233 class OpalTranscoder : public OpalMediaFormatPair
00234 {
00235 PCLASSINFO(OpalTranscoder, OpalMediaFormatPair);
00236 public:
00241 OpalTranscoder(
00242 const OpalMediaFormat & inputMediaFormat,
00243 const OpalMediaFormat & outputMediaFormat
00244 );
00246
00257 virtual BOOL UpdateOutputMediaFormat(
00258 const OpalMediaFormat & mediaFormat
00259 );
00260
00267 virtual BOOL ExecuteCommand(
00268 const OpalMediaCommand & command
00269 );
00270
00277 virtual PINDEX GetOptimalDataFrameSize(
00278 BOOL input
00279 ) const = 0;
00280
00291 virtual BOOL ConvertFrames(
00292 const RTP_DataFrame & input,
00293 RTP_DataFrameList & output
00294 );
00295
00302 virtual BOOL Convert(
00303 const RTP_DataFrame & input,
00304 RTP_DataFrame & output
00305 ) = 0;
00306
00311 static OpalTranscoder * Create(
00312 const OpalMediaFormat & srcFormat,
00313 const OpalMediaFormat & dstFormat,
00314 const BYTE * instance = NULL,
00315 unsigned instanceLen = 0
00316 );
00317
00329 static BOOL SelectFormats(
00330 unsigned sessionID,
00331 const OpalMediaFormatList & srcFormats,
00332 const OpalMediaFormatList & dstFormats,
00333 OpalMediaFormat & srcFormat,
00334 OpalMediaFormat & dstFormat
00335 );
00336
00345 static BOOL FindIntermediateFormat(
00346 OpalMediaFormat & srcFormat,
00347 OpalMediaFormat & dstFormat,
00348 OpalMediaFormat & intermediateFormat
00349 );
00350
00353 static OpalMediaFormatList GetDestinationFormats(
00354 const OpalMediaFormat & srcFormat
00355 );
00356
00359 static OpalMediaFormatList GetSourceFormats(
00360 const OpalMediaFormat & dstFormat
00361 );
00362
00365 static OpalMediaFormatList GetPossibleFormats(
00366 const OpalMediaFormatList & formats
00367 );
00369
00374 PINDEX GetMaxOutputSize() const { return maxOutputSize; }
00375
00378 void SetMaxOutputSize(
00379 PINDEX size
00380 ) { maxOutputSize = size; }
00381
00386 void SetCommandNotifier(
00387 const PNotifier & notifier
00388 ) { commandNotifier = notifier; }
00389
00394 const PNotifier & GetCommandNotifier() const { return commandNotifier; }
00395
00398 virtual void SetInstanceID(
00399 const BYTE * instance,
00400 unsigned instanceLen
00401 );
00402
00403 void SetRTPPayloadMap(const RTP_DataFrame::PayloadMapType & v)
00404 { payloadTypeMap = v; }
00405
00406 void AddRTPPayloadMapping(RTP_DataFrame::PayloadTypes from, RTP_DataFrame::PayloadTypes to)
00407 { payloadTypeMap.insert(RTP_DataFrame::PayloadMapType::value_type(from, to)); }
00408
00409 RTP_DataFrame::PayloadTypes GetPayloadType(
00410 BOOL input
00411 ) const;
00413
00414 protected:
00415 PINDEX maxOutputSize;
00416 bool outputMediaFormatUpdated;
00417 PNotifier commandNotifier;
00418 PMutex updateMutex;
00419
00420 RTP_DataFrame::PayloadMapType payloadTypeMap;
00421
00422 BOOL outputIsRTP, inputIsRTP;
00423 };
00424
00425
00433 class OpalFramedTranscoder : public OpalTranscoder
00434 {
00435 PCLASSINFO(OpalFramedTranscoder, OpalTranscoder);
00436 public:
00441 OpalFramedTranscoder(
00442 const OpalMediaFormat & inputMediaFormat,
00443 const OpalMediaFormat & outputMediaFormat,
00444 PINDEX inputBytesPerFrame,
00445 PINDEX outputBytesPerFrame
00446 );
00448
00457 virtual PINDEX GetOptimalDataFrameSize(
00458 BOOL input
00459 ) const;
00460
00467 virtual BOOL Convert(
00468 const RTP_DataFrame & input,
00469 RTP_DataFrame & output
00470 );
00471
00475 virtual BOOL ConvertFrame(
00476 const BYTE * input,
00477 BYTE * output
00478 );
00479 virtual BOOL ConvertFrame(
00480 const BYTE * input,
00481 PINDEX & consumed,
00482 BYTE * output,
00483 PINDEX & created
00484 );
00485 virtual BOOL ConvertSilentFrame(
00486 BYTE * output
00487 );
00489
00490 protected:
00491 PINDEX inputBytesPerFrame;
00492 PINDEX outputBytesPerFrame;
00493
00494
00495 };
00496
00497
00505 class OpalStreamedTranscoder : public OpalTranscoder
00506 {
00507 PCLASSINFO(OpalStreamedTranscoder, OpalTranscoder);
00508 public:
00513 OpalStreamedTranscoder(
00514 const OpalMediaFormat & inputMediaFormat,
00515 const OpalMediaFormat & outputMediaFormat,
00516 unsigned inputBits,
00517 unsigned outputBits,
00518 PINDEX optimalSamples
00519 );
00521
00530 virtual PINDEX GetOptimalDataFrameSize(
00531 BOOL input
00532 ) const;
00533
00540 virtual BOOL Convert(
00541 const RTP_DataFrame & input,
00542 RTP_DataFrame & output
00543 );
00544
00551 virtual int ConvertOne(int sample) const = 0;
00553
00554 protected:
00555 unsigned inputBitsPerSample;
00556 unsigned outputBitsPerSample;
00557 PINDEX optimalSamples;
00558 };
00559
00560
00562
00563 class Opal_Linear16Mono_PCM : public OpalStreamedTranscoder {
00564 public:
00565 Opal_Linear16Mono_PCM();
00566 virtual int ConvertOne(int sample) const;
00567 };
00568
00569
00571
00572 class Opal_PCM_Linear16Mono : public OpalStreamedTranscoder {
00573 public:
00574 Opal_PCM_Linear16Mono();
00575 virtual int ConvertOne(int sample) const;
00576 };
00577
00578
00580
00581 #define OPAL_REGISTER_L16_MONO() \
00582 OPAL_REGISTER_TRANSCODER(Opal_Linear16Mono_PCM, OpalL16_MONO_8KHZ, OpalPCM16); \
00583 OPAL_REGISTER_TRANSCODER(Opal_PCM_Linear16Mono, OpalPCM16, OpalL16_MONO_8KHZ)
00584
00585
00586 class OpalEmptyFramedAudioTranscoder : public OpalFramedTranscoder
00587 {
00588 PCLASSINFO(OpalEmptyFramedAudioTranscoder, OpalFramedTranscoder);
00589 public:
00590 OpalEmptyFramedAudioTranscoder(const char * inFormat, const char * outFormat)
00591 : OpalFramedTranscoder(inFormat, outFormat, 100, 100)
00592 { }
00593
00594 BOOL ConvertFrame(const BYTE *, PINDEX &, BYTE *, PINDEX &)
00595 { return FALSE; }
00596 };
00597
00598 #define OPAL_DECLARE_EMPTY_TRANSCODER(fmt) \
00599 class Opal_Empty_##fmt##_Encoder : public OpalEmptyFramedAudioTranscoder \
00600 { \
00601 public: \
00602 Opal_Empty_##fmt##_Encoder() \
00603 : OpalEmptyFramedAudioTranscoder(OpalPCM16, fmt) \
00604 { } \
00605 }; \
00606 class Opal_Empty_##fmt##_Decoder : public OpalEmptyFramedAudioTranscoder \
00607 { \
00608 public: \
00609 Opal_Empty_##fmt##_Decoder() \
00610 : OpalEmptyFramedAudioTranscoder(fmt, OpalPCM16) \
00611 { } \
00612 }; \
00613
00614 #define OPAL_DEFINE_EMPTY_TRANSCODER(fmt) \
00615 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Encoder, OpalPCM16, fmt); \
00616 OPAL_REGISTER_TRANSCODER(Opal_Empty_##fmt##_Decoder, fmt, OpalPCM16); \
00617
00618 #endif // __OPAL_TRANSCODERS_H
00619
00620
00621