diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/apps/c_apps/c_main.c | 130 | ||||
-rw-r--r-- | src/apps/c_apps/meson.build | 8 | ||||
-rw-r--r-- | src/apps/meson.build | 2 | ||||
-rw-r--r-- | src/libcamera/camera_manager.cpp | 2 | ||||
-rw-r--r-- | src/libcamera_c/camera_c.cpp | 69 | ||||
-rw-r--r-- | src/libcamera_c/camera_manager_c.cpp | 114 | ||||
-rw-r--r-- | src/libcamera_c/meson.build | 30 | ||||
-rw-r--r-- | src/libcamera_c/request_c.cpp | 8 | ||||
-rw-r--r-- | src/meson.build | 1 |
9 files changed, 363 insertions, 1 deletions
diff --git a/src/apps/c_apps/c_main.c b/src/apps/c_apps/c_main.c new file mode 100644 index 00000000..a44c3d50 --- /dev/null +++ b/src/apps/c_apps/c_main.c @@ -0,0 +1,130 @@ +#include "camera_c.h" +#include "camera_manager_c.h" +#include "request_c.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +[[maybe_unused]] +static void list_camera_cbk(camera_t camera) +{ + printf("Camera name: %s\n", camera_id(camera)); +} + +static void managed_camera_cleanup(managed_camera_t **cameras) +{ + if (!*cameras) + return; + + camera_manager_camera_list_drop(*cameras, 2); + free(*cameras); +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) +{ + camera_manager_t *mngr = camera_manager_create(); + camera_manager_start(mngr); + + printf(" === Unwrap the camera list with callbacks === \n"); + + /* + * Inspect the camera list with callbacks. + + * No memory transfer, the callback has access to members one by one + */ + camera_manager_list_cameras_with_cbk(mngr, list_camera_cbk); + printf("\n"); + + printf(" === View the camera list memory (doesn't work) === \n"); + /* + * View the libcamera::CameraManager::cameras() memory. + * + * This doesn't work and segfaults as CameraManager::cameras() return a new vector instance + * instead of refrencing to its owned copy. + */ + { + const managed_camera_t *cameras; + size_t num_cameras = camera_manager_list_cameras_view(mngr, + &cameras); + + for (size_t i = 0; i < num_cameras; ++i) { + printf("Camera name: %s\n", " nope.. ");//shared_ptr_camera_id(cameras[i])); + } + } + printf("\n"); + + printf(" === Get a list of cameras increasing the ref count (grab) === \n"); + /* + * Borrow the shared_ptr into memory owned by application and increase the reference count + * + * We need to explicitly drop references and release memory + */ + char camera_name[100]; + { + size_t num_cameras = camera_manager_num_cameras(mngr); + + __attribute__((cleanup(managed_camera_cleanup))) + managed_camera_t *cameras = (managed_camera_t *)calloc(num_cameras, + sizeof(*cameras)); + + camera_manager_camera_list_grab(mngr, cameras); + + for (size_t i = 0; i < num_cameras; ++i) { + printf("Camera name: %s\n", shared_ptr_camera_id(&cameras[i])); + } + + const char *name = shared_ptr_camera_id(&cameras[0]); + memcpy(camera_name, name, strlen(name)); + } + printf("\n"); + + printf(" === Get a list of raw camera references (borrow) === \n"); + /* + * Copy the raw Camera pointers in application's memory. + * + * No reference handling needed, but memory has to be released + */ + { + size_t num_cameras = camera_manager_num_cameras(mngr); + camera_t *cameras = (camera_t *)calloc(num_cameras, + sizeof(*cameras)); + + camera_manager_camera_list_borrow(mngr, cameras); + for (size_t i = 0; i < num_cameras; ++i) { + printf("Camera name: %s\n", camera_id(cameras[i])); + } + + free(cameras); + + } + + managed_camera_t camera = {}; + printf("Camera name: %s\n", camera_name); + camera_manager_get_camera(mngr, camera_name, &camera); + + camera_configuration_t config = {}; + enum stream_roles roles[] = { VIEWFINDER }; + camera_generate_configuration(&camera, roles, 1, &config); + + camera_acquire(&camera); + camera_configure(&camera, &config); + + request_t requests[8] = {}; + + for (size_t i = 0; i < 8; ++i) { + camera_create_request(&camera, &requests[i]); + } + + /* Cleanup */ + for (size_t i = 0; i < 8; ++i) + request_drop(&requests[i]); + camera_drop_configuration(&config); + camera_release(&camera); + camera_put(&camera); + + camera_manager_stop(mngr); + camera_manager_delete(mngr); + + return 0; +}
\ No newline at end of file diff --git a/src/apps/c_apps/meson.build b/src/apps/c_apps/meson.build new file mode 100644 index 00000000..c5b0b3b9 --- /dev/null +++ b/src/apps/c_apps/meson.build @@ -0,0 +1,8 @@ + +c_cam_sources = files([ + 'c_main.c', +]) + +c_cam = executable('c_cam', c_cam_sources, + link_with : libcamera_c_abi, + dependencies : libcamera_c) diff --git a/src/apps/meson.build b/src/apps/meson.build index af632b9a..4b0b1598 100644 --- a/src/apps/meson.build +++ b/src/apps/meson.build @@ -12,6 +12,8 @@ endif libtiff = dependency('libtiff-4', required : false) +subdir('c_apps') + subdir('common') subdir('lc-compliance') diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 87e6717e..38671d2b 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -362,7 +362,7 @@ void CameraManager::stop() * * \return List of all available cameras */ -std::vector<std::shared_ptr<Camera>> CameraManager::cameras() const +const std::vector<std::shared_ptr<Camera>> &CameraManager::cameras() const { const Private *const d = _d(); diff --git a/src/libcamera_c/camera_c.cpp b/src/libcamera_c/camera_c.cpp new file mode 100644 index 00000000..eb95937e --- /dev/null +++ b/src/libcamera_c/camera_c.cpp @@ -0,0 +1,69 @@ +#include <camera_c.h> +#include "libcamera/stream.h" + +using namespace libcamera; + +const char *camera_id(camera_t camera) +{ + Camera *c = (Camera *)camera; + + return c->id().c_str(); +} + +const char *shared_ptr_camera_id(const managed_camera_t *shrd) +{ + Camera *c = (*shrd).get(); + + return c->id().c_str(); +} + +void camera_put(managed_camera_t *shrd) +{ + (*shrd).reset(); +} + +void camera_generate_configuration(managed_camera_t *shrd, enum stream_roles *c_roles, + size_t num_roles, camera_configuration_t *config) +{ + Span<StreamRole> roles = Span<StreamRole>((StreamRole *)c_roles, num_roles); + Camera *c = (*shrd).get(); + + using namespace std; + cout << "usage count: " << shrd->use_count() << endl; + cout << "sizeof unique: " << sizeof(*config) << endl; + + *config = c->generateConfiguration(roles); +} + +void camera_drop_configuration(camera_configuration_t *config) +{ + (*config).reset(); +} + +void camera_acquire(managed_camera_t *shrd) +{ + Camera *c = (*shrd).get(); + + c->acquire(); +} + +void camera_release(managed_camera_t *shrd) +{ + Camera *c = (*shrd).get(); + + c->release(); +} + +void camera_configure(managed_camera_t *shrd, camera_configuration_t *config) +{ + Camera *c = (*shrd).get(); + + c->configure((*config).get()); +} + +void camera_create_request(managed_camera_t *shrd, request_t *request) +{ + Camera *c = (*shrd).get(); + + (*request) = c->createRequest(); +}
\ No newline at end of file diff --git a/src/libcamera_c/camera_manager_c.cpp b/src/libcamera_c/camera_manager_c.cpp new file mode 100644 index 00000000..ee7ea41e --- /dev/null +++ b/src/libcamera_c/camera_manager_c.cpp @@ -0,0 +1,114 @@ +#include "camera_manager_c.h" + +#include "camera_c.h" + +#include <libcamera.h> + +using namespace libcamera; + +camera_manager_t *camera_manager_create() +{ + return (camera_manager_t *)new CameraManager(); +} + +void camera_manager_delete(camera_manager_t *mngr) +{ + CameraManager *manager = (CameraManager *)mngr; + delete manager; +} + +int camera_manager_start(camera_manager_t *mngr) +{ + CameraManager *manager = (CameraManager *)mngr; + + return manager->start(); +} + +void camera_manager_stop(camera_manager_t *mngr) +{ + CameraManager *manager = (CameraManager *)mngr; + + manager->stop(); +} + +size_t camera_manager_num_cameras(camera_manager_t *mngr) +{ + CameraManager *manager = (CameraManager *)mngr; + + return manager->cameras().size(); +} + +void camera_manager_list_cameras_with_cbk(camera_manager_t *mngr, + camera_manager_list_camera_cbk cbk) +{ + CameraManager *manager = (CameraManager *)mngr; + + /* Unroll the std::vector<SharedPtr<Camera>> by calling cbk for each element. */ + auto &&cameras = manager->cameras(); + for (auto const &camera : cameras) { + cbk((camera_t)camera.get()); + } +} + +size_t camera_manager_list_cameras_view(camera_manager_t *mngr, + const managed_camera_t **cameras) +{ + CameraManager *manager = (CameraManager *)mngr; + + /* b0rken! manager->cameras() is temporary */ + (*cameras) = manager->cameras().data(); + return manager->cameras().size(); +} + +void camera_manager_camera_list_grab(camera_manager_t *mngr, + managed_camera_t *cameras) +{ + CameraManager *manager = (CameraManager *)mngr; + + auto &&camera_list = manager->cameras(); + + size_t i = 0; + for (auto &camera : camera_list) { + std::cout << "Use count: " << camera.use_count() << std::endl; + cameras[i++] = camera; + std::cout << "Use count: " << camera.use_count() << std::endl; + std::cout << "Use count: " << cameras[i-1].use_count() << std::endl; + } +} + +void camera_manager_camera_list_drop(managed_camera_t *cameras, + size_t num_cameras) +{ + for (size_t i = 0; i < num_cameras; ++i) { + auto &camera = cameras[i]; + + std::cout << "Use count: " << camera.use_count() << std::endl; + + /* Drop reference count */ + camera.reset(); + } +} + +void camera_manager_camera_list_borrow(camera_manager_t *mngr, + camera_t *cameras) +{ + CameraManager *manager = (CameraManager *)mngr; + + auto &&camera_list = manager->cameras(); + size_t i = 0; + for (auto const &camera : camera_list) { + cameras[i++] = (camera_t)camera.get(); + } +} + +void camera_manager_get_camera(camera_manager_t *mngr, const char *id, + managed_camera_t *camera) +{ + CameraManager *manager = (CameraManager *)mngr; + + using namespace std; + cout << "get camera: " << id << endl; + *camera = manager->get(std::string(id)); + if (!(*camera)) + cout << "ARGH!" << endl; +}
\ No newline at end of file diff --git a/src/libcamera_c/meson.build b/src/libcamera_c/meson.build new file mode 100644 index 00000000..4e063410 --- /dev/null +++ b/src/libcamera_c/meson.build @@ -0,0 +1,30 @@ + +c_includes = [ + libcamera_includes, + libcamera_c_includes, +] + +libcamera_c_sources = files([ + 'camera_c.cpp', + 'camera_manager_c.cpp', + 'request_c.cpp', +]) + +libcamera_c_deps = [ + libcamera_public, +] + +libcamera_c_abi = shared_library('libcamera_c', + [ + libcamera_c_sources, + ], + include_directories : c_includes, + dependencies : libcamera_c_deps) + + +libcamera_c = declare_dependency(sources : [ + libcamera_c_headers, + ], + include_directories : libcamera_c_includes, + dependencies : libcamera_public, + link_with : libcamera_c_abi) diff --git a/src/libcamera_c/request_c.cpp b/src/libcamera_c/request_c.cpp new file mode 100644 index 00000000..3fdf52d9 --- /dev/null +++ b/src/libcamera_c/request_c.cpp @@ -0,0 +1,8 @@ +#include "request_c.h" + +using namespace libcamera; + +void request_drop(request_t *request) +{ + (*request).reset(); +}
\ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 76198e95..4d14ac00 100644 --- a/src/meson.build +++ b/src/meson.build @@ -50,6 +50,7 @@ endif # libcamera must be built first as a dependency to the other components. subdir('libcamera') +subdir('libcamera_c') subdir('android') subdir('ipa') |