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