Commit c3a04a2f authored by Daniel Fenner's avatar Daniel Fenner Committed by Commit Bot

Expand webcam_private api such that we can control auto focus setting ('on' or...

Expand webcam_private api such that we can control auto focus setting ('on' or 'off') and the focus value. The focus value can be read back with the get command. Implemented for Visca and UVC cameras.

Bug: 888475
Change-Id: I41ac7c75e4e0893d085b7b1599ead7ffba7b5d26
Reviewed-on: https://chromium-review.googlesource.com/1240281Reviewed-by: default avatarZachary Kuznia <zork@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Commit-Queue: Daniel Fenner <dfenner@google.com>
Cr-Commit-Position: refs/heads/master@{#594672}
parent 712b3456
......@@ -163,6 +163,15 @@ void V4L2Webcam::GetZoom(const GetPTZCompleteCallback& callback) {
callback.Run(success, value, min_value, max_value);
}
void V4L2Webcam::GetFocus(const GetPTZCompleteCallback& callback) {
int value = 0;
int min_value = 0;
int max_value = 0;
bool success = GetWebcamParameter(fd_.get(), V4L2_CID_FOCUS_ABSOLUTE, &value,
&min_value, &max_value);
callback.Run(success, value, min_value, max_value);
}
void V4L2Webcam::SetPan(int value,
int pan_speed,
const SetPTZCompleteCallback& callback) {
......@@ -179,6 +188,16 @@ void V4L2Webcam::SetZoom(int value, const SetPTZCompleteCallback& callback) {
callback.Run(SetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, value));
}
void V4L2Webcam::SetFocus(int value, const SetPTZCompleteCallback& callback) {
callback.Run(SetWebcamParameter(fd_.get(), V4L2_CID_FOCUS_ABSOLUTE, value));
}
void V4L2Webcam::SetAutofocusState(AutofocusState state,
const SetPTZCompleteCallback& callback) {
const int value = (state == AUTOFOCUS_ON) ? 1 : 0;
callback.Run(SetWebcamParameter(fd_.get(), V4L2_CID_FOCUS_AUTO, value));
}
void V4L2Webcam::SetPanDirection(PanDirection direction,
int pan_speed,
const SetPTZCompleteCallback& callback) {
......
......@@ -33,6 +33,7 @@ class V4L2Webcam : public Webcam {
void GetPan(const GetPTZCompleteCallback& callback) override;
void GetTilt(const GetPTZCompleteCallback& callback) override;
void GetZoom(const GetPTZCompleteCallback& callback) override;
void GetFocus(const GetPTZCompleteCallback& callback) override;
void SetPan(int value,
int pan_speed,
const SetPTZCompleteCallback& callback) override;
......@@ -50,6 +51,9 @@ class V4L2Webcam : public Webcam {
bool tilt,
bool zoom,
const SetPTZCompleteCallback& callback) override;
void SetFocus(int value, const SetPTZCompleteCallback& callback) override;
void SetAutofocusState(AutofocusState state,
const SetPTZCompleteCallback& callback) override;
const std::string device_id_;
base::ScopedFD fd_;
......
......@@ -76,6 +76,24 @@ const char kGetZoomCommand[] = {0x81, 0x09, 0x04, 0x47, 0xFF};
const char kSetZoomCommand[] = {0x81, 0x01, 0x04, 0x47, 0x00,
0x00, 0x00, 0x00, 0xFF};
// Command: {0x8X, 0x01, 0x04, 0x38, 0x02, 0xFF}, X = 1 to 7: target device
// address.
const char kSetAutoFocusCommand[] = {0x81, 0x01, 0x04, 0x38, 0x02, 0xFF};
// Command: {0x8X, 0x01, 0x04, 0x38, 0x03, 0xFF}, X = 1 to 7: target device
// address.
const char kSetManualFocusCommand[] = {0x81, 0x01, 0x04, 0x38, 0x03, 0xFF};
// Command: {0x8X, 0x09, 0x04, 0x48, 0xFF}, X = 1 to 7: target device address.
// Response: {0xY0, 0x50, 0x0p, 0x0q, 0x0r, 0x0s, 0xFF}, Y = socket number;
// pqrs: focus position.
const char kGetFocusCommand[] = {0x81, 0x09, 0x04, 0x48, 0xFF};
// Command: {0x8X, 0x01, 0x04, 0x48, 0x0p, 0x0q, 0x0r, 0x0s, 0xFF}, X = 1 to 7:
// target device address; pqrs: focus position;
const char kSetFocusCommand[] = {0x81, 0x01, 0x04, 0x48, 0x00,
0x00, 0x00, 0x00, 0xFF};
// Command: {0x8X, 0x01, 0x06, 0x01, 0x0p, 0x0t, 0x03, 0x01, 0xFF}, X = 1 to 7:
// target device address; p: pan speed; t: tilt speed.
const char kPTUpCommand[] = {0x81, 0x01, 0x06, 0x01, 0x00,
......@@ -350,6 +368,9 @@ void ViscaWebcam::OnInquiryCompleted(InquiryType type,
case INQUIRY_ZOOM:
is_valid_response = CanBuildResponseInt(response, 2);
break;
case INQUIRY_FOCUS:
is_valid_response = CanBuildResponseInt(response, 2);
break;
}
if (!is_valid_response) {
callback.Run(false, 0 /* value */, 0 /* min_value */, 0 /* max_value */);
......@@ -373,6 +394,10 @@ void ViscaWebcam::OnInquiryCompleted(InquiryType type,
// See kGetZoomCommand for the format of response.
value = BuildResponseInt(response, 2);
break;
case INQUIRY_FOCUS:
// See kGetFocusCommand for the format of response.
value = BuildResponseInt(response, 2);
break;
}
// TODO(pbos): Add support for valid ranges.
callback.Run(true, value, 0, 0);
......@@ -418,6 +443,12 @@ void ViscaWebcam::GetZoom(const GetPTZCompleteCallback& callback) {
weak_ptr_factory_.GetWeakPtr(), INQUIRY_ZOOM, callback));
}
void ViscaWebcam::GetFocus(const GetPTZCompleteCallback& callback) {
Send(CHAR_VECTOR_FROM_ARRAY(kGetFocusCommand),
base::Bind(&ViscaWebcam::OnInquiryCompleted,
weak_ptr_factory_.GetWeakPtr(), INQUIRY_FOCUS, callback));
}
void ViscaWebcam::SetPan(int value,
int pan_speed,
const SetPTZCompleteCallback& callback) {
......@@ -458,6 +489,26 @@ void ViscaWebcam::SetZoom(int value, const SetPTZCompleteCallback& callback) {
weak_ptr_factory_.GetWeakPtr(), callback));
}
void ViscaWebcam::SetFocus(int value, const SetPTZCompleteCallback& callback) {
int actual_value = std::max(value, 0);
std::vector<char> command = CHAR_VECTOR_FROM_ARRAY(kSetFocusCommand);
ResponseToCommand(&command, 4, actual_value);
Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted,
weak_ptr_factory_.GetWeakPtr(), callback));
}
void ViscaWebcam::SetAutofocusState(AutofocusState state,
const SetPTZCompleteCallback& callback) {
std::vector<char> command;
if (state == AUTOFOCUS_ON) {
command = CHAR_VECTOR_FROM_ARRAY(kSetAutoFocusCommand);
} else {
command = CHAR_VECTOR_FROM_ARRAY(kSetManualFocusCommand);
}
Send(command, base::Bind(&ViscaWebcam::OnCommandCompleted,
weak_ptr_factory_.GetWeakPtr(), callback));
}
void ViscaWebcam::SetPanDirection(PanDirection direction,
int pan_speed,
const SetPTZCompleteCallback& callback) {
......
......@@ -37,6 +37,7 @@ class ViscaWebcam : public Webcam {
INQUIRY_PAN,
INQUIRY_TILT,
INQUIRY_ZOOM,
INQUIRY_FOCUS,
};
using CommandCompleteCallback =
......@@ -98,6 +99,7 @@ class ViscaWebcam : public Webcam {
void GetPan(const GetPTZCompleteCallback& callback) override;
void GetTilt(const GetPTZCompleteCallback& callback) override;
void GetZoom(const GetPTZCompleteCallback& callback) override;
void GetFocus(const GetPTZCompleteCallback& callback) override;
void SetPan(int value,
int pan_speed,
const SetPTZCompleteCallback& callback) override;
......@@ -115,6 +117,9 @@ class ViscaWebcam : public Webcam {
bool tilt,
bool zoom,
const SetPTZCompleteCallback& callback) override;
void SetFocus(int value, const SetPTZCompleteCallback& callback) override;
void SetAutofocusState(AutofocusState state,
const SetPTZCompleteCallback& callback) override;
// Used only in unit tests in place of Open().
void OpenForTesting(std::unique_ptr<SerialConnection> serial_connection);
......
......@@ -29,6 +29,11 @@ class Webcam : public base::RefCounted<Webcam> {
TILT_STOP,
};
enum AutofocusState {
AUTOFOCUS_ON,
AUTOFOCUS_OFF,
};
Webcam();
using GetPTZCompleteCallback = base::Callback<
......@@ -38,6 +43,7 @@ class Webcam : public base::RefCounted<Webcam> {
virtual void GetPan(const GetPTZCompleteCallback& callback) = 0;
virtual void GetTilt(const GetPTZCompleteCallback& callback) = 0;
virtual void GetZoom(const GetPTZCompleteCallback& callback) = 0;
virtual void GetFocus(const GetPTZCompleteCallback& callback) = 0;
virtual void SetPan(int value,
int pan_speed,
const SetPTZCompleteCallback& callback) = 0;
......@@ -51,6 +57,9 @@ class Webcam : public base::RefCounted<Webcam> {
virtual void SetTiltDirection(TiltDirection direction,
int tilt_speed,
const SetPTZCompleteCallback& callback) = 0;
virtual void SetFocus(int value, const SetPTZCompleteCallback& callback) = 0;
virtual void SetAutofocusState(AutofocusState state,
const SetPTZCompleteCallback& callback) = 0;
virtual void Reset(bool pan,
bool tilt,
bool zoom,
......
......@@ -150,6 +150,12 @@ class WebcamPrivateGetFunction : public UIThreadExtensionFunction {
INQUIRY_PAN,
INQUIRY_TILT,
INQUIRY_ZOOM,
INQUIRY_FOCUS,
};
enum AutofocusState {
AUTOFOCUSSTATE_ON,
AUTOFOCUSSTATE_OFF,
};
void OnGetWebcamParameters(InquiryType type,
......@@ -167,9 +173,13 @@ class WebcamPrivateGetFunction : public UIThreadExtensionFunction {
int min_zoom_;
int max_zoom_;
int zoom_;
int min_focus_;
int max_focus_;
int focus_;
bool get_pan_;
bool get_tilt_;
bool get_zoom_;
bool get_focus_;
bool success_;
DISALLOW_COPY_AND_ASSIGN(WebcamPrivateGetFunction);
......
......@@ -313,6 +313,31 @@ ExtensionFunction::ResponseAction WebcamPrivateSetFunction::Run() {
base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
}
if (params->config.autofocus_state) {
Webcam::AutofocusState state = Webcam::AUTOFOCUS_ON;
switch (params->config.autofocus_state) {
case webcam_private::AUTOFOCUS_STATE_NONE:
case webcam_private::AUTOFOCUS_STATE_OFF:
state = Webcam::AUTOFOCUS_OFF;
break;
case webcam_private::AUTOFOCUS_STATE_ON:
state = Webcam::AUTOFOCUS_ON;
break;
}
++pending_num_set_webcam_param_requests_;
webcam->SetAutofocusState(
state,
base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
}
if (params->config.focus) {
++pending_num_set_webcam_param_requests_;
webcam->SetFocus(
*(params->config.focus),
base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
}
if (pending_num_set_webcam_param_requests_ == 0)
return AlreadyResponded();
......@@ -338,9 +363,13 @@ WebcamPrivateGetFunction::WebcamPrivateGetFunction()
min_zoom_(0),
max_zoom_(0),
zoom_(0),
min_focus_(0),
max_focus_(0),
focus_(0),
get_pan_(false),
get_tilt_(false),
get_zoom_(false),
get_focus_(false),
success_(true) {}
WebcamPrivateGetFunction::~WebcamPrivateGetFunction() {
......@@ -362,6 +391,8 @@ ExtensionFunction::ResponseAction WebcamPrivateGetFunction::Run() {
this, INQUIRY_TILT));
webcam->GetZoom(base::Bind(&WebcamPrivateGetFunction::OnGetWebcamParameters,
this, INQUIRY_ZOOM));
webcam->GetFocus(base::Bind(&WebcamPrivateGetFunction::OnGetWebcamParameters,
this, INQUIRY_FOCUS));
// We might have already responded through OnGetWebcamParameters().
return did_respond() ? AlreadyResponded() : RespondLater();
......@@ -398,8 +429,14 @@ void WebcamPrivateGetFunction::OnGetWebcamParameters(InquiryType type,
zoom_ = value;
get_zoom_ = true;
break;
case INQUIRY_FOCUS:
min_focus_ = min_value;
max_focus_ = max_value;
focus_ = value;
get_focus_ = true;
break;
}
if (get_pan_ && get_tilt_ && get_zoom_) {
if (get_pan_ && get_tilt_ && get_zoom_ && get_focus_) {
webcam_private::WebcamCurrentConfiguration result;
if (min_pan_ != max_pan_) {
result.pan_range = std::make_unique<webcam_private::Range>();
......@@ -416,10 +453,16 @@ void WebcamPrivateGetFunction::OnGetWebcamParameters(InquiryType type,
result.zoom_range->min = min_zoom_;
result.zoom_range->max = max_zoom_;
}
if (min_focus_ != max_focus_) {
result.focus_range = std::make_unique<webcam_private::Range>();
result.focus_range->min = min_focus_;
result.focus_range->max = max_focus_;
}
result.pan = pan_;
result.tilt = tilt_;
result.zoom = zoom_;
result.focus = focus_;
Respond(OneArgument(result.ToValue()));
}
}
......
......@@ -7,6 +7,7 @@ namespace webcamPrivate {
enum PanDirection { stop, right, left };
enum TiltDirection { stop, up, down };
enum Protocol { visca };
enum AutofocusState { on, off };
dictionary ProtocolConfiguration {
Protocol? protocol;
......@@ -20,6 +21,8 @@ namespace webcamPrivate {
double? tiltSpeed;
TiltDirection? tiltDirection;
double? zoom;
AutofocusState? autofocusState;
double? focus;
};
dictionary Range { double min; double max; };
......@@ -28,11 +31,13 @@ namespace webcamPrivate {
double pan;
double tilt;
double zoom;
double focus;
// Supported range of pan, tilt and zoom values.
Range? panRange;
Range? tiltRange;
Range? zoomRange;
Range? focusRange;
};
callback WebcamIdCallback = void(DOMString webcamId);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment