|
|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
/* Настоящие encoder/decoder: отложенное переключение 4M -> 300k -> 4M,
|
|
|
|
|
* один decoder на весь поток, непрерывные capture PTS и измеренный bitrate. */ |
|
|
|
|
#include <QtTest> |
|
|
|
|
#include <QScopeGuard> |
|
|
|
|
#include <clocale> |
|
|
|
|
#include "../src/call_video_encoder.h" |
|
|
|
|
#include "../src/call_video_decoder.h" |
|
|
|
|
#include "../../../src/call/call_video_bitstream.h" |
|
|
|
|
@ -46,6 +48,32 @@ private slots:
|
|
|
|
|
void switchesAtScheduledIdr_data() { |
|
|
|
|
QTest::addColumn<int>("codec"); QTest::newRow("H264") << 1; QTest::newRow("H265") << 2; |
|
|
|
|
} |
|
|
|
|
void levelIndependentOfLocale_data() { |
|
|
|
|
QTest::addColumn<int>("codec"); QTest::addColumn<QByteArray>("locale"); |
|
|
|
|
for (int codec : {1, 2}) for (const auto& locale : {QByteArray("C"), QByteArray("ru_RU.UTF-8")}) |
|
|
|
|
QTest::newRow(qPrintable(QString("codec%1-%2").arg(codec).arg(QString::fromLatin1(locale)))) << codec << locale; |
|
|
|
|
} |
|
|
|
|
void levelIndependentOfLocale() { |
|
|
|
|
QFETCH(int, codec); QFETCH(QByteArray, locale); |
|
|
|
|
QByteArray previous = std::setlocale(LC_NUMERIC, nullptr); |
|
|
|
|
auto restore = qScopeGuard([previous] { std::setlocale(LC_NUMERIC, previous.constData()); }); |
|
|
|
|
if (!std::setlocale(LC_NUMERIC, locale.constData())) QSKIP("Requested numeric locale is not installed"); |
|
|
|
|
if (!avcodec_find_encoder_by_name(codec == 1 ? "libx264" : "libx265")) QSKIP("Software encoder unavailable"); |
|
|
|
|
auto config = configuration(codec); config.width = 1280; config.height = 720; |
|
|
|
|
CallVideoEncoder encoder; QVERIFY2(encoder.open(config, 1000000), qPrintable(encoder.error())); |
|
|
|
|
Decoder decoder; QVERIFY(decoder.open(codec)); |
|
|
|
|
QImage image(config.width, config.height, QImage::Format_RGB32); image.fill(Qt::blue); |
|
|
|
|
uint64_t pts = 1000000, request = 0; |
|
|
|
|
for (uint32_t bitrate : {1000000u, 300000u, 4000000u}) { |
|
|
|
|
QVERIFY(encoder.requestBitrate(config.generation, ++request, bitrate)); |
|
|
|
|
LiveEncodedFrame output; CallVideoRateCompletion completion; |
|
|
|
|
QVERIFY2(encoder.encode(image, pts, true, output, completion), qPrintable(encoder.error())); |
|
|
|
|
QCOMPARE(completion.request, request); QCOMPARE(completion.bitrate, bitrate); |
|
|
|
|
QVERIFY(decoder.decode(output)); QCOMPARE(decoder.context->level, int(config.level)); |
|
|
|
|
QCOMPARE(decoder.frame->width, 1280); QCOMPARE(decoder.frame->height, 720); |
|
|
|
|
pts += 1000000; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void independentDecoders() { |
|
|
|
|
auto caps = CallVideoDecoder::capabilities(); |
|
|
|
|
QCOMPARE(caps.decode[0].profiles, uint8_t(3)); QCOMPARE(caps.decode[1].profiles, uint8_t(1)); |
|
|
|
|
|