summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungha Yang <seungha.yang@navercorp.com>2018-12-13 22:03:36 +0900
committerTim-Philipp Müller <tim@centricular.com>2019-05-02 10:59:56 +0100
commit6f1ff1af8efeeca0413744763200511327e2c21f (patch)
treeadcece5daadc136debb91ac9385b7f7aa9645b5c
parent05d2d6cac397a86c9a6227a5fc78a3bfba4facde (diff)
downloadgstreamer-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.c38
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;
}