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 #ifndef __OPAL_RFC4175_H
00048 #define __OPAL_RFC4175_H
00049
00050 #ifdef P_USE_PRAGMA
00051 #pragma interface
00052 #endif
00053
00054 #include <ptlib.h>
00055
00056 #include <ptclib/random.h>
00057
00058 #include <opal/transcoders.h>
00059 #include <codec/opalplugin.h>
00060 #include <codec/vidcodec.h>
00061
00062 namespace PWLibStupidLinkerHacks {
00063 extern int rfc4175Loader;
00064 };
00065
00066 #define OPAL_RFC4175_YCbCr420 "RFC4175_YCbCr-4:2:0"
00067 extern const OpalVideoFormat & GetOpalRFC4175_YCbCr420();
00068 #define OpalRFC4175YCbCr420 GetOpalRFC4175_YCbCr420()
00069
00070 #define OPAL_RFC4175_RGB "RFC4175_RGB"
00071 extern const OpalVideoFormat & GetOpalRFC4175_RGB();
00072 #define OpalRFC4175RGB GetOpalRFC4175_RGB()
00073
00074
00076
00077 class OpalRFC4175Transcoder : public OpalUncompVideoTranscoder
00078 {
00079 PCLASSINFO(OpalRFC4175Transcoder, OpalUncompVideoTranscoder);
00080 public:
00081 OpalRFC4175Transcoder(
00082 const OpalMediaFormat & inputMediaFormat,
00083 const OpalMediaFormat & outputMediaFormat
00084 );
00085 virtual PINDEX GetPgroupSize() const = 0;
00086 virtual PINDEX GetColsPerPgroup() const = 0;
00087 virtual PINDEX GetRowsPerPgroup() const = 0;
00088
00089 virtual PINDEX PixelsToBytes(PINDEX pixels) const = 0;
00090 PINDEX RFC4175HeaderSize(PINDEX lines);
00091
00092 struct ScanLineHeader {
00093 PUInt16b length;
00094 PUInt16b y;
00095 PUInt16b offset;
00096 };
00097 };
00098
00100
00101 class OpalRFC4175Encoder : public OpalRFC4175Transcoder
00102 {
00103 PCLASSINFO(OpalRFC4175Encoder, OpalRFC4175Transcoder);
00104 public:
00105 OpalRFC4175Encoder(
00106 const OpalMediaFormat & inputMediaFormat,
00107 const OpalMediaFormat & outputMediaFormat
00108 );
00109
00110 BOOL ConvertFrames(const RTP_DataFrame & input, RTP_DataFrameList & output);
00111
00112 protected:
00113 virtual void StartEncoding(const RTP_DataFrame & input);
00114 virtual void EncodeFrames() = 0;
00115
00116 void EncodeFullFrame();
00117 void EncodeScanLineSegment(PINDEX y, PINDEX offs, PINDEX width);
00118 void AddNewDstFrame();
00119 void FinishOutputFrame();
00120
00121 DWORD extendedSequenceNumber;
00122 PINDEX maximumPacketSize;
00123 unsigned frameHeight;
00124 unsigned frameWidth;
00125
00126 DWORD srcTimestamp;
00127
00128 RTP_DataFrameList * dstFrames;
00129 std::vector<PINDEX> dstScanlineCounts;
00130 PINDEX dstScanLineCount;
00131 PINDEX dstPacketSize;
00132 ScanLineHeader * dstScanLineTable;
00133 };
00134
00136
00137 class OpalRFC4175Decoder : public OpalRFC4175Transcoder
00138 {
00139 PCLASSINFO(OpalRFC4175Decoder, OpalRFC4175Transcoder);
00140 public:
00141 OpalRFC4175Decoder(
00142 const OpalMediaFormat & inputMediaFormat,
00143 const OpalMediaFormat & outputMediaFormat
00144 );
00145 ~OpalRFC4175Decoder();
00146
00147 virtual PINDEX PixelsToBytes(PINDEX pixels) const = 0;
00148 virtual PINDEX BytesToPixels(PINDEX pixels) const = 0;
00149
00150 BOOL ConvertFrames(const RTP_DataFrame & input, RTP_DataFrameList & output);
00151
00152 protected:
00153 BOOL Initialise();
00154 virtual BOOL DecodeFrames(RTP_DataFrameList & output) = 0;
00155
00156 RTP_DataFrameList inputFrames;
00157 std::vector<PINDEX> scanlineCounts;
00158 PINDEX frameWidth, frameHeight;
00159
00160 BOOL first;
00161 DWORD lastSequenceNumber;
00162 DWORD lastTimeStamp;
00163 };
00164
00166
00169 class Opal_RFC4175YCbCr420_to_YUV420P : public OpalRFC4175Decoder
00170 {
00171 PCLASSINFO(Opal_RFC4175YCbCr420_to_YUV420P, OpalRFC4175Decoder);
00172 public:
00173 Opal_RFC4175YCbCr420_to_YUV420P() : OpalRFC4175Decoder(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 BOOL DecodeFrames(RTP_DataFrameList & output);
00182 };
00183
00184 class Opal_YUV420P_to_RFC4175YCbCr420 : public OpalRFC4175Encoder
00185 {
00186 PCLASSINFO(Opal_YUV420P_to_RFC4175YCbCr420, OpalRFC4175Encoder);
00187 public:
00188 Opal_YUV420P_to_RFC4175YCbCr420() : OpalRFC4175Encoder(OpalRFC4175YCbCr420, OpalYUV420P) { }
00189 PINDEX GetPgroupSize() const { return 6; }
00190 PINDEX GetColsPerPgroup() const { return 2; }
00191 PINDEX GetRowsPerPgroup() const { return 2; }
00192
00193 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 12 / 8; }
00194 PINDEX BytesToPixels(PINDEX bytes) const { return bytes * 8 / 12; }
00195
00196 void StartEncoding(const RTP_DataFrame & input);
00197 void EncodeFrames();
00198
00199 protected:
00200 BYTE * srcYPlane;
00201 BYTE * srcCbPlane;
00202 BYTE * srcCrPlane;
00203 };
00204
00207 class Opal_RFC4175RGB_to_RGB24 : public OpalRFC4175Decoder
00208 {
00209 PCLASSINFO(Opal_RFC4175RGB_to_RGB24, OpalRFC4175Decoder);
00210 public:
00211 Opal_RFC4175RGB_to_RGB24() : OpalRFC4175Decoder(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 BOOL DecodeFrames(RTP_DataFrameList & output);
00220 };
00221
00222 class Opal_RGB24_to_RFC4175RGB : public OpalRFC4175Encoder
00223 {
00224 PCLASSINFO(Opal_RGB24_to_RFC4175RGB, OpalRFC4175Encoder);
00225 public:
00226 Opal_RGB24_to_RFC4175RGB() : OpalRFC4175Encoder(OpalRFC4175RGB, OpalRGB24) { }
00227 PINDEX GetPgroupSize() const { return 3; }
00228 PINDEX GetColsPerPgroup() const { return 1; }
00229 PINDEX GetRowsPerPgroup() const { return 1; }
00230
00231 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 3; }
00232 PINDEX BytesToPixels(PINDEX bytes) const { return bytes / 3; }
00233
00234 void StartEncoding(const RTP_DataFrame & input);
00235 void EncodeFrames();
00236
00237 protected:
00238 BYTE * rgbBase;
00239 };
00240
00241
00242 #define OPAL_REGISTER_RFC4175_VIDEO(oformat, rformat) \
00243 OPAL_REGISTER_TRANSCODER(Opal_RFC4175##rformat##_to_##oformat, OpalRFC4175##rformat, Opal##oformat); \
00244 OPAL_REGISTER_TRANSCODER(Opal_##oformat##_to_RFC4175##rformat, Opal##oformat, OpalRFC4175##rformat);
00245
00247
00248 #endif