| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #include "webrtc/base/logging.h" | 33 #include "webrtc/base/logging.h" |
| 34 #include "webrtc/video_frame.h" | 34 #include "webrtc/video_frame.h" |
| 35 | 35 |
| 36 using webrtc::kYPlane; | 36 using webrtc::kYPlane; |
| 37 using webrtc::kUPlane; | 37 using webrtc::kUPlane; |
| 38 using webrtc::kVPlane; | 38 using webrtc::kVPlane; |
| 39 | 39 |
| 40 namespace cricket { | 40 namespace cricket { |
| 41 | 41 |
| 42 WebRtcVideoFrame::WebRtcVideoFrame(): | 42 WebRtcVideoFrame::WebRtcVideoFrame(): |
| 43 pixel_width_(0), |
| 44 pixel_height_(0), |
| 43 time_stamp_ns_(0), | 45 time_stamp_ns_(0), |
| 44 rotation_(webrtc::kVideoRotation_0) {} | 46 rotation_(webrtc::kVideoRotation_0) {} |
| 45 | 47 |
| 46 WebRtcVideoFrame::WebRtcVideoFrame( | 48 WebRtcVideoFrame::WebRtcVideoFrame( |
| 47 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, | 49 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, |
| 48 int64_t time_stamp_ns, | 50 int64_t time_stamp_ns, |
| 49 webrtc::VideoRotation rotation) | 51 webrtc::VideoRotation rotation) |
| 50 : video_frame_buffer_(buffer), | 52 : video_frame_buffer_(buffer), |
| 53 pixel_width_(1), |
| 54 pixel_height_(1), |
| 51 time_stamp_ns_(time_stamp_ns), | 55 time_stamp_ns_(time_stamp_ns), |
| 52 rotation_(rotation) { | 56 rotation_(rotation) { |
| 53 } | 57 } |
| 54 | 58 |
| 55 WebRtcVideoFrame::~WebRtcVideoFrame() {} | 59 WebRtcVideoFrame::~WebRtcVideoFrame() {} |
| 56 | 60 |
| 57 bool WebRtcVideoFrame::Init(uint32_t format, | 61 bool WebRtcVideoFrame::Init(uint32_t format, |
| 58 int w, | 62 int w, |
| 59 int h, | 63 int h, |
| 60 int dw, | 64 int dw, |
| 61 int dh, | 65 int dh, |
| 62 uint8_t* sample, | 66 uint8_t* sample, |
| 63 size_t sample_size, | 67 size_t sample_size, |
| 68 size_t pixel_width, |
| 69 size_t pixel_height, |
| 64 int64_t time_stamp_ns, | 70 int64_t time_stamp_ns, |
| 65 webrtc::VideoRotation rotation) { | 71 webrtc::VideoRotation rotation) { |
| 66 return Reset(format, w, h, dw, dh, sample, sample_size, | 72 return Reset(format, w, h, dw, dh, sample, sample_size, pixel_width, |
| 67 time_stamp_ns, rotation, | 73 pixel_height, time_stamp_ns, rotation, |
| 68 true /*apply_rotation*/); | 74 true /*apply_rotation*/); |
| 69 } | 75 } |
| 70 | 76 |
| 71 bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh, | 77 bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh, |
| 72 bool apply_rotation) { | 78 bool apply_rotation) { |
| 73 return Reset(frame->fourcc, frame->width, frame->height, dw, dh, | 79 return Reset(frame->fourcc, frame->width, frame->height, dw, dh, |
| 74 static_cast<uint8_t*>(frame->data), frame->data_size, | 80 static_cast<uint8_t*>(frame->data), frame->data_size, |
| 75 frame->time_stamp, | 81 frame->pixel_width, frame->pixel_height, frame->time_stamp, |
| 76 frame->rotation, apply_rotation); | 82 frame->rotation, apply_rotation); |
| 77 } | 83 } |
| 78 | 84 |
| 79 bool WebRtcVideoFrame::InitToBlack(int w, int h, | 85 bool WebRtcVideoFrame::InitToBlack(int w, int h, size_t pixel_width, |
| 80 int64_t time_stamp_ns) { | 86 size_t pixel_height, int64_t time_stamp_ns) { |
| 81 InitToEmptyBuffer(w, h, time_stamp_ns); | 87 InitToEmptyBuffer(w, h, pixel_width, pixel_height, time_stamp_ns); |
| 82 return SetToBlack(); | 88 return SetToBlack(); |
| 83 } | 89 } |
| 84 | 90 |
| 85 size_t WebRtcVideoFrame::GetWidth() const { | 91 size_t WebRtcVideoFrame::GetWidth() const { |
| 86 return video_frame_buffer_ ? video_frame_buffer_->width() : 0; | 92 return video_frame_buffer_ ? video_frame_buffer_->width() : 0; |
| 87 } | 93 } |
| 88 | 94 |
| 89 size_t WebRtcVideoFrame::GetHeight() const { | 95 size_t WebRtcVideoFrame::GetHeight() const { |
| 90 return video_frame_buffer_ ? video_frame_buffer_->height() : 0; | 96 return video_frame_buffer_ ? video_frame_buffer_->height() : 0; |
| 91 } | 97 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } | 144 } |
| 139 | 145 |
| 140 rtc::scoped_refptr<webrtc::VideoFrameBuffer> | 146 rtc::scoped_refptr<webrtc::VideoFrameBuffer> |
| 141 WebRtcVideoFrame::GetVideoFrameBuffer() const { | 147 WebRtcVideoFrame::GetVideoFrameBuffer() const { |
| 142 return video_frame_buffer_; | 148 return video_frame_buffer_; |
| 143 } | 149 } |
| 144 | 150 |
| 145 VideoFrame* WebRtcVideoFrame::Copy() const { | 151 VideoFrame* WebRtcVideoFrame::Copy() const { |
| 146 WebRtcVideoFrame* new_frame = new WebRtcVideoFrame( | 152 WebRtcVideoFrame* new_frame = new WebRtcVideoFrame( |
| 147 video_frame_buffer_, time_stamp_ns_, rotation_); | 153 video_frame_buffer_, time_stamp_ns_, rotation_); |
| 154 new_frame->pixel_width_ = pixel_width_; |
| 155 new_frame->pixel_height_ = pixel_height_; |
| 148 return new_frame; | 156 return new_frame; |
| 149 } | 157 } |
| 150 | 158 |
| 151 bool WebRtcVideoFrame::MakeExclusive() { | 159 bool WebRtcVideoFrame::MakeExclusive() { |
| 152 RTC_DCHECK(video_frame_buffer_->native_handle() == nullptr); | 160 RTC_DCHECK(video_frame_buffer_->native_handle() == nullptr); |
| 153 if (IsExclusive()) | 161 if (IsExclusive()) |
| 154 return true; | 162 return true; |
| 155 | 163 |
| 156 // Not exclusive already, need to copy buffer. | 164 // Not exclusive already, need to copy buffer. |
| 157 rtc::scoped_refptr<webrtc::VideoFrameBuffer> new_buffer = | 165 rtc::scoped_refptr<webrtc::VideoFrameBuffer> new_buffer = |
| (...skipping 23 matching lines...) Expand all Loading... |
| 181 return VideoFrame::ConvertToRgbBuffer(to_fourcc, buffer, size, stride_rgb); | 189 return VideoFrame::ConvertToRgbBuffer(to_fourcc, buffer, size, stride_rgb); |
| 182 } | 190 } |
| 183 | 191 |
| 184 bool WebRtcVideoFrame::Reset(uint32_t format, | 192 bool WebRtcVideoFrame::Reset(uint32_t format, |
| 185 int w, | 193 int w, |
| 186 int h, | 194 int h, |
| 187 int dw, | 195 int dw, |
| 188 int dh, | 196 int dh, |
| 189 uint8_t* sample, | 197 uint8_t* sample, |
| 190 size_t sample_size, | 198 size_t sample_size, |
| 199 size_t pixel_width, |
| 200 size_t pixel_height, |
| 191 int64_t time_stamp_ns, | 201 int64_t time_stamp_ns, |
| 192 webrtc::VideoRotation rotation, | 202 webrtc::VideoRotation rotation, |
| 193 bool apply_rotation) { | 203 bool apply_rotation) { |
| 194 if (!Validate(format, w, h, sample, sample_size)) { | 204 if (!Validate(format, w, h, sample, sample_size)) { |
| 195 return false; | 205 return false; |
| 196 } | 206 } |
| 197 // Translate aliases to standard enums (e.g., IYUV -> I420). | 207 // Translate aliases to standard enums (e.g., IYUV -> I420). |
| 198 format = CanonicalFourCC(format); | 208 format = CanonicalFourCC(format); |
| 199 | 209 |
| 200 // Set up a new buffer. | 210 // Set up a new buffer. |
| 201 // TODO(fbarchard): Support lazy allocation. | 211 // TODO(fbarchard): Support lazy allocation. |
| 202 int new_width = dw; | 212 int new_width = dw; |
| 203 int new_height = dh; | 213 int new_height = dh; |
| 204 // If rotated swap width, height. | 214 // If rotated swap width, height. |
| 205 if (apply_rotation && (rotation == 90 || rotation == 270)) { | 215 if (apply_rotation && (rotation == 90 || rotation == 270)) { |
| 206 new_width = dh; | 216 new_width = dh; |
| 207 new_height = dw; | 217 new_height = dw; |
| 208 } | 218 } |
| 209 | 219 |
| 210 InitToEmptyBuffer(new_width, new_height, | 220 InitToEmptyBuffer(new_width, new_height, pixel_width, pixel_height, |
| 211 time_stamp_ns); | 221 time_stamp_ns); |
| 212 rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation; | 222 rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation; |
| 213 | 223 |
| 214 int horiz_crop = ((w - dw) / 2) & ~1; | 224 int horiz_crop = ((w - dw) / 2) & ~1; |
| 215 // ARGB on Windows has negative height. | 225 // ARGB on Windows has negative height. |
| 216 // The sample's layout in memory is normal, so just correct crop. | 226 // The sample's layout in memory is normal, so just correct crop. |
| 217 int vert_crop = ((abs(h) - dh) / 2) & ~1; | 227 int vert_crop = ((abs(h) - dh) / 2) & ~1; |
| 218 // Conversion functions expect negative height to flip the image. | 228 // Conversion functions expect negative height to flip the image. |
| 219 int idh = (h < 0) ? -dh : dh; | 229 int idh = (h < 0) ? -dh : dh; |
| 220 int r = libyuv::ConvertToI420( | 230 int r = libyuv::ConvertToI420( |
| 221 sample, sample_size, | 231 sample, sample_size, |
| 222 GetYPlane(), GetYPitch(), | 232 GetYPlane(), GetYPitch(), |
| 223 GetUPlane(), GetUPitch(), | 233 GetUPlane(), GetUPitch(), |
| 224 GetVPlane(), GetVPitch(), | 234 GetVPlane(), GetVPitch(), |
| 225 horiz_crop, vert_crop, | 235 horiz_crop, vert_crop, |
| 226 w, h, | 236 w, h, |
| 227 dw, idh, | 237 dw, idh, |
| 228 static_cast<libyuv::RotationMode>( | 238 static_cast<libyuv::RotationMode>( |
| 229 apply_rotation ? rotation : webrtc::kVideoRotation_0), | 239 apply_rotation ? rotation : webrtc::kVideoRotation_0), |
| 230 format); | 240 format); |
| 231 if (r) { | 241 if (r) { |
| 232 LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format) | 242 LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format) |
| 233 << " return code : " << r; | 243 << " return code : " << r; |
| 234 return false; | 244 return false; |
| 235 } | 245 } |
| 236 return true; | 246 return true; |
| 237 } | 247 } |
| 238 | 248 |
| 239 VideoFrame* WebRtcVideoFrame::CreateEmptyFrame( | 249 VideoFrame* WebRtcVideoFrame::CreateEmptyFrame( |
| 240 int w, int h, | 250 int w, int h, size_t pixel_width, size_t pixel_height, |
| 241 int64_t time_stamp_ns) const { | 251 int64_t time_stamp_ns) const { |
| 242 WebRtcVideoFrame* frame = new WebRtcVideoFrame(); | 252 WebRtcVideoFrame* frame = new WebRtcVideoFrame(); |
| 243 frame->InitToEmptyBuffer(w, h, time_stamp_ns); | 253 frame->InitToEmptyBuffer(w, h, pixel_width, pixel_height, time_stamp_ns); |
| 244 return frame; | 254 return frame; |
| 245 } | 255 } |
| 246 | 256 |
| 247 void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h, | 257 void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h, size_t pixel_width, |
| 258 size_t pixel_height, |
| 248 int64_t time_stamp_ns) { | 259 int64_t time_stamp_ns) { |
| 249 video_frame_buffer_ = new rtc::RefCountedObject<webrtc::I420Buffer>(w, h); | 260 video_frame_buffer_ = new rtc::RefCountedObject<webrtc::I420Buffer>(w, h); |
| 261 pixel_width_ = pixel_width; |
| 262 pixel_height_ = pixel_height; |
| 250 time_stamp_ns_ = time_stamp_ns; | 263 time_stamp_ns_ = time_stamp_ns; |
| 251 rotation_ = webrtc::kVideoRotation_0; | 264 rotation_ = webrtc::kVideoRotation_0; |
| 252 } | 265 } |
| 253 | 266 |
| 254 const VideoFrame* WebRtcVideoFrame::GetCopyWithRotationApplied() const { | 267 const VideoFrame* WebRtcVideoFrame::GetCopyWithRotationApplied() const { |
| 255 // If the frame is not rotated, the caller should reuse this frame instead of | 268 // If the frame is not rotated, the caller should reuse this frame instead of |
| 256 // making a redundant copy. | 269 // making a redundant copy. |
| 257 if (GetVideoRotation() == webrtc::kVideoRotation_0) { | 270 if (GetVideoRotation() == webrtc::kVideoRotation_0) { |
| 258 return this; | 271 return this; |
| 259 } | 272 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 272 | 285 |
| 273 int rotated_width = width; | 286 int rotated_width = width; |
| 274 int rotated_height = height; | 287 int rotated_height = height; |
| 275 if (GetVideoRotation() == webrtc::kVideoRotation_90 || | 288 if (GetVideoRotation() == webrtc::kVideoRotation_90 || |
| 276 GetVideoRotation() == webrtc::kVideoRotation_270) { | 289 GetVideoRotation() == webrtc::kVideoRotation_270) { |
| 277 rotated_width = height; | 290 rotated_width = height; |
| 278 rotated_height = width; | 291 rotated_height = width; |
| 279 } | 292 } |
| 280 | 293 |
| 281 rotated_frame_.reset(CreateEmptyFrame(rotated_width, rotated_height, | 294 rotated_frame_.reset(CreateEmptyFrame(rotated_width, rotated_height, |
| 295 GetPixelWidth(), GetPixelHeight(), |
| 282 GetTimeStamp())); | 296 GetTimeStamp())); |
| 283 | 297 |
| 284 // TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from | 298 // TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from |
| 285 // VideoRotation to libyuv::RotationMode. | 299 // VideoRotation to libyuv::RotationMode. |
| 286 int ret = libyuv::I420Rotate( | 300 int ret = libyuv::I420Rotate( |
| 287 GetYPlane(), GetYPitch(), GetUPlane(), GetUPitch(), GetVPlane(), | 301 GetYPlane(), GetYPitch(), GetUPlane(), GetUPitch(), GetVPlane(), |
| 288 GetVPitch(), rotated_frame_->GetYPlane(), rotated_frame_->GetYPitch(), | 302 GetVPitch(), rotated_frame_->GetYPlane(), rotated_frame_->GetYPitch(), |
| 289 rotated_frame_->GetUPlane(), rotated_frame_->GetUPitch(), | 303 rotated_frame_->GetUPlane(), rotated_frame_->GetUPitch(), |
| 290 rotated_frame_->GetVPlane(), rotated_frame_->GetVPitch(), width, height, | 304 rotated_frame_->GetVPlane(), rotated_frame_->GetVPitch(), width, height, |
| 291 static_cast<libyuv::RotationMode>(GetVideoRotation())); | 305 static_cast<libyuv::RotationMode>(GetVideoRotation())); |
| 292 if (ret == 0) { | 306 if (ret == 0) { |
| 293 return rotated_frame_.get(); | 307 return rotated_frame_.get(); |
| 294 } | 308 } |
| 295 return nullptr; | 309 return nullptr; |
| 296 } | 310 } |
| 297 | 311 |
| 298 } // namespace cricket | 312 } // namespace cricket |
| OLD | NEW |