/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019, Google Inc. * * libcamera Camera API tests */ #include #include #include "camera_test.h" #include "test.h" using namespace libcamera; using namespace std; namespace { class Statemachine : public CameraTest, public Test { public: Statemachine() : CameraTest("platform/vimc.0 Sensor B") { } protected: int testAvailable() { /* Test operations which should fail. */ if (camera_->configure(defconf_.get()) != -EACCES) return TestFail; if (camera_->createRequest()) return TestFail; if (camera_->start() != -EACCES) return TestFail; Request request(camera_.get()); if (camera_->queueRequest(&request) != -EACCES) return TestFail; /* Test operations which should pass. */ if (camera_->release()) return TestFail; if (camera_->stop()) return TestFail; /* Test valid state transitions, end in Acquired state. */ if (camera_->acquire()) return TestFail; return TestPass; } int testAcquired() { /* Test operations which should fail. */ if (camera_->acquire() != -EBUSY) return TestFail; if (camera_->createRequest()) return TestFail; if (camera_->start() != -EACCES) return TestFail; Request request(camera_.get()); if (camera_->queueRequest(&request) != -EACCES) return TestFail; /* Test operations which should pass. */ if (camera_->stop()) return TestFail; /* Test valid state transitions, end in Configured state. */ if (camera_->release()) return TestFail; if (camera_->acquire()) return TestFail; if (camera_->configure(defconf_.get())) return TestFail; return TestPass; } int testConfigured() { /* Test operations which should fail. */ if (camera_->acquire() != -EBUSY) return TestFail; Request request1(camera_.get()); if (camera_->queueRequest(&request1) != -EACCES) return TestFail; /* Test operations which should pass. */ std::unique_ptr request2 = camera_->createRequest(); if (!request2) return TestFail; if (camera_->stop()) return TestFail; /* Test valid state transitions, end in Running state. */ if (camera_->release()) return TestFail; if (camera_->acquire()) return TestFail; if (camera_->configure(defconf_.get())) return TestFail; /* Use internally allocated buffers. */ allocator_ = new FrameBufferAllocator(camera_); Stream *stream = *camera_->streams().begin(); if (allocator_->allocate(stream) < 0) return TestFail; if (camera_->start()) return TestFail; return TestPass; } int testRuning() { /* Test operations which should fail. */ if (camera_->acquire() != -EBUSY) return TestFail; if (camera_->release() != -EBUSY) return TestFail; if (camera_->configure(defconf_.get()) != -EACCES) return TestFail; if (camera_->start() != -EACCES) return TestFail; /* Test operations which should pass. */ std::unique_ptr request = camera_->createRequest(); if (!request) return TestFail; Stream *stream = *camera_->streams().begin(); if (request->addBuffer(stream, allocator_->buffers(stream)[0].get())) return TestFail; if (camera_->queueRequest(request.get())) return TestFail; /* Test valid state transitions, end in Available state. */ if (camera_->stop()) return TestFail; delete allocator_; if (camera_->release()) return TestFail; return TestPass; } int init() override { if (status_ != TestPass) return status_; defconf_ = camera_->generateConfiguration({ StreamRole::VideoRecording }); if (!defconf_) { cout << "Failed to generate default configuration" << endl; return TestFail; } return TestPass; } int run() override { if (testAvailable() != TestPass) { cout << "State machine in Available state failed" << endl; return TestFail; } if (testAcquired() != TestPass) { cout << "State machine in Acquired state failed" << endl; return TestFail; } if (testConfigured() != TestPass) { cout << "State machine in Configured state failed" << endl; return TestFail; } if (testRuning() != TestPass) { cout << "State machine in Running state failed" << endl; return TestFail; } return TestPass; } std::unique_ptr defconf_; FrameBufferAllocator *allocator_; }; } /* namespace */ TEST_REGISTER(Statemachine) 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
# SPDX-License-Identifier: CC0-1.0

project('libcamera', 'c', 'cpp',
    meson_version : '>= 0.47',
    version : '0.0.0',
    default_options : [
        'werror=true',
        'warning_level=2',
        'cpp_std=c++14',
    ],
    license : 'LGPL 2.1+')

# Generate version information. The libcamera_git_version variable contains the
# full version with git patch count and SHA1 (e.g. 1.2.3+211-c94a24f4), while
# the libcamera_version variable contains the major.minor.patch (e.g. 1.2.3)
# only. If the source tree isn't under git control, or if it matches the last
# git version tag, the build metadata (e.g. +211-c94a24f4) is omitted from
# libcamera_git_version.
libcamera_git_version = run_command('utils/gen-version.sh',
                                    meson.build_root()).stdout().strip()
if libcamera_git_version == ''
    libcamera_git_version = meson.project_version()
endif

libcamera_version = libcamera_git_version.split('+')[0]

# Configure the build environment.
cc = meson.get_compiler('c')
config_h = configuration_data()

if cc.has_header_symbol('execinfo.h', 'backtrace')
    config_h.set('HAVE_BACKTRACE', 1)
endif

if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix : '#define _GNU_SOURCE')
    config_h.set('HAVE_SECURE_GETENV', 1)
endif

common_arguments = [
    '-Wno-unused-parameter',
    '-include', 'config.h',
]

c_arguments = []
cpp_arguments = []

if cc.get_id() == 'clang'
    # Turn _FORTIFY_SOURCE by default on optimised builds (as it requires -O1
    # or higher). This is needed on clang only as gcc enables it by default.
    if get_option('optimization') != '0'
        common_arguments += [
            '-D_FORTIFY_SOURCE=2',
        ]
    endif

    # Use libc++ by default if available instead of libstdc++ when compiling
    # with clang.
    if cc.find_library('libc++', required: false).found()
        cpp_arguments += [
            '-stdlib=libc++',
        ]
    endif
endif

# We use C99 designated initializers for arrays as C++ has no equivalent
# feature. Both gcc and clang support this extension, but recent
# versions of clang generate a warning that needs to be disabled.
if cc.has_argument('-Wno-c99-designator')
    common_arguments += [
        '-Wno-c99-designator',
    ]
endif

# gcc 7.1 introduced processor-specific ABI breakages related to parameter
# passing on ARM platforms. This generates a large number of messages during
# compilation with gcc >=7.1 until gcc 9. Silence them.
if (host_machine.cpu_family() == 'arm' and cc.get_id() == 'gcc' and
    cc.version().version_compare('>=7.1') and cc.version().version_compare('<9'))
    cpp_arguments += [
        '-Wno-psabi',
    ]
endif

c_arguments += common_arguments
cpp_arguments += common_arguments

add_project_arguments(c_arguments, language : 'c')
add_project_arguments(cpp_arguments, language : 'cpp')
add_project_link_arguments(cpp_arguments, language : 'cpp')

libcamera_includes = include_directories('include')

subdir('include')
subdir('src')
subdir('utils')

# The documentation and test components are optional and can be disabled
# through configuration values. They are enabled by default.

if get_option('documentation')
    subdir('Documentation')
endif

if get_option('test')
    subdir('test')
endif

# Create a symlink from the build root to the source root. This is used when
# running libcamera from the build directory to locate resources in the source
# directory (such as IPA configuration files).
run_command('ln', '-fsT', meson.source_root(),
            join_paths(meson.build_root(), 'source'))

configure_file(output : 'config.h', configuration : config_h)

pkg_mod = import('pkgconfig')
pkg_mod.generate(libraries : libcamera,
                 version : '1.0',
                 name : 'libcamera',
                 filebase : 'camera',
                 description : 'Complex Camera Support Library',
                 subdirs : 'libcamera')