mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-11-05 12:34:16 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdea0d214b | ||
|
|
72e2c6dabe | ||
|
|
686460fa29 | ||
|
|
54c1c77dfb | ||
|
|
0e0aef7b80 | ||
|
|
31b98f1d59 | ||
|
|
9734c83bd4 | ||
|
|
b88abdcae4 | ||
|
|
6fca17cf52 |
@@ -1,7 +1,7 @@
|
||||
[bumpversion]
|
||||
commit = True
|
||||
tag = True
|
||||
current_version = 6.60
|
||||
current_version = 6.61
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)
|
||||
serialize =
|
||||
{major}.{minor}
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
#include "uslibs/types.h"
|
||||
#include "uslibs/errors.h"
|
||||
#include "uslibs/tools.h"
|
||||
#include "uslibs/threading.h"
|
||||
#include "uslibs/logging.h"
|
||||
#include "uslibs/array.h"
|
||||
#include "uslibs/ring.h"
|
||||
#include "uslibs/threading.h"
|
||||
|
||||
#include "rtp.h"
|
||||
#include "au.h"
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
static void *_pcm_thread(void *v_acap);
|
||||
@@ -60,14 +60,14 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
|
||||
{
|
||||
if ((err = snd_pcm_open(&acap->dev, name, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
|
||||
acap->dev = NULL;
|
||||
US_JLOG_PERROR_ALSA(err, "acap", "Can't open PCM capture");
|
||||
US_LOG_PERROR_ALSA(err, "Can't open PCM capture");
|
||||
goto error;
|
||||
}
|
||||
assert(!snd_pcm_hw_params_malloc(&acap->dev_params));
|
||||
|
||||
# define SET_PARAM(_msg, _func, ...) { \
|
||||
if ((err = _func(acap->dev, acap->dev_params, ##__VA_ARGS__)) < 0) { \
|
||||
US_JLOG_PERROR_ALSA(err, "acap", _msg); \
|
||||
US_LOG_PERROR_ALSA(err, _msg); \
|
||||
goto error; \
|
||||
} \
|
||||
}
|
||||
@@ -78,7 +78,7 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
|
||||
SET_PARAM("Can't set PCM sampling format", snd_pcm_hw_params_set_format, SND_PCM_FORMAT_S16_LE);
|
||||
SET_PARAM("Can't set PCM sampling rate", snd_pcm_hw_params_set_rate_near, &acap->pcm_hz, 0);
|
||||
if (acap->pcm_hz < US_AU_MIN_PCM_HZ || acap->pcm_hz > US_AU_MAX_PCM_HZ) {
|
||||
US_JLOG_ERROR("acap", "Unsupported PCM freq: %u; should be: %u <= F <= %u",
|
||||
US_LOG_ERROR("Unsupported PCM freq: %u; should be: %u <= F <= %u",
|
||||
acap->pcm_hz, US_AU_MIN_PCM_HZ, US_AU_MAX_PCM_HZ);
|
||||
goto error;
|
||||
}
|
||||
@@ -93,7 +93,7 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
|
||||
acap->res = speex_resampler_init(US_RTP_OPUS_CH, acap->pcm_hz, US_RTP_OPUS_HZ, SPEEX_RESAMPLER_QUALITY_DESKTOP, &err);
|
||||
if (err < 0) {
|
||||
acap->res = NULL;
|
||||
US_JLOG_PERROR_RES(err, "acap", "Can't create resampler");
|
||||
US_LOG_PERROR_RES(err, "Can't create resampler");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
|
||||
// OPUS_SET_INBAND_FEC(1), OPUS_SET_PACKET_LOSS_PERC(10): see rtpa.c
|
||||
}
|
||||
|
||||
US_JLOG_INFO("acap", "Capture configured on %uHz; capturing ...", acap->pcm_hz);
|
||||
US_LOG_INFO("Capture configured on %uHz; capturing ...", acap->pcm_hz);
|
||||
acap->tids_created = true;
|
||||
US_THREAD_CREATE(acap->enc_tid, _encoder_thread, acap);
|
||||
US_THREAD_CREATE(acap->pcm_tid, _pcm_thread, acap);
|
||||
@@ -135,7 +135,7 @@ void us_acap_destroy(us_acap_s *acap) {
|
||||
US_RING_DELETE_WITH_ITEMS(acap->enc_ring, us_au_encoded_destroy);
|
||||
US_RING_DELETE_WITH_ITEMS(acap->pcm_ring, us_au_pcm_destroy);
|
||||
if (acap->tids_created) {
|
||||
US_JLOG_INFO("acap", "Capture closed");
|
||||
US_LOG_INFO("Capture closed");
|
||||
}
|
||||
free(acap);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ int us_acap_get_encoded(us_acap_s *acap, u8 *data, uz *size, u64 *pts) {
|
||||
}
|
||||
|
||||
static void *_pcm_thread(void *v_acap) {
|
||||
US_THREAD_SETTLE("us_ac_pcm");
|
||||
US_THREAD_SETTLE("us_acap_pcm");
|
||||
|
||||
us_acap_s *const acap = v_acap;
|
||||
u8 in[US_AU_MAX_BUF8];
|
||||
@@ -169,10 +169,10 @@ static void *_pcm_thread(void *v_acap) {
|
||||
while (!atomic_load(&acap->stop)) {
|
||||
const int frames = snd_pcm_readi(acap->dev, in, acap->pcm_frames);
|
||||
if (frames < 0) {
|
||||
US_JLOG_PERROR_ALSA(frames, "acap", "Fatal: Can't capture PCM frames");
|
||||
US_LOG_PERROR_ALSA(frames, "Fatal: Can't capture PCM frames");
|
||||
break;
|
||||
} else if (frames < (int)acap->pcm_frames) {
|
||||
US_JLOG_ERROR("acap", "Fatal: Too few PCM frames captured");
|
||||
US_LOG_ERROR("Fatal: Too few PCM frames captured");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ static void *_pcm_thread(void *v_acap) {
|
||||
memcpy(out->data, in, acap->pcm_size);
|
||||
us_ring_producer_release(acap->pcm_ring, ri);
|
||||
} else {
|
||||
US_JLOG_ERROR("acap", "PCM ring is full");
|
||||
US_LOG_ERROR("PCM ring is full");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ static void *_pcm_thread(void *v_acap) {
|
||||
}
|
||||
|
||||
static void *_encoder_thread(void *v_acap) {
|
||||
US_THREAD_SETTLE("us_ac_enc");
|
||||
US_THREAD_SETTLE("us_acap_enc");
|
||||
|
||||
us_acap_s *const acap = v_acap;
|
||||
s16 in_res[US_AU_MAX_BUF16];
|
||||
@@ -217,7 +217,7 @@ static void *_encoder_thread(void *v_acap) {
|
||||
|
||||
const int out_ri = us_ring_producer_acquire(acap->enc_ring, 0);
|
||||
if (out_ri < 0) {
|
||||
US_JLOG_ERROR("acap", "OPUS encoder queue is full");
|
||||
US_LOG_ERROR("OPUS encoder queue is full");
|
||||
us_ring_consumer_release(acap->pcm_ring, in_ri);
|
||||
continue;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ static void *_encoder_thread(void *v_acap) {
|
||||
acap->pts += US_AU_HZ_TO_FRAMES(US_RTP_OPUS_HZ);
|
||||
} else {
|
||||
out->used = 0;
|
||||
US_JLOG_PERROR_OPUS(size, "acap", "Fatal: Can't encode PCM frame to OPUS");
|
||||
US_LOG_PERROR_OPUS(size, "Fatal: Can't encode PCM frame to OPUS");
|
||||
}
|
||||
us_ring_producer_release(acap->enc_ring, out_ri);
|
||||
}
|
||||
|
||||
@@ -35,11 +35,11 @@
|
||||
#include "uslibs/types.h"
|
||||
#include "uslibs/tools.h"
|
||||
#include "uslibs/threading.h"
|
||||
#include "uslibs/logging.h"
|
||||
#include "uslibs/array.h"
|
||||
#include "uslibs/list.h"
|
||||
#include "uslibs/ring.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "au.h"
|
||||
#include "rtp.h"
|
||||
|
||||
@@ -102,7 +102,7 @@ void us_janus_client_send(us_janus_client_s *client, const us_rtp_s *rtp) {
|
||||
us_ring_s *const ring = (rtp->video ? client->video_ring : client->acap_ring);
|
||||
const int ri = us_ring_producer_acquire(ring, 0);
|
||||
if (ri < 0) {
|
||||
US_JLOG_ERROR("client", "Session %p %s ring is full",
|
||||
US_LOG_ERROR("Session %p %s ring is full",
|
||||
client->session, (rtp->video ? "video" : "acap"));
|
||||
return;
|
||||
}
|
||||
@@ -142,7 +142,7 @@ void us_janus_client_recv(us_janus_client_s *client, janus_plugin_rtp *packet) {
|
||||
us_ring_s *const ring = client->aplay_enc_ring;
|
||||
const int ri = us_ring_producer_acquire(ring, 0);
|
||||
if (ri < 0) {
|
||||
// US_JLOG_ERROR("client", "Session %p aplay ring is full", client->session);
|
||||
// US_LOG_ERROR("Session %p aplay ring is full", client->session);
|
||||
return;
|
||||
}
|
||||
us_au_encoded_s *enc = ring->items[ri];
|
||||
@@ -157,12 +157,12 @@ void us_janus_client_recv(us_janus_client_s *client, janus_plugin_rtp *packet) {
|
||||
}
|
||||
|
||||
static void *_video_thread(void *v_client) {
|
||||
US_THREAD_SETTLE("us_cx_vid");
|
||||
US_THREAD_SETTLE("us_cx_vcap");
|
||||
return _video_or_acap_thread(v_client, true);
|
||||
}
|
||||
|
||||
static void *_acap_thread(void *v_client) {
|
||||
US_THREAD_SETTLE("us_cx_ac");
|
||||
US_THREAD_SETTLE("us_cx_acap");
|
||||
return _video_or_acap_thread(v_client, false);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ static void *_video_or_acap_thread(void *v_client, bool video) {
|
||||
}
|
||||
|
||||
static void *_aplay_thread(void *v_client) {
|
||||
US_THREAD_SETTLE("us_cx_ap");
|
||||
US_THREAD_SETTLE("us_cx_aplay");
|
||||
|
||||
us_janus_client_s *const client = v_client;
|
||||
|
||||
@@ -258,7 +258,7 @@ static void *_aplay_thread(void *v_client) {
|
||||
|
||||
const int out_ri = us_ring_producer_acquire(client->aplay_pcm_ring, 0);
|
||||
if (out_ri < 0) {
|
||||
US_JLOG_ERROR("aplay", "OPUS decoder queue is full");
|
||||
US_LOG_ERROR("OPUS decoder queue is full");
|
||||
us_ring_consumer_release(client->aplay_enc_ring, in_ri);
|
||||
continue;
|
||||
}
|
||||
@@ -271,7 +271,7 @@ static void *_aplay_thread(void *v_client) {
|
||||
out->frames = frames;
|
||||
} else {
|
||||
out->frames = 0;
|
||||
US_JLOG_PERROR_OPUS(frames, "aplay", "Fatal: Can't decode OPUS to PCM frame");
|
||||
US_LOG_PERROR_OPUS(frames, "Fatal: Can't decode OPUS to PCM frame");
|
||||
}
|
||||
us_ring_producer_release(client->aplay_pcm_ring, out_ri);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
#include "uslibs/types.h"
|
||||
#include "uslibs/tools.h"
|
||||
#include "uslibs/logging.h"
|
||||
|
||||
#include "const.h"
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
static char *_get_value(janus_config *jcfg, const char *section, const char *option);
|
||||
@@ -48,24 +48,24 @@ us_config_s *us_config_init(const char *config_dir_path) {
|
||||
janus_config *jcfg = NULL;
|
||||
|
||||
US_ASPRINTF(config_file_path, "%s/%s.jcfg", config_dir_path, US_PLUGIN_PACKAGE);
|
||||
US_JLOG_INFO("config", "Reading config file '%s' ...", config_file_path);
|
||||
US_LOG_INFO("Reading config file '%s' ...", config_file_path);
|
||||
|
||||
jcfg = janus_config_parse(config_file_path);
|
||||
if (jcfg == NULL) {
|
||||
US_JLOG_ERROR("config", "Can't read config");
|
||||
US_LOG_ERROR("Can't read config");
|
||||
goto error;
|
||||
}
|
||||
janus_config_print(jcfg);
|
||||
|
||||
if ((config->video_sink_name = _get_value(jcfg, "video", "sink")) == NULL) {
|
||||
US_JLOG_ERROR("config", "Missing config value: video.sink");
|
||||
US_LOG_ERROR("Missing config value: video.sink");
|
||||
goto error;
|
||||
}
|
||||
if ((config->acap_dev_name = _get_value(jcfg, "acap", "device")) != NULL) {
|
||||
config->acap_hz = _get_uint(jcfg, "acap", "sampling_rate", 0);
|
||||
config->tc358743_dev_path = _get_value(jcfg, "acap", "tc358743");
|
||||
if (config->acap_hz == 0 && config->tc358743_dev_path == NULL) {
|
||||
US_JLOG_ERROR("config", "Either acap.sampling_rate or acap.tc358743 required");
|
||||
US_LOG_ERROR("Either acap.sampling_rate or acap.tc358743 required");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*****************************************************************************
|
||||
# #
|
||||
# uStreamer - Lightweight and fast MJPEG-HTTP streamer. #
|
||||
# #
|
||||
# Copyright (C) 2018-2024 Maxim Devaev <mdevaev@gmail.com> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include "memsinkfd.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include "uslibs/types.h"
|
||||
#include "uslibs/errors.h"
|
||||
#include "uslibs/tools.h"
|
||||
#include "uslibs/frame.h"
|
||||
#include "uslibs/memsinksh.h"
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
int us_memsink_fd_wait_frame(int fd, us_memsink_shared_s *mem, u64 last_id) {
|
||||
const ldf deadline_ts = us_get_now_monotonic() + 1; // wait_timeout
|
||||
ldf now_ts;
|
||||
do {
|
||||
const int result = us_flock_timedwait_monotonic(fd, 1); // lock_timeout
|
||||
now_ts = us_get_now_monotonic();
|
||||
if (result < 0 && errno != EWOULDBLOCK) {
|
||||
US_JLOG_PERROR("video", "Can't lock memsink");
|
||||
return -1;
|
||||
} else if (result == 0) {
|
||||
if (mem->magic == US_MEMSINK_MAGIC && mem->version == US_MEMSINK_VERSION && mem->id != last_id) {
|
||||
return 0;
|
||||
}
|
||||
if (flock(fd, LOCK_UN) < 0) {
|
||||
US_JLOG_PERROR("video", "Can't unlock memsink");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
usleep(1000); // lock_polling
|
||||
} while (now_ts < deadline_ts);
|
||||
return US_ERROR_NO_DATA;
|
||||
}
|
||||
|
||||
int us_memsink_fd_get_frame(int fd, us_memsink_shared_s *mem, us_frame_s *frame, u64 *frame_id, bool key_required) {
|
||||
us_frame_set_data(frame, us_memsink_get_data(mem), mem->used);
|
||||
US_FRAME_COPY_META(mem, frame);
|
||||
*frame_id = mem->id;
|
||||
mem->last_client_ts = us_get_now_monotonic();
|
||||
if (key_required) {
|
||||
mem->key_requested = true;
|
||||
}
|
||||
|
||||
bool retval = 0;
|
||||
if (frame->format != V4L2_PIX_FMT_H264) {
|
||||
US_JLOG_ERROR("video", "Got non-H264 frame from memsink");
|
||||
retval = -1;
|
||||
}
|
||||
if (flock(fd, LOCK_UN) < 0) {
|
||||
US_JLOG_PERROR("video", "Can't unlock memsink");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -42,13 +42,13 @@
|
||||
#include "uslibs/errors.h"
|
||||
#include "uslibs/tools.h"
|
||||
#include "uslibs/threading.h"
|
||||
#include "uslibs/logging.h"
|
||||
#include "uslibs/list.h"
|
||||
#include "uslibs/ring.h"
|
||||
#include "uslibs/memsinksh.h"
|
||||
#include "uslibs/memsink.h"
|
||||
#include "uslibs/tc358743.h"
|
||||
|
||||
#include "const.h"
|
||||
#include "logging.h"
|
||||
#include "client.h"
|
||||
#include "au.h"
|
||||
#include "acap.h"
|
||||
@@ -56,7 +56,6 @@
|
||||
#include "rtpv.h"
|
||||
#include "rtpa.h"
|
||||
#include "sdp.h"
|
||||
#include "memsinkfd.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -136,81 +135,53 @@ static void *_video_rtp_thread(void *arg) {
|
||||
|
||||
static void *_video_sink_thread(void *arg) {
|
||||
(void)arg;
|
||||
US_THREAD_SETTLE("us_p_vsink");
|
||||
US_THREAD_SETTLE("us_p_vcap");
|
||||
atomic_store(&_g_video_sink_tid_created, true);
|
||||
|
||||
us_frame_s *drop = us_frame_init();
|
||||
u64 frame_id = 0;
|
||||
us_frame_s *tmp = us_frame_init();
|
||||
int once = 0;
|
||||
|
||||
while (!_STOP) {
|
||||
if (!_HAS_WATCHERS) {
|
||||
US_ONCE({ US_JLOG_INFO("video", "No active watchers, memsink disconnected"); });
|
||||
US_ONCE({ US_LOG_INFO("No active watchers, memsink disconnected"); });
|
||||
usleep(_g_watchers_polling);
|
||||
continue;
|
||||
}
|
||||
|
||||
int fd = -1;
|
||||
us_memsink_shared_s *mem = NULL;
|
||||
|
||||
const uz data_size = us_memsink_calculate_size(_g_config->video_sink_name);
|
||||
if (data_size == 0) {
|
||||
US_ONCE({ US_JLOG_ERROR("video", "Invalid memsink object suffix"); });
|
||||
goto close_memsink;
|
||||
}
|
||||
|
||||
if ((fd = shm_open(_g_config->video_sink_name, O_RDWR, 0)) <= 0) {
|
||||
US_ONCE({ US_JLOG_PERROR("video", "Can't open memsink"); });
|
||||
goto close_memsink;
|
||||
}
|
||||
|
||||
if ((mem = us_memsink_shared_map(fd, data_size)) == NULL) {
|
||||
US_ONCE({ US_JLOG_PERROR("video", "Can't map memsink"); });
|
||||
us_memsink_s *sink = us_memsink_init_opened("vcap", _g_config->video_sink_name, false, 0, false, 0, 1);
|
||||
if (sink == NULL) {
|
||||
goto close_memsink;
|
||||
}
|
||||
|
||||
once = 0;
|
||||
|
||||
US_JLOG_INFO("video", "Memsink opened; reading frames ...");
|
||||
US_LOG_INFO("Memsink opened; reading frames ...");
|
||||
while (!_STOP && _HAS_WATCHERS) {
|
||||
const int waited = us_memsink_fd_wait_frame(fd, mem, frame_id);
|
||||
if (waited == 0) {
|
||||
const int got = us_memsink_client_get(sink, tmp, NULL, atomic_load(&_g_key_required));
|
||||
if (got == 0) {
|
||||
const int ri = us_ring_producer_acquire(_g_video_ring, 0);
|
||||
us_frame_s *frame;
|
||||
if (ri >= 0) {
|
||||
frame = _g_video_ring->items[ri];
|
||||
} else {
|
||||
US_ONCE({ US_JLOG_PERROR("video", "Video ring is full"); });
|
||||
frame = drop;
|
||||
}
|
||||
|
||||
const int got = us_memsink_fd_get_frame(fd, mem, frame, &frame_id, atomic_load(&_g_key_required));
|
||||
if (ri >= 0) {
|
||||
us_frame_s *dest = _g_video_ring->items[ri];
|
||||
us_frame_copy(tmp, dest);
|
||||
us_ring_producer_release(_g_video_ring, ri);
|
||||
if (tmp->key) {
|
||||
atomic_store(&_g_key_required, false);
|
||||
}
|
||||
} else {
|
||||
US_ONCE({ US_LOG_ERROR("Video ring is full"); });
|
||||
}
|
||||
if (got < 0) {
|
||||
goto close_memsink;
|
||||
}
|
||||
|
||||
if (ri >= 0 && frame->key) {
|
||||
atomic_store(&_g_key_required, false);
|
||||
}
|
||||
} else if (waited != US_ERROR_NO_DATA) {
|
||||
} else if (got != US_ERROR_NO_DATA) {
|
||||
goto close_memsink;
|
||||
}
|
||||
}
|
||||
|
||||
close_memsink:
|
||||
if (mem != NULL) {
|
||||
us_memsink_shared_unmap(mem, data_size);
|
||||
mem = NULL;
|
||||
}
|
||||
US_CLOSE_FD(fd);
|
||||
US_JLOG_INFO("video", "Memsink closed");
|
||||
US_DELETE(sink, us_memsink_destroy);
|
||||
US_LOG_INFO("Memsink closed");
|
||||
sleep(1); // error_delay
|
||||
}
|
||||
|
||||
us_frame_destroy(drop);
|
||||
us_frame_destroy(tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -220,17 +191,17 @@ static int _get_acap_hz(uint *hz) {
|
||||
return 0;
|
||||
}
|
||||
if (_g_config->tc358743_dev_path == NULL) {
|
||||
US_JLOG_ERROR("acap", "No configured sampling rate");
|
||||
US_LOG_ERROR("No configured sampling rate");
|
||||
return -1;
|
||||
}
|
||||
int fd;
|
||||
if ((fd = open(_g_config->tc358743_dev_path, O_RDWR)) < 0) {
|
||||
US_JLOG_PERROR("acap", "Can't open TC358743 V4L2 device");
|
||||
US_LOG_PERROR("Can't open TC358743 V4L2 device");
|
||||
return -1;
|
||||
}
|
||||
const int checked = us_tc358743_xioctl_get_audio_hz(fd, hz);
|
||||
if (checked < 0) {
|
||||
US_JLOG_PERROR("acap", "Can't check TC358743 audio state (%d)", checked);
|
||||
US_LOG_PERROR("Can't check TC358743 audio state (%d)", checked);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
@@ -240,7 +211,7 @@ static int _get_acap_hz(uint *hz) {
|
||||
|
||||
static void *_acap_thread(void *arg) {
|
||||
(void)arg;
|
||||
US_THREAD_SETTLE("us_p_ac");
|
||||
US_THREAD_SETTLE("us_p_acap");
|
||||
atomic_store(&_g_acap_tid_created, true);
|
||||
|
||||
assert(_g_config->acap_dev_name != NULL);
|
||||
@@ -258,17 +229,17 @@ static void *_acap_thread(void *arg) {
|
||||
us_acap_s *acap = NULL;
|
||||
|
||||
if (!us_au_probe(_g_config->acap_dev_name)) {
|
||||
US_ONCE({ US_JLOG_ERROR("acap", "No PCM capture device"); });
|
||||
US_ONCE({ US_LOG_ERROR("No PCM capture device"); });
|
||||
goto close_acap;
|
||||
}
|
||||
if (_get_acap_hz(&hz) < 0) {
|
||||
goto close_acap;
|
||||
}
|
||||
if (hz == 0) {
|
||||
US_ONCE({ US_JLOG_INFO("acap", "No audio presented from the host"); });
|
||||
US_ONCE({ US_LOG_INFO("No audio presented from the host"); });
|
||||
goto close_acap;
|
||||
}
|
||||
US_ONCE({ US_JLOG_INFO("acap", "Detected host audio"); });
|
||||
US_ONCE({ US_LOG_INFO("Detected host audio"); });
|
||||
if ((acap = us_acap_init(_g_config->acap_dev_name, hz)) == NULL) {
|
||||
goto close_acap;
|
||||
}
|
||||
@@ -301,7 +272,7 @@ static void *_acap_thread(void *arg) {
|
||||
|
||||
static void *_aplay_thread(void *arg) {
|
||||
(void)arg;
|
||||
US_THREAD_SETTLE("us_p_ap");
|
||||
US_THREAD_SETTLE("us_p_aplay");
|
||||
atomic_store(&_g_aplay_tid_created, true);
|
||||
|
||||
assert(_g_config->aplay_dev_name != NULL);
|
||||
@@ -330,10 +301,10 @@ static void *_aplay_thread(void *arg) {
|
||||
}
|
||||
} while (skip && !_STOP);
|
||||
us_au_pcm_mix(&mixed, &last);
|
||||
// US_JLOG_INFO("++++++", "mixed %p", client);
|
||||
// US_LOG_INFO("++++++ mixed %p", client);
|
||||
});
|
||||
_UNLOCK_APLAY;
|
||||
// US_JLOG_INFO("++++++", "--------------");
|
||||
// US_LOG_INFO("++++++ --------------");
|
||||
|
||||
if (skip) {
|
||||
static uint skipped = 0;
|
||||
@@ -351,13 +322,13 @@ static void *_aplay_thread(void *arg) {
|
||||
|
||||
if (dev == NULL) {
|
||||
if (!us_au_probe(_g_config->aplay_dev_name)) {
|
||||
US_ONCE({ US_JLOG_ERROR("aplay", "No PCM playback device"); });
|
||||
US_ONCE({ US_LOG_ERROR("No PCM playback device"); });
|
||||
goto close_aplay;
|
||||
}
|
||||
|
||||
int err = snd_pcm_open(&dev, _g_config->aplay_dev_name, SND_PCM_STREAM_PLAYBACK, 0);
|
||||
if (err < 0) {
|
||||
US_ONCE({ US_JLOG_PERROR_ALSA(err, "aplay", "Can't open PCM playback"); });
|
||||
US_ONCE({ US_LOG_PERROR_ALSA(err, "Can't open PCM playback"); });
|
||||
goto close_aplay;
|
||||
}
|
||||
|
||||
@@ -365,11 +336,11 @@ static void *_aplay_thread(void *arg) {
|
||||
US_RTP_OPUS_CH, US_RTP_OPUS_HZ, 1 /* soft resample */, 50000 /* 50000 = 0.05sec */
|
||||
);
|
||||
if (err < 0) {
|
||||
US_ONCE({ US_JLOG_PERROR_ALSA(err, "aplay", "Can't configure PCM playback"); });
|
||||
US_ONCE({ US_LOG_PERROR_ALSA(err, "Can't configure PCM playback"); });
|
||||
goto close_aplay;
|
||||
}
|
||||
|
||||
US_JLOG_INFO("aplay", "Playback opened, playing ...");
|
||||
US_LOG_INFO("Playback opened, playing ...");
|
||||
once = 0;
|
||||
}
|
||||
|
||||
@@ -379,20 +350,20 @@ static void *_aplay_thread(void *arg) {
|
||||
frames = snd_pcm_recover(dev, frames, 1);
|
||||
} else {
|
||||
if (once != 0) {
|
||||
US_JLOG_INFO("aplay", "Playing resumed (snd_pcm_writei) ...");
|
||||
US_LOG_INFO("Playing resumed (snd_pcm_writei) ...");
|
||||
}
|
||||
once = 0;
|
||||
skip = false;
|
||||
}
|
||||
if (frames < 0) {
|
||||
US_ONCE({ US_JLOG_PERROR_ALSA(frames, "aplay", "Can't play to PCM playback"); });
|
||||
US_ONCE({ US_LOG_PERROR_ALSA(frames, "Can't play to PCM playback"); });
|
||||
if (frames == -ENODEV) {
|
||||
goto close_aplay;
|
||||
}
|
||||
skip = true;
|
||||
} else {
|
||||
if (once != 0) {
|
||||
US_JLOG_INFO("aplay", "Playing resumed (snd_pcm_recover) ...");
|
||||
US_LOG_INFO("Playing resumed (snd_pcm_recover) ...");
|
||||
}
|
||||
once = 0;
|
||||
skip = false;
|
||||
@@ -403,7 +374,7 @@ static void *_aplay_thread(void *arg) {
|
||||
close_aplay:
|
||||
if (dev != NULL) {
|
||||
US_DELETE(dev, snd_pcm_close);
|
||||
US_JLOG_INFO("aplay", "Playback closed");
|
||||
US_LOG_INFO("Playback closed");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -430,7 +401,9 @@ static int _plugin_init(janus_callbacks *gw, const char *config_dir_path) {
|
||||
// sysctl -w net.core.rmem_max=1000000
|
||||
// sysctl -w net.core.wmem_max=1000000
|
||||
|
||||
US_JLOG_INFO("main", "Initializing PiKVM uStreamer plugin %s ...", US_VERSION);
|
||||
US_LOGGING_INIT;
|
||||
|
||||
US_LOG_INFO("Initializing PiKVM uStreamer plugin %s ...", US_VERSION);
|
||||
if (gw == NULL || config_dir_path == NULL || ((_g_config = us_config_init(config_dir_path)) == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -455,7 +428,7 @@ static int _plugin_init(janus_callbacks *gw, const char *config_dir_path) {
|
||||
}
|
||||
|
||||
static void _plugin_destroy(void) {
|
||||
US_JLOG_INFO("main", "Destroying plugin ...");
|
||||
US_LOG_INFO("Destroying plugin ...");
|
||||
|
||||
atomic_store(&_g_stop, true);
|
||||
# define JOIN(_tid) { if (atomic_load(&_tid##_created)) { US_THREAD_JOIN(_tid); } }
|
||||
@@ -475,12 +448,14 @@ static void _plugin_destroy(void) {
|
||||
US_DELETE(_g_rtpa, us_rtpa_destroy);
|
||||
US_DELETE(_g_rtpv, us_rtpv_destroy);
|
||||
US_DELETE(_g_config, us_config_destroy);
|
||||
|
||||
US_LOGGING_DESTROY;
|
||||
}
|
||||
|
||||
static void _plugin_create_session(janus_plugin_session *session, int *err) {
|
||||
_IF_DISABLED({ *err = -1; return; });
|
||||
_LOCK_ALL;
|
||||
US_JLOG_INFO("main", "Creating session %p ...", session);
|
||||
US_LOG_INFO("Creating session %p ...", session);
|
||||
us_janus_client_s *const client = us_janus_client_init(_g_gw, session);
|
||||
US_LIST_APPEND(_g_clients, client);
|
||||
atomic_store(&_g_has_watchers, true);
|
||||
@@ -496,7 +471,7 @@ static void _plugin_destroy_session(janus_plugin_session* session, int *err) {
|
||||
bool has_speakers = false;
|
||||
US_LIST_ITERATE(_g_clients, client, {
|
||||
if (client->session == session) {
|
||||
US_JLOG_INFO("main", "Removing session %p ...", session);
|
||||
US_LOG_INFO("Removing session %p ...", session);
|
||||
US_LIST_REMOVE(_g_clients, client);
|
||||
us_janus_client_destroy(client);
|
||||
found = true;
|
||||
@@ -507,7 +482,7 @@ static void _plugin_destroy_session(janus_plugin_session* session, int *err) {
|
||||
}
|
||||
});
|
||||
if (!found) {
|
||||
US_JLOG_WARN("main", "No session %p", session);
|
||||
US_LOG_ERROR("No session %p", session);
|
||||
*err = -2;
|
||||
}
|
||||
atomic_store(&_g_has_watchers, has_watchers);
|
||||
@@ -539,13 +514,13 @@ static void _set_transmit(janus_plugin_session *session, const char *msg, bool t
|
||||
US_LIST_ITERATE(_g_clients, client, {
|
||||
if (client->session == session) {
|
||||
atomic_store(&client->transmit, transmit);
|
||||
// US_JLOG_INFO("main", "%s session %p", msg, session);
|
||||
// US_LOG_INFO("%s session %p", msg, session);
|
||||
found = true;
|
||||
}
|
||||
has_watchers = (has_watchers || atomic_load(&client->transmit));
|
||||
});
|
||||
if (!found) {
|
||||
US_JLOG_WARN("main", "No session %p", session);
|
||||
US_LOG_ERROR("No session %p", session);
|
||||
}
|
||||
atomic_store(&_g_has_watchers, has_watchers);
|
||||
_UNLOCK_ALL;
|
||||
@@ -567,7 +542,7 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
}
|
||||
|
||||
# define PUSH_ERROR(x_error, x_reason) { \
|
||||
/*US_JLOG_ERROR("main", "Message error in session %p: %s", session, x_reason);*/ \
|
||||
/*US_LOG_ERROR("Message error in session %p: %s", session, x_reason);*/ \
|
||||
json_t *m_event = json_object(); \
|
||||
json_object_set_new(m_event, "ustreamer", json_string("event")); \
|
||||
json_object_set_new(m_event, "error_code", json_integer(x_error)); \
|
||||
@@ -587,7 +562,7 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
PUSH_ERROR(400, "Request not a string");
|
||||
goto done;
|
||||
}
|
||||
// US_JLOG_INFO("main", "Message: %s", request_str);
|
||||
// US_LOG_INFO("Message: %s", request_str);
|
||||
|
||||
# define PUSH_STATUS(x_status, x_payload, x_jsep) { \
|
||||
json_t *const m_event = json_object(); \
|
||||
@@ -680,7 +655,7 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
json_decref(features);
|
||||
|
||||
} else if (!strcmp(request_str, "key_required")) {
|
||||
// US_JLOG_INFO("main", "Got key_required message");
|
||||
// US_LOG_INFO("Got key_required message");
|
||||
atomic_store(&_g_key_required, true);
|
||||
|
||||
} else {
|
||||
@@ -717,9 +692,7 @@ static void _plugin_incoming_rtp(janus_plugin_session *session, janus_plugin_rtp
|
||||
|
||||
static void _plugin_incoming_rtcp(janus_plugin_session *session, janus_plugin_rtcp *packet) {
|
||||
_IF_DISABLED({ return; });
|
||||
if (session == NULL || packet == NULL /*|| !packet->video*/) {
|
||||
// FIXME: Since Chromium 147 we can't distinguish video/audio packets
|
||||
// so we just disable !package->video condition for now.
|
||||
if (session == NULL || packet == NULL || !packet->video) {
|
||||
return; // Accept only valid video
|
||||
}
|
||||
if (
|
||||
|
||||
1
janus/src/uslibs/logging.c
Symbolic link
1
janus/src/uslibs/logging.c
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../src/libs/logging.c
|
||||
1
janus/src/uslibs/logging.h
Symbolic link
1
janus/src/uslibs/logging.h
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../src/libs/logging.h
|
||||
@@ -20,12 +20,13 @@
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <janus/plugins/plugin.h>
|
||||
|
||||
#include "uslibs/types.h"
|
||||
#include "uslibs/frame.h"
|
||||
#include "uslibs/memsinksh.h"
|
||||
#include "threading.h"
|
||||
|
||||
|
||||
int us_memsink_fd_wait_frame(int fd, us_memsink_shared_s *mem, u64 last_id);
|
||||
int us_memsink_fd_get_frame(int fd, us_memsink_shared_s *mem, us_frame_s *frame, u64 *frame_id, bool key_required);
|
||||
#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \
|
||||
char m_tname_buf[US_THREAD_NAME_SIZE] = {0}; \
|
||||
us_thread_get_name(m_tname_buf); \
|
||||
JANUS_LOG(LOG_INFO, "== ustreamer/%-15s " x_label " -- " x_msg "\n", m_tname_buf, ##__VA_ARGS__); \
|
||||
}
|
||||
1
janus/src/uslibs/memsink.c
Symbolic link
1
janus/src/uslibs/memsink.c
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../src/libs/memsink.c
|
||||
1
janus/src/uslibs/memsink.h
Symbolic link
1
janus/src/uslibs/memsink.h
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../src/libs/memsink.h
|
||||
@@ -9,7 +9,7 @@ RUN pacman -Syu --noconfirm \
|
||||
&& pacman -S --needed --noconfirm \
|
||||
vim \
|
||||
git \
|
||||
libjpeg \
|
||||
libjpeg-turbo \
|
||||
libevent \
|
||||
libutil-linux \
|
||||
libbsd \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Manpage for ustreamer-dump.
|
||||
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
|
||||
.TH USTREAMER-DUMP 1 "version 6.60" "January 2021"
|
||||
.TH USTREAMER-DUMP 1 "version 6.61" "January 2021"
|
||||
|
||||
.SH NAME
|
||||
ustreamer-dump \- Dump uStreamer's memory sink to file
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Manpage for ustreamer.
|
||||
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
|
||||
.TH USTREAMER 1 "version 6.60" "November 2020"
|
||||
.TH USTREAMER 1 "version 6.61" "November 2020"
|
||||
|
||||
.SH NAME
|
||||
ustreamer \- stream MJPEG video from any V4L2 device to the network
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
|
||||
pkgname=ustreamer
|
||||
pkgver=6.60
|
||||
pkgver=6.61
|
||||
pkgrel=1
|
||||
pkgdesc="Lightweight and fast MJPEG-HTTP streamer"
|
||||
url="https://github.com/pikvm/ustreamer"
|
||||
license=(GPL)
|
||||
arch=(i686 x86_64 armv6h armv7h aarch64)
|
||||
depends=(libjpeg libevent libbsd libgpiod systemd)
|
||||
depends=(libjpeg-turbo libevent libbsd libgpiod systemd)
|
||||
makedepends=(gcc make pkgconf systemd)
|
||||
source=(${pkgname}::"git+https://github.com/pikvm/ustreamer#commit=v${pkgver}")
|
||||
md5sums=(SKIP)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ustreamer
|
||||
PKG_VERSION:=6.60
|
||||
PKG_VERSION:=6.61
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def main() -> None:
|
||||
flags = _find_flags()
|
||||
setup(
|
||||
name="ustreamer",
|
||||
version="6.60",
|
||||
version="6.61",
|
||||
description="uStreamer tools",
|
||||
author="Maxim Devaev",
|
||||
author_email="mdevaev@gmail.com",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
#define US_VERSION_MAJOR 6
|
||||
#define US_VERSION_MINOR 60
|
||||
#define US_VERSION_MINOR 61
|
||||
|
||||
#define US_MAKE_VERSION2(_major, _minor) #_major "." #_minor
|
||||
#define US_MAKE_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor)
|
||||
|
||||
@@ -56,7 +56,7 @@ static int _drm_find_sink(us_drm_s *drm, uint width, uint height, float hz);
|
||||
|
||||
static drmModeModeInfo *_find_best_mode(drmModeConnector *conn, uint width, uint height, float hz);
|
||||
static u32 _find_dpms(int fd, drmModeConnector *conn);
|
||||
static u32 _find_crtc(int fd, drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs);
|
||||
static u32 _find_crtc(int fd, const drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs);
|
||||
static const char *_connector_type_to_string(u32 type);
|
||||
static float _get_refresh_rate(const drmModeModeInfo *mode);
|
||||
|
||||
@@ -726,7 +726,7 @@ static u32 _find_dpms(int fd, drmModeConnector *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 _find_crtc(int fd, drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs) {
|
||||
static u32 _find_crtc(int fd, const drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs) {
|
||||
for (int ei = 0; ei < conn->count_encoders; ++ei) {
|
||||
drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[ei]);
|
||||
if (enc == NULL) {
|
||||
|
||||
@@ -112,7 +112,7 @@ void us_frametext_draw(us_frametext_s *ft, const char *text, uint width, uint he
|
||||
}
|
||||
|
||||
char *str = us_strdup(text);
|
||||
char *line;
|
||||
const char *line;
|
||||
char *rest;
|
||||
|
||||
uint block_width = 0;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "types.h"
|
||||
#include "tools.h"
|
||||
#include "threading.h"
|
||||
#include "logging_base.h"
|
||||
|
||||
|
||||
enum us_log_level_t {
|
||||
@@ -72,37 +73,7 @@ extern pthread_mutex_t us_g_log_mutex;
|
||||
#define US_COLOR_RESET "\x1b[0m"
|
||||
|
||||
|
||||
#define US_SEP_INFO(x_ch) { \
|
||||
US_LOGGING_LOCK; \
|
||||
for (int m_i = 0; m_i < 80; ++m_i) { \
|
||||
fputc((x_ch), stderr); \
|
||||
} \
|
||||
fputc('\n', stderr); \
|
||||
fflush(stderr); \
|
||||
US_LOGGING_UNLOCK; \
|
||||
}
|
||||
|
||||
#define US_SEP_DEBUG(x_ch) { \
|
||||
if (us_g_log_level >= US_LOG_LEVEL_DEBUG) { \
|
||||
US_SEP_INFO(x_ch); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \
|
||||
char m_tname_buf[US_THREAD_NAME_SIZE] = {0}; \
|
||||
us_thread_get_name(m_tname_buf); \
|
||||
if (us_g_log_colored) { \
|
||||
fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \
|
||||
" [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \
|
||||
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
|
||||
} else { \
|
||||
fprintf(stderr, "-- " x_label " [%.03Lf %9s] -- " x_msg, \
|
||||
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
|
||||
} \
|
||||
fputc('\n', stderr); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
// XXX: See the definition of US_LOG_PRINTF_NOLOCK() in logging_base.h
|
||||
|
||||
#define US_LOG_PRINTF(x_label_color, x_label, x_msg_color, x_msg, ...) { \
|
||||
US_LOGGING_LOCK; \
|
||||
@@ -110,6 +81,10 @@ extern pthread_mutex_t us_g_log_mutex;
|
||||
US_LOGGING_UNLOCK; \
|
||||
}
|
||||
|
||||
#define US_LOG_SEP_INFO { \
|
||||
US_LOG_PRINTF(US_COLOR_GREEN, "INFO ", US_COLOR_GREEN, "============================================="); \
|
||||
}
|
||||
|
||||
#define US_LOG_ERROR(x_msg, ...) { \
|
||||
US_LOG_PRINTF(US_COLOR_RED, "ERROR", US_COLOR_RED, x_msg, ##__VA_ARGS__); \
|
||||
}
|
||||
@@ -120,6 +95,11 @@ extern pthread_mutex_t us_g_log_mutex;
|
||||
free(m_perror_str); \
|
||||
}
|
||||
|
||||
// We don't include alsa, speex and opus headers here
|
||||
#define US_LOG_PERROR_ALSA(x_err, x_msg, ...) US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, snd_strerror(x_err))
|
||||
#define US_LOG_PERROR_RES(x_err, x_msg, ...) US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, speex_resampler_strerror(x_err))
|
||||
#define US_LOG_PERROR_OPUS(x_err, x_msg, ...) US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, opus_strerror(x_err))
|
||||
|
||||
#define US_LOG_INFO(x_msg, ...) { \
|
||||
US_LOG_PRINTF(US_COLOR_GREEN, "INFO ", "", x_msg, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
@@ -20,24 +20,29 @@
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <janus/plugins/plugin.h>
|
||||
#pragma once
|
||||
|
||||
#include "uslibs/tools.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "const.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "tools.h"
|
||||
#include "threading.h"
|
||||
|
||||
|
||||
#define US_JLOG_INFO(x_prefix, x_msg, ...) JANUS_LOG(LOG_INFO, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__)
|
||||
#define US_JLOG_WARN(x_prefix, x_msg, ...) JANUS_LOG(LOG_WARN, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__)
|
||||
#define US_JLOG_ERROR(x_prefix, x_msg, ...) JANUS_LOG(LOG_ERR, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__)
|
||||
|
||||
#define US_JLOG_PERROR(x_prefix, x_msg, ...) { \
|
||||
char *const m_perror_str = us_errno_to_string(errno); \
|
||||
JANUS_LOG(LOG_ERR, "[%s/%-9s] " x_msg ": %s\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__, m_perror_str); \
|
||||
free(m_perror_str); \
|
||||
#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \
|
||||
char m_tname_buf[US_THREAD_NAME_SIZE] = {0}; \
|
||||
us_thread_get_name(m_tname_buf); \
|
||||
if (us_g_log_colored) { \
|
||||
fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \
|
||||
" [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \
|
||||
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
|
||||
} else { \
|
||||
fprintf(stderr, "-- " x_label " [%.03Lf %9s] -- " x_msg, \
|
||||
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
|
||||
} \
|
||||
fputc('\n', stderr); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
|
||||
// We don't include alsa, speex and opus headers here
|
||||
#define US_JLOG_PERROR_ALSA(_err, _prefix, _msg, ...) US_JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, snd_strerror(_err))
|
||||
#define US_JLOG_PERROR_RES(_err, _prefix, _msg, ...) US_JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, speex_resampler_strerror(_err))
|
||||
#define US_JLOG_PERROR_OPUS(_err, _prefix, _msg, ...) US_JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, opus_strerror(_err))
|
||||
@@ -94,12 +94,12 @@ INLINE void us_thread_get_name(char *name) { // Always required for logging
|
||||
#ifdef WITH_PTHREAD_NP
|
||||
int retval = -1;
|
||||
# if defined(__linux__) || defined (__NetBSD__)
|
||||
retval = pthread_getname_np(pthread_self(), name, US_THREAD_NAME_SIZE - 1);
|
||||
retval = pthread_getname_np(pthread_self(), name, US_THREAD_NAME_SIZE); // Always null-terminated
|
||||
# elif \
|
||||
(defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1103500) \
|
||||
|| (defined(__OpenBSD__) && defined(OpenBSD) && OpenBSD >= 201905) \
|
||||
|| defined(__DragonFly__)
|
||||
pthread_get_name_np(pthread_self(), name, US_THREAD_NAME_SIZE - 1);
|
||||
pthread_get_name_np(pthread_self(), name, US_THREAD_NAME_SIZE); // Also null-terminated
|
||||
if (name[0] != '\0') {
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ void us_stream_loop(us_stream_s *stream) {
|
||||
us_capture_close(cap);
|
||||
|
||||
if (!atomic_load(&run->stop)) {
|
||||
US_SEP_INFO('=');
|
||||
US_LOG_SEP_INFO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user