Commit 87624f98 authored by Éloi Bail's avatar Éloi Bail Committed by Guillaume Roguez

daemon: force keyframe rate on encoder at 5 seconds

Some codecs, as h264, use a default keyframe rate based on frame count.
As example, on h264 this rate is one IFrame each 250 frames.
So this rate is sensible to fps changes, that ofen happens with
output type (images, frame size, screen casting, etc).
Using a rate based on fps seems more viable solution.

Moreover, in order to handle video artifacts in case of missed packets,
we want to send more keyframes so that artifacts will be seen for
a shorter period.

Note: the drawback of this solution is an average bitrate higher than
before as I frames are bigger than P frames.

Issue: #79690
Change-Id: I0b9daef8723c84b5998c9eb156d1e73538e8abed
Signed-off-by: Guillaume Roguez's avatarGuillaume Roguez <guillaume.roguez@savoirfairelinux.com>
parent 5edab08f
......@@ -50,6 +50,7 @@ VideoSender::VideoSender(const std::string& dest, const DeviceParams& dev,
, videoEncoder_(new MediaEncoder)
{
videoEncoder_->setDeviceOptions(dev);
keyFrameFreq_ = dev.framerate.numerator() * KEY_FRAME_PERIOD;
videoEncoder_->openOutput(dest.c_str(), args);
videoEncoder_->setInitSeqVal(seqVal);
videoEncoder_->setIOContext(muxContext_);
......@@ -66,10 +67,13 @@ VideoSender::~VideoSender()
void VideoSender::encodeAndSendVideo(VideoFrame& input_frame)
{
bool is_keyframe = forceKeyFrame_ > 0;
bool is_keyframe = forceKeyFrame_ > 0 \
or (keyFrameFreq_ > 0 and (frameNumber_ % keyFrameFreq_) == 0);
if (is_keyframe)
if (is_keyframe) {
RING_DBG("keyframe requested");
--forceKeyFrame_;
}
if (videoEncoder_->encode(input_frame, is_keyframe, frameNumber_++) < 0)
RING_ERR("encoding failed");
......
......@@ -74,6 +74,9 @@ public:
bool useCodec(const AccountVideoCodecInfo* codec) const;
private:
static constexpr int KEYFRAMES_AT_START {3}; // Number of keyframes to enforce at stream startup
static constexpr unsigned KEY_FRAME_PERIOD {5}; // seconds before forcing a keyframe
NON_COPYABLE(VideoSender);
void encodeAndSendVideo(VideoFrame&);
......@@ -82,8 +85,8 @@ private:
std::unique_ptr<MediaIOHandle> muxContext_ = nullptr;
std::unique_ptr<MediaEncoder> videoEncoder_ = nullptr;
static constexpr int KEYFRAMES_AT_START {3}; // Number of keyframes to enforce at stream startup
std::atomic<int> forceKeyFrame_ {KEYFRAMES_AT_START};
int keyFrameFreq_ {0}; // Set keyframe rate, 0 to disable auto-keyframe. Computed in constructor
int64_t frameNumber_ = 0;
std::string sdp_ = "";
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment