mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-07-17 17:21:55 +00:00
memsink: caps protocol
This commit is contained in:
@@ -157,7 +157,8 @@ static void *_video_sink_thread(void *arg) {
|
|||||||
|
|
||||||
US_LOG_INFO("Memsink opened; reading frames ...");
|
US_LOG_INFO("Memsink opened; reading frames ...");
|
||||||
while (!_STOP && _HAS_WATCHERS) {
|
while (!_STOP && _HAS_WATCHERS) {
|
||||||
const int got = us_memsink_client_get(sink, tmp, NULL, atomic_load(&_g_key_required));
|
const us_memsink_wants_s w_put = {.key = atomic_load(&_g_key_required)};
|
||||||
|
const int got = us_memsink_client_get(sink, tmp, NULL, &w_put);
|
||||||
if (got == 0) {
|
if (got == 0) {
|
||||||
const int ri = us_ring_producer_acquire(_g_video_ring, 0);
|
const int ri = us_ring_producer_acquire(_g_video_ring, 0);
|
||||||
if (ri >= 0) {
|
if (ri >= 0) {
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ static PyObject *_MemsinkObject_wait_frame(_MemsinkObject *self, PyObject *args,
|
|||||||
self->frame_id = mem->id;
|
self->frame_id = mem->id;
|
||||||
self->frame_ts = us_get_now_monotonic();
|
self->frame_ts = us_get_now_monotonic();
|
||||||
if (key_required) {
|
if (key_required) {
|
||||||
mem->key_requested = true;
|
mem->wants.key = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flock(self->fd, LOCK_UN) < 0) {
|
if (flock(self->fd, LOCK_UN) < 0) {
|
||||||
|
|||||||
@@ -236,8 +236,9 @@ static int _dump_sink(
|
|||||||
long double last_ts = 0;
|
long double last_ts = 0;
|
||||||
|
|
||||||
while (!_g_stop) {
|
while (!_g_stop) {
|
||||||
bool key_requested;
|
us_memsink_wants_s w_get = {0};
|
||||||
const int got = us_memsink_client_get(sink, frame, &key_requested, key_required);
|
us_memsink_wants_s w_put = {.key = key_required};
|
||||||
|
const int got = us_memsink_client_get(sink, frame, &w_get, (key_required ? &w_put : NULL));
|
||||||
if (got == 0) {
|
if (got == 0) {
|
||||||
key_required = false;
|
key_required = false;
|
||||||
|
|
||||||
@@ -252,7 +253,7 @@ static int _dump_sink(
|
|||||||
frame->height,
|
frame->height,
|
||||||
frame->gop,
|
frame->gop,
|
||||||
frame->key,
|
frame->key,
|
||||||
key_requested,
|
w_get.key,
|
||||||
frame->grab_end_ts - frame->grab_begin_ts,
|
frame->grab_end_ts - frame->grab_begin_ts,
|
||||||
frame->encode_begin_ts - frame->grab_end_ts,
|
frame->encode_begin_ts - frame->grab_end_ts,
|
||||||
frame->encode_end_ts - frame->encode_begin_ts,
|
frame->encode_end_ts - frame->encode_begin_ts,
|
||||||
|
|||||||
@@ -41,8 +41,8 @@
|
|||||||
|
|
||||||
us_memsink_s *us_memsink_init_opened(
|
us_memsink_s *us_memsink_init_opened(
|
||||||
const char *name, const char *obj, bool server,
|
const char *name, const char *obj, bool server,
|
||||||
mode_t mode, bool rm, uint client_ttl, uint timeout) {
|
mode_t mode, bool rm, uint client_ttl, uint timeout
|
||||||
|
) {
|
||||||
us_memsink_s *sink;
|
us_memsink_s *sink;
|
||||||
US_CALLOC(sink, 1);
|
US_CALLOC(sink, 1);
|
||||||
sink->name = name;
|
sink->name = name;
|
||||||
@@ -160,7 +160,11 @@ bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key_requested) {
|
int us_memsink_server_put(
|
||||||
|
us_memsink_s *sink,
|
||||||
|
const us_frame_s *frame,
|
||||||
|
us_memsink_wants_s *wants
|
||||||
|
) {
|
||||||
US_A(sink->server);
|
US_A(sink->server);
|
||||||
|
|
||||||
const ldf now = us_get_now_monotonic();
|
const ldf now = us_get_now_monotonic();
|
||||||
@@ -175,11 +179,11 @@ int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key
|
|||||||
US_LOG_VERBOSE("%s-sink: >>>>> Exposing new frame ...", sink->name);
|
US_LOG_VERBOSE("%s-sink: >>>>> Exposing new frame ...", sink->name);
|
||||||
|
|
||||||
sink->mem->id = us_get_now_id();
|
sink->mem->id = us_get_now_id();
|
||||||
if (sink->mem->key_requested && frame->key) {
|
if (sink->mem->wants.key && frame->key) {
|
||||||
sink->mem->key_requested = false;
|
sink->mem->wants.key = false;
|
||||||
}
|
}
|
||||||
if (key_requested != NULL) { // We don't need it for non-H264 sinks
|
if (wants != NULL) {
|
||||||
*key_requested = sink->mem->key_requested;
|
memcpy(wants, &sink->mem->wants, sizeof(us_memsink_wants_s));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(us_memsink_get_data(sink->mem), frame->data, frame->used);
|
memcpy(us_memsink_get_data(sink->mem), frame->data, frame->used);
|
||||||
@@ -189,7 +193,8 @@ int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key
|
|||||||
sink->mem->magic = US_MEMSINK_MAGIC;
|
sink->mem->magic = US_MEMSINK_MAGIC;
|
||||||
sink->mem->version = US_MEMSINK_VERSION;
|
sink->mem->version = US_MEMSINK_VERSION;
|
||||||
|
|
||||||
atomic_store(&sink->has_clients, (sink->mem->last_client_ts + sink->client_ttl > us_get_now_monotonic()));
|
const bool has_clients = (sink->mem->last_client_ts + sink->client_ttl > us_get_now_monotonic());
|
||||||
|
atomic_store(&sink->has_clients, has_clients);
|
||||||
|
|
||||||
if (flock(sink->fd, LOCK_UN) < 0) {
|
if (flock(sink->fd, LOCK_UN) < 0) {
|
||||||
US_LOG_PERROR("%s-sink: Can't unlock memory", sink->name);
|
US_LOG_PERROR("%s-sink: Can't unlock memory", sink->name);
|
||||||
@@ -208,7 +213,12 @@ int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int us_memsink_client_get(us_memsink_s *sink, us_frame_s *frame, bool *key_requested, bool key_required) {
|
int us_memsink_client_get(
|
||||||
|
us_memsink_s *sink,
|
||||||
|
us_frame_s *frame,
|
||||||
|
us_memsink_wants_s *get,
|
||||||
|
const us_memsink_wants_s *put
|
||||||
|
) {
|
||||||
US_A(!sink->server); // Client only
|
US_A(!sink->server); // Client only
|
||||||
|
|
||||||
if (us_flock_timedwait_monotonic(sink->fd, sink->timeout) < 0) {
|
if (us_flock_timedwait_monotonic(sink->fd, sink->timeout) < 0) {
|
||||||
@@ -243,11 +253,16 @@ int us_memsink_client_get(us_memsink_s *sink, us_frame_s *frame, bool *key_reque
|
|||||||
sink->last_readed_id = sink->mem->id;
|
sink->last_readed_id = sink->mem->id;
|
||||||
us_frame_set_data(frame, us_memsink_get_data(sink->mem), sink->mem->used);
|
us_frame_set_data(frame, us_memsink_get_data(sink->mem), sink->mem->used);
|
||||||
US_FRAME_COPY_META(sink->mem, frame);
|
US_FRAME_COPY_META(sink->mem, frame);
|
||||||
if (key_requested != NULL) { // We don't need it for non-H264 sinks
|
|
||||||
*key_requested = sink->mem->key_requested;
|
if (get != NULL) {
|
||||||
|
memcpy(get, &sink->mem->wants, sizeof(us_memsink_wants_s));
|
||||||
}
|
}
|
||||||
if (key_required) {
|
if (put != NULL) {
|
||||||
sink->mem->key_requested = true;
|
const bool key = sink->mem->wants.key;
|
||||||
|
memcpy(&sink->mem->wants, put, sizeof(us_memsink_wants_s));
|
||||||
|
if (key) {
|
||||||
|
sink->mem->wants.key = key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|||||||
@@ -57,6 +57,14 @@ us_memsink_s *us_memsink_init_opened(
|
|||||||
void us_memsink_destroy(us_memsink_s *sink);
|
void us_memsink_destroy(us_memsink_s *sink);
|
||||||
|
|
||||||
bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame);
|
bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame);
|
||||||
int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key_requested);
|
|
||||||
|
|
||||||
int us_memsink_client_get(us_memsink_s *sink, us_frame_s *frame, bool *key_requested, bool key_required);
|
int us_memsink_server_put(
|
||||||
|
us_memsink_s *sink,
|
||||||
|
const us_frame_s *frame,
|
||||||
|
us_memsink_wants_s *wants);
|
||||||
|
|
||||||
|
int us_memsink_client_get(
|
||||||
|
us_memsink_s *sink,
|
||||||
|
us_frame_s *frame,
|
||||||
|
us_memsink_wants_s *get,
|
||||||
|
const us_memsink_wants_s *put);
|
||||||
|
|||||||
@@ -27,9 +27,18 @@
|
|||||||
|
|
||||||
|
|
||||||
#define US_MEMSINK_MAGIC ((u64)0xCAFEBABECAFEBABE)
|
#define US_MEMSINK_MAGIC ((u64)0xCAFEBABECAFEBABE)
|
||||||
#define US_MEMSINK_VERSION ((u32)8)
|
#define US_MEMSINK_VERSION ((u32)9)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint width;
|
||||||
|
uint height;
|
||||||
|
uint format;
|
||||||
|
uint stride;
|
||||||
|
uint fps;
|
||||||
|
bool key;
|
||||||
|
} us_memsink_wants_s;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
u32 version;
|
u32 version;
|
||||||
@@ -37,7 +46,7 @@ typedef struct {
|
|||||||
uz used;
|
uz used;
|
||||||
|
|
||||||
ldf last_client_ts;
|
ldf last_client_ts;
|
||||||
bool key_requested;
|
us_memsink_wants_s wants;
|
||||||
|
|
||||||
US_FRAME_META_DECLARE;
|
US_FRAME_META_DECLARE;
|
||||||
} us_memsink_shared_s;
|
} us_memsink_shared_s;
|
||||||
|
|||||||
@@ -758,7 +758,9 @@ static void _stream_encode_expose_h264(us_stream_s *stream, const us_frame_s *fr
|
|||||||
force_key = true;
|
force_key = true;
|
||||||
}
|
}
|
||||||
if (!us_m2m_encoder_compress(run->h264_enc, frame, run->h264_dest, force_key)) {
|
if (!us_m2m_encoder_compress(run->h264_enc, frame, run->h264_dest, force_key)) {
|
||||||
meta.online = !us_memsink_server_put(stream->h264_sink, run->h264_dest, &run->h264_key_requested);
|
us_memsink_wants_s wants = {0};
|
||||||
|
meta.online = !us_memsink_server_put(stream->h264_sink, run->h264_dest, &wants);
|
||||||
|
run->h264_key_requested = wants.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|||||||
Reference in New Issue
Block a user