feat(audio): allow sending continuous audio (#4261)
This commit is contained in:
parent
246d8f179f
commit
fbcf2116c2
10 changed files with 24 additions and 10 deletions
|
|
@ -193,7 +193,8 @@ namespace audio {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frame_size = config.packetDuration * stream.sampleRate / 1000;
|
auto frame_size = config.packetDuration * stream.sampleRate / 1000;
|
||||||
auto mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size);
|
bool continuous_audio = config.flags[config_t::CONTINUOUS_AUDIO];
|
||||||
|
auto mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size, continuous_audio);
|
||||||
if (!mic) {
|
if (!mic) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +231,7 @@ namespace audio {
|
||||||
BOOST_LOG(info) << "Reinitializing audio capture"sv;
|
BOOST_LOG(info) << "Reinitializing audio capture"sv;
|
||||||
mic.reset();
|
mic.reset();
|
||||||
do {
|
do {
|
||||||
mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size);
|
mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size, continuous_audio);
|
||||||
if (!mic) {
|
if (!mic) {
|
||||||
BOOST_LOG(warning) << "Couldn't re-initialize audio input"sv;
|
BOOST_LOG(warning) << "Couldn't re-initialize audio input"sv;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ namespace audio {
|
||||||
HIGH_QUALITY, ///< High quality audio
|
HIGH_QUALITY, ///< High quality audio
|
||||||
HOST_AUDIO, ///< Host audio
|
HOST_AUDIO, ///< Host audio
|
||||||
CUSTOM_SURROUND_PARAMS, ///< Custom surround parameters
|
CUSTOM_SURROUND_PARAMS, ///< Custom surround parameters
|
||||||
|
CONTINUOUS_AUDIO, ///< Continuous audio
|
||||||
MAX_FLAGS ///< Maximum number of flags
|
MAX_FLAGS ///< Maximum number of flags
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,7 @@ namespace nvhttp {
|
||||||
launch_session->enable_sops = util::from_view(get_arg(args, "sops", "0"));
|
launch_session->enable_sops = util::from_view(get_arg(args, "sops", "0"));
|
||||||
launch_session->surround_info = util::from_view(get_arg(args, "surroundAudioInfo", "196610"));
|
launch_session->surround_info = util::from_view(get_arg(args, "surroundAudioInfo", "196610"));
|
||||||
launch_session->surround_params = (get_arg(args, "surroundParams", ""));
|
launch_session->surround_params = (get_arg(args, "surroundParams", ""));
|
||||||
|
launch_session->continuous_audio = util::from_view(get_arg(args, "continuousAudio", "0"));
|
||||||
launch_session->gcmap = util::from_view(get_arg(args, "gcmap", "0"));
|
launch_session->gcmap = util::from_view(get_arg(args, "gcmap", "0"));
|
||||||
launch_session->enable_hdr = util::from_view(get_arg(args, "hdrMode", "0"));
|
launch_session->enable_hdr = util::from_view(get_arg(args, "hdrMode", "0"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -554,7 +554,7 @@ namespace platf {
|
||||||
public:
|
public:
|
||||||
virtual int set_sink(const std::string &sink) = 0;
|
virtual int set_sink(const std::string &sink) = 0;
|
||||||
|
|
||||||
virtual std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) = 0;
|
virtual std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if the audio sink is available in the system.
|
* @brief Check if the audio sink is available in the system.
|
||||||
|
|
|
||||||
|
|
@ -440,7 +440,7 @@ namespace platf {
|
||||||
return monitor_name;
|
return monitor_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
|
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous_audio) override {
|
||||||
// Sink choice priority:
|
// Sink choice priority:
|
||||||
// 1. Config sink
|
// 1. Config sink
|
||||||
// 2. Last sink swapped to (Usually virtual in this case)
|
// 2. Last sink swapped to (Usually virtual in this case)
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ namespace platf {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
|
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous_audio) override {
|
||||||
auto mic = std::make_unique<av_mic_t>();
|
auto mic = std::make_unique<av_mic_t>();
|
||||||
const char *audio_sink = "";
|
const char *audio_sink = "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -432,7 +432,11 @@ namespace platf::audio {
|
||||||
// Refill the sample buffer if needed
|
// Refill the sample buffer if needed
|
||||||
while (sample_buf_pos - std::begin(sample_buf) < sample_size) {
|
while (sample_buf_pos - std::begin(sample_buf) < sample_size) {
|
||||||
auto capture_result = _fill_buffer();
|
auto capture_result = _fill_buffer();
|
||||||
if (capture_result != capture_e::ok) {
|
if (capture_result == capture_e::timeout && continuous_audio) {
|
||||||
|
// Write silence to sample_buf
|
||||||
|
std::fill_n(sample_buf_pos, sample_size, 0.0f);
|
||||||
|
sample_buf_pos += sample_size;
|
||||||
|
} else if (capture_result != capture_e::ok) {
|
||||||
return capture_result;
|
return capture_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -447,7 +451,7 @@ namespace platf::audio {
|
||||||
return capture_e::ok;
|
return capture_e::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init(std::uint32_t sample_rate, std::uint32_t frame_size, std::uint32_t channels_out) {
|
int init(std::uint32_t sample_rate, std::uint32_t frame_size, std::uint32_t channels_out, bool continuous) {
|
||||||
audio_event.reset(CreateEventA(nullptr, FALSE, FALSE, nullptr));
|
audio_event.reset(CreateEventA(nullptr, FALSE, FALSE, nullptr));
|
||||||
if (!audio_event) {
|
if (!audio_event) {
|
||||||
BOOST_LOG(error) << "Couldn't create Event handle"sv;
|
BOOST_LOG(error) << "Couldn't create Event handle"sv;
|
||||||
|
|
@ -508,6 +512,7 @@ namespace platf::audio {
|
||||||
REFERENCE_TIME default_latency;
|
REFERENCE_TIME default_latency;
|
||||||
audio_client->GetDevicePeriod(&default_latency, nullptr);
|
audio_client->GetDevicePeriod(&default_latency, nullptr);
|
||||||
default_latency_ms = default_latency / 1000;
|
default_latency_ms = default_latency / 1000;
|
||||||
|
continuous_audio = continuous;
|
||||||
|
|
||||||
std::uint32_t frames;
|
std::uint32_t frames;
|
||||||
status = audio_client->GetBufferSize(&frames);
|
status = audio_client->GetBufferSize(&frames);
|
||||||
|
|
@ -678,6 +683,7 @@ namespace platf::audio {
|
||||||
util::buffer_t<float> sample_buf;
|
util::buffer_t<float> sample_buf;
|
||||||
float *sample_buf_pos;
|
float *sample_buf_pos;
|
||||||
int channels;
|
int channels;
|
||||||
|
bool continuous_audio;
|
||||||
|
|
||||||
HANDLE mmcss_task_handle = nullptr;
|
HANDLE mmcss_task_handle = nullptr;
|
||||||
};
|
};
|
||||||
|
|
@ -761,10 +767,10 @@ namespace platf::audio {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override {
|
std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous_audio) override {
|
||||||
auto mic = std::make_unique<mic_wasapi_t>();
|
auto mic = std::make_unique<mic_wasapi_t>();
|
||||||
|
|
||||||
if (mic->init(sample_rate, frame_size, channels)) {
|
if (mic->init(sample_rate, frame_size, channels, continuous_audio)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1030,6 +1030,10 @@ namespace rtsp_stream {
|
||||||
}
|
}
|
||||||
config.audio.flags[audio::config_t::CUSTOM_SURROUND_PARAMS] = valid;
|
config.audio.flags[audio::config_t::CUSTOM_SURROUND_PARAMS] = valid;
|
||||||
}
|
}
|
||||||
|
if (session.continuous_audio) {
|
||||||
|
BOOST_LOG(info) << "Client requested continuous audio"sv;
|
||||||
|
config.audio.flags[audio::config_t::CONTINUOUS_AUDIO] = true;
|
||||||
|
}
|
||||||
|
|
||||||
// If the client sent a configured bitrate, we will choose the actual bitrate ourselves
|
// If the client sent a configured bitrate, we will choose the actual bitrate ourselves
|
||||||
// by using FEC percentage and audio quality settings. If the calculated bitrate ends up
|
// by using FEC percentage and audio quality settings. If the calculated bitrate ends up
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ namespace rtsp_stream {
|
||||||
int appid;
|
int appid;
|
||||||
int surround_info;
|
int surround_info;
|
||||||
std::string surround_params;
|
std::string surround_params;
|
||||||
|
bool continuous_audio;
|
||||||
bool enable_hdr;
|
bool enable_hdr;
|
||||||
bool enable_sops;
|
bool enable_sops;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ struct AudioTest: PlatformTestSuite, testing::WithParamInterface<std::tuple<std:
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::bitset<config_t::MAX_FLAGS> config_flags(const int flag = -1) {
|
constexpr std::bitset<config_t::MAX_FLAGS> config_flags(const int flag = -1) {
|
||||||
std::bitset<3> result = std::bitset<config_t::MAX_FLAGS>();
|
auto result = std::bitset<config_t::MAX_FLAGS>();
|
||||||
if (flag >= 0) {
|
if (flag >= 0) {
|
||||||
result.set(flag);
|
result.set(flag);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue