Expose radio compressor settings to publication workers
This commit is contained in:
1 parent
125f740a5f
commit
77acdb2d65
3 files changed
+39
No files matched your search
@@ -4,6 +4,7 @@
|
|||||||
#include "../../lib/debug_config.h"
|
#include "../../lib/debug_config.h"
|
||||||
#include "../../lib/u_async.h"
|
#include "../../lib/u_async.h"
|
||||||
#include "../utun_instance.h"
|
#include "../utun_instance.h"
|
||||||
|
#include "../chat/chat_setting.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "stream_network.h"
|
#include "stream_network.h"
|
||||||
#include "stream_publisher.h"
|
#include "stream_publisher.h"
|
||||||
@@ -82,6 +83,9 @@ static void publisher_stats(void *arg) {
|
|||||||
pthread_mutex_lock(&p->lock); p->stats_timer = NULL;
|
pthread_mutex_lock(&p->lock); p->stats_timer = NULL;
|
||||||
if (p->handle && stream_handle_active(p->handle)) {
|
if (p->handle && stream_handle_active(p->handle)) {
|
||||||
uint64_t now = get_time_us(); struct etcp_tx_snapshot transport; struct stream_info info;
|
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) {
|
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.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);
|
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);
|
publisher_close(p, p->stopping ? 0 : STREAM_CLOSE_FAILED);
|
||||||
} else {
|
} else {
|
||||||
p->status.epoch = info.descriptor.source_epoch; p->status.state = STREAM_PUBLISHER_LIVE;
|
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");
|
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); }
|
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",
|
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "publisher opened id=%llu group=%llx epoch=%llx codec=%u size=%ux%u audio=%u",
|
||||||
|
|||||||
@@ -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;
|
uint64_t id, epoch, sample_us, video_bytes, audio_bytes, stream_bytes, transport_bytes, inflight_bytes, acked_1s, total_bytes;
|
||||||
unsigned connections;
|
unsigned connections;
|
||||||
int state, reason, need_key;
|
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);
|
int stream_publisher_create(struct stream_publisher **out, struct UTUN_INSTANCE *inst);
|
||||||
void stream_publisher_destroy(struct stream_publisher *publisher);
|
void stream_publisher_destroy(struct stream_publisher *publisher);
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/* FFmpeg live encoder: один worker владеет контекстом, конвертером и decoder configuration.
|
||||||
|
* open/encode/close последовательны; каждый KEY содержит uAV2 envelope. Пакеты имеют capture PTS.
|
||||||
|
* Encoder открывается по фактическим возможностям; GPU имеет приоритет, затем software того же кодека. */
|
||||||
|
#pragma once
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
#include <memory>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
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<StreamEncodedFrame>& output);
|
||||||
|
QString error() const;
|
||||||
|
QString name() const;
|
||||||
|
static QList<int> available(); // реальная проба открытия и первого KEY; вызывать вне GUI
|
||||||
|
static QString codecName(int codec);
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> m;
|
||||||
|
};
|
||||||
Reference in new issue
Block a user