Verify live Opus output and volume with real null audio devices
This commit is contained in:
1 parent
dd034a9d42
commit
e9982a2db6
2 files changed
+45
-1
No files matched your search
@@ -1,10 +1,14 @@
|
||||
/* Настоящее ядро/actor, подписанный медиаблок и H.264 decoder: каталог до подписки, эпоха, показ и teardown. */
|
||||
#include "../src/streamplayer_window.h"
|
||||
#include "../src/sound_manager.h"
|
||||
#include "../transport/stream_bridge.h"
|
||||
#include <QtTest>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QLabel>
|
||||
#include <QSlider>
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
|
||||
extern "C" {
|
||||
#include "utun_instance.h"
|
||||
@@ -22,6 +26,27 @@ extern "C" {
|
||||
}
|
||||
|
||||
static QList<QByteArray> snapshots;
|
||||
#ifdef TEST_NULL_AUDIO
|
||||
static std::atomic<ma_device_data_proc> originalAudioCallback{nullptr};
|
||||
static std::atomic<uint64_t> nonzeroSamples{0};
|
||||
extern "C" ma_result __real_ma_context_init(const ma_backend*, ma_uint32, const ma_context_config*, ma_context*);
|
||||
extern "C" ma_result __real_ma_device_init(ma_context*, const ma_device_config*, ma_device*);
|
||||
extern "C" ma_result __wrap_ma_context_init(const ma_backend*, ma_uint32, const ma_context_config*, ma_context* context) {
|
||||
ma_backend backend = ma_backend_null; return __real_ma_context_init(&backend, 1, nullptr, context);
|
||||
}
|
||||
static void observeAudio(ma_device* device, void* out, const void* in, ma_uint32 frames) {
|
||||
originalAudioCallback.load()(device, out, in, frames);
|
||||
const auto* pcm = static_cast<const int16_t*>(out);
|
||||
for (unsigned i = 0; i < frames; i++) if (pcm[i]) nonzeroSamples.fetch_add(1);
|
||||
}
|
||||
extern "C" ma_result __wrap_ma_device_init(ma_context* context, const ma_device_config* config, ma_device* device) {
|
||||
ma_device_config copy = *config;
|
||||
if (copy.deviceType == ma_device_type_playback && copy.playback.format == ma_format_s16 && copy.playback.channels == 1) {
|
||||
originalAudioCallback = copy.dataCallback; copy.dataCallback = observeAudio;
|
||||
}
|
||||
return __real_ma_device_init(context, ©, device);
|
||||
}
|
||||
#endif
|
||||
static void sourceEvent(UTUN_INSTANCE*, int type, const uint8_t* data, int size) {
|
||||
if (type == CHAT_EVT_STREAM_SOURCES) snapshots.push_back(QByteArray(reinterpret_cast<const char*>(data), size));
|
||||
}
|
||||
@@ -130,10 +155,24 @@ private slots:
|
||||
AVPacket* packet = av_packet_alloc(); QVERIFY(packet); QCOMPARE(avcodec_receive_packet(context, packet), 0);
|
||||
QByteArray video(reinterpret_cast<const char*>(packet->data), packet->size);
|
||||
av_packet_free(&packet); av_frame_free(&frame); avcodec_free_context(&context);
|
||||
QByteArray audio;
|
||||
#ifdef TEST_NULL_AUDIO
|
||||
QVERIFY(SoundManager::instance()->init());
|
||||
auto* opus = opus_codec_encoder_create(48000, 1); QVERIFY(opus);
|
||||
int16_t pcm[960]; for (unsigned i = 0; i < 960; i++) pcm[i] = static_cast<int16_t>(6000 * std::sin(i * 0.05));
|
||||
uint8_t encoded[1275]; int length = opus_codec_encode(opus, pcm, 960, encoded, sizeof(encoded)); QVERIFY(length > 0);
|
||||
audio = QByteArray(reinterpret_cast<const char*>(encoded), length); opus_codec_encoder_destroy(opus);
|
||||
nonzeroSamples = 0;
|
||||
#endif
|
||||
StreamPlayerWindow window(group, inst->node_id, epoch, "Source");
|
||||
QSignalSpy shown(&window, &StreamPlayerWindow::framePresented); window.show();
|
||||
QTimer sender; connect(&sender, &QTimer::timeout, this, [this, video] { publish(video); }); sender.start(100);
|
||||
QTimer sender; connect(&sender, &QTimer::timeout, this, [this, video, audio] { publish(video, audio); }); sender.start(100);
|
||||
QTRY_VERIFY_WITH_TIMEOUT(shown.count() > 0, 5000);
|
||||
#ifdef TEST_NULL_AUDIO
|
||||
QTRY_VERIFY_WITH_TIMEOUT(nonzeroSamples.load() > 0, 5000);
|
||||
auto* volume = window.findChild<QSlider*>(); QVERIFY(volume); volume->setValue(0);
|
||||
QTest::qWait(50); uint64_t played = nonzeroSamples.load(); QTest::qWait(100); QCOMPARE(nonzeroSamples.load(), played);
|
||||
#endif
|
||||
sender.stop(); window.close(); QTest::qWait(20);
|
||||
stream_info info{}; QCOMPARE(stream_get_info(publisher, &info), STREAM_OK); QCOMPARE(info.owners, 1u);
|
||||
#else
|
||||
@@ -166,6 +205,7 @@ private slots:
|
||||
|
||||
void cleanupTestCase() {
|
||||
poll.stop(); gui_stream_detach(inst); stream_close(publisher); uasync_mark_stopped(ua);
|
||||
SoundManager::instance()->shutdown();
|
||||
utun_instance_destroy(inst); uasync_destroy(ua, 0);
|
||||
QCOMPARE(u_get_allocated_count(), allocations);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user