Source code for libretro.api.camera

"""
Interface and types for providing video input to a :class:`.Core`.

.. seealso::

    :class:`.CameraDriver`
        The protocol that uses these types to implement camera support in libretro.py.

    :mod:`libretro.drivers.camera`
        libretro.py's included :class:`.CameraDriver` implementations.
"""

from ctypes import (
    Structure,
    c_bool,
    c_float,
    c_int,
    c_size_t,
    c_uint,
    c_uint32,
    c_uint64,
)
from dataclasses import dataclass
from enum import IntEnum, IntFlag

from libretro.ctypes import CIntArg, TypedFunctionPointer, TypedPointer

retro_camera_buffer = c_int
RETRO_CAMERA_BUFFER_OPENGL_TEXTURE = 0
RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER = RETRO_CAMERA_BUFFER_OPENGL_TEXTURE + 1
RETRO_CAMERA_BUFFER_DUMMY = 0x7FFFFFFF


retro_camera_start_t = TypedFunctionPointer[c_bool, []]
"""
Start the camera.

Called by the :term:`core` to begin receiving camera frames from the frontend.
Cameras are disabled by default and must be explicitly started.

:return: :obj:`True` if the camera was successfully started,
    :obj:`False` if no camera is available
    or the frontend lacks permission to access it.

Corresponds to :c:type:`retro_camera_start_t` in ``libretro.h``.
"""

retro_camera_stop_t = TypedFunctionPointer[None, []]
"""
Stop the running camera.

Called by the :term:`core` to halt the delivery of camera frames.

Corresponds to :c:type:`retro_camera_stop_t` in ``libretro.h``.
"""

retro_camera_lifetime_status_t = TypedFunctionPointer[None, []]
"""
Notify the core that the camera driver has been initialized or deinitialized.

Registered by the :term:`core` and called by the :term:`frontend`
right after the camera driver is initialized,
or right before it is deinitialized.

Corresponds to :c:type:`retro_camera_lifetime_status_t` in ``libretro.h``.
"""

retro_camera_frame_raw_framebuffer_t = TypedFunctionPointer[
    None, [TypedPointer[c_uint32], CIntArg[c_uint], CIntArg[c_uint], CIntArg[c_size_t]]
]
"""
Deliver a new camera frame as a raw pixel buffer.

Registered by the :term:`core` and called by the :term:`frontend`
when a new camera frame is available in system memory,
with the top-left corner of the image as the first pixel.

:param buffer: Pointer to the camera's most recent video frame,
    with one ``XRGB8888`` pixel per ``uint32_t``.
:param width: Width of the frame, in pixels.
:param height: Height of the frame, in pixels.
:param pitch: Length of one row in ``buffer``, in bytes.

.. warning::
    ``buffer`` may be invalidated when this function returns,
    so the core should make its own copy if it needs to retain the data.

Corresponds to :c:type:`retro_camera_frame_raw_framebuffer_t` in ``libretro.h``.
"""

retro_camera_frame_opengl_texture_t = TypedFunctionPointer[
    None, [CIntArg[c_uint], CIntArg[c_uint], TypedPointer[c_float]]
]
"""
Deliver a new camera frame as an OpenGL texture.

Registered by the :term:`core` and called by the :term:`frontend`
when a new camera frame is available as a frontend-owned OpenGL texture.

:param texture_id: ID of the OpenGL texture that holds the frame.
    Owned by the frontend; the core must not modify it.
:param texture_target: OpenGL texture target type
    (e.g. ``GL_TEXTURE_2D`` or ``GL_TEXTURE_RECTANGLE``).
:param affine: Pointer to a 3x3 column-major affine matrix
    that maps pixel coordinates to texture coordinates.

.. warning::
    ``texture_id`` and ``affine`` may be invalidated when this function returns,
    so the core should make its own copy if it needs to retain them.

Corresponds to :c:type:`retro_camera_frame_opengl_texture_t` in ``libretro.h``.
"""


[docs] class CameraCapabilities(IntEnum): """ Denotes camera features requested by the :class:`.Core` and/or supported by the :class:`.CameraDriver`. Corresponds to :c:type:`retro_camera_buffer`. """ OPENGL_TEXTURE = RETRO_CAMERA_BUFFER_OPENGL_TEXTURE RAW_FRAMEBUFFER = RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER
[docs] def flag(self) -> int: """ Return this capability as a bitmask flag. Equivalent to ``1 << self.value``. >>> from libretro.api import CameraCapabilities >>> CameraCapabilities.OPENGL_TEXTURE.flag() 1 """ return 1 << self.value
[docs] class CameraCapabilityFlags(IntFlag): """ Bitmask of supported camera driver features. >>> from libretro.api import CameraCapabilityFlags >>> CameraCapabilityFlags.RAW_FRAMEBUFFER | CameraCapabilityFlags.OPENGL_TEXTURE <CameraCapabilityFlags.RAW_FRAMEBUFFER|OPENGL_TEXTURE: 3> """ OPENGL_TEXTURE = 1 << CameraCapabilities.OPENGL_TEXTURE RAW_FRAMEBUFFER = 1 << CameraCapabilities.RAW_FRAMEBUFFER
[docs] @dataclass(init=False, slots=True) class retro_camera_callback(Structure): """ Interface between the :term:`core` and the :class:`.CameraDriver`. Corresponds to :c:type:`retro_camera_callback` in ``libretro.h``. """ caps: int """ Bitmask of requested :class:`CameraCapabilities`. Assigned values will be bitwise-masked to fit into a ``uint64_t``. .. seealso:: :attr:`.CameraDriver.caps` """ width: int """ The :term:`core`'s requested width of the camera frame in pixels. ``0`` means that the :class:`.CameraDriver` should choose the width. Assigned values will be bitwise-masked to fit into an :c:expr:`unsigned int`. .. seealso:: :attr:`.CameraDriver.width` """ height: int """ The :term:`core`'s requested height of the camera frame in pixels. ``0`` means that the :class:`.CameraDriver` should choose the height. Assigned values will be bitwise-masked to fit into an :c:expr:`unsigned int`. .. seealso:: :attr:`.CameraDriver.height` """ start: retro_camera_start_t | None """ Called by the :term:`core` to start the camera. .. seealso:: :meth:`.CameraDriver.start` """ stop: retro_camera_stop_t | None """ Called by the :term:`core` to stop the camera. .. seealso:: :meth:`.CameraDriver.stop` """ frame_raw_framebuffer: retro_camera_frame_raw_framebuffer_t | None """ Called by the :class:`.CameraDriver` when it produces a frame backed by a raw framebuffer. Set by the :class:`.Core`. .. seealso:: :attr:`.CameraDriver.frame_raw_framebuffer` """ frame_opengl_texture: retro_camera_frame_opengl_texture_t | None """ Called by the :class:`.CameraDriver` when it produces a frame backed by an OpenGL texture. Set by the :class:`.Core`. .. seealso:: :attr:`.CameraDriver.frame_opengl_texture` """ initialized: retro_camera_lifetime_status_t | None """ Called by the :class:`.CameraDriver` after it's initialized. Set by the :class:`.Core`. Optional. .. seealso:: :attr:`.CameraDriver.initialized` """ deinitialized: retro_camera_lifetime_status_t | None """ Called by the :class:`.CameraDriver` before it's deinitialized. Set by the :class:`.Core`. Optional. .. seealso:: :attr:`.CameraDriver.deinitialized` """ _fields_ = ( ("caps", c_uint64), ("width", c_uint), ("height", c_uint), ("start", retro_camera_start_t), ("stop", retro_camera_stop_t), ("frame_raw_framebuffer", retro_camera_frame_raw_framebuffer_t), ("frame_opengl_texture", retro_camera_frame_opengl_texture_t), ("initialized", retro_camera_lifetime_status_t), ("deinitialized", retro_camera_lifetime_status_t), )
[docs] def __deepcopy__(self, _): """ Return a deep copy of this object. Intended for use with :func:`copy.deepcopy`. >>> import copy >>> from libretro.api import retro_camera_callback >>> cb = retro_camera_callback(caps=1, width=640, height=480) >>> cb2 = copy.deepcopy(cb) >>> cb == cb2 True >>> cb is cb2 False """ return retro_camera_callback( caps=self.caps, width=self.width, height=self.height, start=self.start, stop=self.stop, frame_raw_framebuffer=self.frame_raw_framebuffer, frame_opengl_texture=self.frame_opengl_texture, initialized=self.initialized, deinitialized=self.deinitialized, )
__all__ = [ "retro_camera_start_t", "retro_camera_stop_t", "retro_camera_lifetime_status_t", "retro_camera_frame_raw_framebuffer_t", "retro_camera_frame_opengl_texture_t", "retro_camera_callback", "CameraCapabilities", "CameraCapabilityFlags", "retro_camera_buffer", ]