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

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

Issue 10837225: chop the width/height to even number when incoming frame has odd number dimension. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 4 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
« no previous file with comments | « content/browser/renderer_host/media/video_capture_controller.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 // The memory created to be shared with renderer processes. 60 // The memory created to be shared with renderer processes.
61 scoped_ptr<base::SharedMemory> shared_memory; 61 scoped_ptr<base::SharedMemory> shared_memory;
62 62
63 // Number of renderer processes which hold this shared memory. 63 // Number of renderer processes which hold this shared memory.
64 // renderer process is represented by VidoeCaptureHost. 64 // renderer process is represented by VidoeCaptureHost.
65 int references; 65 int references;
66 }; 66 };
67 67
68 VideoCaptureController::VideoCaptureController( 68 VideoCaptureController::VideoCaptureController(
69 media_stream::VideoCaptureManager* video_capture_manager) 69 media_stream::VideoCaptureManager* video_capture_manager)
70 : frame_info_available_(false), 70 : chopped_width_(0),
71 chopped_height_(0),
72 frame_info_available_(false),
71 video_capture_manager_(video_capture_manager), 73 video_capture_manager_(video_capture_manager),
72 device_in_use_(false), 74 device_in_use_(false),
73 state_(video_capture::kStopped) { 75 state_(video_capture::kStopped) {
74 memset(&current_params_, 0, sizeof(current_params_)); 76 memset(&current_params_, 0, sizeof(current_params_));
75 } 77 }
76 78
77 void VideoCaptureController::StartCapture( 79 void VideoCaptureController::StartCapture(
78 const VideoCaptureControllerID& id, 80 const VideoCaptureControllerID& id,
79 VideoCaptureControllerEventHandler* event_handler, 81 VideoCaptureControllerEventHandler* event_handler,
80 base::ProcessHandle render_process, 82 base::ProcessHandle render_process,
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 2); 272 2);
271 uint8* yplane = target; 273 uint8* yplane = target;
272 uint8* uplane = target + frame_info_.width * frame_info_.height; 274 uint8* uplane = target + frame_info_.width * frame_info_.height;
273 uint8* vplane = uplane + (frame_info_.width * frame_info_.height) / 4; 275 uint8* vplane = uplane + (frame_info_.width * frame_info_.height) / 4;
274 276
275 // Do color conversion from the camera format to I420. 277 // Do color conversion from the camera format to I420.
276 switch (frame_info_.color) { 278 switch (frame_info_.color) {
277 case media::VideoCaptureCapability::kColorUnknown: // Color format not set. 279 case media::VideoCaptureCapability::kColorUnknown: // Color format not set.
278 break; 280 break;
279 case media::VideoCaptureCapability::kI420: { 281 case media::VideoCaptureCapability::kI420: {
282 DCHECK(!chopped_width_ && !chopped_height_);
280 memcpy(target, data, (frame_info_.width * frame_info_.height * 3) / 2); 283 memcpy(target, data, (frame_info_.width * frame_info_.height * 3) / 2);
281 break; 284 break;
282 } 285 }
283 case media::VideoCaptureCapability::kYV12: { 286 case media::VideoCaptureCapability::kYV12: {
287 DCHECK(!chopped_width_ && !chopped_height_);
284 const uint8* ptr = data; 288 const uint8* ptr = data;
285 memcpy(yplane, ptr, (frame_info_.width * frame_info_.height)); 289 memcpy(yplane, ptr, (frame_info_.width * frame_info_.height));
286 ptr += frame_info_.width * frame_info_.height; 290 ptr += frame_info_.width * frame_info_.height;
287 memcpy(vplane, ptr, (frame_info_.width * frame_info_.height) >> 2); 291 memcpy(vplane, ptr, (frame_info_.width * frame_info_.height) >> 2);
288 ptr += (frame_info_.width * frame_info_.height) >> 2; 292 ptr += (frame_info_.width * frame_info_.height) >> 2;
289 memcpy(uplane, ptr, (frame_info_.width * frame_info_.height) >> 2); 293 memcpy(uplane, ptr, (frame_info_.width * frame_info_.height) >> 2);
290 break; 294 break;
291 } 295 }
292 case media::VideoCaptureCapability::kNV21: { 296 case media::VideoCaptureCapability::kNV21: {
297 DCHECK(!chopped_width_ && !chopped_height_);
293 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, 298 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width,
294 frame_info_.height); 299 frame_info_.height);
295 break; 300 break;
296 } 301 }
297 case media::VideoCaptureCapability::kYUY2: { 302 case media::VideoCaptureCapability::kYUY2: {
303 DCHECK(!chopped_width_ && !chopped_height_);
298 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, 304 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width,
299 frame_info_.height); 305 frame_info_.height);
300 break; 306 break;
301 } 307 }
302 case media::VideoCaptureCapability::kRGB24: { 308 case media::VideoCaptureCapability::kRGB24: {
303 int ystride = frame_info_.width; 309 int ystride = frame_info_.width;
304 int uvstride = frame_info_.width / 2; 310 int uvstride = frame_info_.width / 2;
305 #if defined(OS_WIN) // RGB on Windows start at the bottom line. 311 #if defined(OS_WIN) // RGB on Windows start at the bottom line.
306 int rgb_stride = -3 * frame_info_.width; 312 int rgb_stride = -3 * (frame_info_.width + chopped_width_);
307 const uint8* rgb_src = data + 3 * frame_info_.width * 313 const uint8* rgb_src = data + 3 * (frame_info_.width + chopped_width_) *
308 (frame_info_.height -1); 314 (frame_info_.height -1 + chopped_height_);
309 #else 315 #else
310 int rgb_stride = 3 * frame_info_.width; 316 int rgb_stride = 3 * (frame_info_.width + chopped_width_);
311 const uint8* rgb_src = data; 317 const uint8* rgb_src = data;
312 #endif 318 #endif
313 media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane, 319 media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane,
314 frame_info_.width, frame_info_.height, 320 frame_info_.width, frame_info_.height,
315 rgb_stride, ystride, uvstride); 321 rgb_stride, ystride, uvstride);
316 break; 322 break;
317 } 323 }
318 case media::VideoCaptureCapability::kARGB: { 324 case media::VideoCaptureCapability::kARGB: {
319 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width, 325 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width,
320 frame_info_.height, frame_info_.width * 4, 326 frame_info_.height,
327 (frame_info_.width + chopped_width_) * 4,
321 frame_info_.width, frame_info_.width / 2); 328 frame_info_.width, frame_info_.width / 2);
322 break; 329 break;
323 } 330 }
324 default: 331 default:
325 NOTREACHED(); 332 NOTREACHED();
326 } 333 }
327 334
328 BrowserThread::PostTask(BrowserThread::IO, 335 BrowserThread::PostTask(BrowserThread::IO,
329 FROM_HERE, 336 FROM_HERE,
330 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 337 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
331 this, buffer_id, timestamp)); 338 this, buffer_id, timestamp));
332 } 339 }
333 340
334 void VideoCaptureController::OnError() { 341 void VideoCaptureController::OnError() {
335 video_capture_manager_->Error(current_params_.session_id); 342 video_capture_manager_->Error(current_params_.session_id);
336 BrowserThread::PostTask(BrowserThread::IO, 343 BrowserThread::PostTask(BrowserThread::IO,
337 FROM_HERE, 344 FROM_HERE,
338 base::Bind(&VideoCaptureController::DoErrorOnIOThread, this)); 345 base::Bind(&VideoCaptureController::DoErrorOnIOThread, this));
339 } 346 }
340 347
341 void VideoCaptureController::OnFrameInfo( 348 void VideoCaptureController::OnFrameInfo(
342 const media::VideoCaptureCapability& info) { 349 const media::VideoCaptureCapability& info) {
343 frame_info_= info; 350 frame_info_= info;
351 // Handle cases when |info| has odd numbers for width/height.
352 if (info.width & 1) {
353 --frame_info_.width;
354 chopped_width_ = 1;
355 } else {
356 chopped_width_ = 0;
357 }
358 if (info.height & 1) {
359 --frame_info_.height;
360 chopped_height_ = 1;
361 } else {
362 chopped_height_ = 0;
363 }
344 BrowserThread::PostTask(BrowserThread::IO, 364 BrowserThread::PostTask(BrowserThread::IO,
345 FROM_HERE, 365 FROM_HERE,
346 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, 366 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, this));
347 this, info));
348 } 367 }
349 368
350 VideoCaptureController::~VideoCaptureController() { 369 VideoCaptureController::~VideoCaptureController() {
351 // Delete all DIBs. 370 // Delete all DIBs.
352 STLDeleteContainerPairSecondPointers(owned_dibs_.begin(), 371 STLDeleteContainerPairSecondPointers(owned_dibs_.begin(),
353 owned_dibs_.end()); 372 owned_dibs_.end());
354 STLDeleteContainerPointers(controller_clients_.begin(), 373 STLDeleteContainerPointers(controller_clients_.begin(),
355 controller_clients_.end()); 374 controller_clients_.end());
356 STLDeleteContainerPointers(pending_clients_.begin(), 375 STLDeleteContainerPointers(pending_clients_.begin(),
357 pending_clients_.end()); 376 pending_clients_.end());
(...skipping 24 matching lines...) Expand all
382 } 401 }
383 } 402 }
384 403
385 base::AutoLock lock(lock_); 404 base::AutoLock lock(lock_);
386 if (owned_dibs_.find(buffer_id) != owned_dibs_.end()) { 405 if (owned_dibs_.find(buffer_id) != owned_dibs_.end()) {
387 DCHECK_EQ(owned_dibs_[buffer_id]->references, -1); 406 DCHECK_EQ(owned_dibs_[buffer_id]->references, -1);
388 owned_dibs_[buffer_id]->references = count; 407 owned_dibs_[buffer_id]->references = count;
389 } 408 }
390 } 409 }
391 410
392 void VideoCaptureController::DoFrameInfoOnIOThread( 411 void VideoCaptureController::DoFrameInfoOnIOThread() {
393 const media::VideoCaptureCapability& info) {
394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
395 DCHECK(owned_dibs_.empty()) 413 DCHECK(owned_dibs_.empty())
396 << "Device is restarted without releasing shared memory."; 414 << "Device is restarted without releasing shared memory.";
397 415
416 // Allocate memory only when device has been started.
417 if (state_ != video_capture::kStarted)
418 return;
419
398 bool frames_created = true; 420 bool frames_created = true;
399 const size_t needed_size = (info.width * info.height * 3) / 2; 421 const size_t needed_size = (frame_info_.width * frame_info_.height * 3) / 2;
400 { 422 {
401 base::AutoLock lock(lock_); 423 base::AutoLock lock(lock_);
402 for (size_t i = 1; i <= kNoOfDIBS; ++i) { 424 for (size_t i = 1; i <= kNoOfDIBS; ++i) {
403 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 425 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
404 if (!shared_memory->CreateAndMapAnonymous(needed_size)) { 426 if (!shared_memory->CreateAndMapAnonymous(needed_size)) {
405 frames_created = false; 427 frames_created = false;
406 break; 428 break;
407 } 429 }
408 SharedDIB* dib = new SharedDIB(shared_memory.release()); 430 SharedDIB* dib = new SharedDIB(shared_memory.release());
409 owned_dibs_.insert(std::make_pair(i, dib)); 431 owned_dibs_.insert(std::make_pair(i, dib));
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 bool VideoCaptureController::ClientHasDIB() { 571 bool VideoCaptureController::ClientHasDIB() {
550 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 572 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
551 base::AutoLock lock(lock_); 573 base::AutoLock lock(lock_);
552 for (DIBMap::iterator dib_it = owned_dibs_.begin(); 574 for (DIBMap::iterator dib_it = owned_dibs_.begin();
553 dib_it != owned_dibs_.end(); dib_it++) { 575 dib_it != owned_dibs_.end(); dib_it++) {
554 if (dib_it->second->references > 0) 576 if (dib_it->second->references > 0)
555 return true; 577 return true;
556 } 578 }
557 return false; 579 return false;
558 } 580 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698