mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 23:40:26 +00:00
Wrap some video_frame occurences by shared_ptr
This should replace .dispose member in video_frame in future.
This commit is contained in:
@@ -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);
|
||||
|
||||
16
src/main.cpp
16
src/main.cpp
@@ -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
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
/**
|
||||
|
||||
@@ -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 *>;
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(¶ms, 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(¶ms, 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -73,21 +73,19 @@ sage_video_rxtx::sage_video_rxtx(map<string, param_u> const ¶ms) :
|
||||
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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user