diff --git a/picamera/camera.py b/picamera/camera.py index 36b1202a..18197127 100644 --- a/picamera/camera.py +++ b/picamera/camera.py @@ -2974,8 +2974,17 @@ def _get_exposure_speed(self): def _get_analog_gain(self): self._check_camera_open() return mo.to_fraction( - self._camera.control.params[mmal.MMAL_PARAMETER_CAMERA_SETTINGS].analog_gain) - analog_gain = property(_get_analog_gain, doc="""\ + self._camera.control.params[mmal.MMAL_PARAMETER_ANALOG_GAIN]) + def _set_analog_gain(self, value): + self._check_camera_open() + try: + if not (0 <= value <= 16): + raise PiCameraValueError( + "Invalid analog gain value: %d (valid range 0..16)" % value) + except TypeError: + raise PiCameraValueError("Invalid analog gain value: %s" % value) + self._camera.control.params[mmal.MMAL_PARAMETER_ANALOG_GAIN] = mo.to_rational(value) + analog_gain = property(_get_analog_gain, _set_analog_gain, doc="""\ Retrieves the current analog gain of the camera. When queried, this property returns the analog gain currently being @@ -2989,8 +2998,17 @@ def _get_analog_gain(self): def _get_digital_gain(self): self._check_camera_open() return mo.to_fraction( - self._camera.control.params[mmal.MMAL_PARAMETER_CAMERA_SETTINGS].digital_gain) - digital_gain = property(_get_digital_gain, doc="""\ + self._camera.control.params[mmal.MMAL_PARAMETER_DIGITAL_GAIN]) + def _set_digital_gain(self, value): + self._check_camera_open() + try: + if not (0 <= value <= 64): + raise PiCameraValueError( + "Invalid digital gain value: %d (valid range 0..64)" % value) + except TypeError: + raise PiCameraValueError("Invalid digital gain value: %s" % value) + self._camera.control.params[mmal.MMAL_PARAMETER_DIGITAL_GAIN] = mo.to_rational(value) + digital_gain = property(_get_digital_gain, _set_digital_gain, doc="""\ Retrieves the current digital gain of the camera. When queried, this property returns the digital gain currently being diff --git a/picamera/mmal.py b/picamera/mmal.py index 81b059fc..987bd142 100644 --- a/picamera/mmal.py +++ b/picamera/mmal.py @@ -621,7 +621,21 @@ class MMAL_PARAMETER_LOGGING_T(ct.Structure): MMAL_PARAMETER_DPF_CONFIG, MMAL_PARAMETER_JPEG_RESTART_INTERVAL, MMAL_PARAMETER_CAMERA_ISP_BLOCK_OVERRIDE, -) = range(MMAL_PARAMETER_GROUP_CAMERA, MMAL_PARAMETER_GROUP_CAMERA + 82) + MMAL_PARAMETER_LENS_SHADING_OVERRIDE, + MMAL_PARAMETER_BLACK_LEVEL, + MMAL_PARAMETER_RESIZE_PARAMS, + MMAL_PARAMETER_CROP, + MMAL_PARAMETER_OUTPUT_SHIFT, + MMAL_PARAMETER_CCM_SHIFT, + MMAL_PARAMETER_CUSTOM_CCM, + MMAL_PARAMETER_ANALOG_GAIN, + MMAL_PARAMETER_DIGITAL_GAIN, + MMAL_PARAMETER_DENOISE, + MMAL_PARAMETER_SHARPEN, + MMAL_PARAMETER_GREEN_EQ, + MMAL_PARAMETER_DPC, + MMAL_PARAMETER_GAMMA, +) = range(MMAL_PARAMETER_GROUP_CAMERA, MMAL_PARAMETER_GROUP_CAMERA + 96) class MMAL_PARAMETER_THUMBNAIL_CONFIG_T(ct.Structure): _fields_ = [ diff --git a/picamera/mmalobj.py b/picamera/mmalobj.py index ec167f2f..6cfde714 100644 --- a/picamera/mmalobj.py +++ b/picamera/mmalobj.py @@ -202,6 +202,8 @@ mmal.MMAL_PARAMETER_ZERO_COPY: mmal.MMAL_PARAMETER_BOOLEAN_T, mmal.MMAL_PARAMETER_ZERO_SHUTTER_LAG: mmal.MMAL_PARAMETER_ZEROSHUTTERLAG_T, mmal.MMAL_PARAMETER_ZOOM: mmal.MMAL_PARAMETER_SCALEFACTOR_T, + mmal.MMAL_PARAMETER_ANALOG_GAIN: mmal.MMAL_PARAMETER_RATIONAL_T, + mmal.MMAL_PARAMETER_DIGITAL_GAIN: mmal.MMAL_PARAMETER_RATIONAL_T, } diff --git a/tests/test_attr.py b/tests/test_attr.py index 2155c186..e13a4bea 100644 --- a/tests/test_attr.py +++ b/tests/test_attr.py @@ -81,10 +81,15 @@ def boolean_attr(camera, attr): finally: setattr(camera, attr, save_value) - def test_analog_gain(camera, previewing): - # Just test the read-only property returns something sensible - assert 0.0 <= camera.analog_gain <= 8.0 + camera.analog_gain = 1.0 + assert camera.analog_gain == 1.0 + camera.analog_gain = 16.0 + assert camera.analog_gain == 16.0 + with pytest.raises(picamera.PiCameraValueError): + camera.analog_gain = 17.0 + with pytest.raises(picamera.PiCameraValueError): + camera.analog_gain = -1.0 def test_annotate_text(camera, previewing): save_value = camera.annotate_text @@ -194,8 +199,14 @@ def test_contrast(camera, previewing): numeric_attr(camera, 'contrast', -100, 100) def test_digital_gain(camera, previewing): - # Just test the read-only property returns something sensible - assert 0.0 <= camera.digital_gain <= 8.0 + camera.digital_gain = 1.0 + assert camera.digital_gain == 1.0 + camera.digital_gain = 64.0 + assert camera.digital_gain == 64.0 + with pytest.raises(picamera.PiCameraValueError): + camera.digital_gain = 65.0 + with pytest.raises(picamera.PiCameraValueError): + camera.digital_gain = -1.0 def test_exposure_compensation(camera, previewing): numeric_attr(camera, 'exposure_compensation', -25, 25)