mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
vaapipostproc: get "interlaced" attribute from surface proxy.
Add new "interlaced" attribute to GstVaapiSurfaceProxy. Use this in vaapipostproc so that to handles cases where bitstream is interlaced but almost only frame pictures are generated. In this case, we should not be alternating between top/bottom fields.
This commit is contained in:
parent
894d65b81a
commit
b98d334dce
4 changed files with 89 additions and 13 deletions
|
@ -496,7 +496,7 @@ render_frame(GstVaapiDecoderFfmpeg *decoder, AVFrame *frame)
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE;
|
return GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts);
|
gst_vaapi_surface_proxy_set_timestamp(proxy, frame->pts);
|
||||||
if (frame->interlaced_frame)
|
gst_vaapi_surface_proxy_set_interlaced(proxy, !!frame->interlaced_frame);
|
||||||
gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first);
|
gst_vaapi_surface_proxy_set_tff(proxy, frame->top_field_first);
|
||||||
gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy));
|
gst_vaapi_decoder_push_surface_proxy(base_decoder, g_object_ref(proxy));
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
|
@ -43,7 +43,8 @@ struct _GstVaapiSurfaceProxyPrivate {
|
||||||
GstVaapiContext *context;
|
GstVaapiContext *context;
|
||||||
GstVaapiSurface *surface;
|
GstVaapiSurface *surface;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
gboolean tff;
|
guint is_interlaced : 1;
|
||||||
|
guint tff : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -52,6 +53,7 @@ enum {
|
||||||
PROP_CONTEXT,
|
PROP_CONTEXT,
|
||||||
PROP_SURFACE,
|
PROP_SURFACE,
|
||||||
PROP_TIMESTAMP,
|
PROP_TIMESTAMP,
|
||||||
|
PROP_INTERLACED,
|
||||||
PROP_TFF
|
PROP_TFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,6 +88,9 @@ gst_vaapi_surface_proxy_set_property(
|
||||||
case PROP_TIMESTAMP:
|
case PROP_TIMESTAMP:
|
||||||
gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value));
|
gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_INTERLACED:
|
||||||
|
gst_vaapi_surface_proxy_set_interlaced(proxy, g_value_get_boolean(value));
|
||||||
|
break;
|
||||||
case PROP_TFF:
|
case PROP_TFF:
|
||||||
gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value));
|
gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value));
|
||||||
break;
|
break;
|
||||||
|
@ -115,6 +120,9 @@ gst_vaapi_surface_proxy_get_property(
|
||||||
case PROP_TIMESTAMP:
|
case PROP_TIMESTAMP:
|
||||||
g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy));
|
g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy));
|
||||||
break;
|
break;
|
||||||
|
case PROP_INTERLACED:
|
||||||
|
g_value_set_boolean(value, gst_vaapi_surface_proxy_get_interlaced(proxy));
|
||||||
|
break;
|
||||||
case PROP_TFF:
|
case PROP_TFF:
|
||||||
g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy));
|
g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy));
|
||||||
break;
|
break;
|
||||||
|
@ -160,6 +168,15 @@ gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass)
|
||||||
0, G_MAXUINT64, GST_CLOCK_TIME_NONE,
|
0, G_MAXUINT64, GST_CLOCK_TIME_NONE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
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
|
g_object_class_install_property
|
||||||
(object_class,
|
(object_class,
|
||||||
PROP_TFF,
|
PROP_TFF,
|
||||||
|
@ -180,6 +197,7 @@ gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy)
|
||||||
priv->context = NULL;
|
priv->context = NULL;
|
||||||
priv->surface = NULL;
|
priv->surface = NULL;
|
||||||
priv->timestamp = GST_CLOCK_TIME_NONE;
|
priv->timestamp = GST_CLOCK_TIME_NONE;
|
||||||
|
priv->is_interlaced = FALSE;
|
||||||
priv->tff = FALSE;
|
priv->tff = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +369,39 @@ gst_vaapi_surface_proxy_set_timestamp(
|
||||||
proxy->priv->timestamp = timestamp;
|
proxy->priv->timestamp = 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:
|
* gst_vaapi_surface_proxy_get_tff:
|
||||||
* @proxy: a #GstVaapiSurfaceProxy
|
* @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);
|
g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE);
|
||||||
|
|
||||||
return proxy->priv->tff;
|
return proxy->priv->is_interlaced && proxy->priv->tff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,6 +72,15 @@ G_BEGIN_DECLS
|
||||||
#define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \
|
#define GST_VAAPI_SURFACE_PROXY_TIMESTAMP(surface) \
|
||||||
gst_vaapi_surface_proxy_get_timestamp(surface)
|
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:
|
* GST_VAAPI_SURFACE_PROXY_TFF:
|
||||||
* @surface: a #GstVaapiSurfaceProxy
|
* @surface: a #GstVaapiSurfaceProxy
|
||||||
|
@ -143,6 +152,12 @@ gst_vaapi_surface_proxy_set_timestamp(
|
||||||
GstClockTime timestamp
|
GstClockTime timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy);
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy);
|
gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy);
|
||||||
|
|
||||||
|
|
|
@ -239,8 +239,10 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
guint outbuf_flags, flags = 0;
|
guint outbuf_flags, flags;
|
||||||
gboolean tff;
|
gboolean interlaced, tff;
|
||||||
|
|
||||||
|
flags = gst_vaapi_video_buffer_get_render_flags(vbuf);
|
||||||
|
|
||||||
/* Deinterlacing disabled, push frame */
|
/* Deinterlacing disabled, push frame */
|
||||||
if (!postproc->deinterlace) {
|
if (!postproc->deinterlace) {
|
||||||
|
@ -253,8 +255,12 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP(buf);
|
timestamp = GST_BUFFER_TIMESTAMP(buf);
|
||||||
proxy = gst_vaapi_video_buffer_get_surface_proxy(vbuf);
|
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);
|
tff = gst_vaapi_surface_proxy_get_tff(proxy);
|
||||||
|
|
||||||
|
flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD|
|
||||||
|
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD);
|
||||||
|
|
||||||
/* First field */
|
/* First field */
|
||||||
outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy);
|
outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy);
|
||||||
if (!outbuf)
|
if (!outbuf)
|
||||||
|
@ -262,9 +268,11 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
|
||||||
|
|
||||||
vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
|
vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
|
||||||
outbuf_flags = flags;
|
outbuf_flags = flags;
|
||||||
outbuf_flags |= tff ?
|
outbuf_flags |= interlaced ? (
|
||||||
|
tff ?
|
||||||
GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD :
|
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_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP(outbuf) = timestamp;
|
GST_BUFFER_TIMESTAMP(outbuf) = timestamp;
|
||||||
|
@ -281,9 +289,11 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
|
||||||
|
|
||||||
vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
|
vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
|
||||||
outbuf_flags = flags;
|
outbuf_flags = flags;
|
||||||
outbuf_flags |= tff ?
|
outbuf_flags |= interlaced ? (
|
||||||
|
tff ?
|
||||||
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD :
|
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_vaapi_video_buffer_set_render_flags(vbuf, outbuf_flags);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration;
|
GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration;
|
||||||
|
|
Loading…
Reference in a new issue