From cd883427e93d9a38541fee3a89498abf9a92e423 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Fri, 27 Sep 2019 10:50:18 +0800 Subject: [PATCH] msdkdec: add parse callback for non-packetized input commit 55c0d720 added the capability to handle non-packetized bitstream, and there is a loop to handle multiple frames in a non-packetized buffer in gst_msdkdec_handle_frame. However it is possible that a non-packetized buffer still contains valid data but there is no long any pending unfinished frame. Currently gst_video_decoder_decode_frame is invoked to send a new frame with new input data, the situaltion is repeated till an EOS is received. An application has to exit when receiving an EOS, however there is still valid data in a non-packetezied input buffer, hence some frames are dropped. This fix adds a parse callback for non-packeteized input, a new frame will be sent to the subclass as soon as the input buffer has valid data This fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/665 --- sys/msdk/gstmsdkdec.c | 28 +++++++++++++++++++++++++++- sys/msdk/gstmsdkvc1dec.c | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/sys/msdk/gstmsdkdec.c b/sys/msdk/gstmsdkdec.c index 59fe7441bb..f01f691dc4 100644 --- a/sys/msdk/gstmsdkdec.c +++ b/sys/msdk/gstmsdkdec.c @@ -1135,7 +1135,6 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) if (!thiz->is_packetized) { /* flush out the data which has already been consumed by msdk */ gst_adapter_flush (thiz->adapter, bitstream.DataOffset); - flow = GST_FLOW_OK; } /* @@ -1164,6 +1163,32 @@ error: return flow; } +static GstFlowReturn +gst_msdkdec_parse (GstVideoDecoder * decoder, GstVideoCodecFrame * frame, + GstAdapter * adapter, gboolean at_eos) +{ + gsize size; + GstFlowReturn ret; + GstBuffer *buffer; + GstMsdkDec *thiz = GST_MSDKDEC (decoder); + + /* Don't parse the input buffer indeed, it will invoke + * gst_msdkdec_handle_frame to handle the input buffer */ + size = gst_adapter_available (adapter); + gst_video_decoder_add_to_frame (decoder, size); + ret = gst_video_decoder_have_frame (decoder); + size = gst_adapter_available (thiz->adapter); + + if (size) { + /* The base class will set up a new frame for parsing as + * soon as there is valid data in the buffer */ + buffer = gst_adapter_get_buffer (thiz->adapter, size); + gst_adapter_flush (thiz->adapter, size); + gst_adapter_push (adapter, buffer); + } + + return ret; +} static GstBufferPool * gst_msdkdec_create_buffer_pool (GstMsdkDec * thiz, GstVideoInfo * info, @@ -1591,6 +1616,7 @@ gst_msdkdec_class_init (GstMsdkDecClass * klass) decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkdec_set_format); decoder_class->finish = GST_DEBUG_FUNCPTR (gst_msdkdec_finish); decoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_msdkdec_handle_frame); + decoder_class->parse = GST_DEBUG_FUNCPTR (gst_msdkdec_parse); decoder_class->decide_allocation = GST_DEBUG_FUNCPTR (gst_msdkdec_decide_allocation); decoder_class->flush = GST_DEBUG_FUNCPTR (gst_msdkdec_flush); diff --git a/sys/msdk/gstmsdkvc1dec.c b/sys/msdk/gstmsdkvc1dec.c index 99f191fc88..919fad8072 100644 --- a/sys/msdk/gstmsdkvc1dec.c +++ b/sys/msdk/gstmsdkvc1dec.c @@ -104,6 +104,7 @@ gst_msdkvc1dec_configure (GstMsdkDec * decoder) } decoder->is_packetized = FALSE; + gst_video_decoder_set_packetized (GST_VIDEO_DECODER (decoder), FALSE); } /* This is a deprecated attribute in msdk-2017 version, but some