From 8ecc35ecf203397d35c402083893f934345c99ff Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 11:54:40 +0100 Subject: 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. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 77 ++++++++++--------------- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 38 +++--------- gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h | 14 ----- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 34 ++--------- gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h | 14 ----- gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 26 +++++++-- 6 files changed, 63 insertions(+), 140 deletions(-) (limited to 'gst-libs') 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); -- cgit v1.2.1