Video frame pool: allocator as a parameter

This commit is contained in:
Martin Pulec
2021-01-07 11:43:49 +01:00
parent 9e67b0904d
commit dcdd7d1a9a
8 changed files with 36 additions and 23 deletions

View File

@@ -38,18 +38,18 @@
#include "video_frame_pool.h" #include "video_frame_pool.h"
void *video_frame_pool_init(struct video_desc desc, int len) { void *video_frame_pool_init(struct video_desc desc, int len) {
auto out = new video_frame_pool<default_data_allocator>(len); auto *out = new video_frame_pool(len, default_data_allocator());
out->reconfigure(desc); out->reconfigure(desc);
return (void *) out; return (void *) out;
} }
struct video_frame *video_frame_pool_get_disposable_frame(void *state) { struct video_frame *video_frame_pool_get_disposable_frame(void *state) {
auto s = static_cast<video_frame_pool<default_data_allocator>* >(state); auto *s = static_cast<video_frame_pool* >(state);
return s->get_disposable_frame(); return s->get_disposable_frame();
} }
void video_frame_pool_destroy(void *state) { void video_frame_pool_destroy(void *state) {
auto s = static_cast<video_frame_pool<default_data_allocator>* >(state); auto *s = static_cast<video_frame_pool* >(state);
delete s; delete s;
} }

View File

@@ -54,16 +54,26 @@
#include <queue> #include <queue>
#include <stdexcept> #include <stdexcept>
struct default_data_allocator { struct video_frame_pool_allocator {
void *allocate(size_t size) { virtual void *allocate(size_t size) = 0;
virtual void deallocate(void *ptr) = 0;
virtual struct video_frame_pool_allocator *clone() const = 0;
virtual ~video_frame_pool_allocator() {}
};
struct default_data_allocator : public video_frame_pool_allocator {
void *allocate(size_t size) override {
return malloc(size); return malloc(size);
} }
void deallocate(void *ptr) { void deallocate(void *ptr) override {
free(ptr); free(ptr);
} }
struct video_frame_pool_allocator *clone() const override {
return new default_data_allocator(*this);
}
}; };
template <typename allocator>
struct video_frame_pool { struct video_frame_pool {
public: public:
/** /**
@@ -72,7 +82,7 @@ struct video_frame_pool {
* is called and that number of frames * is called and that number of frames
* is unreturned, get_frames() will block. * is unreturned, get_frames() will block.
*/ */
video_frame_pool(unsigned int max_used_frames = 0) : m_generation(0), m_desc(), m_max_data_len(0), m_unreturned_frames(0), m_max_used_frames(max_used_frames) { video_frame_pool(unsigned int max_used_frames = 0, video_frame_pool_allocator const &alloc = default_data_allocator()) : m_allocator(alloc.clone()), m_generation(0), m_desc(), m_max_data_len(0), m_unreturned_frames(0), m_max_used_frames(max_used_frames) {
} }
virtual ~video_frame_pool() { virtual ~video_frame_pool() {
@@ -116,7 +126,7 @@ struct video_frame_pool {
ret = vf_alloc_desc(m_desc); ret = vf_alloc_desc(m_desc);
for (unsigned int i = 0; i < m_desc.tile_count; ++i) { for (unsigned int i = 0; i < m_desc.tile_count; ++i) {
ret->tiles[i].data = (char *) ret->tiles[i].data = (char *)
m_allocator.allocate(m_max_data_len); m_allocator->allocate(m_max_data_len);
if (ret->tiles[i].data == NULL) { if (ret->tiles[i].data == NULL) {
throw std::runtime_error("Cannot allocate data"); throw std::runtime_error("Cannot allocate data");
} }
@@ -165,8 +175,8 @@ struct video_frame_pool {
return out; return out;
} }
allocator & get_allocator() { video_frame_pool_allocator const & get_allocator() {
return m_allocator; return *m_allocator;
} }
private: private:
@@ -182,11 +192,12 @@ struct video_frame_pool {
if (frame == NULL) if (frame == NULL)
return; return;
for (unsigned int i = 0; i < frame->tile_count; ++i) { for (unsigned int i = 0; i < frame->tile_count; ++i) {
m_allocator.deallocate(frame->tiles[i].data); m_allocator->deallocate(frame->tiles[i].data);
} }
vf_free(frame); vf_free(frame);
} }
std::unique_ptr<video_frame_pool_allocator> m_allocator;
std::queue<struct video_frame *> m_free_frames; std::queue<struct video_frame *> m_free_frames;
std::mutex m_lock; std::mutex m_lock;
std::condition_variable m_frame_returned; std::condition_variable m_frame_returned;
@@ -194,7 +205,6 @@ struct video_frame_pool {
struct video_desc m_desc; struct video_desc m_desc;
size_t m_max_data_len; size_t m_max_data_len;
unsigned int m_unreturned_frames; unsigned int m_unreturned_frames;
allocator m_allocator;
unsigned int m_max_used_frames; unsigned int m_max_used_frames;
}; };
#endif // __cplusplus #endif // __cplusplus

View File

@@ -161,7 +161,7 @@ class vidcap_state_aja {
uint32_t mVideoBufferSize{}; /// My video buffer size, in bytes uint32_t mVideoBufferSize{}; /// My video buffer size, in bytes
uint32_t mAudioBufferSize{}; /// My audio buffer size, in bytes uint32_t mAudioBufferSize{}; /// My audio buffer size, in bytes
thread mProducerThread; /// My producer thread object -- does the frame capturing thread mProducerThread; /// My producer thread object -- does the frame capturing
video_frame_pool<aligned_data_allocator> mPool; video_frame_pool mPool;
shared_ptr<video_frame> mOutputFrame; shared_ptr<video_frame> mOutputFrame;
shared_ptr<uint32_t> mOutputAudioFrame; shared_ptr<uint32_t> mOutputAudioFrame;
size_t mOutputAudioFrameSize{}; size_t mOutputAudioFrameSize{};

View File

@@ -96,7 +96,7 @@ struct state_video_compress_j2k {
struct cmpto_j2k_enc_cfg *enc_settings{}; struct cmpto_j2k_enc_cfg *enc_settings{};
long long int rate; ///< bitrate in bits per second long long int rate; ///< bitrate in bits per second
int mct; // force use of mct - -1 means default int mct; // force use of mct - -1 means default
video_frame_pool<default_data_allocator> pool; ///< pool for frames allocated by us but not yet consumed by encoder video_frame_pool pool; ///< pool for frames allocated by us but not yet consumed by encoder
unsigned int max_in_frames; ///< max number of frames between push and pop unsigned int max_in_frames; ///< max number of frames between push and pop
unsigned int in_frames{}; ///< number of currently encoding frames unsigned int in_frames{}; ///< number of currently encoding frames
mutex lock; mutex lock;

View File

@@ -56,8 +56,8 @@ using namespace std;
namespace { namespace {
struct cuda_buffer_data_allocator { struct cuda_buffer_data_allocator : public video_frame_pool_allocator {
void *allocate(size_t size) { void *allocate(size_t size) override {
void *ptr; void *ptr;
if (CUDA_WRAPPER_SUCCESS != cuda_wrapper_malloc_host(&ptr, if (CUDA_WRAPPER_SUCCESS != cuda_wrapper_malloc_host(&ptr,
size)) { size)) {
@@ -65,9 +65,12 @@ struct cuda_buffer_data_allocator {
} }
return ptr; return ptr;
} }
void deallocate(void *ptr) { void deallocate(void *ptr) override {
cuda_wrapper_free(ptr); cuda_wrapper_free(ptr);
} }
video_frame_pool_allocator *clone() const override {
return new cuda_buffer_data_allocator(*this);
}
}; };
struct state_video_compress_cuda_dxt { struct state_video_compress_cuda_dxt {
@@ -81,7 +84,7 @@ struct state_video_compress_cuda_dxt {
codec_t out_codec; codec_t out_codec;
decoder_t decoder; decoder_t decoder;
video_frame_pool<cuda_buffer_data_allocator> pool; video_frame_pool pool{0, cuda_buffer_data_allocator()};
}; };
static void cuda_dxt_compress_done(struct module *mod); static void cuda_dxt_compress_done(struct module *mod);

View File

@@ -79,7 +79,7 @@ struct state_video_compress_rtdxt {
struct gl_context gl_context; struct gl_context gl_context;
video_frame_pool<default_data_allocator> pool; video_frame_pool pool;
}; };
static int configure_with(struct state_video_compress_rtdxt *s, struct video_frame *frame); static int configure_with(struct state_video_compress_rtdxt *s, struct video_frame *frame);

View File

@@ -87,7 +87,7 @@ private:
int m_device_id; int m_device_id;
struct gpujpeg_encoder *m_encoder; struct gpujpeg_encoder *m_encoder;
struct video_desc m_saved_desc; struct video_desc m_saved_desc;
video_frame_pool<default_data_allocator> m_pool; video_frame_pool m_pool;
decoder_t m_decoder; decoder_t m_decoder;
codec_t m_enc_input_codec{}; codec_t m_enc_input_codec{};
unique_ptr<char []> m_decoded; unique_ptr<char []> m_decoded;

View File

@@ -124,7 +124,7 @@ struct state_video_compress_uyvy {
int gl_format; int gl_format;
video_frame_pool<default_data_allocator> *pool; video_frame_pool *pool;
}; };
int uyvy_configure_with(struct state_video_compress_uyvy *s, struct video_frame *tx); int uyvy_configure_with(struct state_video_compress_uyvy *s, struct video_frame *tx);
@@ -156,7 +156,7 @@ struct module * uyvy_compress_init(struct module *parent, const char *)
gl_context_make_current(NULL); gl_context_make_current(NULL);
s->pool = new video_frame_pool<default_data_allocator>(); s->pool = new video_frame_pool();
module_init_default(&s->module_data); module_init_default(&s->module_data);
s->module_data.cls = MODULE_CLASS_DATA; s->module_data.cls = MODULE_CLASS_DATA;