|
|
|
@ -82,7 +82,7 @@ StreamPublishEngine::StreamPublishEngine(QObject* parent) : QObject(parent), m(s |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
try { |
|
|
|
try { |
|
|
|
m->probeThread = std::thread([this] { |
|
|
|
m->probeThread = std::thread([this] { |
|
|
|
auto codecs = supported() ? StreamVideoEncoder::available() : QList<int>(); |
|
|
|
auto codecs = supported() ? LiveVideoEncoder::available() : QList<int>(); |
|
|
|
std::lock_guard<std::mutex> guard(m->lock); m->codecs = std::move(codecs); m->probeReady = true; |
|
|
|
std::lock_guard<std::mutex> guard(m->lock); m->codecs = std::move(codecs); m->probeReady = true; |
|
|
|
}); |
|
|
|
}); |
|
|
|
} catch (const std::system_error& error) { |
|
|
|
} catch (const std::system_error& error) { |
|
|
|
@ -415,7 +415,7 @@ void StreamPublishEngine::audioLoop() { |
|
|
|
|
|
|
|
|
|
|
|
void StreamPublishEngine::videoLoop() { |
|
|
|
void StreamPublishEngine::videoLoop() { |
|
|
|
#ifdef HAVE_STREAM_CAPTURE |
|
|
|
#ifdef HAVE_STREAM_CAPTURE |
|
|
|
std::unique_ptr<StreamVideoEncoder> encoder; |
|
|
|
std::unique_ptr<LiveVideoEncoder> encoder; |
|
|
|
StreamPublishConfig encoding; |
|
|
|
StreamPublishConfig encoding; |
|
|
|
QImage lastImage; uint64_t current = 0; uint32_t revision = 0; |
|
|
|
QImage lastImage; uint64_t current = 0; uint32_t revision = 0; |
|
|
|
int64_t lastPts = -1, lastKey = -1000000, next = 0, report = 0; unsigned count = 0, skipped = 0; |
|
|
|
int64_t lastPts = -1, lastKey = -1000000, next = 0, report = 0; unsigned count = 0, skipped = 0; |
|
|
|
@ -438,7 +438,7 @@ void StreamPublishEngine::videoLoop() { |
|
|
|
if (generation == m->generation) { emit configurationChanged(); emit stateChanged(text("Live")); } |
|
|
|
if (generation == m->generation) { emit configurationChanged(); emit stateChanged(text("Live")); } |
|
|
|
}); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
auto candidate = std::make_unique<StreamVideoEncoder>(); |
|
|
|
auto candidate = std::make_unique<LiveVideoEncoder>(); |
|
|
|
if (!candidate->open(config.video)) { |
|
|
|
if (!candidate->open(config.video)) { |
|
|
|
QString error = candidate->error(); |
|
|
|
QString error = candidate->error(); |
|
|
|
QMetaObject::invokeMethod(this, [this, generation, error] { sourceFailed(generation, error); }); |
|
|
|
QMetaObject::invokeMethod(this, [this, generation, error] { sourceFailed(generation, error); }); |
|
|
|
@ -475,7 +475,7 @@ void StreamPublishEngine::videoLoop() { |
|
|
|
next = now + 1000000 / config.video.fps; |
|
|
|
next = now + 1000000 / config.video.fps; |
|
|
|
stream_publisher_status status; bool needsKey = gui_stream_publish_status(m->id, status) && status.need_key; |
|
|
|
stream_publisher_status status; bool needsKey = gui_stream_publish_status(m->id, status) && status.need_key; |
|
|
|
bool key = pts - lastKey >= 1000000 || needsKey; |
|
|
|
bool key = pts - lastKey >= 1000000 || needsKey; |
|
|
|
QList<StreamEncodedFrame> output; |
|
|
|
QList<LiveEncodedFrame> output; |
|
|
|
if (!encoder->encode(lastImage, std::max(lastPts + 1, pts), key, output)) { |
|
|
|
if (!encoder->encode(lastImage, std::max(lastPts + 1, pts), key, output)) { |
|
|
|
QString error = encoder->error(); QMetaObject::invokeMethod(this, [this, generation, error] { sourceFailed(generation, error); }); continue; |
|
|
|
QString error = encoder->error(); QMetaObject::invokeMethod(this, [this, generation, error] { sourceFailed(generation, error); }); continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|