Skip to content
Snippets Groups Projects
Commit 87624f98 authored by Eloi Bail's avatar Eloi Bail Committed by Guillaume Roguez
Browse files

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: default avatarGuillaume Roguez <guillaume.roguez@savoirfairelinux.com>
parent 5edab08f
Branches
Tags
No related merge requests found
......@@ -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_ = "";
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment