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

Side by Side Diff: content/browser/renderer_host/media/web_contents_video_capture_device.cc

Issue 23551011: From Video Capture, abolish OnFrameInfo and enable resolution changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix constant declaration issue. Created 7 years, 2 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // Implementation notes: This needs to work on a variety of hardware 5 // Implementation notes: This needs to work on a variety of hardware
6 // configurations where the speed of the CPU and GPU greatly affect overall 6 // configurations where the speed of the CPU and GPU greatly affect overall
7 // performance. Spanning several threads, the process of capturing has been 7 // performance. Spanning several threads, the process of capturing has been
8 // split up into four conceptual stages: 8 // split up into four conceptual stages:
9 // 9 //
10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 } 132 }
133 133
134 // Thread-safe, refcounted proxy to the VideoCaptureOracle. This proxy wraps 134 // Thread-safe, refcounted proxy to the VideoCaptureOracle. This proxy wraps
135 // the VideoCaptureOracle, which decides which frames to capture, and a 135 // the VideoCaptureOracle, which decides which frames to capture, and a
136 // VideoCaptureDevice::Client, which allocates and receives the captured 136 // VideoCaptureDevice::Client, which allocates and receives the captured
137 // frames, in a lock to synchronize state between the two. 137 // frames, in a lock to synchronize state between the two.
138 class ThreadSafeCaptureOracle 138 class ThreadSafeCaptureOracle
139 : public base::RefCountedThreadSafe<ThreadSafeCaptureOracle> { 139 : public base::RefCountedThreadSafe<ThreadSafeCaptureOracle> {
140 public: 140 public:
141 ThreadSafeCaptureOracle(scoped_ptr<media::VideoCaptureDevice::Client> client, 141 ThreadSafeCaptureOracle(scoped_ptr<media::VideoCaptureDevice::Client> client,
142 scoped_ptr<VideoCaptureOracle> oracle); 142 scoped_ptr<VideoCaptureOracle> oracle,
143 const gfx::Size& capture_size);
143 144
144 bool ObserveEventAndDecideCapture( 145 bool ObserveEventAndDecideCapture(
145 VideoCaptureOracle::Event event, 146 VideoCaptureOracle::Event event,
146 base::Time event_time, 147 base::Time event_time,
147 scoped_refptr<media::VideoFrame>* storage, 148 scoped_refptr<media::VideoFrame>* storage,
148 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback); 149 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback);
149 150
150 base::TimeDelta capture_period() const { 151 base::TimeDelta capture_period() const {
151 return oracle_->capture_period(); 152 return oracle_->capture_period();
152 } 153 }
(...skipping 14 matching lines...) Expand all
167 base::Time timestamp, 168 base::Time timestamp,
168 bool success); 169 bool success);
169 // Protects everything below it. 170 // Protects everything below it.
170 base::Lock lock_; 171 base::Lock lock_;
171 172
172 // Recipient of our capture activity. 173 // Recipient of our capture activity.
173 scoped_ptr<media::VideoCaptureDevice::Client> client_; 174 scoped_ptr<media::VideoCaptureDevice::Client> client_;
174 175
175 // Makes the decision to capture a frame. 176 // Makes the decision to capture a frame.
176 const scoped_ptr<VideoCaptureOracle> oracle_; 177 const scoped_ptr<VideoCaptureOracle> oracle_;
178
179 // The resolution at which we're capturing.
180 const gfx::Size capture_size_;
177 }; 181 };
178 182
179 // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible 183 // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible
180 // with RenderWidgetHostViewFrameSubscriber. We create one per event type. 184 // with RenderWidgetHostViewFrameSubscriber. We create one per event type.
181 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { 185 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
182 public: 186 public:
183 FrameSubscriber(VideoCaptureOracle::Event event_type, 187 FrameSubscriber(VideoCaptureOracle::Event event_type,
184 const scoped_refptr<ThreadSafeCaptureOracle>& oracle) 188 const scoped_refptr<ThreadSafeCaptureOracle>& oracle)
185 : event_type_(event_type), 189 : event_type_(event_type),
186 oracle_proxy_(oracle) {} 190 oracle_proxy_(oracle) {}
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 // verbose logging is turned on. 393 // verbose logging is turned on.
390 base::Time last_frame_rate_log_time_; 394 base::Time last_frame_rate_log_time_;
391 int count_frames_rendered_; 395 int count_frames_rendered_;
392 int last_frame_number_; 396 int last_frame_number_;
393 397
394 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog); 398 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog);
395 }; 399 };
396 400
397 ThreadSafeCaptureOracle::ThreadSafeCaptureOracle( 401 ThreadSafeCaptureOracle::ThreadSafeCaptureOracle(
398 scoped_ptr<media::VideoCaptureDevice::Client> client, 402 scoped_ptr<media::VideoCaptureDevice::Client> client,
399 scoped_ptr<VideoCaptureOracle> oracle) 403 scoped_ptr<VideoCaptureOracle> oracle,
400 : client_(client.Pass()), oracle_(oracle.Pass()) {} 404 const gfx::Size& capture_size)
405 : client_(client.Pass()),
406 oracle_(oracle.Pass()),
407 capture_size_(capture_size) {
408 }
401 409
402 bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture( 410 bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
403 VideoCaptureOracle::Event event, 411 VideoCaptureOracle::Event event,
404 base::Time event_time, 412 base::Time event_time,
405 scoped_refptr<media::VideoFrame>* storage, 413 scoped_refptr<media::VideoFrame>* storage,
406 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback) { 414 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* callback) {
407 base::AutoLock guard(lock_); 415 base::AutoLock guard(lock_);
408 416
409 if (!client_) 417 if (!client_)
410 return false; // Capture is stopped. 418 return false; // Capture is stopped.
411 419
412 scoped_refptr<media::VideoFrame> output_buffer = 420 scoped_refptr<media::VideoFrame> output_buffer =
413 client_->ReserveOutputBuffer(); 421 client_->ReserveOutputBuffer(capture_size_);
414 const bool should_capture = 422 const bool should_capture =
415 oracle_->ObserveEventAndDecideCapture(event, event_time); 423 oracle_->ObserveEventAndDecideCapture(event, event_time);
416 const bool content_is_dirty = 424 const bool content_is_dirty =
417 (event == VideoCaptureOracle::kCompositorUpdate || 425 (event == VideoCaptureOracle::kCompositorUpdate ||
418 event == VideoCaptureOracle::kSoftwarePaint); 426 event == VideoCaptureOracle::kSoftwarePaint);
419 const char* event_name = 427 const char* event_name =
420 (event == VideoCaptureOracle::kTimerPoll ? "poll" : 428 (event == VideoCaptureOracle::kTimerPoll ? "poll" :
421 (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" : 429 (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" :
422 "paint")); 430 "paint"));
423 431
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 // wants (or will convert to) YUV420. 1029 // wants (or will convert to) YUV420.
1022 width = MakeEven(width); 1030 width = MakeEven(width);
1023 height = MakeEven(height); 1031 height = MakeEven(height);
1024 if (width < kMinFrameWidth || height < kMinFrameHeight) { 1032 if (width < kMinFrameWidth || height < kMinFrameHeight) {
1025 DVLOG(1) << "invalid width (" << width << ") and/or height (" 1033 DVLOG(1) << "invalid width (" << width << ") and/or height ("
1026 << height << ")"; 1034 << height << ")";
1027 client->OnError(); 1035 client->OnError();
1028 return; 1036 return;
1029 } 1037 }
1030 1038
1031 // Initialize capture settings which will be consistent for the 1039 // Need to call OnFrameInfo just to set the frame rate.
1032 // duration of the capture. 1040 // The other parameters of this struct are ignored.
1033 media::VideoCaptureCapability settings; 1041 media::VideoCaptureCapability settings;
1034
1035 settings.width = width;
1036 settings.height = height;
1037 settings.frame_rate = frame_rate; 1042 settings.frame_rate = frame_rate;
1038 // Note: the value of |settings.color| doesn't matter if we use only the 1043 client->OnFrameInfo(settings);
1039 // VideoFrame based methods on |client|.
1040 settings.color = media::PIXEL_FORMAT_I420;
1041 settings.expected_capture_delay = 0;
1042 settings.interlaced = false;
1043 1044
1044 base::TimeDelta capture_period = base::TimeDelta::FromMicroseconds( 1045 base::TimeDelta capture_period = base::TimeDelta::FromMicroseconds(
1045 1000000.0 / settings.frame_rate + 0.5); 1046 1000000.0 / frame_rate + 0.5);
1046 1047
1047 client->OnFrameInfo(settings);
1048 scoped_ptr<VideoCaptureOracle> oracle( 1048 scoped_ptr<VideoCaptureOracle> oracle(
1049 new VideoCaptureOracle(capture_period, 1049 new VideoCaptureOracle(capture_period,
1050 kAcceleratedSubscriberIsSupported)); 1050 kAcceleratedSubscriberIsSupported));
1051 oracle_proxy_ = new ThreadSafeCaptureOracle(client.Pass(), oracle.Pass()); 1051 oracle_proxy_ = new ThreadSafeCaptureOracle(
1052 client.Pass(), oracle.Pass(), gfx::Size(width, height));
1052 1053
1053 // Allocates the CaptureMachine. The CaptureMachine will be tracking render 1054 // Allocates the CaptureMachine. The CaptureMachine will be tracking render
1054 // view swapping over its lifetime, and we don't want to lose our reference to 1055 // view swapping over its lifetime, and we don't want to lose our reference to
1055 // the current render view by starting over with the stale 1056 // the current render view by starting over with the stale
1056 // |initial_render_view_id_|. 1057 // |initial_render_view_id_|.
1057 DCHECK(!capture_machine_.get()); 1058 DCHECK(!capture_machine_.get());
1058 BrowserThread::PostTaskAndReplyWithResult( 1059 BrowserThread::PostTaskAndReplyWithResult(
1059 BrowserThread::UI, FROM_HERE, 1060 BrowserThread::UI, FROM_HERE,
1060 base::Bind(&CaptureMachine::Create, 1061 base::Bind(&CaptureMachine::Create,
1061 initial_render_process_id_, 1062 initial_render_process_id_,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 capture_format.height, 1180 capture_format.height,
1180 capture_format.frame_rate, 1181 capture_format.frame_rate,
1181 client.Pass()); 1182 client.Pass());
1182 } 1183 }
1183 1184
1184 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { 1185 void WebContentsVideoCaptureDevice::StopAndDeAllocate() {
1185 impl_->StopAndDeAllocate(); 1186 impl_->StopAndDeAllocate();
1186 } 1187 }
1187 1188
1188 } // namespace content 1189 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698