mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Add methods to get or set camera parameters
This change adds new methods to set and get camera parameters. As the vendor may handle a parameter set request with invalid value, a set method returns an effective value with a status code. Bug: 138328396 Test: VTS Change-Id: I278dad6c285fb9b341be3517cde09359da14cda6 Signed-off-by: Changyeon Jo <changyeon@google.com>
This commit is contained in:
@@ -54,4 +54,59 @@ interface IEvsCamera extends @1.0::IEvsCamera {
|
||||
* @return result Return EvsResult::OK if this call is successful.
|
||||
*/
|
||||
doneWithFrame_1_1(BufferDesc buffer) generates (EvsResult result);
|
||||
|
||||
/**
|
||||
* Requests to be a master client.
|
||||
*
|
||||
* When multiple clients subscribe to a single camera hardware and one of
|
||||
* them adjusts a camera parameter such as the contrast, it may disturb
|
||||
* other clients' operations. Therefore, the client must call this method
|
||||
* to be a master client. Once it becomes a master, it will be able to
|
||||
* change camera parameters until either it dies or explicitly gives up the
|
||||
* role.
|
||||
*
|
||||
* @return result EvsResult::OK if a master role is granted.
|
||||
* EvsResult::OWNERSHIP_LOST if there is already a
|
||||
* master client.
|
||||
*/
|
||||
setMaster() generates (EvsResult result);
|
||||
|
||||
|
||||
/**
|
||||
* Retires from a master client role.
|
||||
*
|
||||
* @return result EvsResult::OK if this call is successful.
|
||||
* EvsResult::INVALID_ARG if the caller client is not a
|
||||
* master client.
|
||||
*/
|
||||
unsetMaster() generates (EvsResult result);
|
||||
|
||||
/**
|
||||
* Requests to set a camera parameter.
|
||||
*
|
||||
* @param id The identifier of camera parameter, CameraParam enum.
|
||||
* value A desired parameter value.
|
||||
* @return result EvsResult::OK if it succeeds to set a parameter.
|
||||
* EvsResult::INVALID_ARG if either the request is
|
||||
* not made by a master client, or a requested
|
||||
* parameter is not supported.
|
||||
* EvsResult::UNDERLYING_SERVICE_ERROR if it fails to
|
||||
* program a value by any other reason.
|
||||
* effectiveValue A programmed parameter value. This may differ
|
||||
* from what the client gives if, for example, the
|
||||
* driver does not support a target parameter.
|
||||
*/
|
||||
setParameter(CameraParam id, int32_t value)
|
||||
generates (EvsResult result, int32_t effectiveValue);
|
||||
|
||||
/**
|
||||
* Retrieves a value of given camera parameter.
|
||||
*
|
||||
* @param id The identifier of camera parameter, CameraParam enum.
|
||||
* @return result EvsResult::OK if it succeeds to read a parameter.
|
||||
* EvsResult::INVALID_ARG if either a requested parameter is
|
||||
* not supported.
|
||||
* value A value of requested camera parameter.
|
||||
*/
|
||||
getParameter(CameraParam id) generates(EvsResult result, int32_t value);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ package android.hardware.automotive.evs@1.1;
|
||||
import @1.0::IEvsCameraStream;
|
||||
|
||||
/**
|
||||
* Implemented on client side to receive asynchronous video frame deliveries.
|
||||
* Implemented on client side to receive asynchronous streaming event deliveries.
|
||||
*/
|
||||
interface IEvsCameraStream extends @1.0::IEvsCameraStream {
|
||||
/**
|
||||
|
||||
@@ -258,6 +258,38 @@ Return<EvsResult> EvsCamera::resumeVideoStream() {
|
||||
}
|
||||
|
||||
|
||||
Return<EvsResult> EvsCamera::setMaster() {
|
||||
// Default implementation does not expect multiple subscribers and therefore
|
||||
// return a success code always.
|
||||
return EvsResult::OK;
|
||||
}
|
||||
|
||||
|
||||
Return<EvsResult> EvsCamera::unsetMaster() {
|
||||
// Default implementation does not expect multiple subscribers and therefore
|
||||
// return a success code always.
|
||||
return EvsResult::OK;
|
||||
}
|
||||
|
||||
|
||||
Return<void> EvsCamera::setParameter(CameraParam id, int32_t value,
|
||||
setParameter_cb _hidl_cb) {
|
||||
// Default implementation does not support this.
|
||||
(void)id;
|
||||
(void)value;
|
||||
_hidl_cb(EvsResult::INVALID_ARG, 0);
|
||||
return Void();
|
||||
}
|
||||
|
||||
|
||||
Return<void> EvsCamera::getParameter(CameraParam id, getParameter_cb _hidl_cb) {
|
||||
// Default implementation does not support this.
|
||||
(void)id;
|
||||
_hidl_cb(EvsResult::INVALID_ARG, 0);
|
||||
return Void();
|
||||
}
|
||||
|
||||
|
||||
bool EvsCamera::setAvailableFrames_Locked(unsigned bufferCount) {
|
||||
if (bufferCount < 1) {
|
||||
ALOGE("Ignoring request to set buffer count to zero");
|
||||
@@ -468,7 +500,9 @@ void EvsCamera::generateFrames() {
|
||||
|
||||
// If we've been asked to stop, send an event to signal the actual end of stream
|
||||
EvsEvent event;
|
||||
event.info(EvsEventType::STREAM_STOPPED);
|
||||
InfoEventDesc desc = {};
|
||||
desc.aType = InfoEventType::STREAM_STOPPED;
|
||||
event.info(desc);
|
||||
auto result = mStream->notifyEvent(event);
|
||||
if (!result.isOk()) {
|
||||
ALOGE("Error delivering end of stream marker");
|
||||
|
||||
@@ -60,6 +60,11 @@ public:
|
||||
Return<EvsResult> pauseVideoStream() override;
|
||||
Return<EvsResult> resumeVideoStream() override;
|
||||
Return<EvsResult> doneWithFrame_1_1(const BufferDesc_1_1& buffer) override;
|
||||
Return<EvsResult> setMaster() override;
|
||||
Return<EvsResult> unsetMaster() override;
|
||||
Return<void> setParameter(CameraParam id, int32_t value,
|
||||
setParameter_cb _hidl_cb) override;
|
||||
Return<void> getParameter(CameraParam id, getParameter_cb _hidl_cb) override;
|
||||
|
||||
// Implementation details
|
||||
EvsCamera(const char *id);
|
||||
|
||||
@@ -48,9 +48,9 @@ struct BufferDesc {
|
||||
};
|
||||
|
||||
/**
|
||||
* EVS event types
|
||||
* Types of informative streaming events
|
||||
*/
|
||||
enum EvsEventType : uint32_t {
|
||||
enum InfoEventType : uint32_t {
|
||||
/**
|
||||
* Video stream is started
|
||||
*/
|
||||
@@ -67,6 +67,25 @@ enum EvsEventType : uint32_t {
|
||||
* Timeout happens
|
||||
*/
|
||||
TIMEOUT,
|
||||
/**
|
||||
* Camera parameter is changed; payload contains a changed parameter ID and
|
||||
* its value
|
||||
*/
|
||||
PARAMETER_CHANGED,
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure that describes informative events occurred during EVS is streaming
|
||||
*/
|
||||
struct InfoEventDesc {
|
||||
/**
|
||||
* Type of an informative event
|
||||
*/
|
||||
InfoEventType aType;
|
||||
/**
|
||||
* Possible additional information
|
||||
*/
|
||||
uint32_t[4] payload;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -80,5 +99,74 @@ safe_union EvsEvent {
|
||||
/**
|
||||
* General streaming events
|
||||
*/
|
||||
EvsEventType info;
|
||||
InfoEventDesc info;
|
||||
};
|
||||
|
||||
/**
|
||||
* EVS Camera Parameter
|
||||
*/
|
||||
enum CameraParam : uint32_t {
|
||||
/**
|
||||
* The brightness of image frames
|
||||
*/
|
||||
BRIGHTNESS,
|
||||
/**
|
||||
* The contrast of image frames
|
||||
*/
|
||||
CONTRAST,
|
||||
/**
|
||||
* Automatic gain/exposure control
|
||||
*/
|
||||
AUTOGAIN,
|
||||
/**
|
||||
* Gain control
|
||||
*/
|
||||
GAIN,
|
||||
/**
|
||||
* Mirror the image horizontally
|
||||
*/
|
||||
HFLIP,
|
||||
/**
|
||||
* Mirror the image vertically
|
||||
*/
|
||||
VFLIP,
|
||||
/**
|
||||
* Automatic Whitebalance
|
||||
*/
|
||||
AUTO_WHITE_BALANCE,
|
||||
/**
|
||||
* Manual white balance setting as a color temperature in Kelvin.
|
||||
*/
|
||||
WHITE_BALANCE_TEMPERATURE,
|
||||
/**
|
||||
* Image sharpness adjustment
|
||||
*/
|
||||
SHARPNESS,
|
||||
/**
|
||||
* Auto Exposure Control modes; auto, manual, shutter priority, or
|
||||
* aperture priority.
|
||||
*/
|
||||
AUTO_EXPOSURE,
|
||||
/**
|
||||
* Manual exposure time of the camera
|
||||
*/
|
||||
ABSOLUTE_EXPOSURE,
|
||||
/**
|
||||
* When AEC is running in either auto or aperture priority, this parameter
|
||||
* sets whether a frame rate varies.
|
||||
*/
|
||||
AUTO_EXPOSURE_PRIORITY,
|
||||
/**
|
||||
* Set the focal point of the camera to the specified position. This
|
||||
* parameter may not be effective when auto focus is enabled.
|
||||
*/
|
||||
ABSOLUTE_FOCUS,
|
||||
/**
|
||||
* Enables continuous automatic focus adjustments.
|
||||
*/
|
||||
AUTO_FOCUS,
|
||||
/**
|
||||
* Specify the objective lens focal length as an absolute value.
|
||||
*/
|
||||
ABSOLUTE_ZOOM,
|
||||
};
|
||||
|
||||
@@ -79,7 +79,7 @@ void FrameHandler::blockingStopStream() {
|
||||
// Wait until the stream has actually stopped
|
||||
std::unique_lock<std::mutex> lock(mLock);
|
||||
if (mRunning) {
|
||||
mSignal.wait(lock, [this]() { return !mRunning; });
|
||||
mEventSignal.wait(lock, [this]() { return !mRunning; });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,9 @@ bool FrameHandler::isRunning() {
|
||||
void FrameHandler::waitForFrameCount(unsigned frameCount) {
|
||||
// Wait until we've seen at least the requested number of frames (could be more)
|
||||
std::unique_lock<std::mutex> lock(mLock);
|
||||
mSignal.wait(lock, [this, frameCount](){ return mFramesReceived >= frameCount; });
|
||||
mFrameSignal.wait(lock, [this, frameCount](){
|
||||
return mFramesReceived >= frameCount;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -135,16 +137,21 @@ Return<void> FrameHandler::deliverFrame(const BufferDesc_1_0& bufferArg) {
|
||||
|
||||
Return<void> FrameHandler::notifyEvent(const EvsEvent& event) {
|
||||
// Local flag we use to keep track of when the stream is stopping
|
||||
bool timeToStop = false;
|
||||
|
||||
auto type = event.getDiscriminator();
|
||||
if (type == EvsEvent::hidl_discriminator::info) {
|
||||
if (event.info() == EvsEventType::STREAM_STOPPED) {
|
||||
mLock.lock();
|
||||
mLatestEventDesc = event.info();
|
||||
if (mLatestEventDesc.aType == InfoEventType::STREAM_STOPPED) {
|
||||
// Signal that the last frame has been received and the stream is stopped
|
||||
timeToStop = true;
|
||||
mRunning = false;
|
||||
} else if (mLatestEventDesc.aType == InfoEventType::PARAMETER_CHANGED) {
|
||||
ALOGD("Camera parameter 0x%X is changed to 0x%X",
|
||||
mLatestEventDesc.payload[0], mLatestEventDesc.payload[1]);
|
||||
} else {
|
||||
ALOGD("Received an event 0x%X", event.info());
|
||||
ALOGD("Received an event 0x%X", mLatestEventDesc.aType);
|
||||
}
|
||||
mLock.unlock();
|
||||
mEventSignal.notify_all();
|
||||
} else {
|
||||
auto bufDesc = event.buffer();
|
||||
const AHardwareBuffer_Desc* pDesc =
|
||||
@@ -207,21 +214,14 @@ Return<void> FrameHandler::notifyEvent(const EvsEvent& event) {
|
||||
mHeldBuffers.push(bufDesc);
|
||||
}
|
||||
|
||||
mLock.lock();
|
||||
++mFramesReceived;
|
||||
mLock.unlock();
|
||||
mFrameSignal.notify_all();
|
||||
|
||||
ALOGD("Frame handling complete");
|
||||
}
|
||||
|
||||
|
||||
// Update our received frame count and notify anybody who cares that things have changed
|
||||
mLock.lock();
|
||||
if (timeToStop) {
|
||||
mRunning = false;
|
||||
} else {
|
||||
mFramesReceived++;
|
||||
}
|
||||
mLock.unlock();
|
||||
mSignal.notify_all();
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
@@ -338,3 +338,20 @@ void FrameHandler::getFrameDimension(unsigned* width, unsigned* height) {
|
||||
*height = mFrameHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameHandler::waitForEvent(const InfoEventType aTargetEvent,
|
||||
InfoEventDesc &eventDesc) {
|
||||
// Wait until we get an expected parameter change event.
|
||||
std::unique_lock<std::mutex> lock(mLock);
|
||||
mEventSignal.wait(lock, [this, aTargetEvent, &eventDesc](){
|
||||
bool flag = mLatestEventDesc.aType == aTargetEvent;
|
||||
if (flag) {
|
||||
eventDesc.aType = mLatestEventDesc.aType;
|
||||
eventDesc.payload[0] = mLatestEventDesc.payload[0];
|
||||
eventDesc.payload[1] = mLatestEventDesc.payload[1];
|
||||
}
|
||||
|
||||
return flag;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
bool isRunning();
|
||||
|
||||
void waitForFrameCount(unsigned frameCount);
|
||||
void waitForEvent(const InfoEventType aTargetEvent,
|
||||
InfoEventDesc &eventDesc);
|
||||
void getFramesCounters(unsigned* received, unsigned* displayed);
|
||||
void getFrameDimension(unsigned* width, unsigned* height);
|
||||
|
||||
@@ -88,7 +90,8 @@ private:
|
||||
// we need to protect all member variables that may be modified while we're streaming
|
||||
// (ie: those below)
|
||||
std::mutex mLock;
|
||||
std::condition_variable mSignal;
|
||||
std::condition_variable mEventSignal;
|
||||
std::condition_variable mFrameSignal;
|
||||
|
||||
std::queue<BufferDesc_1_1> mHeldBuffers;
|
||||
bool mRunning = false;
|
||||
@@ -96,6 +99,7 @@ private:
|
||||
unsigned mFramesDisplayed = 0; // Simple counter -- rolls over eventually!
|
||||
unsigned mFrameWidth = 0;
|
||||
unsigned mFrameHeight = 0;
|
||||
InfoEventDesc mLatestEventDesc;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ protected:
|
||||
|
||||
sp<IEvsEnumerator> pEnumerator; // Every test needs access to the service
|
||||
std::vector <CameraDesc> cameraInfo; // Empty unless/until loadCameraList() is called
|
||||
bool mIsHwModule; // boolean to tell current module under testing
|
||||
// is HW module implementation.
|
||||
bool mIsHwModule; // boolean to tell current module under testing
|
||||
// is HW module implementation.
|
||||
};
|
||||
|
||||
|
||||
@@ -516,6 +516,317 @@ TEST_F(EvsHidlTest, MultiCameraStream) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CameraParameter:
|
||||
* Verify that a client can adjust a camera parameter.
|
||||
*/
|
||||
TEST_F(EvsHidlTest, CameraParameter) {
|
||||
ALOGI("Starting CameraParameter test");
|
||||
|
||||
// Get the camera list
|
||||
loadCameraList();
|
||||
|
||||
// Test each reported camera
|
||||
for (auto&& cam: cameraInfo) {
|
||||
// Create a camera client
|
||||
sp<IEvsCamera_1_1> pCam =
|
||||
IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId))
|
||||
.withDefault(nullptr);
|
||||
ASSERT_NE(pCam, nullptr);
|
||||
|
||||
// Set up per-client frame receiver objects which will fire up its own thread
|
||||
sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
|
||||
nullptr,
|
||||
FrameHandler::eAutoReturn);
|
||||
ASSERT_NE(frameHandler, nullptr);
|
||||
|
||||
// Start the camera's video stream
|
||||
bool startResult = frameHandler->startStream();
|
||||
ASSERT_TRUE(startResult);
|
||||
|
||||
// Ensure the stream starts
|
||||
frameHandler->waitForFrameCount(1);
|
||||
|
||||
// Try to program few parameters
|
||||
EvsResult result = EvsResult::OK;
|
||||
int32_t val0 = 100;
|
||||
int32_t val1 = 0;
|
||||
|
||||
result = pCam->setMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
|
||||
pCam->setParameter(CameraParam::BRIGHTNESS, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK ||
|
||||
result == EvsResult::INVALID_ARG);
|
||||
|
||||
pCam->getParameter(CameraParam::BRIGHTNESS,
|
||||
[&result, &val1](auto status, auto value) {
|
||||
result = status;
|
||||
if (status == EvsResult::OK) {
|
||||
val1 = value;
|
||||
}
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK ||
|
||||
result == EvsResult::INVALID_ARG);
|
||||
ASSERT_EQ(val0, val1) << "Values are not matched.";
|
||||
|
||||
val0 = 80;
|
||||
val1 = 0;
|
||||
pCam->setParameter(CameraParam::CONTRAST, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK ||
|
||||
result == EvsResult::INVALID_ARG);
|
||||
|
||||
pCam->getParameter(CameraParam::CONTRAST,
|
||||
[&result, &val1](auto status, auto value) {
|
||||
result = status;
|
||||
if (status == EvsResult::OK) {
|
||||
val1 = value;
|
||||
}
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK ||
|
||||
result == EvsResult::INVALID_ARG);
|
||||
ASSERT_EQ(val0, val1) << "Values are not matched.";
|
||||
|
||||
val0 = 300;
|
||||
val1 = 0;
|
||||
pCam->setParameter(CameraParam::ABSOLUTE_ZOOM, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK ||
|
||||
result == EvsResult::INVALID_ARG);
|
||||
|
||||
pCam->getParameter(CameraParam::ABSOLUTE_ZOOM,
|
||||
[&result, &val1](auto status, auto value) {
|
||||
result = status;
|
||||
if (status == EvsResult::OK) {
|
||||
val1 = value;
|
||||
}
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK ||
|
||||
result == EvsResult::INVALID_ARG);
|
||||
ASSERT_EQ(val0, val1) << "Values are not matched.";
|
||||
|
||||
result = pCam->unsetMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
|
||||
// Shutdown another
|
||||
frameHandler->shutdown();
|
||||
|
||||
// Explicitly release the camera
|
||||
pEnumerator->closeCamera(pCam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MultiCameraParameter:
|
||||
* Verify that master and non-master clients behave as expected when they try to adjust
|
||||
* camera parameters.
|
||||
*/
|
||||
TEST_F(EvsHidlTest, MultiCameraParameter) {
|
||||
ALOGI("Starting CameraParameter test");
|
||||
|
||||
if (mIsHwModule) {
|
||||
// This test is not for HW module implementation.
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the camera list
|
||||
loadCameraList();
|
||||
|
||||
// Test each reported camera
|
||||
for (auto&& cam: cameraInfo) {
|
||||
// Create two camera clients.
|
||||
sp<IEvsCamera_1_1> pCamMaster =
|
||||
IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId))
|
||||
.withDefault(nullptr);
|
||||
ASSERT_NE(pCamMaster, nullptr);
|
||||
sp<IEvsCamera_1_1> pCamNonMaster =
|
||||
IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId))
|
||||
.withDefault(nullptr);
|
||||
ASSERT_NE(pCamNonMaster, nullptr);
|
||||
|
||||
// Set up per-client frame receiver objects which will fire up its own thread
|
||||
sp<FrameHandler> frameHandlerMaster =
|
||||
new FrameHandler(pCamMaster, cam,
|
||||
nullptr,
|
||||
FrameHandler::eAutoReturn);
|
||||
ASSERT_NE(frameHandlerMaster, nullptr);
|
||||
sp<FrameHandler> frameHandlerNonMaster =
|
||||
new FrameHandler(pCamNonMaster, cam,
|
||||
nullptr,
|
||||
FrameHandler::eAutoReturn);
|
||||
ASSERT_NE(frameHandlerNonMaster, nullptr);
|
||||
|
||||
// Set one client as the master
|
||||
EvsResult result = pCamMaster->setMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
|
||||
// Try to set another client as the master.
|
||||
result = pCamNonMaster->setMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OWNERSHIP_LOST);
|
||||
|
||||
// Start the camera's video stream via a master client.
|
||||
bool startResult = frameHandlerMaster->startStream();
|
||||
ASSERT_TRUE(startResult);
|
||||
|
||||
// Ensure the stream starts
|
||||
frameHandlerMaster->waitForFrameCount(1);
|
||||
|
||||
// Start the camera's video stream via another client
|
||||
startResult = frameHandlerNonMaster->startStream();
|
||||
ASSERT_TRUE(startResult);
|
||||
|
||||
// Ensure the stream starts
|
||||
frameHandlerNonMaster->waitForFrameCount(1);
|
||||
|
||||
// Try to program CameraParam::BRIGHTNESS
|
||||
int32_t val0 = 100;
|
||||
int32_t val1 = 0;
|
||||
|
||||
pCamMaster->setParameter(CameraParam::BRIGHTNESS, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program
|
||||
result == EvsResult::INVALID_ARG); // Camera parameter is not supported
|
||||
|
||||
// Non-master client expects to receive a parameter change notification
|
||||
// whenever a master client adjusts it.
|
||||
InfoEventDesc aNotification = {};
|
||||
|
||||
pCamMaster->getParameter(CameraParam::BRIGHTNESS,
|
||||
[&result, &val1](auto status, auto value) {
|
||||
result = status;
|
||||
if (status == EvsResult::OK) {
|
||||
val1 = value;
|
||||
}
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program
|
||||
result == EvsResult::INVALID_ARG); // Camera parameter is not supported
|
||||
if (result == EvsResult::OK) {
|
||||
ASSERT_EQ(val0, val1) << "Values are not matched.";
|
||||
|
||||
// Verify a change notification
|
||||
frameHandlerNonMaster->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification);
|
||||
ASSERT_EQ(InfoEventType::PARAMETER_CHANGED,
|
||||
static_cast<InfoEventType>(aNotification.aType));
|
||||
ASSERT_EQ(CameraParam::BRIGHTNESS,
|
||||
static_cast<CameraParam>(aNotification.payload[0]));
|
||||
ASSERT_EQ(val1,
|
||||
static_cast<int32_t>(aNotification.payload[1]));
|
||||
}
|
||||
|
||||
// Try to program CameraParam::CONTRAST
|
||||
val0 = 80;
|
||||
val1 = 0;
|
||||
pCamMaster->setParameter(CameraParam::CONTRAST, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program
|
||||
result == EvsResult::INVALID_ARG); // Camera parameter is not supported
|
||||
|
||||
if (result == EvsResult::OK) {
|
||||
pCamMaster->getParameter(CameraParam::CONTRAST,
|
||||
[&result, &val1](auto status, auto value) {
|
||||
result = status;
|
||||
if (status == EvsResult::OK) {
|
||||
val1 = value;
|
||||
}
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
ASSERT_EQ(val0, val1) << "Values are not matched.";
|
||||
|
||||
|
||||
// Verify a change notification
|
||||
frameHandlerNonMaster->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification);
|
||||
ASSERT_EQ(InfoEventType::PARAMETER_CHANGED,
|
||||
static_cast<InfoEventType>(aNotification.aType));
|
||||
ASSERT_EQ(CameraParam::CONTRAST,
|
||||
static_cast<CameraParam>(aNotification.payload[0]));
|
||||
ASSERT_EQ(val1,
|
||||
static_cast<int32_t>(aNotification.payload[1]));
|
||||
}
|
||||
|
||||
// Try to adjust a parameter via non-master client
|
||||
pCamNonMaster->setParameter(CameraParam::CONTRAST, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::INVALID_ARG);
|
||||
|
||||
// Non-master client attemps to be a master
|
||||
result = pCamNonMaster->setMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OWNERSHIP_LOST);
|
||||
|
||||
// Master client retires from a master role
|
||||
result = pCamMaster->unsetMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
|
||||
// Try to adjust a parameter after being retired
|
||||
pCamMaster->setParameter(CameraParam::BRIGHTNESS, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::INVALID_ARG);
|
||||
|
||||
// Non-master client becomes a master
|
||||
result = pCamNonMaster->setMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
|
||||
// Try to adjust a parameter via new master client
|
||||
pCamNonMaster->setParameter(CameraParam::BRIGHTNESS, val0,
|
||||
[&result, &val1](auto status, auto effectiveValue) {
|
||||
result = status;
|
||||
val1 = effectiveValue;
|
||||
});
|
||||
ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program
|
||||
result == EvsResult::INVALID_ARG); // Camera parameter is not supported
|
||||
|
||||
// Wait a moment
|
||||
sleep(1);
|
||||
|
||||
// Verify a change notification
|
||||
if (result == EvsResult::OK) {
|
||||
frameHandlerMaster->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification);
|
||||
ASSERT_EQ(static_cast<InfoEventType>(aNotification.aType),
|
||||
InfoEventType::PARAMETER_CHANGED);
|
||||
ASSERT_EQ(static_cast<CameraParam>(aNotification.payload[0]),
|
||||
CameraParam::BRIGHTNESS);
|
||||
ASSERT_EQ(val1,
|
||||
static_cast<int32_t>(aNotification.payload[1]));
|
||||
}
|
||||
|
||||
// New master retires from a master role
|
||||
result = pCamNonMaster->unsetMaster();
|
||||
ASSERT_TRUE(result == EvsResult::OK);
|
||||
|
||||
// Shutdown
|
||||
frameHandlerMaster->shutdown();
|
||||
frameHandlerNonMaster->shutdown();
|
||||
|
||||
// Explicitly release the camera
|
||||
pEnumerator->closeCamera(pCamMaster);
|
||||
pEnumerator->closeCamera(pCamNonMaster);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance());
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
Reference in New Issue
Block a user