From 00e1561bf2b0ecfa5dbaa1495b9bc14bb3ad7c78 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 23 Apr 2021 23:20:54 +0900 Subject: [PATCH] d3d11decoder: Set flushing to internal pool on flush event d3d11 decoders use internal pool for DPB texture and Gst*Decoder::new_picture() will be blocked if internal pool is full. We should be able to unblock in on flush-start event as expected. Part-of: --- sys/d3d11/gstd3d11decoder.cpp | 23 ++++++++++++++++++----- sys/d3d11/gstd3d11decoder.h | 5 +++-- sys/d3d11/gstd3d11h264dec.cpp | 22 ++++++++++++++++------ sys/d3d11/gstd3d11h265dec.cpp | 22 ++++++++++++++++------ sys/d3d11/gstd3d11mpeg2dec.cpp | 23 +++++++++++++++++------ sys/d3d11/gstd3d11vp8dec.cpp | 22 ++++++++++++++++------ sys/d3d11/gstd3d11vp9dec.cpp | 22 ++++++++++++++++------ 7 files changed, 102 insertions(+), 37 deletions(-) diff --git a/sys/d3d11/gstd3d11decoder.cpp b/sys/d3d11/gstd3d11decoder.cpp index 433fdffd88..a93f6a3bd6 100644 --- a/sys/d3d11/gstd3d11decoder.cpp +++ b/sys/d3d11/gstd3d11decoder.cpp @@ -147,6 +147,9 @@ struct _GstD3D11Decoder GstVideoCodecState *input_state; GstVideoCodecState *output_state; + /* Protect internal pool */ + GMutex internal_pool_lock; + GstBufferPool *internal_pool; /* Internal pool params */ gint aligned_width; @@ -211,6 +214,7 @@ gst_d3d11_decoder_class_init (GstD3D11DecoderClass * klass) static void gst_d3d11_decoder_init (GstD3D11Decoder * self) { + g_mutex_init (&self->internal_pool_lock); } static void @@ -281,10 +285,12 @@ gst_d3d11_decoder_get_property (GObject * object, guint prop_id, static void gst_d3d11_decoder_clear_resource (GstD3D11Decoder * self) { + g_mutex_lock (&self->internal_pool_lock); if (self->internal_pool) { gst_buffer_pool_set_active (self->internal_pool, FALSE); gst_clear_object (&self->internal_pool); } + g_mutex_unlock (&self->internal_pool_lock); GST_D3D11_CLEAR_COM (self->decoder_handle); GST_D3D11_CLEAR_COM (self->staging); @@ -331,14 +337,16 @@ gst_d3d11_decoder_dispose (GObject * obj) static void gst_d3d11_decoder_finalize (GObject * obj) { -#if HAVE_WINMM GstD3D11Decoder *self = GST_D3D11_DECODER (obj); +#if HAVE_WINMM /* Restore clock precision */ if (self->timer_resolution) timeEndPeriod (self->timer_resolution); #endif + g_mutex_clear (&self->internal_pool_lock); + G_OBJECT_CLASS (parent_class)->finalize (obj); } @@ -434,10 +442,12 @@ gst_d3d11_decoder_prepare_output_view_pool (GstD3D11Decoder * self) GstVideoInfo *info = &self->info; guint pool_size; + g_mutex_lock (&self->internal_pool_lock); if (self->internal_pool) { gst_buffer_pool_set_active (self->internal_pool, FALSE); gst_clear_object (&self->internal_pool); } + g_mutex_unlock (&self->internal_pool_lock); if (!self->use_array_of_texture) { alloc_flags = GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY; @@ -501,7 +511,9 @@ gst_d3d11_decoder_prepare_output_view_pool (GstD3D11Decoder * self) goto error; } + g_mutex_lock (&self->internal_pool_lock); self->internal_pool = pool; + g_mutex_unlock (&self->internal_pool_lock); return TRUE; @@ -1662,14 +1674,15 @@ gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decoder, } gboolean -gst_d3d11_decoder_flush (GstD3D11Decoder * decoder, GstVideoDecoder * videodec) +gst_d3d11_decoder_set_flushing (GstD3D11Decoder * decoder, + GstVideoDecoder * videodec, gboolean flushing) { g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE); - /* Set active FALSE so that other thread which is waiting DPB texture buffer - * to be able to wakeup */ + g_mutex_lock (&decoder->internal_pool_lock); if (decoder->internal_pool) - gst_buffer_pool_set_active (decoder->internal_pool, FALSE); + gst_buffer_pool_set_flushing (decoder->internal_pool, flushing); + g_mutex_unlock (&decoder->internal_pool_lock); return TRUE; } diff --git a/sys/d3d11/gstd3d11decoder.h b/sys/d3d11/gstd3d11decoder.h index f88a377142..ada1368426 100644 --- a/sys/d3d11/gstd3d11decoder.h +++ b/sys/d3d11/gstd3d11decoder.h @@ -107,8 +107,9 @@ gboolean gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decod GstVideoDecoder * videodec, GstQuery * query); -gboolean gst_d3d11_decoder_flush (GstD3D11Decoder * decoder, - GstVideoDecoder * videodec); +gboolean gst_d3d11_decoder_set_flushing (GstD3D11Decoder * decoder, + GstVideoDecoder * videodec, + gboolean flushing); /* Utils for class registration */ gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device); diff --git a/sys/d3d11/gstd3d11h264dec.cpp b/sys/d3d11/gstd3d11h264dec.cpp index f68a5179e6..3e2787f383 100644 --- a/sys/d3d11/gstd3d11h264dec.cpp +++ b/sys/d3d11/gstd3d11h264dec.cpp @@ -155,7 +155,8 @@ static gboolean gst_d3d11_h264_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query); static gboolean gst_d3d11_h264_dec_src_query (GstVideoDecoder * decoder, GstQuery * query); -static gboolean gst_d3d11_h264_dec_flush (GstVideoDecoder * decoder); +static gboolean gst_d3d11_h264_dec_sink_event (GstVideoDecoder * decoder, + GstEvent * event); /* GstH264Decoder */ static gboolean gst_d3d11_h264_dec_new_sequence (GstH264Decoder * decoder, @@ -234,7 +235,7 @@ gst_d3d11_h264_dec_class_init (GstD3D11H264DecClass * klass, gpointer data) decoder_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_d3d11_h264_dec_decide_allocation); decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_d3d11_h264_dec_src_query); - decoder_class->flush = GST_DEBUG_FUNCPTR (gst_d3d11_h264_dec_flush); + decoder_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_h264_dec_sink_event); h264decoder_class->new_sequence = GST_DEBUG_FUNCPTR (gst_d3d11_h264_dec_new_sequence); @@ -402,14 +403,23 @@ gst_d3d11_h264_dec_src_query (GstVideoDecoder * decoder, GstQuery * query) } static gboolean -gst_d3d11_h264_dec_flush (GstVideoDecoder * decoder) +gst_d3d11_h264_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event) { GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder); - if (self->d3d11_decoder) - gst_d3d11_decoder_flush (self->d3d11_decoder, decoder); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, TRUE); + break; + case GST_EVENT_FLUSH_STOP: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, FALSE); + default: + break; + } - return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); } static gboolean diff --git a/sys/d3d11/gstd3d11h265dec.cpp b/sys/d3d11/gstd3d11h265dec.cpp index 18fba71a88..04e5bd5099 100644 --- a/sys/d3d11/gstd3d11h265dec.cpp +++ b/sys/d3d11/gstd3d11h265dec.cpp @@ -125,7 +125,8 @@ static gboolean gst_d3d11_h265_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query); static gboolean gst_d3d11_h265_dec_src_query (GstVideoDecoder * decoder, GstQuery * query); -static gboolean gst_d3d11_h265_dec_flush (GstVideoDecoder * decoder); +static gboolean gst_d3d11_h265_dec_sink_event (GstVideoDecoder * decoder, + GstEvent * event); /* GstH265Decoder */ static gboolean gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder, @@ -208,7 +209,7 @@ gst_d3d11_h265_dec_class_init (GstD3D11H265DecClass * klass, gpointer data) decoder_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_decide_allocation); decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_src_query); - decoder_class->flush = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_flush); + decoder_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_sink_event); h265decoder_class->new_sequence = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_sequence); @@ -357,14 +358,23 @@ gst_d3d11_h265_dec_src_query (GstVideoDecoder * decoder, GstQuery * query) } static gboolean -gst_d3d11_h265_dec_flush (GstVideoDecoder * decoder) +gst_d3d11_h265_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event) { GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder); - if (self->d3d11_decoder) - gst_d3d11_decoder_flush (self->d3d11_decoder, decoder); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, TRUE); + break; + case GST_EVENT_FLUSH_STOP: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, FALSE); + default: + break; + } - return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); } static gboolean diff --git a/sys/d3d11/gstd3d11mpeg2dec.cpp b/sys/d3d11/gstd3d11mpeg2dec.cpp index 2bb91d0ef4..4e903dbbad 100644 --- a/sys/d3d11/gstd3d11mpeg2dec.cpp +++ b/sys/d3d11/gstd3d11mpeg2dec.cpp @@ -120,7 +120,8 @@ static gboolean gst_d3d11_mpeg2_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query); static gboolean gst_d3d11_mpeg2_dec_src_query (GstVideoDecoder * decoder, GstQuery * query); -static gboolean gst_d3d11_mpeg2_dec_flush (GstVideoDecoder * decoder); +static gboolean gst_d3d11_mpeg2_dec_sink_event (GstVideoDecoder * decoder, + GstEvent * event); /* GstMpeg2Decoder */ static gboolean gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder, @@ -200,7 +201,8 @@ gst_d3d11_mpeg2_dec_class_init (GstD3D11Mpeg2DecClass * klass, gpointer data) decoder_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_d3d11_mpeg2_dec_decide_allocation); decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_d3d11_mpeg2_dec_src_query); - decoder_class->flush = GST_DEBUG_FUNCPTR (gst_d3d11_mpeg2_dec_flush); + decoder_class->sink_event = + GST_DEBUG_FUNCPTR (gst_d3d11_mpeg2_dec_sink_event); mpeg2decoder_class->new_sequence = GST_DEBUG_FUNCPTR (gst_d3d11_mpeg2_dec_new_sequence); @@ -349,14 +351,23 @@ gst_d3d11_mpeg2_dec_src_query (GstVideoDecoder * decoder, GstQuery * query) } static gboolean -gst_d3d11_mpeg2_dec_flush (GstVideoDecoder * decoder) +gst_d3d11_mpeg2_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event) { GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder); - if (self->d3d11_decoder) - gst_d3d11_decoder_flush (self->d3d11_decoder, decoder); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, TRUE); + break; + case GST_EVENT_FLUSH_STOP: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, FALSE); + default: + break; + } - return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); } static gboolean diff --git a/sys/d3d11/gstd3d11vp8dec.cpp b/sys/d3d11/gstd3d11vp8dec.cpp index 04356f2d68..2ff7d707bf 100644 --- a/sys/d3d11/gstd3d11vp8dec.cpp +++ b/sys/d3d11/gstd3d11vp8dec.cpp @@ -106,7 +106,8 @@ static gboolean gst_d3d11_vp8_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query); static gboolean gst_d3d11_vp8_dec_src_query (GstVideoDecoder * decoder, GstQuery * query); -static gboolean gst_d3d11_vp8_dec_flush (GstVideoDecoder * decoder); +static gboolean gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder, + GstEvent * event); /* GstVp8Decoder */ static gboolean gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder, @@ -178,7 +179,7 @@ gst_d3d11_vp8_dec_class_init (GstD3D11Vp8DecClass * klass, gpointer data) decoder_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_d3d11_vp8_dec_decide_allocation); decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_d3d11_vp8_dec_src_query); - decoder_class->flush = GST_DEBUG_FUNCPTR (gst_d3d11_vp8_dec_flush); + decoder_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_vp8_sink_event); vp8decoder_class->new_sequence = GST_DEBUG_FUNCPTR (gst_d3d11_vp8_dec_new_sequence); @@ -313,14 +314,23 @@ gst_d3d11_vp8_dec_src_query (GstVideoDecoder * decoder, GstQuery * query) } static gboolean -gst_d3d11_vp8_dec_flush (GstVideoDecoder * decoder) +gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder, GstEvent * event) { GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder); - if (self->d3d11_decoder) - gst_d3d11_decoder_flush (self->d3d11_decoder, decoder); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, TRUE); + break; + case GST_EVENT_FLUSH_STOP: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, FALSE); + default: + break; + } - return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); } static gboolean diff --git a/sys/d3d11/gstd3d11vp9dec.cpp b/sys/d3d11/gstd3d11vp9dec.cpp index a293bb75f8..a49378ebfd 100644 --- a/sys/d3d11/gstd3d11vp9dec.cpp +++ b/sys/d3d11/gstd3d11vp9dec.cpp @@ -133,7 +133,8 @@ static gboolean gst_d3d11_vp9_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query); static gboolean gst_d3d11_vp9_dec_src_query (GstVideoDecoder * decoder, GstQuery * query); -static gboolean gst_d3d11_vp9_dec_flush (GstVideoDecoder * decoder); +static gboolean gst_d3d11_vp9_dec_sink_event (GstVideoDecoder * decoder, + GstEvent * event); /* GstVp9Decoder */ static gboolean gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder, @@ -207,7 +208,7 @@ gst_d3d11_vp9_dec_class_init (GstD3D11Vp9DecClass * klass, gpointer data) decoder_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_d3d11_vp9_dec_decide_allocation); decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_d3d11_vp9_dec_src_query); - decoder_class->flush = GST_DEBUG_FUNCPTR (gst_d3d11_vp9_dec_flush); + decoder_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_vp9_dec_sink_event); vp9decoder_class->new_sequence = GST_DEBUG_FUNCPTR (gst_d3d11_vp9_dec_new_sequence); @@ -344,14 +345,23 @@ gst_d3d11_vp9_dec_src_query (GstVideoDecoder * decoder, GstQuery * query) } static gboolean -gst_d3d11_vp9_dec_flush (GstVideoDecoder * decoder) +gst_d3d11_vp9_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event) { GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder); - if (self->d3d11_decoder) - gst_d3d11_decoder_flush (self->d3d11_decoder, decoder); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, TRUE); + break; + case GST_EVENT_FLUSH_STOP: + if (self->d3d11_decoder) + gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, FALSE); + default: + break; + } - return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); } static gboolean