mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
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:
parent
3a99517f7c
commit
309a940614
7 changed files with 122 additions and 7 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue