Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MediaControl: Fix privacy mode for upstream IVSC #112

Merged
merged 1 commit into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/core/CameraDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,11 @@ int CameraDevice::init() {

// PRIVACY_MODE_S
if (PlatformData::getSupportPrivacy(mCameraId) == CVF_BASED_PRIVACY_MODE) {
ret = mCvfPrivacyChecker->init();
CheckAndLogError((ret != OK), ret, "%s: Init privacy checker falied", __func__);
mCvfPrivacyChecker->run("CvfPrivacyChecker", PRIORITY_NORMAL);
if (OK == mCvfPrivacyChecker->init()) {
mCvfPrivacyChecker->run("CvfPrivacyChecker", PRIORITY_NORMAL);
} else {
LOGW("%s: Init privacy checker not initialized", __func__);
}
}
// PRIVACY_MODE_E

Expand Down
33 changes: 22 additions & 11 deletions src/core/CvfPrivacyChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "iutils/CameraLog.h"
#include "iutils/Errors.h"
#include "iutils/Thread.h"
#include "MediaControl.h"
#include "PlatformData.h"
#include "V4l2DeviceFactory.h"

Expand Down Expand Up @@ -55,16 +56,26 @@ CvfPrivacyChecker::~CvfPrivacyChecker() {
}

int CvfPrivacyChecker::init() {
MediaControl* mc = MediaControl::getInstance();
std::string subDevName;
int ret = PlatformData::getDevNameByType(mCameraId, VIDEO_PIXEL_ARRAY, subDevName);
if (ret == OK) {
LOG1("%s: ArraySubdev camera id:%d dev name:%s", __func__, mCameraId, subDevName.c_str());
mPixelArraySubdev = V4l2DeviceFactory::getSubDev(mCameraId, subDevName);
} else {
LOG1("%s: Can't get pixel array subdevice. camera id:%d, return: %d", __func__, mCameraId,
ret);
int privacy = -1;
int ret = mc->getPrivacyDeviceName(&subDevName);

if (ret != OK) {
// Try to get sensor as privacy device
ret = PlatformData::getDevNameByType(mCameraId, VIDEO_PIXEL_ARRAY, subDevName);
CheckAndLogError(ret != OK, ret, "<id%d>%s: Can't get privacy subdev (%d)", mCameraId,
__func__, ret);
}
return ret;
mPixelArraySubdev = V4l2DeviceFactory::getSubDev(mCameraId, subDevName);

ret = mPixelArraySubdev->GetControl(V4L2_CID_PRIVACY, &privacy);
CheckAndLogError(ret != OK, ret, "<id%d>%s: get %s V4L2_CID_PRIVACY failed (%d)", mCameraId,
__func__, subDevName.c_str(), ret);
LOG1("<id%d>%s: privacy subdev: %s status %d", mCameraId, __func__,
mPixelArraySubdev->Name().c_str(), privacy);

return OK;
}

void CvfPrivacyChecker::handleEvent(EventData eventData) {
Expand Down Expand Up @@ -111,12 +122,12 @@ bool CvfPrivacyChecker::threadLoop() {

if (privacy && !mPrivacyOn) {
for (int i = 0; i < MAX_STREAM_NUMBER; ++i) {
LOGI("%s: mCameraStreams[%d] == %p", __func__, i, mCameraStreams[i]);
LOG2("%s: mCameraStreams[%d] == %p", __func__, i, mCameraStreams[i]);
if (mCameraStreams[i]) {
auto buf = mCameraStreams[i]->getPrivacyBuffer();
auto port = mCameraStreams[i]->getPort();
if (buf == nullptr) {
LOGI("%s: getPrivacyBuffer returned nullptr", __func__);
LOG2("%s: getPrivacyBuffer returned nullptr", __func__);
return true;
}
setPrivacyImage(buf);
Expand All @@ -136,7 +147,7 @@ bool CvfPrivacyChecker::checkPrivacyStatus() {
}
int privacy = -1;
int status = mPixelArraySubdev->GetControl(V4L2_CID_PRIVACY, &privacy);
CheckAndLogError(status != OK, status, "Couldn't get V4L2_CID_PRIVACY, status:%d", status);
CheckWarningNoReturn(status != OK, "Couldn't get V4L2_CID_PRIVACY, status:%d", status);
return (privacy == 1);
}

Expand Down
63 changes: 46 additions & 17 deletions src/v4l2/MediaControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,15 +875,19 @@ int MediaControl::mediaCtlSetup(int cameraId, MediaCtlConf* mc, int width, int h
if (ivsc->links[i].sink->entity == ivsc) {
MediaEntity* sensor = ivsc->links[i].source->entity;
int sensor_entity_id = sensor->info.id;
LOG1("@%s, found %s -> %s", __func__,
sensor->info.name, ivscName.c_str());
LOG1("@%s, found %s -> %s", __func__, sensor->info.name, ivscName.c_str());
for (McLink& link : mc->links) {
if (link.srcEntity == sensor_entity_id) {
LOG1("@%s, skip %s, link %s -> %s",
__func__, link.srcEntityName.c_str(),
LOG1("@%s, skip %s, link %s -> %s", __func__, link.srcEntityName.c_str(),
ivscName.c_str(), link.sinkEntityName.c_str());
link.srcEntity = ivsc->info.id;
link.srcEntityName = ivscName;
for (uint32_t j = 0; j < ivsc->info.pads; ++j) {
if (ivsc->pads[j].flags & MEDIA_PAD_FL_SOURCE) {
link.srcPad = j;
break;
}
}
break;
}
}
Expand Down Expand Up @@ -949,26 +953,51 @@ int MediaControl::getLensName(string* lensName) {
return UNKNOWN_ERROR;
}

// PRIVACY_MODE_S
int MediaControl::getPrivacyDeviceName(std::string* name) {
CheckAndLogError(!name, UNKNOWN_ERROR, "nullptr input");
MediaEntity* ivsc = getEntityByName(ivscName.c_str());

if (!ivsc) {
return BAD_VALUE;
}
name->assign(ivsc->devname);
return OK;
}
// PRIVACY_MODE_E

bool MediaControl::checkHasSource(const MediaEntity* sink, const std::string& source) {
for (unsigned int i = 0; i < sink->numLinks; ++i) {
if (sink->links[i].sink->entity == sink) {
// links[i] is the link to sink entity
// pre is the link's source entity
MediaEntity* pre = sink->links[i].source->entity;
if (pre->info.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR) {
// if pre is sensor, return compare name result
if (strncmp(source.c_str(), pre->info.name, source.length()) == 0) return true;
} else {
// if pre is not sensor, search recursively
if (checkHasSource(pre, source)) return true;
}
}
}

return false;
}

// This function must be called after enumEntities().
bool MediaControl::checkAvailableSensor(const std::string& sensorEntityName,
const std::string& sinkEntityName) {
LOG1("@%s, sensorEntityName:%s, sinkEntityName:%s", __func__, sensorEntityName.c_str(),
sinkEntityName.c_str());

std::string sensorEntityNameTmp = sensorEntityName;
sensorEntityNameTmp.append(" ");
size_t nameLen = sensorEntityNameTmp.length();
// Check if any sensor starts with sensorEntityName connects to
// sinkEntityName, which is IPU CSI port
std::string sensorEntityNameTmp = sensorEntityName + " ";
for (auto& entity : mEntities) {
int linksCount = entity.info.links;
MediaLink* links = entity.links;
for (int i = 0; i < linksCount; i++) {
if (strcmp(links[i].sink->entity->info.name, sinkEntityName.c_str()) == 0 ||
strcmp(links[i].sink->entity->info.name, ivscName.c_str()) == 0) {
char* entityName = entity.info.name;
if (strncmp(entityName, sensorEntityNameTmp.c_str(), nameLen) == 0) {
return true;
}
}
if (strcmp(sinkEntityName.c_str(), entity.info.name) == 0) {
// Got the correct IPU CSI port, check its source
return checkHasSource(&entity, sensorEntityNameTmp);
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/v4l2/MediaControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,17 @@ class MediaControl {
*/
int getVCMI2CAddr(const char* vcmName, std::string* vcmI2CAddr);

// PRIVACY_MODE_S
/**
* \brief Get privacy control device name
*
* \param [out]name: the device name which has privacy control
*
* \return 0 if succeed or error value if error
*/
int getPrivacyDeviceName(std::string* name);
// PRIVACY_MODE_E

/**
* \brief Set up media controller pipe
*
Expand Down Expand Up @@ -306,6 +317,7 @@ class MediaControl {
int getDevnameFromSysfs(MediaEntity* entity);
MediaEntity* getEntityById(uint32_t id);
MediaEntity* getEntityByName(const char* name);
bool checkHasSource(const MediaEntity* sink, const std::string& source);

// set up entity link.

Expand Down