video_frame_buffer.cc (7193B)
1 /* 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "api/video/video_frame_buffer.h" 12 13 #include <cstddef> 14 #include <string> 15 16 #include "api/array_view.h" 17 #include "api/scoped_refptr.h" 18 #include "api/video/i420_buffer.h" 19 #include "api/video/i422_buffer.h" 20 #include "api/video/i444_buffer.h" 21 #include "api/video/nv12_buffer.h" 22 #include "rtc_base/checks.h" 23 24 namespace webrtc { 25 26 scoped_refptr<VideoFrameBuffer> VideoFrameBuffer::CropAndScale( 27 int offset_x, 28 int offset_y, 29 int crop_width, 30 int crop_height, 31 int scaled_width, 32 int scaled_height) { 33 scoped_refptr<I420Buffer> result = 34 I420Buffer::Create(scaled_width, scaled_height); 35 result->CropAndScaleFrom(*this->ToI420(), offset_x, offset_y, crop_width, 36 crop_height); 37 return result; 38 } 39 40 void VideoFrameBuffer::PrepareMappedBufferAsync( 41 size_t width, 42 size_t height, 43 scoped_refptr<PreparedFrameHandler> handler, 44 size_t frame_identifier) { 45 // Default implementation can't do any preparations, 46 // so it just invokes the callback immediately. 47 handler->OnFramePrepared(frame_identifier); 48 } 49 50 const I420BufferInterface* VideoFrameBuffer::GetI420() const { 51 // Overridden by subclasses that can return an I420 buffer without any 52 // conversion, in particular, I420BufferInterface. 53 return nullptr; 54 } 55 56 const I420ABufferInterface* VideoFrameBuffer::GetI420A() const { 57 RTC_CHECK(type() == Type::kI420A); 58 return static_cast<const I420ABufferInterface*>(this); 59 } 60 61 const I444BufferInterface* VideoFrameBuffer::GetI444() const { 62 RTC_CHECK(type() == Type::kI444); 63 return static_cast<const I444BufferInterface*>(this); 64 } 65 66 const I422BufferInterface* VideoFrameBuffer::GetI422() const { 67 RTC_CHECK(type() == Type::kI422); 68 return static_cast<const I422BufferInterface*>(this); 69 } 70 71 const I010BufferInterface* VideoFrameBuffer::GetI010() const { 72 RTC_CHECK(type() == Type::kI010); 73 return static_cast<const I010BufferInterface*>(this); 74 } 75 76 const I210BufferInterface* VideoFrameBuffer::GetI210() const { 77 RTC_CHECK(type() == Type::kI210); 78 return static_cast<const I210BufferInterface*>(this); 79 } 80 81 const I410BufferInterface* VideoFrameBuffer::GetI410() const { 82 RTC_CHECK(type() == Type::kI410); 83 return static_cast<const I410BufferInterface*>(this); 84 } 85 86 const NV12BufferInterface* VideoFrameBuffer::GetNV12() const { 87 RTC_CHECK(type() == Type::kNV12); 88 return static_cast<const NV12BufferInterface*>(this); 89 } 90 91 scoped_refptr<VideoFrameBuffer> VideoFrameBuffer::GetMappedFrameBuffer( 92 ArrayView<Type> /* types */) { 93 RTC_CHECK(type() == Type::kNative); 94 return nullptr; 95 } 96 97 std::string VideoFrameBuffer::storage_representation() const { 98 return "?"; 99 } 100 101 VideoFrameBuffer::Type I420BufferInterface::type() const { 102 return Type::kI420; 103 } 104 105 const char* VideoFrameBufferTypeToString(VideoFrameBuffer::Type type) { 106 switch (type) { 107 case VideoFrameBuffer::Type::kNative: 108 return "kNative"; 109 case VideoFrameBuffer::Type::kI420: 110 return "kI420"; 111 case VideoFrameBuffer::Type::kI420A: 112 return "kI420A"; 113 case VideoFrameBuffer::Type::kI444: 114 return "kI444"; 115 case VideoFrameBuffer::Type::kI422: 116 return "kI422"; 117 case VideoFrameBuffer::Type::kI010: 118 return "kI010"; 119 case VideoFrameBuffer::Type::kI210: 120 return "kI210"; 121 case VideoFrameBuffer::Type::kI410: 122 return "kI410"; 123 case VideoFrameBuffer::Type::kNV12: 124 return "kNV12"; 125 default: 126 RTC_DCHECK_NOTREACHED(); 127 } 128 } 129 130 int I420BufferInterface::ChromaWidth() const { 131 return (width() + 1) / 2; 132 } 133 134 int I420BufferInterface::ChromaHeight() const { 135 return (height() + 1) / 2; 136 } 137 138 scoped_refptr<I420BufferInterface> I420BufferInterface::ToI420() { 139 return scoped_refptr<I420BufferInterface>(this); 140 } 141 142 const I420BufferInterface* I420BufferInterface::GetI420() const { 143 return this; 144 } 145 146 VideoFrameBuffer::Type I420ABufferInterface::type() const { 147 return Type::kI420A; 148 } 149 150 VideoFrameBuffer::Type I444BufferInterface::type() const { 151 return Type::kI444; 152 } 153 154 int I444BufferInterface::ChromaWidth() const { 155 return width(); 156 } 157 158 int I444BufferInterface::ChromaHeight() const { 159 return height(); 160 } 161 162 scoped_refptr<VideoFrameBuffer> I444BufferInterface::CropAndScale( 163 int offset_x, 164 int offset_y, 165 int crop_width, 166 int crop_height, 167 int scaled_width, 168 int scaled_height) { 169 scoped_refptr<I444Buffer> result = 170 I444Buffer::Create(scaled_width, scaled_height); 171 result->CropAndScaleFrom(*this, offset_x, offset_y, crop_width, crop_height); 172 return result; 173 } 174 175 VideoFrameBuffer::Type I422BufferInterface::type() const { 176 return Type::kI422; 177 } 178 179 int I422BufferInterface::ChromaWidth() const { 180 return (width() + 1) / 2; 181 } 182 183 int I422BufferInterface::ChromaHeight() const { 184 return height(); 185 } 186 187 scoped_refptr<VideoFrameBuffer> I422BufferInterface::CropAndScale( 188 int offset_x, 189 int offset_y, 190 int crop_width, 191 int crop_height, 192 int scaled_width, 193 int scaled_height) { 194 scoped_refptr<I422Buffer> result = 195 I422Buffer::Create(scaled_width, scaled_height); 196 result->CropAndScaleFrom(*this, offset_x, offset_y, crop_width, crop_height); 197 return result; 198 } 199 200 VideoFrameBuffer::Type I010BufferInterface::type() const { 201 return Type::kI010; 202 } 203 204 int I010BufferInterface::ChromaWidth() const { 205 return (width() + 1) / 2; 206 } 207 208 int I010BufferInterface::ChromaHeight() const { 209 return (height() + 1) / 2; 210 } 211 212 VideoFrameBuffer::Type I210BufferInterface::type() const { 213 return Type::kI210; 214 } 215 216 int I210BufferInterface::ChromaWidth() const { 217 return (width() + 1) / 2; 218 } 219 220 int I210BufferInterface::ChromaHeight() const { 221 return height(); 222 } 223 224 VideoFrameBuffer::Type I410BufferInterface::type() const { 225 return Type::kI410; 226 } 227 228 int I410BufferInterface::ChromaWidth() const { 229 return width(); 230 } 231 232 int I410BufferInterface::ChromaHeight() const { 233 return height(); 234 } 235 236 VideoFrameBuffer::Type NV12BufferInterface::type() const { 237 return Type::kNV12; 238 } 239 240 int NV12BufferInterface::ChromaWidth() const { 241 return (width() + 1) / 2; 242 } 243 244 int NV12BufferInterface::ChromaHeight() const { 245 return (height() + 1) / 2; 246 } 247 248 scoped_refptr<VideoFrameBuffer> NV12BufferInterface::CropAndScale( 249 int offset_x, 250 int offset_y, 251 int crop_width, 252 int crop_height, 253 int scaled_width, 254 int scaled_height) { 255 scoped_refptr<NV12Buffer> result = 256 NV12Buffer::Create(scaled_width, scaled_height); 257 result->CropAndScaleFrom(*this, offset_x, offset_y, crop_width, crop_height); 258 return result; 259 } 260 261 void CheckValidDimensions(int width, 262 int height, 263 int stride_y, 264 int stride_u, 265 int stride_v) { 266 RTC_CHECK_GT(width, 0); 267 RTC_CHECK_GT(height, 0); 268 RTC_CHECK_GE(stride_y, width); 269 RTC_CHECK_GT(stride_u, 0); 270 RTC_CHECK_GT(stride_v, 0); 271 } 272 273 } // namespace webrtc