104#include <condition_variable>
113#include <unordered_map>
142#if __has_include(<libavcodec/avcodec.h>)
143#include <libavcodec/avcodec.h>
149#define MOD_NAME "[video dec.] "
151#define FRAMEBUFFER_NOT_READY(decoder) (decoder->frame == NULL && decoder->out_codec != VIDEO_CODEC_END)
153using namespace std::string_literals;
154using std::chrono::duration_cast;
155using std::chrono::high_resolution_clock;
156using std::chrono::nanoseconds;
157using std::chrono::seconds;
158using std::chrono::steady_clock;
159using std::atomic_ulong;
160using std::condition_variable;
164using std::ostringstream;
169using std::unique_lock;
170using std::unique_ptr;
193 for (map<int, int>::const_iterator it = m.begin();
194 it != m.end(); ++it) {
220 unsigned int dst_linesize;
221 unsigned int dst_pitch;
222 unsigned int src_linesize;
225struct reported_statistics_cumul {
226 ~reported_statistics_cumul() {
229 long long int last_buffer_number = -1;
230 steady_clock::time_point t_last = steady_clock::now();
231 unsigned long int displayed = 0, dropped = 0, corrupted = 0, missing = 0;
232 atomic_ulong fec_ok = 0, fec_corrected = 0, fec_nok = 0;
235 if (fec_ok + fec_nok + fec_corrected > 0) {
236 fec <<
" FEC noerr/OK/NOK: " <<
SBOLD(fec_ok) <<
"/" <<
SBOLD(fec_corrected) <<
"/" <<
SBOLD(fec_nok);
238 unsigned long total = displayed + dropped + missing;
240 <<
SBOLD(total) <<
" total / "
241 <<
SBOLD(displayed) <<
" disp / "
242 <<
SBOLD(dropped) <<
" drop / "
243 <<
SBOLD(corrupted) <<
" corr / "
244 <<
SBOLD(missing) <<
" miss"
245 <<
fec.str() <<
"\n";
246 if (total > 3000 && dropped * 50 >= total) {
248 "to network jitter, try adding \"--param decoder-drop-policy=blocking\" if the problem persists.\n", dropped, total);
251 void update(
int buffer_number) {
252 if (last_buffer_number != -1) {
253 long long int diff = buffer_number -
254 ((last_buffer_number + 1) & ((1U<<
BUFNUM_BITS) - 1));
262 last_buffer_number = buffer_number;
263 const auto now = steady_clock::now();
264 if (duration_cast<seconds>(now - t_last).
count() >
274 inline frame_msg(
struct control_state *c,
struct reported_statistics_cumul &sr) : control(c), recv_frame(nullptr),
275 nofec_frame(nullptr),
276 received_pkts_cum(0), expected_pkts_cum(0),
279 inline ~frame_msg() {
281 int received_bytes = 0;
282 for (
unsigned int i = 0; i < recv_frame->tile_count; ++i) {
283 received_bytes +=
sum_map(pckt_list[i]);
286 if (recv_frame->fec_params.type !=
FEC_NONE) {
290 if (received_bytes == expected_bytes) {
293 stats.fec_corrected += 1;
297 stats.corrupted += is_corrupted;
298 stats.displayed += is_displayed;
299 stats.dropped += !is_displayed;
305 vector <uint32_t> buffer_num;
308 unique_ptr<map<int, int>[]> pckt_list;
309 unsigned long long int received_pkts_cum, expected_pkts_cum;
310 struct reported_statistics_cumul &stats;
311 bool is_corrupted =
false;
312 bool is_displayed =
false;
315struct main_msg_reconfigure {
316 inline main_msg_reconfigure(
struct video_desc d,
317 unique_ptr<frame_msg> &&f,
323 compress_internal_prop(pd) {}
373 struct line_decoder *line_decoder = NULL;
398 struct reported_statistics_cumul
stats = {};
407 unique_lock<mutex> lk(decoder->
lock);
411#define ENCRYPTED_ERR "Receiving encrypted video data but " \
412 "no decryption key entered!\n"
413#define NOT_ENCRYPTED_ERR "Receiving unencrypted video data " \
414 "while expecting encrypted.\n"
421 fec *fec_state = NULL;
427 if (!data->recv_frame) {
436 if(!fec_state ||
desc.k !=
data->recv_frame->fec_params.k ||
437 desc.m !=
data->recv_frame->fec_params.m ||
438 desc.c !=
data->recv_frame->fec_params.c ||
439 desc.seed !=
data->recv_frame->fec_params.seed
442 desc =
data->recv_frame->fec_params;
444 if(fec_state == NULL) {
453 data->nofec_frame->ssrc =
data->recv_frame->ssrc;
454 data->nofec_frame->timestamp =
data->recv_frame->timestamp;
457 bool buffer_swapped =
false;
460 char *fec_out_buffer = NULL;
463 if (
data->recv_frame->tiles[pos].data_len != (
unsigned int)
sum_map(
data->pckt_list[pos])) {
464 debug_msg(
"Frame incomplete - substream %d, buffer %d: expected %u bytes, got %u.\n", pos,
465 (
unsigned int)
data->buffer_num[pos],
466 data->recv_frame->tiles[pos].data_len,
470 bool ret = fec_state->
decode(
data->recv_frame->tiles[pos].data,
471 data->recv_frame->tiles[pos].data_len,
472 &fec_out_buffer, &fec_out_len,
data->pckt_list[pos]);
475 data->is_corrupted =
true;
476 verbose_msg(
"[decoder] FEC: unable to reconstruct data.\n");
486 memcpy(&video_hdr, fec_out_buffer,
495 decoder->
msg_queue.
push(
new main_msg_reconfigure(network_desc, std::move(data)));
504 data->nofec_frame->tiles[pos].data_len = fec_out_len;
505 data->nofec_frame->tiles[pos].data = fec_out_buffer;
507 if (!buffer_swapped) {
508 buffer_swapped =
true;
510 unique_lock<mutex> lk(decoder->
lock);
524 struct line_decoder *line_decoder =
528 char *src = fec_out_buffer;
529 char *dst =
tile->
data + line_decoder->base_offset;
530 while(data_pos < (
int) fec_out_len) {
531 line_decoder->decode_line((
unsigned char*)dst, (
unsigned char *) src, line_decoder->dst_linesize,
532 line_decoder->shifts[0],
533 line_decoder->shifts[1],
534 line_decoder->shifts[2]);
535 src += line_decoder->src_linesize;
537 data_pos += line_decoder->src_linesize;
543 data->nofec_frame->tiles[i].data_len = data->recv_frame->tiles[i].data_len;
544 data->nofec_frame->tiles[i].data = data->recv_frame->tiles[i].data;
546 if (data->recv_frame->tiles[i].data_len != (
unsigned int)
sum_map(data->pckt_list[i])) {
547 debug_msg(
"Frame incomplete - substream %d, buffer %d: expected %u bytes, got %u.%s\n", i,
548 (
unsigned int) data->buffer_num[i],
549 data->recv_frame->tiles[i].data_len,
550 (
unsigned int)
sum_map(data->pckt_list[i]),
552 data->is_corrupted =
true;
598 if (!d->compressed->tiles[d->pos].data)
601 (
unsigned char *) d->out,
602 (
unsigned char *) d->compressed->tiles[d->pos].data,
603 d->compressed->tiles[d->pos].data_len,
611 "* decoder-drop-policy=blocking|nonblock|<sec>\n"
612 " Force specified blocking policy (default nonblock).\n"
613 " <sec> - specifies frame timeout in seconds (can have suffixes, eg. \"20ms\")\n");
621 long long force_putf_timeout = []() {
626 if (drop_policy->second ==
"nonblock") {
629 if (drop_policy->second ==
"blocking") {
632 return static_cast<long long>(
641 if(!
msg->recv_frame) {
645 auto t0 = std::chrono::high_resolution_clock::now();
646 unique_ptr<char[]> tmp;
649 tmp = unique_ptr<char[]>(
new char[tile_height * (tile_width *
MAX_BPS +
PADDING)]);
655 vector<task_result_handle_t> handle(tile_count);
656 vector<decompress_data> data(tile_count);
657 for (
int pos = 0; pos < tile_count; ++pos) {
658 data[pos].decoder = decoder;
660 data[pos].compressed =
msg->nofec_frame;
661 data[pos].buffer_num =
msg->buffer_num[pos];
663 data[pos].out = (
unsigned char *) tmp.get();
673 if (tile_count > 1) {
679 if (tile_count > 1) {
680 for (
int pos = 0; pos < tile_count; ++pos) {
684 for (
int pos = 0; pos < tile_count; ++pos) {
707 duration_cast<nanoseconds>(high_resolution_clock::now() - t0).count() / 1000000.0 <<
" ms\n";
718 long long putf_timeout = force_putf_timeout != -1 ? force_putf_timeout :
PUTF_NONBLOCK;
724 msg->is_displayed = ret;
726 assert(decoder->
frame !=
nullptr);
731 unique_lock<mutex> lk(decoder->
lock);
769 if (strlen(encryption) > 0) {
821 unique_ptr<frame_msg>
msg(
new frame_msg(decoder->
control, decoder->
stats));
835 for ( ; it !=
codecs.end(); ++it) {
842 "* decoder-use-codec=<codec>\n"
843 " Use specified pixel format for decoding (eg. v210). This overrides automatic\n"
844 " choice. The pixel format must be supported by the video display. Use 'help' to see\n"
845 " available options for a display (eg.: 'uv -d gl --param decoder-use-codec=help').\n"
846 "* decoder-use-codec=!<codec>\n"
847 " Blacklist specified pixel format ('!<codec' may need to be quoted).\n");
862 assert(decoder->
display == NULL);
875 for (
size_t i = 0; i <
len /
sizeof(
codec_t); ++i) {
881 bool blacklist_codec =
false;
882 if (codec_str[0] ==
'!') {
883 blacklist_codec =
true;
887 if (
"help"s == codec_str) {
896 if (blacklist_codec) {
945 if (decoder->
frame) {
947 decoder->
frame = NULL;
1007 vector<pair<struct pixfmt_desc, codec_t>> ret;
1010 for (
auto codec : display_codecs) {
1012 ret.emplace_back(comp_int_prop,
codec);
1013 if (comp_int_prop.
depth != 0) {
1020 for (
auto codec : display_codecs) {
1021 if (used.find(
codec) != used.end()) {
1025 ret.emplace_back(comp_int_prop,
codec);
1026 if (comp_int_prop.
depth != 0) {
1033 vector<codec_t> remaining;
1034 for (
auto codec : display_codecs) {
1035 if (used.find(
codec) != used.end()) {
1038 remaining.emplace_back(
codec);
1040 if (comp_int_prop.
depth != 0) {
1041 sort(remaining.begin(), remaining.end(), [comp_int_prop](
const codec_t &a,
const codec_t &b) {
1042 struct pixfmt_desc desc_a = get_pixfmt_desc(a);
1043 struct pixfmt_desc desc_b = get_pixfmt_desc(b);
1044 return compare_pixdesc(&desc_a, &desc_b, &comp_int_prop) < 0;
1047 for (
auto & c : remaining) {
1048 ret.emplace_back(comp_int_prop, c);
1049 if (comp_int_prop.
depth != 0) {
1056 for (
auto it = ret.begin(); it != ret.end(); ++it) {
1095 goto after_linedecoder_lookup;
1100 vector<codec_t> native_codecs_copy = decoder->
native_codecs;
1105 goto after_linedecoder_lookup;
1109after_linedecoder_lookup:
1112 if(*decode_line == NULL) {
1120 if (supports_autodetection) {
1126 vector<pair<struct pixfmt_desc, codec_t>> formats_to_try;
1129 for (
auto it = formats_to_try.begin(); it != formats_to_try.end(); ++it) {
1136 goto after_decoder_lookup;
1141after_decoder_lookup:
1166 struct transcode_t transcode[] = {
1174 for (i = 0; i < il_out_cnt; ++i) {
1175 if(in_il == supported[i]) {
1181 for (i = 0; i < il_out_cnt; ++i) {
1183 for (j = 0; j <
sizeof(transcode) /
sizeof(
struct transcode_t); ++j) {
1184 if(in_il == transcode[j].in && supported[i] == transcode[j].out) {
1185 *out_il = transcode[j].out;
1186 return transcode[j].func;
1192 "interlacing modes!\n");
1220 decoder->
frame = NULL;
1230 LOG(
LOG_LEVEL_ERROR) <<
"Could not find neither line conversion nor decompress from " <<
1238 size_t len =
sizeof(int);
1241 &display_mode, &
len)) {
1242 debug_msg(
"Failed to get video display mode.\n");
1269 len =
sizeof(display_requested_rgb_shift);
1271 &display_requested_rgb_shift, &
len);
1273 debug_msg(
"Failed to get r,g,b shift property from video driver.\n");
1275 memcpy(&display_requested_rgb_shift, rgb_shift,
sizeof(rgb_shift));
1279 &display_requested_pitch, &
len);
1281 debug_msg(
"Failed to get pitch from video driver.\n");
1296 decoder->
pitch = display_requested_pitch;
1303 decoder->
line_decoder = (
struct line_decoder *) malloc(src_x_tiles * src_y_tiles *
1304 sizeof(
struct line_decoder));
1307 out->base_offset = 0;
1310 memcpy(out->shifts, display_requested_rgb_shift, 3 *
sizeof(
int));
1312 out->decode_line = decode_line;
1313 out->dst_pitch = decoder->
pitch;
1320 for(x = 0; x < src_x_tiles; ++x) {
1321 for(y = 0; y < src_y_tiles; ++y) {
1330 memcpy(out->shifts, display_requested_rgb_shift,
1333 out->decode_line = decode_line;
1335 out->dst_pitch = decoder->
pitch;
1345 for(x = 0; x < src_x_tiles; ++x) {
1346 for(y = 0; y < src_y_tiles; ++y) {
1349 out->base_offset = 0;
1352 memcpy(out->shifts, display_requested_rgb_shift,
1355 out->decode_line = decode_line;
1365 }
else if (decoder->
decoder_type == EXTERNAL_DECODER) {
1370 display_requested_rgb_shift[0],
1371 display_requested_rgb_shift[1],
1372 display_requested_rgb_shift[2],
1381 size_t size =
sizeof(res);
1399 assert(decoder->
frame !=
nullptr);
1408 int fps_pt, fpsd, fd, fi;
1410 tmp = ntohl(hdr[0]);
1418 (
const char *)&hdr[4]);
1422 tmp = ntohl(hdr[5]);
1424 fps_pt = (tmp >> 19) & 0x3ff;
1425 fpsd = (tmp >> 15) & 0xf;
1426 fd = (tmp >> 14) & 0x1;
1427 fi = (tmp >> 13) & 0x1;
1449 decoder->
frame = NULL;
1460 const bool comp_int_eq =
1462 if (desc_eq && comp_int_eq) {
1475 const uint32_t *hdr)
1485 <<
"[video dec.] New incoming video format detected: "
1486 << network_desc <<
"\n";
1490#define ERROR_GOTO_CLEANUP ret = false; goto cleanup;
1491#define max(a, b) (((a) > (b))? (a): (b))
1517 unique_ptr<map<int, int>[]> pckt_list(
new map<int, int>[max_substreams]);
1519 int buffer_number = 0;
1520 bool buffer_swapped =
false;
1528 main_msg_reconfigure *msg_reconf;
1530 if (msg_reconf->force) {
1532 msg_reconf->compress_internal_prop);
1536 decoder, msg_reconf->desc,
1537 msg_reconf->compress_internal_prop);
1539 if (msg_reconf->last_frame) {
1547 int pt = cdata->
data->pt;
1549 const uint32_t *hdr = (uint32_t *)(
void *)cdata->
data->data;
1550 const uint32_t tmp = ntohl(hdr[3]);
1551 const int k = tmp >> 19;
1552 const int m = 0x1fff & (tmp >> 6);
1553 const int c = 0x3f & tmp;
1554 const int seed = ntohl(hdr[4]);
1559 while (cdata != NULL) {
1566 const uint32_t *hdr = (uint32_t *)(
void *) pckt->data;
1567 const uint32_t data_pos = ntohl(hdr[1]);
1568 uint32_t tmp = ntohl(hdr[0]);
1569 const uint32_t substream = tmp >> 22;
1570 buffer_number = tmp & 0x3fffff;
1571 const int buffer_length = ntohl(hdr[2]);
1602 uint32_t crypto_hdr = ntohl(*(
const uint32_t *)(
const void *)((
const char *)hdr + media_hdr_len));
1621 if ((
int) substream >= max_substreams) {
1622 log_msg(
LOG_LEVEL_WARNING,
"[decoder] received substream ID %d. Expecting at most %d substreams. Did you set -M option?\n",
1623 substream, max_substreams);
1651 plaintext, crypto_mode)) == 0) {
1654 data = (
char *) plaintext;
1673 buffer_num[substream] = buffer_number;
1675 pckt_list[substream][data_pos] =
len;
1679 if(!buffer_swapped) {
1681 buffer_swapped =
true;
1682 unique_lock<mutex> lk(decoder->
lock);
1692 struct line_decoder *line_decoder =
1704 int y = (data_pos / line_decoder->src_linesize) * line_decoder->dst_pitch;
1707 int s_x = data_pos % line_decoder->src_linesize;
1712 int d_x = s_x * line_decoder->conv_num / line_decoder->conv_den;
1715 auto *
source = (
const unsigned char *)(data);
1724 int l =
len * line_decoder->conv_num / line_decoder->conv_den;
1729 if (l + d_x > (
int) line_decoder->dst_linesize) {
1730 l = line_decoder->dst_linesize - d_x;
1734 const uint32_t
offset = y + d_x;
1742 line_decoder->decode_line((
unsigned char*)
tile->
data + line_decoder->base_offset +
offset,
source, l,
1743 line_decoder->shifts[0], line_decoder->shifts[1],
1744 line_decoder->shifts[2]);
1747 len -= line_decoder->src_linesize - s_x;
1749 source += line_decoder->src_linesize - s_x;
1755 if((prints % 100) == 0) {
1757 "Well this should not happened. Expect troubles pretty soon.\n");
1765 y += line_decoder->dst_pitch;
1772 if (data_pos +
len > (
unsigned) buffer_length) {
1773 if((prints % 100) == 0) {
1775 "Well this should not happened. Expect troubles pretty soon.\n");
1781 (
const unsigned char *)data,
len);
1799 for(
int i = 0; i < max_substreams; ++i) {
1800 unsigned int last_end = 0;
1801 for (
auto const & packets : pckt_list[i]) {
1802 unsigned int start = packets.first;
1803 unsigned int len = packets.second;
1804 if (last_end <
start) {
1809 if (last_end < frame->tiles[i].data_len) {
1816 unsigned int frame_size = 0;
1817 for (
int i = 0; i < max_substreams; ++i) {
1823 unique_ptr <frame_msg> fec_msg (
new frame_msg(decoder->
control, decoder->
stats));
1824 fec_msg->buffer_num = std::move(buffer_num);
1825 fec_msg->recv_frame =
frame;
1827 fec_msg->pckt_list = std::move(pckt_list);
1831 auto t0 = std::chrono::high_resolution_clock::now();
1833 auto t1 = std::chrono::high_resolution_clock::now();
1835 if (std::chrono::duration_cast<std::chrono::duration<double>>(t1 - t0).
count() > tpf && decoder->
stats.displayed > 20) {
1836 decoder->
slow_msg.
print(
"Your computer may be too SLOW to play this !!!\n");
1847 decoder->
stats.update(buffer_number);
1860 if (strcmp(m_univ->
text,
"get_format") == 0) {
struct video_frame * frame
struct video_frame * vf_alloc(int count)
Allocates blank video frame.
void vf_free(struct video_frame *buf)
Frees video_frame structure.
void vf_data_deleter(struct video_frame *buf)
int vc_get_linesize(unsigned int width, codec_t codec)
const char * get_codec_name(codec_t codec)
codec_t get_codec_from_name(const char *name)
simple blocking synchronized queue
T pop(bool nonblocking=false)
void push(T const &message)
static void new_message(struct module *m)
static __device__ const float offset
void log_msg(int level, const char *format,...)
void log_msg_once(int level, uint32_t id, const char *msg,...)
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define debug_msg(...)
#define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, "[pid/%d +%d %s] ", getpid(), LINE,...
#define LOG_LEVEL_FATAL
errors that prevent UG run
#define CUMULATIVE_REPORTS_INTERVAL
#define LOG_LEVEL_WARNING
less severe errors
#define PITCH_DEFAULT
default pitch, i. e. respective linesize
bool display_put_frame(struct display *d, struct video_frame *frame, long long timeout_ns)
Puts filled video frame. After calling this function, video frame cannot be used.
bool display_ctl_property(struct display *d, int property, void *val, size_t *len)
Gets property from video display.
struct video_frame * display_get_frame(struct display *d)
Returns video framebuffer which will be written to.
@ DISPLAY_PROPERTY_BUF_PITCH
requested framebuffer pitch - int (bytes), may be PITCH_DEFAULT
@ DISPLAY_PROPERTY_RGB_SHIFT
red,green,blue shift - int[3] (bits)
@ DISPLAY_PROPERTY_SUPPORTED_IL_MODES
display supported interlacing modes - enum interlacing_t[]
@ DISPLAY_PROPERTY_VIDEO_MODE
requested video mode - int (one of display_prop_vid_mode)
@ DISPLAY_PROPERTY_CODECS
list of natively supported codecs - codec_t[]
@ DISPLAY_PROPERTY_VIDEO_SEPARATE_TILES
framebuffer consists of separate tiles
@ DISPLAY_PROPERTY_VIDEO_MERGED
monolithic framebuffer
@ DISPLAY_PROPERTY_VIDEO_SEPARATE_3D
same as MERGED but 2 streams should be handled as separate 3D tiles
void module_init_default(struct module *module_data)
void module_register(struct module *module_data, struct module *parent)
struct module * get_module(struct module *root, const char *const_path)
void module_done(struct module *module_data)
struct module * get_root_module(struct module *node)
#define DECOMPRESS_PROPERTY_ACCEPTS_CORRUPTED_FRAME
decompress_status decompress_frame(struct state_decompress *s, unsigned char *dst, unsigned char *compressed, unsigned int compressed_len, int frame_seq, struct video_frame_callbacks *callbacks, struct pixfmt_desc *internal_prop)
Decompresses video frame.
int decompress_get_property(struct state_decompress *s, int property, void *val, size_t *len)
void decompress_done(struct state_decompress *s)
int decompress_reconfigure(struct state_decompress *s, struct video_desc desc, int rshift, int gshift, int bshift, int pitch, codec_t out_codec)
bool decompress_init_multi(codec_t compression, struct pixfmt_desc internal_prop, codec_t out_codec, struct state_decompress **out, int count)
Initializes (multiple) decompress states.
@ DECODER_GOT_CODEC
Internal pixel format was determined.
@ DECODER_UNSUPP_PIXFMT
Decoder can't decode to selected out_codec.
void video_decoder_destroy(struct state_video_decoder *decoder)
Destroys decoder created with decoder_init()
bool parse_video_hdr(const uint32_t *hdr, struct video_desc *desc)
bool video_decoder_register_display(struct state_video_decoder *decoder, struct display *display)
Registers video display to be used for displaying decoded video frames.
void video_decoder_remove_display(struct state_video_decoder *decoder)
This removes display from current decoder.
int decode_video_frame(struct coded_data *cdata, void *decoder_data, struct pbuf_stats *stats)
Decodes a participant buffer representing one video frame.
void handle_error(int status)
const char * get_commandline_param(const char *key)
std::unordered_map< std::string, std::string > commandline_params
#define ADD_TO_PARAM(param, doc)
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_UNDEFINED
#define to_fourcc(a, b, c, d)
Creates FourCC word.
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct response * send_message_to_receiver(struct module *receiver, struct message *msg)
struct message * check_message(struct module *mod)
void free_response(struct response *r)
@ RECEIVER_MSG_VIDEO_PROP_CHANGED
#define RESPONSE_NOT_FOUND
double unit_evaluate_dbl(const char *str, bool case_sensitive, const char **endptr)
#define OPENSSL_DECRYPT_ABI_VERSION
openssl_mode
only GCM provides autenticity, other modes only check integrity (CRC)
decoder_t get_decoder_from_to(codec_t in, codec_t out)
decoder_t get_best_decoder_from(codec_t in, const codec_t *out_candidates, codec_t *out)
decoder_func_t * decoder_t
decoder_func_t vc_memcpy
dummy conversion - ptr to it returned if no conversion needed
#define DEFAULT_RGB_SHIFT_INIT
#define RTP_MAX_PACKET_LEN
#define PT_ENCRYPT_VIDEO_RS
uint32_t fec_payload_hdr_t[5]
#define PT_VIDEO_IS_ENCRYPTED(pt)
#define PT_Unassign_Type95
uint32_t crypto_payload_hdr_t[1]
#define PT_ENCRYPT_VIDEO_LDGM
#define PT_VIDEO_HAS_FEC(pt)
uint32_t video_payload_hdr_t[6]
HRESULT __stdcall(* func)()
struct video_frame * compressed
struct pixfmt_desc internal_prop
struct state_video_decoder * decoder
This struct represents initialized video display state.
static fec * create_from_desc(struct fec_desc) noexcept
static enum fec_type fec_type_from_pt(int pt)
virtual bool decode(char *in, int in_len, char **out, int *out_len, const std::map< int, int > &)=0
notify_t new_message
if set, notifies module that new message is in queue, receiver lock is hold during the call
int(* init)(struct openssl_decrypt **state, const char *passphrase)
void(* destroy)(struct openssl_decrypt *state)
int(* decrypt)(struct openssl_decrypt *decrypt, const char *ciphertext, int ciphertext_len, const char *aad, int aad_len, char *plaintext, enum openssl_mode mode)
long long int received_pkts_cum
long long int expected_pkts_cum
int depth
bit depth; 0 means that whole struct is undefined
thread decompress_thread_id
enum interlacing_t * disp_supported_il
display supported interlacing mode
struct line_decoder * line_decoder
is neeeded, use this structure
synchronized_queue< unique_ptr< frame_msg >, 1 > fec_queue
enum decoder_type_t decoder_type
how will the video data be decoded
size_t disp_supported_il_cnt
count of disp_supported_il
const struct openssl_decrypt_info * dec_funcs
decrypt state
struct video_frame * frame
vector< codec_t > native_codecs
list of display native codecs
synchronized_queue< unique_ptr< frame_msg >, 1 > decompress_queue
struct openssl_decrypt * decrypt
decrypt state
struct video_desc received_vid_desc
description of the network video
bool merged_fb
flag if the display device driver requires tiled video or not
change_il_t change_il
function to change interlacing, if needed. Otherwise NULL.
condition_variable buffer_swapped_cv
condition variable associated with buffer_swapped
bool accepts_corrupted_frame
whether we should pass corrupted frame to decompress
timed_message< LOG_LEVEL_WARNING > slow_msg
shows warning ony in certain interval
unsigned int max_substreams
maximal number of expected substreams
struct pixfmt_desc received_int_desc
compression int desc
struct control_state * control
struct reported_statistics_cumul stats
stats to be reported through control socket
struct video_desc display_desc
description of the mode that display is currently configured to
vector< struct state_decompress * > decompress_state
state of the decompress (for every substream)
vector< void * > change_il_state
enum video_mode video_mode
video mode set for this decoder
synchronized_queue< main_msg_reconfigure *, -1 > msg_queue
state_video_decoder(struct module *parent)
Struct tile is an area of video_frame.
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
void print(const char *str)
unsigned int max_frame_size
struct state_video_decoder * decoder
enum interlacing_t interlacing
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
void(* data_deleter)(struct video_frame *)
Struct video_frame represents a video frame and contains video description.
unsigned int decoder_overrides_data_len
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
struct video_frame_callbacks callbacks
struct fec_desc fec_params
void set_thread_name(const char *name)
@ VIDEO_UNKNOWN
unspecified video mode
@ VIDEO_NORMAL
normal video (one tile)
@ LOWER_FIELD_FIRST
First stored field is bottom, followed by top.
@ UPPER_FIELD_FIRST
First stored field is top, followed by bottom.
@ PROGRESSIVE
progressive frame
@ SEGMENTED_FRAME
Segmented frame. Contains the same data as progressive frame.
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
@ DXT1
S3 Texture Compression DXT1.
@ RGB
RGB 8-bit (packed into 24-bit word)
@ VIDEO_CODEC_NONE
dummy color spec
@ VIDEO_CODEC_COUNT
count of known video codecs (including VIDEO_CODEC_NONE)
@ DXT5
S3 Texture Compression DXT5.
@ DXT1_YUV
Structure same as DXT1, instead of RGB, YCbCr values are stored.
@ RGBA
RGBA 8-bit, big-endian.
enum video_mode guess_video_mode(int num_substreams)
Tries to guess video mode from number of substreams.
int get_video_mode_tiles_x(enum video_mode video_mode)
const char * get_video_mode_description(enum video_mode video_mode)
int get_video_mode_tiles_y(enum video_mode video_mode)
This is an umbrella header for video functions.
bool codec_is_hw_accelerated(codec_t codec)
const char * get_pixdesc_desc(struct pixfmt_desc desc)
struct pixfmt_desc get_pixfmt_desc(codec_t pixfmt)
bool pixdesc_equals(struct pixfmt_desc desc_a, struct pixfmt_desc desc_b)
int get_pf_block_bytes(codec_t codec)
returns codec_info_t::block_size_bytes
int get_pf_block_pixels(codec_t codec)
returns codec_info_t::block_size_pixels
codec_t get_codec_from_fcc(uint32_t fourcc)
#define MAX_BPS
maximal (average) number of pixels per know pixel formats (up-round if needed)
static void * decompress_thread(void *args)
static bool blacklist_current_out_codec(struct state_video_decoder *decoder)
static void reconfigure_helper(struct state_video_decoder *decoder, struct video_desc network_desc, struct pixfmt_desc comp_int_desc)
static change_il_t select_il_func(enum interlacing_t in_il, enum interlacing_t *supported, int il_out_cnt, enum interlacing_t *out_il)
#define FRAMEBUFFER_NOT_READY(decoder)
struct state_video_decoder * video_decoder_init(struct module *parent, enum video_mode video_mode, struct display *display, const char *encryption)
Initializes video decompress state.
static auto codec_list_to_str(vector< codec_t > const &codecs)
static int sum_map(map< int, int > const &m)
static void video_decoder_stop_threads(struct state_video_decoder *decoder)
This function stops running threads.
static bool reconfigure_decoder(struct state_video_decoder *decoder, struct video_desc desc, struct pixfmt_desc comp_int_desc)
static vector< pair< struct pixfmt_desc, codec_t > > video_decoder_order_output_codecs(struct pixfmt_desc comp_int_prop, vector< codec_t > const &display_codecs)
static void decoder_process_message(struct module *)
void(* change_il_t)(char *dst, char *src, int linesize, int height, void **state)
#define NOT_ENCRYPTED_ERR
static codec_t choose_codec_and_decoder(struct state_video_decoder *decoder, struct video_desc desc, decoder_t *decode_line, struct pixfmt_desc comp_int_prop)
static void video_decoder_start_threads(struct state_video_decoder *decoder)
starts decompress and ldmg threads
static void reconfigure_if_needed(struct state_video_decoder *decoder, struct video_desc network_desc, struct pixfmt_desc comp_int_desc)
static void check_for_mode_change(struct state_video_decoder *decoder, const uint32_t *hdr)
static void decoder_set_video_mode(struct state_video_decoder *decoder, enum video_mode video_mode)
static void wait_for_framebuffer_swap(struct state_video_decoder *decoder)
static void * decompress_worker(void *data)
static void * fec_thread(void *args)
#define ERROR_GOTO_CLEANUP
API for video decompress drivers.
bool display_reconfigure(struct display *d, struct video_desc desc, enum video_mode video_mode)
Reconfigure display to new video format.
void il_merged_to_upper(char *dst, char *src, int linesize, int height, void **state)
Converts interlaced merged to upper-field-first.
bool video_desc_eq_excl_param(struct video_desc a, struct video_desc b, unsigned int excluded_params)
Compares two video descriptions.
double compute_fps(int fps, int fpsd, int fd, int fi)
Computes FPS as a double from packet fields.
unsigned int vf_get_data_len(struct video_frame *f)
void il_lower_to_merged(char *dst, char *src, int linesize, int height, void **stored_state)
struct tile * vf_get_tile(struct video_frame *buf, int pos)
Returns pointer to n-th tile from video frame Equivalent to &video_frame::tiles[pos].
bool video_desc_eq(struct video_desc a, struct video_desc b)
Compares two video descriptions.
void il_upper_to_merged(char *dst, char *src, int linesize, int height, void **state)
Converts upper-field-first to interlaced merged.
void * wait_task(task_result_handle_t handle)
task_result_handle_t task_run_async(runnable_t task, void *data)
Runs task asynchronously.