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 24 matching lines...) Expand all Loading... |
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), | 43 pixel_width_(0), |
44 pixel_height_(0), | 44 pixel_height_(0), |
45 elapsed_time_ns_(0), | |
46 time_stamp_ns_(0), | 45 time_stamp_ns_(0), |
47 rotation_(webrtc::kVideoRotation_0) {} | 46 rotation_(webrtc::kVideoRotation_0) {} |
48 | 47 |
49 WebRtcVideoFrame::WebRtcVideoFrame( | 48 WebRtcVideoFrame::WebRtcVideoFrame( |
50 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, | 49 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, |
51 int64_t elapsed_time_ns, | |
52 int64_t time_stamp_ns, | 50 int64_t time_stamp_ns, |
53 webrtc::VideoRotation rotation) | 51 webrtc::VideoRotation rotation) |
54 : video_frame_buffer_(buffer), | 52 : video_frame_buffer_(buffer), |
55 pixel_width_(1), | 53 pixel_width_(1), |
56 pixel_height_(1), | 54 pixel_height_(1), |
57 elapsed_time_ns_(elapsed_time_ns), | |
58 time_stamp_ns_(time_stamp_ns), | 55 time_stamp_ns_(time_stamp_ns), |
59 rotation_(rotation) { | 56 rotation_(rotation) { |
60 } | 57 } |
61 | 58 |
62 WebRtcVideoFrame::WebRtcVideoFrame( | 59 WebRtcVideoFrame::WebRtcVideoFrame( |
63 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, | 60 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, |
64 int64_t elapsed_time_ns, | 61 int64_t elapsed_time_ns, |
65 int64_t time_stamp_ns) | 62 int64_t time_stamp_ns) |
66 : video_frame_buffer_(buffer), | 63 : video_frame_buffer_(buffer), |
67 pixel_width_(1), | 64 pixel_width_(1), |
68 pixel_height_(1), | 65 pixel_height_(1), |
69 elapsed_time_ns_(elapsed_time_ns), | |
70 time_stamp_ns_(time_stamp_ns), | 66 time_stamp_ns_(time_stamp_ns), |
71 rotation_(webrtc::kVideoRotation_0) { | 67 rotation_(webrtc::kVideoRotation_0) { |
72 } | 68 } |
73 | 69 |
74 WebRtcVideoFrame::~WebRtcVideoFrame() {} | 70 WebRtcVideoFrame::~WebRtcVideoFrame() {} |
75 | 71 |
76 bool WebRtcVideoFrame::Init(uint32 format, | 72 bool WebRtcVideoFrame::Init(uint32 format, |
77 int w, | 73 int w, |
78 int h, | 74 int h, |
79 int dw, | 75 int dw, |
80 int dh, | 76 int dh, |
81 uint8* sample, | 77 uint8* sample, |
82 size_t sample_size, | 78 size_t sample_size, |
83 size_t pixel_width, | 79 size_t pixel_width, |
84 size_t pixel_height, | 80 size_t pixel_height, |
85 int64_t elapsed_time_ns, | |
86 int64_t time_stamp_ns, | 81 int64_t time_stamp_ns, |
87 webrtc::VideoRotation rotation) { | 82 webrtc::VideoRotation rotation) { |
88 return Reset(format, w, h, dw, dh, sample, sample_size, pixel_width, | 83 return Reset(format, w, h, dw, dh, sample, sample_size, pixel_width, |
89 pixel_height, elapsed_time_ns, time_stamp_ns, rotation, | 84 pixel_height, time_stamp_ns, rotation, |
90 true /*apply_rotation*/); | 85 true /*apply_rotation*/); |
91 } | 86 } |
92 | 87 |
93 bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh, | 88 bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh, |
94 bool apply_rotation) { | 89 bool apply_rotation) { |
95 return Reset(frame->fourcc, frame->width, frame->height, dw, dh, | 90 return Reset(frame->fourcc, frame->width, frame->height, dw, dh, |
96 static_cast<uint8*>(frame->data), frame->data_size, | 91 static_cast<uint8*>(frame->data), frame->data_size, |
97 frame->pixel_width, frame->pixel_height, frame->elapsed_time, | 92 frame->pixel_width, frame->pixel_height, |
98 frame->time_stamp, | 93 frame->time_stamp, |
99 frame->GetRotation(), | 94 frame->GetRotation(), |
100 apply_rotation); | 95 apply_rotation); |
101 } | 96 } |
102 | 97 |
103 bool WebRtcVideoFrame::InitToBlack(int w, int h, size_t pixel_width, | 98 bool WebRtcVideoFrame::InitToBlack(int w, int h, size_t pixel_width, |
104 size_t pixel_height, int64_t elapsed_time_ns, | 99 size_t pixel_height, int64_t, |
105 int64_t time_stamp_ns) { | 100 int64_t time_stamp_ns) { |
106 InitToEmptyBuffer(w, h, pixel_width, pixel_height, elapsed_time_ns, | 101 return InitToBlack(w, h, pixel_width, pixel_height, time_stamp_ns); |
107 time_stamp_ns); | 102 } |
| 103 |
| 104 bool WebRtcVideoFrame::InitToBlack(int w, int h, size_t pixel_width, |
| 105 size_t pixel_height, int64_t time_stamp_ns) { |
| 106 InitToEmptyBuffer(w, h, pixel_width, pixel_height, time_stamp_ns); |
108 return SetToBlack(); | 107 return SetToBlack(); |
109 } | 108 } |
110 | 109 |
111 size_t WebRtcVideoFrame::GetWidth() const { | 110 size_t WebRtcVideoFrame::GetWidth() const { |
112 return video_frame_buffer_ ? video_frame_buffer_->width() : 0; | 111 return video_frame_buffer_ ? video_frame_buffer_->width() : 0; |
113 } | 112 } |
114 | 113 |
115 size_t WebRtcVideoFrame::GetHeight() const { | 114 size_t WebRtcVideoFrame::GetHeight() const { |
116 return video_frame_buffer_ ? video_frame_buffer_->height() : 0; | 115 return video_frame_buffer_ ? video_frame_buffer_->height() : 0; |
117 } | 116 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 return video_frame_buffer_ ? video_frame_buffer_->native_handle() : nullptr; | 162 return video_frame_buffer_ ? video_frame_buffer_->native_handle() : nullptr; |
164 } | 163 } |
165 | 164 |
166 rtc::scoped_refptr<webrtc::VideoFrameBuffer> | 165 rtc::scoped_refptr<webrtc::VideoFrameBuffer> |
167 WebRtcVideoFrame::GetVideoFrameBuffer() const { | 166 WebRtcVideoFrame::GetVideoFrameBuffer() const { |
168 return video_frame_buffer_; | 167 return video_frame_buffer_; |
169 } | 168 } |
170 | 169 |
171 VideoFrame* WebRtcVideoFrame::Copy() const { | 170 VideoFrame* WebRtcVideoFrame::Copy() const { |
172 WebRtcVideoFrame* new_frame = new WebRtcVideoFrame( | 171 WebRtcVideoFrame* new_frame = new WebRtcVideoFrame( |
173 video_frame_buffer_, elapsed_time_ns_, time_stamp_ns_, rotation_); | 172 video_frame_buffer_, time_stamp_ns_, rotation_); |
174 new_frame->pixel_width_ = pixel_width_; | 173 new_frame->pixel_width_ = pixel_width_; |
175 new_frame->pixel_height_ = pixel_height_; | 174 new_frame->pixel_height_ = pixel_height_; |
176 return new_frame; | 175 return new_frame; |
177 } | 176 } |
178 | 177 |
179 bool WebRtcVideoFrame::MakeExclusive() { | 178 bool WebRtcVideoFrame::MakeExclusive() { |
180 RTC_DCHECK(video_frame_buffer_->native_handle() == nullptr); | 179 RTC_DCHECK(video_frame_buffer_->native_handle() == nullptr); |
181 if (IsExclusive()) | 180 if (IsExclusive()) |
182 return true; | 181 return true; |
183 | 182 |
(...skipping 25 matching lines...) Expand all Loading... |
209 | 208 |
210 bool WebRtcVideoFrame::Reset(uint32 format, | 209 bool WebRtcVideoFrame::Reset(uint32 format, |
211 int w, | 210 int w, |
212 int h, | 211 int h, |
213 int dw, | 212 int dw, |
214 int dh, | 213 int dh, |
215 uint8* sample, | 214 uint8* sample, |
216 size_t sample_size, | 215 size_t sample_size, |
217 size_t pixel_width, | 216 size_t pixel_width, |
218 size_t pixel_height, | 217 size_t pixel_height, |
219 int64_t elapsed_time_ns, | |
220 int64_t time_stamp_ns, | 218 int64_t time_stamp_ns, |
221 webrtc::VideoRotation rotation, | 219 webrtc::VideoRotation rotation, |
222 bool apply_rotation) { | 220 bool apply_rotation) { |
223 if (!Validate(format, w, h, sample, sample_size)) { | 221 if (!Validate(format, w, h, sample, sample_size)) { |
224 return false; | 222 return false; |
225 } | 223 } |
226 // Translate aliases to standard enums (e.g., IYUV -> I420). | 224 // Translate aliases to standard enums (e.g., IYUV -> I420). |
227 format = CanonicalFourCC(format); | 225 format = CanonicalFourCC(format); |
228 | 226 |
229 // Set up a new buffer. | 227 // Set up a new buffer. |
230 // TODO(fbarchard): Support lazy allocation. | 228 // TODO(fbarchard): Support lazy allocation. |
231 int new_width = dw; | 229 int new_width = dw; |
232 int new_height = dh; | 230 int new_height = dh; |
233 // If rotated swap width, height. | 231 // If rotated swap width, height. |
234 if (apply_rotation && (rotation == 90 || rotation == 270)) { | 232 if (apply_rotation && (rotation == 90 || rotation == 270)) { |
235 new_width = dh; | 233 new_width = dh; |
236 new_height = dw; | 234 new_height = dw; |
237 } | 235 } |
238 | 236 |
239 InitToEmptyBuffer(new_width, new_height, pixel_width, pixel_height, | 237 InitToEmptyBuffer(new_width, new_height, pixel_width, pixel_height, |
240 elapsed_time_ns, time_stamp_ns); | 238 time_stamp_ns); |
241 rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation; | 239 rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation; |
242 | 240 |
243 int horiz_crop = ((w - dw) / 2) & ~1; | 241 int horiz_crop = ((w - dw) / 2) & ~1; |
244 // ARGB on Windows has negative height. | 242 // ARGB on Windows has negative height. |
245 // The sample's layout in memory is normal, so just correct crop. | 243 // The sample's layout in memory is normal, so just correct crop. |
246 int vert_crop = ((abs(h) - dh) / 2) & ~1; | 244 int vert_crop = ((abs(h) - dh) / 2) & ~1; |
247 // Conversion functions expect negative height to flip the image. | 245 // Conversion functions expect negative height to flip the image. |
248 int idh = (h < 0) ? -dh : dh; | 246 int idh = (h < 0) ? -dh : dh; |
249 int r = libyuv::ConvertToI420( | 247 int r = libyuv::ConvertToI420( |
250 sample, sample_size, | 248 sample, sample_size, |
251 GetYPlane(), GetYPitch(), | 249 GetYPlane(), GetYPitch(), |
252 GetUPlane(), GetUPitch(), | 250 GetUPlane(), GetUPitch(), |
253 GetVPlane(), GetVPitch(), | 251 GetVPlane(), GetVPitch(), |
254 horiz_crop, vert_crop, | 252 horiz_crop, vert_crop, |
255 w, h, | 253 w, h, |
256 dw, idh, | 254 dw, idh, |
257 static_cast<libyuv::RotationMode>( | 255 static_cast<libyuv::RotationMode>( |
258 apply_rotation ? rotation : webrtc::kVideoRotation_0), | 256 apply_rotation ? rotation : webrtc::kVideoRotation_0), |
259 format); | 257 format); |
260 if (r) { | 258 if (r) { |
261 LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format) | 259 LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format) |
262 << " return code : " << r; | 260 << " return code : " << r; |
263 return false; | 261 return false; |
264 } | 262 } |
265 return true; | 263 return true; |
266 } | 264 } |
267 | 265 |
268 VideoFrame* WebRtcVideoFrame::CreateEmptyFrame( | 266 VideoFrame* WebRtcVideoFrame::CreateEmptyFrame( |
269 int w, int h, size_t pixel_width, size_t pixel_height, | 267 int w, int h, size_t pixel_width, size_t pixel_height, |
270 int64_t elapsed_time_ns, int64_t time_stamp_ns) const { | 268 int64_t time_stamp_ns) const { |
271 WebRtcVideoFrame* frame = new WebRtcVideoFrame(); | 269 WebRtcVideoFrame* frame = new WebRtcVideoFrame(); |
272 frame->InitToEmptyBuffer(w, h, pixel_width, pixel_height, elapsed_time_ns, | 270 frame->InitToEmptyBuffer(w, h, pixel_width, pixel_height, time_stamp_ns); |
273 time_stamp_ns); | |
274 return frame; | 271 return frame; |
275 } | 272 } |
276 | 273 |
277 void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h, size_t pixel_width, | 274 void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h, size_t pixel_width, |
278 size_t pixel_height, | 275 size_t pixel_height, |
279 int64_t elapsed_time_ns, | |
280 int64_t time_stamp_ns) { | 276 int64_t time_stamp_ns) { |
281 video_frame_buffer_ = new rtc::RefCountedObject<webrtc::I420Buffer>(w, h); | 277 video_frame_buffer_ = new rtc::RefCountedObject<webrtc::I420Buffer>(w, h); |
282 pixel_width_ = pixel_width; | 278 pixel_width_ = pixel_width; |
283 pixel_height_ = pixel_height; | 279 pixel_height_ = pixel_height; |
284 elapsed_time_ns_ = elapsed_time_ns; | |
285 time_stamp_ns_ = time_stamp_ns; | 280 time_stamp_ns_ = time_stamp_ns; |
286 rotation_ = webrtc::kVideoRotation_0; | 281 rotation_ = webrtc::kVideoRotation_0; |
287 } | 282 } |
288 | 283 |
289 const VideoFrame* WebRtcVideoFrame::GetCopyWithRotationApplied() const { | 284 const VideoFrame* WebRtcVideoFrame::GetCopyWithRotationApplied() const { |
290 // If the frame is not rotated, the caller should reuse this frame instead of | 285 // If the frame is not rotated, the caller should reuse this frame instead of |
291 // making a redundant copy. | 286 // making a redundant copy. |
292 if (GetVideoRotation() == webrtc::kVideoRotation_0) { | 287 if (GetVideoRotation() == webrtc::kVideoRotation_0) { |
293 return this; | 288 return this; |
294 } | 289 } |
(...skipping 13 matching lines...) Expand all Loading... |
308 int rotated_width = width; | 303 int rotated_width = width; |
309 int rotated_height = height; | 304 int rotated_height = height; |
310 if (GetVideoRotation() == webrtc::kVideoRotation_90 || | 305 if (GetVideoRotation() == webrtc::kVideoRotation_90 || |
311 GetVideoRotation() == webrtc::kVideoRotation_270) { | 306 GetVideoRotation() == webrtc::kVideoRotation_270) { |
312 rotated_width = height; | 307 rotated_width = height; |
313 rotated_height = width; | 308 rotated_height = width; |
314 } | 309 } |
315 | 310 |
316 rotated_frame_.reset(CreateEmptyFrame(rotated_width, rotated_height, | 311 rotated_frame_.reset(CreateEmptyFrame(rotated_width, rotated_height, |
317 GetPixelWidth(), GetPixelHeight(), | 312 GetPixelWidth(), GetPixelHeight(), |
318 GetElapsedTime(), GetTimeStamp())); | 313 GetTimeStamp())); |
319 | 314 |
320 // TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from | 315 // TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from |
321 // VideoRotation to libyuv::RotationMode. | 316 // VideoRotation to libyuv::RotationMode. |
322 int ret = libyuv::I420Rotate( | 317 int ret = libyuv::I420Rotate( |
323 GetYPlane(), GetYPitch(), GetUPlane(), GetUPitch(), GetVPlane(), | 318 GetYPlane(), GetYPitch(), GetUPlane(), GetUPitch(), GetVPlane(), |
324 GetVPitch(), rotated_frame_->GetYPlane(), rotated_frame_->GetYPitch(), | 319 GetVPitch(), rotated_frame_->GetYPlane(), rotated_frame_->GetYPitch(), |
325 rotated_frame_->GetUPlane(), rotated_frame_->GetUPitch(), | 320 rotated_frame_->GetUPlane(), rotated_frame_->GetUPitch(), |
326 rotated_frame_->GetVPlane(), rotated_frame_->GetVPitch(), width, height, | 321 rotated_frame_->GetVPlane(), rotated_frame_->GetVPitch(), width, height, |
327 static_cast<libyuv::RotationMode>(GetVideoRotation())); | 322 static_cast<libyuv::RotationMode>(GetVideoRotation())); |
328 if (ret == 0) { | 323 if (ret == 0) { |
329 return rotated_frame_.get(); | 324 return rotated_frame_.get(); |
330 } | 325 } |
331 return nullptr; | 326 return nullptr; |
332 } | 327 } |
333 | 328 |
334 } // namespace cricket | 329 } // namespace cricket |
OLD | NEW |