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

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

Issue 2582723002: ImageCapture v4l2: retry reading capabilities (Closed)
Patch Set: Created 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/capture/video/linux/v4l2_capture_delegate.h" 5 #include "media/capture/video/linux/v4l2_capture_delegate.h"
6 6
7 #include <linux/version.h> 7 #include <linux/version.h>
8 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <sys/fcntl.h> 10 #include <sys/fcntl.h>
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 request_buffer->memory = V4L2_MEMORY_MMAP; 115 request_buffer->memory = V4L2_MEMORY_MMAP;
116 request_buffer->count = count; 116 request_buffer->count = count;
117 } 117 }
118 118
119 // Returns the input |fourcc| as a std::string four char representation. 119 // Returns the input |fourcc| as a std::string four char representation.
120 static std::string FourccToString(uint32_t fourcc) { 120 static std::string FourccToString(uint32_t fourcc) {
121 return base::StringPrintf("%c%c%c%c", fourcc & 0xFF, (fourcc >> 8) & 0xFF, 121 return base::StringPrintf("%c%c%c%c", fourcc & 0xFF, (fourcc >> 8) & 0xFF,
122 (fourcc >> 16) & 0xFF, (fourcc >> 24) & 0xFF); 122 (fourcc >> 16) & 0xFF, (fourcc >> 24) & 0xFF);
123 } 123 }
124 124
125 // Creates a mojom::RangePtr with the range of values (min, max, current) of the 125 // Running ioctl() on some devices, especially shortly after (re)opening the
126 // user control associated with |control_id|. Returns an empty Range otherwise. 126 // device file descriptor or (re)starting streaming, can fail but works after
127 // retrying (https://crbug.com/670262).
128 // Returns false if the |request| ioctl fails too many times.
129 static bool RunIoctl(int fd, int request, void* argp) {
130 int num_retries = 0;
131 for (; HANDLE_EINTR(ioctl(fd, request, argp)) < 0 &&
132 num_retries < kMaxIOCtrlRetries;
133 ++num_retries) {
134 DPLOG(WARNING) << "ioctl";
135 }
136 DPLOG_IF(ERROR, num_retries != kMaxIOCtrlRetries);
137 return num_retries != kMaxIOCtrlRetries;
138 }
139
140 // Creates a mojom::RangePtr with the (min, max, current, step) values of the
141 // control associated with |control_id|. Returns an empty Range otherwise.
127 static mojom::RangePtr RetrieveUserControlRange(int device_fd, int control_id) { 142 static mojom::RangePtr RetrieveUserControlRange(int device_fd, int control_id) {
128 mojom::RangePtr capability = mojom::Range::New(); 143 mojom::RangePtr capability = mojom::Range::New();
129 144
130 v4l2_queryctrl range = {}; 145 v4l2_queryctrl range = {};
131 range.id = control_id; 146 range.id = control_id;
132 range.type = V4L2_CTRL_TYPE_INTEGER; 147 range.type = V4L2_CTRL_TYPE_INTEGER;
133 if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_QUERYCTRL, &range)) < 0) 148 if (!RunIoctl(device_fd, VIDIOC_QUERYCTRL, &range))
134 return mojom::Range::New(); 149 return mojom::Range::New();
135 capability->max = range.maximum; 150 capability->max = range.maximum;
136 capability->min = range.minimum; 151 capability->min = range.minimum;
137 capability->step = range.step; 152 capability->step = range.step;
138 153
139 v4l2_control current = {}; 154 v4l2_control current = {};
140 current.id = control_id; 155 current.id = control_id;
141 if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_G_CTRL, &current)) < 0) 156 if (!RunIoctl(device_fd, VIDIOC_G_CTRL, &current))
142 return mojom::Range::New(); 157 return mojom::Range::New();
143 capability->current = current.value; 158 capability->current = current.value;
144 159
145 return capability; 160 return capability;
146 } 161 }
147 162
148 // Determines if |control_id| is special, i.e. controls another one's state. 163 // Determines if |control_id| is special, i.e. controls another one's state.
149 static bool IsSpecialControl(int control_id) { 164 static bool IsSpecialControl(int control_id) {
150 switch (control_id) { 165 switch (control_id) {
151 case V4L2_CID_AUTO_WHITE_BALANCE: 166 case V4L2_CID_AUTO_WHITE_BALANCE:
152 case V4L2_CID_EXPOSURE_AUTO: 167 case V4L2_CID_EXPOSURE_AUTO:
153 case V4L2_CID_EXPOSURE_AUTO_PRIORITY: 168 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
154 case V4L2_CID_FOCUS_AUTO: 169 case V4L2_CID_FOCUS_AUTO:
155 return true; 170 return true;
156 } 171 }
157 return false; 172 return false;
158 } 173 }
159 174
160 // Sets all user control to their default. Some controls are enabled by another 175 // Sets all user control to their default. Some controls are enabled by another
161 // flag, usually having the word "auto" in the name, see IsSpecialControl(). 176 // flag, usually having the word "auto" in the name, see IsSpecialControl().
162 // These flags are preset beforehand, then set to their defaults individually 177 // These flags are preset beforehand, then set to their defaults individually
163 // afterwards. 178 // afterwards.
164 static void ResetUserAndCameraControlsToDefault(int device_fd) { 179 static void ResetUserAndCameraControlsToDefault(int device_fd) {
165 // Set V4L2_CID_AUTO_WHITE_BALANCE to false first. 180 // Set V4L2_CID_AUTO_WHITE_BALANCE to false first.
166 v4l2_control auto_white_balance = {}; 181 v4l2_control auto_white_balance = {};
167 auto_white_balance.id = V4L2_CID_AUTO_WHITE_BALANCE; 182 auto_white_balance.id = V4L2_CID_AUTO_WHITE_BALANCE;
168 auto_white_balance.value = false; 183 auto_white_balance.value = false;
169 int num_retries = 0; 184 if (!RunIoctl(device_fd, VIDIOC_S_CTRL, &auto_white_balance))
170 // Setting up the first control right after stopping streaming seems
171 // not to the work the first time, so retry a few times.
172 for (; num_retries < kMaxIOCtrlRetries &&
173 HANDLE_EINTR(ioctl(device_fd, VIDIOC_S_CTRL, &auto_white_balance)) < 0;
174 ++num_retries) {
175 DPLOG(WARNING) << "VIDIOC_S_CTRL";
176 }
177 if (num_retries == kMaxIOCtrlRetries) {
178 DLOG(ERROR) << "Cannot access device controls";
179 return; 185 return;
180 }
181 186
182 std::vector<struct v4l2_ext_control> special_camera_controls; 187 std::vector<struct v4l2_ext_control> special_camera_controls;
183 // Set V4L2_CID_EXPOSURE_AUTO to V4L2_EXPOSURE_MANUAL. 188 // Set V4L2_CID_EXPOSURE_AUTO to V4L2_EXPOSURE_MANUAL.
184 v4l2_ext_control auto_exposure = {}; 189 v4l2_ext_control auto_exposure = {};
185 auto_exposure.id = V4L2_CID_EXPOSURE_AUTO; 190 auto_exposure.id = V4L2_CID_EXPOSURE_AUTO;
186 auto_exposure.value = V4L2_EXPOSURE_MANUAL; 191 auto_exposure.value = V4L2_EXPOSURE_MANUAL;
187 special_camera_controls.push_back(auto_exposure); 192 special_camera_controls.push_back(auto_exposure);
188 // Set V4L2_CID_EXPOSURE_AUTO_PRIORITY to false. 193 // Set V4L2_CID_EXPOSURE_AUTO_PRIORITY to false.
189 v4l2_ext_control priority_auto_exposure = {}; 194 v4l2_ext_control priority_auto_exposure = {};
190 priority_auto_exposure.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY; 195 priority_auto_exposure.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; 786 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace";
782 return false; 787 return false;
783 } 788 }
784 start_ = static_cast<uint8_t*>(start); 789 start_ = static_cast<uint8_t*>(start);
785 length_ = buffer.length; 790 length_ = buffer.length;
786 payload_size_ = 0; 791 payload_size_ = 0;
787 return true; 792 return true;
788 } 793 }
789 794
790 } // namespace media 795 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698