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

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

Issue 246433006: Change MediaStreamVideoSource to output different resolutions to different tracks depending on the … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 years, 7 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 "base/memory/aligned_memory.h"
10 #include "media/base/video_frame.h" 10 #include "media/base/video_frame.h"
11 #include "third_party/libyuv/include/libyuv/convert.h" 11 #include "third_party/libyuv/include/libyuv/scale.h"
12 12
13 namespace content { 13 namespace content {
14 14
15 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast) 15 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast)
16 : is_screencast_(is_screencast), 16 : is_screencast_(is_screencast),
17 running_(false), 17 running_(false),
18 buffer_(NULL), 18 buffer_(NULL),
19 buffer_size_(0) { 19 buffer_size_(0) {
20 thread_checker_.DetachFromThread(); 20 thread_checker_.DetachFromThread();
21 } 21 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 best_format->width = desired.width; 77 best_format->width = desired.width;
78 best_format->height = desired.height; 78 best_format->height = desired.height;
79 best_format->fourcc = cricket::FOURCC_I420; 79 best_format->fourcc = cricket::FOURCC_I420;
80 best_format->interval = desired.interval; 80 best_format->interval = desired.interval;
81 return true; 81 return true;
82 } 82 }
83 83
84 void WebRtcVideoCapturerAdapter::OnFrameCaptured( 84 void WebRtcVideoCapturerAdapter::OnFrameCaptured(
85 const scoped_refptr<media::VideoFrame>& frame) { 85 const scoped_refptr<media::VideoFrame>& frame) {
86 DCHECK(thread_checker_.CalledOnValidThread()); 86 DCHECK(thread_checker_.CalledOnValidThread());
87 DCHECK(media::VideoFrame::I420 == frame->format() || 87 TRACE_EVENT0("video", "WebRtcVideoCapturerAdapter::OnFrameCaptured");
88 media::VideoFrame::YV12 == frame->format()); 88 if (!(media::VideoFrame::I420 == frame->format() ||
89 media::VideoFrame::YV12 == frame->format())) {
90 // Some types of sources support textures as output. Since connecting
91 // sources and sinks do not check the format, we need to just ignore
92 // formats that we can not handle.
93 NOTREACHED();
94 return;
95 }
96
89 if (first_frame_timestamp_ == media::kNoTimestamp()) 97 if (first_frame_timestamp_ == media::kNoTimestamp())
90 first_frame_timestamp_ = frame->timestamp(); 98 first_frame_timestamp_ = frame->timestamp();
91 99
92 cricket::CapturedFrame captured_frame; 100 cricket::CapturedFrame captured_frame;
93 captured_frame.width = frame->visible_rect().width(); 101 captured_frame.width = frame->natural_size().width();
94 captured_frame.height = frame->visible_rect().height(); 102 captured_frame.height = frame->natural_size().height();
95 // cricket::CapturedFrame time is in nanoseconds. 103 // cricket::CapturedFrame time is in nanoseconds.
96 captured_frame.elapsed_time = 104 captured_frame.elapsed_time =
97 (frame->timestamp() - first_frame_timestamp_).InMicroseconds() * 105 (frame->timestamp() - first_frame_timestamp_).InMicroseconds() *
98 base::Time::kNanosecondsPerMicrosecond; 106 base::Time::kNanosecondsPerMicrosecond;
99 captured_frame.time_stamp = frame->timestamp().InMicroseconds() * 107 captured_frame.time_stamp = frame->timestamp().InMicroseconds() *
100 base::Time::kNanosecondsPerMicrosecond; 108 base::Time::kNanosecondsPerMicrosecond;
101 captured_frame.pixel_height = 1; 109 captured_frame.pixel_height = 1;
102 captured_frame.pixel_width = 1; 110 captured_frame.pixel_width = 1;
103 111
104 // TODO(perkj): 112 // TODO(perkj):
105 // Libjingle expects contiguous layout of image planes as input. 113 // Libjingle expects contiguous layout of image planes as input.
106 // The only format where that is true in Chrome is I420 where the 114 // The only format where that is true in Chrome is I420 where the
107 // coded_size == visible_rect().size(). 115 // coded_size == natural_size().
108 if (frame->format() != media::VideoFrame::I420 || 116 if (frame->format() != media::VideoFrame::I420 ||
109 frame->coded_size() != frame->visible_rect().size()) { 117 frame->coded_size() != frame->natural_size()) {
110 // Cropping and or switching UV planes is needed. 118 // Cropping / Scaling and or switching UV planes is needed.
111 UpdateI420Buffer(frame); 119 UpdateI420Buffer(frame);
112 captured_frame.data = buffer_; 120 captured_frame.data = buffer_;
113 captured_frame.data_size = buffer_size_; 121 captured_frame.data_size = buffer_size_;
114 captured_frame.fourcc = cricket::FOURCC_I420; 122 captured_frame.fourcc = cricket::FOURCC_I420;
115 } else { 123 } else {
116 captured_frame.fourcc = media::VideoFrame::I420 == frame->format() ? 124 captured_frame.fourcc = media::VideoFrame::I420 == frame->format() ?
117 cricket::FOURCC_I420 : cricket::FOURCC_YV12; 125 cricket::FOURCC_I420 : cricket::FOURCC_YV12;
118 captured_frame.data = frame->data(0); 126 captured_frame.data = frame->data(0);
119 captured_frame.data_size = 127 captured_frame.data_size =
120 media::VideoFrame::AllocationSize(frame->format(), frame->coded_size()); 128 media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
121 } 129 }
122 130
123 // This signals to libJingle that a new VideoFrame is available. 131 // This signals to libJingle that a new VideoFrame is available.
124 // libJingle have no assumptions on what thread this signal come from. 132 // libJingle have no assumptions on what thread this signal come from.
125 SignalFrameCaptured(this, &captured_frame); 133 SignalFrameCaptured(this, &captured_frame);
126 } 134 }
127 135
128 void WebRtcVideoCapturerAdapter::UpdateI420Buffer( 136 void WebRtcVideoCapturerAdapter::UpdateI420Buffer(
129 const scoped_refptr<media::VideoFrame>& src) { 137 const scoped_refptr<media::VideoFrame>& src) {
130 DCHECK(thread_checker_.CalledOnValidThread()); 138 DCHECK(thread_checker_.CalledOnValidThread());
131 const int src_width = src->coded_size().width(); 139 const int dst_width = src->natural_size().width();
132 const int src_height = src->coded_size().height(); 140 const int dst_height = src->natural_size().height();
133 const int dst_width = src->visible_rect().width(); 141 DCHECK(src->visible_rect().width() >= dst_width &&
134 const int dst_height = src->visible_rect().height(); 142 src->visible_rect().height() >= dst_height);
135 DCHECK(src_width >= dst_width && src_height >= dst_height);
136 143
137 const int horiz_crop = src->visible_rect().x(); 144 const gfx::Rect& visible_rect = src->visible_rect();
138 const int vert_crop = src->visible_rect().y();
139 145
140 const uint8* src_y = src->data(media::VideoFrame::kYPlane) + 146 const uint8* src_y = src->data(media::VideoFrame::kYPlane) +
141 (src_width * vert_crop + horiz_crop); 147 visible_rect.y() * src->stride(media::VideoFrame::kYPlane) +
142 const int center = (src_width + 1) / 2; 148 visible_rect.x();
143 const uint8* src_u = src->data(media::VideoFrame::kUPlane) + 149 const uint8* src_u = src->data(media::VideoFrame::kUPlane) +
144 (center * vert_crop + horiz_crop) / 2; 150 visible_rect.y() / 2 * src->stride(media::VideoFrame::kUPlane) +
151 visible_rect.x() / 2;
145 const uint8* src_v = src->data(media::VideoFrame::kVPlane) + 152 const uint8* src_v = src->data(media::VideoFrame::kVPlane) +
146 (center * vert_crop + horiz_crop) / 2; 153 visible_rect.y() / 2 * src->stride(media::VideoFrame::kVPlane) +
154 visible_rect.x() / 2;
147 155
148 const size_t dst_size = 156 const size_t dst_size =
149 media::VideoFrame::AllocationSize(src->format(), 157 media::VideoFrame::AllocationSize(src->format(), src->natural_size());
150 src->visible_rect().size());
151 158
152 if (dst_size != buffer_size_) { 159 if (dst_size != buffer_size_) {
153 base::AlignedFree(buffer_); 160 base::AlignedFree(buffer_);
154 buffer_ = reinterpret_cast<uint8*>( 161 buffer_ = reinterpret_cast<uint8*>(
155 base::AlignedAlloc(dst_size + media::VideoFrame::kFrameSizePadding, 162 base::AlignedAlloc(dst_size + media::VideoFrame::kFrameSizePadding,
156 media::VideoFrame::kFrameAddressAlignment)); 163 media::VideoFrame::kFrameAddressAlignment));
157 buffer_size_ = dst_size; 164 buffer_size_ = dst_size;
158 } 165 }
159 166
160 uint8* dst_y = buffer_; 167 uint8* dst_y = buffer_;
161 const int dst_stride_y = dst_width; 168 const int dst_stride_y = dst_width;
162 uint8* dst_u = dst_y + dst_width * dst_height; 169 uint8* dst_u = dst_y + dst_width * dst_height;
163 const int dst_halfwidth = (dst_width + 1) / 2; 170 const int dst_halfwidth = (dst_width + 1) / 2;
164 const int dst_halfheight = (dst_height + 1) / 2; 171 const int dst_halfheight = (dst_height + 1) / 2;
165 uint8* dst_v = dst_u + dst_halfwidth * dst_halfheight; 172 uint8* dst_v = dst_u + dst_halfwidth * dst_halfheight;
166 173
167 libyuv::I420Copy(src_y, 174 libyuv::I420Scale(src_y,
168 src->stride(media::VideoFrame::kYPlane), 175 src->stride(media::VideoFrame::kYPlane),
169 src_u, 176 src_u,
170 src->stride(media::VideoFrame::kUPlane), 177 src->stride(media::VideoFrame::kUPlane),
171 src_v, 178 src_v,
172 src->stride(media::VideoFrame::kVPlane), 179 src->stride(media::VideoFrame::kVPlane),
173 dst_y, 180 visible_rect.width(),
174 dst_stride_y, 181 visible_rect.height(),
175 dst_u, 182 dst_y,
176 dst_halfwidth, 183 dst_stride_y,
177 dst_v, 184 dst_u,
178 dst_halfwidth, 185 dst_halfwidth,
179 dst_width, 186 dst_v,
180 dst_height); 187 dst_halfwidth,
188 dst_width,
189 dst_height,
190 libyuv::kFilterBilinear);
181 } 191 }
182 192
183 } // namespace content 193 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698