Index: content/browser/media/capture/web_contents_video_capture_device.cc |
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc |
index 8380682fc5064f11b55813af04cb4549994a244e..4513db05362e3fd8f7963acff4bc616454cb0b1f 100644 |
--- a/content/browser/media/capture/web_contents_video_capture_device.cc |
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc |
@@ -79,7 +79,6 @@ |
#include "third_party/skia/include/core/SkBitmap.h" |
#include "third_party/skia/include/core/SkColor.h" |
#include "ui/gfx/display.h" |
-#include "ui/gfx/geometry/size.h" |
#include "ui/gfx/geometry/size_conversions.h" |
#include "ui/gfx/screen.h" |
@@ -87,20 +86,6 @@ namespace content { |
namespace { |
-// Compute a letterbox region, aligned to even coordinates. |
-gfx::Rect ComputeYV12LetterboxRegion(const gfx::Rect& visible_rect, |
- const gfx::Size& content_size) { |
- |
- gfx::Rect result = media::ComputeLetterboxRegion(visible_rect, content_size); |
- |
- result.set_x(MakeEven(result.x())); |
- result.set_y(MakeEven(result.y())); |
- result.set_width(std::max(kMinFrameWidth, MakeEven(result.width()))); |
- result.set_height(std::max(kMinFrameHeight, MakeEven(result.height()))); |
- |
- return result; |
-} |
- |
void DeleteOnWorkerThread(scoped_ptr<base::Thread> render_thread, |
const base::Closure& callback) { |
render_thread.reset(); |
@@ -257,6 +242,9 @@ class WebContentsCaptureMachine : public VideoCaptureMachine { |
// Remove the old subscription, and start a new one if |rwh| is not NULL. |
void RenewFrameSubscription(RenderWidgetHost* rwh); |
+ // Called whenever the render widget is resized. |
+ void UpdateCaptureSize(RenderWidgetHost* rwh); |
+ |
// Parameters saved in constructor. |
const int initial_render_process_id_; |
const int initial_main_render_frame_id_; |
@@ -396,7 +384,7 @@ void RenderVideoFrame(const SkBitmap& input, |
// Calculate the width and height of the content region in the |output|, based |
// on the aspect ratio of |input|. |
- gfx::Rect region_in_frame = ComputeYV12LetterboxRegion( |
+ const gfx::Rect region_in_frame = media::ComputeLetterboxRegion( |
output->visible_rect(), gfx::Size(input.width(), input.height())); |
// Scale the bitmap to the required size, if necessary. |
@@ -425,12 +413,20 @@ void RenderVideoFrame(const SkBitmap& input, |
TRACE_EVENT_ASYNC_STEP_INTO0("gpu.capture", "Capture", output.get(), "YUV"); |
{ |
- SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); |
+ // Align to 2x2 pixel boundaries, as required by |
+ // media::CopyRGBToVideoFrame(). |
+ const gfx::Rect region_in_yv12_frame(region_in_frame.x() & ~1, |
+ region_in_frame.y() & ~1, |
+ region_in_frame.width() & ~1, |
+ region_in_frame.height() & ~1); |
+ if (region_in_yv12_frame.IsEmpty()) |
+ return; |
+ SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); |
media::CopyRGBToVideoFrame( |
reinterpret_cast<uint8*>(scaled_bitmap.getPixels()), |
scaled_bitmap.rowBytes(), |
- region_in_frame, |
+ region_in_yv12_frame, |
output.get()); |
} |
@@ -501,6 +497,9 @@ bool WebContentsCaptureMachine::Start( |
// Note: Creation of the first WeakPtr in the following statement will cause |
// IsStarted() to return true from now on. |
+ tracker_->SetResizeChangeCallback( |
+ base::Bind(&WebContentsCaptureMachine::UpdateCaptureSize, |
+ weak_ptr_factory_.GetWeakPtr())); |
tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_, |
base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription, |
weak_ptr_factory_.GetWeakPtr())); |
@@ -551,11 +550,6 @@ void WebContentsCaptureMachine::Capture( |
} |
gfx::Size view_size = view->GetViewBounds().size(); |
- gfx::Size fitted_size; |
- if (!view_size.IsEmpty()) { |
- fitted_size = ComputeYV12LetterboxRegion(target->visible_rect(), |
- view_size).size(); |
- } |
if (view_size != last_view_size_) { |
last_view_size_ = view_size; |
@@ -574,6 +568,8 @@ void WebContentsCaptureMachine::Capture( |
weak_ptr_factory_.GetWeakPtr(), |
start_time, deliver_frame_cb)); |
} else { |
+ const gfx::Size fitted_size = view_size.IsEmpty() ? gfx::Size() : |
+ media::ComputeLetterboxRegion(target->visible_rect(), view_size).size(); |
rwh->CopyFromBackingStore( |
gfx::Rect(), |
fitted_size, // Size here is a request not always honored. |
@@ -589,7 +585,10 @@ void WebContentsCaptureMachine::Capture( |
gfx::Size WebContentsCaptureMachine::ComputeOptimalTargetSize() const { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- gfx::Size optimal_size = oracle_proxy_->GetCaptureSize(); |
+ // TODO(miu): Propagate capture frame size changes as new "preferred size" |
+ // updates, rather than just using the max frame size. This value here |
+ // determines the size of the fullscreen-within-tab widget. |
+ gfx::Size optimal_size = oracle_proxy_->max_frame_size(); |
// If the ratio between physical and logical pixels is greater than 1:1, |
// shrink |optimal_size| by that amount. Then, when external code resizes the |
@@ -688,6 +687,17 @@ void WebContentsCaptureMachine::RenewFrameSubscription(RenderWidgetHost* rwh) { |
weak_ptr_factory_.GetWeakPtr()))); |
} |
+void WebContentsCaptureMachine::UpdateCaptureSize(RenderWidgetHost* rwh) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
+ if (!oracle_proxy_) |
+ return; |
+ RenderWidgetHostView* const view = rwh ? rwh->GetView() : nullptr; |
+ if (!view) |
+ return; |
+ oracle_proxy_->UpdateCaptureSize(view->GetViewBounds().size()); |
+} |
+ |
} // namespace |
WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice( |