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 m_length;
00079 PUInt16b m_y;
00080 PUInt16b m_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 bool 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 m_extendedSequenceNumber;
00107 PINDEX m_maximumPacketSize;
00108 unsigned m_frameHeight;
00109 unsigned m_frameWidth;
00110
00111 DWORD m_srcTimestamp;
00112
00113 RTP_DataFrameList * m_dstFrames;
00114 std::vector<PINDEX> m_dstScanlineCounts;
00115 PINDEX m_dstScanLineCount;
00116 PINDEX m_dstPacketSize;
00117 ScanLineHeader * m_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 bool ConvertFrames(const RTP_DataFrame & input, RTP_DataFrameList & output);
00136
00137 protected:
00138 void DecodeFramesAndSetFrameSize(RTP_DataFrameList & output);
00139 virtual bool DecodeFrames(RTP_DataFrameList & output) = 0;
00140
00141 RTP_DataFrameList m_inputFrames;
00142 std::vector<PINDEX> m_scanlineCounts;
00143 PINDEX m_frameWidth, m_frameHeight;
00144
00145 bool m_first;
00146 bool m_missingPackets;
00147 PINDEX m_maxWidth;
00148 PINDEX m_maxHeight;
00149 DWORD m_nextSequenceNumber;
00150 DWORD m_lastTimeStamp;
00151 DWORD m_timeStampOfFrame;
00152 DWORD m_firstSequenceOfFrame;
00153 };
00154
00156
00159 class Opal_RFC4175YCbCr420_to_YUV420P : public OpalRFC4175Decoder
00160 {
00161 PCLASSINFO(Opal_RFC4175YCbCr420_to_YUV420P, OpalRFC4175Decoder);
00162 public:
00163 Opal_RFC4175YCbCr420_to_YUV420P() : OpalRFC4175Decoder(OpalRFC4175YCbCr420, OpalYUV420P) { }
00164 PINDEX GetPgroupSize() const { return 6; }
00165 PINDEX GetColsPerPgroup() const { return 2; }
00166 PINDEX GetRowsPerPgroup() const { return 2; }
00167
00168 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels*12/8; }
00169 PINDEX BytesToPixels(PINDEX bytes) const { return bytes*8/12; }
00170
00171 bool DecodeFrames(RTP_DataFrameList & output);
00172 };
00173
00174 class Opal_YUV420P_to_RFC4175YCbCr420 : public OpalRFC4175Encoder
00175 {
00176 PCLASSINFO(Opal_YUV420P_to_RFC4175YCbCr420, OpalRFC4175Encoder);
00177 public:
00178 Opal_YUV420P_to_RFC4175YCbCr420() : OpalRFC4175Encoder(OpalYUV420P, OpalRFC4175YCbCr420) { }
00179 PINDEX GetPgroupSize() const { return 6; }
00180 PINDEX GetColsPerPgroup() const { return 2; }
00181 PINDEX GetRowsPerPgroup() const { return 2; }
00182
00183 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 12 / 8; }
00184 PINDEX BytesToPixels(PINDEX bytes) const { return bytes * 8 / 12; }
00185
00186 void StartEncoding(const RTP_DataFrame & input);
00187 void EndEncoding();
00188
00189 protected:
00190 BYTE * m_srcYPlane;
00191 BYTE * m_srcCbPlane;
00192 BYTE * m_srcCrPlane;
00193 };
00194
00197 class Opal_RFC4175RGB_to_RGB24 : public OpalRFC4175Decoder
00198 {
00199 PCLASSINFO(Opal_RFC4175RGB_to_RGB24, OpalRFC4175Decoder);
00200 public:
00201 Opal_RFC4175RGB_to_RGB24() : OpalRFC4175Decoder(OpalRFC4175RGB, OpalRGB24) { }
00202 PINDEX GetPgroupSize() const { return 3; }
00203 PINDEX GetColsPerPgroup() const { return 1; }
00204 PINDEX GetRowsPerPgroup() const { return 1; }
00205
00206 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 3; }
00207 PINDEX BytesToPixels(PINDEX bytes) const { return bytes / 3; }
00208
00209 bool DecodeFrames(RTP_DataFrameList & output);
00210 };
00211
00212 class Opal_RGB24_to_RFC4175RGB : public OpalRFC4175Encoder
00213 {
00214 PCLASSINFO(Opal_RGB24_to_RFC4175RGB, OpalRFC4175Encoder);
00215 public:
00216 Opal_RGB24_to_RFC4175RGB() : OpalRFC4175Encoder(OpalRGB24, OpalRFC4175RGB) { }
00217 PINDEX GetPgroupSize() const { return 3; }
00218 PINDEX GetColsPerPgroup() const { return 1; }
00219 PINDEX GetRowsPerPgroup() const { return 1; }
00220
00221 PINDEX PixelsToBytes(PINDEX pixels) const { return pixels * 3; }
00222 PINDEX BytesToPixels(PINDEX bytes) const { return bytes / 3; }
00223
00224 void StartEncoding(const RTP_DataFrame & input);
00225 void EndEncoding();
00226
00227 protected:
00228 BYTE * m_rgbBase;
00229 };
00230
00231
00232 #define OPAL_REGISTER_RFC4175_VIDEO(oformat, rformat) \
00233 OPAL_REGISTER_TRANSCODER(Opal_RFC4175##rformat##_to_##oformat, OpalRFC4175##rformat, Opal##oformat); \
00234 OPAL_REGISTER_TRANSCODER(Opal_##oformat##_to_RFC4175##rformat, Opal##oformat, OpalRFC4175##rformat);
00235
00236 #define OPAL_REGISTER_RFC4175() \
00237 OPAL_REGISTER_RFC4175_VIDEO(YUV420P, YCbCr420); \
00238 OPAL_REGISTER_RFC4175_VIDEO(RGB24, RGB)
00239
00240
00242
00243 #endif // OPAL_RFC4175
00244
00245 #endif // OPAL_CODEC_RFC4175_H