diff options
author | Seungha Yang <seungha.yang@navercorp.com> | 2018-12-13 22:03:36 +0900 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2019-05-02 10:59:56 +0100 |
commit | 6f1ff1af8efeeca0413744763200511327e2c21f (patch) | |
tree | adcece5daadc136debb91ac9385b7f7aa9645b5c | |
parent | 05d2d6cac397a86c9a6227a5fc78a3bfba4facde (diff) | |
download | gstreamer-plugins-bad-6f1ff1af8efeeca0413744763200511327e2c21f.tar.gz |
nvenc: Ensure drain all frames on finish
To drain all queued encoding items, encoder should gracefully
wait the encoding thread without stealing queued items.
Otherwise, some input frames can be dropped.
-rw-r--r-- | sys/nvenc/gstnvbaseenc.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/sys/nvenc/gstnvbaseenc.c b/sys/nvenc/gstnvbaseenc.c index 8a615a8be..5cf77141b 100644 --- a/sys/nvenc/gstnvbaseenc.c +++ b/sys/nvenc/gstnvbaseenc.c @@ -224,7 +224,8 @@ static void gst_nv_base_enc_get_property (GObject * object, guint prop_id, static void gst_nv_base_enc_finalize (GObject * obj); static GstCaps *gst_nv_base_enc_getcaps (GstVideoEncoder * enc, GstCaps * filter); -static gboolean gst_nv_base_enc_stop_bitstream_thread (GstNvBaseEnc * nvenc); +static gboolean gst_nv_base_enc_stop_bitstream_thread (GstNvBaseEnc * nvenc, + gboolean force); static void gst_nv_base_enc_class_init (GstNvBaseEncClass * klass) @@ -522,7 +523,7 @@ gst_nv_base_enc_stop (GstVideoEncoder * enc) { GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (enc); - gst_nv_base_enc_stop_bitstream_thread (nvenc); + gst_nv_base_enc_stop_bitstream_thread (nvenc, TRUE); gst_nv_base_enc_free_buffers (nvenc); @@ -897,24 +898,27 @@ gst_nv_base_enc_start_bitstream_thread (GstNvBaseEnc * nvenc) } static gboolean -gst_nv_base_enc_stop_bitstream_thread (GstNvBaseEnc * nvenc) +gst_nv_base_enc_stop_bitstream_thread (GstNvBaseEnc * nvenc, gboolean force) { gpointer out_buf; if (nvenc->bitstream_thread == NULL) return TRUE; - /* FIXME */ - GST_FIXME_OBJECT (nvenc, "stop bitstream reading thread properly"); - g_async_queue_lock (nvenc->bitstream_queue); - g_async_queue_lock (nvenc->bitstream_pool); - while ((out_buf = g_async_queue_try_pop_unlocked (nvenc->bitstream_queue))) { - GST_INFO_OBJECT (nvenc, "stole bitstream buffer %p from queue", out_buf); - g_async_queue_push_unlocked (nvenc->bitstream_pool, out_buf); + if (force) { + g_async_queue_lock (nvenc->bitstream_queue); + g_async_queue_lock (nvenc->bitstream_pool); + while ((out_buf = g_async_queue_try_pop_unlocked (nvenc->bitstream_queue))) { + GST_INFO_OBJECT (nvenc, "stole bitstream buffer %p from queue", out_buf); + g_async_queue_push_unlocked (nvenc->bitstream_pool, out_buf); + } + g_async_queue_push_unlocked (nvenc->bitstream_queue, SHUTDOWN_COOKIE); + g_async_queue_unlock (nvenc->bitstream_pool); + g_async_queue_unlock (nvenc->bitstream_queue); + } else { + /* wait for encoder to drain the remaining buffers */ + g_async_queue_push (nvenc->bitstream_queue, SHUTDOWN_COOKIE); } - g_async_queue_push_unlocked (nvenc->bitstream_queue, SHUTDOWN_COOKIE); - g_async_queue_unlock (nvenc->bitstream_pool); - g_async_queue_unlock (nvenc->bitstream_queue); /* temporary unlock, so other thread can find and push frame */ GST_VIDEO_ENCODER_STREAM_UNLOCK (nvenc); @@ -1905,12 +1909,10 @@ gst_nv_base_enc_finish (GstVideoEncoder * enc) { GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (enc); - GST_FIXME_OBJECT (enc, "implement finish"); - - gst_nv_base_enc_drain_encoder (nvenc); + if (!gst_nv_base_enc_drain_encoder (nvenc)) + return GST_FLOW_ERROR; - /* wait for encoder to output the remaining buffers */ - gst_nv_base_enc_stop_bitstream_thread (nvenc); + gst_nv_base_enc_stop_bitstream_thread (nvenc, FALSE); return GST_FLOW_OK; } |