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

Side by Side Diff: media/video/capture/linux/video_capture_device_linux.cc

Issue 83633008: Reland: Reorganize media::VideoCapture* types (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/video/capture/linux/video_capture_device_linux.h" 5 #include "media/video/capture/linux/video_capture_device_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #if defined(OS_OPENBSD) 9 #if defined(OS_OPENBSD)
10 #include <sys/videoio.h> 10 #include <sys/videoio.h>
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 return; 152 return;
153 int fd; 153 int fd;
154 VideoCaptureCapabilities capture_formats; 154 VideoCaptureCapabilities capture_formats;
155 if ((fd = open(device.id().c_str(), O_RDONLY)) < 0) { 155 if ((fd = open(device.id().c_str(), O_RDONLY)) < 0) {
156 // Failed to open this device. 156 // Failed to open this device.
157 return; 157 return;
158 } 158 }
159 159
160 formats->clear(); 160 formats->clear();
161 161
162 VideoCaptureCapability capture_format; 162 VideoCaptureCapability capture_capability;
163 // Retrieve the caps one by one, first get colorspace, then sizes, then 163 // Retrieve the caps one by one, first get colorspace, then sizes, then
164 // framerates. See http://linuxtv.org/downloads/v4l-dvb-apis for reference. 164 // framerates. See http://linuxtv.org/downloads/v4l-dvb-apis for reference.
165 v4l2_fmtdesc pixel_format = {}; 165 v4l2_fmtdesc pixel_format = {};
166 pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 166 pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
167 while (ioctl(fd, VIDIOC_ENUM_FMT, &pixel_format) == 0) { 167 while (ioctl(fd, VIDIOC_ENUM_FMT, &pixel_format) == 0) {
168 capture_format.color = 168 capture_capability.supported_format.pixel_format =
169 V4l2ColorToVideoCaptureColorFormat((int32)pixel_format.pixelformat); 169 V4l2ColorToVideoCaptureColorFormat((int32)pixel_format.pixelformat);
170 if (capture_format.color == PIXEL_FORMAT_UNKNOWN) continue; 170 if (capture_capability.supported_format.pixel_format ==
171 PIXEL_FORMAT_UNKNOWN) {
172 continue;
173 }
171 174
172 v4l2_frmsizeenum frame_size = {}; 175 v4l2_frmsizeenum frame_size = {};
173 frame_size.pixel_format = pixel_format.pixelformat; 176 frame_size.pixel_format = pixel_format.pixelformat;
174 while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size) == 0) { 177 while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size) == 0) {
175 if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 178 if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
176 capture_format.width = frame_size.discrete.width; 179 capture_capability.supported_format.frame_size.SetSize(
177 capture_format.height = frame_size.discrete.height; 180 frame_size.discrete.width, frame_size.discrete.height);
178 } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 181 } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
179 // TODO(mcasas): see http://crbug.com/249953, support these devices. 182 // TODO(mcasas): see http://crbug.com/249953, support these devices.
180 NOTIMPLEMENTED(); 183 NOTIMPLEMENTED();
181 } else if (frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { 184 } else if (frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
182 // TODO(mcasas): see http://crbug.com/249953, support these devices. 185 // TODO(mcasas): see http://crbug.com/249953, support these devices.
183 NOTIMPLEMENTED(); 186 NOTIMPLEMENTED();
184 } 187 }
185 v4l2_frmivalenum frame_interval = {}; 188 v4l2_frmivalenum frame_interval = {};
186 frame_interval.pixel_format = pixel_format.pixelformat; 189 frame_interval.pixel_format = pixel_format.pixelformat;
187 frame_interval.width = frame_size.discrete.width; 190 frame_interval.width = frame_size.discrete.width;
188 frame_interval.height = frame_size.discrete.height; 191 frame_interval.height = frame_size.discrete.height;
189 while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval) == 0) { 192 while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval) == 0) {
190 if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { 193 if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
191 if (frame_interval.discrete.numerator != 0) { 194 if (frame_interval.discrete.numerator != 0) {
192 capture_format.frame_rate = 195 capture_capability.supported_format.frame_rate =
193 static_cast<float>(frame_interval.discrete.denominator) / 196 static_cast<float>(frame_interval.discrete.denominator) /
194 static_cast<float>(frame_interval.discrete.numerator); 197 static_cast<float>(frame_interval.discrete.numerator);
195 } else { 198 } else {
196 capture_format.frame_rate = 0; 199 capture_capability.supported_format.frame_rate = 0;
197 } 200 }
198 } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) { 201 } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
199 // TODO(mcasas): see http://crbug.com/249953, support these devices. 202 // TODO(mcasas): see http://crbug.com/249953, support these devices.
200 NOTIMPLEMENTED(); 203 NOTIMPLEMENTED();
201 break; 204 break;
202 } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) { 205 } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
203 // TODO(mcasas): see http://crbug.com/249953, support these devices. 206 // TODO(mcasas): see http://crbug.com/249953, support these devices.
204 NOTIMPLEMENTED(); 207 NOTIMPLEMENTED();
205 break; 208 break;
206 } 209 }
207 formats->push_back(capture_format); 210 formats->push_back(capture_capability);
208 ++frame_interval.index; 211 ++frame_interval.index;
209 } 212 }
210 ++frame_size.index; 213 ++frame_size.index;
211 } 214 }
212 ++pixel_format.index; 215 ++pixel_format.index;
213 } 216 }
214 217
215 close(fd); 218 close(fd);
216 return; 219 return;
217 } 220 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 // This means that the device have not been DeAllocated properly. 287 // This means that the device have not been DeAllocated properly.
285 DCHECK(!v4l2_thread_.IsRunning()); 288 DCHECK(!v4l2_thread_.IsRunning());
286 289
287 v4l2_thread_.Stop(); 290 v4l2_thread_.Stop();
288 if (device_fd_ >= 0) { 291 if (device_fd_ >= 0) {
289 close(device_fd_); 292 close(device_fd_);
290 } 293 }
291 } 294 }
292 295
293 void VideoCaptureDeviceLinux::AllocateAndStart( 296 void VideoCaptureDeviceLinux::AllocateAndStart(
294 const VideoCaptureCapability& capture_format, 297 const VideoCaptureParams& params,
295 scoped_ptr<VideoCaptureDevice::Client> client) { 298 scoped_ptr<VideoCaptureDevice::Client> client) {
296 if (v4l2_thread_.IsRunning()) { 299 if (v4l2_thread_.IsRunning()) {
297 return; // Wrong state. 300 return; // Wrong state.
298 } 301 }
299 v4l2_thread_.Start(); 302 v4l2_thread_.Start();
300 v4l2_thread_.message_loop()->PostTask( 303 v4l2_thread_.message_loop()->PostTask(
301 FROM_HERE, 304 FROM_HERE,
302 base::Bind(&VideoCaptureDeviceLinux::OnAllocateAndStart, 305 base::Bind(&VideoCaptureDeviceLinux::OnAllocateAndStart,
303 base::Unretained(this), 306 base::Unretained(this),
304 capture_format.width, 307 params.requested_format.frame_size.width(),
305 capture_format.height, 308 params.requested_format.frame_size.height(),
306 capture_format.frame_rate, 309 params.requested_format.frame_rate,
307 base::Passed(&client))); 310 base::Passed(&client)));
308 } 311 }
309 312
310 void VideoCaptureDeviceLinux::StopAndDeAllocate() { 313 void VideoCaptureDeviceLinux::StopAndDeAllocate() {
311 if (!v4l2_thread_.IsRunning()) { 314 if (!v4l2_thread_.IsRunning()) {
312 return; // Wrong state. 315 return; // Wrong state.
313 } 316 }
314 v4l2_thread_.message_loop()->PostTask( 317 v4l2_thread_.message_loop()->PostTask(
315 FROM_HERE, 318 FROM_HERE,
316 base::Bind(&VideoCaptureDeviceLinux::OnStopAndDeAllocate, 319 base::Bind(&VideoCaptureDeviceLinux::OnStopAndDeAllocate,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 405 }
403 DVLOG(2) << "Actual camera driverframerate: " 406 DVLOG(2) << "Actual camera driverframerate: "
404 << streamparm.parm.capture.timeperframe.denominator << "/" 407 << streamparm.parm.capture.timeperframe.denominator << "/"
405 << streamparm.parm.capture.timeperframe.numerator; 408 << streamparm.parm.capture.timeperframe.numerator;
406 } 409 }
407 } 410 }
408 // TODO(mcasas): what should be done if the camera driver does not allow 411 // TODO(mcasas): what should be done if the camera driver does not allow
409 // framerate configuration, or the actual one is different from the desired? 412 // framerate configuration, or the actual one is different from the desired?
410 413
411 // Store our current width and height. 414 // Store our current width and height.
412 frame_info_.color = 415 capture_format_.frame_size.SetSize(video_fmt.fmt.pix.width,
416 video_fmt.fmt.pix.height);
417 capture_format_.frame_rate = frame_rate;
418 capture_format_.pixel_format =
413 V4l2ColorToVideoCaptureColorFormat(video_fmt.fmt.pix.pixelformat); 419 V4l2ColorToVideoCaptureColorFormat(video_fmt.fmt.pix.pixelformat);
414 frame_info_.width = video_fmt.fmt.pix.width;
415 frame_info_.height = video_fmt.fmt.pix.height;
416 frame_info_.frame_rate = frame_rate;
417 frame_info_.frame_size_type = VariableResolutionVideoCaptureDevice;
418 420
419 // Start capturing. 421 // Start capturing.
420 if (!AllocateVideoBuffers()) { 422 if (!AllocateVideoBuffers()) {
421 // Error, We can not recover. 423 // Error, We can not recover.
422 SetErrorState("Allocate buffer failed"); 424 SetErrorState("Allocate buffer failed");
423 return; 425 return;
424 } 426 }
425 427
426 // Start UVC camera. 428 // Start UVC camera.
427 v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 429 v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 buffer.memory = V4L2_MEMORY_MMAP; 514 buffer.memory = V4L2_MEMORY_MMAP;
513 // Dequeue a buffer. 515 // Dequeue a buffer.
514 if (ioctl(device_fd_, VIDIOC_DQBUF, &buffer) == 0) { 516 if (ioctl(device_fd_, VIDIOC_DQBUF, &buffer) == 0) {
515 client_->OnIncomingCapturedFrame( 517 client_->OnIncomingCapturedFrame(
516 static_cast<uint8*>(buffer_pool_[buffer.index].start), 518 static_cast<uint8*>(buffer_pool_[buffer.index].start),
517 buffer.bytesused, 519 buffer.bytesused,
518 base::Time::Now(), 520 base::Time::Now(),
519 0, 521 0,
520 false, 522 false,
521 false, 523 false,
522 frame_info_); 524 capture_format_);
523 525
524 // Enqueue the buffer again. 526 // Enqueue the buffer again.
525 if (ioctl(device_fd_, VIDIOC_QBUF, &buffer) == -1) { 527 if (ioctl(device_fd_, VIDIOC_QBUF, &buffer) == -1) {
526 SetErrorState(base::StringPrintf( 528 SetErrorState(base::StringPrintf(
527 "Failed to enqueue capture buffer errno %d", errno)); 529 "Failed to enqueue capture buffer errno %d", errno));
528 } 530 }
529 } else { 531 } else {
530 SetErrorState(base::StringPrintf( 532 SetErrorState(base::StringPrintf(
531 "Failed to dequeue capture buffer errno %d", errno)); 533 "Failed to dequeue capture buffer errno %d", errno));
532 return; 534 return;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 613
612 void VideoCaptureDeviceLinux::SetErrorState(const std::string& reason) { 614 void VideoCaptureDeviceLinux::SetErrorState(const std::string& reason) {
613 DCHECK(!v4l2_thread_.IsRunning() || 615 DCHECK(!v4l2_thread_.IsRunning() ||
614 v4l2_thread_.message_loop() == base::MessageLoop::current()); 616 v4l2_thread_.message_loop() == base::MessageLoop::current());
615 DVLOG(1) << reason; 617 DVLOG(1) << reason;
616 state_ = kError; 618 state_ = kError;
617 client_->OnError(); 619 client_->OnError();
618 } 620 }
619 621
620 } // namespace media 622 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/linux/video_capture_device_linux.h ('k') | media/video/capture/mac/video_capture_device_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698