msdkdec: Release occupied surface for MFX_ERR_MORE_DATA
An output surface is returned but without sync point when when MFXVideoDECODE_DecodeFrameAsync () returns MFX_ERR_MORE_DATA, this surface should be released too, otherwise the surface is occupied and it is easy to exhaust all pre-allocated mfx surfaces. Example pipeline (input_vp8.webm contains lots of frame with show_frame set to 0): gst-launch-1.0 filesrc location=input_vp8.webm ! matroskademux ! msdkvp8dec ! msdkvpp ! fakesink 0:00:05.995959693 19866 0x563f30f14590 ERROR default gstmsdkvideomemory.c:77:gst_msdk_video_allocator_get_surface: failed to get surface available ERROR: from element /GstPipeline:pipeline0/GstMatroskaDemux:matroskademux0: Internal data stream error.
This commit is contained in:
		
							parent
							
								
									1a96759a34
								
							
						
					
					
						commit
						6c953438f5
					
				| @ -611,9 +611,12 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task) | ||||
|       GST_ERROR_OBJECT (thiz, "failed to do sync operation"); | ||||
|       return GST_FLOW_ERROR; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (G_LIKELY (task->sync_point || (task->surface && task->decode_only))) { | ||||
|     gboolean decode_only = task->decode_only; | ||||
| 
 | ||||
|     frame = gst_msdkdec_get_oldest_frame (decoder); | ||||
|     task->sync_point = NULL; | ||||
| 
 | ||||
|     l = g_list_find_custom (thiz->decoded_msdk_surfaces, task->surface, | ||||
|         _find_msdk_surface); | ||||
| @ -634,11 +637,16 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task) | ||||
|     } | ||||
| 
 | ||||
|     free_surface (thiz, surface); | ||||
|     task->sync_point = NULL; | ||||
|     task->surface = NULL; | ||||
|     task->decode_only = FALSE; | ||||
| 
 | ||||
|     if (!frame) | ||||
|       return GST_FLOW_FLUSHING; | ||||
|     gst_video_codec_frame_unref (frame); | ||||
| 
 | ||||
|     if (decode_only) | ||||
|       GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame); | ||||
|     flow = gst_video_decoder_finish_frame (decoder, frame); | ||||
|     return flow; | ||||
|   } | ||||
| @ -1017,9 +1025,11 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) | ||||
|         break; | ||||
|       } | ||||
|     } else if (status == MFX_ERR_MORE_DATA) { | ||||
|       task->decode_only = TRUE; | ||||
|       thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; | ||||
|       if (surface->surface->Data.Locked > 0) | ||||
|         surface = NULL; | ||||
|       flow = GST_FLOW_OK; | ||||
|       flow = GST_VIDEO_DECODER_FLOW_NEED_DATA; | ||||
|       break; | ||||
|     } else if (status == MFX_ERR_MORE_SURFACE) { | ||||
|       surface = NULL; | ||||
|  | ||||
| @ -113,6 +113,8 @@ struct _MsdkDecTask | ||||
| { | ||||
|   mfxFrameSurface1 *surface; | ||||
|   mfxSyncPoint sync_point; | ||||
| 
 | ||||
|   gboolean decode_only; | ||||
| }; | ||||
| 
 | ||||
| GType gst_msdkdec_get_type (void); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user