msdkdec: force the alignment of width/height to 16 for vp8/vp9

MSDK library requires 16 alignment for vp8/vp9, otherwise a pipeline
for vp8/vp9 decoding might fail.

example pipeline:
gst-launch-1.0 filesrc location=vp8_1280x720.webm ! matroskademux ! \
msdkvp8dec ! fakesink

0:00:00.150565444 10657 0x55c8484036d0 ERROR                msdkdec
gstmsdkdec.c:1056:gst_msdkdec_handle_frame:<msdkvp8dec0>
DecodeFrameAsync failed (invalid video parameters)
This commit is contained in:
Haihao Xiang 2019-02-22 16:20:16 +08:00 committed by Víctor Manuel Jáquez Leal
parent 0806f94e1c
commit a751b33072
4 changed files with 46 additions and 7 deletions

View file

@ -263,6 +263,7 @@ gst_msdkdec_set_context (GstElement * element, GstContext * context)
static gboolean static gboolean
gst_msdkdec_init_decoder (GstMsdkDec * thiz) gst_msdkdec_init_decoder (GstMsdkDec * thiz)
{ {
GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz);
GstVideoInfo *info; GstVideoInfo *info;
mfxSession session; mfxSession session;
mfxStatus status; mfxStatus status;
@ -300,13 +301,8 @@ gst_msdkdec_init_decoder (GstMsdkDec * thiz)
g_return_val_if_fail (thiz->param.mfx.FrameInfo.Width g_return_val_if_fail (thiz->param.mfx.FrameInfo.Width
&& thiz->param.mfx.FrameInfo.Height, FALSE); && thiz->param.mfx.FrameInfo.Height, FALSE);
/* Force 32 bit rounding to avoid messing up of memory alignment when klass->preinit_decoder (thiz);
* dealing with different allocators */
/* Fixme: msdk sometimes only requires 16 bit rounding, optimization possible */
thiz->param.mfx.FrameInfo.Width =
GST_ROUND_UP_16 (thiz->param.mfx.FrameInfo.Width);
thiz->param.mfx.FrameInfo.Height =
GST_ROUND_UP_32 (thiz->param.mfx.FrameInfo.Height);
/* Set framerate only if provided. /* Set framerate only if provided.
* If not, framerate will be assumed inside the driver. * If not, framerate will be assumed inside the driver.
* Also we respect the upstream provided fps values */ * Also we respect the upstream provided fps values */
@ -1449,6 +1445,17 @@ gst_msdkdec_finalize (GObject * object)
g_object_unref (thiz->adapter); g_object_unref (thiz->adapter);
} }
static gboolean
gst_msdkdec_preinit_decoder (GstMsdkDec * decoder)
{
decoder->param.mfx.FrameInfo.Width =
GST_ROUND_UP_16 (decoder->param.mfx.FrameInfo.Width);
decoder->param.mfx.FrameInfo.Height =
GST_ROUND_UP_32 (decoder->param.mfx.FrameInfo.Height);
return TRUE;
}
static void static void
gst_msdkdec_class_init (GstMsdkDecClass * klass) gst_msdkdec_class_init (GstMsdkDecClass * klass)
{ {
@ -1477,6 +1484,8 @@ gst_msdkdec_class_init (GstMsdkDecClass * klass)
decoder_class->flush = GST_DEBUG_FUNCPTR (gst_msdkdec_flush); decoder_class->flush = GST_DEBUG_FUNCPTR (gst_msdkdec_flush);
decoder_class->drain = GST_DEBUG_FUNCPTR (gst_msdkdec_drain); decoder_class->drain = GST_DEBUG_FUNCPTR (gst_msdkdec_drain);
klass->preinit_decoder = GST_DEBUG_FUNCPTR (gst_msdkdec_preinit_decoder);
g_object_class_install_property (gobject_class, GST_MSDKDEC_PROP_HARDWARE, g_object_class_install_property (gobject_class, GST_MSDKDEC_PROP_HARDWARE,
g_param_spec_boolean ("hardware", "Hardware", "Enable hardware decoders", g_param_spec_boolean ("hardware", "Hardware", "Enable hardware decoders",
PROP_HARDWARE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); PROP_HARDWARE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

View file

@ -107,6 +107,10 @@ struct _GstMsdkDecClass
GstVideoDecoderClass parent_class; GstVideoDecoderClass parent_class;
gboolean (*configure) (GstMsdkDec * decoder); gboolean (*configure) (GstMsdkDec * decoder);
/* reset mfx parameters per codec, currently it is only used for
* the alignment exception for frame width and height */
gboolean (*preinit_decoder) (GstMsdkDec * decoder);
}; };
struct _MsdkDecTask struct _MsdkDecTask

View file

@ -132,6 +132,17 @@ gst_msdkdec_vp8_get_property (GObject * object, guint prop_id, GValue * value,
GST_OBJECT_UNLOCK (thiz); GST_OBJECT_UNLOCK (thiz);
} }
static gboolean
gst_msdkvp8dec_preinit_decoder (GstMsdkDec * decoder)
{
decoder->param.mfx.FrameInfo.Width =
GST_ROUND_UP_16 (decoder->param.mfx.FrameInfo.Width);
decoder->param.mfx.FrameInfo.Height =
GST_ROUND_UP_16 (decoder->param.mfx.FrameInfo.Height);
return TRUE;
}
static void static void
gst_msdkvp8dec_class_init (GstMsdkVP8DecClass * klass) gst_msdkvp8dec_class_init (GstMsdkVP8DecClass * klass)
{ {
@ -147,6 +158,8 @@ gst_msdkvp8dec_class_init (GstMsdkVP8DecClass * klass)
gobject_class->get_property = gst_msdkdec_vp8_get_property; gobject_class->get_property = gst_msdkdec_vp8_get_property;
decoder_class->configure = GST_DEBUG_FUNCPTR (gst_msdkvp8dec_configure); decoder_class->configure = GST_DEBUG_FUNCPTR (gst_msdkvp8dec_configure);
decoder_class->preinit_decoder =
GST_DEBUG_FUNCPTR (gst_msdkvp8dec_preinit_decoder);
gst_element_class_set_static_metadata (element_class, gst_element_class_set_static_metadata (element_class,
"Intel MSDK VP8 decoder", "Intel MSDK VP8 decoder",

View file

@ -148,6 +148,17 @@ gst_msdkdec_vp9_get_property (GObject * object, guint prop_id, GValue * value,
GST_OBJECT_UNLOCK (thiz); GST_OBJECT_UNLOCK (thiz);
} }
static gboolean
gst_msdkvp9dec_preinit_decoder (GstMsdkDec * decoder)
{
decoder->param.mfx.FrameInfo.Width =
GST_ROUND_UP_16 (decoder->param.mfx.FrameInfo.Width);
decoder->param.mfx.FrameInfo.Height =
GST_ROUND_UP_16 (decoder->param.mfx.FrameInfo.Height);
return TRUE;
}
static void static void
gst_msdkvp9dec_class_init (GstMsdkVP9DecClass * klass) gst_msdkvp9dec_class_init (GstMsdkVP9DecClass * klass)
{ {
@ -163,6 +174,8 @@ gst_msdkvp9dec_class_init (GstMsdkVP9DecClass * klass)
gobject_class->get_property = gst_msdkdec_vp9_get_property; gobject_class->get_property = gst_msdkdec_vp9_get_property;
decoder_class->configure = GST_DEBUG_FUNCPTR (gst_msdkvp9dec_configure); decoder_class->configure = GST_DEBUG_FUNCPTR (gst_msdkvp9dec_configure);
decoder_class->preinit_decoder =
GST_DEBUG_FUNCPTR (gst_msdkvp9dec_preinit_decoder);
gst_element_class_set_static_metadata (element_class, gst_element_class_set_static_metadata (element_class,
"Intel MSDK VP9 decoder", "Intel MSDK VP9 decoder",