summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c4
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurfaceproxy.c55
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurfaceproxy.h15
-rw-r--r--gst/vaapi/gstvaapipostproc.c28
4 files changed, 89 insertions, 13 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
index 6309ed8d..2d4d5501 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
@@ -496,8 +496,8 @@ render_frame(GstVaapiDecoderFfmpeg *decoder, AVFrame *frame)
return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE;
gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts);
- if (frame->interlaced_frame)
- gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first);
+ gst_vaapi_surface_proxy_set_interlaced(proxy, !!frame->interlaced_frame);
+ gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first);
gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy));
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c
index 9b01ac34..3c2f2299 100644
--- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c
+++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.c
@@ -43,7 +43,8 @@ struct _GstVaapiSurfaceProxyPrivate {
GstVaapiContext *context;
GstVaapiSurface *surface;
GstClockTime timestamp;
- gboolean tff;
+ guint is_interlaced : 1;
+ guint tff : 1;
};
enum {
@@ -52,6 +53,7 @@ enum {
PROP_CONTEXT,
PROP_SURFACE,
PROP_TIMESTAMP,
+ PROP_INTERLACED,
PROP_TFF
};
@@ -86,6 +88,9 @@ gst_vaapi_surface_proxy_set_property(
case PROP_TIMESTAMP:
gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value));
break;
+ case PROP_INTERLACED:
+ gst_vaapi_surface_proxy_set_interlaced(proxy, g_value_get_boolean(value));
+ break;
case PROP_TFF:
gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value));
break;
@@ -115,6 +120,9 @@ gst_vaapi_surface_proxy_get_property(
case PROP_TIMESTAMP:
g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy));
break;
+ case PROP_INTERLACED:
+ g_value_set_boolean(value, gst_vaapi_surface_proxy_get_interlaced(proxy));
+ break;
case PROP_TFF:
g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy));
break;
@@ -162,6 +170,15 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass)
g_object_class_install_property
(object_class,
+ PROP_INTERLACED,
+ g_param_spec_boolean("interlaced",
+ "Interlaced",
+ "Flag indicating whether surface is interlaced",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class,
PROP_TFF,
g_param_spec_boolean("tff",
"Top-Field-First",
@@ -180,6 +197,7 @@ gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy)
priv->context = NULL;
priv->surface = NULL;
priv->timestamp = GST_CLOCK_TIME_NONE;
+ priv->is_interlaced = FALSE;
priv->tff = FALSE;
}
@@ -352,6 +370,39 @@ gst_vaapi_surface_proxy_set_timestamp(
}
/**
+ * gst_vaapi_surface_proxy_get_interlaced:
+ * @proxy: a #GstVaapiSurfaceProxy
+ *
+ * Returns whether the @proxy holds an interlaced #GstVaapiSurface or not.
+ *
+ * Return value: %TRUE if the underlying surface is interlaced, %FALSE
+ * otherwise.
+ */
+gboolean
+gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE);
+
+ return proxy->priv->is_interlaced;
+}
+
+/**
+ * gst_vaapi_surface_proxy_set_interlaced:
+ * @proxy: a #GstVaapiSurfaceProxy
+ * @b: a boolean value
+ *
+ * Sets whether the underlying #GstVaapiSurface for @proxy is interlaced
+ * or not.
+ */
+void
+gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b)
+{
+ g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
+
+ proxy->priv->is_interlaced = b;
+}
+
+/**
* gst_vaapi_surface_proxy_get_tff:
* @proxy: a #GstVaapiSurfaceProxy
*
@@ -364,7 +415,7 @@ gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy)
{
g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE);
- return proxy->priv->tff;
+ return proxy->priv->is_interlaced && proxy->priv->tff;
}
/**
diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h
index a6d96308..b32458c7 100644
--- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h
+++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h
@@ -73,6 +73,15 @@ G_BEGIN_DECLS
gst_vaapi_surface_proxy_get_timestamp(surface)
/**
+ * GST_VAAPI_SURFACE_PROXY_INTERLACED:
+ * @surface: a #GstVaapiSurfaceProxy
+ *
+ * Macro that evaluates to %TRUE if the @surface is interlaced.
+ */
+#define GST_VAAPI_SURFACE_PROXY_INTERLACED(surface) \
+ gst_vaapi_surface_proxy_get_interlaced(surface)
+
+/**
* GST_VAAPI_SURFACE_PROXY_TFF:
* @surface: a #GstVaapiSurfaceProxy
*
@@ -144,6 +153,12 @@ gst_vaapi_surface_proxy_set_timestamp(
);
gboolean
+gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy);
+
+void
+gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b);
+
+gboolean
gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy);
void
diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c
index e0f9f679..31a46e25 100644
--- a/gst/vaapi/gstvaapipostproc.c
+++ b/gst/vaapi/gstvaapipostproc.c
@@ -239,8 +239,10 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
GstClockTime timestamp;
GstFlowReturn ret;
GstBuffer *outbuf = NULL;
- guint outbuf_flags, flags = 0;
- gboolean tff;
+ guint outbuf_flags, flags;
+ gboolean interlaced, tff;
+
+ flags = gst_vaapi_video_buffer_get_render_flags(vbuf);
/* Deinterlacing disabled, push frame */
if (!postproc->deinterlace) {
@@ -251,9 +253,13 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
return GST_FLOW_OK;
}
- timestamp = GST_BUFFER_TIMESTAMP(buf);
- proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf);
- tff = gst_vaapi_surface_proxy_get_tff(proxy);
+ timestamp = GST_BUFFER_TIMESTAMP(buf);
+ proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf);
+ interlaced = gst_vaapi_surface_proxy_get_interlaced(proxy);
+ tff = gst_vaapi_surface_proxy_get_tff(proxy);
+
+ flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD|
+ GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD);
/* First field */
outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy);
@@ -262,9 +268,11 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
outbuf_flags = flags;
- outbuf_flags |= tff ?
+ outbuf_flags |= interlaced ? (
+ tff ?
GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD :
- GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
+ GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) :
+ GST_VAAPI_PICTURE_STRUCTURE_FRAME;
gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags);
GST_BUFFER_TIMESTAMP(outbuf) = timestamp;
@@ -281,9 +289,11 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
outbuf_flags = flags;
- outbuf_flags |= tff ?
+ outbuf_flags |= interlaced ? (
+ tff ?
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD :
- GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
+ GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) :
+ GST_VAAPI_PICTURE_STRUCTURE_FRAME;
gst_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags);
GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration;