From e0f8ce501bf57d4cf93e276d8ac539865ec9b409 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 10 Dec 2021 14:09:44 -0500 Subject: [PATCH] v4l2codecs: vp9: Add alpha decodebin wrapper This will allow HW accelerated decoding of WebM alpha videos. Part-of: --- .../sys/v4l2codecs/gstv4l2codecvp9dec.c | 57 +++++++++++++++++++++- .../sys/v4l2codecs/gstv4l2codecvp9dec.h | 5 +- .../gst-plugins-bad/sys/v4l2codecs/plugin.c | 3 +- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c index 02b48d6..8017ab0 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c @@ -23,6 +23,7 @@ #endif #include "gstv4l2codecallocator.h" +#include "gstv4l2codecalphadecodebin.h" #include "gstv4l2codecpool.h" #include "gstv4l2codecvp9dec.h" #include "linux/v4l2-controls.h" @@ -46,6 +47,13 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, GST_STATIC_CAPS ("video/x-vp9, " "alignment=(string) frame") ); +static GstStaticPadTemplate alpha_template = +GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, + GST_PAD_SINK, GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-vp9, codec-alpha = (boolean) true, " + "alignment = frame") + ); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, @@ -1100,13 +1108,58 @@ gst_v4l2_codec_vp9_dec_subclass_init (GstV4l2CodecVp9DecClass * klass, gst_v4l2_decoder_install_properties (gobject_class, PROP_LAST, device); } +static void gst_v4l2_codec_vp9_alpha_decode_bin_subclass_init + (GstV4l2CodecAlphaDecodeBinClass * klass, gchar * decoder_name) +{ + GstV4l2CodecAlphaDecodeBinClass *adbin_class = + (GstV4l2CodecAlphaDecodeBinClass *) klass; + GstElementClass *element_class = (GstElementClass *) klass; + + adbin_class->decoder_name = decoder_name; + gst_element_class_add_static_pad_template (element_class, &alpha_template); + + gst_element_class_set_static_metadata (element_class, + "VP9 Alpha Decoder", "Codec/Decoder/Video", + "Wrapper bin to decode VP9 with alpha stream.", + "Nicolas Dufresne "); +} + void -gst_v4l2_codec_vp9_dec_register (GstPlugin * plugin, +gst_v4l2_codec_vp9_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, GstV4l2CodecDevice * device, guint rank) { + gchar *element_name; + GstCaps *src_caps, *alpha_caps; + + if (!gst_v4l2_decoder_set_sink_fmt (decoder, V4L2_PIX_FMT_VP9_FRAME, + 320, 240, 8)) + return; + src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + + if (gst_caps_is_empty (src_caps)) { + GST_WARNING ("Not registering VP9 decoder since it produces no " + "supported format"); + goto done; + } + gst_v4l2_decoder_register (plugin, GST_TYPE_V4L2_CODEC_VP9_DEC, (GClassInitFunc) gst_v4l2_codec_vp9_dec_subclass_init, gst_mini_object_ref (GST_MINI_OBJECT (device)), (GInstanceInitFunc) gst_v4l2_codec_vp9_dec_subinit, - "v4l2sl%svp9dec", device, rank, NULL); + "v4l2sl%svp9dec", device, rank, &element_name); + + if (!element_name) + goto done; + + alpha_caps = gst_caps_from_string ("video/x-raw,format={I420, NV12}"); + + if (gst_caps_can_intersect (src_caps, alpha_caps)) + gst_v4l2_codec_alpha_decode_bin_register (plugin, + (GClassInitFunc) gst_v4l2_codec_vp9_alpha_decode_bin_subclass_init, + element_name, "v4l2slvp9%salphadecodebin", device, rank); + + gst_caps_unref (alpha_caps); + +done: + gst_caps_unref (src_caps); } diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.h b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.h index 35cf45e..312ad4f 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.h +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.h @@ -46,8 +46,9 @@ struct _GstV4l2CodecVp9DecClass GType gst_v4l2_codec_vp9_dec_get_type (void); void gst_v4l2_codec_vp9_dec_register (GstPlugin * plugin, - GstV4l2CodecDevice * device, - guint rank); + GstV4l2Decoder * decoder, + GstV4l2CodecDevice * device, + guint rank); G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/plugin.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/plugin.c index f5f09ba..7d0796e 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/plugin.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/plugin.c @@ -69,7 +69,8 @@ register_video_decoder (GstPlugin * plugin, GstV4l2CodecDevice * device) case V4L2_PIX_FMT_VP9_FRAME: GST_INFO_OBJECT (decoder, "Registering %s as VP9 Decoder", device->name); - gst_v4l2_codec_vp9_dec_register (plugin, device, GST_RANK_PRIMARY + 1); + gst_v4l2_codec_vp9_dec_register (plugin, decoder, device, + GST_RANK_PRIMARY + 1); break; default: -- 2.7.4