Theoretical assert when filtering resolutions on RkISP

Quentin Schulz quentin.schulz at cherry.de
Fri Apr 4 11:33:01 CEST 2025


Hi all,

Looking at the code that triggered an assert when running an "old" 
kernel (5.10 for me but should happen until 6.4) on a Rockchip board 
(PX30 based)[1] I think I've identified another way to trigger that 
assert (on recent kernels).

I'm not sure it's reasonable to expect it to happen and I for sure do 
not know what to do, safely.

So here goes nothing:

https://git.libcamera.org/libcamera/libcamera.git/tree/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp#n139

"""
Size RkISP1Path::filterSensorResolution(const CameraSensor *sensor)
{
	auto iter = sensorSizesMap_.find(sensor);
	if (iter != sensorSizesMap_.end())
		return iter->second.back();

	std::vector<Size> &sizes = sensorSizesMap_[sensor];
	for (unsigned int code : sensor->mbusCodes()) {
		for (const Size &size : sensor->sizes(code)) {
			if (size.width > maxResolution_.width ||
			    size.height > maxResolution_.height)
				continue;

			sizes.push_back(size);
		}
	}

	/* Sort in increasing order and remove duplicates. */
	std::sort(sizes.begin(), sizes.end());
	auto last = std::unique(sizes.begin(), sizes.end());
	sizes.erase(last, sizes.end());

	return sizes.back();
}
"""

sensorSizesmap_ is an std::map<const CameraSensor *, std::vector<Size>>.

On first call to this function for sensor X, the first part till the 
for-loop is "skipped" because the sensor isn't present in the map. Then with

sensorSizesMap_[sensor];

it creates a new entry in the map, c.f. 
https://en.cppreference.com/w/cpp/container/map/operator_at

"""
Returns a reference to the value that is mapped to a key equivalent to 
key or x respectively, performing an insertion if such key does not 
already exist.
"""

So now we have a new entry in the map but without anything in 
map->second (or rather an empty std::vector).

Then we filter the sensor resolutions based on the min and max 
resolutions supported by the pipeline. However, it could (at least 
theoretically) be possible to have no possible subset of sensor 
resolution for the pipeline, in which case sizes vector is empty.

I have no clue if that would trigger an issue in the three lines after 
the end of the for loop but it'll for sure trigger an assert in the 
return statement as sizes.back() will assert on !this->empty() that I 
got in [2].

[1] 
https://lists.libcamera.org/pipermail/libcamera-devel/2025-April/049691.html
[2] 
https://lists.libcamera.org/pipermail/libcamera-devel/2025-April/049699.html

An option to not trigger the assert (here) would be to remove the sensor 
from the map if no compatible resolution is found, and then return.... 
what exactly? It seems callers of filterSensorResolution() always expect 
a resolution to be found. Maybe 0 for maxResolution and (unsigned int)-1 
for minResolution? Not sure if the rest of the code is able to handle 
that though. We could also simply insert the same dummy max and min 
resolutions for the sensor instead of removing the sensor from the map 
(same outcome, but we then avoid running through the forloop every time 
someone asks to filter the resolutions for that sensor.

Cheers,
Quentin


More information about the libcamera-devel mailing list