Index: media/video/capture/linux/video_capture_device_linux.cc |
diff --git a/media/video/capture/linux/video_capture_device_linux.cc b/media/video/capture/linux/video_capture_device_linux.cc |
index cc01a3e9830873a20f2edebc8c2b776310df71a9..b7a2e137ea9e42273c9636a82770f0f87e7314f2 100644 |
--- a/media/video/capture/linux/video_capture_device_linux.cc |
+++ b/media/video/capture/linux/video_capture_device_linux.cc |
@@ -196,14 +196,12 @@ VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { |
VideoCaptureDeviceLinux::VideoCaptureDeviceLinux(const Name& device_name) |
: state_(kIdle), |
- client_(NULL), |
device_name_(device_name), |
device_fd_(-1), |
v4l2_thread_("V4L2Thread"), |
buffer_pool_(NULL), |
buffer_pool_size_(0), |
- timeout_count_(0) { |
-} |
+ timeout_count_(0) {} |
VideoCaptureDeviceLinux::~VideoCaptureDeviceLinux() { |
state_ = kIdle; |
@@ -217,68 +215,45 @@ VideoCaptureDeviceLinux::~VideoCaptureDeviceLinux() { |
} |
} |
-void VideoCaptureDeviceLinux::Allocate( |
+void VideoCaptureDeviceLinux::AllocateAndStart( |
const VideoCaptureCapability& capture_format, |
- VideoCaptureDevice::Client* client) { |
+ scoped_ptr<VideoCaptureDevice::Client> client) { |
if (v4l2_thread_.IsRunning()) { |
return; // Wrong state. |
} |
v4l2_thread_.Start(); |
- v4l2_thread_.message_loop() |
- ->PostTask(FROM_HERE, |
- base::Bind(&VideoCaptureDeviceLinux::OnAllocate, |
- base::Unretained(this), |
- capture_format.width, |
- capture_format.height, |
- capture_format.frame_rate, |
- client)); |
-} |
- |
-void VideoCaptureDeviceLinux::Start() { |
- if (!v4l2_thread_.IsRunning()) { |
- return; // Wrong state. |
- } |
v4l2_thread_.message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&VideoCaptureDeviceLinux::OnStart, base::Unretained(this))); |
+ base::Bind(&VideoCaptureDeviceLinux::OnAllocateAndStart, |
+ base::Unretained(this), |
+ capture_format.width, |
+ capture_format.height, |
+ capture_format.frame_rate, |
+ base::Passed(&client))); |
} |
-void VideoCaptureDeviceLinux::Stop() { |
+void VideoCaptureDeviceLinux::StopAndDeAllocate() { |
if (!v4l2_thread_.IsRunning()) { |
return; // Wrong state. |
} |
v4l2_thread_.message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&VideoCaptureDeviceLinux::OnStop, base::Unretained(this))); |
-} |
- |
-void VideoCaptureDeviceLinux::DeAllocate() { |
- if (!v4l2_thread_.IsRunning()) { |
- return; // Wrong state. |
- } |
- v4l2_thread_.message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&VideoCaptureDeviceLinux::OnDeAllocate, |
+ base::Bind(&VideoCaptureDeviceLinux::OnStopAndDeAllocate, |
base::Unretained(this))); |
v4l2_thread_.Stop(); |
- |
// Make sure no buffers are still allocated. |
// This can happen (theoretically) if an error occurs when trying to stop |
// the camera. |
DeAllocateVideoBuffers(); |
} |
-const VideoCaptureDevice::Name& VideoCaptureDeviceLinux::device_name() { |
- return device_name_; |
-} |
- |
-void VideoCaptureDeviceLinux::OnAllocate(int width, |
- int height, |
- int frame_rate, |
- Client* client) { |
+void VideoCaptureDeviceLinux::OnAllocateAndStart(int width, |
+ int height, |
+ int frame_rate, |
+ scoped_ptr<Client> client) { |
DCHECK_EQ(v4l2_thread_.message_loop(), base::MessageLoop::current()); |
- client_ = client; |
+ client_ = client.Pass(); |
// Need to open camera with O_RDWR after Linux kernel 3.3. |
if ((device_fd_ = open(device_name_.id().c_str(), O_RDWR)) < 0) { |
@@ -368,37 +343,10 @@ void VideoCaptureDeviceLinux::OnAllocate(int width, |
current_settings.expected_capture_delay = 0; |
current_settings.interlaced = false; |
- state_ = kAllocated; |
// Report the resulting frame size to the client. |
client_->OnFrameInfo(current_settings); |
-} |
- |
-void VideoCaptureDeviceLinux::OnDeAllocate() { |
- DCHECK_EQ(v4l2_thread_.message_loop(), base::MessageLoop::current()); |
- |
- // If we are in error state or capturing |
- // try to stop the camera. |
- if (state_ == kCapturing) { |
- OnStop(); |
- } |
- if (state_ == kAllocated) { |
- state_ = kIdle; |
- } |
- |
- // We need to close and open the device if we want to change the settings |
- // Otherwise VIDIOC_S_FMT will return error |
- // Sad but true. |
- close(device_fd_); |
- device_fd_ = -1; |
-} |
- |
-void VideoCaptureDeviceLinux::OnStart() { |
- DCHECK_EQ(v4l2_thread_.message_loop(), base::MessageLoop::current()); |
- |
- if (state_ != kAllocated) { |
- return; |
- } |
+ // Start capturing. |
if (!AllocateVideoBuffers()) { |
// Error, We can not recover. |
SetErrorState("Allocate buffer failed"); |
@@ -420,11 +368,9 @@ void VideoCaptureDeviceLinux::OnStart() { |
base::Unretained(this))); |
} |
-void VideoCaptureDeviceLinux::OnStop() { |
+void VideoCaptureDeviceLinux::OnStopAndDeAllocate() { |
DCHECK_EQ(v4l2_thread_.message_loop(), base::MessageLoop::current()); |
- state_ = kAllocated; |
- |
v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
if (ioctl(device_fd_, VIDIOC_STREAMOFF, &type) < 0) { |
SetErrorState("VIDIOC_STREAMOFF failed"); |
@@ -433,6 +379,14 @@ void VideoCaptureDeviceLinux::OnStop() { |
// We don't dare to deallocate the buffers if we can't stop |
// the capture device. |
DeAllocateVideoBuffers(); |
+ |
+ // We need to close and open the device if we want to change the settings |
+ // Otherwise VIDIOC_S_FMT will return error |
+ // Sad but true. |
+ close(device_fd_); |
+ device_fd_ = -1; |
+ state_ = kIdle; |
+ client_.reset(); |
} |
void VideoCaptureDeviceLinux::OnCaptureTask() { |
@@ -581,6 +535,8 @@ void VideoCaptureDeviceLinux::DeAllocateVideoBuffers() { |
} |
void VideoCaptureDeviceLinux::SetErrorState(const std::string& reason) { |
+ DCHECK(!v4l2_thread_.IsRunning() || |
+ v4l2_thread_.message_loop() == base::MessageLoop::current()); |
DVLOG(1) << reason; |
state_ = kError; |
client_->OnError(); |