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

Side by Side Diff: content/browser/media/capture/content_video_capture_device_core.cc

Issue 267813002: Revert of Use texture-backed VideoFrame pipeline for Aura desktop capturing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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/browser/media/capture/content_video_capture_device_core.h" 5 #include "content/browser/media/capture/content_video_capture_device_core.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback_forward.h" 9 #include "base/callback_forward.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 30 matching lines...) Expand all
41 } // namespace 41 } // namespace
42 42
43 ThreadSafeCaptureOracle::ThreadSafeCaptureOracle( 43 ThreadSafeCaptureOracle::ThreadSafeCaptureOracle(
44 scoped_ptr<media::VideoCaptureDevice::Client> client, 44 scoped_ptr<media::VideoCaptureDevice::Client> client,
45 scoped_ptr<VideoCaptureOracle> oracle, 45 scoped_ptr<VideoCaptureOracle> oracle,
46 const media::VideoCaptureParams& params) 46 const media::VideoCaptureParams& params)
47 : client_(client.Pass()), 47 : client_(client.Pass()),
48 oracle_(oracle.Pass()), 48 oracle_(oracle.Pass()),
49 params_(params), 49 params_(params),
50 capture_size_updated_(false) { 50 capture_size_updated_(false) {
51 switch (params_.requested_format.pixel_format) { 51 // Frame dimensions must each be an even integer since the client wants (or
52 case media::PIXEL_FORMAT_I420: 52 // will convert to) YUV420.
53 video_frame_format_ = media::VideoFrame::I420; 53 capture_size_ = gfx::Size(
54 break; 54 MakeEven(params.requested_format.frame_size.width()),
55 case media::PIXEL_FORMAT_TEXTURE: 55 MakeEven(params.requested_format.frame_size.height()));
56 video_frame_format_ = media::VideoFrame::NATIVE_TEXTURE; 56 frame_rate_ = params.requested_format.frame_rate;
57 break;
58 default:
59 LOG(FATAL) << "Unexpected pixel_format "
60 << params_.requested_format.pixel_format;
61 }
62 } 57 }
63 58
64 ThreadSafeCaptureOracle::~ThreadSafeCaptureOracle() {} 59 ThreadSafeCaptureOracle::~ThreadSafeCaptureOracle() {}
65 60
66 bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture( 61 bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
67 VideoCaptureOracle::Event event, 62 VideoCaptureOracle::Event event,
68 base::TimeTicks event_time, 63 base::TimeTicks event_time,
69 scoped_refptr<media::VideoFrame>* storage, 64 scoped_refptr<media::VideoFrame>* storage,
70 CaptureFrameCallback* callback) { 65 CaptureFrameCallback* callback) {
71 base::AutoLock guard(lock_); 66 base::AutoLock guard(lock_);
72 67
73 if (!client_) 68 if (!client_)
74 return false; // Capture is stopped. 69 return false; // Capture is stopped.
75 70
76 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer = 71 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer =
77 client_->ReserveOutputBuffer(video_frame_format_, 72 client_->ReserveOutputBuffer(media::VideoFrame::I420, capture_size_);
78 params_.requested_format.frame_size);
79 const bool should_capture = 73 const bool should_capture =
80 oracle_->ObserveEventAndDecideCapture(event, event_time); 74 oracle_->ObserveEventAndDecideCapture(event, event_time);
81 const bool content_is_dirty = 75 const bool content_is_dirty =
82 (event == VideoCaptureOracle::kCompositorUpdate || 76 (event == VideoCaptureOracle::kCompositorUpdate ||
83 event == VideoCaptureOracle::kSoftwarePaint); 77 event == VideoCaptureOracle::kSoftwarePaint);
84 const char* event_name = 78 const char* event_name =
85 (event == VideoCaptureOracle::kTimerPoll ? "poll" : 79 (event == VideoCaptureOracle::kTimerPoll ? "poll" :
86 (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" : 80 (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" :
87 "paint")); 81 "paint"));
88 82
(...skipping 20 matching lines...) Expand all
109 // to because no output buffer was available. 103 // to because no output buffer was available.
110 TRACE_EVENT_INSTANT1("mirroring", "NearlyEncodeLimited", 104 TRACE_EVENT_INSTANT1("mirroring", "NearlyEncodeLimited",
111 TRACE_EVENT_SCOPE_THREAD, 105 TRACE_EVENT_SCOPE_THREAD,
112 "trigger", event_name); 106 "trigger", event_name);
113 return false; 107 return false;
114 } 108 }
115 int frame_number = oracle_->RecordCapture(); 109 int frame_number = oracle_->RecordCapture();
116 TRACE_EVENT_ASYNC_BEGIN2("mirroring", "Capture", output_buffer.get(), 110 TRACE_EVENT_ASYNC_BEGIN2("mirroring", "Capture", output_buffer.get(),
117 "frame_number", frame_number, 111 "frame_number", frame_number,
118 "trigger", event_name); 112 "trigger", event_name);
119 // NATIVE_TEXTURE frames wrap a texture mailbox, which we don't have at the 113 *storage = media::VideoFrame::WrapExternalPackedMemory(
120 // moment. We do not construct those frames. 114 media::VideoFrame::I420,
121 if (video_frame_format_ != media::VideoFrame::NATIVE_TEXTURE) { 115 capture_size_,
122 *storage = media::VideoFrame::WrapExternalPackedMemory( 116 gfx::Rect(capture_size_),
123 video_frame_format_, 117 capture_size_,
124 params_.requested_format.frame_size, 118 static_cast<uint8*>(output_buffer->data()),
125 gfx::Rect(params_.requested_format.frame_size), 119 output_buffer->size(),
126 params_.requested_format.frame_size, 120 base::SharedMemory::NULLHandle(),
127 static_cast<uint8*>(output_buffer->data()), 121 base::TimeDelta(),
128 output_buffer->size(), 122 base::Closure());
129 base::SharedMemory::NULLHandle(),
130 base::TimeDelta(),
131 base::Closure());
132 }
133 *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame, 123 *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame,
134 this, 124 this,
135 frame_number, 125 output_buffer,
136 output_buffer); 126 *storage,
127 frame_number);
137 return true; 128 return true;
138 } 129 }
139 130
140 gfx::Size ThreadSafeCaptureOracle::GetCaptureSize() const { 131 gfx::Size ThreadSafeCaptureOracle::GetCaptureSize() const {
141 base::AutoLock guard(lock_); 132 base::AutoLock guard(lock_);
142 return params_.requested_format.frame_size; 133 return capture_size_;
143 } 134 }
144 135
145 void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) { 136 void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) {
146 base::AutoLock guard(lock_); 137 base::AutoLock guard(lock_);
147 138
148 // If this is the first call to UpdateCaptureSize(), or the receiver supports 139 // If this is the first call to UpdateCaptureSize(), or the receiver supports
149 // variable resolution, then determine the capture size by treating the 140 // variable resolution, then determine the capture size by treating the
150 // requested width and height as maxima. 141 // requested width and height as maxima.
151 if (!capture_size_updated_ || params_.allow_resolution_change) { 142 if (!capture_size_updated_ || params_.allow_resolution_change) {
152 // The capture resolution should not exceed the source frame size. 143 // The capture resolution should not exceed the source frame size.
153 // In other words it should downscale the image but not upscale it. 144 // In other words it should downscale the image but not upscale it.
154 if (source_size.width() > params_.requested_format.frame_size.width() || 145 if (source_size.width() > params_.requested_format.frame_size.width() ||
155 source_size.height() > params_.requested_format.frame_size.height()) { 146 source_size.height() > params_.requested_format.frame_size.height()) {
156 gfx::Rect capture_rect = media::ComputeLetterboxRegion( 147 gfx::Rect capture_rect = media::ComputeLetterboxRegion(
157 gfx::Rect(params_.requested_format.frame_size), source_size); 148 gfx::Rect(params_.requested_format.frame_size), source_size);
158 params_.requested_format.frame_size.SetSize( 149 capture_size_ = gfx::Size(MakeEven(capture_rect.width()),
159 MakeEven(capture_rect.width()), MakeEven(capture_rect.height())); 150 MakeEven(capture_rect.height()));
160 } else { 151 } else {
161 params_.requested_format.frame_size.SetSize( 152 capture_size_ = gfx::Size(MakeEven(source_size.width()),
162 MakeEven(source_size.width()), MakeEven(source_size.height())); 153 MakeEven(source_size.height()));
163 } 154 }
164 capture_size_updated_ = true; 155 capture_size_updated_ = true;
165 } 156 }
166 } 157 }
167 158
168 void ThreadSafeCaptureOracle::Stop() { 159 void ThreadSafeCaptureOracle::Stop() {
169 base::AutoLock guard(lock_); 160 base::AutoLock guard(lock_);
170 client_.reset(); 161 client_.reset();
171 } 162 }
172 163
173 void ThreadSafeCaptureOracle::ReportError(const std::string& reason) { 164 void ThreadSafeCaptureOracle::ReportError(const std::string& reason) {
174 base::AutoLock guard(lock_); 165 base::AutoLock guard(lock_);
175 if (client_) 166 if (client_)
176 client_->OnError(reason); 167 client_->OnError(reason);
177 } 168 }
178 169
179 void ThreadSafeCaptureOracle::DidCaptureFrame( 170 void ThreadSafeCaptureOracle::DidCaptureFrame(
180 int frame_number,
181 const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer, 171 const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
182 const scoped_refptr<media::VideoFrame>& frame, 172 const scoped_refptr<media::VideoFrame>& frame,
173 int frame_number,
183 base::TimeTicks timestamp, 174 base::TimeTicks timestamp,
184 bool success) { 175 bool success) {
185 base::AutoLock guard(lock_); 176 base::AutoLock guard(lock_);
186 TRACE_EVENT_ASYNC_END2("mirroring", "Capture", buffer.get(), 177 TRACE_EVENT_ASYNC_END2("mirroring", "Capture", buffer.get(),
187 "success", success, 178 "success", success,
188 "timestamp", timestamp.ToInternalValue()); 179 "timestamp", timestamp.ToInternalValue());
189 180
190 if (!client_) 181 if (!client_)
191 return; // Capture is stopped. 182 return; // Capture is stopped.
192 183
193 if (success) { 184 if (success) {
194 if (oracle_->CompleteCapture(frame_number, timestamp)) { 185 if (oracle_->CompleteCapture(frame_number, timestamp)) {
195 media::VideoCaptureFormat format = params_.requested_format; 186 client_->OnIncomingCapturedVideoFrame(
196 format.frame_size = frame->coded_size(); 187 buffer,
197 client_->OnIncomingCapturedVideoFrame(buffer, format, frame, timestamp); 188 media::VideoCaptureFormat(
189 capture_size_, frame_rate_, media::PIXEL_FORMAT_I420),
190 frame,
191 timestamp);
198 } 192 }
199 } 193 }
200 } 194 }
201 195
202 void ContentVideoCaptureDeviceCore::AllocateAndStart( 196 void ContentVideoCaptureDeviceCore::AllocateAndStart(
203 const media::VideoCaptureParams& params, 197 const media::VideoCaptureParams& params,
204 scoped_ptr<media::VideoCaptureDevice::Client> client) { 198 scoped_ptr<media::VideoCaptureDevice::Client> client) {
205 DCHECK(thread_checker_.CalledOnValidThread()); 199 DCHECK(thread_checker_.CalledOnValidThread());
206 200
207 if (state_ != kIdle) { 201 if (state_ != kIdle) {
208 DVLOG(1) << "Allocate() invoked when not in state Idle."; 202 DVLOG(1) << "Allocate() invoked when not in state Idle.";
209 return; 203 return;
210 } 204 }
211 205
212 if (params.requested_format.frame_rate <= 0) { 206 if (params.requested_format.frame_rate <= 0) {
213 std::string error_msg = base::StringPrintf( 207 std::string error_msg = base::StringPrintf(
214 "invalid frame_rate: %d", params.requested_format.frame_rate); 208 "invalid frame_rate: %d", params.requested_format.frame_rate);
215 DVLOG(1) << error_msg; 209 DVLOG(1) << error_msg;
216 client->OnError(error_msg); 210 client->OnError(error_msg);
217 return; 211 return;
218 } 212 }
219 213
220 if (params.requested_format.pixel_format != media::PIXEL_FORMAT_I420 && 214 if (params.requested_format.frame_size.width() < kMinFrameWidth ||
221 params.requested_format.pixel_format != media::PIXEL_FORMAT_TEXTURE) { 215 params.requested_format.frame_size.height() < kMinFrameHeight) {
222 std::string error_msg = base::StringPrintf( 216 std::string error_msg =
223 "unsupported format: %d", params.requested_format.pixel_format); 217 "invalid frame size: " + params.requested_format.frame_size.ToString();
224 DVLOG(1) << error_msg; 218 DVLOG(1) << error_msg;
225 client->OnError(error_msg); 219 client->OnError(error_msg);
226 return; 220 return;
227 } 221 }
228 222
229 media::VideoCaptureParams new_params = params;
230 // Frame dimensions must each be an even integer since the client wants (or
231 // will convert to) YUV420.
232 new_params.requested_format.frame_size.SetSize(
233 MakeEven(params.requested_format.frame_size.width()),
234 MakeEven(params.requested_format.frame_size.height()));
235
236 base::TimeDelta capture_period = base::TimeDelta::FromMicroseconds( 223 base::TimeDelta capture_period = base::TimeDelta::FromMicroseconds(
237 1000000.0 / params.requested_format.frame_rate + 0.5); 224 1000000.0 / params.requested_format.frame_rate + 0.5);
238 225
239 scoped_ptr<VideoCaptureOracle> oracle( 226 scoped_ptr<VideoCaptureOracle> oracle(
240 new VideoCaptureOracle(capture_period, 227 new VideoCaptureOracle(capture_period,
241 kAcceleratedSubscriberIsSupported)); 228 kAcceleratedSubscriberIsSupported));
242 oracle_proxy_ = 229 oracle_proxy_ =
243 new ThreadSafeCaptureOracle(client.Pass(), oracle.Pass(), new_params); 230 new ThreadSafeCaptureOracle(client.Pass(), oracle.Pass(), params);
244 231
245 // Starts the capture machine asynchronously. 232 // Starts the capture machine asynchronously.
246 BrowserThread::PostTaskAndReplyWithResult( 233 BrowserThread::PostTaskAndReplyWithResult(
247 BrowserThread::UI, 234 BrowserThread::UI, FROM_HERE,
248 FROM_HERE,
249 base::Bind(&VideoCaptureMachine::Start, 235 base::Bind(&VideoCaptureMachine::Start,
250 base::Unretained(capture_machine_.get()), 236 base::Unretained(capture_machine_.get()),
251 oracle_proxy_, 237 oracle_proxy_),
252 new_params), 238 base::Bind(&ContentVideoCaptureDeviceCore::CaptureStarted,
253 base::Bind(&ContentVideoCaptureDeviceCore::CaptureStarted, AsWeakPtr())); 239 AsWeakPtr()));
254 240
255 TransitionStateTo(kCapturing); 241 TransitionStateTo(kCapturing);
256 } 242 }
257 243
258 void ContentVideoCaptureDeviceCore::StopAndDeAllocate() { 244 void ContentVideoCaptureDeviceCore::StopAndDeAllocate() {
259 DCHECK(thread_checker_.CalledOnValidThread()); 245 DCHECK(thread_checker_.CalledOnValidThread());
260 246
261 if (state_ != kCapturing) 247 if (state_ != kCapturing)
262 return; 248 return;
263 249
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 return; 310 return;
325 311
326 if (oracle_proxy_) 312 if (oracle_proxy_)
327 oracle_proxy_->ReportError(reason); 313 oracle_proxy_->ReportError(reason);
328 314
329 StopAndDeAllocate(); 315 StopAndDeAllocate();
330 TransitionStateTo(kError); 316 TransitionStateTo(kError);
331 } 317 }
332 318
333 } // namespace content 319 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698