mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 06:33:31 +00:00
qemu-usb/webcam: cache large allocation of libyuv
This commit is contained in:
parent
0d868515a5
commit
264160797d
@ -10,15 +10,18 @@
|
||||
*/
|
||||
|
||||
#include <base/allocator.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/env.h>
|
||||
#include <capture_session/connection.h>
|
||||
#include <gui_session/gui_session.h>
|
||||
#include <os/reporter.h>
|
||||
#include <util/xml_node.h>
|
||||
|
||||
#include <libyuv/libyuv.h>
|
||||
#include <libyuv/convert_from_argb.h>
|
||||
|
||||
extern "C" {
|
||||
#include <stdlib.h>
|
||||
#include "webcam-backend.h"
|
||||
|
||||
void _type_init_usb_webcam_register_types();
|
||||
@ -33,10 +36,12 @@ struct Capture_webcam
|
||||
Gui::Area const _area;
|
||||
bool const _vflip;
|
||||
uint8_t const _fps;
|
||||
bool _force_update { false };
|
||||
bool _force_update { false };
|
||||
bool _libyuv_alloc_in_use { false };
|
||||
|
||||
Constructible<Capture::Connection> _capture;
|
||||
Constructible<Attached_dataspace> _ds;
|
||||
Constructible<Capture::Connection> _capture;
|
||||
Constructible<Attached_dataspace> _ds;
|
||||
Constructible<Attached_ram_dataspace> _libyuv_ds;
|
||||
|
||||
Gui::Area _setup_area(Gui::Area const area_in, bool const auto_area)
|
||||
{
|
||||
@ -130,9 +135,55 @@ struct Capture_webcam
|
||||
} else {
|
||||
_ds.destruct();
|
||||
_capture.destruct();
|
||||
|
||||
if (_libyuv_ds.constructed())
|
||||
libyuv_free(_libyuv_ds->local_addr<void>());
|
||||
}
|
||||
}
|
||||
|
||||
void * libyuv_alloc(unsigned long const size)
|
||||
{
|
||||
if (!size)
|
||||
return nullptr;
|
||||
|
||||
/* heuristic: cache only libyuv::ARGBToYUY2 YUV image allocation */
|
||||
if (size < _area.count() * 2)
|
||||
return nullptr;
|
||||
|
||||
if (_libyuv_alloc_in_use) {
|
||||
Genode::error(__func__, " cached libyuv ds already in use");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (_libyuv_ds.constructed() && _libyuv_ds->size() != size)
|
||||
_libyuv_ds.destruct();
|
||||
|
||||
if (!_libyuv_ds.constructed() || _libyuv_ds->size() != size)
|
||||
_libyuv_ds.construct(_env.pd(), _env.rm(), size);
|
||||
|
||||
_libyuv_alloc_in_use = true;
|
||||
|
||||
return _libyuv_ds->local_addr<void>();
|
||||
}
|
||||
|
||||
|
||||
bool libyuv_free(void *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
if (!_libyuv_ds.constructed())
|
||||
return false;
|
||||
|
||||
if (ptr != _libyuv_ds->local_addr<void>())
|
||||
return false;
|
||||
|
||||
_libyuv_alloc_in_use = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Capture_webcam(Env &env, Gui::Area area, bool auto_area, bool flip, uint8_t fps)
|
||||
:
|
||||
_env(env),
|
||||
@ -170,6 +221,24 @@ extern "C" void webcam_backend_config(struct webcam_config *config)
|
||||
config->height = capture->_area.h();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *malloc_libyuv(unsigned long size)
|
||||
{
|
||||
void * ptr = capture->libyuv_alloc(size);
|
||||
return ptr ? ptr : malloc(size);
|
||||
}
|
||||
|
||||
|
||||
static void free_libyuv(void *ptr)
|
||||
{
|
||||
bool freed = capture->libyuv_free(ptr);
|
||||
|
||||
if (!freed)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do not use type_init macro because of name mangling
|
||||
*/
|
||||
@ -185,4 +254,7 @@ extern "C" void _type_init_host_webcam_register_types(Env &env,
|
||||
|
||||
/* register webcam model, which will call webcam_backend_config() */
|
||||
_type_init_usb_webcam_register_types();
|
||||
|
||||
/* install own memory allocators for libyuv to apply dataspace caching */
|
||||
libyuv::libyuv_init(malloc_libyuv, free_libyuv);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user