Ensure TurboJPEG is imported in the executor (#113504)
The import was too late and it eneded up being imported in the event loop
This commit is contained in:
parent
e0b1531afa
commit
9cc0006b92
2 changed files with 30 additions and 17 deletions
|
@ -2,20 +2,27 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from contextlib import suppress
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Literal, cast
|
from typing import TYPE_CHECKING, Literal, cast
|
||||||
|
|
||||||
|
with suppress(Exception): # pylint: disable=broad-except
|
||||||
|
# TurboJPEG imports numpy which may or may not work so
|
||||||
|
# we have to guard the import here. We still want
|
||||||
|
# to import it at top level so it gets loaded
|
||||||
|
# in the import executor and not in the event loop.
|
||||||
|
from turbojpeg import TurboJPEG
|
||||||
|
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from . import Image
|
||||||
|
|
||||||
SUPPORTED_SCALING_FACTORS = [(7, 8), (3, 4), (5, 8), (1, 2), (3, 8), (1, 4), (1, 8)]
|
SUPPORTED_SCALING_FACTORS = [(7, 8), (3, 4), (5, 8), (1, 2), (3, 8), (1, 4), (1, 8)]
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
JPEG_QUALITY = 75
|
JPEG_QUALITY = 75
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from turbojpeg import TurboJPEG
|
|
||||||
|
|
||||||
from . import Image
|
|
||||||
|
|
||||||
|
|
||||||
def find_supported_scaling_factor(
|
def find_supported_scaling_factor(
|
||||||
current_width: int, current_height: int, target_width: int, target_height: int
|
current_width: int, current_height: int, target_width: int, target_height: int
|
||||||
|
@ -90,12 +97,6 @@ class TurboJPEGSingleton:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Try to create TurboJPEG only once."""
|
"""Try to create TurboJPEG only once."""
|
||||||
try:
|
try:
|
||||||
# TurboJPEG checks for libturbojpeg
|
|
||||||
# when its created, but it imports
|
|
||||||
# numpy which may or may not work so
|
|
||||||
# we have to guard the import here.
|
|
||||||
from turbojpeg import TurboJPEG # pylint: disable=import-outside-toplevel
|
|
||||||
|
|
||||||
TurboJPEGSingleton.__instance = TurboJPEG()
|
TurboJPEGSingleton.__instance = TurboJPEG()
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
_LOGGER.exception(
|
_LOGGER.exception(
|
||||||
|
|
|
@ -38,25 +38,33 @@ def test_scale_jpeg_camera_image() -> None:
|
||||||
camera_image = Image("image/jpeg", EMPTY_16_12_JPEG)
|
camera_image = Image("image/jpeg", EMPTY_16_12_JPEG)
|
||||||
|
|
||||||
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
||||||
with patch("turbojpeg.TurboJPEG", return_value=False):
|
with patch(
|
||||||
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=False
|
||||||
|
):
|
||||||
TurboJPEGSingleton()
|
TurboJPEGSingleton()
|
||||||
assert scale_jpeg_camera_image(camera_image, 16, 12) == camera_image.content
|
assert scale_jpeg_camera_image(camera_image, 16, 12) == camera_image.content
|
||||||
|
|
||||||
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
||||||
turbo_jpeg.decode_header.side_effect = OSError
|
turbo_jpeg.decode_header.side_effect = OSError
|
||||||
with patch("turbojpeg.TurboJPEG", return_value=turbo_jpeg):
|
with patch(
|
||||||
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
||||||
|
):
|
||||||
TurboJPEGSingleton()
|
TurboJPEGSingleton()
|
||||||
assert scale_jpeg_camera_image(camera_image, 16, 12) == camera_image.content
|
assert scale_jpeg_camera_image(camera_image, 16, 12) == camera_image.content
|
||||||
|
|
||||||
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
||||||
with patch("turbojpeg.TurboJPEG", return_value=turbo_jpeg):
|
with patch(
|
||||||
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
||||||
|
):
|
||||||
TurboJPEGSingleton()
|
TurboJPEGSingleton()
|
||||||
assert scale_jpeg_camera_image(camera_image, 16, 12) == EMPTY_16_12_JPEG
|
assert scale_jpeg_camera_image(camera_image, 16, 12) == EMPTY_16_12_JPEG
|
||||||
|
|
||||||
turbo_jpeg = mock_turbo_jpeg(
|
turbo_jpeg = mock_turbo_jpeg(
|
||||||
first_width=16, first_height=12, second_width=8, second_height=6
|
first_width=16, first_height=12, second_width=8, second_height=6
|
||||||
)
|
)
|
||||||
with patch("turbojpeg.TurboJPEG", return_value=turbo_jpeg):
|
with patch(
|
||||||
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
||||||
|
):
|
||||||
TurboJPEGSingleton()
|
TurboJPEGSingleton()
|
||||||
jpeg_bytes = scale_jpeg_camera_image(camera_image, 8, 6)
|
jpeg_bytes = scale_jpeg_camera_image(camera_image, 8, 6)
|
||||||
|
|
||||||
|
@ -65,7 +73,9 @@ def test_scale_jpeg_camera_image() -> None:
|
||||||
turbo_jpeg = mock_turbo_jpeg(
|
turbo_jpeg = mock_turbo_jpeg(
|
||||||
first_width=640, first_height=480, second_width=640, second_height=480
|
first_width=640, first_height=480, second_width=640, second_height=480
|
||||||
)
|
)
|
||||||
with patch("turbojpeg.TurboJPEG", return_value=turbo_jpeg):
|
with patch(
|
||||||
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
||||||
|
):
|
||||||
TurboJPEGSingleton()
|
TurboJPEGSingleton()
|
||||||
jpeg_bytes = scale_jpeg_camera_image(camera_image, 320, 480)
|
jpeg_bytes = scale_jpeg_camera_image(camera_image, 320, 480)
|
||||||
|
|
||||||
|
@ -75,7 +85,9 @@ def test_scale_jpeg_camera_image() -> None:
|
||||||
def test_turbojpeg_load_failure() -> None:
|
def test_turbojpeg_load_failure() -> None:
|
||||||
"""Handle libjpegturbo not being installed."""
|
"""Handle libjpegturbo not being installed."""
|
||||||
_clear_turbojpeg_singleton()
|
_clear_turbojpeg_singleton()
|
||||||
with patch("turbojpeg.TurboJPEG", side_effect=Exception):
|
with patch(
|
||||||
|
"homeassistant.components.camera.img_util.TurboJPEG", side_effect=Exception
|
||||||
|
):
|
||||||
TurboJPEGSingleton()
|
TurboJPEGSingleton()
|
||||||
assert TurboJPEGSingleton.instance() is False
|
assert TurboJPEGSingleton.instance() is False
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue