| Index: content/browser/renderer_host/media/video_capture_controller.cc
|
| ===================================================================
|
| --- content/browser/renderer_host/media/video_capture_controller.cc (revision 141042)
|
| +++ content/browser/renderer_host/media/video_capture_controller.cc (working copy)
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "content/browser/renderer_host/media/video_capture_controller.h"
|
|
|
| +#include <set>
|
| +
|
| #include "base/bind.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/stl_util.h"
|
| @@ -27,8 +29,7 @@
|
| event_handler(handler),
|
| render_process_handle(render_process),
|
| parameters(params),
|
| - session_closed(false),
|
| - report_ready_to_delete(false) {
|
| + session_closed(false) {
|
| }
|
|
|
| ~ControllerClient() {}
|
| @@ -42,14 +43,10 @@
|
| media::VideoCaptureParams parameters;
|
|
|
| // Buffers used by this client.
|
| - std::list<int> buffers;
|
| + std::set<int> buffers;
|
|
|
| // State of capture session, controlled by VideoCaptureManager directly.
|
| bool session_closed;
|
| -
|
| - // Record client's status when it has called StopCapture, but haven't
|
| - // returned all buffers.
|
| - bool report_ready_to_delete;
|
| };
|
|
|
| struct VideoCaptureController::SharedDIB {
|
| @@ -145,60 +142,44 @@
|
|
|
| void VideoCaptureController::StopCapture(
|
| const VideoCaptureControllerID& id,
|
| - VideoCaptureControllerEventHandler* event_handler,
|
| - bool force_buffer_return) {
|
| + VideoCaptureControllerEventHandler* event_handler) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| DVLOG(1) << "VideoCaptureController::StopCapture, id " << id.device_id;
|
|
|
| ControllerClient* client = FindClient(id, event_handler, pending_clients_);
|
| // If the client is still in pending queue, just remove it.
|
| if (client) {
|
| - client->event_handler->OnReadyToDelete(client->controller_id);
|
| pending_clients_.remove(client);
|
| return;
|
| }
|
|
|
| client = FindClient(id, event_handler, controller_clients_);
|
| - DCHECK(client) << "Client should have called StartCapture()";
|
| + if (!client)
|
| + return;
|
|
|
| - if (force_buffer_return) {
|
| - // The client requests to return buffers which means it can't return
|
| - // buffers normally. After buffers are returned, client is free to
|
| - // delete itself. No need to call OnReadyToDelete.
|
| + // Take back all buffers held by the |client|.
|
| + for (std::set<int>::iterator buffer_it = client->buffers.begin();
|
| + buffer_it != client->buffers.end(); ++buffer_it) {
|
| + int buffer_id = *buffer_it;
|
| + DIBMap::iterator dib_it = owned_dibs_.find(buffer_id);
|
| + if (dib_it == owned_dibs_.end())
|
| + continue;
|
|
|
| - // Return all buffers held by the clients.
|
| - for (std::list<int>::iterator buffer_it = client->buffers.begin();
|
| - buffer_it != client->buffers.end(); ++buffer_it) {
|
| - int buffer_id = *buffer_it;
|
| - DIBMap::iterator dib_it = owned_dibs_.find(buffer_id);
|
| - if (dib_it == owned_dibs_.end())
|
| - continue;
|
| -
|
| - {
|
| - base::AutoLock lock(lock_);
|
| - DCHECK_GT(dib_it->second->references, 0)
|
| - << "The buffer is not used by renderer.";
|
| - dib_it->second->references -= 1;
|
| - }
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + DCHECK_GT(dib_it->second->references, 0)
|
| + << "The buffer is not used by renderer.";
|
| + dib_it->second->references -= 1;
|
| }
|
| - client->buffers.clear();
|
| - } else {
|
| - // Normal way to stop capture.
|
| - if (!client->buffers.empty()) {
|
| - // There are still some buffers held by the client.
|
| - client->report_ready_to_delete = true;
|
| - return;
|
| - }
|
| - // No buffer is held by the client. Ready to delete.
|
| - client->event_handler->OnReadyToDelete(client->controller_id);
|
| }
|
| + client->buffers.clear();
|
|
|
| int session_id = client->parameters.session_id;
|
| delete client;
|
| controller_clients_.remove(client);
|
|
|
| // No more clients. Stop device.
|
| - if (controller_clients_.empty()) {
|
| + if (controller_clients_.empty() && state_ == video_capture::kStarted) {
|
| video_capture_manager_->Stop(session_id,
|
| base::Bind(&VideoCaptureController::OnDeviceStopped, this));
|
| frame_info_available_ = false;
|
| @@ -232,25 +213,12 @@
|
| DIBMap::iterator dib_it = owned_dibs_.find(buffer_id);
|
| // If this buffer is not held by this client, or this client doesn't exist
|
| // in controller, do nothing.
|
| - if (!client || dib_it == owned_dibs_.end())
|
| + if (!client ||
|
| + client->buffers.find(buffer_id) == client->buffers.end() ||
|
| + dib_it == owned_dibs_.end())
|
| return;
|
|
|
| - client->buffers.remove(buffer_id);
|
| - // If this client has called StopCapture and doesn't hold any buffer after
|
| - // after this return, ready to delete this client.
|
| - if (client->report_ready_to_delete && client->buffers.empty()) {
|
| - client->event_handler->OnReadyToDelete(client->controller_id);
|
| - delete client;
|
| - controller_clients_.remove(client);
|
| -
|
| - if (controller_clients_.empty()) {
|
| - // No more clients. Stop device.
|
| - video_capture_manager_->Stop(current_params_.session_id,
|
| - base::Bind(&VideoCaptureController::OnDeviceStopped, this));
|
| - frame_info_available_ = false;
|
| - state_ = video_capture::kStopping;
|
| - }
|
| - }
|
| + client->buffers.erase(buffer_id);
|
| {
|
| base::AutoLock lock(lock_);
|
| DCHECK_GT(dib_it->second->references, 0)
|
| @@ -262,7 +230,7 @@
|
|
|
| // When all buffers have been returned by clients and device has been
|
| // called to stop, check if restart is needed. This could happen when
|
| - // some clients call StopCapture before returning all buffers.
|
| + // capture needs to be restarted due to resolution change.
|
| if (!ClientHasDIB() && state_ == video_capture::kStopping) {
|
| PostStopping();
|
| }
|
| @@ -404,13 +372,12 @@
|
| if (state_ == video_capture::kStarted) {
|
| for (ControllerClients::iterator client_it = controller_clients_.begin();
|
| client_it != controller_clients_.end(); client_it++) {
|
| - if ((*client_it)->report_ready_to_delete ||
|
| - (*client_it)->session_closed)
|
| + if ((*client_it)->session_closed)
|
| continue;
|
|
|
| (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id,
|
| buffer_id, timestamp);
|
| - (*client_it)->buffers.push_back(buffer_id);
|
| + (*client_it)->buffers.insert(buffer_id);
|
| count++;
|
| }
|
| }
|
|
|