1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 // Common definition for video, including fourcc and VideoFormat. 29 30 #ifndef TALK_MEDIA_BASE_VIDEOCOMMON_H_ // NOLINT 31 #define TALK_MEDIA_BASE_VIDEOCOMMON_H_ 32 33 #include <string> 34 35 #include "webrtc/base/basictypes.h" 36 #include "webrtc/base/timeutils.h" 37 38 namespace cricket { 39 40 // TODO(janahan): For now, a hard-coded ssrc is used as the video ssrc. 41 // This is because when the video frame is passed to the mediaprocessor for 42 // processing, it doesn't have the correct ssrc. Since currently only Tx 43 // Video processing is supported, this is ok. When we switch over to trigger 44 // from capturer, this should be fixed and this const removed. 45 const uint32_t kDummyVideoSsrc = 0xFFFFFFFF; 46 47 // Minimum interval is 10k fps. 48 #define FPS_TO_INTERVAL(fps) \ 49 (fps ? rtc::kNumNanosecsPerSec / fps : \ 50 rtc::kNumNanosecsPerSec / 10000) 51 52 ////////////////////////////////////////////////////////////////////////////// 53 // Definition of FourCC codes 54 ////////////////////////////////////////////////////////////////////////////// 55 // Convert four characters to a FourCC code. 56 // Needs to be a macro otherwise the OS X compiler complains when the kFormat* 57 // constants are used in a switch. 58 #define FOURCC(a, b, c, d) \ 59 ((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \ 60 (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24)) 61 // Some pages discussing FourCC codes: 62 // http://www.fourcc.org/yuv.php 63 // http://v4l2spec.bytesex.org/spec/book1.htm 64 // http://developer.apple.com/quicktime/icefloe/dispatch020.html 65 // http://msdn.microsoft.com/library/windows/desktop/dd206750.aspx#nv12 66 // http://people.xiph.org/~xiphmont/containers/nut/nut4cc.txt 67 68 // FourCC codes grouped according to implementation efficiency. 69 // Primary formats should convert in 1 efficient step. 70 // Secondary formats are converted in 2 steps. 71 // Auxilliary formats call primary converters. 72 enum FourCC { 73 // 9 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. 74 FOURCC_I420 = FOURCC('I', '4', '2', '0'), 75 FOURCC_I422 = FOURCC('I', '4', '2', '2'), 76 FOURCC_I444 = FOURCC('I', '4', '4', '4'), 77 FOURCC_I411 = FOURCC('I', '4', '1', '1'), 78 FOURCC_I400 = FOURCC('I', '4', '0', '0'), 79 FOURCC_NV21 = FOURCC('N', 'V', '2', '1'), 80 FOURCC_NV12 = FOURCC('N', 'V', '1', '2'), 81 FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'), 82 FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'), 83 84 // 2 Secondary YUV formats: row biplanar. 85 FOURCC_M420 = FOURCC('M', '4', '2', '0'), 86 87 // 9 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp. 88 FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'), 89 FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'), 90 FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'), 91 FOURCC_24BG = FOURCC('2', '4', 'B', 'G'), 92 FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), 93 FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'), 94 FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // bgr565. 95 FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // abgr1555. 96 FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444. 97 98 // 4 Secondary RGB formats: 4 Bayer Patterns. 99 FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'), 100 FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'), 101 FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'), 102 FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'), 103 104 // 1 Primary Compressed YUV format. 105 FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'), 106 107 // 5 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. 108 FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'), 109 FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'), 110 FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'), 111 FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420. 112 FOURCC_J420 = FOURCC('J', '4', '2', '0'), 113 FOURCC_J400 = FOURCC('J', '4', '0', '0'), 114 115 // 14 Auxiliary aliases. CanonicalFourCC() maps these to canonical fourcc. 116 FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420. 117 FOURCC_YU16 = FOURCC('Y', 'U', '1', '6'), // Alias for I422. 118 FOURCC_YU24 = FOURCC('Y', 'U', '2', '4'), // Alias for I444. 119 FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'), // Alias for YUY2. 120 FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'), // Alias for YUY2 on Mac. 121 FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'), // Alias for UYVY. 122 FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY on Mac. 123 FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'), // Alias for MJPG. 124 FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'), // Alias for MJPG on Mac. 125 FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR. 126 FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'), // Alias for RAW. 127 FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'), // Alias for 24BG. 128 FOURCC_CM32 = FOURCC(0, 0, 0, 32), // Alias for BGRA kCMPixelFormat_32ARGB 129 FOURCC_CM24 = FOURCC(0, 0, 0, 24), // Alias for RAW kCMPixelFormat_24RGB 130 131 // 1 Auxiliary compressed YUV format set aside for capturer. 132 FOURCC_H264 = FOURCC('H', '2', '6', '4'), 133 }; 134 135 // Match any fourcc. 136 137 // We move this out of the enum because using it in many places caused 138 // the compiler to get grumpy, presumably since the above enum is 139 // backed by an int. 140 static const uint32_t FOURCC_ANY = 0xFFFFFFFF; 141 142 // Converts fourcc aliases into canonical ones. 143 uint32_t CanonicalFourCC(uint32_t fourcc); 144 145 // Get FourCC code as a string. 146 inline std::string GetFourccName(uint32_t fourcc) { 147 std::string name; 148 name.push_back(static_cast<char>(fourcc & 0xFF)); 149 name.push_back(static_cast<char>((fourcc >> 8) & 0xFF)); 150 name.push_back(static_cast<char>((fourcc >> 16) & 0xFF)); 151 name.push_back(static_cast<char>((fourcc >> 24) & 0xFF)); 152 return name; 153 } 154 155 // Computes a scale less to fit in max_pixels while maintaining aspect ratio. 156 void ComputeScaleMaxPixels(int frame_width, int frame_height, int max_pixels, 157 int* scaled_width, int* scaled_height); 158 159 // For low fps, max pixels limit is set to Retina MacBookPro 15" resolution of 160 // 2880 x 1800 as of 4/18/2013. 161 // For high fps, maximum pixels limit is set based on common 24" monitor 162 // resolution of 2048 x 1280 as of 6/13/2013. The Retina resolution is 163 // therefore reduced to 1440 x 900. 164 void ComputeScale(int frame_width, int frame_height, int fps, 165 int* scaled_width, int* scaled_height); 166 167 // Compute the frame size that conversion should crop to based on aspect ratio. 168 // Ensures size is multiple of 2 due to I420 and conversion limitations. 169 void ComputeCrop(int cropped_format_width, int cropped_format_height, 170 int frame_width, int frame_height, 171 int pixel_width, int pixel_height, 172 int rotation, 173 int* cropped_width, int* cropped_height); 174 175 // Compute the frame size that makes pixels square pixel aspect ratio. 176 void ComputeScaleToSquarePixels(int in_width, int in_height, 177 int pixel_width, int pixel_height, 178 int* scaled_width, int* scaled_height); 179 180 ////////////////////////////////////////////////////////////////////////////// 181 // Definition of VideoFormat. 182 ////////////////////////////////////////////////////////////////////////////// 183 184 // VideoFormat with Plain Old Data for global variables. 185 struct VideoFormatPod { 186 int width; // Number of pixels. 187 int height; // Number of pixels. 188 int64_t interval; // Nanoseconds. 189 uint32_t fourcc; // Color space. FOURCC_ANY means that any color space is OK. 190 }; 191 192 struct VideoFormat : VideoFormatPod { 193 static const int64_t kMinimumInterval = 194 rtc::kNumNanosecsPerSec / 10000; // 10k fps. 195 196 VideoFormat() { 197 Construct(0, 0, 0, 0); 198 } 199 200 VideoFormat(int w, int h, int64_t interval_ns, uint32_t cc) { 201 Construct(w, h, interval_ns, cc); 202 } 203 204 explicit VideoFormat(const VideoFormatPod& format) { 205 Construct(format.width, format.height, format.interval, format.fourcc); 206 } 207 208 void Construct(int w, int h, int64_t interval_ns, uint32_t cc) { 209 width = w; 210 height = h; 211 interval = interval_ns; 212 fourcc = cc; 213 } 214 215 static int64_t FpsToInterval(int fps) { 216 return fps ? rtc::kNumNanosecsPerSec / fps : kMinimumInterval; 217 } 218 219 static int IntervalToFps(int64_t interval) { 220 if (!interval) { 221 return 0; 222 } 223 return static_cast<int>(rtc::kNumNanosecsPerSec / interval); 224 } 225 226 static float IntervalToFpsFloat(int64_t interval) { 227 if (!interval) { 228 return 0.f; 229 } 230 return static_cast<float>(rtc::kNumNanosecsPerSec) / 231 static_cast<float>(interval); 232 } 233 234 bool operator==(const VideoFormat& format) const { 235 return width == format.width && height == format.height && 236 interval == format.interval && fourcc == format.fourcc; 237 } 238 239 bool operator!=(const VideoFormat& format) const { 240 return !(*this == format); 241 } 242 243 bool operator<(const VideoFormat& format) const { 244 return (fourcc < format.fourcc) || 245 (fourcc == format.fourcc && width < format.width) || 246 (fourcc == format.fourcc && width == format.width && 247 height < format.height) || 248 (fourcc == format.fourcc && width == format.width && 249 height == format.height && interval > format.interval); 250 } 251 252 int framerate() const { return IntervalToFps(interval); } 253 254 // Check if both width and height are 0. 255 bool IsSize0x0() const { return 0 == width && 0 == height; } 256 257 // Check if this format is less than another one by comparing the resolution 258 // and frame rate. 259 bool IsPixelRateLess(const VideoFormat& format) const { 260 return width * height * framerate() < 261 format.width * format.height * format.framerate(); 262 } 263 264 // Get a string presentation in the form of "fourcc width x height x fps" 265 std::string ToString() const; 266 }; 267 268 } // namespace cricket 269 270 #endif // TALK_MEDIA_BASE_VIDEOCOMMON_H_ // NOLINT 271