mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Fix SEGFAULT in V4L2Grabber (#1503)
This commit is contained in:
		| @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||||||
|  |  | ||||||
| ### Fixed | ### Fixed | ||||||
|  |  | ||||||
|  | - V4L2-Grabber: Fixed a SEGFAULT in init() when compiled on Ubuntu Server 22.04 | ||||||
|  |  | ||||||
| ## Removed | ## Removed | ||||||
|  |  | ||||||
| ## [2.0.13](https://github.com/hyperion-project/hyperion.ng/releases/tag/2.0.13) - 2022-05-22 | ## [2.0.13](https://github.com/hyperion-project/hyperion.ng/releases/tag/2.0.13) - 2022-05-22 | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ | |||||||
|  |  | ||||||
| #include <QDirIterator> | #include <QDirIterator> | ||||||
| #include <QFileInfo> | #include <QFileInfo> | ||||||
|  | #include <QSet> | ||||||
|  |  | ||||||
| #include "grabber/V4L2Grabber.h" | #include "grabber/V4L2Grabber.h" | ||||||
|  |  | ||||||
| @@ -161,7 +162,7 @@ bool V4L2Grabber::init() | |||||||
| 			setEncoding(pixelFormatToString(_deviceProperties.value(_currentDevicePath).inputs.value(_input).encodingFormats.firstKey())); | 			setEncoding(pixelFormatToString(_deviceProperties.value(_currentDevicePath).inputs.value(_input).encodingFormats.firstKey())); | ||||||
|  |  | ||||||
| 		bool validDimensions = false; | 		bool validDimensions = false; | ||||||
| 		for (auto enc = _deviceProperties.value(_currentDevicePath).inputs.value(_input).encodingFormats.begin(); enc != _deviceProperties.value(_currentDevicePath).inputs.value(_input).encodingFormats.end(); enc++) | 		for (auto enc = _deviceProperties.value(_currentDevicePath).inputs.value(_input).encodingFormats.constBegin(); enc != _deviceProperties.value(_currentDevicePath).inputs.value(_input).encodingFormats.constEnd(); ++enc) | ||||||
| 			if(enc.key() == _pixelFormat && enc.value().width == _width && enc.value().height == _height) | 			if(enc.key() == _pixelFormat && enc.value().width == _width && enc.value().height == _height) | ||||||
| 			{ | 			{ | ||||||
| 				validDimensions = true; | 				validDimensions = true; | ||||||
| @@ -1257,90 +1258,57 @@ QJsonArray V4L2Grabber::discover(const QJsonObject& params) | |||||||
| 	enumVideoCaptureDevices(); | 	enumVideoCaptureDevices(); | ||||||
|  |  | ||||||
| 	QJsonArray inputsDiscovered; | 	QJsonArray inputsDiscovered; | ||||||
| 	for(auto it = _deviceProperties.begin(); it != _deviceProperties.end(); ++it) | 	for (auto device_property = _deviceProperties.constBegin(); device_property != _deviceProperties.constEnd(); ++device_property) | ||||||
| 	{ | 	{ | ||||||
| 		QJsonObject device, in; | 		QJsonObject device, in; | ||||||
| 		QJsonArray video_inputs, formats; | 		QJsonArray video_inputs, formats; | ||||||
|  |  | ||||||
| 		QMultiMap<QString, int> inputs = QMultiMap<QString, int>(); | 		if (!device_property.value().inputs.isEmpty()) | ||||||
| 		for(auto i = _deviceProperties.begin(); i != _deviceProperties.end(); ++i) |  | ||||||
| 			if (i.key() == it.key()) |  | ||||||
| 				for (auto y = i.value().inputs.begin(); y != i.value().inputs.end(); y++) |  | ||||||
| 					if (!inputs.contains(y.value().inputName, y.key())) |  | ||||||
| 						inputs.insert(y.value().inputName, y.key()); |  | ||||||
|  |  | ||||||
| 		if (!inputs.isEmpty()) |  | ||||||
| 		{ | 		{ | ||||||
| 			device["device"] = it.key(); | 			device["device"] = device_property.key(); | ||||||
| 			device["device_name"] = _deviceProperties.value(it.key()).name; | 			device["device_name"] = device_property.value().name; | ||||||
| 			device["type"] = "v4l2"; | 			device["type"] = "v4l2"; | ||||||
|  |  | ||||||
| 			for (auto input = inputs.begin(); input != inputs.end(); input++) | 			for (auto input = device_property.value().inputs.constBegin(); input != device_property.value().inputs.constEnd(); ++input) | ||||||
| 			{ | 			{ | ||||||
| 				in["name"] = input.key(); | 				in["name"] = input.value().inputName; | ||||||
| 				in["inputIdx"] = input.value(); | 				in["inputIdx"] = input.key(); | ||||||
|  |  | ||||||
| 				QJsonArray standards; | 				QJsonArray standards; | ||||||
| 				QList<VideoStandard> videoStandards = QList<VideoStandard>(); | 				for (auto std = input.value().standards.constBegin(); std != input.value().standards.constEnd(); ++std) | ||||||
| 				for(auto i = _deviceProperties.begin(); i != _deviceProperties.end(); ++i) | 					if(!standards.contains(VideoStandard2String(*std))) | ||||||
| 					if (i.key() == it.key()) | 						standards.append(VideoStandard2String(*std)); | ||||||
| 						for (auto y = i.value().inputs.begin(); y != i.value().inputs.end(); y++) |  | ||||||
| 							if (y.key() == input.value()) |  | ||||||
| 								for (auto std = y.value().standards.begin(); std != y.value().standards.end(); std++) |  | ||||||
| 									if(!videoStandards.contains(*std)) |  | ||||||
| 										videoStandards << *std; |  | ||||||
|  |  | ||||||
| 				for (auto standard : videoStandards) |  | ||||||
| 					standards.append(VideoStandard2String(standard)); |  | ||||||
|  |  | ||||||
| 				if (!standards.isEmpty()) | 				if (!standards.isEmpty()) | ||||||
| 					in["standards"] = standards; | 					in["standards"] = standards; | ||||||
|  |  | ||||||
| 				QList<PixelFormat> encodingFormats = QList<PixelFormat>(); | 				for (auto encodingFormat : input.value().encodingFormats.uniqueKeys()) | ||||||
| 				for(auto i = _deviceProperties.begin(); i != _deviceProperties.end(); ++i) |  | ||||||
| 					if (i.key() == it.key()) |  | ||||||
| 						for (auto y = i.value().inputs.begin(); y != i.value().inputs.end(); y++) |  | ||||||
| 							if (y.key() == input.value()) |  | ||||||
| 								for (auto enc = y.value().encodingFormats.begin(); enc != y.value().encodingFormats.end(); enc++) |  | ||||||
| 									if (!encodingFormats.contains(enc.key())) |  | ||||||
| 										encodingFormats << enc.key(); |  | ||||||
|  |  | ||||||
| 				for (auto encodingFormat : encodingFormats) |  | ||||||
| 				{ | 				{ | ||||||
| 					QJsonObject format; | 					QJsonObject format; | ||||||
| 					QJsonArray resolutionArray; | 					QJsonArray resolutionArray; | ||||||
|  |  | ||||||
| 					format["format"] = pixelFormatToString(encodingFormat); | 					format["format"] = pixelFormatToString(encodingFormat); | ||||||
|  |  | ||||||
| 					QMultiMap<int, int> deviceResolutions = QMultiMap<int, int>(); | 					QMap<std::pair<int, int>, QSet<int>> combined = QMap<std::pair<int, int>, QSet<int>>(); | ||||||
| 					for(auto i = _deviceProperties.begin(); i != _deviceProperties.end(); ++i) | 					for (auto enc : input.value().encodingFormats.values(encodingFormat)) | ||||||
| 						if (i.key() == it.key()) | 					{ | ||||||
| 							for (auto y = i.value().inputs.begin(); y != i.value().inputs.end(); y++) | 						std::pair<int, int> width_height{enc.width, enc.height}; | ||||||
| 								if (y.key() == input.value()) | 						auto &com = combined[width_height]; | ||||||
| 									for (auto enc = y.value().encodingFormats.begin(); enc != y.value().encodingFormats.end(); enc++) | 						for (auto framerate : enc.framerates) | ||||||
| 										if (enc.key() == encodingFormat && !deviceResolutions.contains(enc.value().width, enc.value().height)) | 						{ | ||||||
| 											deviceResolutions.insert(enc.value().width, enc.value().height); | 							com.insert(framerate); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 					for (auto width_height = deviceResolutions.begin(); width_height != deviceResolutions.end(); width_height++) | 					for (auto enc = combined.constBegin(); enc != combined.constEnd(); ++enc) | ||||||
| 					{ | 					{ | ||||||
| 						QJsonObject resolution; | 						QJsonObject resolution; | ||||||
| 						QJsonArray fps; | 						QJsonArray fps; | ||||||
|  |  | ||||||
| 						resolution["width"] = int(width_height.key()); | 						resolution["width"] = enc.key().first; | ||||||
| 						resolution["height"] = int(width_height.value()); | 						resolution["height"] = enc.key().second; | ||||||
|  |  | ||||||
| 						QIntList framerates = QIntList(); | 						for (auto framerate : enc.value()) | ||||||
| 						for(auto i = _deviceProperties.begin(); i != _deviceProperties.end(); ++i) |  | ||||||
| 							if (i.key() == it.key()) |  | ||||||
| 								for (auto y = i.value().inputs.begin(); y != i.value().inputs.end(); y++) |  | ||||||
| 									if (y.key() == input.value()) |  | ||||||
| 										for (auto enc = y.value().encodingFormats.begin(); enc != y.value().encodingFormats.end(); enc++) |  | ||||||
| 											if(enc.key() == encodingFormat && enc.value().width == width_height.key() && enc.value().height == width_height.value()) |  | ||||||
| 												for (auto fps = enc.value().framerates.begin(); fps != enc.value().framerates.end(); fps++) |  | ||||||
| 													if(!framerates.contains(*fps)) |  | ||||||
| 														framerates << *fps; |  | ||||||
|  |  | ||||||
| 						for (auto framerate : framerates) |  | ||||||
| 							fps.append(framerate); | 							fps.append(framerate); | ||||||
|  |  | ||||||
| 						resolution["fps"] = fps; | 						resolution["fps"] = fps; | ||||||
| @@ -1358,7 +1326,7 @@ QJsonArray V4L2Grabber::discover(const QJsonObject& params) | |||||||
| 			device["video_inputs"] = video_inputs; | 			device["video_inputs"] = video_inputs; | ||||||
|  |  | ||||||
| 			QJsonObject controls, controls_default; | 			QJsonObject controls, controls_default; | ||||||
| 			for (auto control : _deviceControls[it.key()]) | 			for (auto control : _deviceControls[device_property.key()]) | ||||||
| 			{ | 			{ | ||||||
| 				QJsonObject property; | 				QJsonObject property; | ||||||
| 				property["minValue"] = control.minValue; | 				property["minValue"] = control.minValue; | ||||||
| @@ -1533,7 +1501,7 @@ void V4L2Grabber::enumVideoCaptureDevices() | |||||||
|  |  | ||||||
| 			// Enumerate video control IDs | 			// Enumerate video control IDs | ||||||
| 			QList<DeviceControls> deviceControlList; | 			QList<DeviceControls> deviceControlList; | ||||||
| 			for (auto it = _controlIDPropertyMap->begin(); it != _controlIDPropertyMap->end(); it++) | 			for (auto it = _controlIDPropertyMap->constBegin(); it != _controlIDPropertyMap->constEnd(); it++) | ||||||
| 			{ | 			{ | ||||||
| 				struct v4l2_queryctrl queryctrl; | 				struct v4l2_queryctrl queryctrl; | ||||||
| 				CLEAR(queryctrl); | 				CLEAR(queryctrl); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user