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

Side by Side Diff: media/capture/service/video_capture_handler_impl.cc

Issue 1699553002: Mojo Video Capture service in media/capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased to using MojoSharedBufferVideoFrame Created 4 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/capture/service/video_capture_handler_impl.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/guid.h"
11 #include "base/logging.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/trace_event/trace_event.h"
14 #include "media/base/video_capture_types.h"
15 #include "media/capture/service/stream_impl.h"
16 #include "media/capture/service/video_capture_device_client_impl.h"
17 #include "media/capture/video/video_capture_device_factory.h"
18 #include "mojo/converters/geometry/geometry_type_converters.h"
19
20 namespace media {
21
22 VideoCaptureHandlerImpl::VideoCaptureHandlerImpl(mojo::ApplicationImpl* app)
23 : app_(app),
24 video_capture_device_factory_(
25 media::VideoCaptureDeviceFactory::CreateFactory(
26 base::ThreadTaskRunnerHandle::Get())),
27 weak_factory_(this) {
28 // Enumerating devices is something that takes a while (up to hundred of ms in
29 // certain OSs).
30 // TODO(mcasas): Add a UMA like in VideoCaptureManager::EnumerateDevices().
31 TRACE_EVENT_ASYNC_BEGIN0("video_capture", "EnumerateDeviceNames",
32 this /* id */);
33 video_capture_device_factory_->EnumerateDeviceNames(
34 base::Bind(&VideoCaptureHandlerImpl::OnVideoCaptureDevicesEnumerated,
35 weak_factory_.GetWeakPtr()));
36
37 // Sadly this SystemMonitor does not do much for Video devices unless someone
38 // notifies of changes.
39 // TODO(mcasas): monitor http://crbug.com/584817 and perhaps launch the
40 // appropriate DeviceMonitor from here.
41 base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
42 }
43
44 VideoCaptureHandlerImpl::~VideoCaptureHandlerImpl() {
45 DCHECK(thread_checker_.CalledOnValidThread());
46 for (const auto& id_and_device_and_stream : device_and_streams_)
47 id_and_device_and_stream.second.first->StopAndDeAllocate();
48
49 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this);
50 }
51
52 void VideoCaptureHandlerImpl::EnumerateDevices(
53 const EnumerateDevicesCallback& callback) {
54 DVLOG(1) << __FUNCTION__;
55 DCHECK(thread_checker_.CalledOnValidThread());
56
57 mojo::Array<mojom::VideoCaptureDeviceInfoPtr> reply;
58 if (!device_names_->empty()) {
perkj_chrome 2016/03/07 23:58:27 ? So if this is called before video_capture_device
mcasas 2016/03/08 23:57:29 That should never happen because the Monitors sta
59 for (const auto& device_name : *device_names_) {
60 mojom::VideoCaptureDeviceInfoPtr video_capture_device_info =
61 mojom::VideoCaptureDeviceInfo::New();
62
63 // Send a GUID of the Video Capture id to hide sensitive information.
perkj_chrome 2016/03/07 23:58:27 Why would this be sensitive? Doesnt this mean you
mcasas 2016/03/08 23:57:29 You can't send the OS-specific device ID to rende
64 const std::string guid = base::GenerateGUID();
65 public_to_private_id_map_[guid] = device_name.id();
66 video_capture_device_info->device_id = guid;
67 video_capture_device_info->name = device_name.GetNameAndModel();
68
69 reply.push_back(std::move(video_capture_device_info));
70 }
71 }
72 callback.Run(std::move(reply));
73 }
74
75 void VideoCaptureHandlerImpl::RequestVideoCaptureStream(
76 mojom::VideoCaptureOptionsPtr options,
77 const RequestVideoCaptureStreamCallback& callback) {
78 DVLOG(1) << __FUNCTION__ << " device guid: " << options->device_id;
79 DCHECK(thread_checker_.CalledOnValidThread());
80
81 const std::string& guid = options->device_id;
82 if (!ContainsKey(public_to_private_id_map_, guid)) {
83 DLOG(ERROR) << "Device identified as " << guid << " not found!";
84 return;
85 }
86
87 // Try to find |options->id| in the list of devices. If not found -> return.
88 const std::string& id = public_to_private_id_map_[guid];
89 auto name = std::find_if(device_names_->begin(), device_names_->end(),
90 [id](const media::VideoCaptureDevice::Name& name) {
91 return name.id() == id;
92 });
93 if (name == device_names_->end()) {
94 DLOG(ERROR) << "device " << options->device_id << " not found.";
95 callback.Run(nullptr);
96 return;
97 }
98
99 // TODO(mcasas): At this point we need to ask the user for permission to use
perkj_chrome 2016/03/07 23:58:27 This must be handled outside this mojo and is not
mcasas 2016/03/08 23:57:29 Done.
100 // this device if it hasn't been granted before or elsewhere. Soldier on for
101 // the time being and revisit this part later on.
102
103 media::VideoCaptureParams params;
104 params.requested_format.frame_size = options->capture_size.To<gfx::Size>();
105 params.requested_format.frame_rate = options->frame_rate;
106 params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
107
108 mojom::VideoCaptureStreamPtr stream_ptr;
109 scoped_ptr<StreamImpl> stream = make_scoped_ptr(new StreamImpl(
110 mojo::GetProxy(&stream_ptr), base::Bind(&VideoCaptureHandlerImpl::OnStart,
111 weak_factory_.GetWeakPtr(), id),
112 base::Bind(&VideoCaptureHandlerImpl::OnStopOrError,
113 weak_factory_.GetWeakPtr(), id),
114 base::Bind(&VideoCaptureHandlerImpl::OnStopOrError,
115 weak_factory_.GetWeakPtr(), id)));
116
117 // Create the found device and Start() with the chosen VideoCaptureParameters.
118 scoped_ptr<media::VideoCaptureDevice> video_capture_device =
119 video_capture_device_factory_->Create(*name);
perkj_chrome 2016/03/07 23:58:27 So this means there can only be one VideoCaptureSt
mcasas 2016/03/08 23:57:29 This mirrors the current cardinality: every VCDevi
120 if (!video_capture_device) {
121 DLOG(ERROR) << "device " << id << " could not be created.";
122 callback.Run(nullptr);
123 return;
124 }
125
126 // Create a VideoCaptureDeviceClientImpl using |stream_| as Delegate.
127 scoped_ptr<media::VideoCaptureDevice::Client> device_client(
128 new VideoCaptureDeviceClientImpl(stream.get()));
129 video_capture_device->AllocateAndStart(params, std::move(device_client));
130
131 device_and_streams_.insert(make_pair(
132 id, make_pair(std::move(video_capture_device), std::move(stream))));
133
134 callback.Run(std::move(stream_ptr));
135 }
136
137 void VideoCaptureHandlerImpl::OnDevicesChanged(
138 base::SystemMonitor::DeviceType device_type) {
139 DVLOG(1) << __FUNCTION__;
140 DCHECK(thread_checker_.CalledOnValidThread());
141
142 // NOTE: This method is only called in response to physical audio/video device
143 // changes (from the operating system).
144
145 if (device_type != base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE)
146 return; // Uninteresting device change.
147
148 TRACE_EVENT_ASYNC_BEGIN0("video_capture", "EnumerateDeviceNames",
149 this /* id */);
150 // Always do enumeration even though some enumeration is in progress, because
151 // those enumeration commands could be sent before these devices change.
152 video_capture_device_factory_->EnumerateDeviceNames(
153 base::Bind(&VideoCaptureHandlerImpl::OnVideoCaptureDevicesEnumerated,
154 weak_factory_.GetWeakPtr()));
155 }
156
157 void VideoCaptureHandlerImpl::OnVideoCaptureDevicesEnumerated(
158 scoped_ptr<media::VideoCaptureDevice::Names> device_names) {
159 DCHECK(thread_checker_.CalledOnValidThread());
160 TRACE_EVENT_ASYNC_END0("video_capture", "EnumerateDeviceNames", this);
161 device_names_ = std::move(device_names);
162
163 #if !defined(NDEBUG)
164 for (const auto& device_name : *device_names_) {
165 DVLOG(1) << "device: id: " << device_name.id()
166 << ", name: " << device_name.GetNameAndModel()
167 << ", api: " << device_name.GetCaptureApiTypeString();
168 }
169 #endif
170 }
171
172 void VideoCaptureHandlerImpl::OnStart(const std::string& id) {
173 DVLOG(1) << __FUNCTION__ << " " << id;
174 DCHECK(thread_checker_.CalledOnValidThread());
175 // TODO(mcasas): update some tracking saying that |id| is started ?
176 }
177
178 void VideoCaptureHandlerImpl::OnStopOrError(const std::string& id) {
179 DCHECK(thread_checker_.CalledOnValidThread());
180 const auto& entry = device_and_streams_.find(id);
181 DLOG_IF(ERROR, entry == device_and_streams_.end()) << "Device id " << id
182 << " not found!";
183 if (entry == device_and_streams_.end())
184 return;
185 entry->second.first->StopAndDeAllocate();
186 device_and_streams_.erase(entry);
187 }
188
189 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698