Wrap some video_frame occurences by shared_ptr

This should replace .dispose member in video_frame in future.
This commit is contained in:
Martin Pulec
2014-09-17 09:59:26 +02:00
parent 5a04368005
commit 607d1df324
38 changed files with 241 additions and 421 deletions

View File

@@ -100,18 +100,16 @@ static void *worker(void *arg)
free_message(msg);
}
compress_frame(s->compress, frame.get());
struct video_frame *tx_frame =
compress_frame(s->compress, frame);
shared_ptr<video_frame> tx_frame =
compress_pop(s->compress);
if(tx_frame) {
tx_send(s->tx, tx_frame, s->network_device);
if (tx_frame) {
tx_send(s->tx, tx_frame.get(), s->network_device);
} else {
fprintf(stderr, "Compress failed\n");
}
VIDEO_FRAME_DISPOSE(tx_frame);
frames += 1;
gettimeofday(&t, NULL);
double seconds = tv_diff(t, t0);

View File

@@ -91,6 +91,7 @@
#include "audio/utils.h"
#include <iostream>
#include <memory>
#include <string>
#ifdef USE_MTRACE
@@ -284,12 +285,6 @@ static void usage(void)
printf("\n");
}
static void uncompressed_frame_dispose(struct video_frame *frame)
{
struct wait_obj *wait_obj = (struct wait_obj *) frame->dispose_udata;
wait_obj_notify(wait_obj);
}
/**
* This function captures video and possibly compresses it.
* It then delegates sending to another thread.
@@ -314,16 +309,19 @@ static void *capture_thread(void *arg)
}
//tx_frame = vf_get_copy(tx_frame);
bool wait_for_cur_uncompressed_frame;
shared_ptr<video_frame> frame;
if (!tx_frame->dispose) {
tx_frame->dispose = uncompressed_frame_dispose;
tx_frame->dispose_udata = wait_obj;
wait_obj_reset(wait_obj);
wait_for_cur_uncompressed_frame = true;
frame = shared_ptr<video_frame>(tx_frame, [wait_obj](struct video_frame *) {
wait_obj_notify(wait_obj);
});
} else {
wait_for_cur_uncompressed_frame = false;
frame = shared_ptr<video_frame>(tx_frame, tx_frame->dispose);
}
uv->state_video_rxtx->send(tx_frame);
uv->state_video_rxtx->send(move(frame)); // std::move really important here (!)
// wait for frame frame to be processed, eg. by compress
// or sender (uncompressed video). Grab invalidates previous frame

View File

@@ -42,11 +42,12 @@
#ifdef __cplusplus
#include <map>
#include <memory>
struct video_frame;
struct fec {
virtual struct video_frame *encode(struct video_frame *) = 0;
virtual std::shared_ptr<video_frame> encode(std::shared_ptr<video_frame>) = 0;
virtual void decode(const char *in, int in_len, char **out, int *len,
const std::map<int, int> &) = 0;
virtual ~fec() {}

View File

@@ -382,21 +382,19 @@ ldgm::ldgm(int packet_size, int frame_size, double max_expected_loss)
init(k, m, c);
}
static void ldgm_encoder_dispose_buffer(struct video_frame *frame)
shared_ptr<video_frame> ldgm::encode(shared_ptr<video_frame> tx_frame)
{
for (unsigned int i = 0; i < frame->tile_count; ++i) {
static_cast<ldgm *>(frame->dispose_udata)->freeBuffer(frame->tiles[i].data);
}
vf_free(frame);
}
struct video_frame *ldgm::encode(struct video_frame *tx_frame)
{
struct video_frame *out = vf_alloc_desc(video_desc_from_frame(tx_frame));
shared_ptr<video_frame> out(vf_alloc_desc(video_desc_from_frame(tx_frame.get())),
[this](struct video_frame *frame) {
for (unsigned int i = 0; i < frame->tile_count; ++i) {
freeBuffer(frame->tiles[i].data);
}
vf_free(frame);
});
for (unsigned int i = 0; i < tx_frame->tile_count; ++i) {
video_payload_hdr_t video_hdr;
format_video_header(tx_frame, i, 0, video_hdr);
format_video_header(tx_frame.get(), i, 0, video_hdr);
int out_size;
char *output = m_coding_session->encode_hdr_frame((char *) video_hdr, sizeof(video_hdr),
@@ -412,8 +410,6 @@ struct video_frame *ldgm::encode(struct video_frame *tx_frame)
out->fec_params.c = m_c;
out->fec_params.seed = m_seed;
out->fec_params.symbol_size = m_coding_session->get_packet_size();
out->dispose = ldgm_encoder_dispose_buffer;
out->dispose_udata = this;
return out;
}

View File

@@ -53,7 +53,7 @@ struct ldgm : public fec{
ldgm(unsigned int k, unsigned int m, unsigned int c, unsigned int seed);
ldgm(int packet_size, int frame_size, double max_expected_loss);
ldgm(const char *cfg);
struct video_frame *encode(struct video_frame *);
std::shared_ptr<video_frame> encode(std::shared_ptr<video_frame>);
void decode(const char *in, int in_len, char **out, int *len,
const std::map<int, int> &);
void freeBuffer(char *buffer);

View File

@@ -248,7 +248,7 @@ struct state_video_decoder
* has been processed and we can write to a new one */
pthread_cond_t buffer_swapped_cv; ///< condition variable associated with @ref buffer_swapped
unique_ptr<message_queue> decompress_queue;
unique_ptr<message_queue<>> decompress_queue;
codec_t out_codec;
// display or postprocessor
@@ -262,7 +262,7 @@ struct state_video_decoder
int pp_output_frames_count;
/// @}
unique_ptr<message_queue> fec_queue;
unique_ptr<message_queue<>> fec_queue;
enum video_mode video_mode; ///< video mode set for this decoder
unsigned merged_fb:1; ///< flag if the display device driver requires tiled video or not
@@ -275,7 +275,7 @@ struct state_video_decoder
/// @}
timed_message slow_msg; ///< shows warning ony in certain interval
message_queue msg_queue;
message_queue<> msg_queue;
struct openssl_decrypt *decrypt; ///< decrypt state
@@ -648,8 +648,8 @@ struct state_video_decoder *video_decoder_init(struct module *parent,
s->buffer_swapped = true;
s->last_buffer_number = -1;
s->decompress_queue = unique_ptr<message_queue>(new message_queue(1));
s->fec_queue = unique_ptr<message_queue>(new message_queue(1));
s->decompress_queue = unique_ptr<message_queue<>>(new message_queue<>(1));
s->fec_queue = unique_ptr<message_queue<>>(new message_queue<>(1));
if (encryption) {
if(openssl_decrypt_init(&s->decrypt,

View File

@@ -167,6 +167,8 @@ struct video_frame {
* Can be called from arbitrary thread.
* @note
* Can be changed only by frame originator.
* @deprecated
* Should not be longer used. Suggested replacement is with shared pointers with custom deleter.
*/
void (*dispose)(struct video_frame *);
/**
@@ -174,6 +176,8 @@ struct video_frame {
*
* @note
* Can be changed only by frame originator.
* @deprecated
* Should not be longer used. Suggested replacement is with shared pointers with custom deleter.
*/
void *dispose_udata;
/**

View File

@@ -39,56 +39,8 @@
#include "config_unix.h"
#include "config_win32.h"
#include "utils/lock_guard.h"
#define NO_EXTERN_MSGQ_MSG
#include "utils/message_queue.h"
message_queue::message_queue(int max_len) :
m_max_len(max_len)
{
pthread_mutex_init(&m_lock, NULL);
pthread_cond_init(&m_queue_incremented, NULL);
pthread_cond_init(&m_queue_decremented, NULL);
}
message_queue::~message_queue()
{
pthread_mutex_destroy(&m_lock);
pthread_cond_destroy(&m_queue_incremented);
pthread_cond_destroy(&m_queue_decremented);
}
int message_queue::size()
{
lock_guard guard(m_lock);
return m_queue.size();
}
void message_queue::push(msg *message)
{
lock_guard guard(m_lock);
if (m_max_len != -1) {
while (m_queue.size() >= (unsigned int) m_max_len) {
pthread_cond_wait(&m_queue_decremented, &m_lock);
}
}
m_queue.push(message);
pthread_cond_signal(&m_queue_incremented);
}
msg *message_queue::pop(bool nonblocking)
{
lock_guard guard(m_lock);
if (m_queue.size() == 0 && nonblocking) {
return NULL;
}
while (m_queue.size() == 0) {
pthread_cond_wait(&m_queue_incremented, &m_lock);
}
msg *ret = m_queue.front();
m_queue.pop();
pthread_cond_signal(&m_queue_decremented);
return ret;
}
template class message_queue<msg *>;

View File

@@ -38,31 +38,74 @@
#ifndef MESSAGE_QUEUE_H_
#define MESSAGE_QUEUE_H_
#include <condition_variable>
#include <mutex>
#include <queue>
struct msg {
virtual ~msg() {}
};
// some common messages
struct msg_quit : public msg {};
template<typename T = struct msg *>
class message_queue {
public:
message_queue(int max_len = -1);
virtual ~message_queue();
int size();
void push(msg *);
msg *pop(bool nonblocking = false);
message_queue(int max_len = -1) :
m_max_len(max_len)
{
}
virtual ~message_queue()
{
}
int size()
{
std::unique_lock<std::mutex> l(m_lock);
return m_queue.size();
}
void push(T const & message)
{
std::unique_lock<std::mutex> l(m_lock);
if (m_max_len != -1) {
m_queue_decremented.wait(l, [this]{return m_queue.size() < (unsigned int) m_max_len;});
}
m_queue.push(message);
l.unlock();
m_queue_incremented.notify_one();
}
T pop(bool nonblocking = false)
{
std::unique_lock<std::mutex> l(m_lock);
if (m_queue.size() == 0 && nonblocking) {
return T();
}
m_queue_incremented.wait(l, [this]{return m_queue.size() > 0;});
T ret = m_queue.front();
m_queue.pop();
l.unlock();
m_queue_decremented.notify_one();
return ret;
}
private:
int m_max_len;
std::queue<msg *> m_queue;
pthread_mutex_t m_lock;
pthread_cond_t m_queue_decremented;
pthread_cond_t m_queue_incremented;
int m_max_len;
std::queue<T> m_queue;
std::mutex m_lock;
std::condition_variable m_queue_decremented;
std::condition_variable m_queue_incremented;
};
#ifndef NO_EXTERN_MSGQ_MSG
extern template class message_queue<msg *>;
#endif
#endif // MESSAGE_QUEUE_H_

View File

@@ -130,118 +130,45 @@ void vf_split_horizontal(struct video_frame *out, struct video_frame *src,
}
}
#include "utils/wait_obj.h"
using namespace std;
namespace {
struct dispose_original_frame_udata {
dispose_original_frame_udata(struct video_frame *original_frame) :
m_disposed(0u),
m_original_frame(original_frame) {
pthread_mutex_init(&m_lock, NULL);
}
~dispose_original_frame_udata() {
pthread_mutex_destroy(&m_lock);
}
static void dispose_tile(struct video_frame *frame) {
struct dispose_original_frame_udata *inst =
(struct dispose_original_frame_udata *) frame->dispose_udata;
pthread_mutex_lock(&inst->m_lock);
inst->m_disposed++;
if (inst->m_disposed == inst->m_original_frame->tile_count) {
VIDEO_FRAME_DISPOSE(inst->m_original_frame);
pthread_mutex_unlock(&inst->m_lock);
delete inst;
} else {
pthread_mutex_unlock(&inst->m_lock);
}
vf_free(frame);
}
pthread_mutex_t m_lock;
unsigned int m_disposed;
struct video_frame *m_original_frame;
};
} // end of anonymous namespace
vector<struct video_frame *> vf_separate_tiles(struct video_frame *frame)
vector<shared_ptr<video_frame>> vf_separate_tiles(shared_ptr<video_frame> frame)
{
vector<struct video_frame *> ret(frame->tile_count, 0);
struct video_desc desc = video_desc_from_frame(frame);
vector<shared_ptr<video_frame>> ret(frame->tile_count, 0);
struct video_desc desc = video_desc_from_frame(frame.get());
desc.tile_count = 1;
struct dispose_original_frame_udata *udata =
new dispose_original_frame_udata(frame);
for (unsigned int i = 0; i < frame->tile_count; ++i) {
ret[i] = vf_alloc_desc(desc);
auto holder = new shared_ptr<video_frame>(frame);
ret[i] = shared_ptr<video_frame>(vf_alloc_desc(desc), [holder](struct video_frame *frame) {
delete holder;
vf_free(frame);
});
ret[i]->tiles[0].data_len = frame->tiles[i].data_len;
ret[i]->tiles[0].data = frame->tiles[i].data;
ret[i]->dispose = dispose_original_frame_udata::dispose_tile;
ret[i]->dispose_udata = udata;
}
return ret;
}
namespace {
struct separate_tiles_dispose_udata {
separate_tiles_dispose_udata(size_t max_count) : m_count(0) {
m_dispose = (void (**)(struct video_frame *frame)) calloc(max_count,
sizeof(void (*)(struct video_frame *frame)));
m_frame = (struct video_frame **) calloc(max_count, sizeof(struct video_frame *));
}
~separate_tiles_dispose_udata() {
free((void *) m_dispose);
free(m_frame);
}
void add(struct video_frame *frame) {
m_dispose[m_count] = frame->dispose;
m_frame[m_count] = frame;
m_count++;
}
void (**m_dispose)(struct video_frame *frame);
struct video_frame **m_frame;
size_t m_count;
};
void separate_tiles_dispose(struct video_frame *frame) {
struct separate_tiles_dispose_udata *dispose_udata =
(struct separate_tiles_dispose_udata *) frame->dispose_udata;
for (size_t i = 0; i < dispose_udata->m_count; i++) {
dispose_udata->m_dispose[i](dispose_udata->m_frame[i]);
}
delete dispose_udata;
vf_free(frame);
}
} // end of anonymous namespace
struct video_frame * vf_merge_tiles(std::vector<struct video_frame *> const & tiles)
shared_ptr<video_frame> vf_merge_tiles(std::vector<shared_ptr<video_frame>> const & tiles)
{
struct video_desc desc = video_desc_from_frame(tiles[0]);
struct video_desc desc = video_desc_from_frame(tiles[0].get());
desc.tile_count = tiles.size();
struct video_frame *ret = vf_alloc_desc(desc);
struct separate_tiles_dispose_udata *udata =
new separate_tiles_dispose_udata(tiles.size());
auto holder = new decay<decltype(tiles)>::type(tiles);
shared_ptr<video_frame> ret(vf_alloc_desc(desc),
[holder](struct video_frame *frame) {
delete holder;
vf_free(frame);
});
for (unsigned int i = 0; i < tiles.size(); ++i) {
ret->tiles[i].data = tiles[i]->tiles[0].data;
ret->tiles[i].data_len = tiles[i]->tiles[0].data_len;
if (tiles[i]->dispose) {
udata->add(tiles[i]);
}
}
ret->dispose = separate_tiles_dispose;
ret->dispose_udata = udata;
return ret;
}

View File

@@ -75,10 +75,11 @@ void vf_split_horizontal(struct video_frame *out, struct video_frame *src,
#endif
#ifdef __cplusplus
#include <memory>
#include <vector>
std::vector<struct video_frame *> vf_separate_tiles(struct video_frame *frame);
struct video_frame * vf_merge_tiles(std::vector<struct video_frame *> const & tiles);
std::vector<std::shared_ptr<video_frame>> vf_separate_tiles(std::shared_ptr<video_frame> frame);
std::shared_ptr<video_frame> vf_merge_tiles(std::vector<std::shared_ptr<video_frame>> const & tiles);
#endif // __cplusplus

View File

@@ -50,6 +50,7 @@
#include "utils/lock_guard.h"
#include <iostream>
#include <memory>
#include <queue>
#include <stdexcept>
@@ -62,29 +63,8 @@ struct default_data_allocator {
}
};
struct auto_video_frame_disposer {
auto_video_frame_disposer(struct video_frame *frame) :
m_frame(frame) {
}
~auto_video_frame_disposer() {
VIDEO_FRAME_DISPOSE(m_frame);
}
struct video_frame *m_frame;
};
template <typename allocator>
struct video_frame_pool {
struct vf_udata {
vf_udata(struct video_frame_pool<allocator> &pool,
int generation) : m_pool(pool), m_generation(generation) {
}
struct video_frame_pool<allocator> &m_pool;
int m_generation;
};
public:
video_frame_pool() : m_generation(0), m_desc(), m_max_data_len(0) {
pthread_mutex_init(&m_lock, NULL);
@@ -103,7 +83,7 @@ struct video_frame_pool {
m_generation++;
}
struct video_frame *get_frame() {
std::shared_ptr<video_frame> get_frame() {
assert(m_generation != 0);
struct video_frame *ret = NULL;
lock_guard guard(m_lock);
@@ -121,32 +101,21 @@ struct video_frame_pool {
}
ret->tiles[i].data_len = m_max_data_len;
}
ret->dispose_udata = new vf_udata(*this, m_generation);
ret->dispose = video_frame_pool<allocator>::dispose;
} catch (std::exception &e) {
std::cerr << e.what() << std::endl;
deallocate_frame(ret);
throw e;
}
}
return ret;
}
return std::shared_ptr<video_frame>(ret, std::bind([this](struct video_frame *frame, int generation) {
lock_guard guard(m_lock);
static void dispose(struct video_frame *frame) {
struct vf_udata *udata = (struct vf_udata *) frame->dispose_udata;
udata->m_pool.put_frame(frame);
}
void put_frame(struct video_frame *frame) {
struct vf_udata *udata = (struct vf_udata *) frame->dispose_udata;
lock_guard guard(m_lock);
if (udata->m_generation != m_generation) {
deallocate_frame(frame);
} else {
m_free_frames.push(frame);
}
if (this->m_generation != generation) {
deallocate_frame(frame);
} else {
m_free_frames.push(frame);
}
}, std::placeholders::_1, m_generation));
}
allocator & get_allocator() {
@@ -165,11 +134,9 @@ struct video_frame_pool {
void deallocate_frame(struct video_frame *frame) {
if (frame == NULL)
return;
struct vf_udata *udata = (struct vf_udata *) frame->dispose_udata;
for (unsigned int i = 0; i < frame->tile_count; ++i) {
m_allocator.deallocate(frame->tiles[i].data);
}
delete udata;
vf_free(frame);
}

View File

@@ -107,12 +107,7 @@ struct compress_state_real {
unsigned int state_count; ///< count of compress states (equal to tiles' count)
char compress_options[1024]; ///< compress options (for reconfiguration)
message_queue *queue;
};
struct msg_frame : public msg {
msg_frame(struct video_frame *f) : frame(f) {}
struct video_frame *frame;
message_queue<shared_ptr<video_frame>> *queue;
};
}
@@ -136,8 +131,8 @@ typedef struct compress_state compress_state_proxy; ///< Used to emphasize that
struct module compress_init_noerr;
static void init_compressions(void);
static struct video_frame *compress_frame_tiles(struct compress_state_real *s, struct video_frame *frame,
struct module *parent);
static shared_ptr<video_frame> compress_frame_tiles(struct compress_state_real *s,
shared_ptr<video_frame> frame, struct module *parent);
static int compress_init_real(struct module *parent, const char *config_string,
struct compress_state_real **state);
static void compress_done_real(struct compress_state_real *s);
@@ -451,7 +446,7 @@ static int compress_init_real(struct module *parent, const char *config_string,
memset(&params, 0, sizeof(params));
s = (struct compress_state_real *) calloc(1, sizeof(struct compress_state_real));
s->queue = new message_queue(1);
s->queue = new message_queue<shared_ptr<video_frame>>(1);
s->state_count = 1;
@@ -518,15 +513,15 @@ const char *get_compress_name(compress_state_proxy *proxy)
* @param frame uncompressed frame to be compressed
* @return compressed frame, may be NULL if compression failed
*/
void compress_frame(compress_state_proxy *proxy, struct video_frame *frame)
void compress_frame(compress_state_proxy *proxy, shared_ptr<video_frame> frame)
{
if (!proxy)
abort();
struct compress_state_real *s = proxy->ptr;
if (frame == NULL) { // pass poisoned pill
s->queue->push(new msg_frame(NULL));
if (!frame) { // pass poisoned pill
s->queue->push(shared_ptr<video_frame>());
return;
}
@@ -535,23 +530,22 @@ void compress_frame(compress_state_proxy *proxy, struct video_frame *frame)
compress_process_message(proxy, msg);
}
struct video_frame *sync_api_frame;
shared_ptr<video_frame> sync_api_frame;
if(s->handle->compress_frame_func) {
sync_api_frame = s->handle->compress_frame_func(s->state[0], frame);
} else if(s->handle->compress_tile_func) {
sync_api_frame = compress_frame_tiles(s, frame, &proxy->mod);
} else {
sync_api_frame = NULL;
sync_api_frame = {};
}
// NULL has special meaning - it is poisoned pill so we must
// prevent passing it further
if (sync_api_frame == NULL) {
// empty return value here represents error, but we don't want to pass it to queue, since it would
// be interpreted as poisoned pill
if (!sync_api_frame) {
return;
}
msg_frame *frame_msg = new msg_frame(sync_api_frame);
s->queue->push(frame_msg);
s->queue->push(sync_api_frame);
}
/**
@@ -564,10 +558,10 @@ void compress_frame(compress_state_proxy *proxy, struct video_frame *frame)
*/
struct compress_worker_data {
struct module *state; ///< compress driver status
struct video_frame *frame; ///< uncompressed tile to be compressed
shared_ptr<video_frame> frame; ///< uncompressed tile to be compressed
compress_tile_t callback; ///< tile compress callback
void *ret; ///< OUT - returned compressed tile, NULL if failed
shared_ptr<video_frame> ret; ///< OUT - returned compressed tile, NULL if failed
};
/**
@@ -576,7 +570,7 @@ struct compress_worker_data {
* @return @ref compress_worker_data (same as input)
*/
static void *compress_tile_callback(void *arg) {
struct compress_worker_data *s = (struct compress_worker_data *) arg;
compress_worker_data *s = (compress_worker_data *) arg;
s->ret = s->callback(s->state, s->frame);
@@ -591,8 +585,8 @@ static void *compress_tile_callback(void *arg) {
* @param parent parent module (for the case when there is a need to reconfigure)
* @return compressed video frame, may be NULL if compression failed
*/
static struct video_frame *compress_frame_tiles(struct compress_state_real *s,
struct video_frame *frame, struct module *parent)
static shared_ptr<video_frame> compress_frame_tiles(struct compress_state_real *s,
shared_ptr<video_frame> frame, struct module *parent)
{
struct video_compress_params params;
memset(&params, 0, sizeof(params));
@@ -611,11 +605,11 @@ static struct video_frame *compress_frame_tiles(struct compress_state_real *s,
task_result_handle_t task_handle[frame->tile_count];
vector<struct video_frame *> separate_tiles = vf_separate_tiles(frame);
vector<shared_ptr<video_frame>> separate_tiles = vf_separate_tiles(frame);
// frame pointer may no longer be valid
frame = NULL;
struct compress_worker_data data_tile[separate_tiles.size()];
vector <compress_worker_data> data_tile(separate_tiles.size());
for(unsigned int i = 0; i < separate_tiles.size(); ++i) {
struct compress_worker_data *data = &data_tile[i];
data->state = s->state[i];
@@ -625,7 +619,7 @@ static struct video_frame *compress_frame_tiles(struct compress_state_real *s,
task_handle[i] = task_run_async(compress_tile_callback, data);
}
vector<struct video_frame *> compressed_tiles(separate_tiles.size(), nullptr);
vector<shared_ptr<video_frame>> compressed_tiles(separate_tiles.size(), nullptr);
bool failed = false;
for(unsigned int i = 0; i < separate_tiles.size(); ++i) {
@@ -636,13 +630,10 @@ static struct video_frame *compress_frame_tiles(struct compress_state_real *s,
failed = true;
}
compressed_tiles[i] = (struct video_frame *) data->ret;
compressed_tiles[i] = data->ret;
}
if (failed) {
for(unsigned int i = 0; i < separate_tiles.size(); ++i) {
VIDEO_FRAME_DISPOSE(compressed_tiles[i]);
}
return NULL;
}
@@ -686,20 +677,13 @@ static void compress_done_real(struct compress_state_real *s)
free(s);
}
struct video_frame *compress_pop(compress_state_proxy *proxy)
shared_ptr<video_frame> compress_pop(compress_state_proxy *proxy)
{
struct video_frame *ret = NULL;
if(!proxy)
return NULL;
struct compress_state_real *s = proxy->ptr;
msg *message = s->queue->pop();
msg_frame *frame_msg = dynamic_cast<msg_frame *>(message);
assert(frame_msg != NULL);
ret = frame_msg->frame;
delete frame_msg;
return ret;
return s->queue->pop();
}

View File

@@ -71,6 +71,23 @@ struct video_compress_params {
*/
typedef struct module *(*compress_init_t)(struct module *parent,
const struct video_compress_params *params);
typedef bool (*compress_is_supported_t)(void);
/// @}
void show_compress_help(void);
int compress_init(struct module *parent, const char *config_string, struct compress_state **);
const char *get_compress_name(struct compress_state *);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include <list>
#include <memory>
#include <string>
/**
* @brief Compresses video frame
*
@@ -81,7 +98,8 @@ typedef struct module *(*compress_init_t)(struct module *parent,
* same index.
* @return compressed frame, may be NULL if compression failed
*/
typedef struct video_frame * (*compress_frame_t)(struct module *state, struct video_frame *frame);
typedef std::shared_ptr<video_frame> (*compress_frame_t)(struct module *state, std::shared_ptr<video_frame> frame);
/**
* @brief Compresses tile of a video frame
*
@@ -93,26 +111,10 @@ typedef struct video_frame * (*compress_frame_t)(struct module *state, struct v
* same index.
* @return compressed frame with one tile, may be NULL if compression failed
*/
typedef struct video_frame * (*compress_tile_t)(struct module *state, struct video_frame *in_frame);
typedef std::shared_ptr<video_frame> (*compress_tile_t)(struct module *state, std::shared_ptr<video_frame> in_frame);
typedef bool (*compress_is_supported_t)(void);
/// @}
void compress_frame(struct compress_state *, std::shared_ptr<video_frame>);
void show_compress_help(void);
int compress_init(struct module *parent, const char *config_string, struct compress_state **);
const char *get_compress_name(struct compress_state *);
void compress_frame(struct compress_state *, struct video_frame*);
struct video_frame *compress_pop(struct compress_state *);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include <list>
#include <string>
struct compress_preset {
struct compress_prop {
int latency; // ms
@@ -128,6 +130,8 @@ struct compress_preset {
};
std::list<compress_preset> get_compress_capabilities();
std::shared_ptr<video_frame> compress_pop(struct compress_state *);
#endif
#endif /* __video_compress_h */

View File

@@ -53,6 +53,8 @@
#include "video.h"
#include "video_compress.h"
using namespace std;
struct cuda_buffer_data_allocator {
void *allocate(size_t size) {
void *ptr;
@@ -181,19 +183,17 @@ static bool configure_with(struct state_video_compress_cuda_dxt *s, struct video
return true;
}
struct video_frame *cuda_dxt_compress_tile(struct module *mod, struct video_frame *tx)
shared_ptr<video_frame> cuda_dxt_compress_tile(struct module *mod, shared_ptr<video_frame> tx)
{
auto_video_frame_disposer tx_disposer(tx);
struct state_video_compress_cuda_dxt *s =
(struct state_video_compress_cuda_dxt *) mod->priv_data;
cuda_wrapper_set_device(cuda_devices[0]);
if (!video_desc_eq_excl_param(video_desc_from_frame(tx),
if (!video_desc_eq_excl_param(video_desc_from_frame(tx.get()),
s->saved_desc, PARAM_TILE_COUNT)) {
if(configure_with(s, video_desc_from_frame(tx))) {
s->saved_desc = video_desc_from_frame(tx);
if(configure_with(s, video_desc_from_frame(tx.get()))) {
s->saved_desc = video_desc_from_frame(tx.get());
} else {
fprintf(stderr, "[CUDA DXT] Reconfiguration failed!\n");
return NULL;
@@ -260,13 +260,12 @@ struct video_frame *cuda_dxt_compress_tile(struct module *mod, struct video_fram
return NULL;
}
struct video_frame *out = s->pool.get_frame();
shared_ptr<video_frame> out = s->pool.get_frame();
if (cuda_wrapper_memcpy(out->tiles[0].data,
s->cuda_out_buffer,
out->tiles[0].data_len,
CUDA_WRAPPER_MEMCPY_DEVICE_TO_HOST) != CUDA_WRAPPER_SUCCESS) {
fprintf(stderr, "Memcpy failed: %s\n", cuda_wrapper_last_error_string());
VIDEO_FRAME_DISPOSE(out);
return NULL;
}

View File

@@ -37,20 +37,14 @@
#include "types.h"
#define JPEG_TO_DXT_MAGIC 0x20BF0088
#include <memory>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define JPEG_TO_DXT_MAGIC 0x20BF0088
struct module;
struct video_compress_params;
struct module *cuda_dxt_compress_init(struct module *parent,
const struct video_compress_params *parms);
struct video_frame *cuda_dxt_compress_tile(struct module *mod, struct video_frame *tx);
#ifdef __cplusplus
}
#endif // __cplusplus
std::shared_ptr<video_frame> cuda_dxt_compress_tile(struct module *mod, std::shared_ptr<video_frame> tx);

View File

@@ -260,10 +260,8 @@ struct module *dxt_glsl_compress_init(struct module *parent, const struct video_
return &s->module_data;
}
struct video_frame * dxt_glsl_compress(struct module *mod, struct video_frame * tx)
shared_ptr<video_frame> dxt_glsl_compress(struct module *mod, shared_ptr<video_frame> tx)
{
auto_video_frame_disposer tx_frame_disposer(tx);
struct state_video_compress_rtdxt *s = (struct state_video_compress_rtdxt *) mod->priv_data;
int i;
unsigned char *line1, *line2;
@@ -274,16 +272,16 @@ struct video_frame * dxt_glsl_compress(struct module *mod, struct video_frame *
if(!s->configured) {
int ret;
ret = configure_with(s, tx);
ret = configure_with(s, tx.get());
if(!ret)
return NULL;
}
struct video_frame *out_frame = s->pool.get_frame();
shared_ptr<video_frame> out_frame = s->pool.get_frame();
for (x = 0; x < tx->tile_count; ++x) {
struct tile *in_tile = vf_get_tile(tx, x);
struct tile *out_tile = vf_get_tile(out_frame, x);
struct tile *in_tile = vf_get_tile(tx.get(), x);
struct tile *out_tile = vf_get_tile(out_frame.get(), x);
line1 = (unsigned char *) in_tile->data;
line2 = (unsigned char *) s->decoded.get();

View File

@@ -44,20 +44,14 @@
#include "config_win32.h"
#endif // HAVE_CONFIG_H
#include <memory>
struct video_frame;
struct module;
struct video_compres_params;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
struct module *dxt_glsl_compress_init(struct module *parent,
const struct video_compress_params *params);
struct video_frame *dxt_glsl_compress(struct module *mod, struct video_frame * tx);
std::shared_ptr<video_frame> dxt_glsl_compress(struct module *mod, std::shared_ptr<video_frame> tx);
bool dxt_is_supported(void);
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -324,14 +324,11 @@ struct module * jpeg_compress_init(struct module *parent, const struct video_com
return &s->module_data;
}
struct video_frame * jpeg_compress(struct module *mod, struct video_frame * tx)
shared_ptr<video_frame> jpeg_compress(struct module *mod, shared_ptr<video_frame> tx)
{
auto_video_frame_disposer tx_disposer(tx);
struct state_video_compress_jpeg *s = (struct state_video_compress_jpeg *) mod->priv_data;
int i;
unsigned char *line1, *line2;
struct video_frame *out;
unsigned int x;
@@ -339,30 +336,30 @@ struct video_frame * jpeg_compress(struct module *mod, struct video_frame * tx)
if(!s->encoder) {
int ret;
ret = configure_with(s, tx);
ret = configure_with(s, tx.get());
if(!ret) {
return NULL;
}
}
struct video_desc desc;
desc = video_desc_from_frame(tx);
desc = video_desc_from_frame(tx.get());
// if format changed, reconfigure
if(!video_desc_eq_excl_param(s->saved_desc, desc, PARAM_INTERLACING)) {
cleanup_state(s);
int ret;
ret = configure_with(s, tx);
ret = configure_with(s, tx.get());
if(!ret) {
return NULL;
}
}
out = s->pool.get_frame();
shared_ptr<video_frame> out = s->pool.get_frame();
for (x = 0; x < tx->tile_count; ++x) {
struct tile *in_tile = vf_get_tile(tx, x);
struct tile *out_tile = vf_get_tile(out, x);
struct tile *in_tile = vf_get_tile(tx.get(), x);
struct tile *out_tile = vf_get_tile(out.get(), x);
line1 = (unsigned char *) in_tile->data;
line2 = (unsigned char *) s->decoded.get();
@@ -394,8 +391,7 @@ struct video_frame * jpeg_compress(struct module *mod, struct video_frame * tx)
ret = gpujpeg_encoder_encode(s->encoder, &encoder_input, &compressed, &size);
if(ret != 0) {
VIDEO_FRAME_DISPOSE(out);
return NULL;
return {};
}
out_tile->data_len = size;

View File

@@ -44,9 +44,7 @@
#include "config_win32.h"
#endif // HAVE_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <memory>
struct module;
struct video_frame;
@@ -54,10 +52,6 @@ struct video_compress_params;
struct module *jpeg_compress_init(struct module *parent,
const struct video_compress_params *params);
struct video_frame *jpeg_compress(struct module *mod, struct video_frame * tx);
std::shared_ptr<video_frame> jpeg_compress(struct module *mod, std::shared_ptr<video_frame> tx);
bool jpeg_is_supported(void);
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -563,7 +563,7 @@ void *my_task(void *arg) {
return NULL;
}
struct video_frame *libavcodec_compress_tile(struct module *mod, struct video_frame *tx)
shared_ptr<video_frame> libavcodec_compress_tile(struct module *mod, shared_ptr<video_frame> tx)
{
struct state_video_compress_libav *s = (struct state_video_compress_libav *) mod->priv_data;
static int frame_seq = 0;
@@ -573,21 +573,20 @@ struct video_frame *libavcodec_compress_tile(struct module *mod, struct video_fr
AVPacket *pkt;
#endif
unsigned char *decoded;
struct video_frame *out = NULL;
shared_ptr<video_frame> out{};
platform_spin_lock(&s->spin);
if(!video_desc_eq_excl_param(video_desc_from_frame(tx),
if(!video_desc_eq_excl_param(video_desc_from_frame(tx.get()),
s->saved_desc, PARAM_TILE_COUNT)) {
cleanup(s);
int ret = configure_with(s, video_desc_from_frame(tx));
int ret = configure_with(s, video_desc_from_frame(tx.get()));
if(!ret) {
goto error;
}
}
out = vf_alloc_desc(s->compressed_desc);
out->dispose = libavcodec_vid_enc_frame_dispose;
out = shared_ptr<video_frame>(vf_alloc_desc(s->compressed_desc), libavcodec_vid_enc_frame_dispose);
#if LIBAVCODEC_VERSION_MAJOR >= 54
pkt = (AVPacket *) malloc(sizeof(AVPacket));
av_init_packet(pkt);
@@ -684,13 +683,9 @@ struct video_frame *libavcodec_compress_tile(struct module *mod, struct video_fr
platform_spin_unlock(&s->spin);
VIDEO_FRAME_DISPOSE(tx);
return out;
error:
VIDEO_FRAME_DISPOSE(tx);
VIDEO_FRAME_DISPOSE(out);
platform_spin_unlock(&s->spin);
return NULL;
}

View File

@@ -37,21 +37,16 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <memory>
struct module;
struct tile;
struct video_desc;
struct video_frame;
struct video_compress_params;
struct module *libavcodec_compress_init(struct module *parent,
const struct video_compress_params *params);
struct video_frame *libavcodec_compress_tile(struct module *mod, struct video_frame *tx);
std::shared_ptr<video_frame> libavcodec_compress_tile(struct module *mod, std::shared_ptr<video_frame> tx);
bool libavcodec_is_supported(void);
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -88,7 +88,7 @@ struct module * none_compress_init(struct module *parent, const struct video_com
return &s->module_data;
}
struct video_frame * none_compress(struct module *mod, struct video_frame * tx)
std::shared_ptr<video_frame> none_compress(struct module *mod, std::shared_ptr<video_frame> tx)
{
struct state_video_compress_none *s = (struct state_video_compress_none *) mod->priv_data;

View File

@@ -47,18 +47,12 @@
*
*/
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <memory>
struct module;
struct video_frame;
struct video_compress_params;
struct module *none_compress_init(struct module *parent, const struct video_compress_params *params);
struct video_frame *none_compress(struct module *mod, struct video_frame * tx);
#ifdef __cplusplus
}
#endif // __cplusplus
std::shared_ptr<video_frame> none_compress(struct module *mod, std::shared_ptr<video_frame> tx);

View File

@@ -58,6 +58,8 @@
#include "gl_context.h"
using namespace std;
static const char fp_display_rgba_to_yuv422_legacy[] =
"#define GL_legacy 1\n"
"#if GL_legacy\n"
@@ -269,24 +271,22 @@ int uyvy_configure_with(struct state_video_compress_uyvy *s, struct video_frame
return true;
}
struct video_frame * uyvy_compress(struct module *mod, struct video_frame * tx)
shared_ptr<video_frame> uyvy_compress(struct module *mod, shared_ptr<video_frame> tx)
{
auto_video_frame_disposer tx_disposer(tx);
struct state_video_compress_uyvy *s = (struct state_video_compress_uyvy *) mod->priv_data;
gl_context_make_current(&s->context);
if(!s->configured) {
int ret;
ret = uyvy_configure_with(s, tx);
ret = uyvy_configure_with(s, tx.get());
if(!ret)
return NULL;
}
assert(video_desc_eq(video_desc_from_frame(tx), s->saved_desc));
assert(video_desc_eq(video_desc_from_frame(tx.get()), s->saved_desc));
struct video_frame *out = s->pool->get_frame();
shared_ptr<video_frame> out = s->pool->get_frame();
struct tile *tile = &out->tiles[0];
glBindTexture(GL_TEXTURE_2D, s->texture_rgba);

View File

@@ -37,18 +37,12 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <memory>
struct module;
struct video_frame;
struct video_compress_params;
struct module *uyvy_compress_init(struct module *parent, const struct video_compress_params *params);
struct video_frame *uyvy_compress(struct module *mod, struct video_frame * tx);
#ifdef __cplusplus
}
#endif // __cplusplus
std::shared_ptr<video_frame> uyvy_compress(struct module *mod, std::shared_ptr<video_frame> tx);

View File

@@ -64,9 +64,9 @@ struct thread_data {
jpeg_decoder(0), desc(), out_codec(), ppb(), dxt_out_buff(0),
cuda_dev_index(-1)
{}
message_queue m_in;
message_queue<> m_in;
// currently only for output frames
message_queue m_out;
message_queue<> m_out;
struct gpujpeg_decoder *jpeg_decoder;
struct video_desc desc;

View File

@@ -66,6 +66,7 @@ extern "C" {
#define VIDEO_FRAME_DISPOSE(frame) if (frame && frame->dispose) \
frame->dispose(frame)
void video_frame_dispose(struct video_frame *);
/**
* @brief Allocates blank video frame

View File

@@ -177,7 +177,7 @@ const char *video_rxtx::get_name(enum rxtx_protocol proto) {
}
}
void video_rxtx::send(struct video_frame *frame) {
void video_rxtx::send(shared_ptr<video_frame> frame) {
compress_frame(m_compression, frame);
}
@@ -206,18 +206,16 @@ void *video_rxtx::sender_loop() {
while(1) {
check_sender_messages();
struct video_frame *tx_frame = NULL;
shared_ptr<video_frame> tx_frame;
tx_frame = compress_pop(m_compression);
if (!tx_frame)
goto exit;
video_export(m_video_exporter, tx_frame);
video_export(m_video_exporter, tx_frame.get());
if (!m_paused) {
send_frame(tx_frame);
} else {
VIDEO_FRAME_DISPOSE(tx_frame);
}
rtp_video_rxtx *rtp_rxtx = dynamic_cast<rtp_video_rxtx *>(this);

View File

@@ -40,6 +40,7 @@
#include <map>
#include <string>
#include <memory>
#include "module.h"
@@ -76,7 +77,7 @@ class video_rxtx {
public:
video_rxtx(std::map<std::string, param_u> const &);
virtual ~video_rxtx();
void send(struct video_frame *);
void send(std::shared_ptr<struct video_frame>);
static const char *get_name(enum rxtx_protocol);
static void *receiver_thread(void *arg) {
video_rxtx *rxtx = static_cast<video_rxtx *>(arg);
@@ -94,7 +95,7 @@ protected:
struct module m_receiver_mod;
int m_rxtx_mode;
private:
virtual void send_frame(struct video_frame *) = 0;
virtual void send_frame(std::shared_ptr<video_frame>) = 0;
virtual void *(*get_receiver_thread())(void *arg) = 0;
static void *sender_thread(void *args);
void *sender_loop();

View File

@@ -66,18 +66,17 @@ h264_rtp_video_rxtx::h264_rtp_video_rxtx(std::map<std::string, param_u> const &p
#endif
}
void h264_rtp_video_rxtx::send_frame(struct video_frame *tx_frame)
void h264_rtp_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame)
{
if (m_connections_count == 1) { /* normal/default case - only one connection */
tx_send_h264(m_tx, tx_frame, m_network_devices[0]);
tx_send_h264(m_tx, tx_frame.get(), m_network_devices[0]);
} else {
//TODO to be tested, the idea is to reply per destiny
for (int i = 0; i < m_connections_count; ++i) {
tx_send_h264(m_tx, tx_frame,
tx_send_h264(m_tx, tx_frame.get(),
m_network_devices[i]);
}
}
VIDEO_FRAME_DISPOSE(tx_frame);
}
h264_rtp_video_rxtx::~h264_rtp_video_rxtx()

View File

@@ -51,7 +51,7 @@ public:
h264_rtp_video_rxtx(std::map<std::string, param_u> const &);
virtual ~h264_rtp_video_rxtx();
private:
virtual void send_frame(struct video_frame *);
virtual void send_frame(std::shared_ptr<video_frame>);
virtual void *(*get_receiver_thread())(void *arg) {
return NULL;
}

View File

@@ -69,11 +69,10 @@
using namespace std;
void ihdtv_video_rxtx::send_frame(struct video_frame *tx_frame)
void ihdtv_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame)
{
#ifdef HAVE_IHDTV
ihdtv_send(&m_tx_connection, tx_frame, 9000000); // FIXME: fix the use of frame size!!
VIDEO_FRAME_DISPOSE(tx_frame);
ihdtv_send(&m_tx_connection, tx_frame.get(), 9000000); // FIXME: fix the use of frame size!!
#else // IHDTV
UNUSED(tx_frame);
#endif // IHDTV

View File

@@ -70,7 +70,7 @@ public:
ihdtv_video_rxtx(std::map<std::string, param_u> const &);
~ihdtv_video_rxtx();
private:
void send_frame(struct video_frame *);
void send_frame(std::shared_ptr<video_frame>);
static void *receiver_thread(void *arg) {
ihdtv_video_rxtx *s = static_cast<ihdtv_video_rxtx *>(arg);
return s->receiver_loop();

View File

@@ -73,21 +73,19 @@ sage_video_rxtx::sage_video_rxtx(map<string, param_u> const &params) :
memset(&m_saved_video_desc, 0, sizeof(m_saved_video_desc));
}
void sage_video_rxtx::send_frame(struct video_frame *tx_frame)
void sage_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame)
{
if(!video_desc_eq(m_saved_video_desc,
video_desc_from_frame(tx_frame))) {
video_desc_from_frame(tx_frame.get()))) {
display_reconfigure(m_sage_tx_device,
video_desc_from_frame(tx_frame));
m_saved_video_desc = video_desc_from_frame(tx_frame);
video_desc_from_frame(tx_frame.get()));
m_saved_video_desc = video_desc_from_frame(tx_frame.get());
}
struct video_frame *frame =
display_get_frame(m_sage_tx_device);
memcpy(frame->tiles[0].data, tx_frame->tiles[0].data,
tx_frame->tiles[0].data_len);
display_put_frame(m_sage_tx_device, frame, PUTF_NONBLOCK);
VIDEO_FRAME_DISPOSE(tx_frame);
}
sage_video_rxtx::~sage_video_rxtx()

View File

@@ -67,7 +67,7 @@ public:
sage_video_rxtx(std::map<std::string, param_u> const &);
~sage_video_rxtx();
private:
void send_frame(struct video_frame *);
void send_frame(std::shared_ptr<video_frame>);
void *(*get_receiver_thread())(void *arg) {
return NULL;
}

View File

@@ -115,15 +115,13 @@ void *(*ultragrid_rtp_video_rxtx::get_receiver_thread())(void *arg) {
return receiver_thread;
}
void ultragrid_rtp_video_rxtx::send_frame(struct video_frame *tx_frame)
void ultragrid_rtp_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame)
{
if (m_fec_state) {
struct video_frame *old_frame = tx_frame;
tx_frame = m_fec_state->encode(tx_frame);
VIDEO_FRAME_DISPOSE(old_frame);
}
auto data = new pair<ultragrid_rtp_video_rxtx *, struct video_frame *>(this, tx_frame);
auto data = new pair<ultragrid_rtp_video_rxtx *, shared_ptr<video_frame>>(this, tx_frame);
unique_lock<mutex> lk(m_async_sending_lock);
m_async_sending_cv.wait(lk, [this]{return !m_async_sending;});
@@ -133,7 +131,7 @@ void ultragrid_rtp_video_rxtx::send_frame(struct video_frame *tx_frame)
}
void *ultragrid_rtp_video_rxtx::send_frame_async_callback(void *arg) {
auto data = (pair<ultragrid_rtp_video_rxtx *, struct video_frame *> *) arg;
auto data = (pair<ultragrid_rtp_video_rxtx *, shared_ptr<video_frame>> *) arg;
data->first->send_frame_async(data->second);
delete data;
@@ -142,18 +140,18 @@ void *ultragrid_rtp_video_rxtx::send_frame_async_callback(void *arg) {
}
void ultragrid_rtp_video_rxtx::send_frame_async(struct video_frame *tx_frame)
void ultragrid_rtp_video_rxtx::send_frame_async(shared_ptr<video_frame> tx_frame)
{
lock_guard<mutex> lock(m_network_devices_lock);
if (m_connections_count == 1) { /* normal case - only one connection */
tx_send(m_tx, tx_frame,
tx_send(m_tx, tx_frame.get(),
m_network_devices[0]);
} else { /* split */
struct video_frame *split_frames = vf_alloc(m_connections_count);
//assert(frame_count == 1);
vf_split_horizontal(split_frames, tx_frame,
vf_split_horizontal(split_frames, tx_frame.get(),
m_connections_count);
for (int i = 0; i < m_connections_count; ++i) {
tx_send_tile(m_tx, split_frames, i,
@@ -163,8 +161,6 @@ void ultragrid_rtp_video_rxtx::send_frame_async(struct video_frame *tx_frame)
vf_free(split_frames);
}
VIDEO_FRAME_DISPOSE(tx_frame);
m_async_sending_lock.lock();
m_async_sending = false;
m_async_sending_cv.notify_all();

View File

@@ -55,10 +55,10 @@ public:
friend ssize_t hd_rum_decompress_write(void *state, void *buf, size_t count);
private:
static void *receiver_thread(void *arg);
virtual void send_frame(struct video_frame *);
virtual void send_frame(std::shared_ptr<video_frame>);
void *receiver_loop();
static void *send_frame_async_callback(void *arg);
virtual void send_frame_async(struct video_frame *);
virtual void send_frame_async(std::shared_ptr<video_frame>);
virtual void *(*get_receiver_thread())(void *arg);
void receiver_process_messages();