avviddec: Introduce a class for shared properties
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Tue, 1 Nov 2022 15:13:23 +0000 (11:13 -0400)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 2 Nov 2022 19:23:14 +0000 (19:23 +0000)
Without a parent class,the documentation would need to be duplicated for
every CODECs. This patch adds an abstract class in between GstVideoDecoder
and the element.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3311>

subprojects/gst-libav/ext/libav/gstav.c
subprojects/gst-libav/ext/libav/gstav.h
subprojects/gst-libav/ext/libav/gstavcodecmap.c
subprojects/gst-libav/ext/libav/gstavcodecmap.h
subprojects/gst-libav/ext/libav/gstavutils.h
subprojects/gst-libav/ext/libav/gstavviddec.c
subprojects/gst-libav/ext/libav/gstavviddec.h

index f3fb648..20f21c7 100644 (file)
@@ -61,7 +61,7 @@ gst_ffmpeg_avcodec_is_ffmpeg (void)
 }
 
 int
-gst_ffmpeg_avcodec_open (AVCodecContext * avctx, AVCodec * codec)
+gst_ffmpeg_avcodec_open (AVCodecContext * avctx, const AVCodec * codec)
 {
   int ret;
 
index 0693b77..b705b0d 100644 (file)
@@ -44,7 +44,7 @@ extern gboolean gst_ffmpegvidenc_register (GstPlugin * plugin);
 extern gboolean gst_ffmpegmux_register (GstPlugin * plugin);
 extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin);
 
-int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec);
+int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, const AVCodec *codec);
 int gst_ffmpeg_avcodec_close (AVCodecContext *avctx);
 int gst_ffmpeg_av_find_stream_info(AVFormatContext *ic);
 
index df3aa6b..6610593 100644 (file)
@@ -244,7 +244,7 @@ gst_ffmpeg_video_set_pix_fmts (GstCaps * caps, const enum AVPixelFormat *fmts)
  * but I'm too lazy today. Maybe later.
  */
 static GstCaps *
-gst_ff_vid_caps_new (AVCodecContext * context, AVCodec * codec,
+gst_ff_vid_caps_new (AVCodecContext * context, const AVCodec * codec,
     enum AVCodecID codec_id, gboolean encode, const char *mimetype,
     const char *fieldname, ...)
 {
@@ -2562,7 +2562,7 @@ gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
 
 GstCaps *
 gst_ffmpeg_codectype_to_video_caps (AVCodecContext * context,
-    enum AVCodecID codec_id, gboolean encode, AVCodec * codec)
+    enum AVCodecID codec_id, gboolean encode, const AVCodec * codec)
 {
   GstCaps *caps;
 
index 04b0479..b7f1f20 100644 (file)
@@ -48,15 +48,15 @@ gst_ffmpeg_codecid_to_caps   (enum AVCodecID    codec_id,
  */
 
 GstCaps *
-gst_ffmpeg_codectype_to_audio_caps (AVCodecContext *context, 
+gst_ffmpeg_codectype_to_audio_caps (AVCodecContext *context,
                               enum AVCodecID codec_id,
                                    gboolean encode,
                                    AVCodec *codec);
 GstCaps *
-gst_ffmpeg_codectype_to_video_caps (AVCodecContext *context, 
+gst_ffmpeg_codectype_to_video_caps (AVCodecContext *context,
                               enum AVCodecID codec_id,
                                    gboolean encode,
-                                   AVCodec *codec);
+                                   const AVCodec *codec);
 
 /*
  * caps_to_codecid () transforms a GstCaps that belongs to
index fab7969..bc31c1a 100644 (file)
@@ -114,6 +114,11 @@ av_smp_format_depth(enum AVSampleFormat smp_fmt);
 GstBuffer *
 new_aligned_buffer (gint size);
 
+/**
+ * GstAvCodecCompliance:
+ *
+ * Since: 1.22
+ */
 typedef enum
 {
   GST_AV_CODEC_COMPLIANCE_AUTO = G_MAXINT,
index dac01f5..b15f2ae 100644 (file)
@@ -65,9 +65,6 @@ enum
 };
 
 /* A number of function prototypes are given so we can refer to them later. */
-static void gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass);
-static void gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass);
-static void gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec);
 static void gst_ffmpegviddec_finalize (GObject * object);
 
 static gboolean gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
@@ -104,9 +101,10 @@ static gboolean picture_changed (GstFFMpegVidDec * ffmpegdec,
 static gboolean context_changed (GstFFMpegVidDec * ffmpegdec,
     AVCodecContext * context);
 
-#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
+G_DEFINE_ABSTRACT_TYPE (GstFFMpegVidDec, gst_ffmpegviddec,
+    GST_TYPE_VIDEO_DECODER);
 
-static GstElementClass *parent_class = NULL;
+#define parent_class gst_ffmpegviddec_parent_class
 
 #define GST_FFMPEGVIDDEC_TYPE_LOWRES (gst_ffmpegviddec_lowres_get_type())
 static GType
@@ -189,17 +187,40 @@ dup_caps_with_alternate (GstCaps * caps)
 }
 
 static void
-gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
+gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = gst_ffmpegviddec_set_property;
+  gobject_class->get_property = gst_ffmpegviddec_get_property;
+
+  /**
+   * GstFFMpegVidDec:std-compliance:
+   *
+   * Specifies standard compliance mode to use
+   *
+   * Since: 1.22
+   */
+  g_object_class_install_property (gobject_class, PROP_STD_COMPLIANCE,
+      g_param_spec_enum ("std-compliance", "Standard Compliance",
+          "Standard compliance mode to use", GST_TYPE_AV_CODEC_COMPLIANCE,
+          DEFAULT_STD_COMPLIANCE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gst_ffmpegviddec_subclass_init (GstFFMpegVidDecClass * klass,
+    gconstpointer class_data)
 {
+  GstVideoDecoderClass *viddec_class = GST_VIDEO_DECODER_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GstPadTemplate *sinktempl, *srctempl;
   GstCaps *sinkcaps, *srccaps;
-  AVCodec *in_plugin;
+  const AVCodec *in_plugin;
   gchar *longname, *description;
+  int caps;
 
-  in_plugin =
-      (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
-      GST_FFDEC_PARAMS_QDATA);
+  in_plugin = class_data;
   g_assert (in_plugin != NULL);
 
   /* construct the element details struct */
@@ -239,16 +260,6 @@ gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
   gst_caps_unref (srccaps);
 
   klass->in_plugin = in_plugin;
-}
-
-static void
-gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GstVideoDecoderClass *viddec_class = GST_VIDEO_DECODER_CLASS (klass);
-  int caps;
-
-  parent_class = g_type_class_peek_parent (klass);
 
   gobject_class->finalize = gst_ffmpegviddec_finalize;
 
@@ -295,18 +306,6 @@ gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
             DEFAULT_THREAD_TYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   }
 
-  /**
-   * GstFFMpegVidDec::std-compliance:
-   *
-   * Specifies standard compliance mode to use
-   *
-   * Since: 1.20
-   */
-  g_object_class_install_property (gobject_class, PROP_STD_COMPLIANCE,
-      g_param_spec_enum ("std-compliance", "Standard Compliance",
-          "Standard compliance mode to use", GST_TYPE_AV_CODEC_COMPLIANCE,
-          DEFAULT_STD_COMPLIANCE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   viddec_class->set_format = gst_ffmpegviddec_set_format;
   viddec_class->handle_frame = gst_ffmpegviddec_handle_frame;
   viddec_class->start = gst_ffmpegviddec_start;
@@ -323,11 +322,17 @@ gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
   gst_type_mark_as_plugin_api (GST_FFMPEGVIDDEC_TYPE_SKIPFRAME, 0);
   gst_type_mark_as_plugin_api (GST_FFMPEGVIDDEC_TYPE_THREAD_TYPE, 0);
   gst_type_mark_as_plugin_api (GST_TYPE_AV_CODEC_COMPLIANCE, 0);
+  gst_type_mark_as_plugin_api (GST_TYPE_FFMPEGVIDDEC, 0);
 }
 
 static void
 gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
 {
+}
+
+static void
+gst_ffmpegviddec_subinit (GstFFMpegVidDec * ffmpegdec)
+{
   GstFFMpegVidDecClass *klass =
       (GstFFMpegVidDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
 
@@ -352,7 +357,7 @@ gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
 static void
 gst_ffmpegviddec_finalize (GObject * object)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
 
   av_frame_free (&ffmpegdec->picture);
   avcodec_free_context (&ffmpegdec->context);
@@ -391,7 +396,7 @@ gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec, gboolean reset)
   GstFFMpegVidDecClass *oclass;
   guint i;
 
-  oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
+  oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
 
   GST_LOG_OBJECT (ffmpegdec, "closing ffmpeg codec");
 
@@ -425,7 +430,7 @@ gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
   GstFFMpegVidDecClass *oclass;
   guint i;
 
-  oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
+  oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
 
   if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
     goto could_not_open;
@@ -510,8 +515,8 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
   gboolean is_live;
   GstQuery *query;
 
-  ffmpegdec = (GstFFMpegVidDec *) decoder;
-  oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
+  ffmpegdec = GST_FFMPEGVIDDEC (decoder);
+  oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
 
   GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
 
@@ -889,7 +894,7 @@ gst_ffmpegviddec_can_direct_render (GstFFMpegVidDec * ffmpegdec)
   if (!ffmpegdec->direct_rendering)
     return FALSE;
 
-  oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
+  oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
   return ((oclass->in_plugin->capabilities & AV_CODEC_CAP_DR1) ==
       AV_CODEC_CAP_DR1);
 }
@@ -907,7 +912,7 @@ gst_ffmpegviddec_get_buffer2 (AVCodecContext * context, AVFrame * picture,
   GstFlowReturn ret;
   int create_buffer_flags = 0;
 
-  ffmpegdec = (GstFFMpegVidDec *) context->opaque;
+  ffmpegdec = GST_FFMPEGVIDDEC (context->opaque);
 
   GST_DEBUG_OBJECT (ffmpegdec, "getting buffer picture %p", picture);
 
@@ -2014,7 +2019,7 @@ no_codec:
 static GstFlowReturn
 gst_ffmpegviddec_drain (GstVideoDecoder * decoder)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
   GstFlowReturn ret = GST_FLOW_OK;
   gboolean got_frame = FALSE;
 
@@ -2049,7 +2054,7 @@ static GstFlowReturn
 gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
     GstVideoCodecFrame * frame)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
   guint8 *data;
   gint size;
   gboolean got_frame;
@@ -2156,10 +2161,10 @@ send_packet_failed:
 static gboolean
 gst_ffmpegviddec_start (GstVideoDecoder * decoder)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
   GstFFMpegVidDecClass *oclass;
 
-  oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
+  oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
 
   GST_OBJECT_LOCK (ffmpegdec);
   avcodec_free_context (&ffmpegdec->context);
@@ -2178,7 +2183,7 @@ gst_ffmpegviddec_start (GstVideoDecoder * decoder)
 static gboolean
 gst_ffmpegviddec_stop (GstVideoDecoder * decoder)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
 
   GST_OBJECT_LOCK (ffmpegdec);
   gst_ffmpegviddec_close (ffmpegdec, FALSE);
@@ -2233,7 +2238,7 @@ gst_ffmpegviddec_finish (GstVideoDecoder * decoder)
 static gboolean
 gst_ffmpegviddec_flush (GstVideoDecoder * decoder)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
 
   if (ffmpegdec->opened) {
     GST_LOG_OBJECT (decoder, "flushing buffers");
@@ -2246,7 +2251,7 @@ gst_ffmpegviddec_flush (GstVideoDecoder * decoder)
 static gboolean
 gst_ffmpegviddec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
   GstVideoCodecState *state;
   GstBufferPool *pool;
   guint size, min, max;
@@ -2418,7 +2423,7 @@ static void
 gst_ffmpegviddec_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
 
   switch (prop_id) {
     case PROP_LOWRES:
@@ -2458,7 +2463,7 @@ static void
 gst_ffmpegviddec_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec)
 {
-  GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object;
+  GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
 
   switch (prop_id) {
     case PROP_LOWRES:
@@ -2498,14 +2503,14 @@ gst_ffmpegviddec_register (GstPlugin * plugin)
 {
   GTypeInfo typeinfo = {
     sizeof (GstFFMpegVidDecClass),
-    (GBaseInitFunc) gst_ffmpegviddec_base_init,
     NULL,
-    (GClassInitFunc) gst_ffmpegviddec_class_init,
+    NULL,
+    (GClassInitFunc) gst_ffmpegviddec_subclass_init,
     NULL,
     NULL,
     sizeof (GstFFMpegVidDec),
     0,
-    (GInstanceInitFunc) gst_ffmpegviddec_init,
+    (GInstanceInitFunc) gst_ffmpegviddec_subinit,
   };
   GType type;
   AVCodec *in_plugin;
@@ -2634,10 +2639,10 @@ gst_ffmpegviddec_register (GstPlugin * plugin)
 
     if (!type) {
       /* create the gtype now */
+      typeinfo.class_data = in_plugin;
       type =
-          g_type_register_static (GST_TYPE_VIDEO_DECODER, type_name, &typeinfo,
+          g_type_register_static (GST_TYPE_FFMPEGVIDDEC, type_name, &typeinfo,
           0);
-      g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) in_plugin);
     }
 
     /* (Ronald) MPEG-4 gets a higher priority because it has been well-
index d3b5544..0f713de 100644 (file)
 
 G_BEGIN_DECLS
 
+#define GST_TYPE_FFMPEGVIDDEC           (gst_ffmpegviddec_get_type())
+#define GST_FFMPEGVIDDEC(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGVIDDEC,GstFFMpegVidDec))
+#define GST_FFMPEGVIDDEC_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGVIDDEC,GstFFMpegVidDecClass))
+#define GST_FFMPEGVIDDEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_FFMPEGVIDDEC, GstFFMpegVidDecClass))
+#define GST_IS_FFMPEGVIDDEC(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGVIDDEC))
+#define GST_IS_FFMPEGVIDDEC_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGVIDDEC))
+
+/**
+ * GstFFMpegVidDec:
+ *
+ * The #GstFFMpegVidDec data structure.
+ *
+ * Since: 1.22
+ */
 typedef struct _GstFFMpegVidDec GstFFMpegVidDec;
+
 struct _GstFFMpegVidDec
 {
   GstVideoDecoder parent;
@@ -87,9 +102,11 @@ struct _GstFFMpegVidDecClass
 {
   GstVideoDecoderClass parent_class;
 
-  AVCodec *in_plugin;
+  const AVCodec *in_plugin;
 };
 
+GType gst_ffmpegviddec_get_type (void);
+
 G_END_DECLS
 
 #endif