Chromium Code Reviews| 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..2537cdc1b17ef5e94812bf258842e446bfee9e05 100644 |
| --- a/media/video/capture/linux/video_capture_device_linux.cc |
| +++ b/media/video/capture/linux/video_capture_device_linux.cc |
| @@ -196,7 +196,6 @@ 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"), |
| @@ -217,68 +216,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 +344,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 +369,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 +380,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 +536,7 @@ void VideoCaptureDeviceLinux::DeAllocateVideoBuffers() { |
| } |
| void VideoCaptureDeviceLinux::SetErrorState(const std::string& reason) { |
| + DCHECK_EQ(v4l2_thread_.message_loop(), base::MessageLoop::current()); |
|
ncarter (slow)
2013/10/01 20:45:23
The "theoretical" cleanup call to DeAllocateVideoB
Ami GONE FROM CHROMIUM
2013/10/01 21:17:27
I think line 380 is the reason for the "(theoretic
jiayl
2013/10/01 21:34:17
Done.
|
| DVLOG(1) << reason; |
| state_ = kError; |
| client_->OnError(); |