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

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

Issue 48113011: Remove media::VideoFrame from media::VideoCaptureDevice::Client interface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: ffdbaeb83 Trybot failures. Created 7 years, 1 month 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
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 #include "content/browser/renderer_host/media/video_capture_controller.h" 5 #include "content/browser/renderer_host/media/video_capture_controller.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/stl_util.h" 11 #include "base/stl_util.h"
13 #include "content/browser/renderer_host/media/media_stream_manager.h" 12 #include "content/browser/renderer_host/media/media_stream_manager.h"
14 #include "content/browser/renderer_host/media/video_capture_manager.h" 13 #include "content/browser/renderer_host/media/video_capture_manager.h"
15 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
16 #include "media/base/video_frame.h" 15 #include "media/base/video_frame.h"
17 #include "media/base/video_util.h" 16 #include "media/base/video_util.h"
18 #include "media/base/yuv_convert.h" 17 #include "media/base/yuv_convert.h"
19 18
20 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 19 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
21 #include "third_party/libyuv/include/libyuv.h" 20 #include "third_party/libyuv/include/libyuv.h"
22 #endif 21 #endif
23 22
24 using media::VideoCaptureCapability; 23 using media::VideoCaptureCapability;
25 24
26 namespace content { 25 namespace content {
27 26
27 namespace {
28
28 // The number of buffers that VideoCaptureBufferPool should allocate. 29 // The number of buffers that VideoCaptureBufferPool should allocate.
29 static const int kNoOfBuffers = 3; 30 const int kNoOfBuffers = 3;
31
32 class PoolBuffer : public media::VideoCaptureDevice::Client::Buffer {
33 public:
34 PoolBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool,
35 int buffer_id,
36 void* data,
37 size_t size)
38 : Buffer(buffer_id, data, size), pool_(pool) {
39 DCHECK(pool_);
40 }
41
42 private:
43 virtual ~PoolBuffer() { pool_->RelinquishProducerReservation(id()); }
44
45 const scoped_refptr<VideoCaptureBufferPool> pool_;
46 };
47
48 } // anonymous namespace
30 49
31 struct VideoCaptureController::ControllerClient { 50 struct VideoCaptureController::ControllerClient {
32 ControllerClient( 51 ControllerClient(
33 const VideoCaptureControllerID& id, 52 const VideoCaptureControllerID& id,
34 VideoCaptureControllerEventHandler* handler, 53 VideoCaptureControllerEventHandler* handler,
35 base::ProcessHandle render_process, 54 base::ProcessHandle render_process,
36 const media::VideoCaptureParams& params) 55 const media::VideoCaptureParams& params)
37 : controller_id(id), 56 : controller_id(id),
38 event_handler(handler), 57 event_handler(handler),
39 render_process_handle(render_process), 58 render_process_handle(render_process),
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // v4l2_thread on Linux, and the UI thread for tab capture. 99 // v4l2_thread on Linux, and the UI thread for tab capture.
81 class VideoCaptureController::VideoCaptureDeviceClient 100 class VideoCaptureController::VideoCaptureDeviceClient
82 : public media::VideoCaptureDevice::Client { 101 : public media::VideoCaptureDevice::Client {
83 public: 102 public:
84 explicit VideoCaptureDeviceClient( 103 explicit VideoCaptureDeviceClient(
85 const base::WeakPtr<VideoCaptureController>& controller, 104 const base::WeakPtr<VideoCaptureController>& controller,
86 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool); 105 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool);
87 virtual ~VideoCaptureDeviceClient(); 106 virtual ~VideoCaptureDeviceClient();
88 107
89 // VideoCaptureDevice::Client implementation. 108 // VideoCaptureDevice::Client implementation.
90 virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer( 109 virtual scoped_refptr<Buffer> ReserveOutputBuffer(
110 media::VideoFrame::Format format,
91 const gfx::Size& size) OVERRIDE; 111 const gfx::Size& size) OVERRIDE;
92 virtual void OnIncomingCapturedFrame( 112 virtual void OnIncomingCapturedFrame(const uint8* data,
93 const uint8* data, 113 int length,
94 int length, 114 base::Time timestamp,
95 base::Time timestamp, 115 int rotation,
96 int rotation, 116 bool flip_vert,
97 bool flip_vert, 117 bool flip_horiz,
98 bool flip_horiz, 118 const VideoCaptureCapability& frame_info)
99 const VideoCaptureCapability& frame_info) OVERRIDE; 119 OVERRIDE;
100 virtual void OnIncomingCapturedVideoFrame( 120 virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer,
101 const scoped_refptr<media::VideoFrame>& frame, 121 media::VideoFrame::Format format,
102 base::Time timestamp, 122 const gfx::Size& dimensions,
103 int frame_rate) OVERRIDE; 123 base::Time timestamp,
124 int frame_rate) OVERRIDE;
104 virtual void OnError() OVERRIDE; 125 virtual void OnError() OVERRIDE;
105 126
106 private: 127 private:
107 scoped_refptr<media::VideoFrame> DoReserveI420VideoFrame( 128 scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format,
108 const gfx::Size& size, 129 const gfx::Size& dimensions,
109 int rotation); 130 int rotation);
110 131
111 // The controller to which we post events. 132 // The controller to which we post events.
112 const base::WeakPtr<VideoCaptureController> controller_; 133 const base::WeakPtr<VideoCaptureController> controller_;
113 134
114 // The pool of shared-memory buffers used for capturing. 135 // The pool of shared-memory buffers used for capturing.
115 const scoped_refptr<VideoCaptureBufferPool> buffer_pool_; 136 const scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
137
138 // The set of buffers that have been used for rotated capturing.
139 std::set<int> rotated_buffers_;
116 }; 140 };
117 141
118 VideoCaptureController::VideoCaptureController() 142 VideoCaptureController::VideoCaptureController()
119 : buffer_pool_(new VideoCaptureBufferPool(kNoOfBuffers)), 143 : buffer_pool_(new VideoCaptureBufferPool(kNoOfBuffers)),
120 state_(VIDEO_CAPTURE_STATE_STARTED), 144 state_(VIDEO_CAPTURE_STATE_STARTED),
121 weak_ptr_factory_(this) { 145 weak_ptr_factory_(this) {
122 } 146 }
123 147
124 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient( 148 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient(
125 const base::WeakPtr<VideoCaptureController>& controller, 149 const base::WeakPtr<VideoCaptureController>& controller,
126 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool) 150 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool)
127 : controller_(controller), 151 : controller_(controller), buffer_pool_(buffer_pool) {}
128 buffer_pool_(buffer_pool) {}
129 152
130 VideoCaptureController::VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {} 153 VideoCaptureController::VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {}
131 154
132 base::WeakPtr<VideoCaptureController> VideoCaptureController::GetWeakPtr() { 155 base::WeakPtr<VideoCaptureController> VideoCaptureController::GetWeakPtr() {
133 return weak_ptr_factory_.GetWeakPtr(); 156 return weak_ptr_factory_.GetWeakPtr();
134 } 157 }
135 158
136 scoped_ptr<media::VideoCaptureDevice::Client> 159 scoped_ptr<media::VideoCaptureDevice::Client>
137 VideoCaptureController::NewDeviceClient() { 160 VideoCaptureController::NewDeviceClient() {
138 scoped_ptr<media::VideoCaptureDevice::Client> result( 161 scoped_ptr<media::VideoCaptureDevice::Client> result(
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 // If this buffer is not held by this client, or this client doesn't exist 245 // If this buffer is not held by this client, or this client doesn't exist
223 // in controller, do nothing. 246 // in controller, do nothing.
224 if (!client || !client->active_buffers.erase(buffer_id)) { 247 if (!client || !client->active_buffers.erase(buffer_id)) {
225 NOTREACHED(); 248 NOTREACHED();
226 return; 249 return;
227 } 250 }
228 251
229 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); 252 buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
230 } 253 }
231 254
232 scoped_refptr<media::VideoFrame> 255 scoped_refptr<media::VideoCaptureDevice::Client::Buffer>
233 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer( 256 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer(
257 media::VideoFrame::Format format,
234 const gfx::Size& size) { 258 const gfx::Size& size) {
235 return DoReserveI420VideoFrame(size, 0); 259 return DoReserveOutputBuffer(format, size, 0);
236 } 260 }
237 261
238 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( 262 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
239 const uint8* data, 263 const uint8* data,
240 int length, 264 int length,
241 base::Time timestamp, 265 base::Time timestamp,
242 int rotation, 266 int rotation,
243 bool flip_vert, 267 bool flip_vert,
244 bool flip_horiz, 268 bool flip_horiz,
245 const VideoCaptureCapability& frame_info) { 269 const VideoCaptureCapability& frame_info) {
(...skipping 11 matching lines...) Expand all
257 281
258 if (frame_info.width & 1) { 282 if (frame_info.width & 1) {
259 --new_width; 283 --new_width;
260 chopped_width = 1; 284 chopped_width = 1;
261 } 285 }
262 if (frame_info.height & 1) { 286 if (frame_info.height & 1) {
263 --new_height; 287 --new_height;
264 chopped_height = 1; 288 chopped_height = 1;
265 } 289 }
266 290
267 scoped_refptr<media::VideoFrame> dst = DoReserveI420VideoFrame( 291 const gfx::Size dimensions(new_width, new_height);
268 gfx::Size(new_width, new_height), rotation); 292 scoped_refptr<Buffer> buffer =
293 DoReserveOutputBuffer(media::VideoFrame::I420, dimensions, rotation);
269 294
270 if (!dst.get()) 295 if (!buffer)
271 return; 296 return;
272 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 297 #if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
273 298 uint8* yplane = reinterpret_cast<uint8*>(buffer->data());
274 uint8* yplane = dst->data(media::VideoFrame::kYPlane); 299 uint8* uplane =
275 uint8* uplane = dst->data(media::VideoFrame::kUPlane); 300 yplane +
276 uint8* vplane = dst->data(media::VideoFrame::kVPlane); 301 media::VideoFrame::PlaneAllocationSize(
302 media::VideoFrame::I420, media::VideoFrame::kYPlane, dimensions);
303 uint8* vplane =
304 uplane +
305 media::VideoFrame::PlaneAllocationSize(
306 media::VideoFrame::I420, media::VideoFrame::kUPlane, dimensions);
277 int yplane_stride = new_width; 307 int yplane_stride = new_width;
278 int uv_plane_stride = (new_width + 1) / 2; 308 int uv_plane_stride = new_width / 2;
279 int crop_x = 0; 309 int crop_x = 0;
280 int crop_y = 0; 310 int crop_y = 0;
281 int destination_width = new_width; 311 int destination_width = new_width;
282 int destination_height = new_height; 312 int destination_height = new_height;
283 libyuv::FourCC origin_colorspace = libyuv::FOURCC_ANY; 313 libyuv::FourCC origin_colorspace = libyuv::FOURCC_ANY;
284 // Assuming rotation happens first and flips next, we can consolidate both 314 // Assuming rotation happens first and flips next, we can consolidate both
285 // vertical and horizontal flips together with rotation into two variables: 315 // vertical and horizontal flips together with rotation into two variables:
286 // new_rotation = (rotation + 180 * vertical_flip) modulo 360 316 // new_rotation = (rotation + 180 * vertical_flip) modulo 360
287 // new_vertical_flip = horizontal_flip XOR vertical_flip 317 // new_vertical_flip = horizontal_flip XOR vertical_flip
288 int new_rotation_angle = (rotation + 180 * flip_vert) % 360; 318 int new_rotation_angle = (rotation + 180 * flip_vert) % 360;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 // kRGB24 on Windows start at the bottom line and has a negative stride. This 365 // kRGB24 on Windows start at the bottom line and has a negative stride. This
336 // is not supported by libyuv, so the media API is used instead. 366 // is not supported by libyuv, so the media API is used instead.
337 if (frame_info.color == media::PIXEL_FORMAT_RGB24) { 367 if (frame_info.color == media::PIXEL_FORMAT_RGB24) {
338 // Rotation and flipping is not supported in kRGB24 and OS_WIN case. 368 // Rotation and flipping is not supported in kRGB24 and OS_WIN case.
339 DCHECK(!rotation && !flip_vert && !flip_horiz); 369 DCHECK(!rotation && !flip_vert && !flip_horiz);
340 need_convert_rgb24_on_win = true; 370 need_convert_rgb24_on_win = true;
341 } 371 }
342 #endif 372 #endif
343 if (need_convert_rgb24_on_win) { 373 if (need_convert_rgb24_on_win) {
344 int rgb_stride = -3 * (new_width + chopped_width); 374 int rgb_stride = -3 * (new_width + chopped_width);
345 const uint8* rgb_src = 375 const uint8* rgb_src = data + 3 * (new_width + chopped_width) *
346 data + 3 * (new_width + chopped_width) * 376 (new_height - 1 + chopped_height);
347 (new_height - 1 + chopped_height);
348 media::ConvertRGB24ToYUV(rgb_src, 377 media::ConvertRGB24ToYUV(rgb_src,
349 yplane, 378 yplane,
350 uplane, 379 uplane,
351 vplane, 380 vplane,
352 new_width, 381 new_width,
353 new_height, 382 new_height,
354 rgb_stride, 383 rgb_stride,
355 yplane_stride, 384 yplane_stride,
356 uv_plane_stride); 385 uv_plane_stride);
357 } else { 386 } else {
358 if (new_rotation_angle==90 || new_rotation_angle==270){ 387 if (new_rotation_angle==90 || new_rotation_angle==270){
359 // To be compatible with non-libyuv code in RotatePlaneByPixels, when 388 // To be compatible with non-libyuv code in RotatePlaneByPixels, when
360 // rotating by 90/270, only the maximum square portion located in the 389 // rotating by 90/270, only the maximum square portion located in the
361 // center of the image is rotated. F.i. 640x480 pixels, only the central 390 // center of the image is rotated. F.i. 640x480 pixels, only the central
362 // 480 pixels would be rotated and the leftmost and rightmost 80 columns 391 // 480 pixels would be rotated and the leftmost and rightmost 80 columns
363 // would be ignored. This process is called letterboxing. 392 // would be ignored. This process is called letterboxing.
364 int letterbox_thickness = abs(new_width - new_height) / 2; 393 int letterbox_thickness = abs(new_width - new_height) / 2;
365 if (destination_width > destination_height) { 394 if (destination_width > destination_height) {
366 yplane += letterbox_thickness; 395 yplane += letterbox_thickness;
367 uplane += letterbox_thickness / 2; 396 uplane += letterbox_thickness / 2;
368 vplane += letterbox_thickness / 2; 397 vplane += letterbox_thickness / 2;
369 destination_width = destination_height; 398 destination_width = destination_height;
370 } else { 399 } else {
371 yplane += letterbox_thickness * destination_width; 400 yplane += letterbox_thickness * destination_width;
372 uplane += (letterbox_thickness * destination_width) / 2; 401 uplane += (letterbox_thickness * destination_width) / 2;
373 vplane += (letterbox_thickness * destination_width) / 2; 402 vplane += (letterbox_thickness * destination_width) / 2;
374 destination_height = destination_width; 403 destination_height = destination_width;
375 } 404 }
376 } 405 }
377 libyuv::ConvertToI420( 406 libyuv::ConvertToI420(data,
378 data, length, 407 length,
379 yplane, yplane_stride, 408 yplane,
380 uplane, uv_plane_stride, 409 yplane_stride,
381 vplane, uv_plane_stride, 410 uplane,
382 crop_x, crop_y, 411 uv_plane_stride,
383 new_width + chopped_width, 412 vplane,
384 new_height * (flip_vert ^ flip_horiz ? -1 : 1), 413 uv_plane_stride,
385 destination_width, 414 crop_x,
386 destination_height, 415 crop_y,
387 rotation_mode, 416 new_width + chopped_width,
388 origin_colorspace); 417 new_height * (flip_vert ^ flip_horiz ? -1 : 1),
418 destination_width,
419 destination_height,
420 rotation_mode,
421 origin_colorspace);
389 } 422 }
390 #else 423 #else
391 // Libyuv is not linked in for Android WebView builds, but video capture is 424 // Libyuv is not linked in for Android WebView builds, but video capture is
392 // not used in those builds either. Whenever libyuv is added in that build, 425 // not used in those builds either. Whenever libyuv is added in that build,
393 // address all these #ifdef parts, see http://crbug.com/299611 . 426 // address all these #ifdef parts, see http://crbug.com/299611 .
394 NOTREACHED(); 427 NOTREACHED();
395 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW) 428 #endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
396 BrowserThread::PostTask( 429 BrowserThread::PostTask(
397 BrowserThread::IO, 430 BrowserThread::IO,
398 FROM_HERE, 431 FROM_HERE,
399 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 432 base::Bind(
400 controller_, 433 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread,
401 dst, 434 controller_,
402 frame_info.frame_rate, 435 buffer,
403 timestamp)); 436 dimensions,
437 frame_info.frame_rate,
438 timestamp));
404 } 439 }
405 440
406 void 441 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
407 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( 442 const scoped_refptr<Buffer>& buffer,
408 const scoped_refptr<media::VideoFrame>& frame, 443 media::VideoFrame::Format format,
444 const gfx::Size& dimensions,
409 base::Time timestamp, 445 base::Time timestamp,
410 int frame_rate) { 446 int frame_rate) {
411 // If this is a frame that belongs to the buffer pool, we can forward it 447 // The capture pipeline expects I420 for now.
412 // directly to the IO thread and be done. 448 DCHECK_EQ(format, media::VideoFrame::I420)
413 if (buffer_pool_->RecognizeReservedBuffer( 449 << "Non-I420 output buffer returned";
414 frame->shared_memory_handle()) >= 0) {
415 BrowserThread::PostTask(BrowserThread::IO,
416 FROM_HERE,
417 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
418 controller_, frame, frame_rate, timestamp));
419 return;
420 }
421 450
422 NOTREACHED() << "Frames should always belong to the buffer pool."; 451 BrowserThread::PostTask(
452 BrowserThread::IO,
453 FROM_HERE,
454 base::Bind(
455 &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread,
456 controller_,
457 buffer,
458 dimensions,
459 frame_rate,
460 timestamp));
423 } 461 }
424 462
425 void VideoCaptureController::VideoCaptureDeviceClient::OnError() { 463 void VideoCaptureController::VideoCaptureDeviceClient::OnError() {
426 BrowserThread::PostTask(BrowserThread::IO, 464 BrowserThread::PostTask(BrowserThread::IO,
427 FROM_HERE, 465 FROM_HERE,
428 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_)); 466 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
429 } 467 }
430 468
431 scoped_refptr<media::VideoFrame> 469 scoped_refptr<media::VideoCaptureDevice::Client::Buffer>
432 VideoCaptureController::VideoCaptureDeviceClient::DoReserveI420VideoFrame( 470 VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer(
433 const gfx::Size& size, 471 media::VideoFrame::Format format,
472 const gfx::Size& dimensions,
434 int rotation) { 473 int rotation) {
474 // The capture pipeline expects I420 for now.
475 DCHECK_EQ(format, media::VideoFrame::I420)
476 << "Non-I420 output buffer requested";
477
435 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; 478 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId;
436 scoped_refptr<media::VideoFrame> frame = 479 const size_t frame_bytes =
437 buffer_pool_->ReserveI420VideoFrame(size, rotation, &buffer_id_to_drop); 480 media::VideoFrame::AllocationSize(format, dimensions);
481
482 int buffer_id =
483 buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop);
484 if (buffer_id == VideoCaptureBufferPool::kInvalidId)
485 return NULL;
486 void* data;
487 size_t size;
488 buffer_pool_->GetBufferInfo(buffer_id, &data, &size);
489
490 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
491 new PoolBuffer(buffer_pool_, buffer_id, data, size));
492
438 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { 493 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) {
439 BrowserThread::PostTask(BrowserThread::IO, 494 BrowserThread::PostTask(BrowserThread::IO,
440 FROM_HERE, 495 FROM_HERE,
441 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, 496 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread,
442 controller_, buffer_id_to_drop)); 497 controller_, buffer_id_to_drop));
498 rotated_buffers_.erase(buffer_id_to_drop);
443 } 499 }
444 return frame; 500
501 // If a 90/270 rotation is required, letterboxing will be required. If the
502 // returned frame has not been rotated before, then the letterbox borders will
503 // not yet have been cleared and we should clear them now.
504 if ((rotation % 180) == 0) {
505 rotated_buffers_.erase(buffer_id);
506 } else {
507 if (rotated_buffers_.insert(buffer_id).second)
508 memset(output_buffer->data(), 0, output_buffer->size());
509 }
510
511 return output_buffer;
445 } 512 }
446 513
447 VideoCaptureController::~VideoCaptureController() { 514 VideoCaptureController::~VideoCaptureController() {
448 STLDeleteContainerPointers(controller_clients_.begin(), 515 STLDeleteContainerPointers(controller_clients_.begin(),
449 controller_clients_.end()); 516 controller_clients_.end());
450 } 517 }
451 518
452 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( 519 void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread(
453 const scoped_refptr<media::VideoFrame>& reserved_frame, 520 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer,
521 const gfx::Size& dimensions,
454 int frame_rate, 522 int frame_rate,
455 base::Time timestamp) { 523 base::Time timestamp) {
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
457 525 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId);
458 int buffer_id = buffer_pool_->RecognizeReservedBuffer(
459 reserved_frame->shared_memory_handle());
460 if (buffer_id < 0) {
461 NOTREACHED();
462 return;
463 }
464 526
465 media::VideoCaptureFormat frame_format( 527 media::VideoCaptureFormat frame_format(
466 reserved_frame->coded_size().width(), 528 dimensions.width(),
467 reserved_frame->coded_size().height(), 529 dimensions.height(),
468 frame_rate, 530 frame_rate,
469 media::VariableResolutionVideoCaptureDevice); 531 media::VariableResolutionVideoCaptureDevice);
470 532
471 int count = 0; 533 int count = 0;
472 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 534 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
473 for (ControllerClients::iterator client_it = controller_clients_.begin(); 535 for (ControllerClients::iterator client_it = controller_clients_.begin();
474 client_it != controller_clients_.end(); ++client_it) { 536 client_it != controller_clients_.end(); ++client_it) {
475 ControllerClient* client = *client_it; 537 ControllerClient* client = *client_it;
476 if (client->session_closed) 538 if (client->session_closed)
477 continue; 539 continue;
478 540
479 bool is_new_buffer = client->known_buffers.insert(buffer_id).second; 541 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second;
480 if (is_new_buffer) { 542 if (is_new_buffer) {
481 // On the first use of a buffer on a client, share the memory handle. 543 // On the first use of a buffer on a client, share the memory handle.
482 size_t memory_size = 0; 544 size_t memory_size = 0;
483 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess( 545 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess(
484 buffer_id, client->render_process_handle, &memory_size); 546 buffer->id(), client->render_process_handle, &memory_size);
485 client->event_handler->OnBufferCreated(client->controller_id, 547 client->event_handler->OnBufferCreated(
486 remote_handle, 548 client->controller_id, remote_handle, memory_size, buffer->id());
487 memory_size,
488 buffer_id);
489 } 549 }
490 550
491 client->event_handler->OnBufferReady(client->controller_id, 551 client->event_handler->OnBufferReady(
492 buffer_id, timestamp, 552 client->controller_id, buffer->id(), timestamp, frame_format);
493 frame_format); 553 bool inserted = client->active_buffers.insert(buffer->id()).second;
494 bool inserted = client->active_buffers.insert(buffer_id).second; 554 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id();
495 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer_id;
496 count++; 555 count++;
497 } 556 }
498 } 557 }
499 558
500 buffer_pool_->HoldForConsumers(buffer_id, count); 559 buffer_pool_->HoldForConsumers(buffer->id(), count);
501 } 560 }
502 561
503 void VideoCaptureController::DoErrorOnIOThread() { 562 void VideoCaptureController::DoErrorOnIOThread() {
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
505 state_ = VIDEO_CAPTURE_STATE_ERROR; 564 state_ = VIDEO_CAPTURE_STATE_ERROR;
506 565
507 for (ControllerClients::iterator client_it = controller_clients_.begin(); 566 for (ControllerClients::iterator client_it = controller_clients_.begin();
508 client_it != controller_clients_.end(); ++client_it) { 567 client_it != controller_clients_.end(); ++client_it) {
509 ControllerClient* client = *client_it; 568 ControllerClient* client = *client_it;
510 if (client->session_closed) 569 if (client->session_closed)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 } 617 }
559 return NULL; 618 return NULL;
560 } 619 }
561 620
562 int VideoCaptureController::GetClientCount() { 621 int VideoCaptureController::GetClientCount() {
563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
564 return controller_clients_.size(); 623 return controller_clients_.size();
565 } 624 }
566 625
567 } // namespace content 626 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698