msdkdec: avoid releasing the input buffer when it is still in use

The input buffer is released in gst_msdkdec_finish_task () when decoding
some special clips however this buffer is still in use, so ref the input
buffer before gst_msdkdec_finish_task () and unref it at the end of
gst_msdkdec_handle_frame ().

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/862
This commit is contained in:
Haihao Xiang 2019-01-11 16:18:11 +08:00 committed by Víctor Manuel Jáquez Leal
parent 572a283b4a
commit 74f297f31b

View file

@ -841,7 +841,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
GstMsdkDec *thiz = GST_MSDKDEC (decoder); GstMsdkDec *thiz = GST_MSDKDEC (decoder);
GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz); GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz);
GstFlowReturn flow; GstFlowReturn flow;
GstBuffer *buffer; GstBuffer *buffer, *input_buffer = NULL;
GstVideoInfo alloc_info; GstVideoInfo alloc_info;
MsdkDecTask *task = NULL; MsdkDecTask *task = NULL;
mfxBitstream bitstream; mfxBitstream bitstream;
@ -878,8 +878,11 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
} }
} }
if (!gst_buffer_map (frame->input_buffer, &map_info, GST_MAP_READ)) input_buffer = gst_buffer_ref (frame->input_buffer);
if (!gst_buffer_map (input_buffer, &map_info, GST_MAP_READ)) {
gst_buffer_unref (input_buffer);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
}
memset (&bitstream, 0, sizeof (bitstream)); memset (&bitstream, 0, sizeof (bitstream));
@ -892,7 +895,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
bitstream.DataFlag = MFX_BITSTREAM_COMPLETE_FRAME; bitstream.DataFlag = MFX_BITSTREAM_COMPLETE_FRAME;
} else { } else {
/* Non packetized streams: eg: vc1 advanced profile with per buffer bdu */ /* Non packetized streams: eg: vc1 advanced profile with per buffer bdu */
gst_adapter_push (thiz->adapter, gst_buffer_ref (frame->input_buffer)); gst_adapter_push (thiz->adapter, gst_buffer_ref (input_buffer));
data_size = gst_adapter_available (thiz->adapter); data_size = gst_adapter_available (thiz->adapter);
bitstream.Data = (mfxU8 *) gst_adapter_map (thiz->adapter, data_size); bitstream.Data = (mfxU8 *) gst_adapter_map (thiz->adapter, data_size);
@ -1040,11 +1043,15 @@ done:
if (surface) if (surface)
free_surface (thiz, surface); free_surface (thiz, surface);
gst_buffer_unmap (frame->input_buffer, &map_info); gst_buffer_unmap (input_buffer, &map_info);
gst_buffer_unref (input_buffer);
return flow; return flow;
error: error:
gst_buffer_unmap (frame->input_buffer, &map_info); if (input_buffer) {
gst_buffer_unmap (input_buffer, &map_info);
gst_buffer_unref (input_buffer);
}
gst_video_decoder_drop_frame (decoder, frame); gst_video_decoder_drop_frame (decoder, frame);
return flow; return flow;