Skip to content

Commit

Permalink
Add IDR refresh to encoder.
Browse files Browse the repository at this point in the history
  • Loading branch information
Themaister committed Oct 28, 2023
1 parent 01c460d commit 0e7ebfe
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 1 deletion.
16 changes: 15 additions & 1 deletion video/ffmpeg_encode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ bool VideoEncoder::Impl::encode_frame(const uint8_t *buffer, const PlaneLayout *
memcpy(dst_chroma, src_chroma, chroma_width);
}

video.av_frame->pict_type = AV_PICTURE_TYPE_NONE;

if (options.realtime)
{
int64_t target_pts = av_rescale_q_rnd(pts, {1, AV_TIME_BASE}, video.av_ctx->time_base, AV_ROUND_ZERO);
Expand Down Expand Up @@ -527,6 +529,12 @@ bool VideoEncoder::Impl::encode_frame(const uint8_t *buffer, const PlaneLayout *
else
video.av_frame->pts = encode_video_pts++;

// When new stream clients come in we need to force IDR frames.
// This is not necessary for x264 apparently, but NVENC does ...
// Callback is responsible for controlling how often an IDR should be sent.
if (mux_stream_callback && mux_stream_callback->should_force_idr())
video.av_frame->pict_type = AV_PICTURE_TYPE_I;

AVFrame *hw_frame = nullptr;
if (hw.get_hw_device_type() != AV_HWDEVICE_TYPE_NONE)
{
Expand All @@ -544,6 +552,7 @@ bool VideoEncoder::Impl::encode_frame(const uint8_t *buffer, const PlaneLayout *
}

hw_frame->pts = video.av_frame->pts;
hw_frame->pict_type = video.av_frame->pict_type;
}

ret = avcodec_send_frame(video.av_ctx, hw_frame ? hw_frame : video.av_frame);
Expand Down Expand Up @@ -631,7 +640,6 @@ bool VideoEncoder::Impl::drain_packets(CodecStream &stream)
{
if (&stream == &video)
{
// Avoid negative values in the beginning by biasing.
mux_stream_callback->write_video_packet(
stream.av_pkt->pts,
stream.av_pkt->dts,
Expand Down Expand Up @@ -962,6 +970,12 @@ bool VideoEncoder::Impl::init_video_codec()
if (options.low_latency)
av_dict_set_int(&opts, "zerolatency", 1, 0);
}

if ((is_x264 || is_nvenc) && options.low_latency)
{
av_dict_set_int(&opts, "intra-refresh", 1, 0);
av_dict_set_int(&opts, "forced-idr", 1, 0);
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions video/ffmpeg_encode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class MuxStreamCallback
virtual void set_codec_parameters(const pyro_codec_parameters &codec) = 0;
virtual void write_video_packet(int64_t pts, int64_t dts, const void *data, size_t size, bool is_key_frame) = 0;
virtual void write_audio_packet(int64_t pts, int64_t dts, const void *data, size_t size) = 0;
virtual bool should_force_idr() = 0;
};

class VideoEncoder
Expand Down
1 change: 1 addition & 0 deletions video/pyro_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct pyro_progress_report
{
uint64_t total_received_packets;
uint64_t total_dropped_packets;
uint64_t total_received_key_frames;
};

#define PYRO_MAX_UDP_DATAGRAM_SIZE (PYRO_MAX_PAYLOAD_SIZE + sizeof(struct pyro_codec_parameters))
Expand Down

0 comments on commit 0e7ebfe

Please sign in to comment.