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