msdkenc: handle the MORE_DATA case

If the driver requires more data, just unref the frame at the moment
then retreive/finish the frame after encoding is finished.

This also fixes a memory leak.

https://bugzilla.gnome.org/show_bug.cgi?id=790312
This commit is contained in:
Hyunjun Ko 2017-11-21 14:57:03 +09:00 committed by Sebastian Dröge
parent e2c8afa261
commit ddd9355767
2 changed files with 32 additions and 5 deletions

View file

@ -630,6 +630,7 @@ gst_msdkenc_reset_task (MsdkEncTask * task)
task->input_frame = NULL;
task->output_bitstream.DataLength = 0;
task->sync_point = NULL;
task->more_data = FALSE;
}
static GstFlowReturn
@ -638,6 +639,25 @@ gst_msdkenc_finish_frame (GstMsdkEnc * thiz, MsdkEncTask * task,
{
GstVideoCodecFrame *frame = task->input_frame;
if (task->more_data) {
GstVideoCodecFrame *frame;
frame =
gst_video_encoder_get_frame (GST_VIDEO_ENCODER_CAST (thiz),
task->pending_frame_number);
if (frame) {
gst_msdkenc_dequeue_frame (thiz, frame);
gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (thiz), frame);
gst_msdkenc_reset_task (task);
return GST_FLOW_OK;
} else {
GST_ERROR_OBJECT (thiz,
"Couldn't find the pending frame %d to be finished",
task->pending_frame_number);
return GST_FLOW_ERROR;
}
}
if (!task->sync_point) {
return GST_FLOW_OK;
}
@ -699,11 +719,6 @@ gst_msdkenc_encode_frame (GstMsdkEnc * thiz, mfxFrameSurface1 * surface,
g_usleep (1000);
};
if (task->sync_point) {
task->input_frame = input_frame;
thiz->next_task = ((task - thiz->tasks) + 1) % thiz->num_tasks;
}
if (status != MFX_ERR_NONE && status != MFX_ERR_MORE_DATA) {
GST_ELEMENT_ERROR (thiz, STREAM, ENCODE, ("Encode frame failed."),
("MSDK encode error (%s)", msdk_status_to_string (status)));
@ -712,6 +727,16 @@ gst_msdkenc_encode_frame (GstMsdkEnc * thiz, mfxFrameSurface1 * surface,
return GST_FLOW_ERROR;
}
if (task->sync_point) {
task->input_frame = input_frame;
thiz->next_task = ((task - thiz->tasks) + 1) % thiz->num_tasks;
} else if (status == MFX_ERR_MORE_DATA) {
task->more_data = TRUE;
task->pending_frame_number = input_frame->system_frame_number;
gst_video_codec_frame_unref (input_frame);
thiz->next_task = ((task - thiz->tasks) + 1) % thiz->num_tasks;
}
/* Ensure that next task is available */
task = thiz->tasks + thiz->next_task;
return gst_msdkenc_finish_frame (thiz, task, FALSE);

View file

@ -118,6 +118,8 @@ struct _MsdkEncTask
GstVideoCodecFrame *input_frame;
mfxSyncPoint sync_point;
mfxBitstream output_bitstream;
gboolean more_data;
guint pending_frame_number;
};
GType gst_msdkenc_get_type (void);