d3d11decoder: Do negotiation again per forward/reverse playback mode change

For reverse playback, we are always copying decoded
frame to downstream buffer. So the pool size can be
and need to be large enough.

In case that forward playback, however, we need to restrict
the max pool size for performance reason. Otherwise decoder
will keep copying decoded texture to downstream buffer pool
if decoding is faster than downstream throughput
performance and also there are queue element between them.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2083>
This commit is contained in:
Seungha Yang 2021-03-15 18:26:03 +09:00 committed by GStreamer Marge Bot
parent 3a99517f7c
commit 309a940614
7 changed files with 122 additions and 7 deletions

View file

@ -125,6 +125,8 @@ struct _GstD3D11Decoder
gboolean configured;
gboolean opened;
gboolean reverse_playback;
GstD3D11Device *device;
ID3D11VideoDevice *video_device;
@ -989,26 +991,43 @@ gst_d3d11_decoder_get_output_view_buffer (GstD3D11Decoder * decoder,
{
GstBuffer *buf = NULL;
GstFlowReturn ret;
gboolean reverse_playback = FALSE;
gboolean rate_changed = FALSE;
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
if (!decoder->internal_pool) {
if (videodec->input_segment.rate < 0)
reverse_playback = TRUE;
if (reverse_playback != decoder->reverse_playback) {
GST_DEBUG_OBJECT (videodec, "Rate was changed, need re-negotiation");
rate_changed = TRUE;
}
if (!decoder->internal_pool || rate_changed) {
gboolean reconfigured;
/* Replicate gst_video_decoder_allocate_output_buffer().
* In case of zero-copy playback, this is the last chance for querying
* required min-buffer size by downstream and take account of
* the min-buffer size into our internel pool size */
GST_VIDEO_DECODER_STREAM_LOCK (videodec);
if (gst_pad_check_reconfigure (GST_VIDEO_DECODER_SRC_PAD (videodec))) {
GST_DEBUG_OBJECT (videodec,
"Downstream was reconfigured, negotiating again");
gst_video_decoder_negotiate (videodec);
}
reconfigured =
gst_pad_check_reconfigure (GST_VIDEO_DECODER_SRC_PAD (videodec));
GST_DEBUG_OBJECT (videodec,
"Downstream was reconfigured, negotiating again");
GST_VIDEO_DECODER_STREAM_UNLOCK (videodec);
if (reconfigured || rate_changed)
gst_video_decoder_negotiate (videodec);
if (!gst_d3d11_decoder_prepare_output_view_pool (decoder)) {
GST_ERROR_OBJECT (videodec, "Failed to setup internal pool");
return NULL;
}
} else if (!gst_buffer_pool_set_active (decoder->internal_pool, TRUE)) {
GST_ERROR_OBJECT (videodec, "Couldn't set active internal pool");
return NULL;
}
ret = gst_buffer_pool_acquire_buffer (decoder->internal_pool, &buf, NULL);
@ -1408,6 +1427,22 @@ gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decoder,
size = (guint) vinfo.size;
}
if (videodec->input_segment.rate >= 0) {
decoder->reverse_playback = FALSE;
/* Don't allow too large pool size */
if (use_d3d11_pool) {
guint prev_max = max;
max = MAX (4, max);
max = MAX (max, min);
GST_DEBUG_OBJECT (videodec, "Update max size %d -> %d", prev_max, max);
}
} else {
decoder->reverse_playback = TRUE;
}
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
@ -1464,6 +1499,19 @@ gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decoder,
return TRUE;
}
gboolean
gst_d3d11_decoder_flush (GstD3D11Decoder * decoder, GstVideoDecoder * videodec)
{
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 */
if (decoder->internal_pool)
gst_buffer_pool_set_active (decoder->internal_pool, FALSE);
return TRUE;
}
gboolean
gst_d3d11_decoder_can_direct_render (GstD3D11Decoder * decoder,
GstBuffer * view_buffer, GstMiniObject * picture)

View file

@ -109,11 +109,13 @@ 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_can_direct_render (GstD3D11Decoder * decoder,
GstBuffer * view_buffer,
GstMiniObject * picture);
/* Utils for class registration */
gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device);

View file

@ -157,6 +157,7 @@ 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);
/* GstH264Decoder */
static gboolean gst_d3d11_h264_dec_new_sequence (GstH264Decoder * decoder,
@ -235,6 +236,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);
h264decoder_class->new_sequence =
GST_DEBUG_FUNCPTR (gst_d3d11_h264_dec_new_sequence);
@ -408,6 +410,17 @@ gst_d3d11_h264_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
}
static gboolean
gst_d3d11_h264_dec_flush (GstVideoDecoder * decoder)
{
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
if (self->d3d11_decoder)
gst_d3d11_decoder_flush (self->d3d11_decoder, decoder);
return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder);
}
static gboolean
gst_d3d11_h264_dec_new_sequence (GstH264Decoder * decoder,
const GstH264SPS * sps, gint max_dpb_size)

View file

@ -127,6 +127,7 @@ 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);
/* GstH265Decoder */
static gboolean gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
@ -209,6 +210,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);
h265decoder_class->new_sequence =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_sequence);
@ -363,6 +365,17 @@ gst_d3d11_h265_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
}
static gboolean
gst_d3d11_h265_dec_flush (GstVideoDecoder * decoder)
{
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
if (self->d3d11_decoder)
gst_d3d11_decoder_flush (self->d3d11_decoder, decoder);
return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder);
}
static gboolean
gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
const GstH265SPS * sps, gint max_dpb_size)

View file

@ -121,6 +121,7 @@ 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);
/* GstMpeg2Decoder */
static gboolean gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
@ -200,6 +201,7 @@ 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);
mpeg2decoder_class->new_sequence =
GST_DEBUG_FUNCPTR (gst_d3d11_mpeg2_dec_new_sequence);
@ -350,6 +352,17 @@ gst_d3d11_mpeg2_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
}
static gboolean
gst_d3d11_mpeg2_dec_flush (GstVideoDecoder * decoder)
{
GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
if (self->d3d11_decoder)
gst_d3d11_decoder_flush (self->d3d11_decoder, decoder);
return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder);
}
static gboolean
gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
const GstMpegVideoSequenceHdr * seq,

View file

@ -107,6 +107,7 @@ 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);
/* GstVp8Decoder */
static gboolean gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
@ -178,6 +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);
vp8decoder_class->new_sequence =
GST_DEBUG_FUNCPTR (gst_d3d11_vp8_dec_new_sequence);
@ -314,6 +316,17 @@ gst_d3d11_vp8_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
}
static gboolean
gst_d3d11_vp8_dec_flush (GstVideoDecoder * decoder)
{
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
if (self->d3d11_decoder)
gst_d3d11_decoder_flush (self->d3d11_decoder, decoder);
return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder);
}
static gboolean
gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr)

View file

@ -141,6 +141,7 @@ 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);
/* GstVp9Decoder */
static gboolean gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
@ -214,6 +215,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);
vp9decoder_class->new_sequence =
GST_DEBUG_FUNCPTR (gst_d3d11_vp9_dec_new_sequence);
@ -352,6 +354,17 @@ gst_d3d11_vp9_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
}
static gboolean
gst_d3d11_vp9_dec_flush (GstVideoDecoder * decoder)
{
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
if (self->d3d11_decoder)
gst_d3d11_decoder_flush (self->d3d11_decoder, decoder);
return GST_VIDEO_DECODER_CLASS (parent_class)->flush (decoder);
}
static gboolean
gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)