Skip to content

Commit

Permalink
Refine annotation handling
Browse files Browse the repository at this point in the history
Make mmalobj layer aware of different revisions, and make revision easy
to configure and query
  • Loading branch information
waveform80 committed May 12, 2016
1 parent 4ffedd6 commit 9feff85
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 24 deletions.
34 changes: 15 additions & 19 deletions picamera/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ class PiCamera(object):
'_overlays',
'_raw_format',
'_image_effect_params',
'_annotate_v3',
'_exif_tags',
)

Expand Down Expand Up @@ -366,7 +365,6 @@ def __init__(
self._overlays = []
self._raw_format = 'yuv'
self._image_effect_params = None
self._annotate_v3 = None
self._exif_tags = {
'IFD0.Model': 'RP_OV5647',
'IFD0.Make': 'RaspberryPi',
Expand Down Expand Up @@ -3311,8 +3309,7 @@ def _set_annotate_frame_num(self, value):

def _get_annotate_text_size(self):
self._check_camera_open()
mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
if self._annotate_v3:
if self._camera.annotate_rev == 3:
return mp.text_size or self.DEFAULT_ANNOTATE_SIZE
else:
return self.DEFAULT_ANNOTATE_SIZE
Expand All @@ -3321,16 +3318,15 @@ def _set_annotate_text_size(self, value):
if not (6 <= value <= 160):
raise PiCameraValueError(
"Invalid annotation text size: %d (valid range 6-160)" % value)
if not self._annotate_v3:
if value != self.DEFAULT_ANNOTATE_SIZE:
warnings.warn(
PiCameraFallback(
"Firmware does not support setting annotation text "
"size; using default (%d) instead" % self.DEFAULT_ANNOTATE_SIZE))
return
mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
mp.text_size = value
self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] = mp
if self._camera.annotate_rev == 3:
mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
mp.text_size = value
self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] = mp
elif value != self.DEFAULT_ANNOTATE_SIZE:
warnings.warn(
PiCameraFallback(
"Firmware does not support setting annotation text "
"size; using default (%d) instead" % self.DEFAULT_ANNOTATE_SIZE))
annotate_text_size = property(
_get_annotate_text_size, _set_annotate_text_size, doc="""\
Controls the size of the annotation text.
Expand All @@ -3345,7 +3341,7 @@ def _set_annotate_text_size(self, value):
def _get_annotate_foreground(self):
self._check_camera_open()
mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
if self._annotate_v3 and mp.custom_text_color:
if self._camera.annotate_rev == 3 and mp.custom_text_color:
return Color.from_yuv_bytes(
mp.custom_text_Y,
mp.custom_text_U,
Expand All @@ -3357,7 +3353,7 @@ def _set_annotate_foreground(self, value):
if not isinstance(value, Color):
raise PiCameraValueError(
'annotate_foreground must be a Color')
elif not self._annotate_v3:
elif self._camera.annotate_rev < 3:
if value.rgb_bytes != (255, 255, 255):
warnings.warn(
PiCameraFallback(
Expand Down Expand Up @@ -3401,7 +3397,7 @@ def _set_annotate_foreground(self, value):
def _get_annotate_background(self):
self._check_camera_open()
mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
if self._annotate_v3:
if self._camera.annotate_rev == 3:
if mp.enable_text_background:
if mp.custom_background_color:
return Color.from_yuv_bytes(
Expand Down Expand Up @@ -3436,13 +3432,13 @@ def _set_annotate_background(self, value):
elif not isinstance(value, Color):
raise PiCameraValueError(
'annotate_background must be a Color or None')
elif not self._annotate_v3 and value.rgb_bytes != (0, 0, 0):
elif self._camera.annotate_rev < 3 and value.rgb_bytes != (0, 0, 0):
warnings.warn(
PiCameraFallback(
"Firmware does not support setting a custom background "
"annotation color; using black instead"))
mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
if self._annotate_v3:
if self._camera.annotate_rev == 3:
if value is None:
mp.enable_text_background = False
else:
Expand Down
35 changes: 30 additions & 5 deletions picamera/mmalobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,11 +1165,36 @@ def __init__(self):
for port, opaque_subformat in zip(self.outputs, formats):
port.opaque_subformat = opaque_subformat
mp = self.control.params[mmal.MMAL_PARAMETER_ANNOTATE]
PARAM_TYPES[mmal.MMAL_PARAMETER_ANNOTATE] = {
ct.sizeof(mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_T): mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_T,
ct.sizeof(mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T): mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T,
ct.sizeof(mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T): mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T,
}.get(mp.hdr.size, mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T)
self.annotate_rev = {
ct.sizeof(mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_T): 1,
ct.sizeof(mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T): 2,
ct.sizeof(mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T): 3,
}.get(mp.hdr.size, 3)

def _get_annotate_rev(self):
return {
mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_T: 1,
mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T: 2,
mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T: 3,
}[PARAM_TYPES[mmal.MMAL_PARAMETER_ANNOTATE]]
def _set_annotate_rev(self, value):
try:
PARAM_TYPES[mmal.MMAL_PARAMETER_ANNOTATE] = {
1: mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_T,
2: mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T,
3: mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T,
}[value]
except KeyError:
raise PiCameraMMALError(
mmal.MMAL_EINVAL, "cannot set annotation revision")
annotate_rev = property(_get_annotate_rev, _set_annotate_rev, doc="""\
The annotation capabilities of the firmware have evolved over time and
several structures are available for querying and setting video
annotations. By default the :class:`MMALCamera` class will pick the
latest annotation structure supported by the current firmware but you
can select older revisions with :attr:`annotate_rev` for other purposes
(e.g. testing).
""")


class MMALCameraInfo(MMALComponent):
Expand Down

0 comments on commit 9feff85

Please sign in to comment.