|
|
|
|
@ -33,11 +33,8 @@ struct Decoder {
|
|
|
|
|
|
|
|
|
|
class CallVideoEncoderTest : public QObject { |
|
|
|
|
Q_OBJECT |
|
|
|
|
LiveVideoConfig configuration(int codec) { |
|
|
|
|
LiveVideoConfig config; config.width = 640; config.height = 360; config.fps = 30; config.bitrate = 4000000; |
|
|
|
|
config.codec = codec; config.references = 1; config.vbvBits = 1000000; |
|
|
|
|
config.profile = codec == 1 ? LiveVideoProfile::H264ConstrainedBaseline : LiveVideoProfile::H265Main; |
|
|
|
|
config.level = codec == 1 ? 31 : 93; config.backend = codec == 1 ? "libx264" : "libx265"; return config; |
|
|
|
|
call_video_format configuration(int codec) { |
|
|
|
|
return {17, 640, 360, 30, 0, (uint8_t)codec, (uint8_t)(codec == 1 ? 31 : 93), 4000000, 1000000}; |
|
|
|
|
} |
|
|
|
|
private slots: |
|
|
|
|
void initTestCase() { |
|
|
|
|
@ -50,8 +47,13 @@ private slots:
|
|
|
|
|
void switchesAtScheduledIdr() { |
|
|
|
|
QFETCH(int, codec); |
|
|
|
|
auto config = configuration(codec); |
|
|
|
|
if (!avcodec_find_encoder_by_name(config.backend.toLatin1().constData())) QSKIP("Software encoder unavailable"); |
|
|
|
|
CallVideoEncoder encoder; QVERIFY2(encoder.open(config, 17, 4000000), qPrintable(encoder.error())); |
|
|
|
|
if (!avcodec_find_encoder_by_name(codec == 1 ? "libx264" : "libx265")) QSKIP("Software encoder unavailable"); |
|
|
|
|
call_video_caps sender{}, receiver{}; |
|
|
|
|
sender.encode[codec - 1] = receiver.decode[codec - 1] |
|
|
|
|
= {1280, 720, 30, 1280 * 720 * 30, 4000000, 1000000, config.level}; |
|
|
|
|
config.level = 0; QCOMPARE(call_video_choose(&sender, &receiver, &config), codec); |
|
|
|
|
QVERIFY(call_video_format_supported(&sender, &receiver, &config)); |
|
|
|
|
CallVideoEncoder encoder; QVERIFY2(encoder.open(config, 4000000), qPrintable(encoder.error())); |
|
|
|
|
Decoder decoder; QVERIFY(decoder.open(codec)); |
|
|
|
|
QImage image(config.width, config.height, QImage::Format_RGB32); |
|
|
|
|
uint32_t random = 1; unsigned completions = 0; |
|
|
|
|
@ -95,14 +97,16 @@ private slots:
|
|
|
|
|
QCOMPARE(completions, 2u); |
|
|
|
|
} |
|
|
|
|
void keepsOldEncoderAndRejectsInvalidCommands() { |
|
|
|
|
auto config = configuration(1); config.width = 160; config.height = 90; config.bitrate = 500000; |
|
|
|
|
auto config = configuration(1); config.width = 160; config.height = 90; config.generation = 9; config.maximum_bps = 700000; |
|
|
|
|
if (!avcodec_find_encoder_by_name("libx264")) QSKIP("libx264 unavailable"); |
|
|
|
|
CallVideoEncoder encoder; QVERIFY(encoder.open(config, 9, 700000)); |
|
|
|
|
CallVideoEncoder encoder; QVERIFY(encoder.open(config, 500000)); |
|
|
|
|
QImage image(160, 90, QImage::Format_RGB32); image.fill(Qt::blue); |
|
|
|
|
LiveEncodedFrame output; CallVideoRateCompletion completion; |
|
|
|
|
QVERIFY(encoder.encode(image, 100000, false, output, completion)); |
|
|
|
|
QVERIFY(!encoder.requestBitrate(9, 1, 700001)); QVERIFY(!encoder.requestBitrate(9, 1, 299999)); |
|
|
|
|
auto bad = config; bad.backend = "unavailable"; QVERIFY(!encoder.open(bad, 10, 700000)); |
|
|
|
|
auto bad = config; bad.generation = 10; QVERIFY(!encoder.open(bad, 500000, "unavailable")); |
|
|
|
|
bad.width = 1920; bad.height = 1080; QVERIFY(!encoder.open(bad, 500000)); // Level 3.1 не допускает этот размер.
|
|
|
|
|
bad = config; bad.vbv_bits = 14000001; QVERIFY(!encoder.open(bad, 500000)); // CPB level 3.1.
|
|
|
|
|
QVERIFY(encoder.requestBitrate(9, 1, 500000)); // Неизменный target подтверждается на KEY.
|
|
|
|
|
QVERIFY(encoder.encode(image, 133333, false, output, completion)); QVERIFY(!completion.request && !output.key); |
|
|
|
|
QVERIFY(encoder.encode(image, 166666, true, output, completion)); |
|
|
|
|
|