Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(728)

Side by Side Diff: content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc

Issue 183113004: Make sure MediaStreamVideoSource support cropping. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Crop with origin 0,0 and temporary disable failing test. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" 5 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/memory/aligned_memory.h"
9 #include "media/base/video_frame.h" 10 #include "media/base/video_frame.h"
11 #include "third_party/libyuv/include/libyuv/convert.h"
10 12
11 namespace content { 13 namespace content {
12 14
13 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast) 15 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast)
14 : is_screencast_(is_screencast), 16 : is_screencast_(is_screencast),
15 running_(false) { 17 running_(false),
18 buffer_(NULL),
19 buffer_size_(0) {
16 } 20 }
17 21
18 WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() { 22 WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() {
19 DVLOG(3) << " WebRtcVideoCapturerAdapter::dtor"; 23 DVLOG(3) << " WebRtcVideoCapturerAdapter::dtor";
24 base::AlignedFree(buffer_);
20 } 25 }
21 26
22 void WebRtcVideoCapturerAdapter::SetRequestedFormat( 27 void WebRtcVideoCapturerAdapter::SetRequestedFormat(
23 const media::VideoCaptureFormat& format) { 28 const media::VideoCaptureFormat& format) {
24 DCHECK_EQ(media::PIXEL_FORMAT_I420, format.pixel_format); 29 DCHECK_EQ(media::PIXEL_FORMAT_I420, format.pixel_format);
25 DVLOG(3) << "WebRtcVideoCapturerAdapter::SetRequestedFormat" 30 DVLOG(3) << "WebRtcVideoCapturerAdapter::SetRequestedFormat"
26 << " w = " << format.frame_size.width() 31 << " w = " << format.frame_size.width()
27 << " h = " << format.frame_size.height(); 32 << " h = " << format.frame_size.height();
28 cricket::VideoFormat supported_format(format.frame_size.width(), 33 cricket::VideoFormat supported_format(format.frame_size.width(),
29 format.frame_size.height(), 34 format.frame_size.height(),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // Use the desired format as the best format. 89 // Use the desired format as the best format.
85 best_format->width = desired.width; 90 best_format->width = desired.width;
86 best_format->height = desired.height; 91 best_format->height = desired.height;
87 best_format->fourcc = cricket::FOURCC_I420; 92 best_format->fourcc = cricket::FOURCC_I420;
88 best_format->interval = desired.interval; 93 best_format->interval = desired.interval;
89 return true; 94 return true;
90 } 95 }
91 96
92 void WebRtcVideoCapturerAdapter::OnFrameCaptured( 97 void WebRtcVideoCapturerAdapter::OnFrameCaptured(
93 const scoped_refptr<media::VideoFrame>& frame) { 98 const scoped_refptr<media::VideoFrame>& frame) {
94 DCHECK_EQ(media::VideoFrame::I420, frame->format()); 99 DCHECK(media::VideoFrame::I420 == frame->format() ||
100 media::VideoFrame::YV12 == frame->format());
95 if (first_frame_timestamp_ == media::kNoTimestamp()) 101 if (first_frame_timestamp_ == media::kNoTimestamp())
96 first_frame_timestamp_ = frame->GetTimestamp(); 102 first_frame_timestamp_ = frame->GetTimestamp();
97 103
98 // Currently, |fourcc| is always I420.
99 cricket::CapturedFrame captured_frame; 104 cricket::CapturedFrame captured_frame;
100 captured_frame.width = frame->coded_size().width(); 105 captured_frame.width = frame->visible_rect().width();
101 captured_frame.height = frame->coded_size().height(); 106 captured_frame.height = frame->visible_rect().height();
102 captured_frame.fourcc = cricket::FOURCC_I420;
103 // cricket::CapturedFrame time is in nanoseconds. 107 // cricket::CapturedFrame time is in nanoseconds.
104 captured_frame.elapsed_time = 108 captured_frame.elapsed_time =
105 (frame->GetTimestamp() - first_frame_timestamp_).InMicroseconds() * 109 (frame->GetTimestamp() - first_frame_timestamp_).InMicroseconds() *
106 base::Time::kNanosecondsPerMicrosecond; 110 base::Time::kNanosecondsPerMicrosecond;
107 captured_frame.time_stamp = frame->GetTimestamp().InMicroseconds() * 111 captured_frame.time_stamp = frame->GetTimestamp().InMicroseconds() *
108 base::Time::kNanosecondsPerMicrosecond; 112 base::Time::kNanosecondsPerMicrosecond;
109 // TODO(sheu): we assume contiguous layout of image planes.
110 captured_frame.data = frame->data(0);
111 captured_frame.data_size =
112 media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
113 captured_frame.pixel_height = 1; 113 captured_frame.pixel_height = 1;
114 captured_frame.pixel_width = 1; 114 captured_frame.pixel_width = 1;
115 115
116 // TODO(perkj):
117 // Libjingle expect contiguous layout of image planes as input.
tommi (sloooow) - chröme 2014/03/06 10:14:09 expects
perkj_chrome 2014/03/06 12:45:42 Done.
118 // The only format where that is true in Chrome is I420 where the
119 // coded_size == visible_rect().size().
120 if (frame->format() != media::VideoFrame::I420 ||
121 frame->coded_size() != frame->visible_rect().size()) {
122 // Cropping and or switching UV planes is needed.
123 UpdateI420Buffer(frame);
124 captured_frame.data = buffer_;
125 captured_frame.data_size = buffer_size_;
126 captured_frame.fourcc = cricket::FOURCC_I420;
127 } else {
128 captured_frame.fourcc =
129 media::VideoFrame::I420 == frame->format() ?
tommi (sloooow) - chröme 2014/03/06 10:14:09 fix indent
perkj_chrome 2014/03/06 12:45:42 Done.
130 cricket::FOURCC_I420 : cricket::FOURCC_YV12;
131 captured_frame.data = frame->data(0);
132 captured_frame.data_size =
133 media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
134 }
135
116 // This signals to libJingle that a new VideoFrame is available. 136 // This signals to libJingle that a new VideoFrame is available.
117 // libJingle have no assumptions on what thread this signal come from. 137 // libJingle have no assumptions on what thread this signal come from.
118 SignalFrameCaptured(this, &captured_frame); 138 SignalFrameCaptured(this, &captured_frame);
119 } 139 }
120 140
141 void WebRtcVideoCapturerAdapter::UpdateI420Buffer(
142 const scoped_refptr<media::VideoFrame>& src) {
143 const int src_width = src->coded_size().width();
144 const int src_height = src->coded_size().height();
145 const int dst_width = src->visible_rect().width();
146 const int dst_height = src->visible_rect().height();
147 DCHECK(src_width > dst_width || src_height > dst_height);
tommi (sloooow) - chröme 2014/03/06 10:14:09 should these checks be >= ? also, should the || b
perkj_chrome 2014/03/06 12:45:42 Done.
148
149 const int horiz_crop = src->visible_rect().x();
150 const int vert_crop = src->visible_rect().y();
151
152 const uint8* src_y = src->data(media::VideoFrame::kYPlane) +
153 (src_width * vert_crop + horiz_crop);
154 const int halfwidth = (src_width + 1) / 2;
tommi (sloooow) - chröme 2014/03/06 10:14:09 half_width (or center depending on how you prefer
perkj_chrome 2014/03/06 12:45:42 Done.
155 const uint8* src_u = src->data(media::VideoFrame::kUPlane) +
156 (halfwidth * vert_crop + horiz_crop) / 2;
157 const uint8* src_v = src->data(media::VideoFrame::kVPlane) +
158 (halfwidth * vert_crop + horiz_crop) / 2;
159
160 const size_t dst_size =
161 media::VideoFrame::AllocationSize(src->format(),
162 src->visible_rect().size());
163
164 if (dst_size != buffer_size_) {
165 base::AlignedFree(buffer_);
166 buffer_ = reinterpret_cast<uint8*>(
167 base::AlignedAlloc(dst_size + media::VideoFrame::kFrameSizePadding,
168 media::VideoFrame::kFrameAddressAlignment));
169 buffer_size_ = dst_size;
170 }
171
172 uint8* dst_y = buffer_;
173 const int dst_stride_y = dst_width;
174 uint8* dst_u = dst_y + dst_width * dst_height;
175 const int dst_halfwidth = (dst_width + 1) / 2;
176 const int dst_halfheight = (dst_height + 1) / 2;
177 uint8* dst_v = dst_u + dst_halfwidth * dst_halfheight;
178
179 libyuv::I420Copy(src_y,
180 src->stride(media::VideoFrame::kYPlane),
181 src_u,
182 src->stride(media::VideoFrame::kUPlane),
183 src_v,
184 src->stride(media::VideoFrame::kVPlane),
185 dst_y,
186 dst_stride_y,
187 dst_u,
188 dst_halfwidth,
189 dst_v,
190 dst_halfwidth,
191 dst_width,
192 dst_height);
193 }
194
121 } // namespace content 195 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698