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 #ifndef OPAL_CODEC_RFC4175_H
00032 #define OPAL_CODEC_RFC4175_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #include <ptlib.h>
00039
00040 #include <opal/buildopts.h>
00041
00042 #if OPAL_RFC4175
00043
00044 #include <ptclib/random.h>
00045
00046 #include <opal/transcoders.h>
00047 #include <codec/opalplugin.h>
00048 #include <codec/vidcodec.h>
00049
00050
00051 #define OPAL_RFC4175_YCbCr420 "RFC4175_YCbCr-4:2:0"
00052 extern const OpalVideoFormat & GetOpalRFC4175_YCbCr420();
00053 #define OpalRFC4175YCbCr420 GetOpalRFC4175_YCbCr420()
00054
00055 #define OPAL_RFC4175_RGB "RFC4175_RGB"
00056 extern const OpalVideoFormat & GetOpalRFC4175_RGB();
00057 #define OpalRFC4175RGB GetOpalRFC4175_RGB()
00058
00059
00061
00062 class OpalRFC4175Transcoder : public OpalVideoTranscoder
00063 {
00064 PCLASSINFO(OpalRFC4175Transcoder, OpalVideoTranscoder);
00065 public:
00066 OpalRFC4175Transcoder(
00067 const OpalMediaFormat & inputMediaFormat,
00068 const OpalMediaFormat & outputMediaFormat
00069 );
00070 virtual PINDEX GetPgroupSize() const = 0;
00071 virtual PINDEX GetColsPerPgroup() const = 0;
00072 virtual PINDEX GetRowsPerPgroup() const = 0;
00073
00074 virtual PINDEX PixelsToBytes(PINDEX pixels) const = 0;
00075 PINDEX RFC4175HeaderSize(PINDEX lines);
00076
00077 struct ScanLineHeader {
00078 PUInt16b length;
00079 PUInt16b y;
00080 PUInt16b offset;
00081 };
00082 };
00083
00085
00086 class OpalRFC4175Encoder : public OpalRFC4175Transcoder
00087 {
00088 PCLASSINFO(OpalRFC4175Encoder, OpalRFC4175Transcoder);
00089 public:
00090 OpalRFC4175Encoder(
00091 const OpalMediaFormat & inputMediaFormat,
00092 const OpalMediaFormat & outputMediaFormat
00093 );
00094
00095 PBoolean ConvertFrames(const RTP_DataFrame & input, RTP_DataFrameList & output);
00096
00097 protected:
00098 virtual void StartEncoding(const RTP_DataFrame & input);
00099 virtual void EndEncoding() = 0;
00100
00101 void EncodeFullFrame();
00102 void EncodeScanLineSegment(PINDEX y, PINDEX offs, PINDEX width);
00103 void AddNewDstFrame();
00104 void FinishOutputFrame();
00105
00106 DWORD extendedSequenceNumber;
00107 PINDEX maximumPacketSize;
00108 unsigned frameHeight;
00109 unsigned frameWidth;
00110
00111 DWORD srcTimestamp;
00112
00113 RTP_DataFrameList * dstFrames;
00114 std::vector<PINDEX> dstScanlineCounts;
00115 PINDEX dstScanLineCount;
00116 PINDEX dstPacketSize;
00117 ScanLineHeader * dstScanLineTable;
00118 };
00119
00121
00122 class OpalRFC4175Decoder : public OpalRFC4175Transcoder
00123 {
00124 PCLASSINFO(OpalRFC4175Decoder, OpalRFC4175Transcoder);
00125 public:
00126 OpalRFC4175Decoder(
00127 const OpalMediaFormat & inputMediaFormat,
00128 const OpalMediaFormat & outputMediaFormat
00129 );
00130 ~OpalRFC4175Decoder();
00131
00132 virtual PINDEX PixelsToBytes(PINDEX pixels) const = 0;
00133 virtual PINDEX BytesToPixels(PINDEX pixels) const = 0;
00134
00135 PBoolean ConvertFrames(const RTP_DataFrame & input, RTP_DataFrameList & output);
00136
00137 protected:
00138 PBoolean Initialise();
00139 virtual PBoolean DecodeFrames(RTP_DataFrameList & output) = 0;
00140
00141 RTP_DataFrameList inputFrames;
00142 std::vector<PINDEX> scanlineCounts;
00143 PINDEX frameWidth, frameHeight;
00144
00145 PBoolean first;
00146 DWORD lastSequenceNumber;
00147 DWORD lastTimeStamp;
00148 };
00149
00151
00154 class Opal_RFC4175YCbCr420_to_YUV420P : public OpalRFC4175Decoder
00155 {
00156 PCLASSINFO(Opal_RFC4175YCbCr420_to_YUV420P, OpalRFC4175Decoder);
00157 public:
00158 Opal_RFC4175YCbCr420_to_YUV420P() : OpalRFC4175Decoder(OpalRFC4175YCbCr420, OpalYUV420P) { }
00159 PINDEX GetPgroupSize() const { return 6; }
00160 PINDEX GetColsPerPgroup() const { return 2; }
00161 PINDEX GetRowsPerPgroup() const { return 2; }
00162
00163 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels*12/8; }
00164 PINDEX BytesToPixels(PINDEX bytes) const { return bytes*8/12; }
00165
00166 PBoolean DecodeFrames(RTP_DataFrameList & output);
00167 };
00168
00169 class Opal_YUV420P_to_RFC4175YCbCr420 : public OpalRFC4175Encoder
00170 {
00171 PCLASSINFO(Opal_YUV420P_to_RFC4175YCbCr420, OpalRFC4175Encoder);
00172 public:
00173 Opal_YUV420P_to_RFC4175YCbCr420() : OpalRFC4175Encoder(OpalYUV420P, OpalRFC4175YCbCr420) { }
00174 PINDEX GetPgroupSize() const { return 6; }
00175 PINDEX GetColsPerPgroup() const { return 2; }
00176 PINDEX GetRowsPerPgroup() const { return 2; }
00177
00178 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 12 / 8; }
00179 PINDEX BytesToPixels(PINDEX bytes) const { return bytes * 8 / 12; }
00180
00181 void StartEncoding(const RTP_DataFrame & input);
00182 void EndEncoding();
00183
00184 protected:
00185 BYTE * srcYPlane;
00186 BYTE * srcCbPlane;
00187 BYTE * srcCrPlane;
00188 };
00189
00192 class Opal_RFC4175RGB_to_RGB24 : public OpalRFC4175Decoder
00193 {
00194 PCLASSINFO(Opal_RFC4175RGB_to_RGB24, OpalRFC4175Decoder);
00195 public:
00196 Opal_RFC4175RGB_to_RGB24() : OpalRFC4175Decoder(OpalRFC4175RGB, OpalRGB24) { }
00197 PINDEX GetPgroupSize() const { return 3; }
00198 PINDEX GetColsPerPgroup() const { return 1; }
00199 PINDEX GetRowsPerPgroup() const { return 1; }
00200
00201 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 3; }
00202 PINDEX BytesToPixels(PINDEX bytes) const { return bytes / 3; }
00203
00204 PBoolean DecodeFrames(RTP_DataFrameList & output);
00205 };
00206
00207 class Opal_RGB24_to_RFC4175RGB : public OpalRFC4175Encoder
00208 {
00209 PCLASSINFO(Opal_RGB24_to_RFC4175RGB, OpalRFC4175Encoder);
00210 public:
00211 Opal_RGB24_to_RFC4175RGB() : OpalRFC4175Encoder(OpalRGB24, OpalRFC4175RGB) { }
00212 PINDEX GetPgroupSize() const { return 3; }
00213 PINDEX GetColsPerPgroup() const { return 1; }
00214 PINDEX GetRowsPerPgroup() const { return 1; }
00215
00216 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 3; }
00217 PINDEX BytesToPixels(PINDEX bytes) const { return bytes / 3; }
00218
00219 void StartEncoding(const RTP_DataFrame & input);
00220 void EndEncoding();
00221
00222 protected:
00223 BYTE * rgbBase;
00224 };
00225
00226
00227 #define OPAL_REGISTER_RFC4175_VIDEO(oformat, rformat) \
00228 OPAL_REGISTER_TRANSCODER(Opal_RFC4175##rformat##_to_##oformat, OpalRFC4175##rformat, Opal##oformat); \
00229 OPAL_REGISTER_TRANSCODER(Opal_##oformat##_to_RFC4175##rformat, Opal##oformat, OpalRFC4175##rformat);
00230
00231 #define OPAL_REGISTER_RFC4175() \
00232 OPAL_REGISTER_RFC4175_VIDEO(YUV420P, YCbCr420); \
00233 OPAL_REGISTER_RFC4175_VIDEO(RGB24, RGB)
00234
00235
00237
00238 #endif // OPAL_RFC4175
00239
00240 #endif // OPAL_CODEC_RFC4175_H