Browse Source

Validate publisher lifecycle in optional codec builds

master
evgeny 6 days ago
parent
commit
f85f45fbd3
  1. 18
      tools/chatgui/tests/test_stream_publish.cpp

18
tools/chatgui/tests/test_stream_publish.cpp

@ -64,12 +64,17 @@ class StreamPublishTest : public QObject {
uint64_t group = 0;
size_t allocations = 0;
static QByteArray keyframe(int codec, int width = 160, int height = 90, uint64_t pts = 100000) {
#ifndef HAVE_FFMPEG
Q_UNUSED(codec); Q_UNUSED(width); Q_UNUSED(height); Q_UNUSED(pts);
return QByteArray(4, '\0') + "opaque access unit";
#else
StreamVideoEncoder encoder; StreamVideoConfig config; config.width = width; config.height = height; config.codec = codec;
if (!encoder.open(config)) return {};
QImage image(width, height, QImage::Format_RGB32); image.fill(QColor(45, 130, 220));
QList<StreamEncodedFrame> output;
if (!encoder.encode(image, pts, true, output) || output.isEmpty() || !output.front().key) return {};
return output.front().data;
#endif
}
bool record(uint64_t id, StreamRecordKind kind, StreamRecord& out) {
QElapsedTimer elapsed; elapsed.start();
@ -110,11 +115,14 @@ private slots:
}
void encoderRoundTrip_data() {
QTest::addColumn<int>("codec");
for (int codec : StreamVideoEncoder::available()) QTest::newRow(qPrintable(StreamVideoEncoder::codecName(codec))) << codec;
auto codecs = StreamVideoEncoder::available();
if (codecs.isEmpty()) QTest::newRow("unavailable") << 0;
for (int codec : codecs) QTest::newRow(qPrintable(StreamVideoEncoder::codecName(codec))) << codec;
}
void encoderRoundTrip() {
#ifdef HAVE_FFMPEG
QFETCH(int, codec); auto encoded = keyframe(codec); QVERIFY(!encoded.isEmpty());
QFETCH(int, codec); if (!codec) QSKIP("No supported encoder");
auto encoded = keyframe(codec); QVERIFY(!encoded.isEmpty());
const uint8_t *config = nullptr, *frame = nullptr; size_t configLength = 0, frameLength = 0;
QCOMPARE(stream_media_key_parse((const uint8_t*)encoded.constData(), encoded.size(), &config, &configLength, &frame, &frameLength), STREAM_OK);
const char* names[] = {"", "h264", "hevc", "vp9", "av1", "vvc"};
@ -180,14 +188,14 @@ private slots:
QSignalSpy errors(&engine, &StreamPublishEngine::errorOccurred);
QVERIFY(engine.start(group, config));
QTRY_VERIFY_WITH_TIMEOUT(engine.config().video.codec == STREAM_MEDIA_H264, 10000);
char* sources = nullptr; uint64_t epoch = 0;
uint64_t epoch = 0;
QElapsedTimer wait; wait.start();
while (!epoch && wait.elapsed() < 5000) {
stream_member_state member{};
if (stream_member_load(inst, group, inst->node_id, &member, nullptr) == STREAM_OK && member.published) epoch = member.source.source_epoch;
QTest::qWait(1);
}
Q_UNUSED(sources); QVERIFY(epoch); QVERIFY(gui_stream_open(202, group, inst->node_id, epoch));
QVERIFY(epoch); QVERIFY(gui_stream_open(202, group, inst->node_id, epoch));
StreamRecord out; QVERIFY(record(202, StreamRecordKind::Opened, out)); QVERIFY(record(202, StreamRecordKind::Video, out));
uint64_t first = out.pts; unsigned audio = 0, video = 0; uint64_t latest = first, left = 0, right = 0;
auto* decoder = opus_codec_decoder_create(48000, 2); QVERIFY(decoder);
@ -236,7 +244,7 @@ private slots:
QVERIFY(!gui_stream_ready()); QVERIFY(gui_stream_attach(inst));
}
void cleanupTestCase() {
poll.stop(); gui_stream_detach(inst); uasync_mark_stopped(ua); utun_instance_destroy(inst); uasync_destroy(ua);
poll.stop(); gui_stream_detach(inst); uasync_mark_stopped(ua); utun_instance_destroy(inst); uasync_destroy(ua, 1);
QCOMPARE(u_get_allocated_count(), allocations);
}
};

Loading…
Cancel
Save