summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-12-04 11:54:40 +0100
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-12-04 19:14:38 +0100
commit8ecc35ecf203397d35c402083893f934345c99ff (patch)
treee6b8e68860b97eaffab62b0b7d7a78feef4eadd9 /gst-libs
parent0fb7c605080e926a4ff3a7b01337281d968148b5 (diff)
downloadgst-vaapi-8ecc35ecf203397d35c402083893f934345c99ff.tar.gz
encoder: fix subclassing process.
Fix the GstVaapiEncoderClass parent class type. Make sure to validate subclass hooks as early as possible, i.e. in gst_vaapi_encoder_init(), thus avoiding useless run-time checks. Also simplify the subclass initialization process to be less error prone.
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder.c77
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_h264.c38
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h14
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c34
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h14
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_priv.h26
6 files changed, 63 insertions, 140 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c
index 61f063a6..adb5b2cd 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder.c
@@ -261,9 +261,6 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder,
GstVaapiCodedBufferProxy *coded_buf = NULL;
GstVaapiEncoderSyncPic *sync_pic = NULL;
- if (!klass->reordering || !klass->encode)
- goto error;
-
again:
picture = NULL;
sync_pic = NULL;
@@ -350,18 +347,9 @@ end:
GstVaapiEncoderStatus
gst_vaapi_encoder_flush (GstVaapiEncoder * encoder)
{
- GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS;
GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
- if (!klass->flush)
- goto error;
-
- ret = klass->flush (encoder);
- return ret;
-
-error:
- GST_ERROR ("flush failed");
- return GST_VAAPI_ENCODER_STATUS_FUNC_PTR_ERR;
+ return klass->flush (encoder);
}
GstVaapiEncoderStatus
@@ -390,9 +378,8 @@ gst_vaapi_encoder_ensure_context (GstVaapiEncoder * encoder)
return TRUE;
memset (&info, 0, sizeof (info));
- if (!klass->get_context_info || !klass->get_context_info (encoder, &info)) {
+ if (!klass->get_context_info (encoder, &info))
return FALSE;
- }
context = gst_vaapi_context_new_full (GST_VAAPI_ENCODER_DISPLAY (encoder),
&info);
@@ -418,9 +405,6 @@ gst_vaapi_encoder_set_format (GstVaapiEncoder * encoder,
}
GST_VAAPI_ENCODER_VIDEO_INFO (encoder) = in_state->info;
- if (!klass->set_format)
- goto error;
-
out_caps = klass->set_format (encoder, in_state, ref_caps);
if (!out_caps)
goto error;
@@ -460,19 +444,28 @@ error:
static gboolean
gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display)
{
- GstVaapiEncoderClass *kclass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
+ GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
- g_assert (kclass);
- g_assert (display);
+ g_return_val_if_fail (display != NULL, FALSE);
- g_return_val_if_fail (display, FALSE);
- g_return_val_if_fail (encoder->display == NULL, FALSE);
+#define CHECK_VTABLE_HOOK(FUNC) do { \
+ if (!klass->FUNC) \
+ goto error_invalid_vtable; \
+ } while (0)
+
+ CHECK_VTABLE_HOOK (init);
+ CHECK_VTABLE_HOOK (finalize);
+ CHECK_VTABLE_HOOK (encode);
+ CHECK_VTABLE_HOOK (reordering);
+ CHECK_VTABLE_HOOK (flush);
+ CHECK_VTABLE_HOOK (get_context_info);
+ CHECK_VTABLE_HOOK (set_format);
+
+#undef CHECK_VTABLE_HOOK
encoder->display = gst_vaapi_display_ref (display);
encoder->va_display = gst_vaapi_display_get_display (display);
- encoder->context = NULL;
encoder->va_context = VA_INVALID_ID;
- encoder->caps = NULL;
gst_video_info_init (&encoder->video_info);
@@ -482,18 +475,22 @@ gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display)
g_queue_init (&encoder->sync_pictures);
g_cond_init (&encoder->sync_ready);
- if (kclass->init)
- return kclass->init (encoder);
- return TRUE;
+ return klass->init (encoder);
+
+ /* ERRORS */
+error_invalid_vtable:
+ {
+ GST_ERROR ("invalid subclass hook (internal error)");
+ return FALSE;
+ }
}
-static void
-gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder)
+void
+gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder)
{
GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
- if (klass->destroy)
- klass->destroy (encoder);
+ klass->finalize (encoder);
gst_vaapi_encoder_free_sync_pictures (encoder);
gst_vaapi_video_pool_replace (&encoder->codedbuf_pool, NULL);
@@ -508,22 +505,6 @@ gst_vaapi_encoder_destroy (GstVaapiEncoder * encoder)
g_cond_clear (&encoder->sync_ready);
}
-void
-gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder)
-{
- gst_vaapi_encoder_destroy (encoder);
-}
-
-void
-gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass)
-{
- GstVaapiMiniObjectClass *const object_class =
- GST_VAAPI_MINI_OBJECT_CLASS (klass);
-
- object_class->size = sizeof (GstVaapiEncoder);
- object_class->finalize = (GDestroyNotify) gst_vaapi_encoder_finalize;
-}
-
GstVaapiEncoder *
gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass,
GstVaapiDisplay * display)
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
index a7fa921c..01546daf 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
@@ -1711,10 +1711,10 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base)
}
static void
-gst_vaapi_encoder_h264_destroy (GstVaapiEncoder * base)
+gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base)
{
/*free private buffers */
- GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base);
+ GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base);
GstVaapiEncPicture *pic;
GstVaapiEncoderH264Ref *ref;
@@ -1736,38 +1736,14 @@ gst_vaapi_encoder_h264_destroy (GstVaapiEncoder * base)
}
-static void
-gst_vaapi_encoder_h264_class_init (GstVaapiEncoderH264Class * klass)
-{
- GstVaapiMiniObjectClass *const object_class =
- GST_VAAPI_MINI_OBJECT_CLASS (klass);
- GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
-
- gst_vaapi_encoder_class_init (encoder_class);
-
- object_class->size = sizeof (GstVaapiEncoderH264);
-
- encoder_class->init = gst_vaapi_encoder_h264_init;
- encoder_class->destroy = gst_vaapi_encoder_h264_destroy;
- encoder_class->set_format = gst_vaapi_encoder_h264_set_format;
- encoder_class->get_context_info = gst_vaapi_encoder_h264_get_context_info;
- encoder_class->reordering = gst_vaapi_encoder_h264_reordering;
- encoder_class->encode = gst_vaapi_encoder_h264_encode;
- encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data;
- encoder_class->flush = gst_vaapi_encoder_h264_flush;
-}
-
static inline const GstVaapiEncoderClass *
gst_vaapi_encoder_h264_class ()
{
- static GstVaapiEncoderH264Class g_class;
- static gsize g_class_init = FALSE;
-
- if (g_once_init_enter (&g_class_init)) {
- gst_vaapi_encoder_h264_class_init (&g_class);
- g_once_init_leave (&g_class_init, TRUE);
- }
- return GST_VAAPI_ENCODER_CLASS (&g_class);
+ static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
+ GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
+ .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
+ };
+ return &GstVaapiEncoderH264Class;
}
GstVaapiEncoder *
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
index a7027ae9..3a60a6fc 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
@@ -33,14 +33,6 @@ G_BEGIN_DECLS
((GstVaapiEncoderH264 *)(encoder))
#define GST_VAAPI_ENCODER_H264_CAST(encoder) \
((GstVaapiEncoderH264 *)(encoder))
-#define GST_VAAPI_ENCODER_H264_CLASS(klass) \
- ((GstVaapiEncoderH264Class *)(klass))
-#define GST_IS_VAAPI_ENCODER_H264_CLASS(klass) \
- ((klass) != NULL)
-#define GST_VAAPI_ENCODER_H264_GET_CLASS(obj) \
- GST_VAAPI_ENCODER_H264_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj))
-
-typedef struct _GstVaapiEncoderH264Class GstVaapiEncoderH264Class;
typedef enum
{
@@ -115,12 +107,6 @@ struct _GstVaapiEncoderH264
};
-struct _GstVaapiEncoderH264Class
-{
- /*< private > */
- GstVaapiEncoderClass parent_class;
-};
-
G_END_DECLS
#endif /*GST_VAAPI_ENCODER_H264_PRIV_H */
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
index 70decdb3..10de5875 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
@@ -741,7 +741,7 @@ push_reference (GstVaapiEncoderMpeg2 * encoder, GstVaapiSurfaceProxy * ref)
}
static void
-gst_vaapi_encoder_mpeg2_destroy (GstVaapiEncoder * base)
+gst_vaapi_encoder_mpeg2_finalize (GstVaapiEncoder * base)
{
/*free private buffers */
GstVaapiEncoderMpeg2 *encoder = GST_VAAPI_ENCODER_MPEG2 (base);
@@ -756,37 +756,13 @@ gst_vaapi_encoder_mpeg2_destroy (GstVaapiEncoder * base)
g_queue_clear (&encoder->b_frames);
}
-static void
-gst_vaapi_encoder_mpeg2_class_init (GstVaapiEncoderMpeg2Class * klass)
-{
- GstVaapiMiniObjectClass *const object_class =
- GST_VAAPI_MINI_OBJECT_CLASS (klass);
- GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
-
- gst_vaapi_encoder_class_init (encoder_class);
-
- object_class->size = sizeof (GstVaapiEncoderMpeg2);
-
- encoder_class->init = gst_vaapi_encoder_mpeg2_init;
- encoder_class->destroy = gst_vaapi_encoder_mpeg2_destroy;
- encoder_class->set_format = gst_vaapi_encoder_mpeg2_set_format;
- encoder_class->get_context_info = gst_vaapi_encoder_mpeg2_get_context_info;
- encoder_class->reordering = gst_vaapi_encoder_mpeg2_reordering;
- encoder_class->encode = gst_vaapi_encoder_mpeg2_encode;
- encoder_class->flush = gst_vaapi_encoder_mpeg2_flush;
-}
-
static inline const GstVaapiEncoderClass *
gst_vaapi_encoder_mpeg2_class ()
{
- static GstVaapiEncoderMpeg2Class g_class;
- static gsize g_class_init = FALSE;
-
- if (g_once_init_enter (&g_class_init)) {
- gst_vaapi_encoder_mpeg2_class_init (&g_class);
- g_once_init_leave (&g_class_init, TRUE);
- }
- return GST_VAAPI_ENCODER_CLASS (&g_class);
+ static const GstVaapiEncoderClass GstVaapiEncoderMpeg2Class = {
+ GST_VAAPI_ENCODER_CLASS_INIT (Mpeg2, mpeg2),
+ };
+ return &GstVaapiEncoderMpeg2Class;
}
GstVaapiEncoder *
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
index c5da350e..ff20dbe5 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
@@ -32,14 +32,6 @@ G_BEGIN_DECLS
((GstVaapiEncoderMpeg2 *)(encoder))
#define GST_VAAPI_ENCODER_MPEG2_CAST(encoder) \
((GstVaapiEncoderMpeg2 *)(encoder))
-#define GST_VAAPI_ENCODER_MPEG2_CLASS(klass) \
- ((GstVaapiEncoderMpeg2Class *)(klass))
-#define GST_IS_VAAPI_ENCODER_MPEG2_CLASS(klass) \
- ((klass) != NULL)
-#define GST_VAAPI_ENCODER_MPEG2_GET_CLASS(obj) \
- GST_VAAPI_ENCODER_MPEG2_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj))
-
-typedef struct _GstVaapiEncoderMpeg2Class GstVaapiEncoderMpeg2Class;
typedef enum
{
@@ -105,12 +97,6 @@ struct _GstVaapiEncoderMpeg2
guint32 frame_num; /* same value picture header, but it's not mod by 1024 */
};
-struct _GstVaapiEncoderMpeg2Class
-{
- /*< private > */
- GstVaapiEncoderClass parent_class;
-};
-
G_END_DECLS
#endif /* GST_VAAPI_ENCODER_MPEG2_PRIV_H */
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
index 8b78ac95..e18fe588 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
@@ -105,10 +105,10 @@ struct _GstVaapiEncoder
struct _GstVaapiEncoderClass
{
- GObjectClass parent_class;
+ GstVaapiMiniObjectClass parent_class;
gboolean (*init) (GstVaapiEncoder * encoder);
- void (*destroy) (GstVaapiEncoder * encoder);
+ void (*finalize) (GstVaapiEncoder * encoder);
GstCaps * (*set_format) (GstVaapiEncoder * encoder,
GstVideoCodecState * in_state,
@@ -132,13 +132,31 @@ struct _GstVaapiEncoderClass
GstBuffer ** codec_data);
};
-void
-gst_vaapi_encoder_class_init (GstVaapiEncoderClass * klass);
+#define GST_VAAPI_ENCODER_CLASS_HOOK(codec, func) \
+ .func = G_PASTE (G_PASTE (G_PASTE (gst_vaapi_encoder_,codec),_), func)
+
+#define GST_VAAPI_ENCODER_CLASS_INIT_BASE(CODEC) \
+ .parent_class = { \
+ .size = sizeof (G_PASTE (GstVaapiEncoder, CODEC)), \
+ .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize \
+ }
+#define GST_VAAPI_ENCODER_CLASS_INIT(CODEC, codec) \
+ GST_VAAPI_ENCODER_CLASS_INIT_BASE (CODEC), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, init), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_format), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_context_info), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \
+ GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush)
+
+G_GNUC_INTERNAL
GstVaapiEncoder *
gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass,
GstVaapiDisplay * display);
+G_GNUC_INTERNAL
void
gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder);