diff --git a/src/stream/stream_publisher.c b/src/stream/stream_publisher.c index c4399463..dddad047 100644 --- a/src/stream/stream_publisher.c +++ b/src/stream/stream_publisher.c @@ -4,6 +4,7 @@ #include "../../lib/debug_config.h" #include "../../lib/u_async.h" #include "../utun_instance.h" +#include "../chat/chat_setting.h" #include "stream.h" #include "stream_network.h" #include "stream_publisher.h" @@ -82,6 +83,9 @@ static void publisher_stats(void *arg) { pthread_mutex_lock(&p->lock); p->stats_timer = NULL; if (p->handle && stream_handle_active(p->handle)) { uint64_t now = get_time_us(); struct etcp_tx_snapshot transport; struct stream_info info; + p->status.compressor_enabled = chat_setting_get_int(p->inst, "radio_compressor_enabled", 1); + p->status.compressor_max_gain_db = chat_setting_get_int(p->inst, "radio_compressor_max_gain_db", 15); + p->status.compressor_rise_rate = chat_setting_get_int(p->inst, "compressor_rise_rate", 2); if (etcp_tx_get_snapshot(p->inst, now, &transport) == 0 && stream_get_info(p->handle, &info) == STREAM_OK) { p->status.sample_us = now; p->status.video_bytes = p->video.bytes - (p->video.head ? p->video.head->offset : 0); p->status.audio_bytes = p->audio.bytes; p->status.stream_bytes = stream_network_pending_bytes(p->inst, &info.descriptor); @@ -155,6 +159,9 @@ static void publisher_process(void *arg) { publisher_close(p, p->stopping ? 0 : STREAM_CLOSE_FAILED); } else { p->status.epoch = info.descriptor.source_epoch; p->status.state = STREAM_PUBLISHER_LIVE; + p->status.compressor_enabled = chat_setting_get_int(p->inst, "radio_compressor_enabled", 1); + p->status.compressor_max_gain_db = chat_setting_get_int(p->inst, "radio_compressor_max_gain_db", 15); + p->status.compressor_rise_rate = chat_setting_get_int(p->inst, "compressor_rise_rate", 2); p->stats_timer = uasync_set_timeout(p->inst->ua, 1000, p, publisher_stats, "publisher_stats"); if (!p->stats_timer) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "publisher stats start failed"); publisher_close(p, STREAM_CLOSE_FAILED); } DEBUG_INFO(DEBUG_CATEGORY_STREAM, "publisher opened id=%llu group=%llx epoch=%llx codec=%u size=%ux%u audio=%u", diff --git a/src/stream/stream_publisher.h b/src/stream/stream_publisher.h index f8050793..ad7f78cf 100644 --- a/src/stream/stream_publisher.h +++ b/src/stream/stream_publisher.h @@ -17,6 +17,7 @@ struct stream_publisher_status { uint64_t id, epoch, sample_us, video_bytes, audio_bytes, stream_bytes, transport_bytes, inflight_bytes, acked_1s, total_bytes; unsigned connections; int state, reason, need_key; + int compressor_enabled, compressor_max_gain_db, compressor_rise_rate; }; int stream_publisher_create(struct stream_publisher **out, struct UTUN_INSTANCE *inst); void stream_publisher_destroy(struct stream_publisher *publisher); diff --git a/tools/chatgui/src/stream_video_encoder.h b/tools/chatgui/src/stream_video_encoder.h new file mode 100644 index 00000000..81dbe4d4 --- /dev/null +++ b/tools/chatgui/src/stream_video_encoder.h @@ -0,0 +1,31 @@ +/* FFmpeg live encoder: один worker владеет контекстом, конвертером и decoder configuration. + * open/encode/close последовательны; каждый KEY содержит uAV2 envelope. Пакеты имеют capture PTS. + * Encoder открывается по фактическим возможностям; GPU имеет приоритет, затем software того же кодека. */ +#pragma once +#include +#include +#include +#include +#include +#include + +struct StreamVideoConfig { + int width = 1280, height = 720, fps = 30, bitrate = 2500000, codec = 1, rotation = 0; + bool operator==(const StreamVideoConfig&) const = default; +}; +struct StreamEncodedFrame { QByteArray data; uint64_t pts = 0; bool key = false; }; +class StreamVideoEncoder { +public: + StreamVideoEncoder(); + ~StreamVideoEncoder(); + bool open(const StreamVideoConfig& config); + void close(); + bool encode(const QImage& image, uint64_t pts, bool key, QList& output); + QString error() const; + QString name() const; + static QList available(); // реальная проба открытия и первого KEY; вызывать вне GUI + static QString codecName(int codec); +private: + struct Impl; + std::unique_ptr m; +};