summaryrefslogtreecommitdiff
path: root/sys/msdk/gstmsdkvpp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/msdk/gstmsdkvpp.c')
-rw-r--r--sys/msdk/gstmsdkvpp.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/sys/msdk/gstmsdkvpp.c b/sys/msdk/gstmsdkvpp.c
index 8a8d6c841..bd74e9bd6 100644
--- a/sys/msdk/gstmsdkvpp.c
+++ b/sys/msdk/gstmsdkvpp.c
@@ -867,9 +867,10 @@ gst_msdkvpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
mfxFrameInfo *in_info = NULL;
MsdkSurface *in_surface = NULL;
MsdkSurface *out_surface = NULL;
+ GstBuffer *outbuf_new = NULL;
gboolean locked_by_others;
+ gboolean create_new_surface = FALSE;
- timestamp = GST_BUFFER_TIMESTAMP (inbuf);
free_unlocked_msdk_surfaces (thiz);
in_surface = get_msdk_surface_from_input_buffer (thiz, inbuf);
@@ -883,6 +884,13 @@ gst_msdkvpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
}
locked_by_others = ! !in_surface->surface->Data.Locked;
+ /* always convert timestamp of input surface as msdk timestamp */
+ if (inbuf->pts == GST_CLOCK_TIME_NONE)
+ in_surface->surface->Data.TimeStamp = MFX_TIMESTAMP_UNKNOWN;
+ else
+ in_surface->surface->Data.TimeStamp =
+ gst_util_uint64_scale_round (inbuf->pts, 90000, GST_SECOND);
+
if (gst_msdk_is_msdk_buffer (outbuf)) {
out_surface = g_slice_new0 (MsdkSurface);
out_surface->surface = gst_msdk_get_surface_from_buffer (outbuf);
@@ -912,11 +920,18 @@ gst_msdkvpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
status =
MFXVideoVPP_RunFrameVPPAsync (session, in_surface->surface,
out_surface->surface, NULL, &sync_point);
+ timestamp = out_surface->surface->Data.TimeStamp;
+
if (status != MFX_WRN_DEVICE_BUSY)
break;
/* If device is busy, wait 1ms and retry, as per MSDK's recommendation */
g_usleep (1000);
- };
+ }
+
+ if (timestamp == MFX_TIMESTAMP_UNKNOWN)
+ timestamp = GST_CLOCK_TIME_NONE;
+ else
+ timestamp = gst_util_uint64_scale_round (timestamp, GST_SECOND, 90000);
if (status == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM)
GST_WARNING_OBJECT (thiz, "VPP returned: %s",
@@ -937,16 +952,29 @@ gst_msdkvpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
MFXVideoCORE_SyncOperation (session, sync_point,
300000) != MFX_ERR_NONE)
GST_WARNING_OBJECT (thiz, "failed to do sync operation");
+ /* push new output buffer forward after sync operation */
+ if (create_new_surface) {
+ create_new_surface = FALSE;
+ ret = gst_pad_push (GST_BASE_TRANSFORM_SRC_PAD (trans), outbuf_new);
+ if (ret != GST_FLOW_OK)
+ goto error_push_buffer;
+ }
/* More than one output buffers are generated */
if (status == MFX_ERR_MORE_SURFACE) {
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- GST_BUFFER_DURATION (outbuf) = thiz->buffer_duration;
- timestamp += thiz->buffer_duration;
- ret = gst_pad_push (GST_BASE_TRANSFORM_SRC_PAD (trans), outbuf);
- if (ret != GST_FLOW_OK)
- goto error_push_buffer;
- outbuf = create_output_buffer (thiz);
+ outbuf_new = create_output_buffer (thiz);
+ GST_BUFFER_TIMESTAMP (outbuf_new) = timestamp;
+ GST_BUFFER_DURATION (outbuf_new) = thiz->buffer_duration;
+
+ if (gst_msdk_is_msdk_buffer (outbuf_new)) {
+ release_out_surface (thiz, out_surface);
+ out_surface = g_slice_new0 (MsdkSurface);
+ out_surface->surface = gst_msdk_get_surface_from_buffer (outbuf_new);
+ create_new_surface = TRUE;
+ } else {
+ GST_ERROR_OBJECT (thiz, "Failed to get msdk outsurface!");
+ goto vpp_error;
+ }
} else {
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
GST_BUFFER_DURATION (outbuf) = thiz->buffer_duration;
@@ -1175,8 +1203,10 @@ gst_msdkvpp_initialize (GstMsdkVPP * thiz)
|| GST_VIDEO_INFO_FPS_D (&thiz->sinkpad_info) !=
GST_VIDEO_INFO_FPS_D (&thiz->srcpad_info))) {
thiz->flags |= GST_MSDK_FLAG_FRC;
- /* So far this is the only algorithm which is working somewhat good */
- thiz->frc_algm = MFX_FRCALGM_PRESERVE_TIMESTAMP;
+ /* manually set distributed timestamp as frc algorithm
+ * as it is more resonable for framerate conversion
+ */
+ thiz->frc_algm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP;
}
/* work-around to avoid zero fps in msdk structure */