OPAL
Version 3.10.4
|
00001 /* 00002 * rfc4175.h 00003 * 00004 * RFC4175 transport for uncompressed video 00005 * 00006 * Open Phone Abstraction Library 00007 * 00008 * Copyright (C) 2007 Post Increment 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Open Phone Abstraction Library. 00021 * 00022 * The Initial Developer of the Original Code is Post Increment 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Revision: 24413 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2010-05-27 19:41:47 -0500 (Thu, 27 May 2010) $ 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; // has field flag in top bit 00080 PUInt16b m_offset; // has last line flag in top bit 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