Generate continuous stereo Opus in live playback regression
This commit is contained in:
1 parent
727106f4e9
commit
50005b108f
2 files changed
+28
-18
No files matched your search
@@ -87,7 +87,7 @@ class StreamViewTest : public QObject {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop test missing record id=%llu", (unsigned long long)id); return false;
|
||||
}
|
||||
|
||||
void publish(const QByteArray& video, const QByteArray& audio = {}, unsigned videoFrames = 1) {
|
||||
void publish(const QByteArray& video, const QList<QByteArray>& audio = {}, unsigned videoFrames = 1) {
|
||||
stream_media_block media{}; media.format = {160, 90, rotation, STREAM_MEDIA_H264, STREAM_MEDIA_OPUS_STEREO, revision};
|
||||
mediaPts += 100000;
|
||||
media.first_frame_offset = 0; media.video_count = videoFrames;
|
||||
@@ -95,9 +95,9 @@ class StreamViewTest : public QObject {
|
||||
static_cast<uint32_t>(video.size()), 0, static_cast<uint32_t>(video.size()), STREAM_MEDIA_KEY,
|
||||
reinterpret_cast<const uint8_t*>(video.constData())};
|
||||
if (!audio.isEmpty()) {
|
||||
media.audio_count = videoFrames > 1 ? 5 : 1;
|
||||
media.audio_count = audio.size();
|
||||
for (unsigned i = 0; i < media.audio_count; i++) media.audio[i] = {mediaPts + i * 20000,
|
||||
static_cast<uint32_t>(audio.size()), 960, reinterpret_cast<const uint8_t*>(audio.constData())};
|
||||
static_cast<uint32_t>(audio[i].size()), 960, reinterpret_cast<const uint8_t*>(audio[i].constData())};
|
||||
}
|
||||
uint8_t wire[7080]; size_t length = 0;
|
||||
QCOMPARE(stream_media_encode(&media, wire, sizeof(wire), &length), STREAM_OK);
|
||||
@@ -146,7 +146,7 @@ private slots:
|
||||
void mediaAndPressure() {
|
||||
QVERIFY(gui_stream_open(102, group, inst->node_id, epoch)); StreamRecord event;
|
||||
QVERIFY(receive(102, event)); QCOMPARE(event.kind, StreamRecordKind::Opened);
|
||||
const QByteArray frame(1500, 'k'); const QByteArray audio("opus"); publish(frame, audio);
|
||||
const QByteArray frame(1500, 'k'); const QByteArray audio("opus"); publish(frame, {audio});
|
||||
QVERIFY(receive(102, event)); QCOMPARE(event.kind, StreamRecordKind::Video); QCOMPARE(event.data, frame);
|
||||
QCOMPARE(event.format.rotation, uint16_t(90));
|
||||
QVERIFY(receive(102, event)); QCOMPARE(event.kind, StreamRecordKind::Audio); QCOMPARE(event.data, audio);
|
||||
@@ -176,24 +176,33 @@ 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;
|
||||
std::unique_ptr<opus_codec_encoder_t, decltype(&opus_codec_encoder_destroy)> opus(nullptr, opus_codec_encoder_destroy);
|
||||
uint64_t sampleFrame = 0;
|
||||
#ifdef TEST_NULL_AUDIO
|
||||
QVERIFY(SoundManager::instance()->init());
|
||||
auto* opus = opus_codec_encoder_create(48000, 2); QVERIFY(opus);
|
||||
QCOMPARE(opus_codec_encoder_application_set(opus, OPUS_CODEC_APP_AUDIO), 0);
|
||||
QCOMPARE(opus_codec_encoder_bitrate_set(opus, 128000), 0);
|
||||
int16_t pcm[1920];
|
||||
for (unsigned i = 0; i < 960; i++) {
|
||||
pcm[2 * i] = static_cast<int16_t>(6000 * std::sin(i * 0.05));
|
||||
pcm[2 * i + 1] = static_cast<int16_t>(1500 * std::sin(i * 0.13));
|
||||
}
|
||||
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);
|
||||
opus.reset(opus_codec_encoder_create(48000, 2)); QVERIFY(opus);
|
||||
QCOMPARE(opus_codec_encoder_application_set(opus.get(), OPUS_CODEC_APP_AUDIO), 0);
|
||||
QCOMPARE(opus_codec_encoder_bitrate_set(opus.get(), 128000), 0);
|
||||
nonzeroSamples = 0; leftEnergy = rightEnergy = 0; playbackDelayUs = 200000;
|
||||
#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, audio] { publish(video, audio, 3); }); sender.start(100);
|
||||
QTimer sender;
|
||||
connect(&sender, &QTimer::timeout, this, [this, video, &opus, &sampleFrame] {
|
||||
QList<QByteArray> packets;
|
||||
if (opus) for (unsigned frame = 0; frame < 5; frame++) {
|
||||
int16_t pcm[1920]; uint8_t encoded[1275];
|
||||
for (unsigned i = 0; i < 960; i++) {
|
||||
pcm[2 * i] = static_cast<int16_t>(6000 * std::sin((sampleFrame + i) * 0.05));
|
||||
pcm[2 * i + 1] = static_cast<int16_t>(1500 * std::sin((sampleFrame + i) * 0.13));
|
||||
}
|
||||
sampleFrame += 960;
|
||||
int length = opus_codec_encode(opus.get(), pcm, 960, encoded, sizeof(encoded)); QVERIFY(length > 0);
|
||||
packets.append(QByteArray(reinterpret_cast<const char*>(encoded), length));
|
||||
}
|
||||
publish(video, packets, 3);
|
||||
});
|
||||
sender.start(100);
|
||||
QTRY_VERIFY_WITH_TIMEOUT(shown.count() > 0, 5000);
|
||||
int beforeSteady = shown.count(); QTest::qWait(1500);
|
||||
QVERIFY2(shown.count() >= beforeSteady + 30, "30fps video must keep advancing with 200ms physical audio latency");
|
||||
@@ -204,6 +213,9 @@ private slots:
|
||||
#ifdef TEST_NULL_AUDIO
|
||||
QTRY_VERIFY_WITH_TIMEOUT(nonzeroSamples.load() > 0, 5000);
|
||||
QVERIFY(rightEnergy.load() > 0);
|
||||
qInfo("Stereo playback energies: left=%llu right=%llu ratio=%.3f",
|
||||
(unsigned long long)leftEnergy.load(), (unsigned long long)rightEnergy.load(),
|
||||
static_cast<double>(leftEnergy.load()) / rightEnergy.load());
|
||||
QVERIFY2(leftEnergy.load() > rightEnergy.load() * 8 && leftEnergy.load() < rightEnergy.load() * 25,
|
||||
"Independent stereo channels must reach the playback device without downmix");
|
||||
auto* volume = window.findChild<QSlider*>(); QVERIFY(volume); volume->setValue(0);
|
||||
|
||||
Reference in new issue
Block a user