encoder: reduce function parameters and change variable names
authorWind Yuan <feng.yuan@intel.com>
Thu, 20 Sep 2012 06:41:53 +0000 (14:41 +0800)
committerZhong Cong <congx.zhong@intel.com>
Tue, 5 Feb 2013 07:37:12 +0000 (15:37 +0800)
gst-libs/gst/vaapi/gstvaapibaseencoder.c
gst-libs/gst/vaapi/gstvaapibaseencoder.h
gst-libs/gst/vaapi/gstvaapiencoder.c
gst-libs/gst/vaapi/gstvaapiencoder.h
gst-libs/gst/vaapi/gstvaapiencoder_h263.c
gst-libs/gst/vaapi/gstvaapiencoder_h263.h
gst-libs/gst/vaapi/gstvaapiencoder_h264.c
gst-libs/gst/vaapi/gstvaapiencoder_mpeg4.c
gst-libs/gst/vaapi/gstvaapiencoder_mpeg4.h

index 00ec591..3d4ebbc 100644 (file)
@@ -66,168 +66,153 @@ struct _GstVaapiBaseEncoderPrivate {
 
 G_DEFINE_TYPE(GstVaapiBaseEncoder, gst_vaapi_base_encoder, GST_TYPE_VAAPI_ENCODER);
 
-static EncoderStatus gst_vaapi_base_encoder_initialize_default(
-                         GstVaapiEncoder* encoder, GstVaapiDisplay *display);
-static EncoderStatus gst_vaapi_base_encoder_uninitialize_default(
-                         GstVaapiEncoder* encoder, GstVaapiDisplay *display);
-static EncoderStatus gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder,
-                         GstVaapiDisplay *display,
-                         GstVaapiContext **context);
-static EncoderStatus gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder,
-                         GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder,
-                         GstVaapiDisplay *display, GstVaapiContext *context,
-                         GstBuffer *raw_pic, GList **coded_pics);
-static EncoderStatus gst_vaapi_base_encoder_flush_default(GstVaapiEncoder* encoder,
-                         GstVaapiDisplay *display,
-                         GstVaapiContext *context,
-                         GList **coded_pics);
-static GstBuffer    *gst_vaapi_base_encoder_copy_buffer_default(GstVaapiBaseEncoder *encoder,
-                         guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
-
-
-static gboolean      base_encoder_alloc_coded_buffers(GstVaapiBaseEncoder *base_encoder,
-                         GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus base_encoder_release_coded_buffers(GstVaapiBaseEncoder *base_encoder,
-                         GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus base_query_encoding_status(GstVaapiBaseEncoder *base_encoder,
-                         GstVaapiDisplay *display, GstVaapiSurface *buffer_surface,
-                         gboolean is_key, GstVaapiVideoBuffer *surface_buffer,
-                         VABufferID *coded_buf, GList **coded_pics);
-
-static VABufferID   *pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *base_prv);
+static VABufferID   *pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv);
 static gboolean      push_available_coded_buffer(
-                         GstVaapiBaseEncoderPrivate *base_prv, VABufferID *buf);
+                         GstVaapiBaseEncoderPrivate *priv, VABufferID *buf);
+void
+gst_vaapi_base_encoder_set_frame_notify(GstVaapiBaseEncoder *encoder, gboolean flag)
+{
+  GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+  priv->frame_notify_flag = flag;
+}
 
-static void
-gst_vaapi_base_encoder_finalize(GObject *object)
+gboolean
+gst_vaapi_base_encoder_set_va_profile(GstVaapiBaseEncoder *encoder, guint profile)
 {
-  /*free private buffers*/
-  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(object);
+  GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+  priv->profile = profile;
+  return TRUE;
+}
 
-  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
-    gst_vaapi_encoder_uninitialize(encoder);
-  }
+void
+gst_vaapi_base_encoder_set_input_format(GstVaapiBaseEncoder* encoder, guint32 format)
+{
+  GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+  priv->format = format;
+}
 
-  g_mutex_free(base_prv->code_buffer_lock);
-  g_cond_free(base_prv->code_buffer_cond);
-  if (base_prv->available_code_buffers) {
-    g_queue_free(base_prv->available_code_buffers);
-    base_prv->available_code_buffers = NULL;
+static gboolean
+default_validate_encoder_parameters(GstVaapiBaseEncoder *encoder)
+{
+  if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
+    return FALSE;
   }
-
-  G_OBJECT_CLASS(gst_vaapi_base_encoder_parent_class)->finalize(object);
+  return TRUE;
 }
 
-
-static void
-gst_vaapi_base_encoder_class_init(GstVaapiBaseEncoderClass *klass)
+static gboolean
+base_encoder_alloc_coded_buffers(
+    GstVaapiBaseEncoder *base_encoder,
+    GstVaapiContext *context
+)
 {
-  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
-  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
-  g_type_class_add_private(klass, sizeof(GstVaapiBaseEncoderPrivate));
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+  VADisplay va_dpy;
+  VAContextID context_id;
+  VAStatus va_status = VA_STATUS_SUCCESS;
+  gboolean is_locked = FALSE;
+  guint i = 0;
+  gboolean ret = TRUE;
+  guint32 buffer_size = (ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder) * 400) / (16*16);
 
-  GST_DEBUG_CATEGORY_INIT (gst_vaapi_base_encoder_debug, "gst_vaapi_base_encoder", 0,
-      "gst_vaapi_base_encoder element");
+  ENCODER_ASSERT(display && context);
+  ENCODER_ASSERT(priv->available_code_buffers);
+  ENCODER_ASSERT(!priv->coded_bufs);
 
-  object_class->finalize = gst_vaapi_base_encoder_finalize;
+  va_dpy = ENCODER_VA_DISPLAY(base_encoder);
+  context_id = gst_vaapi_context_get_id(context);
 
-  encoder_class->initialize = gst_vaapi_base_encoder_initialize_default;
-  encoder_class->uninitialize = gst_vaapi_base_encoder_uninitialize_default;
-  encoder_class->open = gst_vaapi_base_encoder_open_default;
-  encoder_class->close = gst_vaapi_base_encoder_close_default;
-  encoder_class->encode = gst_vaapi_base_encoder_encode_default;
-  encoder_class->flush = gst_vaapi_base_encoder_flush_default;
-  encoder_class->get_codec_data = NULL;
+  priv->coded_bufs = (VABufferID*)g_malloc0(priv->coded_buf_num * sizeof(priv->coded_bufs[0]));
 
-  /* user defined functions*/
-  klass->validate_attributes = NULL;
-  klass->pre_alloc_resource = NULL;
-  klass->release_resource = NULL;
-  klass->prepare_next_input_buffer = NULL;
-  klass->render_frame = NULL;
-  klass->notify_frame = NULL;
-  klass->copy_coded_frame = NULL;
-  klass->encode_frame_failed = NULL;
+  ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+  for (i = 0; i < priv->coded_buf_num; i++) {
+    va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
+                               buffer_size, 1, NULL, &priv->coded_bufs[i]);
+    if (VA_STATUS_SUCCESS != va_status)
+      break;
+  }
+  ENCODER_RELEASE_DISPLAY_LOCK(display);
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, FALSE, "create coded buffer failed.");
 
-  /*
-  object_class->set_property = gst_vaapi_base_encoder_set_property;
-  object_class->get_property = gst_vaapi_base_encoder_get_property;
-  */
-}
+  /* init queue available_code_buffers */
+  g_mutex_lock(priv->code_buffer_lock);
+  for (i = 0; i < priv->coded_buf_num; i++) {
+    g_queue_push_head(priv->available_code_buffers, &priv->coded_bufs[i]);
+  }
+  g_cond_signal(priv->code_buffer_cond);
+  g_mutex_unlock(priv->code_buffer_lock);
 
-static void
-gst_vaapi_base_encoder_init(GstVaapiBaseEncoder *encoder)
-{
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
-  ENCODER_ASSERT(base_prv);
+end:
+  return ret;
 
-  /* init private values*/
-  base_prv->format = 0;
-  base_prv->profile= VA_INVALID_PROFILE;
-  base_prv->frame_count = 0;
-  base_prv->frame_notify_flag = FALSE;
-
-  base_prv->coded_bufs = NULL;
-  base_prv->coded_buf_num = DEFAULT_VA_CODEDBUF_NUM;
-  base_prv->code_buffer_lock = g_mutex_new();
-  base_prv->code_buffer_cond = g_cond_new();
-  base_prv->available_code_buffers = g_queue_new();
-
-  base_prv->need_flush = FALSE;
 }
 
-void
-gst_vaapi_base_encoder_set_frame_notify(GstVaapiBaseEncoder *encoder, gboolean flag)
+static EncoderStatus
+base_encoder_release_coded_buffers(GstVaapiBaseEncoder *base_encoder)
 {
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
-  base_prv->frame_notify_flag = flag;
-}
+  VAStatus va_status = VA_STATUS_SUCCESS;
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+  guint32 available_buf_count = priv->coded_buf_num;
+  guint32 i;
+  gboolean is_locked = FALSE;
 
-gboolean
-gst_vaapi_base_encoder_set_va_profile(GstVaapiBaseEncoder *encoder, guint profile)
-{
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
-  base_prv->profile = profile;
-  return TRUE;
-}
+  ENCODER_ASSERT(display);
+  VAAPI_UNUSED_ARG(va_status);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
 
-void
-gst_vaapi_base_encoder_set_input_format(GstVaapiBaseEncoder* encoder, guint32 format)
-{
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
-  base_prv->format = format;
-}
+  /* wait clear all available coded buffers*/
+  g_mutex_lock(priv->code_buffer_lock);
+  while (available_buf_count) {
+    if (g_queue_is_empty(priv->available_code_buffers)) {
+      g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
+    } else {
+      g_queue_pop_head(priv->available_code_buffers);
+      available_buf_count--;
+    }
+  }
+  g_mutex_unlock(priv->code_buffer_lock);
+
+  ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+  for (i = 0; i < priv->coded_buf_num; i++) {
+    va_status = vaDestroyBuffer(va_dpy, priv->coded_bufs[i]);
+  }
+  ENCODER_RELEASE_DISPLAY_LOCK(display);
 
-EncoderStatus
-gst_vaapi_base_encoder_initialize_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
-{
   return ENCODER_NO_ERROR;
 }
 
-EncoderStatus
-gst_vaapi_base_encoder_uninitialize_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
+static EncoderStatus
+gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder)
 {
-  return ENCODER_NO_ERROR;
+  GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
+  GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+  EncoderStatus ret = ENCODER_NO_ERROR;
 
-}
+  /* release buffers first */
+  priv->need_flush = FALSE;
 
-gboolean
-default_validate_encoder_parameters(GstVaapiBaseEncoder *encoder)
-{
-  if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
-    return FALSE;
+  if (base_class->release_resource) {
+    base_class->release_resource(base_encoder);
   }
-  return TRUE;
+  base_encoder_release_coded_buffers(base_encoder);
+  priv->frame_count = 0;
+
+  return ret;
 }
 
-EncoderStatus
-gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext **context)
+static EncoderStatus
+gst_vaapi_base_encoder_open_default(
+    GstVaapiEncoder* encoder,
+    GstVaapiContext **context
+)
 {
   GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
   GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
 
   GstVaapiContext *out_context = NULL;
 
@@ -240,12 +225,12 @@ gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder, GstVaapiDisplay *d
     check_attri_ret = default_validate_encoder_parameters(base_encoder);
   }
   ENCODER_CHECK_STATUS(check_attri_ret, ENCODER_PARAMETER_ERR, "vaapi encoder paramerter error.");
-  ENCODER_CHECK_STATUS(VA_INVALID_PROFILE != base_prv->profile, ENCODER_PROFILE_ERR, "vaapi encoder profile not set.");
+  ENCODER_CHECK_STATUS(VA_INVALID_PROFILE != priv->profile, ENCODER_PROFILE_ERR, "vaapi encoder profile not set.");
 
   ENCODER_ASSERT(ENCODER_DISPLAY(encoder));
 
   out_context = gst_vaapi_context_new(display,
-                        gst_vaapi_profile(base_prv->profile),
+                        gst_vaapi_profile(priv->profile),
                         gst_vaapi_entrypoint(VAEntrypointEncSlice),
                         ENCODER_WIDTH(encoder),
                         ENCODER_HEIGHT(encoder));
@@ -253,11 +238,11 @@ gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder, GstVaapiDisplay *d
   ENCODER_CHECK_STATUS(VA_INVALID_ID != GST_VAAPI_OBJECT_ID(out_context), ENCODER_CONTEXT_ERR, "gst_vaapi_context_new failed.");
 
   if (base_class->pre_alloc_resource) {
-    ENCODER_CHECK_STATUS(base_class->pre_alloc_resource(base_encoder, display, out_context),
+    ENCODER_CHECK_STATUS(base_class->pre_alloc_resource(base_encoder, out_context),
                          ENCODER_MEM_ERR, "encoder <pre_alloc_resource> failed.");
   }
   ENCODER_CHECK_STATUS(
-    base_encoder_alloc_coded_buffers(base_encoder, display, out_context),
+    base_encoder_alloc_coded_buffers(base_encoder, out_context),
     ENCODER_MEM_ERR,
     "encoder <base_encoder_alloc_coded_buffers> failed."
   );
@@ -268,7 +253,7 @@ gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder, GstVaapiDisplay *d
 end:
   // clear resources
   if (ENCODER_NO_ERROR != ret) {
-    gst_vaapi_base_encoder_close_default(encoder, display, out_context);
+    gst_vaapi_base_encoder_close_default(encoder);
     if (out_context) {
       g_object_unref(out_context);
     }
@@ -276,123 +261,139 @@ end:
   return ret;
 }
 
-EncoderStatus
-gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+static GstBuffer *
+gst_vaapi_base_encoder_copy_buffer_default(GstVaapiBaseEncoder *encoder,
+                                        guint8 *frame,
+                                        guint32 frame_size,
+                                        VABufferID *coded_buf)
 {
-  GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
-  GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
-  EncoderStatus ret = ENCODER_NO_ERROR;
-
-  /* release buffers first */
-  base_prv->need_flush = FALSE;
-
-  if (base_class->release_resource) {
-    base_class->release_resource(base_encoder, display, context);
-  }
-  base_encoder_release_coded_buffers(base_encoder, display, context);
-  base_prv->frame_count = 0;
-
-  return ret;
+  GstBuffer *ret_buffer = NULL;
+#if SHARE_CODED_BUF
+  ret_buffer = gst_base_encode_share_buffer_new(encoder, coded_buf);
+  ENCODER_ASSERT(ret_buffer);
+  GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
+  GST_BUFFER_DATA(ret_buffer) = frame;
+  GST_BUFFER_SIZE(ret_buffer) = frame_size;
+#else
+  ret_buffer = gst_buffer_new_and_alloc(frame_size);
+  memcpy(GST_BUFFER_DATA(ret_buffer),frame, frame_size);
+#endif
+  return ret_buffer;
 }
 
-static gboolean
-base_encoder_alloc_coded_buffers(GstVaapiBaseEncoder *base_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+static EncoderStatus
+base_query_encoding_status(GstVaapiBaseEncoder *base_encoder,
+                           GstVaapiSurface *buffer_surface,
+                           gboolean is_key,
+                           GstVaapiVideoBuffer *surface_buffer,
+                           VABufferID *coded_buf,
+                           GList **coded_pics)
 {
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-
-  ENCODER_ASSERT(display && context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
-  VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+  EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
+  VASurfaceStatus surface_status = 0;
+  VACodedBufferSegment *buf_list = NULL;
+  GstBuffer* ret_buffer = NULL;
+  gboolean has_coded_data = FALSE;
   gboolean is_locked = FALSE;
-  guint i = 0;
-  gboolean ret = TRUE;
-  guint32 buffer_size = (ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder) * 400) / (16*16);
+  GstVaapiBaseEncoderClass   *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(base_encoder);
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
 
-  ENCODER_ASSERT(base_prv->available_code_buffers);
-  ENCODER_ASSERT(!base_prv->coded_bufs);
+  ENCODER_ASSERT(display);
+  VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
+  VADisplay va_dpy = ENCODER_VA_DISPLAY(base_encoder);
 
-  base_prv->coded_bufs = (VABufferID*)g_malloc0(base_prv->coded_buf_num * sizeof(base_prv->coded_bufs[0]));
+  ENCODER_ASSERT(coded_pics);
+  VAAPI_UNUSED_ARG(has_coded_data);
 
+  /* lock display */
   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
-  for (i = 0; i < base_prv->coded_buf_num; i++) {
-    va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
-                               buffer_size, 1, NULL, &base_prv->coded_bufs[i]);
-    if (VA_STATUS_SUCCESS != va_status)
-      break;
-  }
-  ENCODER_RELEASE_DISPLAY_LOCK(display);
-  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, FALSE, "create coded buffer failed.");
 
-  /* init queue available_code_buffers */
-  g_mutex_lock(base_prv->code_buffer_lock);
-  for (i = 0; i < base_prv->coded_buf_num; i++) {
-    g_queue_push_head(base_prv->available_code_buffers, &base_prv->coded_bufs[i]);
-  }
-  g_cond_signal(base_prv->code_buffer_cond);
-  g_mutex_unlock(base_prv->code_buffer_lock);
+  va_status = vaSyncSurface(va_dpy, surface_id);
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaSyncSurface failed.");
 
-end:
-  return ret;
+  va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaQuerySurfaceStatus failed.");
+  if (VASurfaceSkipped&surface_status) {
+    ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(surface_buffer)));
+  }
 
-}
+  va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaMapBuffer failed.");
 
-static EncoderStatus
-base_encoder_release_coded_buffers(GstVaapiBaseEncoder *base_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
-{
-  VAStatus va_status = VA_STATUS_SUCCESS;
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-  guint32 available_buf_count = base_prv->coded_buf_num;
-  guint32 i;
-  gboolean is_locked = FALSE;
+  /*unlock display*/
+  ENCODER_RELEASE_DISPLAY_LOCK(display);
 
-  ENCODER_ASSERT(display);
-  ENCODER_ASSERT(context);
-  VAAPI_UNUSED_ARG(va_status);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
+  while (buf_list != NULL) {
+      if (priv->frame_notify_flag && base_class->notify_frame) {
+        base_class->notify_frame(base_encoder, buf_list->buf, buf_list->size);
+      }
 
-  /* wait clear all available coded buffers*/
-  g_mutex_lock(base_prv->code_buffer_lock);
-  while (available_buf_count) {
-    if (g_queue_is_empty(base_prv->available_code_buffers)) {
-      g_cond_wait(base_prv->code_buffer_cond, base_prv->code_buffer_lock);
-    } else {
-      g_queue_pop_head(base_prv->available_code_buffers);
-      available_buf_count--;
-    }
+      if (base_class->copy_coded_frame) {
+        ret_buffer = base_class->copy_coded_frame(
+                        base_encoder, buf_list->buf,
+                        buf_list->size, coded_buf);
+      } else {
+        ret_buffer = gst_vaapi_base_encoder_copy_buffer_default(
+                          base_encoder, buf_list->buf,
+                          buf_list->size, coded_buf);
+      }
+      GST_BUFFER_TIMESTAMP(ret_buffer) = GST_BUFFER_TIMESTAMP(surface_buffer);
+      GST_BUFFER_DURATION(ret_buffer) = GST_BUFFER_DURATION(surface_buffer);
+      if (!is_key) {
+        GST_BUFFER_FLAG_SET(ret_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+      }
+      GST_BUFFER_OFFSET_END(ret_buffer) = GST_BUFFER_OFFSET_END(surface_buffer);
+      *coded_pics = g_list_append(*coded_pics, ret_buffer);
+      buf_list = (VACodedBufferSegment*)buf_list->next;
+      ENCODER_ASSERT(NULL == buf_list);
+      has_coded_data = TRUE;
+      FPS_CALCULATION(vaapiencode);
   }
-  g_mutex_unlock(base_prv->code_buffer_lock);
 
-  ENCODER_ACQUIRE_DISPLAY_LOCK(display);
-  for (i = 0; i < base_prv->coded_buf_num; i++) {
-    va_status = vaDestroyBuffer(va_dpy, base_prv->coded_bufs[i]);
+#if SHARE_CODED_BUF
+  if (!has_coded_data)
+#endif
+  { // if non-related, push back to available_code_buffers
+    ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+    vaUnmapBuffer(va_dpy, *coded_buf);
+    ENCODER_RELEASE_DISPLAY_LOCK(display);
+    push_available_coded_buffer(priv, coded_buf);
   }
-  ENCODER_RELEASE_DISPLAY_LOCK(display);
 
   return ENCODER_NO_ERROR;
+
+end:
+  /*unlock display*/
+  ENCODER_RELEASE_DISPLAY_LOCK(display);
+  return ret;
 }
 
-EncoderStatus
-gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                        GstVaapiContext *context, GstBuffer *raw_pic, GList **coded_pics)
+static EncoderStatus
+gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder,
+    GstBuffer *raw_pic,
+    GList **coded_pics
+)
 {
   GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
   GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+  GstVaapiContext *context = ENCODER_CONTEXT(encoder);
   EncoderStatus ret = ENCODER_NO_ERROR;
   gboolean is_key = FALSE;
   VABufferID* coded_buf = NULL;
   VAStatus va_status = VA_STATUS_SUCCESS;
   VASurfaceID  buffer_surface_id = VA_INVALID_SURFACE;
   GstVaapiSurface *buffer_surface = NULL;
-
   gboolean is_locked = FALSE;
+  VADisplay va_dpy;
+  VAContextID context_id;
 
   ENCODER_ASSERT(display && context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
-  VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+  va_dpy = ENCODER_VA_DISPLAY(encoder);
+  context_id = ENCODER_VA_CONTEXT(encoder);
 
   /* Video Buffer */
   GstVaapiVideoBuffer *video_buffer = NULL;
@@ -408,14 +409,14 @@ gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder, GstVaapiDisplay
         /* do something else */
     }
   } else {
-    base_prv->need_flush = TRUE;
+    priv->need_flush = TRUE;
   }
 
 again:
   if (base_class->prepare_next_input_buffer) {
     GstVaapiVideoBuffer* tmp_buf = NULL;
-    ret = base_class->prepare_next_input_buffer(base_encoder, video_buffer, base_prv->need_flush, &tmp_buf);
-    base_prv->need_flush = FALSE;
+    ret = base_class->prepare_next_input_buffer(base_encoder, video_buffer, priv->need_flush, &tmp_buf);
+    priv->need_flush = FALSE;
     if (video_buffer) {
       gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
       video_buffer = NULL;
@@ -437,16 +438,18 @@ again:
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaBeginPicture error.");
 
   /*get valid coded buffer*/
-  coded_buf = pop_available_coded_buffer(base_prv);
+  coded_buf = pop_available_coded_buffer(priv);
   ENCODER_CHECK_STATUS(coded_buf, ENCODER_ENC_RES_ERR, "dequeue_available_coded_buffer error.");
 
   /* prepare frame*/
-  ret = base_class->render_frame(base_encoder, display, context,
-                                  buffer_surface, base_prv->frame_count,
-                                  *coded_buf, &is_key);
+  ret = base_class->render_frame(base_encoder,
+                                 buffer_surface,
+                                 priv->frame_count,
+                                 *coded_buf,
+                                 &is_key);
   /* prepare failed, push back */
   if (ENCODER_NO_ERROR != ret) {
-    push_available_coded_buffer(base_prv, coded_buf);
+    push_available_coded_buffer(priv, coded_buf);
   }
   ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ENCODER_PICTURE_ERR, "base_prepare_encoding failed.");
 
@@ -457,13 +460,13 @@ again:
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaEndPicture error.");
 
   /*query surface result*/
-  ret = base_query_encoding_status(base_encoder, display, buffer_surface,
+  ret = base_query_encoding_status(base_encoder, buffer_surface,
                                    is_key, video_buffer, coded_buf, coded_pics);
   if (ENCODER_NO_ERROR != ret) {
     goto end;
   }
 
-  base_prv->frame_count++;
+  priv->frame_count++;
 
   if (base_class->prepare_next_input_buffer) {
     if (video_buffer) {
@@ -490,32 +493,32 @@ end:
 }
 
 static VABufferID *
-pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *base_prv)
+pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv)
 {
   VABufferID *coded_buf = NULL;
   gboolean ret = TRUE;
 
-  g_mutex_lock(base_prv->code_buffer_lock);
+  g_mutex_lock(priv->code_buffer_lock);
 
-  ENCODER_CHECK_STATUS(base_prv->available_code_buffers, FALSE, "coded buffer not found");
-  while (g_queue_is_empty(base_prv->available_code_buffers)) {
-    g_cond_wait(base_prv->code_buffer_cond, base_prv->code_buffer_lock);
+  ENCODER_CHECK_STATUS(priv->available_code_buffers, FALSE, "coded buffer not found");
+  while (g_queue_is_empty(priv->available_code_buffers)) {
+    g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
   }
-  coded_buf = (VABufferID*)g_queue_pop_head (base_prv->available_code_buffers);
+  coded_buf = (VABufferID*)g_queue_pop_head (priv->available_code_buffers);
 
 end:
-  g_mutex_unlock(base_prv->code_buffer_lock);
+  g_mutex_unlock(priv->code_buffer_lock);
   VAAPI_UNUSED_ARG(ret);
   return coded_buf;
 }
 
 static gboolean
-push_available_coded_buffer(GstVaapiBaseEncoderPrivate *base_prv, VABufferID *buf)
+push_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv, VABufferID *buf)
 {
-  g_mutex_lock(base_prv->code_buffer_lock);
-  g_queue_push_head(base_prv->available_code_buffers, buf);
-  g_cond_signal(base_prv->code_buffer_cond);
-  g_mutex_unlock(base_prv->code_buffer_lock);
+  g_mutex_lock(priv->code_buffer_lock);
+  g_queue_push_head(priv->available_code_buffers, buf);
+  g_cond_signal(priv->code_buffer_cond);
+  g_mutex_unlock(priv->code_buffer_lock);
   return TRUE;
 }
 
@@ -536,7 +539,7 @@ base_put_raw_buffer_to_surface(GstVaapiBaseEncoder *base_encoder,
   guint32 plane_count = 0;
   guint32 image_width = 0, image_height = 0;
   guint32 pitchy = 0, pitchu = 0, pitchv = 0;
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
 
   ENCODER_ASSERT(display);
   VAAPI_UNUSED_ARG(pitchv);
@@ -579,7 +582,7 @@ base_put_raw_buffer_to_surface(GstVaapiBaseEncoder *base_encoder,
   }
 
   if (GST_VAAPI_IMAGE_NV12 == image_format) { /* UV plane */
-    if (GST_VAAPI_IMAGE_I420 == base_prv->format) {
+    if (GST_VAAPI_IMAGE_I420 == priv->format) {
       for (row = 0; row < image_height / 2; row++) {
           for (col = 0; col < image_width / 2; col++) {
               u_dst[col * 2] = u_src[col];
@@ -590,7 +593,7 @@ base_put_raw_buffer_to_surface(GstVaapiBaseEncoder *base_encoder,
           u_src += (ENCODER_WIDTH(base_encoder)>>1);
           v_src += (ENCODER_WIDTH(base_encoder)>>1);
       }
-    } else if (GST_VAAPI_IMAGE_NV12 == base_prv->format){
+    } else if (GST_VAAPI_IMAGE_NV12 == priv->format){
       for (row = 0; row < image_height / 2; row++) {
         memcpy(u_dst, u_src, image_width);
         u_src += ENCODER_WIDTH(base_encoder);
@@ -612,128 +615,97 @@ base_put_raw_buffer_to_surface(GstVaapiBaseEncoder *base_encoder,
 #endif
 
 static EncoderStatus
-base_query_encoding_status(GstVaapiBaseEncoder *base_encoder,
-                           GstVaapiDisplay *display,
-                           GstVaapiSurface *buffer_surface,
-                           gboolean is_key,
-                           GstVaapiVideoBuffer *surface_buffer,
-                           VABufferID *coded_buf,
-                           GList **coded_pics)
+gst_vaapi_base_encoder_flush_default(
+    GstVaapiEncoder* encoder,
+    GList **coded_pics
+)
 {
+  GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
   EncoderStatus ret = ENCODER_NO_ERROR;
-  VAStatus va_status = VA_STATUS_SUCCESS;
-  VASurfaceStatus surface_status = 0;
-  VACodedBufferSegment *buf_list = NULL;
-  GstBuffer* ret_buffer = NULL;
-  gboolean has_coded_data = FALSE;
-  gboolean is_locked = FALSE;
-  GstVaapiBaseEncoderClass   *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(base_encoder);
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-
-  ENCODER_ASSERT(display);
-  VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
-
-  ENCODER_ASSERT(coded_pics);
-  VAAPI_UNUSED_ARG(has_coded_data);
-
-  /* lock display */
-  ENCODER_ACQUIRE_DISPLAY_LOCK(display);
-
-  va_status = vaSyncSurface(va_dpy, surface_id);
-  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaSyncSurface failed.");
+  GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
 
-  va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
-  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaQuerySurfaceStatus failed.");
-  if (VASurfaceSkipped&surface_status) {
-    ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(surface_buffer)));
-  }
+  priv->frame_count = 0;
+  priv->need_flush = TRUE;
+  /*do we need destroy priv->seq_parameter? */
 
-  va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
-  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaMapBuffer failed.");
+  //end:
+  return ret;
+}
 
-  /*unlock display*/
-  ENCODER_RELEASE_DISPLAY_LOCK(display);
 
-  while (buf_list != NULL) {
-      if (base_prv->frame_notify_flag && base_class->notify_frame) {
-        base_class->notify_frame(base_encoder, buf_list->buf, buf_list->size);
-      }
+static void
+gst_vaapi_base_encoder_finalize(GObject *object)
+{
+  /*free private buffers*/
+  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+  GstVaapiBaseEncoderPrivate *priv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(object);
 
-      if (base_class->copy_coded_frame) {
-        ret_buffer = base_class->copy_coded_frame(
-                        base_encoder, buf_list->buf,
-                        buf_list->size, coded_buf);
-      } else {
-        ret_buffer = gst_vaapi_base_encoder_copy_buffer_default(
-                          base_encoder, buf_list->buf,
-                          buf_list->size, coded_buf);
-      }
-      GST_BUFFER_TIMESTAMP(ret_buffer) = GST_BUFFER_TIMESTAMP(surface_buffer);
-      GST_BUFFER_DURATION(ret_buffer) = GST_BUFFER_DURATION(surface_buffer);
-      if (!is_key) {
-        GST_BUFFER_FLAG_SET(ret_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
-      }
-      GST_BUFFER_OFFSET_END(ret_buffer) = GST_BUFFER_OFFSET_END(surface_buffer);
-      *coded_pics = g_list_append(*coded_pics, ret_buffer);
-      buf_list = (VACodedBufferSegment*)buf_list->next;
-      ENCODER_ASSERT(NULL == buf_list);
-      has_coded_data = TRUE;
-      FPS_CALCULATION(vaapiencode);
+  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+    gst_vaapi_encoder_uninitialize(encoder);
   }
 
-#if SHARE_CODED_BUF
-  if (!has_coded_data)
-#endif
-  { // if non-related, push back to available_code_buffers
-    ENCODER_ACQUIRE_DISPLAY_LOCK(display);
-    vaUnmapBuffer(va_dpy, *coded_buf);
-    ENCODER_RELEASE_DISPLAY_LOCK(display);
-    push_available_coded_buffer(base_prv, coded_buf);
+  g_mutex_free(priv->code_buffer_lock);
+  g_cond_free(priv->code_buffer_cond);
+  if (priv->available_code_buffers) {
+    g_queue_free(priv->available_code_buffers);
+    priv->available_code_buffers = NULL;
   }
 
-  return ENCODER_NO_ERROR;
-
-end:
-  /*unlock display*/
-  ENCODER_RELEASE_DISPLAY_LOCK(display);
-  return ret;
+  G_OBJECT_CLASS(gst_vaapi_base_encoder_parent_class)->finalize(object);
 }
 
-static GstBuffer *
-gst_vaapi_base_encoder_copy_buffer_default(GstVaapiBaseEncoder *encoder,
-                                        guint8 *frame,
-                                        guint32 frame_size,
-                                        VABufferID *coded_buf)
+static void
+gst_vaapi_base_encoder_init(GstVaapiBaseEncoder *encoder)
 {
-  GstBuffer *ret_buffer = NULL;
-#if SHARE_CODED_BUF
-  ret_buffer = gst_base_encode_share_buffer_new(encoder, coded_buf);
-  ENCODER_ASSERT(ret_buffer);
-  GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
-  GST_BUFFER_DATA(ret_buffer) = frame;
-  GST_BUFFER_SIZE(ret_buffer) = frame_size;
-#else
-  ret_buffer = gst_buffer_new_and_alloc(frame_size);
-  memcpy(GST_BUFFER_DATA(ret_buffer),frame, frame_size);
-#endif
-  return ret_buffer;
+  GstVaapiBaseEncoderPrivate *priv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
+  ENCODER_ASSERT(priv);
+  encoder->priv = priv;
+
+  /* init private values*/
+  priv->format = 0;
+  priv->profile= VA_INVALID_PROFILE;
+  priv->frame_count = 0;
+  priv->frame_notify_flag = FALSE;
+
+  priv->coded_bufs = NULL;
+  priv->coded_buf_num = DEFAULT_VA_CODEDBUF_NUM;
+  priv->code_buffer_lock = g_mutex_new();
+  priv->code_buffer_cond = g_cond_new();
+  priv->available_code_buffers = g_queue_new();
+
+  priv->need_flush = FALSE;
 }
 
-EncoderStatus
-gst_vaapi_base_encoder_flush_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                       GstVaapiContext *context, GList **coded_pics)
+static void
+gst_vaapi_base_encoder_class_init(GstVaapiBaseEncoderClass *klass)
 {
-  GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
-  EncoderStatus ret = ENCODER_NO_ERROR;
-  GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
+  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+  g_type_class_add_private(klass, sizeof(GstVaapiBaseEncoderPrivate));
+
+  GST_DEBUG_CATEGORY_INIT (gst_vaapi_base_encoder_debug, "gst_vaapi_base_encoder", 0,
+      "gst_vaapi_base_encoder element");
 
-  base_prv->frame_count = 0;
-  base_prv->need_flush = TRUE;
-  /*do we need destroy base_prv->seq_parameter? */
+  object_class->finalize = gst_vaapi_base_encoder_finalize;
 
-  //end:
-  return ret;
-}
+  encoder_class->open = gst_vaapi_base_encoder_open_default;
+  encoder_class->close = gst_vaapi_base_encoder_close_default;
+  encoder_class->encode = gst_vaapi_base_encoder_encode_default;
+  encoder_class->flush = gst_vaapi_base_encoder_flush_default;
+  encoder_class->get_codec_data = NULL;
 
+  /* user defined functions*/
+  klass->validate_attributes = NULL;
+  klass->pre_alloc_resource = NULL;
+  klass->release_resource = NULL;
+  klass->prepare_next_input_buffer = NULL;
+  klass->render_frame = NULL;
+  klass->notify_frame = NULL;
+  klass->copy_coded_frame = NULL;
+  klass->encode_frame_failed = NULL;
 
+  /*
+  object_class->set_property = gst_vaapi_base_encoder_set_property;
+  object_class->get_property = gst_vaapi_base_encoder_get_property;
+  */
+}
index 830a66f..38e1142 100644 (file)
@@ -39,9 +39,10 @@ typedef struct _GstVaapiBaseEncoderClass         GstVaapiBaseEncoderClass;
 #define GST_VAAPI_BASE_ENCODER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_BASE_ENCODER,  GstVaapiBaseEncoderClass))
 #define GST_VAAPI_BASE_ENCODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GST_TYPE_VAAPI_BASE_ENCODER,  GstVaapiBaseEncoderPrivate))
 
-
 struct _GstVaapiBaseEncoder {
   GstVaapiEncoder parent;
+
+  GstVaapiBaseEncoderPrivate *priv;
 };
 
 struct _GstVaapiBaseEncoderClass {
@@ -49,30 +50,23 @@ struct _GstVaapiBaseEncoderClass {
 
   /* in <open> function*/
   gboolean (*validate_attributes)   (GstVaapiBaseEncoder* encoder);
-  gboolean (*pre_alloc_resource)    (GstVaapiBaseEncoder *base_encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+  gboolean (*pre_alloc_resource)    (GstVaapiBaseEncoder *encoder, GstVaapiContext* context);
 
   /* in <close> function */
-  gboolean (*release_resource)      (GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+  gboolean (*release_resource)      (GstVaapiBaseEncoder* encoder);
 
   /* in <encode> function */
-  EncoderStatus (*prepare_next_input_buffer)(GstVaapiBaseEncoder* encoder, GstVaapiVideoBuffer *display_buf,
-                                             gboolean need_flush, GstVaapiVideoBuffer **out_buf);
-  EncoderStatus (*render_frame)     (GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
-                                     GstVaapiContext *context, GstVaapiSurface *surface,
+  EncoderStatus (*prepare_next_input_buffer)(GstVaapiBaseEncoder* encoder,
+                                             GstVaapiVideoBuffer *display_buf,
+                                             gboolean need_flush,
+                                             GstVaapiVideoBuffer **out_buf);
+  EncoderStatus (*render_frame)     (GstVaapiBaseEncoder *encoder, GstVaapiSurface *surface,
                                      guint frame_index, VABufferID coded_buf, gboolean *is_key);
   void (*encode_frame_failed)       (GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer);
   void (*notify_frame)              (GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
   GstBuffer *(*copy_coded_frame)    (GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size, VABufferID *coded_buf);
 };
 
-/*
-struct _GstVaapiBaseEncoderPrivate {
-  GstVaapiDisplay     *display;
-  GstVaapiContext     *context;
-  //VAAPI_Encode_State   state;
-};
-*/
-
 GType    gst_vaapi_base_encoder_get_type(void);
 void     gst_vaapi_base_encoder_set_frame_notify(GstVaapiBaseEncoder *encoder, gboolean flag);
 gboolean gst_vaapi_base_encoder_set_va_profile(GstVaapiBaseEncoder *encoder, guint profile);
index 3030fbb..39c748b 100644 (file)
@@ -31,71 +31,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_encoder_debug);
 
 G_DEFINE_TYPE(GstVaapiEncoder, gst_vaapi_encoder, G_TYPE_OBJECT);
 
-static void gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass);
-static void gst_vaapi_encoder_init(GstVaapiEncoder *encoder);
-static void gst_vaapi_encoder_finalize(GObject *object);
-
-static void
-gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass)
-{
-  GObjectClass * const object_class = G_OBJECT_CLASS(kclass);
-  g_type_class_add_private(kclass, sizeof(GstVaapiEncoderPrivate));
-
-
-  GST_DEBUG_CATEGORY_INIT (gst_vaapi_encoder_debug, "gst_va_encoder", 0,
-        "gst_va_encoder element");
-
-  object_class->finalize = gst_vaapi_encoder_finalize;
-  kclass->initialize = NULL;
-  kclass->uninitialize = NULL;
-  kclass->open = NULL;
-  kclass->close = NULL;
-  kclass->encode = NULL;
-  kclass->flush = NULL;
-  kclass->get_codec_data = NULL;
-}
-
-static void
-gst_vaapi_encoder_init(GstVaapiEncoder *encoder)
-{
-  GstVaapiEncoderPrivate *priv;
-
-  encoder->priv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
-  priv = encoder->priv;
-  ENCODER_ASSERT(priv);
-
-  priv->display = NULL;
-  priv->context = NULL;
-  priv->state = VAAPI_ENC_NULL;
-
-  encoder->width = 0;
-  encoder->height = 0;
-  encoder->frame_rate = 0;
-}
-
-static void
-gst_vaapi_encoder_finalize(GObject *object)
-{
-  GstVaapiEncoder* encoder = GST_VAAPI_ENCODER(object);
-  GstVaapiEncoderPrivate *priv = encoder->priv;
-  if (VAAPI_ENC_NULL != priv->state) {
-    gst_vaapi_encoder_uninitialize(encoder);
-  }
-
-  if (priv->context) {
-    g_object_unref(priv->context);
-    priv->context = NULL;
-  }
-
-  if (priv->display) {
-    g_object_unref(priv->display);
-    priv->display = NULL;
-  }
-
-  G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object);
-}
-
-
 gboolean
 gst_vaapi_encoder_set_display(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
 {
@@ -110,8 +45,12 @@ gst_vaapi_encoder_set_display(GstVaapiEncoder* encoder, GstVaapiDisplay *display
   if (priv->display) {
     g_object_unref(priv->display);
     priv->display = NULL;
+    priv->va_display = NULL;
+  }
+  if (display) {
+    priv->display = g_object_ref(display);
+    priv->va_display = gst_vaapi_display_get_display(display);
   }
-  priv->display = g_object_ref(display);
   return TRUE;
 }
 
@@ -158,10 +97,11 @@ gst_vaapi_encoder_initialize(GstVaapiEncoder* encoder)
   if (!priv->display) {
     priv->display = gst_vaapi_display_x11_new(NULL);
     ENCODER_CHECK_STATUS(priv->display, ENCODER_DISPLAY_ERR, "gst_vaapi_display_x11_new failed.");
+    priv->va_display = gst_vaapi_display_get_display(priv->display);
   }
 
   if (encoder_class->initialize) {
-    ret = encoder_class->initialize(encoder, priv->display);
+    ret = encoder_class->initialize(encoder);
     ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == ret, ret, "encoder <initialize> failed.");
   }
   priv->state = VAAPI_ENC_INIT;
@@ -188,10 +128,10 @@ gst_vaapi_encoder_open(GstVaapiEncoder* encoder)
   ENCODER_ASSERT(!priv->context);
 
   ENCODER_CHECK_STATUS(encoder_class->open, ENCODER_FUNC_PTR_ERR, "encoder <open> function pointer empty.");
-  ret = encoder_class->open(encoder, priv->display, &priv->context);
+  ret = encoder_class->open(encoder, &priv->context);
   ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <open> failed.");
   ENCODER_CHECK_STATUS(priv->context, ENCODER_CONTEXT_ERR, "encoder <open> context failed.");
-
+  priv->va_context = gst_vaapi_context_get_id(priv->context);
   priv->state = VAAPI_ENC_OPENED;
 
 end:
@@ -207,7 +147,7 @@ gst_vaapi_encoder_encode(GstVaapiEncoder* encoder, GstBuffer *raw_pic, GList **c
 
   ENCODER_CHECK_STATUS(priv->state >= VAAPI_ENC_OPENED, ENCODER_STATE_ERR, "encoder was not opened before <encode>.");
   ENCODER_CHECK_STATUS(encoder_class->encode, ENCODER_FUNC_PTR_ERR, "encoder <encode> function pointer empty.");
-  ret = encoder_class->encode(encoder, priv->display, priv->context, raw_pic, coded_pics);
+  ret = encoder_class->encode(encoder, raw_pic, coded_pics);
   ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <encode> failed.");
   if (priv->state < VAAPI_ENC_ENCODING) {
     priv->state = VAAPI_ENC_ENCODING;
@@ -245,7 +185,7 @@ gst_vaapi_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics)
     return ENCODER_STATE_ERR;
   }
   ENCODER_CHECK_STATUS(encoder_class->flush, ENCODER_FUNC_PTR_ERR, "encoder <flush> function pointer empty.");
-  ret = encoder_class->flush(encoder, priv->display, priv->context, coded_pics);
+  ret = encoder_class->flush(encoder, coded_pics);
   ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <flush> failed.");
   if (priv->state > VAAPI_ENC_OPENED) {
     priv->state = VAAPI_ENC_OPENED;
@@ -265,12 +205,13 @@ gst_vaapi_encoder_close(GstVaapiEncoder* encoder)
     return ENCODER_NO_ERROR;
   }
   ENCODER_CHECK_STATUS(encoder_class->close, ENCODER_FUNC_PTR_ERR, "encoder <close> function pointers empty.");
-  ret = encoder_class->close(encoder, priv->display, priv->context);
+  ret = encoder_class->close(encoder);
   ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <close> failed.");
 end:
   if (priv->context) {
     g_object_unref(priv->context);
     priv->context = NULL;
+    priv->va_context = VA_INVALID_ID;
   }
 
   priv->state = VAAPI_ENC_INIT;
@@ -293,13 +234,15 @@ gst_vaapi_encoder_uninitialize(GstVaapiEncoder* encoder)
   }
   ENCODER_ASSERT(VAAPI_ENC_INIT == priv->state);
   if (encoder_class->uninitialize) {
-    ret = encoder_class->uninitialize(encoder, priv->display);
+    ret = encoder_class->uninitialize(encoder);
     ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <uninitialize> failed.");
   }
+
 end:
   if (priv->display) {
     g_object_unref(priv->display);
     priv->display = NULL;
+    priv->va_display = NULL;
   }
   priv->state = VAAPI_ENC_NULL;
   return ret;
@@ -320,3 +263,59 @@ char *vaapi_encoder_dump_bytes(const guint8 *buf, guint32 num)
   return tmp;
 }
 
+static void
+gst_vaapi_encoder_init(GstVaapiEncoder *encoder)
+{
+  GstVaapiEncoderPrivate *priv;
+
+  encoder->priv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
+  priv = encoder->priv;
+  ENCODER_ASSERT(priv);
+
+  priv->display = NULL;
+  priv->va_display = NULL;
+  priv->context = NULL;
+  priv->va_context = VA_INVALID_ID;
+  priv->state = VAAPI_ENC_NULL;
+
+  encoder->width = 0;
+  encoder->height = 0;
+  encoder->frame_rate = 0;
+}
+
+static void
+gst_vaapi_encoder_finalize(GObject *object)
+{
+  GstVaapiEncoder* encoder = GST_VAAPI_ENCODER(object);
+  GstVaapiEncoderPrivate *priv = encoder->priv;
+  if (VAAPI_ENC_NULL != priv->state) {
+    gst_vaapi_encoder_uninitialize(encoder);
+  }
+
+  if (priv->context) {
+    g_object_unref(priv->context);
+    priv->context = NULL;
+    priv->va_context = VA_INVALID_ID;
+  }
+
+  if (priv->display) {
+    g_object_unref(priv->display);
+    priv->display = NULL;
+    priv->va_display = NULL;
+  }
+
+  G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object);
+}
+
+static void
+gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass)
+{
+  GObjectClass * const object_class = G_OBJECT_CLASS(kclass);
+  g_type_class_add_private(kclass, sizeof(GstVaapiEncoderPrivate));
+
+
+  GST_DEBUG_CATEGORY_INIT (gst_vaapi_encoder_debug, "gst_va_encoder", 0,
+        "gst_va_encoder element");
+
+  object_class->finalize = gst_vaapi_encoder_finalize;
+}
index 244c3a0..97678a0 100644 (file)
@@ -27,8 +27,8 @@
 
 #include "gst/gstinfo.h"
 #include "gst/gstbuffer.h"
-#include "gst/vaapi/gstvaapidisplay.h"
-#include "gst/vaapi/gstvaapicontext.h"
+#include "gstvaapidisplay.h"
+#include "gstvaapicontext.h"
 
 G_BEGIN_DECLS
 
@@ -116,8 +116,14 @@ typedef struct _GstVaapiEncoderClass         GstVaapiEncoderClass;
 #define GST_VAAPI_ENCODER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_ENCODER,  GstVaapiEncoderClass))
 #define GST_VAAPI_ENCODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GST_TYPE_VAAPI_ENCODER,  GstVaapiEncoderPrivate))
 
-#define ENCODER_DISPLAY(encoder) (((GstVaapiEncoder*)(encoder))->priv->display)
-#define ENCODER_CONTEXT(encoder) (((GstVaapiEncoder*)(encoder))->priv->context)
+#define GST_VAAPI_ENCODER_CAST(encoder)    ((GstVaapiEncoder *)(encoder))
+
+#define ENCODER_DISPLAY(encoder)    (((GstVaapiEncoder*)(encoder))->priv->display)
+#define ENCODER_VA_DISPLAY(encoder) (((GstVaapiEncoder*)(encoder))->priv->va_display)
+
+#define ENCODER_CONTEXT(encoder)    (((GstVaapiEncoder*)(encoder))->priv->context)
+#define ENCODER_VA_CONTEXT(encoder) (((GstVaapiEncoder*)(encoder))->priv->va_context)
+
 #define ENCODER_WIDTH(encoder)   (((GstVaapiEncoder*)(encoder))->width)
 #define ENCODER_HEIGHT(encoder)  (((GstVaapiEncoder*)(encoder))->height)
 #define ENCODER_FPS(encoder)     (((GstVaapiEncoder*)(encoder))->frame_rate)
@@ -134,27 +140,30 @@ struct _GstVaapiEncoder {
 struct _GstVaapiEncoderClass {
   GObjectClass parent_class;
 
-  EncoderStatus (*initialize)    (GstVaapiEncoder* encoder, GstVaapiDisplay *display);  /* can be NULL */
-  EncoderStatus (*uninitialize)  (GstVaapiEncoder* encoder, GstVaapiDisplay *display);  /* can be NULL */
+  EncoderStatus (*initialize)    (GstVaapiEncoder* encoder);  /* can be NULL */
+  EncoderStatus (*uninitialize)  (GstVaapiEncoder* encoder);  /* can be NULL */
 
   /* context [out] */
-  EncoderStatus (*open)          (GstVaapiEncoder* encoder, GstVaapiDisplay *display,
+  EncoderStatus (*open)          (GstVaapiEncoder* encoder,
                                   GstVaapiContext **context);
 
-  EncoderStatus (*close)         (GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+  EncoderStatus (*close)         (GstVaapiEncoder* encoder);
   /* coded_pics [out] */
-  EncoderStatus (*encode)        (GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                                  GstVaapiContext *context, GstBuffer *raw_pic, GList **coded_pics);
+  EncoderStatus (*encode)        (GstVaapiEncoder* encoder,
+                                  GstBuffer *raw_pic,
+                                  GList **coded_pics);
   /* coded_pics [out] */
-  EncoderStatus (*flush)         (GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                                  GstVaapiContext *context, GList **coded_pics);
+  EncoderStatus (*flush)         (GstVaapiEncoder* encoder, GList **coded_pics);
 
-  EncoderStatus (*get_codec_data)(GstVaapiEncoder* encoder, GstBuffer **codec_data); /* can be NULL */
+  /* get_codec_data can be NULL */
+  EncoderStatus (*get_codec_data)(GstVaapiEncoder* encoder, GstBuffer **codec_data);
 };
 
 struct _GstVaapiEncoderPrivate {
   GstVaapiDisplay     *display;
+  VADisplay            va_display;
   GstVaapiContext     *context;
+  VAContextID          va_context;
   VAAPI_Encode_State   state;
 };
 
index 8bfa61b..56ff7f7 100644 (file)
@@ -34,6 +34,8 @@
 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h263_encoder_debug);
 #define GST_CAT_DEFAULT gst_vaapi_h263_encoder_debug
 
+#define GST_VAAPI_ENCODER_H263_CAST(encoder)    ((GstVaapiEncoderH263 *)(encoder))
+
 struct _GstVaapiEncoderH263Private {
   GstVaapiSurface  *ref_surface;  /* reference buffer*/
   GstVaapiSurface  *recon_surface; /* reconstruct buffer*/
@@ -45,249 +47,173 @@ struct _GstVaapiEncoderH263Private {
 
 G_DEFINE_TYPE(GstVaapiEncoderH263, gst_vaapi_encoder_h263, GST_TYPE_VAAPI_BASE_ENCODER);
 
-/*
-static EncoderStatus gst_vaapi_encoder_h263_flush(GstVaapiEncoder* encoder,
-                            GstVaapiDisplay *display, GstVaapiContext *context,
-                            GList **coded_pics);
-*/
-
-static void          gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass);
-static void          gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *encoder);
-static void          gst_vaapi_encoder_h263_finalize(GObject *object);
-
-static gboolean      gst_h263_validate_parameters(GstVaapiBaseEncoder* encoder);
-static gboolean      gst_vaapi_encoder_h263_release_resource(
-                            GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display,
-                            GstVaapiContext *context);
-static EncoderStatus gst_vaapi_encoder_h263_rendering(GstVaapiBaseEncoder *encoder,
-                            GstVaapiDisplay *display, GstVaapiContext *context,
-                            GstVaapiSurface *surface, guint frame_index,
-                            VABufferID coded_buf, gboolean *is_key);
-
 GstVaapiEncoderH263 *
 gst_vaapi_encoder_h263_new(void)
 {
-  return GST_VAAPI_ENCODER_H263(g_object_new(GST_TYPE_VAAPI_ENCODER_H263, NULL));
-}
-
-
-static void
-gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass)
-{
-  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
-  GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
-  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
-  g_type_class_add_private(klass, sizeof(GstVaapiEncoderH263Private));
-
-  GST_DEBUG_CATEGORY_INIT (gst_vaapi_h263_encoder_debug, "gst_va_h263_encoder", 0,
-      "gst_va_h263_encoder element");
-
-  object_class->finalize = gst_vaapi_encoder_h263_finalize;
-
-  base_class->validate_attributes = gst_h263_validate_parameters;
-  base_class->pre_alloc_resource  = NULL;
-  base_class->release_resource    = gst_vaapi_encoder_h263_release_resource;
-  base_class->render_frame = gst_vaapi_encoder_h263_rendering;
-  base_class->notify_frame = NULL;
-  base_class->copy_coded_frame = NULL;
-
-  /*
-  encoder_class->flush = gst_vaapi_encoder_h263_flush;
-  */
-  encoder_class->get_codec_data = NULL;
-
-}
-
-static void
-gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *h263_encoder)
-{
-  GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
-  ENCODER_ASSERT(h263_prv);
-
-  /* init public */
-  h263_encoder->bitrate = 0;
-  h263_encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
-  h263_encoder->init_qp = H263_DEFAULT_INIT_QP;
-  h263_encoder->min_qp = H263_DEFAULT_MIN_QP;
-
-  /* init private */
-  h263_prv->ref_surface = NULL;
-  h263_prv->recon_surface = NULL;
-
-  h263_prv->seq_parameter = VA_INVALID_ID;
-  h263_prv->pic_parameter = VA_INVALID_ID;
-  h263_prv->slice_parameter = VA_INVALID_ID;
-}
-
-static void
-gst_vaapi_encoder_h263_finalize(GObject *object)
-{
-  /*free private buffers*/
-  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
-
-  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
-    gst_vaapi_encoder_uninitialize(encoder);
-  }
-  G_OBJECT_CLASS(gst_vaapi_encoder_h263_parent_class)->finalize(object);
+  return GST_VAAPI_ENCODER_H263_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_H263, NULL));
 }
 
 static gboolean
-gst_h263_validate_parameters(GstVaapiBaseEncoder* encoder)
+gst_h263_validate_parameters(GstVaapiBaseEncoder* base)
 {
-  GstVaapiEncoderH263 *h263_encoder = GST_VAAPI_ENCODER_H263(encoder);
-  if (!ENCODER_WIDTH(h263_encoder) || !ENCODER_HEIGHT(h263_encoder) || !ENCODER_FPS(h263_encoder)) {
+  GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+  if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
     return FALSE;
   }
-  if (!h263_encoder->intra_period) {
-    h263_encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
+  if (!encoder->intra_period) {
+    encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
   }
-  if (-1 == h263_encoder->init_qp) {
-    h263_encoder->init_qp = H263_DEFAULT_INIT_QP;
+  if (-1 == encoder->init_qp) {
+    encoder->init_qp = H263_DEFAULT_INIT_QP;
   }
-  if (-1 == h263_encoder->min_qp) {
-    h263_encoder->min_qp = H263_DEFAULT_MIN_QP;
+  if (-1 == encoder->min_qp) {
+    encoder->min_qp = H263_DEFAULT_MIN_QP;
   }
 
   /* default compress ratio 1: (4*8*1.5) */
-  if (!h263_encoder->bitrate) {
-    h263_encoder->bitrate = ENCODER_WIDTH(h263_encoder)*ENCODER_HEIGHT(h263_encoder)*ENCODER_FPS(h263_encoder)/4;
+  if (!encoder->bitrate) {
+    encoder->bitrate = ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
   }
-  gst_vaapi_base_encoder_set_va_profile(GST_VAAPI_BASE_ENCODER(h263_encoder), VAProfileH263Baseline);
+  gst_vaapi_base_encoder_set_va_profile(GST_VAAPI_BASE_ENCODER(encoder), VAProfileH263Baseline);
   return TRUE;
 
 }
 
 
 static void
-h263_release_parameters(GstVaapiEncoderH263 *h263_encoder, GstVaapiDisplay *display)
+h263_release_parameters(GstVaapiEncoderH263 *encoder)
 {
-  GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
+  GstVaapiEncoderH263Private *priv = encoder->priv;
+  VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
   VAStatus va_status = VA_STATUS_SUCCESS;
 
   VAAPI_UNUSED_ARG(va_status);
 
-  if (VA_INVALID_ID != h263_prv->seq_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, h263_prv->seq_parameter);
-    h263_prv->seq_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->seq_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->seq_parameter);
+    priv->seq_parameter = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h263_prv->pic_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, h263_prv->pic_parameter);
-    h263_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h263_prv->slice_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, h263_prv->slice_parameter);
-    h263_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
 
 }
 
 static gboolean
-gst_vaapi_encoder_h263_release_resource(GstVaapiBaseEncoder* encoder,
-                       GstVaapiDisplay *display,
-                       GstVaapiContext *context)
+gst_vaapi_encoder_h263_release_resource(GstVaapiBaseEncoder* base)
 {
-  GstVaapiEncoderH263 *h263_encoder = GST_VAAPI_ENCODER_H263(encoder);
-  GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
+  GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+  GstVaapiEncoderH263Private *priv = encoder->priv;
+  GstVaapiContext *context = ENCODER_CONTEXT(base);
 
-  h263_release_parameters(h263_encoder, display);
+  h263_release_parameters(encoder);
 
   /*remove ref_surface*/
-  if (h263_prv->ref_surface) {
+  if (priv->ref_surface) {
     if (context) {
-      gst_vaapi_context_put_surface(context, h263_prv->ref_surface);
+      gst_vaapi_context_put_surface(context, priv->ref_surface);
     } else {
-      g_object_unref(h263_prv->ref_surface);
+      g_object_unref(priv->ref_surface);
     }
-    h263_prv->ref_surface = NULL;
+    priv->ref_surface = NULL;
   }
 
   /*remove recon_surface*/
-  if (h263_prv->recon_surface) {
+  if (priv->recon_surface) {
     if (context) {
-      gst_vaapi_context_put_surface(context, h263_prv->recon_surface);
+      gst_vaapi_context_put_surface(context, priv->recon_surface);
     } else {
-      g_object_unref(h263_prv->recon_surface);
+      g_object_unref(priv->recon_surface);
     }
-    h263_prv->recon_surface = NULL;
+    priv->recon_surface = NULL;
   }
 
   return TRUE;
 }
 
 static EncoderStatus
-gst_vaapi_encoder_h263_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
-                     GstVaapiContext *context, GstVaapiSurface *surface,
-                     guint frame_index, VABufferID coded_buf, gboolean *is_key)
+gst_vaapi_encoder_h263_rendering(
+    GstVaapiBaseEncoder *base,
+    GstVaapiSurface *surface,
+    guint frame_index,
+    VABufferID coded_buf,
+    gboolean *is_key
+)
 
 {
-  GstVaapiEncoderH263 *h263_encoder = GST_VAAPI_ENCODER_H263(encoder);
-  GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
-  VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+  GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+  GstVaapiEncoderH263Private *priv = encoder->priv;
+  GstVaapiContext *context = ENCODER_CONTEXT(base);
+  VADisplay va_dpy = ENCODER_VA_DISPLAY(base);
+  VAContextID context_id = ENCODER_VA_CONTEXT(base);
 
   VAStatus va_status = VA_STATUS_SUCCESS;
   EncoderStatus ret = ENCODER_NO_ERROR;
 
-  *is_key = (frame_index % h263_encoder->intra_period == 0);
+  *is_key = (frame_index % encoder->intra_period == 0);
 
   /* initialize sequence parameter set, only first time */
-  if (VA_INVALID_ID == h263_prv->seq_parameter) { /*only the first time*/
+  if (VA_INVALID_ID == priv->seq_parameter) { /*only the first time*/
     VAEncSequenceParameterBufferH263 seq_h263 = {0};
 
-    seq_h263.intra_period = h263_encoder->intra_period;
-    seq_h263.bits_per_second = h263_encoder->bitrate;
-    seq_h263.frame_rate = ENCODER_FPS(h263_encoder);
-    seq_h263.initial_qp = h263_encoder->init_qp;
-    seq_h263.min_qp = h263_encoder->min_qp;
+    seq_h263.intra_period = encoder->intra_period;
+    seq_h263.bits_per_second = encoder->bitrate;
+    seq_h263.frame_rate = ENCODER_FPS(encoder);
+    seq_h263.initial_qp = encoder->init_qp;
+    seq_h263.min_qp = encoder->min_qp;
 
     va_status = vaCreateBuffer(va_dpy, context_id,
                                VAEncSequenceParameterBufferType,
-                               sizeof(seq_h263), 1, &seq_h263, &h263_prv->seq_parameter);
+                               sizeof(seq_h263), 1, &seq_h263, &priv->seq_parameter);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_ENC_RES_ERR, "h263 alloc seq-buffer failed.");
-    va_status = vaRenderPicture(va_dpy, context_id, &h263_prv->seq_parameter, 1);
+    va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_parameter, 1);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "h263 vaRenderPicture seq-parameters failed.");
   }
 
   /* set reference and reconstructed surfaces */
-  if (!h263_prv->ref_surface) {
-    h263_prv->ref_surface = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h263_prv->ref_surface, ENCODER_SURFACE_ERR, "h263 reference surface, h263_pop_free_surface failed.");
+  if (!priv->ref_surface) {
+    priv->ref_surface = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->ref_surface, ENCODER_SURFACE_ERR, "h263 reference surface, h263_pop_free_surface failed.");
   }
-  if (!h263_prv->recon_surface) {
-    h263_prv->recon_surface = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h263_prv->recon_surface, ENCODER_SURFACE_ERR, "h263 reconstructed surface, h263_pop_free_surface failed.");
+  if (!priv->recon_surface) {
+    priv->recon_surface = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->recon_surface, ENCODER_SURFACE_ERR, "h263 reconstructed surface, h263_pop_free_surface failed.");
   }
 
   /* initialize picture, every time, every frame */
   VAEncPictureParameterBufferH263 pic_h263 = {0};
-  pic_h263.reference_picture = GST_VAAPI_OBJECT_ID(h263_prv->ref_surface);
-  pic_h263.reconstructed_picture = GST_VAAPI_OBJECT_ID(h263_prv->recon_surface);
+  pic_h263.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface);
+  pic_h263.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
   pic_h263.coded_buf = coded_buf;
-  pic_h263.picture_width = ENCODER_WIDTH(h263_encoder);
-  pic_h263.picture_height = ENCODER_HEIGHT(h263_encoder);
+  pic_h263.picture_width = ENCODER_WIDTH(encoder);
+  pic_h263.picture_height = ENCODER_HEIGHT(encoder);
   pic_h263.picture_type = (*is_key) ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
-  if (VA_INVALID_ID != h263_prv->pic_parameter) { /* destroy first*/
-    va_status = vaDestroyBuffer(va_dpy, h263_prv->pic_parameter);
-    h263_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) { /* destroy first*/
+    va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
 
   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
-                               sizeof(pic_h263), 1, &pic_h263, &h263_prv->pic_parameter);
+                               sizeof(pic_h263), 1, &pic_h263, &priv->pic_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_ENC_RES_ERR, "h263 creating pic-param buffer failed.");
-  va_status = vaRenderPicture(va_dpy, context_id, &h263_prv->pic_parameter, 1);
+  va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_parameter, 1);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR, "h263 rendering pic-param buffer failed.");
   /*initialize slice parameters, only ONE slice for h263*/
   VAEncSliceParameterBuffer slice_h263 = { 0 };
   slice_h263.start_row_number = 0;
-  slice_h263.slice_height = (ENCODER_HEIGHT(h263_encoder)+15)/16; /*MB?*/
+  slice_h263.slice_height = (ENCODER_HEIGHT(encoder)+15)/16; /*MB?*/
   slice_h263.slice_flags.bits.is_intra = *is_key;
   slice_h263.slice_flags.bits.disable_deblocking_filter_idc = 0;
-  if (VA_INVALID_ID != h263_prv->slice_parameter) {
-    vaDestroyBuffer(va_dpy, h263_prv->slice_parameter);
-    h263_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
 
   va_status = vaCreateBuffer(va_dpy,
@@ -296,22 +222,82 @@ gst_vaapi_encoder_h263_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
                              sizeof(slice_h263),
                              1,
                              &slice_h263,
-                             &h263_prv->slice_parameter);
+                             &priv->slice_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_ENC_RES_ERR,
                        "h263 creating slice-parameters buffer failed.");
 
-  va_status = vaRenderPicture(va_dpy, context_id, &h263_prv->slice_parameter, 1);
+  va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_parameter, 1);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR,
                        "h263 rendering slice-parameters buffer failed.");
 
   /*swap ref_surface and recon_surface */
-  GstVaapiSurface *swap = h263_prv->ref_surface;
-  h263_prv->ref_surface = h263_prv->recon_surface;
-  h263_prv->recon_surface = swap;
+  GstVaapiSurface *swap = priv->ref_surface;
+  priv->ref_surface = priv->recon_surface;
+  priv->recon_surface = swap;
 
 end:
   return ret;
 }
 
+static void
+gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *encoder)
+{
+  GstVaapiEncoderH263Private *priv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(encoder);
+  encoder->priv = priv;
+  ENCODER_ASSERT(priv);
+
+  /* init public */
+  encoder->bitrate = 0;
+  encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
+  encoder->init_qp = H263_DEFAULT_INIT_QP;
+  encoder->min_qp = H263_DEFAULT_MIN_QP;
+
+  /* init private */
+  priv->ref_surface = NULL;
+  priv->recon_surface = NULL;
+
+  priv->seq_parameter = VA_INVALID_ID;
+  priv->pic_parameter = VA_INVALID_ID;
+  priv->slice_parameter = VA_INVALID_ID;
+}
+
+static void
+gst_vaapi_encoder_h263_finalize(GObject *object)
+{
+  /*free private buffers*/
+  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+
+  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+    gst_vaapi_encoder_uninitialize(encoder);
+  }
+  G_OBJECT_CLASS(gst_vaapi_encoder_h263_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass)
+{
+  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+  GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+  g_type_class_add_private(klass, sizeof(GstVaapiEncoderH263Private));
+
+  GST_DEBUG_CATEGORY_INIT (gst_vaapi_h263_encoder_debug, "gst_va_h263_encoder", 0,
+      "gst_va_h263_encoder element");
+
+  object_class->finalize = gst_vaapi_encoder_h263_finalize;
+
+  base_class->validate_attributes = gst_h263_validate_parameters;
+  base_class->pre_alloc_resource  = NULL;
+  base_class->release_resource    = gst_vaapi_encoder_h263_release_resource;
+  base_class->render_frame = gst_vaapi_encoder_h263_rendering;
+  base_class->notify_frame = NULL;
+  base_class->copy_coded_frame = NULL;
+
+  /*
+  encoder_class->flush = gst_vaapi_encoder_h263_flush;
+  */
+  encoder_class->get_codec_data = NULL;
+
+}
index 06b5611..2cf1cda 100644 (file)
@@ -54,6 +54,8 @@ struct _GstVaapiEncoderH263 {
   guint32  intra_period;
   guint32  init_qp;  /*default 15, 1~31*/
   guint32  min_qp;   /*default 1, 1~31*/
+
+  GstVaapiEncoderH263Private *priv;
 };
 
 struct _GstVaapiEncoderH263Class {
index d3cc239..4401b8f 100644 (file)
@@ -45,6 +45,8 @@
 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
 #define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
 
+#define GST_VAAPI_ENCODER_H264_CAST(encoder)    ((GstVaapiEncoderH264 *)(encoder))
+
 #define SHARE_CODED_BUF         0
 
 #define DEFAULT_SURFACE_NUMBER  3
@@ -146,35 +148,9 @@ typedef struct _H264Bitstream H264Bitstream;
 
 static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
 
-static EncoderStatus gst_vaapi_encoder_h264_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                                    GstVaapiContext *context, GList **coded_pics);
-
-/*other functions*/
 /*other functions*/
-static EncoderStatus gst_vaapi_encoder_h264_get_codec_data(
-                                    GstVaapiEncoder* encoder, GstBuffer **buffer);
-static gboolean      gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
-static void          gst_vaapi_encoder_h264_finalize(GObject *object);
 static void          gst_vaapi_encoder_h264_init_public_values(GstVaapiEncoderH264* encoder);
 
-static gboolean      gst_vaapi_encoder_h264_alloc_slices(GstVaapiBaseEncoder *encoder,
-                                    GstVaapiDisplay *display, GstVaapiContext *context);
-static gboolean      gst_vaapi_encoder_h264_release_resource(GstVaapiBaseEncoder* encoder,
-                                    GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
-                                    GstVaapiVideoBuffer *display_buf,  gboolean need_flush,
-                                    GstVaapiVideoBuffer **out_buf);
-static void          gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *encoder,
-                                    GstVaapiVideoBuffer* buffer);
-static EncoderStatus gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
-                                    GstVaapiContext *context, GstVaapiSurface *surface,
-                                    guint frame_index, VABufferID coded_buf, gboolean *is_key);
-static void          gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
-//static EncoderStatus h264_encoder_read_sps_pps(
-//                                    GstVaapiEncoderH264Private *h264_prv, const guint8 *buf, guint32 size);
-static GstBuffer    *gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
-                                    guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
-
 /* h264 bitstream functions */
 static void     h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
 static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
@@ -196,33 +172,6 @@ static const guint8 *h264_next_nal(const guint8 *buffer, guint32 len, guint32 *n
 static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
                                     guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
 
-static void
-gst_vaapi_encoder_h264_class_init(GstVaapiEncoderH264Class *klass)
-{
-  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
-  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
-  GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
-
-  g_type_class_add_private(klass, sizeof(GstVaapiEncoderH264Private));
-
-  GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
-      "gst_va_h264_encoder element");
-
-  object_class->finalize = gst_vaapi_encoder_h264_finalize;
-
-  base_class->validate_attributes = gst_h264_validate_parameters;
-  base_class->pre_alloc_resource  = gst_vaapi_encoder_h264_alloc_slices;
-  base_class->release_resource    = gst_vaapi_encoder_h264_release_resource;
-  base_class->prepare_next_input_buffer = gst_vaapi_encoder_h264_prepare_next_buffer;
-  base_class->render_frame = gst_vaapi_encoder_h264_rendering;
-  base_class->notify_frame = gst_h264_notify_frame;
-  base_class->copy_coded_frame = gst_vaapi_encoder_h264_copy_coded_buffer;
-  base_class->encode_frame_failed = gst_vaapi_encoder_h264_frame_failed;
-
-  encoder_class->flush = gst_vaapi_encoder_h264_flush;
-  encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data;
-}
-
 static VAProfile
 h264_get_va_profile(guint32 profile)
 {
@@ -242,91 +191,10 @@ h264_get_va_profile(guint32 profile)
   return (-1);
 }
 
-static void
-gst_vaapi_encoder_h264_init(GstVaapiEncoderH264 *encoder)
-{
-  GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder);
-  ENCODER_ASSERT(h264_prv);
-  h264_prv->public = encoder;
-  encoder->priv = h264_prv;
-
-  /* init public attributes */
-  gst_vaapi_encoder_h264_init_public_values(encoder);
-  gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
-
-  /* init private values*/
-  h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
-  h264_prv->avc_flag = FALSE;
-
-  h264_prv->ref_surface1 = NULL;
-  h264_prv->ref_surface2 = NULL;
-  h264_prv->recon_surface = NULL;
-
-  h264_prv->seq_parameter = VA_INVALID_ID;
-  h264_prv->pic_parameter = VA_INVALID_ID;
-  h264_prv->slice_parameter = VA_INVALID_ID;
-  h264_prv->packed_sps_par_buf = VA_INVALID_ID;
-  h264_prv->packed_sps_data_buf = VA_INVALID_ID;
-  h264_prv->packed_pps_par_buf = VA_INVALID_ID;
-  h264_prv->packed_pps_data_buf = VA_INVALID_ID;
-  h264_prv->slice_param_buffers = NULL;
-  h264_prv->default_slice_height = 0;
-  h264_prv->slice_mod_mb_num = 0;
-
-  h264_prv->sps_data = NULL;
-  h264_prv->pps_data = NULL;
-
-  h264_prv->queued_buffers = g_queue_new();
-  h264_prv->gop_count = 0;
-  h264_prv->cur_display_num = 0;
-  h264_prv->cur_decode_num = 0;
-  h264_prv->cur_slice_type = SLICE_TYPE_I;
-  h264_prv->last_decode_time = 0LL;
-  h264_prv->default_cts_offset = 0;
-
-  h264_prv->max_frame_num = 0;
-  h264_prv->max_pic_order_cnt = 0;
-  h264_prv->idr_num = 0;
-}
-
-static void
-gst_vaapi_encoder_h264_finalize(GObject *object)
-{
-  /*free private buffers*/
-  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
-  GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(object);
-
-  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
-    gst_vaapi_encoder_uninitialize(encoder);
-  }
-
-  if (h264_prv->sps_data) {
-    gst_buffer_unref(h264_prv->sps_data);
-    h264_prv->sps_data = NULL;
-  }
-  if (h264_prv->pps_data) {
-    gst_buffer_unref(h264_prv->pps_data);
-    h264_prv->pps_data = NULL;
-  }
-  if (h264_prv->slice_param_buffers) {
-    g_free(h264_prv->slice_param_buffers);
-    h264_prv->slice_param_buffers = NULL;
-  }
-
-  if (h264_prv->queued_buffers) {
-    ENCODER_ASSERT(g_queue_is_empty(h264_prv->queued_buffers));
-    g_queue_free(h264_prv->queued_buffers);
-    h264_prv->queued_buffers = NULL;
-  }
-
-  G_OBJECT_CLASS(gst_vaapi_encoder_h264_parent_class)->finalize(object);
-}
-
-
 GstVaapiEncoderH264 *
 gst_vaapi_encoder_h264_new(void)
 {
-  return GST_VAAPI_ENCODER_H264(g_object_new(GST_TYPE_VAAPI_ENCODER_H264, NULL));
+  return GST_VAAPI_ENCODER_H264_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_H264, NULL));
 }
 
 static void
@@ -345,29 +213,29 @@ gst_vaapi_encoder_h264_init_public_values(GstVaapiEncoderH264* encoder)
 void
 gst_vaapi_encoder_h264_set_avc_flag(GstVaapiEncoderH264* encoder, gboolean avc)
 {
-  GstVaapiEncoderH264Private *h264_prv = encoder->priv;
-  h264_prv->avc_flag = avc;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+  priv->avc_flag = avc;
 }
 
 gboolean
 gst_vaapi_encoder_h264_get_avc_flag(GstVaapiEncoderH264* encoder)
 {
-  GstVaapiEncoderH264Private *h264_prv = encoder->priv;
-  return h264_prv->avc_flag;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+  return priv->avc_flag;
 }
 
 gboolean
-gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
+gst_h264_validate_parameters(GstVaapiBaseEncoder *base)
 {
-  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264(base_encoder);
-  GstVaapiEncoderH264Private *h264_prv = encoder->priv;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
     return FALSE;
   }
   if (!encoder->profile) {
     encoder->profile = H264_DEFAULT_PROFILE;
   }
-  gst_vaapi_base_encoder_set_va_profile(base_encoder, h264_get_va_profile(encoder->profile));
+  gst_vaapi_base_encoder_set_va_profile(base, h264_get_va_profile(encoder->profile));
   if (!encoder->level) {
     if (encoder->profile <= H264_PROFILE_BASELINE)
       encoder->level = H264_LEVEL_30;
@@ -408,29 +276,31 @@ gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
                  slice_7_height = 1
                  slice_8_height = 1
    */
-  h264_prv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
-  if (0 == h264_prv->default_slice_height) { /* special value */
-    h264_prv->default_slice_height = 1;
-    h264_prv->slice_mod_mb_num = 0;
+  priv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
+  if (0 == priv->default_slice_height) { /* special value */
+    priv->default_slice_height = 1;
+    priv->slice_mod_mb_num = 0;
     encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
   } else {
-    h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
+    priv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
   }
 
   if (encoder->b_frame_num) {
-    h264_prv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
+    priv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
   } else {
-    h264_prv->default_cts_offset = 0;
+    priv->default_cts_offset = 0;
   }
   return TRUE;
 }
 
 
 static gboolean
-h264_encoder_release_parameters(GstVaapiEncoderH264 *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+h264_encoder_release_parameters(GstVaapiEncoderH264 *encoder)
 {
   VAStatus va_status = VA_STATUS_SUCCESS;
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+  GstVaapiContext *context = ENCODER_CONTEXT(encoder);
 
   gboolean is_locked = FALSE;
 
@@ -440,60 +310,60 @@ h264_encoder_release_parameters(GstVaapiEncoderH264 *h264_encoder, GstVaapiDispl
   VADisplay va_dpy = gst_vaapi_display_get_display(display);
 
   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
-  if (VA_INVALID_ID != h264_prv->seq_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
-    h264_prv->seq_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->seq_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->seq_parameter);
+    priv->seq_parameter = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h264_prv->pic_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
-    h264_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h264_prv->slice_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
-    h264_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
 
-  if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_par_buf);
-    h264_prv->packed_sps_par_buf = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->packed_sps_par_buf) {
+    va_status = vaDestroyBuffer(va_dpy, priv->packed_sps_par_buf);
+    priv->packed_sps_par_buf = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_data_buf);
-    h264_prv->packed_sps_data_buf = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->packed_sps_data_buf) {
+    va_status = vaDestroyBuffer(va_dpy, priv->packed_sps_data_buf);
+    priv->packed_sps_data_buf = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_par_buf);
-    h264_prv->packed_pps_par_buf = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->packed_pps_par_buf) {
+    va_status = vaDestroyBuffer(va_dpy, priv->packed_pps_par_buf);
+    priv->packed_pps_par_buf = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
-    va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_data_buf);
-    h264_prv->packed_pps_data_buf = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->packed_pps_data_buf) {
+    va_status = vaDestroyBuffer(va_dpy, priv->packed_pps_data_buf);
+    priv->packed_pps_data_buf = VA_INVALID_ID;
   }
 
   ENCODER_RELEASE_DISPLAY_LOCK(display);
 
-  if (h264_prv->slice_param_buffers) {
-    g_free(h264_prv->slice_param_buffers);
-    h264_prv->slice_param_buffers = NULL;
+  if (priv->slice_param_buffers) {
+    g_free(priv->slice_param_buffers);
+    priv->slice_param_buffers = NULL;
   }
 
-  if (h264_prv->sps_data) {
-    gst_buffer_unref(h264_prv->sps_data);
-    h264_prv->sps_data = NULL;
+  if (priv->sps_data) {
+    gst_buffer_unref(priv->sps_data);
+    priv->sps_data = NULL;
   }
-  if (h264_prv->pps_data) {
-    gst_buffer_unref(h264_prv->pps_data);
-    h264_prv->pps_data = NULL;
+  if (priv->pps_data) {
+    gst_buffer_unref(priv->pps_data);
+    priv->pps_data = NULL;
   }
 
   return TRUE;
 }
 
 static void
-h264_release_queued_buffers(GstVaapiEncoderH264Private *h264_prv)
+h264_release_queued_buffers(GstVaapiEncoderH264Private *priv)
 {
-    while (!g_queue_is_empty(h264_prv->queued_buffers)) {
-    GstBuffer* tmp = g_queue_pop_head(h264_prv->queued_buffers);
+    while (!g_queue_is_empty(priv->queued_buffers)) {
+    GstBuffer* tmp = g_queue_pop_head(priv->queued_buffers);
     if (tmp)
       gst_buffer_unref(tmp);
   }
@@ -501,146 +371,152 @@ h264_release_queued_buffers(GstVaapiEncoderH264Private *h264_prv)
 
 
 static gboolean
-gst_vaapi_encoder_h264_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+gst_vaapi_encoder_h264_release_resource(
+    GstVaapiBaseEncoder* base
+)
 {
-  GstVaapiEncoderH264* h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
+  GstVaapiEncoderH264* encoder = GST_VAAPI_ENCODER_H264_CAST(base);
   gboolean ret = TRUE;
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+  GstVaapiContext *context = ENCODER_CONTEXT(base);
 
   /* release buffers first */
-  h264_encoder_release_parameters(h264_encoder, display, context);
-  h264_release_queued_buffers(h264_prv);
-  h264_prv->cur_display_num = 0;
-  h264_prv->cur_decode_num = 0;
-  h264_prv->cur_slice_type = SLICE_TYPE_I;
-  h264_prv->gop_count = 0;
-  h264_prv->last_decode_time = 0LL;
-  h264_prv->default_cts_offset = 0;
+  h264_encoder_release_parameters(encoder);
+  h264_release_queued_buffers(priv);
+  priv->cur_display_num = 0;
+  priv->cur_decode_num = 0;
+  priv->cur_slice_type = SLICE_TYPE_I;
+  priv->gop_count = 0;
+  priv->last_decode_time = 0LL;
+  priv->default_cts_offset = 0;
 
   /*remove ref_surface1*/
-  if (h264_prv->ref_surface1) {
+  if (priv->ref_surface1) {
     if (context) {
-      gst_vaapi_context_put_surface(context, h264_prv->ref_surface1);
+      gst_vaapi_context_put_surface(context, priv->ref_surface1);
     } else {
-      g_object_unref(h264_prv->ref_surface1);
+      g_object_unref(priv->ref_surface1);
     }
-    h264_prv->ref_surface1 = NULL;
+    priv->ref_surface1 = NULL;
   }
 
-  if (h264_prv->ref_surface2) {
+  if (priv->ref_surface2) {
     if (context) {
-      gst_vaapi_context_put_surface(context, h264_prv->ref_surface2);
+      gst_vaapi_context_put_surface(context, priv->ref_surface2);
     } else {
-      g_object_unref(h264_prv->ref_surface2);
+      g_object_unref(priv->ref_surface2);
     }
-    h264_prv->ref_surface2 = NULL;
+    priv->ref_surface2 = NULL;
   }
 
   /*remove recon_surface*/
-  if (h264_prv->recon_surface) {
+  if (priv->recon_surface) {
     if (context) {
-      gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
+      gst_vaapi_context_put_surface(context, priv->recon_surface);
     } else {
-      g_object_unref(h264_prv->recon_surface);
+      g_object_unref(priv->recon_surface);
     }
-    h264_prv->recon_surface = NULL;
+    priv->recon_surface = NULL;
   }
 
   return ret;
 }
 
 static gboolean
-gst_vaapi_encoder_h264_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+gst_vaapi_encoder_h264_alloc_slices(
+    GstVaapiBaseEncoder *base,
+    GstVaapiContext *context
+)
 {
   gboolean ret = TRUE;
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
 
-  h264_prv->slice_param_buffers =
+  priv->slice_param_buffers =
 #ifdef _SIMPLE_LIB_VA_
   (VAEncSliceParameterBuffer*)
 #else
   (VAEncSliceParameterBufferH264*)
 #endif
-          g_malloc0_n(h264_encoder->slice_num,
-              sizeof(h264_prv->slice_param_buffers[0]));
+          g_malloc0_n(encoder->slice_num,
+              sizeof(priv->slice_param_buffers[0]));
 
   return ret;
 }
 
 static void
-gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer)
+gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *base, GstVaapiVideoBuffer* buffer)
 {
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
-
-  h264_release_queued_buffers(h264_prv);
-  h264_prv->cur_display_num = 0;
-  h264_prv->cur_decode_num = 0;
-  h264_prv->cur_slice_type = SLICE_TYPE_I;
-  h264_prv->gop_count = 0;
-  h264_prv->last_decode_time = 0LL;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+
+  h264_release_queued_buffers(priv);
+  priv->cur_display_num = 0;
+  priv->cur_decode_num = 0;
+  priv->cur_slice_type = SLICE_TYPE_I;
+  priv->gop_count = 0;
+  priv->last_decode_time = 0LL;
 }
 
 static EncoderStatus
-gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
+gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* base,
                               GstVaapiVideoBuffer *display_buf, gboolean need_flush,
                               GstVaapiVideoBuffer **out_buf)
 {
   EncoderStatus ret = ENCODER_NO_ERROR;
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   GstVaapiVideoBuffer  *return_buf = NULL;
   //guint64 pts = 0;
 
-  if (NULL == display_buf && g_queue_is_empty(h264_prv->queued_buffers)) {
+  if (NULL == display_buf && g_queue_is_empty(priv->queued_buffers)) {
     ret = ENCODER_BUFFER_EMPTY;
-    if (h264_prv->gop_count >= h264_encoder->intra_period || need_flush)
-      h264_prv->gop_count = 0;
+    if (priv->gop_count >= encoder->intra_period || need_flush)
+      priv->gop_count = 0;
     goto end;
   }
 
   if (display_buf) {
-    ++h264_prv->gop_count;
+    ++priv->gop_count;
     gst_buffer_ref(GST_BUFFER_CAST(display_buf));
-    h264_prv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
+    priv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
   }
 
   /* first frame */
-  if (h264_prv->gop_count == 1) {
+  if (priv->gop_count == 1) {
     ENCODER_ASSERT(display_buf);
-    h264_prv->cur_display_num = 0;
-    h264_prv->cur_decode_num = 0;
-    h264_prv->cur_slice_type = SLICE_TYPE_I;
-    ++h264_prv->idr_num;
+    priv->cur_display_num = 0;
+    priv->cur_decode_num = 0;
+    priv->cur_slice_type = SLICE_TYPE_I;
+    ++priv->idr_num;
     return_buf = display_buf;
     goto end;
   }
 
   if (display_buf) {
-    if (h264_encoder->b_frame_num &&
-        h264_prv->gop_count < h264_encoder->intra_period &&
-        g_queue_get_length(h264_prv->queued_buffers) < h264_encoder->b_frame_num
+    if (encoder->b_frame_num &&
+        priv->gop_count < encoder->intra_period &&
+        g_queue_get_length(priv->queued_buffers) < encoder->b_frame_num
         )
     {
-      g_queue_push_tail(h264_prv->queued_buffers, display_buf);
+      g_queue_push_tail(priv->queued_buffers, display_buf);
       ret = ENCODER_BUFFER_WAITING;
       goto end;
     }
-    h264_prv->cur_slice_type = SLICE_TYPE_P;
-    h264_prv->cur_display_num = h264_prv->gop_count-1;
-    ++h264_prv->cur_decode_num;
+    priv->cur_slice_type = SLICE_TYPE_P;
+    priv->cur_display_num = priv->gop_count-1;
+    ++priv->cur_decode_num;
     return_buf = display_buf;
   } else {
     if (need_flush) {
-      return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(h264_prv->queued_buffers);
-      h264_prv->cur_slice_type = SLICE_TYPE_P;
-      h264_prv->cur_display_num = h264_prv->gop_count - 1;
-      ++h264_prv->cur_decode_num;
+      return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(priv->queued_buffers);
+      priv->cur_slice_type = SLICE_TYPE_P;
+      priv->cur_display_num = priv->gop_count - 1;
+      ++priv->cur_decode_num;
     } else {
-      return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(h264_prv->queued_buffers);
-      h264_prv->cur_slice_type = SLICE_TYPE_B;
-      h264_prv->cur_display_num = h264_prv->gop_count - 2 - g_queue_get_length(h264_prv->queued_buffers);
+      return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(priv->queued_buffers);
+      priv->cur_slice_type = SLICE_TYPE_B;
+      priv->cur_display_num = priv->gop_count - 2 - g_queue_get_length(priv->queued_buffers);
     }
   }
 
@@ -650,8 +526,19 @@ end:
   return ret;
 }
 
+static inline void
+h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
+{
+  GstVaapiSurface *tmp;
+
+  g_return_if_fail(s1 && s2);
+  tmp = *s1;
+  *s1 = *s2;
+  *s2 = tmp;
+}
 
 #ifdef _SIMPLE_LIB_VA_
+
 static EncoderStatus
 gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
                              GstVaapiContext *context, GstVaapiSurface *surface,
@@ -659,8 +546,8 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
 {
   EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264_CAST(encoder);
+  GstVaapiEncoderH264Private *priv = h264_encoder->priv;
   VAEncPictureParameterBufferH264 pic_h264;
   VAEncSliceParameterBuffer *slice_h264 = NULL;
 
@@ -670,13 +557,13 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
   VADisplay va_dpy = gst_vaapi_display_get_display(display);
   VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
 
-  *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
+  *is_key = (priv->cur_slice_type == SLICE_TYPE_I);
 
   /* lock display */
   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
   /*handle first surface_index*/
   /*only need first frame*/
-  if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
+  if (VA_INVALID_ID == priv->seq_parameter) { /*first time*/
     VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
     seq_h264.level_idc = h264_encoder->level; /* 3.0 */
     seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
@@ -693,57 +580,57 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
 
     va_status = vaCreateBuffer(va_dpy, context_id,
                                VAEncSequenceParameterBufferType,
-                               sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
+                               sizeof(seq_h264), 1, &seq_h264, &priv->seq_parameter);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.");
-    va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
+    va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_parameter, 1);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.");
   }
 
   /* set pic_parameters*/
-  if (!h264_prv->ref_surface1) {
-    h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h264_prv->ref_surface1, ENCODER_SURFACE_ERR,
+  if (!priv->ref_surface1) {
+    priv->ref_surface1 = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->ref_surface1, ENCODER_SURFACE_ERR,
                          "reference surface, h264_pop_free_surface failed.");
   }
-  if (!h264_prv->recon_surface) {
-    h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR,
+  if (!priv->recon_surface) {
+    priv->recon_surface = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->recon_surface, ENCODER_SURFACE_ERR,
                          "reconstructed surface, h264_pop_free_surface failed.");
   }
 
-  pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
-  pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
+  pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+  pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
   pic_h264.coded_buf = coded_buf;
   pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
   pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
   pic_h264.last_picture = 0; // last pic or not
 
-  if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
-    vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
-    h264_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) { /* share the same pic_parameter*/
+    vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
-                               sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
+                               sizeof(pic_h264), 1, &pic_h264, &priv->pic_parameter);
 
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR, "creating pic-param buffer failed.");
 
-  va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
+  va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_parameter, 1);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.");
 
   /* set slice parameters, support multiple slices */
   int i = 0;
   guint32 last_row_num = 0;
-  guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
+  guint32 slice_mod_num = priv->slice_mod_mb_num;
 
-  memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
+  memset(priv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(priv->slice_param_buffers[0]));
   for (i = 0; i < h264_encoder->slice_num; ++i) {
-    slice_h264 = &h264_prv->slice_param_buffers[i];
+    slice_h264 = &priv->slice_param_buffers[i];
     slice_h264->start_row_number = last_row_num;               /* unit MB*/
-    slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
+    slice_h264->slice_height = priv->default_slice_height; /* unit MB */
     if (slice_mod_num) {
       ++slice_h264->slice_height;
       --slice_mod_num;
@@ -755,28 +642,28 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
   }
   ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
 
-  if (VA_INVALID_ID != h264_prv->slice_parameter) {
-    vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
-    h264_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
   va_status = vaCreateBuffer(va_dpy,
                              context_id,
                              VAEncSliceParameterBufferType,
-                             sizeof(h264_prv->slice_param_buffers[0]),
+                             sizeof(priv->slice_param_buffers[0]),
                              h264_encoder->slice_num,
-                             h264_prv->slice_param_buffers,
-                             &h264_prv->slice_parameter);
+                             priv->slice_param_buffers,
+                             &priv->slice_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.");
 
-  va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
+  va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_parameter, 1);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.");
 
   /*after finished, set ref_surface1_index, recon_surface_index */
-  GstVaapiSurface *swap = h264_prv->ref_surface1;
-  h264_prv->ref_surface1 = h264_prv->recon_surface;
-  h264_prv->recon_surface = swap;
+  GstVaapiSurface *swap = priv->ref_surface1;
+  priv->ref_surface1 = priv->recon_surface;
+  priv->recon_surface = swap;
 
   end:
   ENCODER_RELEASE_DISPLAY_LOCK(display);
@@ -785,36 +672,26 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
 
 #else  /* extended libva, new parameter structures*/
 
-static void h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
-{
-  GstVaapiSurface *tmp;
-
-  g_return_if_fail(s1 && s2);
-  tmp = *s1;
-  *s1 = *s2;
-  *s2 = tmp;
-}
-
 static gboolean
-set_sequence_parameters(GstVaapiEncoderH264 *h264_encoder,
+set_sequence_parameters(GstVaapiEncoderH264 *encoder,
                       VAEncSequenceParameterBufferH264 *seq_param)
 {
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   guint width_in_mbs, height_in_mbs;
 
-  width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
-  height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
+  width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+  height_in_mbs = (ENCODER_HEIGHT(encoder)+15)/16;
 
   seq_param->seq_parameter_set_id = 0;
-  seq_param->level_idc = h264_encoder->level; /* 3.0 */
-  seq_param->intra_period = h264_encoder->intra_period;
+  seq_param->level_idc = encoder->level; /* 3.0 */
+  seq_param->intra_period = encoder->intra_period;
   seq_param->ip_period = 0;           // ?
-  if (h264_encoder->bitrate> 0)
-      seq_param->bits_per_second = h264_encoder->bitrate; /* use kbps as input */
+  if (encoder->bitrate> 0)
+      seq_param->bits_per_second = encoder->bitrate; /* use kbps as input */
   else
       seq_param->bits_per_second = 0;
 
-  seq_param->max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1);  // ?, why 4
+  seq_param->max_num_ref_frames = (encoder->b_frame_num < 2 ? 3 : encoder->b_frame_num+1);  // ?, why 4
   seq_param->picture_width_in_mbs = width_in_mbs;
   seq_param->picture_height_in_mbs = height_in_mbs;
 
@@ -833,8 +710,8 @@ set_sequence_parameters(GstVaapiEncoderH264 *h264_encoder,
         seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 2;
   seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
 
-  h264_prv->max_frame_num = 1<<(seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4);
-  h264_prv->max_pic_order_cnt = 1 <<(seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
+  priv->max_frame_num = 1<<(seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4);
+  priv->max_pic_order_cnt = 1 <<(seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
 
   seq_param->bit_depth_luma_minus8 = 0;
   seq_param->bit_depth_chroma_minus8 = 0;
@@ -845,13 +722,14 @@ set_sequence_parameters(GstVaapiEncoderH264 *h264_encoder,
   seq_param->offset_for_top_to_bottom_field = 0;
   memset(seq_param->offset_for_ref_frame, 0, sizeof(seq_param->offset_for_ref_frame));
 
-  if (height_in_mbs*16 - ENCODER_HEIGHT(h264_encoder)) {
+  if (height_in_mbs*16 - ENCODER_HEIGHT(encoder)) {
     seq_param->frame_cropping_flag = 1;
     seq_param->frame_crop_left_offset = 0;
     seq_param->frame_crop_right_offset = 0;
     seq_param->frame_crop_top_offset = 0;
     seq_param->frame_crop_bottom_offset =
-           (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1));
+        ((height_in_mbs * 16 - ENCODER_HEIGHT(encoder))/
+         (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)));
   }
 #if 0
   if (h264_encoder->init_qp == -1)
@@ -870,28 +748,29 @@ set_sequence_parameters(GstVaapiEncoderH264 *h264_encoder,
 }
 
 static gboolean
-h264_fill_sequence_buffer(GstVaapiEncoderH264 *h264_encoder,
-                        VADisplay va_dpy, VAContextID context_id)
+h264_fill_sequence_buffer(GstVaapiEncoderH264 *encoder)
 {
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
+  VADisplay va_dpy       = ENCODER_VA_DISPLAY(encoder);
+  VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
   gboolean ret = TRUE;
   VAStatus va_status = VA_STATUS_SUCCESS;
 
   /* only once */
-  if (VA_INVALID_ID != h264_prv->seq_parameter)
+  if (VA_INVALID_ID != priv->seq_parameter)
     return TRUE;
 
-  set_sequence_parameters(h264_encoder, &seq_h264);
+  set_sequence_parameters(encoder, &seq_h264);
   va_status = vaCreateBuffer(va_dpy, context_id,
                              VAEncSequenceParameterBufferType,
                              sizeof(seq_h264), 1,
-                             &seq_h264, &h264_prv->seq_parameter);
+                             &seq_h264, &priv->seq_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                      FALSE, "alloc seq-buffer failed.");
 
   /*pack sps header buffer/data */
-  if (NULL == h264_prv->sps_data) {
+  if (NULL == priv->sps_data) {
     VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
     guint32 length_in_bits;
     guint8 *packed_seq_buffer = NULL;
@@ -899,15 +778,15 @@ h264_fill_sequence_buffer(GstVaapiEncoderH264 *h264_encoder,
     h264_bitstream_init(&bitstream, 128*8);
     h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
     h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
-    h264_bitstream_write_sps(&bitstream, &seq_h264, h264_encoder->profile);
+    h264_bitstream_write_sps(&bitstream, &seq_h264, encoder->profile);
     ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
     length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
     packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
 
     /* set codec data sps */
-    h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
-    GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
-    memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, GST_BUFFER_SIZE(h264_prv->sps_data));
+    priv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+    GST_BUFFER_SIZE(priv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
+    memcpy(GST_BUFFER_DATA(priv->sps_data), packed_seq_buffer+4, GST_BUFFER_SIZE(priv->sps_data));
 
     packed_header_param_buffer.type = VAEncPackedHeaderSequence;
     packed_header_param_buffer.bit_length = length_in_bits;
@@ -917,7 +796,7 @@ h264_fill_sequence_buffer(GstVaapiEncoderH264 *h264_encoder,
                                VAEncPackedHeaderParameterBufferType,
                                sizeof(packed_header_param_buffer), 1,
                                &packed_header_param_buffer,
-                               &h264_prv->packed_sps_par_buf);
+                               &priv->packed_sps_par_buf);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          FALSE,
                          "EncPackedSeqHeaderParameterBuffer failed");
@@ -926,7 +805,7 @@ h264_fill_sequence_buffer(GstVaapiEncoderH264 *h264_encoder,
                                VAEncPackedHeaderDataBufferType,
                                (length_in_bits + 7) / 8, 1,
                                packed_seq_buffer,
-                               &h264_prv->packed_sps_data_buf);
+                               &priv->packed_sps_data_buf);
     h264_bitstream_destroy(&bitstream, TRUE);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          FALSE,
@@ -938,18 +817,20 @@ end:
 }
 
 static gboolean
-set_picture_parameters(GstVaapiEncoderH264 *h264_encoder,
-                        VAEncPictureParameterBufferH264 *pic_param)
+set_picture_parameters(
+    GstVaapiEncoderH264 *encoder,
+    VAEncPictureParameterBufferH264 *pic_param
+)
 {
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
 
   pic_param->pic_parameter_set_id = 0;
   pic_param->seq_parameter_set_id = 0;
   pic_param->last_picture = 0; /* means last encoding picture */
-  pic_param->frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ?
-                       (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num);
+  pic_param->frame_num = (priv->cur_slice_type == SLICE_TYPE_B ?
+                       (priv->cur_decode_num + 1) : priv->cur_decode_num);
   //pic_h264.coding_type = 0;
-  pic_param->pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26);
+  pic_param->pic_init_qp = (encoder->init_qp >= 0 ? encoder->init_qp : 26);
   pic_param->num_ref_idx_l0_active_minus1 = 0; /* only 1 reference */
   pic_param->num_ref_idx_l1_active_minus1 = 0; /* B frames only have 1 backward and 1 forward reference*/
   pic_param->chroma_qp_index_offset = 0;
@@ -957,8 +838,8 @@ set_picture_parameters(GstVaapiEncoderH264 *h264_encoder,
 
   /* set picture fields */
   pic_param->pic_fields.value = 0;
-  pic_param->pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I);
-  pic_param->pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B);
+  pic_param->pic_fields.bits.idr_pic_flag = (priv->cur_slice_type == SLICE_TYPE_I);
+  pic_param->pic_fields.bits.reference_pic_flag = (priv->cur_slice_type != SLICE_TYPE_B);
   pic_param->pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC;
   pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
   pic_param->pic_fields.bits.weighted_bipred_idc = 0;
@@ -974,44 +855,47 @@ set_picture_parameters(GstVaapiEncoderH264 *h264_encoder,
 }
 
 static gboolean
-h264_fill_picture_buffer(GstVaapiEncoderH264 *h264_encoder,
-                        VADisplay va_dpy, VAContextID context_id,
-                        VABufferID coded_buf)
+h264_fill_picture_buffer(
+    GstVaapiEncoderH264 *encoder,
+    VABufferID coded_buf
+)
 {
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   VAEncPictureParameterBufferH264 pic_h264;
+  VADisplay va_dpy       = ENCODER_VA_DISPLAY(encoder);
+  VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
   gboolean ret = TRUE;
   VAStatus va_status = VA_STATUS_SUCCESS;
 
   VAAPI_UNUSED_ARG(va_status);
   memset(&pic_h264, 0, sizeof(pic_h264));
-  set_picture_parameters(h264_encoder, &pic_h264);
-  pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
-  pic_h264.CurrPic.TopFieldOrderCnt = h264_prv->cur_display_num * 2;   // ??? /**/
-  pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
-  pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
+  set_picture_parameters(encoder, &pic_h264);
+  pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+  pic_h264.CurrPic.TopFieldOrderCnt = priv->cur_display_num * 2;   // ??? /**/
+  pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+  pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
   pic_h264.ReferenceFrames[2].picture_id = VA_INVALID_ID;
   pic_h264.coded_buf = coded_buf;
 
   char *frame_type = "I";
-  if (h264_prv->cur_slice_type == SLICE_TYPE_P)
+  if (priv->cur_slice_type == SLICE_TYPE_P)
     frame_type = "P";
-  if (h264_prv->cur_slice_type == SLICE_TYPE_B)
+  if (priv->cur_slice_type == SLICE_TYPE_B)
     frame_type = "B";
   ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
          frame_type, pic_h264.frame_num, pic_h264.CurrPic.TopFieldOrderCnt);
 
-  if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
-    vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
-    h264_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) { /* share the same pic_parameter*/
+    vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
-                               sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
+                               sizeof(pic_h264), 1, &pic_h264, &priv->pic_parameter);
 
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        FALSE, "creating pic-param buffer failed.");
 
-  if (VA_INVALID_ID == h264_prv->packed_pps_data_buf) {
+  if (VA_INVALID_ID == priv->packed_pps_data_buf) {
     VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
     guint32 length_in_bits;
     guint8 *packed_pic_buffer = NULL;
@@ -1025,9 +909,9 @@ h264_fill_picture_buffer(GstVaapiEncoderH264 *h264_encoder,
     packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
 
     /*set codec data pps*/
-    h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
-    GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4;
-    memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, GST_BUFFER_SIZE(h264_prv->pps_data));
+    priv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+    GST_BUFFER_SIZE(priv->pps_data) = (length_in_bits+7)/8-4;
+    memcpy(GST_BUFFER_DATA(priv->pps_data), packed_pic_buffer+4, GST_BUFFER_SIZE(priv->pps_data));
 
     packed_header_param_buffer.type = VAEncPackedHeaderPicture;
     packed_header_param_buffer.bit_length = length_in_bits;
@@ -1038,7 +922,7 @@ h264_fill_picture_buffer(GstVaapiEncoderH264 *h264_encoder,
                                VAEncPackedHeaderParameterBufferType,
                                sizeof(packed_header_param_buffer), 1,
                                &packed_header_param_buffer,
-                               &h264_prv->packed_pps_par_buf);
+                               &priv->packed_pps_par_buf);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          FALSE,
                          "EncPackedPicHeaderParameterBuffer failed");
@@ -1048,7 +932,7 @@ h264_fill_picture_buffer(GstVaapiEncoderH264 *h264_encoder,
                                VAEncPackedHeaderDataBufferType,
                                (length_in_bits + 7) / 8, 1,
                                packed_pic_buffer,
-                               &h264_prv->packed_pps_data_buf);
+                               &priv->packed_pps_data_buf);
     h264_bitstream_destroy(&bitstream, TRUE);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          FALSE,
@@ -1060,39 +944,44 @@ end:
 
 
 static gboolean
-h264_fill_slice_buffers(GstVaapiEncoderH264 *h264_encoder,
-                        VADisplay va_dpy, VAContextID context_id)
+h264_fill_slice_buffers(
+    GstVaapiEncoderH264 *encoder
+)
 {
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   VAEncSliceParameterBufferH264 *slice_h264 = NULL;
+  VADisplay va_dpy       = ENCODER_VA_DISPLAY(encoder);
+  VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
   guint width_in_mbs;
   gboolean ret = TRUE;
   VAStatus va_status = VA_STATUS_SUCCESS;
 
-  width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
+  width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
 
   int i = 0;
   guint32 last_row_num = 0;
-  guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
+  guint32 slice_mod_num = priv->slice_mod_mb_num;
 
-  memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
-  for (i = 0; i < h264_encoder->slice_num; ++i) {
+  memset(priv->slice_param_buffers,
+         0,
+         encoder->slice_num*sizeof(priv->slice_param_buffers[0]));
+  for (i = 0; i < encoder->slice_num; ++i) {
     int i_pic = 0;
-    slice_h264 = &h264_prv->slice_param_buffers[i];
+    slice_h264 = &priv->slice_param_buffers[i];
 
     slice_h264->macroblock_address = last_row_num*width_in_mbs;
-    slice_h264->num_macroblocks = width_in_mbs*h264_prv->default_slice_height;
-    last_row_num += h264_prv->default_slice_height;
+    slice_h264->num_macroblocks = width_in_mbs*priv->default_slice_height;
+    last_row_num += priv->default_slice_height;
     if (slice_mod_num) {
       slice_h264->num_macroblocks += width_in_mbs;
       ++last_row_num;
       --slice_mod_num;
     }
     slice_h264->macroblock_info = VA_INVALID_ID;
-    slice_h264->slice_type = h264_prv->cur_slice_type;
+    slice_h264->slice_type = priv->cur_slice_type;
     slice_h264->pic_parameter_set_id = 0;
-    slice_h264->idr_pic_id = h264_prv->idr_num;
-    slice_h264->pic_order_cnt_lsb = (h264_prv->cur_display_num*2) % h264_prv->max_pic_order_cnt;
+    slice_h264->idr_pic_id = priv->idr_num;
+    slice_h264->pic_order_cnt_lsb = (priv->cur_display_num*2) % priv->max_pic_order_cnt;
 
     /* not used if pic_order_cnt_type = 0 */
     slice_h264->delta_pic_order_cnt_bottom = 0;
@@ -1105,15 +994,15 @@ h264_fill_slice_buffers(GstVaapiEncoderH264 *h264_encoder,
     slice_h264->num_ref_idx_l0_active_minus1 = 0;
     slice_h264->num_ref_idx_l1_active_minus1 = 0;
 
-    slice_h264->RefPicList0[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
+    slice_h264->RefPicList0[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
     for (i_pic = 1;
          i_pic < sizeof(slice_h264->RefPicList0)/sizeof(slice_h264->RefPicList0[0]);
          i_pic++) {
       slice_h264->RefPicList0[i_pic].picture_id = VA_INVALID_ID;
     }
 
-    if (SLICE_TYPE_B == h264_prv->cur_slice_type) {
-      slice_h264->RefPicList1[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
+    if (SLICE_TYPE_B == priv->cur_slice_type) {
+      slice_h264->RefPicList1[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
       i_pic = 1;
     } else
       i_pic = 0;
@@ -1143,19 +1032,19 @@ h264_fill_slice_buffers(GstVaapiEncoderH264 *h264_encoder,
     slice_h264->slice_beta_offset_div2 = 2;
 
   }
-  ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
+  ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(encoder)+15)/16);
 
-  if (VA_INVALID_ID != h264_prv->slice_parameter) {
-    vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
-    h264_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
   va_status = vaCreateBuffer(va_dpy,
                              context_id,
                              VAEncSliceParameterBufferType,
-                             sizeof(h264_prv->slice_param_buffers[0]),
-                             h264_encoder->slice_num,
-                             h264_prv->slice_param_buffers,
-                             &h264_prv->slice_parameter);
+                             sizeof(priv->slice_param_buffers[0]),
+                             encoder->slice_num,
+                             priv->slice_param_buffers,
+                             &priv->slice_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        FALSE, "creating slice-parameters buffer failed.");
 
@@ -1164,59 +1053,67 @@ end:
 }
 
 static EncoderStatus
-gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
-                             GstVaapiContext *context, GstVaapiSurface *surface,
-                             guint frame_index, VABufferID coded_buf, gboolean *is_key)
+gst_vaapi_encoder_h264_rendering(
+    GstVaapiBaseEncoder *base,
+    GstVaapiSurface *surface,
+    guint frame_index,
+    VABufferID coded_buf,
+    gboolean *is_key
+)
 {
   EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(base);
+  GstVaapiContext *context = ENCODER_CONTEXT(base);
+  VADisplay va_dpy;
+  VAContextID context_id;
   VABufferID va_buffers[64];
   guint32    va_buffers_count = 0;
   gboolean is_params_ok = TRUE;
-
   gboolean is_locked = FALSE;
 
-  ENCODER_ASSERT(display && context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
-  VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+  ENCODER_ASSERT(context);
+
+  va_dpy = ENCODER_VA_DISPLAY(base);
+  context_id = ENCODER_VA_CONTEXT(base);
 
-  *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
+  *is_key = (priv->cur_slice_type == SLICE_TYPE_I);
 
-  if (!h264_prv->ref_surface1) {
-    h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h264_prv->ref_surface1,
+  if (!priv->ref_surface1) {
+    priv->ref_surface1 = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->ref_surface1,
                          ENCODER_SURFACE_ERR,
                          "reference surface, h264_pop_free_surface failed.");
   }
-  if (!h264_prv->ref_surface2) {
-    h264_prv->ref_surface2 = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h264_prv->ref_surface2,
+  if (!priv->ref_surface2) {
+    priv->ref_surface2 = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->ref_surface2,
                          ENCODER_SURFACE_ERR,
                          "reference surface, h264_pop_free_surface failed.");
   }
-  if (!h264_prv->recon_surface) {
-    h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(h264_prv->recon_surface,
+  if (!priv->recon_surface) {
+    priv->recon_surface = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->recon_surface,
                          ENCODER_SURFACE_ERR,
                          "reconstructed surface, h264_pop_free_surface failed.");
   }
 
-  if (SLICE_TYPE_P == h264_prv->cur_slice_type) {
-    h264_swap_surface(&h264_prv->ref_surface1, &h264_prv->ref_surface2);
+  if (SLICE_TYPE_P == priv->cur_slice_type) {
+    h264_swap_surface(&priv->ref_surface1, &priv->ref_surface2);
   }
 
   /* fill sequence parameters, need set every time */
-  is_params_ok = h264_fill_sequence_buffer(h264_encoder, va_dpy, context_id);
+  is_params_ok = h264_fill_sequence_buffer(encoder);
   ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
                        "h264_recreate_seq_param failed");
   /* set pic_parameters*/
-  is_params_ok = h264_fill_picture_buffer(h264_encoder, va_dpy, context_id, coded_buf);
+  is_params_ok = h264_fill_picture_buffer(encoder, coded_buf);
   ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
                        "h264_recreate_pic_param failed");
   /* set slice parameters, support multiple slices */
-  is_params_ok = h264_fill_slice_buffers(h264_encoder, va_dpy, context_id);
+  is_params_ok = h264_fill_slice_buffers(encoder);
   ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
                        "h264_recreate_slice_param failed");
 
@@ -1224,27 +1121,27 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
 
   /*render all buffers*/
-  if (VA_INVALID_ID != h264_prv->seq_parameter) {
-    va_buffers[va_buffers_count++] = h264_prv->seq_parameter;
+  if (VA_INVALID_ID != priv->seq_parameter) {
+    va_buffers[va_buffers_count++] = priv->seq_parameter;
   }
-  if (VA_INVALID_ID != h264_prv->pic_parameter) {
-    va_buffers[va_buffers_count++] = h264_prv->pic_parameter;
+  if (VA_INVALID_ID != priv->pic_parameter) {
+    va_buffers[va_buffers_count++] = priv->pic_parameter;
   }
-  if (VA_INVALID_ID != h264_prv->slice_parameter) {
-    va_buffers[va_buffers_count++] = h264_prv->slice_parameter;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    va_buffers[va_buffers_count++] = priv->slice_parameter;
   }
-  if (SLICE_TYPE_I == h264_prv->cur_slice_type) {
-    if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
-      va_buffers[va_buffers_count++] = h264_prv->packed_sps_par_buf;
+  if (SLICE_TYPE_I == priv->cur_slice_type) {
+    if (VA_INVALID_ID != priv->packed_sps_par_buf) {
+      va_buffers[va_buffers_count++] = priv->packed_sps_par_buf;
     }
-    if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
-      va_buffers[va_buffers_count++] = h264_prv->packed_sps_data_buf;
+    if (VA_INVALID_ID != priv->packed_sps_data_buf) {
+      va_buffers[va_buffers_count++] = priv->packed_sps_data_buf;
     }
-    if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
-      va_buffers[va_buffers_count++] = h264_prv->packed_pps_par_buf;
+    if (VA_INVALID_ID != priv->packed_pps_par_buf) {
+      va_buffers[va_buffers_count++] = priv->packed_pps_par_buf;
     }
-    if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
-      va_buffers[va_buffers_count++] = h264_prv->packed_pps_data_buf;
+    if (VA_INVALID_ID != priv->packed_pps_data_buf) {
+      va_buffers[va_buffers_count++] = priv->packed_pps_data_buf;
     }
   }
 
@@ -1253,9 +1150,9 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
                        "vaRenderH264Picture failed.");
 
   /*after finished,  swap  recon and surface2*/
-  if (SLICE_TYPE_P == h264_prv->cur_slice_type ||
-      SLICE_TYPE_I == h264_prv->cur_slice_type) {
-    h264_swap_surface(&h264_prv->recon_surface, &h264_prv->ref_surface2);
+  if (SLICE_TYPE_P == priv->cur_slice_type ||
+      SLICE_TYPE_I == priv->cur_slice_type) {
+    h264_swap_surface(&priv->recon_surface, &priv->ref_surface2);
   }
 
   end:
@@ -1266,13 +1163,13 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *
 #endif
 
 static GstBuffer *
-gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
+gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *base,
                                         guint8 *frame,
                                         guint32 frame_size,
                                         VABufferID *coded_buf)
 {
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   GstBuffer *ret_buffer;
   guint32   nal_size;
   const guint8   *nal_start;
@@ -1285,7 +1182,7 @@ gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
   h264_bitstream_align(&bitstream, 0);
   ENCODER_ASSERT(bitstream.bit_size == 0);
 
-  if (!h264_prv->avc_flag) { /*nal format*/
+  if (!priv->avc_flag) { /*nal format*/
     h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
     ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
   } else { /* elementary format */
@@ -1314,7 +1211,7 @@ gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
 }
 
 static EncoderStatus
-h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *h264_prv, const guint8 *buf, guint32 size)
+h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *priv, const guint8 *buf, guint32 size)
 {
   const guint8 *end = buf + size;
   const guint8 *nal_start = buf;
@@ -1333,7 +1230,7 @@ h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *h264_prv, const guint8 *bu
       case NAL_SPS: {
         sps = gst_buffer_new_and_alloc(nal_size);
         memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
-        gst_buffer_replace(&h264_prv->sps_data, sps);
+        gst_buffer_replace(&priv->sps_data, sps);
         gst_buffer_unref(sps); /*don't set to NULL*/
         break;
       }
@@ -1341,7 +1238,7 @@ h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *h264_prv, const guint8 *bu
       case NAL_PPS: {
         pps = gst_buffer_new_and_alloc(nal_size);
         memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
-        gst_buffer_replace(&h264_prv->pps_data, pps);
+        gst_buffer_replace(&priv->pps_data, pps);
         gst_buffer_unref(pps);
         break;
       }
@@ -1359,15 +1256,15 @@ h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *h264_prv, const guint8 *bu
 }
 
 static void
-gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
+gst_h264_notify_frame(GstVaapiBaseEncoder *base, guint8 *buf, guint32 size)
 {
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
-  if (!h264_prv->sps_data || !h264_prv->pps_data) {
-    h264_encoder_read_sps_pps(h264_prv, buf, size);
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
+  if (!priv->sps_data || !priv->pps_data) {
+    h264_encoder_read_sps_pps(priv, buf, size);
   }
-  if (h264_prv->sps_data && h264_prv->pps_data) {
-    gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
+  if (priv->sps_data && priv->pps_data) {
+    gst_vaapi_base_encoder_set_frame_notify(base, FALSE);
   }
 }
 
@@ -1390,40 +1287,45 @@ h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
 
 
 static EncoderStatus
-gst_vaapi_encoder_h264_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                       GstVaapiContext *context, GList **coded_pics)
+gst_vaapi_encoder_h264_flush(
+    GstVaapiEncoder* base,
+    GList **coded_pics
+)
 {
-  GstVaapiEncoderH264* h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
+  GstVaapiEncoderH264* encoder = GST_VAAPI_ENCODER_H264_CAST(base);
   EncoderStatus ret = ENCODER_NO_ERROR;
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
 
-  //h264_prv->frame_count = 0;
-  h264_prv->cur_display_num = 0;
-  h264_prv->cur_decode_num = 0;
-  h264_prv->cur_slice_type = SLICE_TYPE_I;
-  h264_prv->gop_count = g_queue_get_length(h264_prv->queued_buffers);
+  //priv->frame_count = 0;
+  priv->cur_display_num = 0;
+  priv->cur_decode_num = 0;
+  priv->cur_slice_type = SLICE_TYPE_I;
+  priv->gop_count = g_queue_get_length(priv->queued_buffers);
   //gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
 
   //end:
   return ret;
 }
 
-EncoderStatus
-gst_vaapi_encoder_h264_get_avcC_codec_data(GstVaapiEncoderH264 *h264_encoder, GstBuffer **buffer)
+static EncoderStatus
+gst_vaapi_encoder_h264_get_avcC_codec_data(
+    GstVaapiEncoderH264 *encoder,
+    GstBuffer **buffer
+)
 {
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264Private *priv = encoder->priv;
   GstBuffer *avc_codec;
   const guint32 configuration_version = 0x01;
   const guint32 length_size_minus_one = 0x03;
   guint32 profile, profile_comp, level_idc;
 
   ENCODER_ASSERT(buffer);
-  if (!h264_prv->sps_data || !h264_prv->pps_data) {
+  if (!priv->sps_data || !priv->pps_data) {
     return ENCODER_DATA_NOT_READY;
   }
 
-  if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(h264_prv->sps_data),
-                                   GST_BUFFER_SIZE(h264_prv->sps_data),
+  if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(priv->sps_data),
+                                   GST_BUFFER_SIZE(priv->sps_data),
                                    &profile, &profile_comp, &level_idc))
   {
     ENCODER_ASSERT(0);
@@ -1432,7 +1334,7 @@ gst_vaapi_encoder_h264_get_avcC_codec_data(GstVaapiEncoderH264 *h264_encoder, Gs
 
   H264Bitstream bitstream;
   h264_bitstream_init(&bitstream,
-                     (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 32)*8);
+                     (GST_BUFFER_SIZE(priv->sps_data)+GST_BUFFER_SIZE(priv->pps_data) + 32)*8);
 
   /*codec_data*/
   h264_bitstream_write_uint(&bitstream, configuration_version, 8);
@@ -1446,15 +1348,15 @@ gst_vaapi_encoder_h264_get_avcC_codec_data(GstVaapiEncoderH264 *h264_encoder, Gs
   /*write sps*/
   h264_bitstream_write_uint(&bitstream, 1, 5);   /* sps count = 1*/
   ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
-  h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->sps_data), 16);
-  h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
-                                              GST_BUFFER_SIZE(h264_prv->sps_data));
+  h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(priv->sps_data), 16);
+  h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(priv->sps_data),
+                                              GST_BUFFER_SIZE(priv->sps_data));
 
   /*write pps*/
   h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
-  h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->pps_data), 16);
-  h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
-                                              GST_BUFFER_SIZE(h264_prv->pps_data));
+  h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(priv->pps_data), 16);
+  h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(priv->pps_data),
+                                              GST_BUFFER_SIZE(priv->pps_data));
 
   avc_codec = gst_buffer_new();
   GST_BUFFER_MALLOCDATA(avc_codec) =
@@ -1468,17 +1370,126 @@ gst_vaapi_encoder_h264_get_avcC_codec_data(GstVaapiEncoderH264 *h264_encoder, Gs
 }
 
 static EncoderStatus
-gst_vaapi_encoder_h264_get_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer)
+gst_vaapi_encoder_h264_get_codec_data(
+    GstVaapiEncoder* base,
+    GstBuffer **buffer)
 {
-  GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
-  GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+  GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+  GstVaapiEncoderH264Private *priv = encoder->priv;
 
-  if (h264_prv->avc_flag)
-    return gst_vaapi_encoder_h264_get_avcC_codec_data(h264_encoder, buffer);
+  if (priv->avc_flag)
+    return gst_vaapi_encoder_h264_get_avcC_codec_data(encoder, buffer);
   return ENCODER_NO_DATA;
 }
 
 static void
+gst_vaapi_encoder_h264_init(GstVaapiEncoderH264 *encoder)
+{
+  GstVaapiEncoderH264Private *priv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder);
+  ENCODER_ASSERT(priv);
+  priv->public = encoder;
+  encoder->priv = priv;
+
+  /* init public attributes */
+  gst_vaapi_encoder_h264_init_public_values(encoder);
+  gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
+
+  /* init private values*/
+  priv->format = GST_MAKE_FOURCC('N','V','1','2');
+  priv->avc_flag = FALSE;
+
+  priv->ref_surface1 = NULL;
+  priv->ref_surface2 = NULL;
+  priv->recon_surface = NULL;
+
+  priv->seq_parameter = VA_INVALID_ID;
+  priv->pic_parameter = VA_INVALID_ID;
+  priv->slice_parameter = VA_INVALID_ID;
+  priv->packed_sps_par_buf = VA_INVALID_ID;
+  priv->packed_sps_data_buf = VA_INVALID_ID;
+  priv->packed_pps_par_buf = VA_INVALID_ID;
+  priv->packed_pps_data_buf = VA_INVALID_ID;
+  priv->slice_param_buffers = NULL;
+  priv->default_slice_height = 0;
+  priv->slice_mod_mb_num = 0;
+
+  priv->sps_data = NULL;
+  priv->pps_data = NULL;
+
+  priv->queued_buffers = g_queue_new();
+  priv->gop_count = 0;
+  priv->cur_display_num = 0;
+  priv->cur_decode_num = 0;
+  priv->cur_slice_type = SLICE_TYPE_I;
+  priv->last_decode_time = 0LL;
+  priv->default_cts_offset = 0;
+
+  priv->max_frame_num = 0;
+  priv->max_pic_order_cnt = 0;
+  priv->idr_num = 0;
+}
+
+static void
+gst_vaapi_encoder_h264_finalize(GObject *object)
+{
+  /*free private buffers*/
+  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+  GstVaapiEncoderH264Private *priv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(object);
+
+  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+    gst_vaapi_encoder_uninitialize(encoder);
+  }
+
+  if (priv->sps_data) {
+    gst_buffer_unref(priv->sps_data);
+    priv->sps_data = NULL;
+  }
+  if (priv->pps_data) {
+    gst_buffer_unref(priv->pps_data);
+    priv->pps_data = NULL;
+  }
+  if (priv->slice_param_buffers) {
+    g_free(priv->slice_param_buffers);
+    priv->slice_param_buffers = NULL;
+  }
+
+  if (priv->queued_buffers) {
+    ENCODER_ASSERT(g_queue_is_empty(priv->queued_buffers));
+    g_queue_free(priv->queued_buffers);
+    priv->queued_buffers = NULL;
+  }
+
+  G_OBJECT_CLASS(gst_vaapi_encoder_h264_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_h264_class_init(GstVaapiEncoderH264Class *klass)
+{
+  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+  GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+
+  g_type_class_add_private(klass, sizeof(GstVaapiEncoderH264Private));
+
+  GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
+      "gst_va_h264_encoder element");
+
+  object_class->finalize = gst_vaapi_encoder_h264_finalize;
+
+  base_class->validate_attributes = gst_h264_validate_parameters;
+  base_class->pre_alloc_resource  = gst_vaapi_encoder_h264_alloc_slices;
+  base_class->release_resource    = gst_vaapi_encoder_h264_release_resource;
+  base_class->prepare_next_input_buffer = gst_vaapi_encoder_h264_prepare_next_buffer;
+  base_class->render_frame = gst_vaapi_encoder_h264_rendering;
+  base_class->notify_frame = gst_h264_notify_frame;
+  base_class->copy_coded_frame = gst_vaapi_encoder_h264_copy_coded_buffer;
+  base_class->encode_frame_failed = gst_vaapi_encoder_h264_frame_failed;
+
+  encoder_class->flush = gst_vaapi_encoder_h264_flush;
+  encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data;
+}
+
+static void
 h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
 {
   bitstream->bit_size = 0;
index 192fc90..94721b6 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg4_encoder_debug);
 #define GST_CAT_DEFAULT gst_vaapi_mpeg4_encoder_debug
 
+#define GST_VAAPI_ENCODER_MPEG4_CAST(encoder)    ((GstVaapiEncoderMpeg4 *)(encoder))
+
+#define VISUAL_OBJECT_SEQUENCE_START_CODE  0x000001B0
+#define VISUAL_OBJECT_SEQUENCE_END_CODE    0x000001B1
+#define VISUAL_OBJECT_START_CODE           0x000001B5
+#define VIDEO_OBJECT_PLANE_START_CODE      0x000001B6
+/* Video Object Start Code range */
+#define VIDEO_OBJECT_START_CODE_MIN        0x00000100
+#define VIDEO_OBJECT_START_CODE_MAX        0x0000011F
+/* Video Object Layer Start Code range 0x00000120 ~ 0x0000012F*/
+#define VIDEO_OBJECT_LAYER_START_CODE      0x00000120
+#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0
+
 
 struct _GstVaapiEncoderMpeg4Private {
   GstVaapiSurface  *ref_surface;  /* reference buffer*/
@@ -48,190 +61,97 @@ struct _GstVaapiEncoderMpeg4Private {
 
 G_DEFINE_TYPE(GstVaapiEncoderMpeg4, gst_vaapi_encoder_mpeg4, GST_TYPE_VAAPI_BASE_ENCODER);
 
-/*
-static EncoderStatus gst_vaapi_encoder_mpeg4_flush(GstVaapiEncoder* encoder,
-                         GstVaapiDisplay *display, GstVaapiContext *context,
-                         GList **coded_pics);
-*/
-static EncoderStatus gst_vaapi_encoder_mpeg4_get_codec_data(
-                         GstVaapiEncoder *encoder, GstBuffer **buffer);
-static gboolean      gst_mpeg4_validate_parameters(GstVaapiBaseEncoder *encoder);
-static gboolean      gst_vaapi_encoder_mpeg4_release_resource(
-                         GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display,
-                         GstVaapiContext *context);
-static void          gst_mpeg4_notify_frame(GstVaapiBaseEncoder *encoder,
-                         guint8 *buf, guint32 size);
-
-static EncoderStatus gst_vaapi_encoder_mpeg4_rendering(GstVaapiBaseEncoder *encoder,
-                       GstVaapiDisplay *display, GstVaapiContext *context,
-                       GstVaapiSurface *surface, guint frame_index,
-                       VABufferID coded_buf, gboolean *is_key);
-
-
-static void          gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass);
-static void          gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *encoder);
-static void          gst_vaapi_encoder_mpeg4_finalize(GObject *object);
-
-static gboolean      mpeg4_encoder_generate_codec_data(const guint8 *in_buffer,
-                                          guint32 in_size, GstBuffer **out_buffer);
-
 GstVaapiEncoderMpeg4 *
 gst_vaapi_encoder_mpeg4_new(void)
 {
-  return GST_VAAPI_ENCODER_MPEG4(g_object_new(GST_TYPE_VAAPI_ENCODER_MPEG4, NULL));
-}
-
-
-static void
-gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass)
-{
-  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
-  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
-  GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
-
-  g_type_class_add_private(klass, sizeof(GstVaapiEncoderMpeg4Private));
-
-  GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg4_encoder_debug, "gst_va_mpeg4_encoder", 0,
-      "gst_va_mpeg4_encoder element");
-
-  object_class->finalize = gst_vaapi_encoder_mpeg4_finalize;
-
-  base_class->validate_attributes = gst_mpeg4_validate_parameters;
-  base_class->pre_alloc_resource  = NULL;
-  base_class->release_resource    = gst_vaapi_encoder_mpeg4_release_resource;
-  base_class->render_frame = gst_vaapi_encoder_mpeg4_rendering;
-  base_class->notify_frame = gst_mpeg4_notify_frame;
-  base_class->copy_coded_frame = NULL;
-
-  /*
-  encoder_class->flush = gst_vaapi_encoder_mpeg4_flush;
-  */
-  encoder_class->get_codec_data = gst_vaapi_encoder_mpeg4_get_codec_data;
-}
-
-static void
-gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *mpeg4_encoder)
-{
-  GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
-  ENCODER_ASSERT(mpeg4_prv);
-
-  /* init public */
-  mpeg4_encoder->profile = VAProfileMPEG4Simple;
-  mpeg4_encoder->bitrate = 0;
-  mpeg4_encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
-  mpeg4_encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
-  mpeg4_encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
-
-  gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(mpeg4_encoder), TRUE);
-  /* init private */
-  mpeg4_prv->ref_surface = NULL;
-  mpeg4_prv->recon_surface = NULL;
-
-  mpeg4_prv->seq_parameter = VA_INVALID_ID;
-  mpeg4_prv->pic_parameter = VA_INVALID_ID;
-  mpeg4_prv->slice_parameter = VA_INVALID_ID;
-
-  mpeg4_prv->codec_data = NULL;
-}
-
-static void
-gst_vaapi_encoder_mpeg4_finalize(GObject *object)
-{
-  /*free private buffers*/
-  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
-
-  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
-    gst_vaapi_encoder_uninitialize(encoder);
-  }
-  G_OBJECT_CLASS(gst_vaapi_encoder_mpeg4_parent_class)->finalize(object);
+  return GST_VAAPI_ENCODER_MPEG4_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_MPEG4, NULL));
 }
 
 gboolean
-gst_mpeg4_validate_parameters(GstVaapiBaseEncoder *encoder)
+gst_mpeg4_validate_parameters(GstVaapiBaseEncoder *base)
 {
-  GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
-  if (!ENCODER_WIDTH(mpeg4_encoder) || !ENCODER_HEIGHT(mpeg4_encoder) || !ENCODER_FPS(mpeg4_encoder)) {
+  GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+  if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
     return FALSE;
   }
-  if (VAProfileMPEG4Simple != mpeg4_encoder->profile && VAProfileMPEG4AdvancedSimple != mpeg4_encoder->profile) {
+  if (VAProfileMPEG4Simple != encoder->profile && VAProfileMPEG4AdvancedSimple != encoder->profile) {
     return FALSE;
   }
-  gst_vaapi_base_encoder_set_va_profile(encoder, mpeg4_encoder->profile);
+  gst_vaapi_base_encoder_set_va_profile(base, encoder->profile);
 
-  if (!mpeg4_encoder->intra_period) {
-    mpeg4_encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
+  if (!encoder->intra_period) {
+    encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
   }
-  if (-1 == mpeg4_encoder->init_qp) {
-    mpeg4_encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
+  if (-1 == encoder->init_qp) {
+    encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
   }
-  if (-1 == mpeg4_encoder->min_qp) {
-    mpeg4_encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
+  if (-1 == encoder->min_qp) {
+    encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
   }
 
   /* default compress ratio 1: (4*8*1.5) */
-  if (!mpeg4_encoder->bitrate) {
-    mpeg4_encoder->bitrate = ENCODER_WIDTH(mpeg4_encoder)*ENCODER_HEIGHT(mpeg4_encoder)*ENCODER_FPS(mpeg4_encoder)/4;
+  if (!encoder->bitrate) {
+    encoder->bitrate = ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
   }
   return TRUE;
 
 }
 
 static void
-mpeg4_release_parameters(GstVaapiEncoderMpeg4 *mpeg4_encoder, GstVaapiDisplay *display)
+mpeg4_release_parameters(GstVaapiEncoderMpeg4 *encoder)
 {
-  GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
+  GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+  VADisplay va_dpy = ENCODER_DISPLAY(encoder);
   VAStatus va_status = VA_STATUS_SUCCESS;
 
   VAAPI_UNUSED_ARG(va_status);
 
-  if (VA_INVALID_ID != mpeg4_prv->seq_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->seq_parameter);
-    mpeg4_prv->seq_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->seq_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->seq_parameter);
+    priv->seq_parameter = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != mpeg4_prv->pic_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->pic_parameter);
-    mpeg4_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
-  if (VA_INVALID_ID != mpeg4_prv->slice_parameter) {
-    va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->slice_parameter);
-    mpeg4_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    va_status = vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
 }
 
 static gboolean
-gst_vaapi_encoder_mpeg4_release_resource(GstVaapiBaseEncoder* encoder,
-                       GstVaapiDisplay *display,
-                       GstVaapiContext *context)
+gst_vaapi_encoder_mpeg4_release_resource(GstVaapiBaseEncoder* base)
 {
-  GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
-  GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
+  GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+  GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+  GstVaapiContext *context = ENCODER_CONTEXT(base);
 
-  mpeg4_release_parameters(mpeg4_encoder, display);
+  mpeg4_release_parameters(encoder);
 
   /*remove ref_surface*/
-  if (mpeg4_prv->ref_surface) {
+  if (priv->ref_surface) {
     if (context) {
-      gst_vaapi_context_put_surface(context, mpeg4_prv->ref_surface);
+      gst_vaapi_context_put_surface(context, priv->ref_surface);
     } else {
-      g_object_unref(mpeg4_prv->ref_surface);
+      g_object_unref(priv->ref_surface);
     }
-    mpeg4_prv->ref_surface = NULL;
+    priv->ref_surface = NULL;
   }
 
   /*remove recon_surface*/
-  if (mpeg4_prv->recon_surface) {
+  if (priv->recon_surface) {
     if (context) {
-      gst_vaapi_context_put_surface(context, mpeg4_prv->recon_surface);
+      gst_vaapi_context_put_surface(context, priv->recon_surface);
     } else {
-      g_object_unref(mpeg4_prv->recon_surface);
+      g_object_unref(priv->recon_surface);
     }
-    mpeg4_prv->recon_surface = NULL;
+    priv->recon_surface = NULL;
   }
 
-  if (mpeg4_prv->codec_data) {
-    gst_buffer_unref(mpeg4_prv->codec_data);
-    mpeg4_prv->codec_data = NULL;
+  if (priv->codec_data) {
+    gst_buffer_unref(priv->codec_data);
+    priv->codec_data = NULL;
   }
 
   return TRUE;
@@ -253,101 +173,106 @@ mpeg4_get_profile_level_indication(guint32 profile)
 
 
 static EncoderStatus
-gst_vaapi_encoder_mpeg4_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
-                       GstVaapiContext *context, GstVaapiSurface *surface,
-                       guint frame_index, VABufferID coded_buf, gboolean *is_key)
+gst_vaapi_encoder_mpeg4_rendering(
+    GstVaapiBaseEncoder *base,
+    GstVaapiSurface *surface,
+    guint frame_index,
+    VABufferID coded_buf,
+    gboolean *is_key
+)
 {
-  GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
-  GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
-  VADisplay va_dpy = gst_vaapi_display_get_display(display);
-  VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+  GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+  GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+  GstVaapiContext *context = ENCODER_CONTEXT(base);
+  VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+  VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
 
   VAStatus va_status = VA_STATUS_SUCCESS;
   EncoderStatus ret = ENCODER_NO_ERROR;
 
-  *is_key = (frame_index % mpeg4_encoder->intra_period == 0);
+  *is_key = (frame_index % encoder->intra_period == 0);
 
   /* initialize sequence parameter set, only first time */
-  if (VA_INVALID_ID == mpeg4_prv->seq_parameter) { /*only the first time*/
+  if (VA_INVALID_ID == priv->seq_parameter) { /*only the first time*/
     VAEncSequenceParameterBufferMPEG4 seq_mpeg4 = {0};
 
-    seq_mpeg4.profile_and_level_indication = mpeg4_get_profile_level_indication(mpeg4_encoder->profile);
-    seq_mpeg4.intra_period = mpeg4_encoder->intra_period;
-    seq_mpeg4.video_object_layer_width = ENCODER_WIDTH(mpeg4_encoder);
-    seq_mpeg4.video_object_layer_height = ENCODER_HEIGHT(mpeg4_encoder);
-    seq_mpeg4.vop_time_increment_resolution = ENCODER_FPS(mpeg4_encoder);
+    seq_mpeg4.profile_and_level_indication = mpeg4_get_profile_level_indication(encoder->profile);
+    seq_mpeg4.intra_period = encoder->intra_period;
+    seq_mpeg4.video_object_layer_width = ENCODER_WIDTH(encoder);
+    seq_mpeg4.video_object_layer_height = ENCODER_HEIGHT(encoder);
+    seq_mpeg4.vop_time_increment_resolution = ENCODER_FPS(encoder);
     seq_mpeg4.fixed_vop_rate = MPEG4_DEFAULT_FIXED_VOP_RATE;
     if (seq_mpeg4.fixed_vop_rate) {
       seq_mpeg4.fixed_vop_time_increment = 1;
     }
-    seq_mpeg4.bits_per_second = mpeg4_encoder->bitrate;
-    seq_mpeg4.frame_rate = ENCODER_FPS(mpeg4_encoder);
-    seq_mpeg4.initial_qp = mpeg4_encoder->init_qp;
-    seq_mpeg4.min_qp = mpeg4_encoder->min_qp; //mpeg4_encoder->min_qp;
+    seq_mpeg4.bits_per_second = encoder->bitrate;
+    seq_mpeg4.frame_rate = ENCODER_FPS(encoder);
+    seq_mpeg4.initial_qp = encoder->init_qp;
+    seq_mpeg4.min_qp = encoder->min_qp; //mpeg4_encoder->min_qp;
 
     va_status = vaCreateBuffer(va_dpy, context_id,
                                VAEncSequenceParameterBufferType,
-                               sizeof(seq_mpeg4), 1, &seq_mpeg4, &mpeg4_prv->seq_parameter);
+                               sizeof(seq_mpeg4), 1, &seq_mpeg4, &priv->seq_parameter);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          ENCODER_ENC_RES_ERR, "mpeg4 alloc seq-buffer failed.");
-    va_status = vaRenderPicture(va_dpy, context_id, &mpeg4_prv->seq_parameter, 1);
+    va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_parameter, 1);
     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
                          ENCODER_PICTURE_ERR,
                          "mpeg4 vaRenderPicture seq-parameters failed.");
   }
 
   /* set reference and reconstructed surfaces */
-  if (!mpeg4_prv->ref_surface) {
-    mpeg4_prv->ref_surface = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(mpeg4_prv->ref_surface,
+  if (!priv->ref_surface) {
+    priv->ref_surface = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->ref_surface,
                          ENCODER_SURFACE_ERR,
                          "mpeg4 reference surface, mpeg4_pop_free_surface failed.");
   }
-  if (!mpeg4_prv->recon_surface) {
-    mpeg4_prv->recon_surface = gst_vaapi_context_get_surface(context);
-    ENCODER_CHECK_STATUS(mpeg4_prv->recon_surface,
+  if (!priv->recon_surface) {
+    priv->recon_surface = gst_vaapi_context_get_surface(context);
+    ENCODER_CHECK_STATUS(priv->recon_surface,
                          ENCODER_SURFACE_ERR,
                          "mpeg4 reconstructed surface, mpeg4_pop_free_surface failed.");
   }
 
   /* initialize picture, every time, every frame */
   VAEncPictureParameterBufferMPEG4 pic_mpeg4 = {0};
-  pic_mpeg4.reference_picture = GST_VAAPI_OBJECT_ID(mpeg4_prv->ref_surface);
-  pic_mpeg4.reconstructed_picture = GST_VAAPI_OBJECT_ID(mpeg4_prv->recon_surface);
+  pic_mpeg4.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface);
+  pic_mpeg4.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
   pic_mpeg4.coded_buf = coded_buf;
-  pic_mpeg4.picture_width = ENCODER_WIDTH(mpeg4_encoder);
-  pic_mpeg4.picture_height = ENCODER_HEIGHT(mpeg4_encoder);
+  pic_mpeg4.picture_width = ENCODER_WIDTH(encoder);
+  pic_mpeg4.picture_height = ENCODER_HEIGHT(encoder);
   if (0 == frame_index) {
     pic_mpeg4.modulo_time_base = 0;
   } else {
-    pic_mpeg4.modulo_time_base = ((frame_index%ENCODER_FPS(mpeg4_encoder)) == 0 ? 1 : 0);
+    pic_mpeg4.modulo_time_base = ((frame_index%ENCODER_FPS(encoder)) == 0 ? 1 : 0);
   }
-  pic_mpeg4.vop_time_increment = 301%ENCODER_FPS(mpeg4_encoder);
+  pic_mpeg4.vop_time_increment = 301%ENCODER_FPS(encoder);
   pic_mpeg4.picture_type = *is_key ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
 
-  if (VA_INVALID_ID != mpeg4_prv->pic_parameter) { /* destroy first*/
-    va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->pic_parameter);
-    mpeg4_prv->pic_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->pic_parameter) { /* destroy first*/
+    va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+    priv->pic_parameter = VA_INVALID_ID;
   }
 
   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
-                               sizeof(pic_mpeg4), 1, &pic_mpeg4, &mpeg4_prv->pic_parameter);
+                               sizeof(pic_mpeg4), 1, &pic_mpeg4, &priv->pic_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_ENC_RES_ERR,
                        "mpeg4 creating pic-param buffer failed.");
-  va_status = vaRenderPicture(va_dpy, context_id, &mpeg4_prv->pic_parameter, 1);
+  va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_parameter, 1);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR,
                        "mpeg4 rendering pic-param buffer failed.");
   /*initialize slice parameters, only ONE slice for mpeg4*/
   VAEncSliceParameterBuffer slice_mpeg4 = { 0 };
   slice_mpeg4.start_row_number = 0;
-  slice_mpeg4.slice_height = (ENCODER_HEIGHT(mpeg4_encoder)+15)/16; /*MB?*/
+  slice_mpeg4.slice_height = (ENCODER_HEIGHT(encoder)+15)/16; /*MB?*/
   slice_mpeg4.slice_flags.bits.is_intra = *is_key;
   slice_mpeg4.slice_flags.bits.disable_deblocking_filter_idc = 0;
-  if (VA_INVALID_ID != mpeg4_prv->slice_parameter) {
-    vaDestroyBuffer(va_dpy, mpeg4_prv->slice_parameter);
-    mpeg4_prv->slice_parameter = VA_INVALID_ID;
+  if (VA_INVALID_ID != priv->slice_parameter) {
+    vaDestroyBuffer(va_dpy, priv->slice_parameter);
+    priv->slice_parameter = VA_INVALID_ID;
   }
 
   va_status = vaCreateBuffer(va_dpy,
@@ -356,20 +281,20 @@ gst_vaapi_encoder_mpeg4_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay
                              sizeof(slice_mpeg4),
                              1,
                              &slice_mpeg4,
-                             &mpeg4_prv->slice_parameter);
+                             &priv->slice_parameter);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_ENC_RES_ERR,
                        "mpeg4 creating slice-parameters buffer failed.");
 
-  va_status = vaRenderPicture(va_dpy, context_id, &mpeg4_prv->slice_parameter, 1);
+  va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_parameter, 1);
   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
                        ENCODER_PICTURE_ERR,
                        "mpeg4 rendering slice-parameters buffer failed.");
 
   /*swap ref_surface and recon_surface */
-  GstVaapiSurface *swap = mpeg4_prv->ref_surface;
-  mpeg4_prv->ref_surface = mpeg4_prv->recon_surface;
-  mpeg4_prv->recon_surface = swap;
+  GstVaapiSurface *swap = priv->ref_surface;
+  priv->ref_surface = priv->recon_surface;
+  priv->recon_surface = swap;
 
 end:
   return ret;
@@ -386,7 +311,7 @@ gst_vaapi_encoder_mpeg4_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
   memcpy(GST_BUFFER_DATA(buffer), frame, frame_size);
 
   #if 0
-  GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
+  GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4_CAST(encoder);
   if (mpeg4_encoder->profile == VAProfileMPEG4AdvancedSimple) {
     guint8 *start_code = GST_BUFFER_DATA(buffer)+16; /*fix old issue of ASP in mrst platform*/
     if (start_code[0] == 0x01 && start_code[1] == 0x20
@@ -401,55 +326,6 @@ gst_vaapi_encoder_mpeg4_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
 }
 #endif
 
-static void
-gst_mpeg4_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
-{
-  GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
-  if (!mpeg4_prv->codec_data) {
-    if (!mpeg4_encoder_generate_codec_data(buf, size, &mpeg4_prv->codec_data)) {
-      ENCODER_LOG_ERROR("mpeg4 encoder coded data error, please check <mpeg4_encoder_generate_codec_data>.");
-    }
-  }
-  if (mpeg4_prv->codec_data) {
-    gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
-  }
-}
-
-
-static EncoderStatus
-gst_vaapi_encoder_mpeg4_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
-                       GstVaapiContext *context, GList **coded_pics)
-{
-  GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
-
-  mpeg4_release_parameters(mpeg4_encoder, display);
-  return ENCODER_NO_ERROR;
-}
-
-
-static EncoderStatus
-gst_vaapi_encoder_mpeg4_get_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
-{
-  GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
-
-  if (!mpeg4_prv->codec_data)
-    return ENCODER_DATA_NOT_READY;
-  *buffer = gst_buffer_ref(mpeg4_prv->codec_data);
-  return ENCODER_NO_ERROR;
-}
-
-#define VISUAL_OBJECT_SEQUENCE_START_CODE  0x000001B0
-#define VISUAL_OBJECT_SEQUENCE_END_CODE    0x000001B1
-#define VISUAL_OBJECT_START_CODE           0x000001B5
-#define VIDEO_OBJECT_PLANE_START_CODE      0x000001B6
-/* Video Object Start Code range */
-#define VIDEO_OBJECT_START_CODE_MIN        0x00000100
-#define VIDEO_OBJECT_START_CODE_MAX        0x0000011F
-/* Video Object Layer Start Code range 0x00000120 ~ 0x0000012F*/
-#define VIDEO_OBJECT_LAYER_START_CODE      0x00000120
-#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0
-
-
 static gboolean
 find_video_object_configuration_info(const guint8 *in_buffer, guint32 in_size,
                                      const guint8 **out_buffer, guint32 *out_size)
@@ -481,13 +357,21 @@ find_video_object_configuration_info(const guint8 *in_buffer, guint32 in_size,
 }
 
 static gboolean
-mpeg4_encoder_generate_codec_data(const guint8 *in_buffer, guint32 in_size, GstBuffer **out_buffer)
+mpeg4_encoder_generate_codec_data(
+    const guint8 *in_buffer,
+    guint32 in_size,
+    GstBuffer **out_buffer
+)
 {
   const guint8 *codec_buffer = NULL;
   guint32 codec_size = 0;
   guint8 *visual_obj_seq_end = NULL;
 
-  if (!find_video_object_configuration_info(in_buffer, in_size, &codec_buffer, &codec_size)) {
+  if (!find_video_object_configuration_info(in_buffer,
+                                            in_size,
+                                            &codec_buffer,
+                                            &codec_size)
+     ) {
     return FALSE;
   }
   ENCODER_ASSERT(codec_size);
@@ -501,3 +385,105 @@ mpeg4_encoder_generate_codec_data(const guint8 *in_buffer, guint32 in_size, GstB
   return TRUE;
 }
 
+static void
+gst_mpeg4_notify_frame(GstVaapiBaseEncoder *base, guint8 *buf, guint32 size)
+{
+  GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+  GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+  if (!priv->codec_data) {
+    if (!mpeg4_encoder_generate_codec_data(buf, size, &priv->codec_data)) {
+      ENCODER_LOG_ERROR("mpeg4 encoder coded data error, please check <mpeg4_encoder_generate_codec_data>.");
+    }
+  }
+  if (priv->codec_data) {
+    gst_vaapi_base_encoder_set_frame_notify(base, FALSE);
+  }
+}
+
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_flush(
+    GstVaapiEncoder* base,
+    GList **coded_pics)
+{
+  GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+
+  mpeg4_release_parameters(encoder);
+  return ENCODER_NO_ERROR;
+}
+
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_get_codec_data(GstVaapiEncoder *base, GstBuffer **buffer)
+{
+  GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+  GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+
+  if (!priv->codec_data)
+    return ENCODER_DATA_NOT_READY;
+  *buffer = gst_buffer_ref(priv->codec_data);
+  return ENCODER_NO_ERROR;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *encoder)
+{
+  GstVaapiEncoderMpeg4Private *priv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
+  ENCODER_ASSERT(priv);
+  encoder->priv = priv;
+
+  /* init public */
+  encoder->profile = VAProfileMPEG4Simple;
+  encoder->bitrate = 0;
+  encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
+  encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
+  encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
+
+  gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
+  /* init private */
+  priv->ref_surface = NULL;
+  priv->recon_surface = NULL;
+
+  priv->seq_parameter = VA_INVALID_ID;
+  priv->pic_parameter = VA_INVALID_ID;
+  priv->slice_parameter = VA_INVALID_ID;
+
+  priv->codec_data = NULL;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_finalize(GObject *object)
+{
+  /*free private buffers*/
+  GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+
+  if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+    gst_vaapi_encoder_uninitialize(encoder);
+  }
+  G_OBJECT_CLASS(gst_vaapi_encoder_mpeg4_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass)
+{
+  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+  GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+
+  g_type_class_add_private(klass, sizeof(GstVaapiEncoderMpeg4Private));
+
+  GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg4_encoder_debug, "gst_va_mpeg4_encoder", 0,
+      "gst_va_mpeg4_encoder element");
+
+  object_class->finalize = gst_vaapi_encoder_mpeg4_finalize;
+
+  base_class->validate_attributes = gst_mpeg4_validate_parameters;
+  base_class->pre_alloc_resource  = NULL;
+  base_class->release_resource    = gst_vaapi_encoder_mpeg4_release_resource;
+  base_class->render_frame = gst_vaapi_encoder_mpeg4_rendering;
+  base_class->notify_frame = gst_mpeg4_notify_frame;
+  base_class->copy_coded_frame = NULL;
+
+  encoder_class->flush = gst_vaapi_encoder_mpeg4_flush;
+  encoder_class->get_codec_data = gst_vaapi_encoder_mpeg4_get_codec_data;
+}
index c265646..a5b85d1 100644 (file)
@@ -58,6 +58,8 @@ struct _GstVaapiEncoderMpeg4 {
   guint32   intra_period;
   guint32   init_qp;  /*default 15, 1~31*/
   guint32   min_qp;   /*default 1, 1~31*/
+
+  GstVaapiEncoderMpeg4Private *priv;
 };
 
 struct _GstVaapiEncoderMpeg4Class {