'text_right',
'threshold',
'videodevice',
- 'width'
+ 'width',
+ 'mmalcam_name'
}
while camera_id in camera_ids:
camera_id += 1
- logging.info('adding new camera with id %(id)s...' % {'id': camera_id})
+ logging.info('adding new %(prt)s camera with id %(id)s...' % {'prt': proto, 'id': camera_id})
# prepare a default camera config
camera_config = {'@enabled': True}
camera_config['@password'] = device_details['password']
camera_config['@remote_camera_id'] = device_details['remote_camera_id']
+ elif proto == 'mmal':
+ camera_config['mmalcam_name'] = device_details['path']
+ camera_config['width'] = 640
+ camera_config['height'] = 480
+
elif proto == 'netcam':
camera_config['netcam_url'] = device_details['url']
camera_config['text_double'] = True
if utils.is_v4l2_camera(old_config):
proto = 'v4l2'
+ elif utils.is_mmal_camera(old_config):
+ proto = 'mmal'
+
else:
proto = 'netcam'
- if proto == 'v4l2':
+ if (proto == 'v4l2') or (proto == 'mmal'):
# leave videodevice unchanged
# resolution
# we have no other choice but use something like 640x480 as reference
threshold = data['threshold'] * 100.0 / (640 * 480)
+ elif utils.is_mmal_camera(data):
+ ui['device_url'] = data['mmalcam_name']
+ ui['proto'] = 'mmal'
+
+ resolutions = utils.RPI_MMAL_RESOLUTIONS
+ resolutions = [r for r in resolutions if motionctl.resolution_is_valid(*r)]
+ ui['available_resolutions'] = [(str(w) + 'x' + str(h)) for (w, h) in resolutions]
+ ui['resolution'] = str(data['width']) + 'x' + str(data['height'])
+
+ threshold = data['threshold'] * 100.0 / (data['width'] * data['height'])
+
else: # assuming v4l2
ui['device_url'] = data['videodevice']
ui['proto'] = 'v4l2'
self.finish_json({'cameras': cameras})
+ elif proto == 'mmal':
+ configured_devices = set()
+ for camera_id in config.get_camera_ids():
+ data = config.get_camera(camera_id)
+ if utils.is_mmal_camera(data):
+ configured_devices.add(data['mmalcam_name'])
+
+ if "vc.ril.camera" not in configured_devices:
+ cameras = [{'id': "vc.ril.camera", 'name': "VideoCore Camera (vc.ril.camera)"}]
+ else:
+ cameras = []
+
+ self.finish_json({'cameras': cameras})
+
else: # assuming local motionEye camera listing
cameras = []
camera_ids = config.get_camera_ids()
case 'netcam':
prettyType = 'Network Camera';
break;
+
+ case 'mmal':
+ prettyType = 'MMAL Camera';
+ break;
case 'motioneye':
prettyType = 'Remote motionEye Camera';
var cameraIdsByInstance = {};
getCameraFrames().each(function () {
var instance;
- if (this.config.proto == 'netcam' || this.config.proto == 'v4l2') {
+ if (this.config.proto == 'netcam' || this.config.proto == 'v4l2' || this.config.proto == 'mmal') {
instance = '';
}
else if (this.config.proto == 'motioneye') {
'<td class="dialog-item-label"><span class="dialog-item-label">Camera Type</span></td>' +
'<td class="dialog-item-value"><select class="styled" id="typeSelect">' +
(hasLocalCamSupport ? '<option value="v4l2">Local Camera</option>' : '') +
+ (hasLocalCamSupport ? '<option value="mmal">Local MMAL Camera</option>' : '') +
(hasNetCamSupport ? '<option value="netcam">Network Camera</option>' : '') +
'<option value="motioneye">Remote motionEye Camera</option>' +
'<option value="mjpeg">Simple MJPEG Camera</option>' +
'<td class="dialog-item-value"><input type="password" class="styled" id="passwordEntry" placeholder="password..."></td>' +
'<td><span class="help-mark" title="the password for the URL, if required">?</span></td>' +
'</tr>' +
- '<tr class="v4l2 motioneye netcam mjpeg">' +
+ '<tr class="v4l2 motioneye netcam mjpeg mmal">' +
'<td class="dialog-item-label"><span class="dialog-item-label">Camera</span></td>' +
'<td class="dialog-item-value"><select class="styled" id="addCameraSelect"></select><span id="cameraMsgLabel"></span></td>' +
'<td><span class="help-mark" title="the camera you wish to add">?</span></td>' +
'</tr>' +
- '<tr class="v4l2 motioneye netcam mjpeg">' +
+ '<tr class="v4l2 motioneye netcam mjpeg mmal">' +
'<td colspan="100"><div class="dialog-item-separator"></div></td>' +
'</tr>' +
- '<tr class="v4l2 motioneye netcam mjpeg">' +
+ '<tr class="v4l2 motioneye netcam mjpeg mmal">' +
'<td class="dialog-item-value" colspan="100"><div id="addCameraInfo"></div></td>' +
'</tr>' +
'</table>');
/* ui interaction */
function updateUi() {
- content.find('tr.v4l2, tr.motioneye, tr.netcam, tr.mjpeg').css('display', 'none');
+ content.find('tr.v4l2, tr.motioneye, tr.netcam, tr.mjpeg, tr.mmal').css('display', 'none');
if (typeSelect.val() == 'motioneye') {
content.find('tr.motioneye').css('display', 'table-row');
'Network cameras (or IP cameras) are devices that natively stream RTSP or MJPEG videos or plain JPEG images. ' +
"Consult your device's manual to find out the correct RTSP, MJPEG or JPEG URL.");
}
+ else if (typeSelect.val() == 'mmal') {
+ content.find('tr.mmal').css('display', 'table-row');
+ addCameraInfo.html(
+ 'Local MMAL cameras are devices that are connected directly to your motionEye system. ' +
+ 'These are usually board-specific cameras.');
+ }
else if (typeSelect.val() == 'mjpeg') {
usernameEntry.removeAttr('readonly');
data.proto = 'netcam';
data.camera_index = addCameraSelect.val();
}
+ else if (typeSelect.val() == 'mmal') {
+ data.path = addCameraSelect.val();
+ data.proto = 'mmal';
+ }
else if (typeSelect.val() == 'mjpeg') {
data = splitCameraUrl(urlEntry.val());
data.username = usernameEntry.val();
(1920, 1080)
]
+RPI_MMAL_RESOLUTIONS = [
+ (640, 480),
+ (1280, 720),
+ (1280, 960),
+ (1920, 1080),
+ (1920, 1088),
+ (2592, 1944)
+]
+
def _(x):
return x # this could later be replaced by a proper translate function
def is_local_motion_camera(config):
"""Tells if a camera is managed by the local motion instance."""
- return bool(config.get('videodevice') or config.get('netcam_url'))
-
+ return bool(config.get('videodevice') or config.get('netcam_url') or config.get('mmalcam_name'))
def is_remote_camera(config):
"""Tells if a camera is managed by a remote motionEye server."""
"""Tells if a camera is a v4l2 device managed by the local motion instance."""
return bool(config.get('videodevice'))
+def is_mmal_camera(config):
+ '''Tells if a camera is mmal device managed by the local motion instance.'''
+ return bool(config.get('mmalcam_name'))
def is_net_camera(config):
"""Tells if a camera is a network camera managed by the local motion instance."""