msdkdec: avoid releasing the input buffer when it is still in use
authorHaihao Xiang <haihao.xiang@intel.com>
Fri, 11 Jan 2019 08:18:11 +0000 (16:18 +0800)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Sat, 2 Feb 2019 16:32:02 +0000 (16:32 +0000)
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

sys/msdk/gstmsdkdec.c

index 94511e6..5ee5d59 100644 (file)
@@ -841,7 +841,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
   GstMsdkDec *thiz = GST_MSDKDEC (decoder);
   GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz);
   GstFlowReturn flow;
-  GstBuffer *buffer;
+  GstBuffer *buffer, *input_buffer = NULL;
   GstVideoInfo alloc_info;
   MsdkDecTask *task = NULL;
   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;
+  }
 
   memset (&bitstream, 0, sizeof (bitstream));
 
@@ -892,7 +895,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
     bitstream.DataFlag = MFX_BITSTREAM_COMPLETE_FRAME;
   } else {
     /* 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);
 
     bitstream.Data = (mfxU8 *) gst_adapter_map (thiz->adapter, data_size);
@@ -1040,11 +1043,15 @@ done:
   if (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;
 
 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);
 
   return flow;