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
This commit is contained in:
Haihao Xiang 2019-09-27 10:50:18 +08:00 committed by Víctor Manuel Jáquez Leal
parent d8372736c6
commit cd883427e9
2 changed files with 28 additions and 1 deletions

View file

@ -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);

View file

@ -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