mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:46:13 +00:00
nvdec: implement flush/drain
Fixes outputted frame sequence when performing a seek i.e. when seeking backwards, the first frame after the seek was a frame from the future. This would result in GstVideoDecoder essentially marking all the timestamps as essentially bogus and the base class would attempt to compensate. A visible indication of this was 'decreasing timestamp' warning after a seek. https://bugzilla.gnome.org/show_bug.cgi?id=790478
This commit is contained in:
parent
16294a147e
commit
4e422bec4f
1 changed files with 42 additions and 0 deletions
|
@ -216,6 +216,8 @@ static gboolean gst_nvdec_decide_allocation (GstVideoDecoder * decoder,
|
||||||
static void gst_nvdec_set_context (GstElement * element, GstContext * context);
|
static void gst_nvdec_set_context (GstElement * element, GstContext * context);
|
||||||
static gboolean gst_nvdec_src_query (GstVideoDecoder * decoder,
|
static gboolean gst_nvdec_src_query (GstVideoDecoder * decoder,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
|
static gboolean gst_nvdec_flush (GstVideoDecoder * decoder);
|
||||||
|
static GstFlowReturn gst_nvdec_drain (GstVideoDecoder * decoder);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_nvdec_sink_template =
|
static GstStaticPadTemplate gst_nvdec_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
||||||
|
@ -260,6 +262,8 @@ gst_nvdec_class_init (GstNvDecClass * klass)
|
||||||
video_decoder_class->decide_allocation =
|
video_decoder_class->decide_allocation =
|
||||||
GST_DEBUG_FUNCPTR (gst_nvdec_decide_allocation);
|
GST_DEBUG_FUNCPTR (gst_nvdec_decide_allocation);
|
||||||
video_decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_nvdec_src_query);
|
video_decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_nvdec_src_query);
|
||||||
|
video_decoder_class->drain = GST_DEBUG_FUNCPTR (gst_nvdec_drain);
|
||||||
|
video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_nvdec_flush);
|
||||||
|
|
||||||
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nvdec_set_context);
|
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nvdec_set_context);
|
||||||
}
|
}
|
||||||
|
@ -856,6 +860,44 @@ gst_nvdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
||||||
return handle_pending_frames (nvdec);
|
return handle_pending_frames (nvdec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_nvdec_flush (GstVideoDecoder * decoder)
|
||||||
|
{
|
||||||
|
GstNvDec *nvdec = GST_NVDEC (decoder);
|
||||||
|
CUVIDSOURCEDATAPACKET packet = { 0, };
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (nvdec, "flush");
|
||||||
|
|
||||||
|
packet.payload_size = 0;
|
||||||
|
packet.payload = NULL;
|
||||||
|
packet.flags = CUVID_PKT_ENDOFSTREAM;
|
||||||
|
|
||||||
|
if (!cuda_OK (cuvidParseVideoData (nvdec->parser, &packet)))
|
||||||
|
GST_WARNING_OBJECT (nvdec, "parser failed");
|
||||||
|
|
||||||
|
handle_pending_frames (nvdec);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_nvdec_drain (GstVideoDecoder * decoder)
|
||||||
|
{
|
||||||
|
GstNvDec *nvdec = GST_NVDEC (decoder);
|
||||||
|
CUVIDSOURCEDATAPACKET packet = { 0, };
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (nvdec, "draining decoder");
|
||||||
|
|
||||||
|
packet.payload_size = 0;
|
||||||
|
packet.payload = NULL;
|
||||||
|
packet.flags = CUVID_PKT_ENDOFSTREAM;
|
||||||
|
|
||||||
|
if (!cuda_OK (cuvidParseVideoData (nvdec->parser, &packet)))
|
||||||
|
GST_WARNING_OBJECT (nvdec, "parser failed");
|
||||||
|
|
||||||
|
return handle_pending_frames (nvdec);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_nvdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
gst_nvdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue