Commit 36fc2a74 authored by George Kiagiadakis's avatar George Kiagiadakis
Browse files

vpxenc: discard frames that have been dropped by libvpx

This fixes a memory leak. When dropframe-threshold has been set,
libvpx may output less frames than the input ones, which causes
some GstVideoCodecFrames to queue up in GstVideoEncoder's internal
frame queue with no chance of ever being all released. And because
the frames keep references to the input buffers, the input buffer
pool keeps allocating new buffers and memory usage grows very fast.
For example the following pipeline's memory usage grows at a rate
of about 1GB per minute!

videotestsrc ! capsfilter caps=video/x-raw,width=1920,height=1080,framerate=30/1,format=I420 ! \
  vp8enc target-bitrate=1000000 end-usage=cbr dropframe-threshold=95 ! fakesink
parent 5e48e85f
......@@ -1668,6 +1668,7 @@ gst_vpx_enc_process (GstVPXEnc * encoder)
GstVideoCodecFrame *frame;
GstFlowReturn ret = GST_FLOW_OK;
GstVPXEncClass *vpx_enc_class;
vpx_codec_pts_t pts;
video_encoder = GST_VIDEO_ENCODER (encoder);
vpx_enc_class = GST_VPX_ENC_GET_CLASS (encoder);
......@@ -1707,7 +1708,21 @@ gst_vpx_enc_process (GstVPXEnc * encoder)
invisible = (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) != 0;
frame = gst_video_encoder_get_oldest_frame (video_encoder);
/* discard older frames that were dropped by libvpx */
frame = NULL;
do {
if (frame)
gst_video_encoder_finish_frame (video_encoder, frame);
frame = gst_video_encoder_get_oldest_frame (video_encoder);
pts =
gst_util_uint64_scale (frame->pts,
encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
GST_TRACE_OBJECT (encoder, "vpx pts: %" G_GINT64_FORMAT
", gst frame pts: %" G_GINT64_FORMAT, pkt->data.frame.pts, pts);
} while (pkt->data.frame.pts > pts);
g_assert (frame != NULL);
if ((pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0)
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