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

Unified Diff: content/renderer/media/video_capture_impl.cc

Issue 8400084: refactor video capture in renderer process (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: code review Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/media/video_capture_impl.h ('k') | content/renderer/media/video_capture_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/video_capture_impl.cc
===================================================================
--- content/renderer/media/video_capture_impl.cc (revision 107874)
+++ content/renderer/media/video_capture_impl.cc (working copy)
@@ -9,15 +9,24 @@
#include "content/common/child_process.h"
#include "content/common/media/video_capture_messages.h"
-VideoCaptureImpl::DIBBuffer::DIBBuffer(
- base::SharedMemory* d, media::VideoCapture::VideoFrameBuffer* ptr)
- : dib(d),
- mapped_memory(ptr) {}
+struct VideoCaptureImpl::DIBBuffer {
+ public:
+ DIBBuffer(
+ base::SharedMemory* d,
+ media::VideoCapture::VideoFrameBuffer* ptr)
+ : dib(d),
+ mapped_memory(ptr),
+ references(0) {
+ }
+ ~DIBBuffer() {}
-VideoCaptureImpl::DIBBuffer::~DIBBuffer() {
- delete dib;
-}
+ scoped_ptr<base::SharedMemory> dib;
+ scoped_refptr<media::VideoCapture::VideoFrameBuffer> mapped_memory;
+ // Number of clients which hold this DIB.
+ int references;
+};
+
bool VideoCaptureImpl::CaptureStarted() {
return state_ == kStarted;
}
@@ -47,8 +56,7 @@
state_(kStopped) {
DCHECK(filter);
memset(&current_params_, 0, sizeof(current_params_));
- memset(&new_params_, 0, sizeof(new_params_));
- current_params_.session_id = new_params_.session_id = id;
+ current_params_.session_id = id;
}
VideoCaptureImpl::~VideoCaptureImpl() {
@@ -147,81 +155,62 @@
const VideoCaptureCapability& capability) {
DCHECK(ml_proxy_->BelongsToCurrentThread());
- if (pending_clients_.find(handler) != pending_clients_.end() ||
+ if (state_ == kError) {
+ handler->OnError(this, 1);
+ handler->OnRemoved(this);
+ return;
+ }
+
+ ClientInfo::iterator it1 = clients_pending_on_filter_.find(handler);
+ ClientInfo::iterator it2 = clients_pending_on_restart_.find(handler);
+ if (it1 != clients_pending_on_filter_.end() ||
+ it2 != clients_pending_on_restart_.end() ||
clients_.find(handler) != clients_.end() ) {
// This client has started.
return;
}
if (!device_id_) {
- pending_clients_[handler] = capability;
+ clients_pending_on_filter_[handler] = capability;
return;
}
- if (capability.resolution_fixed && master_clients_.size()) {
- bool matches_current_params =
- CapabilityMatchesParameters(capability, current_params_);
- bool matches_new_params =
- CapabilityMatchesParameters(capability, new_params_);
- if ((state_ == kStarted && !matches_current_params) ||
- (state_ == kStopping && !matches_new_params)) {
- // Can't have 2 master clients with different resolutions.
- handler->OnError(this, 1);
- handler->OnRemoved(this);
- return;
- }
- }
-
handler->OnStarted(this);
- clients_[handler] = capability;
- if (capability.resolution_fixed) {
- master_clients_.push_back(handler);
- if (master_clients_.size() > 1) {
- if (device_info_available_)
- handler->OnDeviceInfoReceived(this, device_info_);
+ if (state_ == kStarted) {
+ if (capability.width > current_params_.width ||
+ capability.height > current_params_.height) {
+ StopDevice();
+ DVLOG(1) << "StartCapture: Got client with higher resolution ("
+ << capability.width << ", " << capability.height << ") "
+ << "after started, try to restart.";
+ clients_pending_on_restart_[handler] = capability;
return;
}
- }
- if (state_ == kStarted) {
- // Take the resolution of master client.
- if (capability.resolution_fixed &&
- !CapabilityMatchesParameters(capability, current_params_)) {
- new_params_.width = capability.width;
- new_params_.height = capability.height;
- new_params_.frame_per_second = capability.max_fps;
- DLOG(INFO) << "StartCapture: Got master client with new resolution ("
- << new_params_.width << ", " << new_params_.height << ") "
- << "during started, try to restart.";
- StopDevice();
- } else if (device_info_available_) {
+ if (device_info_available_) {
handler->OnDeviceInfoReceived(this, device_info_);
}
+
+ clients_[handler] = capability;
return;
}
if (state_ == kStopping) {
- if (capability.resolution_fixed || !pending_start()) {
- new_params_.width = capability.width;
- new_params_.height = capability.height;
- new_params_.frame_per_second = capability.max_fps;
- DLOG(INFO) << "StartCapture: Got new resolution ("
- << new_params_.width << ", " << new_params_.height << ") "
- << ", already in stopping.";
- }
+ clients_pending_on_restart_[handler] = capability;
+ DVLOG(1) << "StartCapture: Got new resolution ("
+ << capability.width << ", " << capability.height << ") "
+ << ", during stopping.";
return;
}
+ clients_[handler] = capability;
DCHECK_EQ(clients_.size(), 1ul);
video_type_ = capability.raw_type;
- new_params_.width = 0;
- new_params_.height = 0;
- new_params_.frame_per_second = 0;
current_params_.width = capability.width;
current_params_.height = capability.height;
current_params_.frame_per_second = capability.max_fps;
- DLOG(INFO) << "StartCapture: resolution ("
- << current_params_.width << ", " << current_params_.height << ")";
+ DVLOG(1) << "StartCapture: starting with first resolution ("
+ << current_params_.width << ", " << current_params_.height << ")";
StartCaptureInternal();
}
@@ -230,13 +219,20 @@
media::VideoCapture::EventHandler* handler) {
DCHECK(ml_proxy_->BelongsToCurrentThread());
- ClientInfo::iterator it = pending_clients_.find(handler);
- if (it != pending_clients_.end()) {
+ ClientInfo::iterator it = clients_pending_on_filter_.find(handler);
+ if (it != clients_pending_on_filter_.end()) {
handler->OnStopped(this);
handler->OnRemoved(this);
- pending_clients_.erase(it);
+ clients_pending_on_filter_.erase(it);
return;
}
+ it = clients_pending_on_restart_.find(handler);
+ if (it != clients_pending_on_restart_.end()) {
+ handler->OnStopped(this);
+ handler->OnRemoved(this);
+ clients_pending_on_filter_.erase(it);
+ return;
+ }
if (clients_.find(handler) == clients_.end())
return;
@@ -244,64 +240,15 @@
handler->OnStopped(this);
handler->OnRemoved(this);
clients_.erase(handler);
- master_clients_.remove(handler);
- // Still have at least one master client.
- if (master_clients_.size() > 0)
- return;
-
- // TODO(wjia): Is it really needed to handle resolution change for non-master
- // clients, except no client case?
- if (clients_.size() > 0) {
- DLOG(INFO) << "StopCapture: No master client.";
- int max_width = 0;
- int max_height = 0;
- int frame_rate = 0;
- for (ClientInfo::iterator it = clients_.begin();
- it != clients_.end(); it++) {
- if (it->second.width > max_width && it->second.height > max_height) {
- max_width = it->second.width;
- max_height = it->second.height;
- frame_rate = it->second.max_fps;
- }
- }
-
- if (state_ == kStarted) {
- // Only handle resolution reduction.
- if (max_width < current_params_.width &&
- max_height < current_params_.height) {
- new_params_.width = max_width;
- new_params_.height = max_height;
- new_params_.frame_per_second = frame_rate;
- DLOG(INFO) << "StopCapture: New smaller resolution ("
- << new_params_.width << ", " << new_params_.height << ") "
- << "), stopping ...";
- StopDevice();
- }
- return;
- }
-
- if (state_ == kStopping) {
- new_params_.width = max_width;
- new_params_.height = max_height;
- new_params_.frame_per_second = frame_rate;
- DLOG(INFO) << "StopCapture: New resolution ("
- << new_params_.width << ", " << new_params_.height << ") "
- << "), during stopping.";
- return;
- }
- } else {
- new_params_.width = current_params_.width = 0;
- new_params_.height = current_params_.height = 0;
- new_params_.frame_per_second = current_params_.frame_per_second = 0;
- DLOG(INFO) << "StopCapture: No more client, stopping ...";
+ if (clients_.empty()) {
+ DVLOG(1) << "StopCapture: No more client, stopping ...";
StopDevice();
}
}
void VideoCaptureImpl::DoFeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) {
DCHECK(ml_proxy_->BelongsToCurrentThread());
- DCHECK(client_side_dibs_.find(buffer) != client_side_dibs_.end());
CachedDIB::iterator it;
for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) {
@@ -310,11 +257,10 @@
}
DCHECK(it != cached_dibs_.end());
- if (client_side_dibs_[buffer] <= 1) {
- client_side_dibs_.erase(buffer);
+ DCHECK_GT(it->second->references, 0);
+ it->second->references--;
+ if (it->second->references == 0) {
Send(new VideoCaptureHostMsg_BufferReady(device_id_, it->first));
- } else {
- client_side_dibs_[buffer]--;
}
}
@@ -322,6 +268,7 @@
base::SharedMemoryHandle handle,
int length, int buffer_id) {
DCHECK(ml_proxy_->BelongsToCurrentThread());
+ DCHECK(device_info_available_);
media::VideoCapture::VideoFrameBuffer* buffer;
DCHECK(cached_dibs_.find(buffer_id) == cached_dibs_.end());
@@ -331,8 +278,9 @@
buffer = new VideoFrameBuffer();
buffer->memory_pointer = static_cast<uint8*>(dib->memory());
buffer->buffer_size = length;
- buffer->width = current_params_.width;
- buffer->height = current_params_.height;
+ buffer->width = device_info_.width;
+ buffer->height = device_info_.height;
+ buffer->stride = device_info_.width;
DIBBuffer* dib_buffer = new DIBBuffer(dib, buffer);
cached_dibs_[buffer_id] = dib_buffer;
@@ -353,7 +301,7 @@
for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) {
it->first->OnBufferReady(this, buffer);
}
- client_side_dibs_[buffer] = clients_.size();
+ cached_dibs_[buffer_id]->references = clients_.size();
}
void VideoCaptureImpl::DoStateChanged(const media::VideoCapture::State& state) {
@@ -364,9 +312,9 @@
break;
case media::VideoCapture::kStopped:
state_ = kStopped;
- DLOG(INFO) << "OnStateChanged: stopped!, device_id = " << device_id_;
+ DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_;
STLDeleteValues(&cached_dibs_);
- if (pending_start())
+ if (!clients_.empty() || !clients_pending_on_restart_.empty())
RestartCapture();
break;
case media::VideoCapture::kPaused:
@@ -376,6 +324,7 @@
}
break;
case media::VideoCapture::kError:
+ DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_;
for (ClientInfo::iterator it = clients_.begin();
it != clients_.end(); it++) {
// TODO(wjia): browser process would send error code.
@@ -383,9 +332,7 @@
it->first->OnRemoved(this);
}
clients_.clear();
- master_clients_.clear();
- state_ = kStopped;
- current_params_.width = current_params_.height = 0;
+ state_ = kError;
break;
default:
break;
@@ -395,9 +342,10 @@
void VideoCaptureImpl::DoDeviceInfoReceived(
const media::VideoCaptureParams& device_info) {
DCHECK(ml_proxy_->BelongsToCurrentThread());
- if (state_ != kStarted)
- return;
+ DCHECK(!ClientHasDIB());
+ STLDeleteValues(&cached_dibs_);
+
device_info_ = device_info;
device_info_available_ = true;
for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) {
@@ -406,15 +354,15 @@
}
void VideoCaptureImpl::DoDelegateAdded(int32 device_id) {
- DLOG(INFO) << "DoDelegateAdded: device_id " << device_id;
+ DVLOG(1) << "DoDelegateAdded: device_id " << device_id;
DCHECK(ml_proxy_->BelongsToCurrentThread());
device_id_ = device_id;
- for (ClientInfo::iterator it = pending_clients_.begin();
- it != pending_clients_.end(); ) {
+ for (ClientInfo::iterator it = clients_pending_on_filter_.begin();
+ it != clients_pending_on_filter_.end(); ) {
media::VideoCapture::EventHandler* handler = it->first;
const VideoCaptureCapability capability = it->second;
- pending_clients_.erase(it++);
+ clients_pending_on_filter_.erase(it++);
StartCapture(handler, capability);
}
}
@@ -434,16 +382,28 @@
DCHECK(ml_proxy_->BelongsToCurrentThread());
DCHECK_EQ(state_, kStopped);
- current_params_.width = new_params_.width;
- current_params_.height = new_params_.height;
- current_params_.frame_per_second = new_params_.frame_per_second;
-
- new_params_.width = 0;
- new_params_.height = 0;
- new_params_.frame_per_second = 0;
-
- DLOG(INFO) << "RestartCapture, " << current_params_.width << ", "
- << current_params_.height;
+ int width = 0;
+ int height = 0;
+ for (ClientInfo::iterator it = clients_.begin();
+ it != clients_.end(); it++) {
+ if (it->second.width > width)
+ width = it->second.width;
+ if (it->second.height > height)
+ height = it->second.height;
+ }
+ for (ClientInfo::iterator it = clients_pending_on_restart_.begin();
+ it != clients_pending_on_restart_.end(); ) {
+ if (it->second.width > width)
+ width = it->second.width;
+ if (it->second.height > height)
+ height = it->second.height;
+ clients_[it->first] = it->second;
+ clients_pending_on_restart_.erase(it++);
+ }
+ current_params_.width = width;
+ current_params_.height = height;
+ DVLOG(1) << "RestartCapture, " << current_params_.width << ", "
+ << current_params_.height;
StartCaptureInternal();
}
@@ -473,10 +433,11 @@
message_filter_.get(), message)));
}
-bool VideoCaptureImpl::CapabilityMatchesParameters(
- const VideoCaptureCapability& capability,
- const media::VideoCaptureParams& params) {
- return (capability.width == params.width &&
- capability.height == params.height &&
- capability.max_fps == params.frame_per_second);
+bool VideoCaptureImpl::ClientHasDIB() {
+ CachedDIB::iterator it;
+ for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) {
+ if (it->second->references > 0)
+ return true;
+ }
+ return false;
}
« no previous file with comments | « content/renderer/media/video_capture_impl.h ('k') | content/renderer/media/video_capture_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698