extract vaapiencoder structure to make other encoders possible
authorWind Yuan <feng.yuan@intel.com>
Mon, 10 Oct 2011 02:24:02 +0000 (10:24 +0800)
committerZhong Cong <congx.zhong@intel.com>
Tue, 5 Feb 2013 07:37:11 +0000 (15:37 +0800)
gst/vaapiencode/gsth264encode.c [deleted file]
gst/vaapiencode/gsth264encode.h [deleted file]
gst/vaapiencode/gstvaapiencode.h
gst/vaapiencode/h264encoder.c
gst/vaapiencode/h264encoder.h

diff --git a/gst/vaapiencode/gsth264encode.c b/gst/vaapiencode/gsth264encode.c
deleted file mode 100644 (file)
index b183605..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-#include "gsth264encode.h"
-
-#include <string.h>
-#include <X11/Xlib.h>
-
-#include "gst/vaapi/gstvaapivideobuffer.h"
-
-
-#define PACKAGE "libgsth264encode"
-#define VERSION "0.1.0"
-
-#define GST_H264_ENCODE_CHECK_STATUS(exp, err_num, err_reason, ...)  \
-  H264_ASSERT(exp);                             \
-  if (!(exp)) {                                 \
-    ret_num = err_num;                              \
-    H264_LOG_ERROR(err_reason, ## __VA_ARGS__);                 \
-    goto finish;                                 \
-  }
-
-
-#define GST_H264ENCODE_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_H264ENCODE, GstH264EncodePrivate))
-
-typedef struct _GstH264EncodePrivate GstH264EncodePrivate;
-
-static const GstElementDetails gst_h264encode_details =
-    GST_ELEMENT_DETAILS(
-        "VA-API h264 encoder",
-        "Codec/Encoder/Video",
-        "A VA-API based h264 encoder",
-        "Yuan Feng <feng.yuan@intel.com>");
-
-/* Default templates */
-#define GST_CAPS_CODEC(CODEC)                   \
-    CODEC ", "                                  \
-    "width  = (int) [ 1, MAX ], "               \
-    "height = (int) [ 1, MAX ]; "
-
-static const char gst_h264encode_sink_caps_str[] =
-    GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { I420 } ")
-    GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { NV12 } ")
-    GST_CAPS_CODEC("video/x-vaapi-surface ")
-    ;
-
-static const char gst_h264encode_src_caps_str[] =
-    GST_CAPS_CODEC("video/x-h264");
-
-static GstStaticPadTemplate gst_h264encode_sink_factory =
-    GST_STATIC_PAD_TEMPLATE(
-        "sink",
-        GST_PAD_SINK,
-        GST_PAD_ALWAYS,
-        GST_STATIC_CAPS(gst_h264encode_sink_caps_str));
-
-static GstStaticPadTemplate gst_h264encode_src_factory =
-    GST_STATIC_PAD_TEMPLATE(
-        "src",
-        GST_PAD_SRC,
-        GST_PAD_ALWAYS,
-        GST_STATIC_CAPS(gst_h264encode_src_caps_str));
-
-GST_BOILERPLATE(
-    GstH264Encode,
-    gst_h264encode,
-    GstElement,
-    GST_TYPE_ELEMENT);
-
-enum {
-    PROP_0,
-    PROP_PROFILE,
-    PROP_LEVEL,
-    PROP_BITRATE,
-    PROP_INTRA_PERIOD,
-    PROP_INIT_QP,
-    PROP_MIN_QP,
-    PROP_SLICE_NUM,
-};
-
-
-/*static extern*/
-static void gst_h264encode_finalize(GObject *object);
-static void gst_h264encode_set_property(GObject *object, guint prop_id,
-    const GValue *value, GParamSpec *pspec);
-static void gst_h264encode_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_h264encode_set_caps(GstPad *sink_pad, GstCaps *caps);
-static GstCaps *gst_h264encode_get_caps(GstPad *sink_pad);
-static GstFlowReturn gst_h264encode_chain(GstPad *sink_pad, GstBuffer *buf);
-static GstStateChangeReturn gst_h264encode_change_state(GstElement *element, GstStateChange transition);
-static GstFlowReturn gst_h264encode_buffer_alloc(GstPad * pad, guint64 offset, guint size,
-                           GstCaps * caps, GstBuffer ** buf);
-
-static char* _h264_dump_caps(GstCaps *cpas);
-static gboolean _h264_check_valid_profile(guint profile);
-static gboolean _h264_check_valid_level(guint level);
-
-
-/*gst fix functions*/
-
-static void
-gst_h264encode_base_init(gpointer klass)
-{
-  GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
-
-  gst_element_class_set_details(element_class, &gst_h264encode_details);
-
-  /* sink pad */
-  gst_element_class_add_pad_template(
-      element_class,
-      gst_static_pad_template_get(&gst_h264encode_sink_factory)
-  );
-
-  /* src pad */
-  gst_element_class_add_pad_template(
-      element_class,
-      gst_static_pad_template_get(&gst_h264encode_src_factory)
-  );
-}
-
-
-static void
-gst_h264encode_class_init(GstH264EncodeClass *klass)
-{
-  GObjectClass * const object_class = G_OBJECT_CLASS(klass);
-  GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
-
-  object_class->finalize      = gst_h264encode_finalize;
-  object_class->set_property  = gst_h264encode_set_property;
-  object_class->get_property  = gst_h264encode_get_property;
-
-  g_object_class_install_property (object_class, PROP_PROFILE,
-        g_param_spec_uint ("profile",
-            "H264 Profile",
-            "Profile supports: 66(Baseline), 77(Main), 100(High)",
-            H264_PROFILE_BASELINE,
-            H264_PROFILE_HIGH10,
-            H264_DEFAULT_PROFILE,
-            G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_LEVEL,
-        g_param_spec_uint ("level",
-            "H264 level idc",
-            "Level idc supports: 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41",
-            H264_LEVEL_10,
-            H264_LEVEL_41,
-            H264_DEFAULT_LEVEL,
-            G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_BITRATE,
-        g_param_spec_uint ("bitrate",
-            "H264 encoding bitrate",
-            "H264 encoding bitrate, 10k~100M, (0, auto-calculate)",
-            0,
-            100*1000*1000,
-            0,
-            G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_INTRA_PERIOD,
-        g_param_spec_uint ("intra-period",
-            "H264 encoding intra-period",
-            "H264 encoding intra-period",
-            1,
-            300,
-            H264_DEFAULT_INTRA_PERIOD,
-            G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_INIT_QP,
-        g_param_spec_uint ("init-qp",
-            "H264 init-qp",
-            "H264 init-qp",
-            1,
-            51,
-            H264_DEFAULT_INIT_QP,
-            G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_MIN_QP,
-        g_param_spec_uint ("min-qp",
-            "H264 min-qp",
-            "H264 min-qp",
-            1,
-            51,
-            H264_DEFAULT_MIN_QP,
-            G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_SLICE_NUM,
-        g_param_spec_uint ("slice-num",
-            "H264 slice num",
-            "H264 slice num",
-            1,
-            200,
-            1,
-            G_PARAM_READWRITE));
-
-  element_class->change_state = gst_h264encode_change_state;
-}
-
-static void
-gst_h264encode_finalize(GObject *object)
-{
-  GstH264Encode * const encode = GST_H264ENCODE(object);
-
-  if (encode->sinkpad_caps) {
-    gst_caps_unref(encode->sinkpad_caps);
-    encode->sinkpad_caps = NULL;
-  }
-  encode->sinkpad = NULL;
-
-  if (encode->srcpad_caps) {
-    gst_caps_unref(encode->srcpad_caps);
-    encode->srcpad_caps = NULL;
-  }
-  encode->srcpad = NULL;
-
-  if (encode->encoder) {
-      gst_h264_encoder_close(encode->encoder);
-      gst_h264_encoder_uninitialize(encode->encoder);
-      gst_h264_encoder_unref(encode->encoder);
-      encode->encoder = NULL;
-  }
-
-  G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-static void
-gst_h264encode_init(GstH264Encode *encode, GstH264EncodeClass *klass)
-{
-  GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
-
-  encode->sinkpad_caps       = NULL;
-  encode->srcpad_caps        = NULL;
-  encode->first_sink_frame   = TRUE;
-  encode->first_src_frame    = TRUE;
-
-  encode->encoder = gst_h264_encoder_new();
-  H264_ASSERT(encode->encoder);
-
-  /*sink pad */
-  encode->sinkpad = gst_pad_new_from_template(
-      gst_element_class_get_pad_template(element_class, "sink"),
-      "sink"
-  );
-  gst_pad_set_getcaps_function(encode->sinkpad, gst_h264encode_get_caps);
-  gst_pad_set_setcaps_function(encode->sinkpad, gst_h264encode_set_caps);
-  gst_pad_set_chain_function(encode->sinkpad, gst_h264encode_chain);
-  gst_pad_set_bufferalloc_function(encode->sinkpad, gst_h264encode_buffer_alloc);
-  /*gst_pad_set_event_function(encode->sinkpad, gst_h264encode_sink_event); */
-  /*gst_pad_use_fixed_caps(encode->sinkpad);*/
-  gst_element_add_pad(GST_ELEMENT(encode), encode->sinkpad);
-
-  /* src pad */
-  encode->srcpad = gst_pad_new_from_template(
-      gst_element_class_get_pad_template(element_class, "src"),
-      "src"
-  );
-  encode->srcpad_caps = NULL;
-
-  gst_pad_use_fixed_caps(encode->srcpad);
-  /*gst_pad_set_event_function(encode->srcpad, gst_h264encode_src_event);*/
-  gst_element_add_pad(GST_ELEMENT(encode), encode->srcpad);
-}
-
-
-static void
-gst_h264encode_set_property(GObject *object, guint prop_id,
-    const GValue *value, GParamSpec *pspec)
-{
-  GstH264Encode *encode = GST_H264ENCODE(object);
-  H264_ASSERT(encode->encoder);
-
-  switch (prop_id) {
-    case PROP_PROFILE: {
-      guint profile = g_value_get_uint(value);
-      if (_h264_check_valid_profile(profile)) {
-        encode->encoder->profile = profile;
-      } else {
-        H264_LOG_ERROR("h264encode set property <profile> failed.\n");
-      }
-    }
-      break;
-
-    case PROP_LEVEL: {
-      guint level = g_value_get_uint(value);
-      if (_h264_check_valid_level(level)) {
-        encode->encoder->level= level;
-      } else {
-        H264_LOG_ERROR("h264encode set property <level> failed.\n");
-      }
-    }
-      break;
-
-    case PROP_BITRATE: {
-      encode->encoder->bitrate = g_value_get_uint(value);
-    }
-      break;
-
-    case PROP_INTRA_PERIOD: {
-      encode->encoder->intra_period = g_value_get_uint(value);
-    }
-      break;
-
-    case PROP_INIT_QP: {
-      encode->encoder->init_qp = g_value_get_uint(value);
-    }
-      break;
-
-    case PROP_MIN_QP: {
-      encode->encoder->min_qp = g_value_get_uint(value);
-    }
-      break;
-
-    case PROP_SLICE_NUM: {
-      encode->encoder->slice_num= g_value_get_uint(value);
-    }
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_h264encode_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstH264Encode *encode = GST_H264ENCODE(object);
-  H264_ASSERT(encode->encoder);
-
-  switch (prop_id) {
-    case PROP_PROFILE:
-      g_value_set_uint (value, encode->encoder->profile);
-      break;
-
-    case PROP_LEVEL:
-      g_value_set_uint (value, encode->encoder->level);
-      break;
-
-    case PROP_BITRATE:
-      g_value_set_uint (value, encode->encoder->bitrate);
-      break;
-
-    case PROP_INTRA_PERIOD:
-      g_value_set_uint (value, encode->encoder->intra_period);
-      break;
-
-    case PROP_INIT_QP:
-      g_value_set_uint (value, encode->encoder->init_qp);
-      break;
-
-    case PROP_MIN_QP:
-      g_value_set_uint (value, encode->encoder->min_qp);
-      break;
-
-    case PROP_SLICE_NUM:
-      g_value_set_uint (value, encode->encoder->slice_num);
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_h264encode_set_caps(GstPad *sink_pad, GstCaps *caps)
-{
-  GstH264Encode *encode = GST_H264ENCODE(GST_OBJECT_PARENT(sink_pad));
-  GstStructure *structure;
-  gint width = 0, height = 0;
-  gint fps_n = 0, fps_d = 0;
-  const GValue *fps_value = NULL;
-  encode->sinkpad_caps = caps;
-  gst_caps_ref(caps);
-  H264_LOG_INFO("gst_h264encode_set_caps,\n%s", _h264_dump_caps(caps));
-
-  structure = gst_caps_get_structure (caps, 0);
-  if (gst_structure_get_int (structure, "width", &width)) {
-    encode->encoder->width = width;
-  }
-  if (gst_structure_get_int (structure, "height", &height)) {
-    encode->encoder->height = height;
-  }
-  fps_value = gst_structure_get_value (structure, "framerate");
-  if (fps_value) {
-    fps_n = gst_value_get_fraction_numerator (fps_value);
-    fps_d = gst_value_get_fraction_denominator (fps_value);
-    encode->encoder->frame_rate = fps_n/fps_d;
-  }
-  return TRUE;
-}
-
-static GstCaps *
-gst_h264encode_get_caps(GstPad *sink_pad)
-{
-  GstCaps *caps = NULL;
-  GstH264Encode * const encode = GST_H264ENCODE(GST_OBJECT_PARENT(sink_pad));
-  if (encode->sinkpad_caps) {
-    gst_caps_ref(encode->sinkpad_caps);
-    H264_LOG_INFO("get caps,\n%s", _h264_dump_caps(encode->sinkpad_caps));
-    return encode->sinkpad_caps;
-  }
-  caps = gst_caps_copy(gst_pad_get_pad_template_caps(sink_pad));
-  return caps;
-}
-
-static GstStateChangeReturn
-gst_h264encode_change_state(GstElement *element, GstStateChange transition)
-{
-  GstH264Encode * const encode = GST_H264ENCODE(element);
-  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
-  switch (transition) {
-  case GST_STATE_CHANGE_READY_TO_PAUSED:
-    break;
-  case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-    break;
-  default:
-    break;
-  }
-
-  ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
-  if (ret != GST_STATE_CHANGE_SUCCESS)
-    return ret;
-
-  switch (transition) {
-  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
-    break;
-  case GST_STATE_CHANGE_PAUSED_TO_READY: {
-    gst_h264_encoder_close(encode->encoder);
-  }
-    break;
-  default:
-    break;
-  }
-  return GST_STATE_CHANGE_SUCCESS;
-}
-
-
-static GstFlowReturn
-gst_h264encode_chain(GstPad *sink_pad, GstBuffer *buf)
-{
-  GstFlowReturn ret_num = GST_FLOW_OK;
-  GstH264Encode *encode = GST_H264ENCODE(GST_OBJECT_PARENT(sink_pad));
-  H264Status h264ret = H264_NO_ERROR;
-  GList *out_buffers = NULL;
-  GstBuffer *tmp_buffer = NULL;
-
-  static guint input_count = 0;
-  static guint output_count = 0;
-
-  H264_ASSERT(encode && encode->encoder);
-  if (encode->first_sink_frame) {
-    /* get first buffer caps and set encoder values */
-    GstStructure *recv_struct, *src_struct;
-    GstCaps *recv_caps = GST_BUFFER_CAPS(buf);
-    gint width, height;
-    GValue const *framerate, *format_value;
-    gint fps_n, fps_d;
-    guint32 format;
-    GstVaapiSurfacePool *surface_pool = NULL;
-
-    H264_LOG_INFO("gst_h264encode_chain 1st recv-buffer caps,\n%s", _h264_dump_caps(recv_caps));
-
-    recv_struct = gst_caps_get_structure (recv_caps, 0);
-    GST_H264_ENCODE_CHECK_STATUS(NULL != recv_caps, GST_FLOW_ERROR, "gst_h264encode_chain, 1st buffer didn't have detailed caps.\n");
-    if (gst_structure_get_int (recv_struct, "width", &width)) {
-      encode->encoder->width = width;
-    }
-    if (gst_structure_get_int (recv_struct, "height", &height)) {
-      encode->encoder->height = height;
-    }
-    framerate = gst_structure_get_value (recv_struct, "framerate");
-    if (framerate) {
-      fps_n = gst_value_get_fraction_numerator (framerate);
-      fps_d = gst_value_get_fraction_denominator (framerate);
-      encode->encoder->frame_rate = fps_n/fps_d;
-    }
-    format_value = gst_structure_get_value (recv_struct, "format");
-    if (format_value) {
-      GST_H264_ENCODE_CHECK_STATUS(format_value && GST_TYPE_FOURCC == G_VALUE_TYPE(format_value),
-                                 GST_FLOW_ERROR, "1st buffer caps' format type is not fourcc.\n");
-      format = gst_value_get_fourcc (format_value);
-      if (format) {
-        gst_h264_encoder_set_input_format(encode->encoder, format);
-      }
-    }
-
-    /*set src pad caps*/
-    if (encode->srcpad_caps) {
-      gst_caps_unref(encode->srcpad_caps);
-    }
-    encode->srcpad_caps = gst_caps_copy(gst_pad_get_pad_template_caps(encode->srcpad));
-    src_struct = gst_caps_get_structure(encode->srcpad_caps, 0);
-    gst_structure_set(src_struct, "width", G_TYPE_INT, width,
-                      "height", G_TYPE_INT, height,
-                      "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
-
-    /*set display and initialize encoder*/
-    if (GST_VAAPI_IS_VIDEO_BUFFER(buf)) {
-      GstVaapiDisplay *display = NULL;
-      GstVaapiVideoBuffer *video_buffer = GST_VAAPI_VIDEO_BUFFER(buf);
-      H264_ASSERT(video_buffer);
-      display = gst_vaapi_video_buffer_get_display(video_buffer);
-      //need to get surface_pool and set to h264encoder->vaapi_context
-      //(video_buffer->priv->surface_pool);
-      #ifdef _MRST_
-      surface_pool = GST_VAAPI_SURFACE_POOL(gst_vaapi_video_buffer_get_surface_pool(video_buffer));
-      #endif
-      if (display) {
-        GST_H264_ENCODE_CHECK_STATUS(gst_h264_encoder_set_display(encode->encoder,display)
-                                    , GST_FLOW_ERROR, "set display failed in gst_h264encode_chain.\n");
-      }
-    }
-    h264ret = gst_h264_encoder_initialize(encode->encoder);
-    GST_H264_ENCODE_CHECK_STATUS (H264_NO_ERROR == h264ret, GST_FLOW_ERROR, "h264_encoder_initialize failed.\n");
-  #ifdef _MRST_
-    h264ret = gst_h264_encoder_open(encode->encoder, surface_pool);
-  #else
-    h264ret = gst_h264_encoder_open(encode->encoder);
-  #endif
-    GST_H264_ENCODE_CHECK_STATUS (H264_NO_ERROR == h264ret, GST_FLOW_ERROR, "gst_h264_encoder_open failed.\n");
-
-    encode->first_sink_frame = FALSE;
-  }
-
-  /*encoding frames*/
-  H264_ASSERT(gst_h264_encoder_get_state(encode->encoder) >= H264_ENC_OPENED);
-  ++input_count;
-  H264_LOG_INFO("input %d\n", input_count);
-  h264ret = gst_h264_encoder_encode(encode->encoder, buf, &out_buffers);
-  GST_H264_ENCODE_CHECK_STATUS (H264_NO_ERROR == h264ret, GST_FLOW_ERROR, "h264_encoder_encode failed.\n");
-
-  /*check results*/
-  while (out_buffers) {
-    tmp_buffer = out_buffers->data;
-    out_buffers = g_list_remove(out_buffers, tmp_buffer);
-    /*out_buffers = g_list_next(out_buffers);*/
-    if (encode->first_src_frame) {
-      GstBuffer *codec_data;
-      H264_ASSERT(encode->srcpad_caps);
-      /*replace codec data in src pad caps*/
-      if (H264_NO_ERROR == gst_h264_encoder_get_avcC_codec_data(encode->encoder, &codec_data)) {
-        gst_caps_set_simple(encode->srcpad_caps, "codec_data",GST_TYPE_BUFFER, codec_data, NULL);
-      }
-      gst_pad_set_caps (encode->srcpad, encode->srcpad_caps);
-      GST_BUFFER_CAPS(tmp_buffer) = gst_caps_ref(encode->srcpad_caps);
-      H264_LOG_INFO("gst_h264encode_chain 1st push-buffer caps,\n%s", _h264_dump_caps(encode->srcpad_caps));
-      encode->first_src_frame = FALSE;
-    }
-    ++output_count;
-    H264_LOG_INFO("output:%d, %" GST_TIME_FORMAT ", 0x%s\n",
-                   output_count,
-                   GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(tmp_buffer)),
-                   h264_dump_bytes(GST_BUFFER_DATA(tmp_buffer),
-                                  (GST_BUFFER_SIZE(tmp_buffer) > 16? 16: GST_BUFFER_SIZE(tmp_buffer))));
-    gst_pad_push(encode->srcpad, tmp_buffer);
-  }
-
-finish:
-  gst_mini_object_unref(GST_MINI_OBJECT(buf));
-  return ret_num;
-
-}
-
-static GstFlowReturn
-gst_h264encode_buffer_alloc(GstPad * pad, guint64 offset, guint size,
-                           GstCaps * caps, GstBuffer ** buf)
-{
-  GstH264Encode * const encode = GST_H264ENCODE(GST_OBJECT_PARENT(pad));
-  GstStructure *structure = NULL;
-  GstBuffer *buffer;
-  GstVaapiDisplay* display = NULL;
-  GstFlowReturn ret_num = GST_FLOW_ERROR;
-
-  if (caps) {
-    structure = gst_caps_get_structure(caps, 0);
-  }
-  if (!structure || gst_structure_has_name(structure, "video/x-vaapi-surface")) {
-    H264_ASSERT(encode->encoder);
-    display = gst_h264_encoder_get_display(encode->encoder);
-    if (!display) {
-      gst_h264_encoder_initialize(encode->encoder);
-      display = gst_h264_encoder_get_display(encode->encoder);
-      GST_H264_ENCODE_CHECK_STATUS(display, GST_FLOW_ERROR, "gst_h264_encoder_get_display failed in gst_h264encode_buffer_alloc.\n");
-    }
-    buffer = gst_vaapi_video_buffer_new(display);
-  } else { /* video/x-raw-yuv */
-    buffer = gst_buffer_new_and_alloc(size);
-  }
-
-  GST_H264_ENCODE_CHECK_STATUS(buffer, GST_FLOW_ERROR, "gst_h264encode_buffer_alloc failed.\n");
-
-  GST_BUFFER_OFFSET (buffer) = offset;
-  if (caps) {
-    gst_buffer_set_caps(buffer, caps);
-  }
-  *buf = buffer;
-  ret_num = GST_FLOW_OK;
-
-finish:
-  if (display) {
-    g_object_unref(display);
-  }
-  return ret_num;
-}
-
-static gboolean _h264_check_valid_profile(guint profile)
-{
-   static const limit_profiles[] = {
-         H264_PROFILE_BASELINE,
-         H264_PROFILE_MAIN,
-         H264_PROFILE_HIGH
-        };
-   guint n_profiles = sizeof(limit_profiles)/sizeof(limit_profiles[0]);
-   guint i;
-   for (i = 0; i < n_profiles; ++i) {
-     if (limit_profiles[i] == profile)
-       return TRUE;
-   }
-   return FALSE;
-}
-
-static gboolean _h264_check_valid_level(guint level)
-{
-  static const limit_levels[] = {
-        H264_LEVEL_10,
-        H264_LEVEL_11,
-        H264_LEVEL_12,
-        H264_LEVEL_13,
-        H264_LEVEL_20,
-        H264_LEVEL_21,
-        H264_LEVEL_22,
-        H264_LEVEL_30,
-        H264_LEVEL_31,
-        H264_LEVEL_32,
-        H264_LEVEL_40,
-        H264_LEVEL_41,
-        H264_LEVEL_42,
-        H264_LEVEL_50,
-        H264_LEVEL_51
-       };
-  guint n_levels = sizeof(limit_levels)/sizeof(limit_levels[0]);
-  guint i;
-  for (i = 0; i < n_levels; ++i) {
-    if (limit_levels[i] == level)
-      return TRUE;
-  }
-  return FALSE;
-
-}
-
-static char*
-_h264_dump_caps(GstCaps *cpas)
-{
-  guint i = 0, j = 0;
-  GstStructure const *structure;
-  GValue const *value;
-  static char caps_string[4096*5];
-  char *tmp;
-
-  char *cur = caps_string;
-  memset(caps_string, 0, sizeof(caps_string));
-  for (i = 0; i < gst_caps_get_size(cpas); i++) {
-    structure = gst_caps_get_structure(cpas, i);
-    const char* caps_name = gst_structure_get_name (structure);
-    sprintf(cur, "cap_%02d:%s\n", i, caps_name);
-    cur += strlen(cur);
-
-    for (j = 0; j < gst_structure_n_fields(structure); j++) {
-      const char* name = gst_structure_nth_field_name(structure, j);
-      value = gst_structure_get_value(structure, name);
-      tmp = gst_value_serialize(value);
-      sprintf(cur, "\t%s:%s(%s)\n", name, tmp, G_VALUE_TYPE_NAME(value));
-      cur += strlen(cur);
-      g_free(tmp);
-    }
-  }
-
-  return caps_string;
-}
-
-
-
-
-/* plugin register*/
-static gboolean
-h264encode_init (GstPlugin * plugin)
-{
-  return gst_element_register (plugin, "vah264encode", GST_RANK_PRIMARY,
-      GST_TYPE_H264ENCODE);
-}
-
-/* gstreamer looks for this structure to register mrstcamsrc */
-GST_PLUGIN_DEFINE (
-    GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    "vaapiencode",
-    "Vaapi Encoder",
-    h264encode_init,
-    VERSION,
-    "LGPL",
-    "GStreamer",
-    "http://gstreamer.net/")
-
-
diff --git a/gst/vaapiencode/gsth264encode.h b/gst/vaapiencode/gsth264encode.h
deleted file mode 100644 (file)
index 08a0fd6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  gstvaapidecode.h - VA-API video decoder
- *
- *  gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
- *  Copyright (C) 2011 Intel Corporation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- */
-
-#ifndef GST_H264ENCODE_H
-#define GST_H264ENCODE_H
-
-#include <gst/gst.h>
-#include "h264encoder.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_H264ENCODE             (gst_h264encode_get_type())
-#define GST_IS_H264ENCODE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_H264ENCODE))
-#define GST_IS_H264ENCODE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_H264ENCODE))
-#define GST_H264ENCODE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_H264ENCODE, GstH264EncodeClass))
-#define GST_H264ENCODE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_H264ENCODE, GstH264Encode))
-#define GST_H264ENCODE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_H264ENCODE, GstH264EncodeClass))
-
-
-typedef struct _GstH264Encode        GstH264Encode;
-typedef struct _GstH264EncodeClass   GstH264EncodeClass;
-
-struct _GstH264Encode {
-    GstElement          parent_instance;
-
-    GstPad             *sinkpad;
-    GstCaps            *sinkpad_caps;
-
-    GstPad             *srcpad;
-    GstCaps            *srcpad_caps;
-
-    GstH264Encoder     *encoder;
-    gboolean            first_sink_frame;
-    gboolean            first_src_frame;
-};
-
-struct _GstH264EncodeClass {
-    GstElementClass     parent_class;
-};
-
-GType gst_h264encode_get_type(void);
-
-G_END_DECLS
-
-#endif /* GST_H264ENCODE_H */
-
index 42e13d6..d87e734 100644 (file)
@@ -1,22 +1,22 @@
 /*
- *  gstvaapiencode.h - VA-API video encoder
+ *  gstvaapiencode.h - VA-API video encode
  *
+ *  gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
  *  Copyright (C) 2011 Intel Corporation
  *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1
- *  of the License, or (at your option) any later version.
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This library is distributed in the hope that it will be useful,
+ *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free
- *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301 USA
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
 #ifndef GST_VAAPI_ENCODE_H
 
 G_BEGIN_DECLS
 
-/* Default templates */
-#define GST_CAPS_CODEC(CODEC)          \
-    CODEC ", "                         \
-    "width  = (int) [ 1, MAX ], "      \
-    "height = (int) [ 1, MAX ]; "
-
-
 #define GST_TYPE_VAAPI_ENCODE             (gst_vaapi_encode_get_type())
 #define GST_IS_VAAPI_ENCODE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODE))
 #define GST_IS_VAAPI_ENCODE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODE))
@@ -61,7 +54,6 @@ struct _GstVaapiEncode {
 
 struct _GstVaapiEncodeClass {
     GstElementClass     parent_class;
-    gboolean          (*set_encoder_src_caps)(GstVaapiEncode* encode, GstCaps *caps);
 };
 
 GType gst_vaapi_encode_get_type(void);
index d16d632..21bb7f1 100644 (file)
@@ -11,7 +11,6 @@
 #include "gst/gstclock.h"
 #include "gst/gstvalue.h"
 
-#include "gst/vaapi/gstvaapidisplay_x11.h"
 #include "gst/vaapi/gstvaapiobject.h"
 #include "gst/vaapi/gstvaapiobject_priv.h"
 #include "gst/vaapi/gstvaapicontext.h"
 
 #define ENCPRV(encoder) GST_H264_ENCODER_GET_PRIVATE(encoder)
 
-#define H264_CHECK_STATUS(exp, err_num, err_reason, ...)  \
-  H264_ASSERT(exp);                             \
-  if (!(exp)) {                                 \
-    ret = err_num;                              \
-    H264_LOG_ERROR(err_reason, ## __VA_ARGS__);                 \
-    goto error;                                 \
-  }
-
 #define SHARE_CODED_BUF         0
 
 #define DEFAULT_SURFACE_NUMBER  3
@@ -64,14 +55,14 @@ struct _GstH264EncoderPrivate {
   gboolean          es_flag;  /*elementary flag*/
 
   /* private data*/
-  GstVaapiDisplay  *vaapi_display;
+  //GstVaapiDisplay  *vaapi_display;
   GstVaapiContext  *vaapi_context;
   GQueue           *video_buffer_caches; /*not used for baseline*/
 
   GstVaapiSurface  *ref_surface;  /* reference buffer*/
   GstVaapiSurface  *recon_surface; /* reconstruct buffer*/
 
-  H264_Encode_State encode_state;
+  //VAAPI_Encode_State encode_state;
 
   VABufferID        seq_parameter;
   VABufferID        pic_parameter;
@@ -96,7 +87,7 @@ struct _GstH264EncoderPrivate {
 
 };
 
-G_DEFINE_TYPE(GstH264Encoder, gst_h264_encoder, G_TYPE_OBJECT);
+G_DEFINE_TYPE(GstH264Encoder, gst_h264_encoder, GST_TYPE_VAAPI_ENCODER);
 
 
 // 4096-1
@@ -117,27 +108,36 @@ static const uint8_t h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3
 
 static GstBufferClass *h264_encode_buffer_parent_class = NULL;
 
+
+static EncoderStatus gst_h264_encoder_initialize(GstVaapiEncoder* encoder);
+static EncoderStatus gst_h264_encoder_uninitialize(GstVaapiEncoder* encoder);
+static EncoderStatus gst_h264_encoder_open(GstVaapiEncoder* encoder, void* private_data);
+static EncoderStatus gst_h264_encoder_close(GstVaapiEncoder* encoder);
+static EncoderStatus gst_h264_encoder_encode(GstVaapiEncoder* encoder, GstBuffer *raw_pic, GList **coded_pics);
+static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics);
+
+static gboolean   gst_h264_validate_parameters(GstH264Encoder *encoder);
 static void     gst_h264_encoder_finalize(GObject *object);
 static void     gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
 
 static VAProfile  h264_get_va_profile(uint32_t profile);
-static H264Status h264_encoder_alloc_buffers(GstH264EncoderPrivate *h264_prv);
-static H264Status h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv);
-static H264Status h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
+static EncoderStatus h264_encoder_alloc_buffers(GstH264EncoderPrivate *h264_prv);
+static EncoderStatus h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv);
+static EncoderStatus h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
                                              GstBuffer *raw_pic,
                                              GstVaapiSurface *surface);
 
-static H264Status h264_prepare_encoding(GstH264EncoderPrivate *h264_prv,
+static EncoderStatus h264_prepare_encoding(GstH264EncoderPrivate *h264_prv,
                                              GstBuffer *raw_pic, gboolean is_key,
                                              VABufferID coded_buf);
-static H264Status h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
+static EncoderStatus h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
                                          VASurfaceID surface_id,
                                          gboolean is_key,
                                          GstClockTime timestamp,
                                          GstClockTime duration,
                                          VABufferID *coded_buf,
                                          GList **coded_pics);
-static H264Status
+static EncoderStatus
 h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const uint8_t *buf, uint32_t size);
 static GstBuffer *h264_encoder_create_coded_buffer(GstH264EncoderPrivate *h264_prv,
                                                    uint8_t *frame,
@@ -153,7 +153,7 @@ static GstH264EncodeBuffer *gst_h264_encode_buffer_new(GstH264EncoderPrivate *h2
                                                        VABufferID *coded_id);
 
 /* h264 bitstream functions */
-static void h264_bitstream_init(H264Bitstream *bitstream, uint32_t bit_capability);
+static void     h264_bitstream_init(H264Bitstream *bitstream, uint32_t bit_capability);
 static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, uint32_t value, uint32_t bit_size);
 static gboolean h264_bitstream_align(H264Bitstream *bitstream, uint32_t value);
 static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, uint32_t value);
@@ -161,7 +161,7 @@ static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, int32_t value)
 static gboolean h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
 
 static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const uint8_t *buf, uint32_t byte_size);
-static void h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
+static void     h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
 static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, uint32_t extra_bit_size);
 static gboolean h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv);
 static gboolean h264_bitstream_write_pps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv);
@@ -169,13 +169,26 @@ static const uint8_t *h264_next_nal(const uint8_t *buffer, uint32_t len, uint32_
 static gboolean h264_read_sps_attributes(const uint8_t *sps_data, uint32_t sps_size,
                                 uint32_t *profile_idc, uint32_t *profile_comp, uint32_t *level_idc);
 
+/*other functions*/
+static EncoderStatus gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
+static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
+
+
 static void
 gst_h264_encoder_class_init(GstH264EncoderClass *klass)
 {
   GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+  GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
   g_type_class_add_private(klass, sizeof(GstH264EncoderPrivate));
 
   object_class->finalize = gst_h264_encoder_finalize;
+
+  encoder_class->initialize = gst_h264_encoder_initialize;
+  encoder_class->uninitialize = gst_h264_encoder_uninitialize;
+  encoder_class->open = gst_h264_encoder_open;
+  encoder_class->close = gst_h264_encoder_close;
+  encoder_class->encode = gst_h264_encoder_encode;
+  encoder_class->flush = gst_h264_encoder_flush;
   /*
   object_class->set_property = gst_h264_encoder_set_property;
   object_class->get_property = gst_h264_encoder_get_property;
@@ -189,7 +202,7 @@ gst_h264_encode_buffer_class_init (gpointer g_class, gpointer class_data)
   GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class);
 
   h264_encode_buffer_parent_class = g_type_class_peek_parent(g_class);
-  H264_ASSERT(h264_encode_buffer_parent_class);
+  ENCODER_ASSERT(h264_encode_buffer_parent_class);
 
   mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
       gst_h264_encode_buffer_finalize;
@@ -224,17 +237,19 @@ gst_h264_encode_buffer_finalize (GstH264EncodeBuffer *h264_buffer)
 {
   GstH264EncoderPrivate *h264_prv = NULL;
   VABufferID* coded_id = NULL;
+  GstVaapiDisplay *display = NULL;
 
   h264_prv = h264_buffer->encoder;
   coded_id = h264_buffer->coded_id;
+  display = ENCODER_DISPLAY(h264_prv->public);
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(h264_prv->vaapi_context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  ENCODER_ASSERT(display);
+  ENCODER_ASSERT(h264_prv->vaapi_context);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
 
-  H264_ASSERT(h264_prv);
-  H264_ASSERT(coded_id && VA_INVALID_ID!= *coded_id);
-  H264_ASSERT(h264_prv->available_code_buffers);
+  ENCODER_ASSERT(h264_prv);
+  ENCODER_ASSERT(coded_id && VA_INVALID_ID!= *coded_id);
+  ENCODER_ASSERT(h264_prv->available_code_buffers);
 
   g_mutex_lock(h264_prv->code_buffer_lock);
   /*if (--(*h264_buffer->ref_coded_id) == 0) */
@@ -269,14 +284,14 @@ h264_get_video_surface(GstH264EncoderPrivate *h264_prv, GstVaapiVideoBuffer *vid
   //ref_surface
   GstVaapiSurface *ret = gst_vaapi_video_buffer_get_surface(video_buffer);
 
-  H264_CHECK_STATUS(ret, NULL, "video buffer doesn't have a surface");
+  ENCODER_CHECK_STATUS(ret, NULL, "video buffer doesn't have a surface");
 #if 0
   g_queue_push_tail(h264_prv->video_buffer_caches,video_buffer);
   gst_buffer_ref(GST_BUFFER(video_buffer));
 #endif
   return ret;
 
-  error:
+  end:
   return NULL;
 }
 
@@ -284,7 +299,7 @@ static void
 h264_release_video_surface(GstH264EncoderPrivate *h264_prv, VASurfaceID surface)
 {
 #if 0
-  H264_ASSERT(h264_prv->video_buffer_caches);
+  ENCODER_ASSERT(h264_prv->video_buffer_caches);
   g_queue_find_custom(h264_prv->video_buffer_caches,xx, compare_func);
   for (h264_prv->video_buffer_caches) {
   }
@@ -294,7 +309,7 @@ h264_release_video_surface(GstH264EncoderPrivate *h264_prv, VASurfaceID surface)
 static GstVaapiSurface *
 h264_pop_free_surface(GstH264EncoderPrivate *h264_prv)
 {
-  H264_ASSERT(h264_prv && h264_prv->vaapi_context);
+  ENCODER_ASSERT(h264_prv && h264_prv->vaapi_context);
 
   /*may need lock*/
   GstVaapiSurface *surface = gst_vaapi_context_get_surface(h264_prv->vaapi_context);
@@ -304,7 +319,7 @@ h264_pop_free_surface(GstH264EncoderPrivate *h264_prv)
 static void
 h264_push_free_surface(GstH264EncoderPrivate *h264_prv, GstVaapiSurface *surface)
 {
-  H264_ASSERT(surface);
+  ENCODER_ASSERT(surface);
   if (!surface) {
     return;
   }
@@ -312,13 +327,6 @@ h264_push_free_surface(GstH264EncoderPrivate *h264_prv, GstVaapiSurface *surface
 }
 
 
-H264_Encode_State gst_h264_encoder_get_state(GstH264Encoder* encoder)
-{
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-  return h264_prv->encode_state;
-}
-
-
 static VAProfile
 h264_get_va_profile(uint32_t profile)
 {
@@ -349,7 +357,8 @@ static void
 gst_h264_encoder_init(GstH264Encoder *encoder)
 {
   GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-  H264_ASSERT(h264_prv);
+  GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
+  ENCODER_ASSERT(h264_prv);
   h264_prv->public = encoder;
 
   /* init public attributes */
@@ -359,13 +368,13 @@ gst_h264_encoder_init(GstH264Encoder *encoder)
   h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
   h264_prv->es_flag = TRUE;
 
-  h264_prv->vaapi_display = NULL;
+  //h264_prv->vaapi_display = NULL;
   h264_prv->vaapi_context= NULL;
   h264_prv->ref_surface = NULL;
   h264_prv->recon_surface = NULL;
   h264_prv->video_buffer_caches = g_queue_new();
 
-  h264_prv->encode_state = H264_ENC_NULL;
+  //h264_prv->encode_state = H264_ENC_NULL;
   h264_prv->seq_parameter = VA_INVALID_ID;
   h264_prv->pic_parameter = VA_INVALID_ID;
   h264_prv->slice_parameter = VA_INVALID_ID;
@@ -385,6 +394,9 @@ gst_h264_encoder_init(GstH264Encoder *encoder)
   h264_prv->code_buffer_cond = g_cond_new();
   h264_prv->available_code_buffers = g_queue_new();
 
+  encoder_prv->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
+  /* encoder_prv->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
+
 }
 
 static void
@@ -420,10 +432,7 @@ gst_h264_encoder_finalize(GObject *object)
     g_object_unref(h264_prv->vaapi_context);
     h264_prv->vaapi_context= NULL;
   }
-  if (h264_prv->vaapi_display) {
-    g_object_unref(h264_prv->vaapi_display);
-    h264_prv->vaapi_display = NULL;
-  }
+
   if (h264_prv->video_buffer_caches) {
     g_queue_free(h264_prv->video_buffer_caches);
     h264_prv->video_buffer_caches = NULL;
@@ -448,9 +457,9 @@ gst_h264_encoder_init_public_values(GstH264Encoder* encoder)
 {
   encoder->profile = 0;
   encoder->level = 0;
-  encoder->width = 0;
-  encoder->height = 0;
-  encoder->frame_rate = 0;
+  //encoder->width = 0;
+  //encoder->height = 0;
+  //encoder->frame_rate = 0;
   encoder->bitrate = 0;
   encoder->intra_period = 0;
   encoder->init_qp = -1;
@@ -472,99 +481,24 @@ gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es)
   h264_prv->es_flag = es;
 }
 
-gboolean
-gst_h264_encoder_set_display(GstH264Encoder* encoder, GstVaapiDisplay *display)
+EncoderStatus
+gst_h264_encoder_initialize(GstVaapiEncoder* encoder)
 {
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-  if (display == h264_prv->vaapi_display) {
-    return TRUE;
-  }
-
-  if (H264_ENC_INIT < h264_prv->encode_state) {
-    return FALSE;
-  }
-  if (h264_prv->vaapi_display) {
-    g_object_unref(h264_prv->vaapi_display);
-    h264_prv->vaapi_display = NULL;
-  }
-  h264_prv->vaapi_display = g_object_ref(display);
-  return TRUE;
+  return ENCODER_NO_ERROR;
 }
 
-GstVaapiDisplay *
-gst_h264_encoder_get_display(GstH264Encoder* encoder)
+EncoderStatus
+gst_h264_encoder_uninitialize(GstVaapiEncoder* encoder)
 {
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-  return (h264_prv->vaapi_display ? g_object_ref(h264_prv->vaapi_display) : NULL);
-}
-
+  return ENCODER_NO_ERROR;
 
-H264Status
-gst_h264_encoder_initialize(GstH264Encoder* encoder)
-{
-  H264Status ret = H264_NO_ERROR;
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-  VAStatus va_status = VA_STATUS_SUCCESS;
-  int major_ver, minor_ver;
-
-  /* check state */
-  if (H264_ENC_INIT == h264_prv->encode_state) {
-    return H264_NO_ERROR;
-  }
-  H264_ASSERT(H264_ENC_NULL == h264_prv->encode_state);
-  if (H264_ENC_NULL != h264_prv->encode_state) {
-    return H264_STATE_ERR;
-  }
-
-/* create va_dpy*/
-  if (!h264_prv->vaapi_display) {
-    h264_prv->vaapi_display = gst_vaapi_display_x11_new(NULL);
-    H264_CHECK_STATUS(h264_prv->vaapi_display, H264_DISPLAY_ERR, "gst_vaapi_display_x11_new failed.\n");
-  }
-
-  h264_prv->encode_state = H264_ENC_INIT;
-  return H264_NO_ERROR;
-
-  error:
-  gst_h264_encoder_uninitialize(encoder);
-  return ret;
-}
-
-H264Status
-gst_h264_encoder_uninitialize(GstH264Encoder* encoder)
-{
-  H264Status ret = H264_NO_ERROR;
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-
-  /* release buffers first */
-  if (H264_ENC_NULL == h264_prv->encode_state) {
-    return H264_NO_ERROR;
-  }
-
-  if (H264_ENC_INIT < h264_prv->encode_state) {
-    gst_h264_encoder_close(encoder);
-  }
-
-  H264_ASSERT(H264_ENC_INIT == h264_prv->encode_state);
-
-  /* close va_dpy */
-  if (h264_prv->vaapi_display) {
-    g_object_unref(h264_prv->vaapi_display);
-    h264_prv->vaapi_display = NULL;
-  }
-
-  h264_prv->encode_state = H264_ENC_NULL;
-  return H264_NO_ERROR;
-
-  //error:
-  return ret;
 }
 
 gboolean
 gst_h264_validate_parameters(GstH264Encoder *encoder)
 {
   GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-  if (!encoder->width || !encoder->height || !encoder->frame_rate) {
+  if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
     return FALSE;
   }
   if (!encoder->profile) {
@@ -589,7 +523,7 @@ gst_h264_validate_parameters(GstH264Encoder *encoder)
 
   /* default compress ratio 1: (4*8*1.5) */
   if (!encoder->bitrate) {
-    encoder->bitrate = encoder->width*encoder->height*encoder->frame_rate/4;
+    encoder->bitrate = ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
   }
 
   if (!encoder->slice_num) {
@@ -607,57 +541,48 @@ gst_h264_validate_parameters(GstH264Encoder *encoder)
                  slice_7_height = 1
                  slice_8_height = 1
    */
-  h264_prv->default_slice_height = (encoder->height+15)/16/encoder->slice_num;
+  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;
-    encoder->slice_num = (encoder->height+15)/16;
+    encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
   } else {
-    h264_prv->slice_mod_mb_num = ((encoder->height+15)/16)%encoder->slice_num;
+    h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
   }
   return TRUE;
 }
 
-H264Status
-#ifdef _MRST_
-gst_h264_encoder_open(GstH264Encoder* encoder, GstVaapiSurfacePool *surfaces_pool)
-#else
-gst_h264_encoder_open(GstH264Encoder* encoder)
-#endif
+EncoderStatus
+gst_h264_encoder_open(GstVaapiEncoder* encoder, void* private_data)
 {
-  H264Status ret = H264_NO_ERROR;
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
+  GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
+  GstVaapiSurfacePool *surfaces_pool = private_data;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+  GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
+
+  EncoderStatus ret = ENCODER_NO_ERROR;
   VAProfile va_profile = -1;
   VAEntrypoint entrypoints[5];
   int num_entrypoints,slice_entrypoint;
   VAConfigAttrib attrib[5];
   VAStatus va_status = VA_STATUS_SUCCESS;
 
-  /* check state */
-  if (H264_ENC_OPENED == h264_prv->encode_state) {
-    return H264_NO_ERROR;
-  }
-  H264_ASSERT(H264_ENC_INIT == h264_prv->encode_state);
-  if (H264_ENC_INIT != h264_prv->encode_state) {
-    return H264_STATE_ERR;
-  }
-
   /*check and set default values*/
-  H264_CHECK_STATUS(gst_h264_validate_parameters(encoder), H264_PARAMETER_ERR, "h264encoder paramerter error.\n");
+  ENCODER_CHECK_STATUS(gst_h264_validate_parameters(h264_encoder), ENCODER_PARAMETER_ERR, "h264encoder paramerter error.\n");
 
-  va_profile = h264_get_va_profile(encoder->profile);
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(!h264_prv->vaapi_context);
-  H264_CHECK_STATUS(-1 != va_profile, H264_PROFILE_ERR, "profile(%d) is NOT supported.\n", encoder->profile);
+  va_profile = h264_get_va_profile(h264_encoder->profile);
+  ENCODER_ASSERT(ENCODER_DISPLAY(encoder));
+  ENCODER_ASSERT(!h264_prv->vaapi_context);
+  ENCODER_CHECK_STATUS(-1 != va_profile, ENCODER_PROFILE_ERR, "profile(%d) is NOT supported.\n", h264_encoder->profile);
 
 #ifdef _MRST_
   h264_prv->vaapi_context = g_object_new(
         GST_VAAPI_TYPE_CONTEXT,
-        "display",      h264_prv->vaapi_display,
+        "display",      display,
         "id",           GST_VAAPI_ID(VA_INVALID_ID),
         "entrypoint",   gst_vaapi_entrypoint(VAEntrypointEncSlice),
-        "width",        h264_prv->public->width,
-        "height",       h264_prv->public->height,
+        "width",        ENCODER_WIDTH(encoder),
+        "height",       ENCODER_HEIGHT(encoder),
         NULL
     );
   if (surfaces_pool) {
@@ -666,42 +591,37 @@ gst_h264_encoder_open(GstH264Encoder* encoder)
   g_object_set(h264_prv->vaapi_context, "profile",  gst_vaapi_profile(va_profile), NULL);
 
 #else
-  h264_prv->vaapi_context = gst_vaapi_context_new(h264_prv->vaapi_display,
+  VAAPI_UNUSED_ARG(surfaces_pool);
+  h264_prv->vaapi_context = gst_vaapi_context_new(display,
                         gst_vaapi_profile(va_profile),
                         gst_vaapi_entrypoint(VAEntrypointEncSlice),
-                        h264_prv->public->width,
-                        h264_prv->public->height);
+                        ENCODER_WIDTH(encoder),
+                        ENCODER_HEIGHT(encoder));
 #endif
-  H264_CHECK_STATUS(h264_prv->vaapi_context, H264_CONTEXT_ERR, "gst_vaapi_context_new failed.\n");
+  ENCODER_CHECK_STATUS(h264_prv->vaapi_context, ENCODER_CONTEXT_ERR, "gst_vaapi_context_new failed.\n");
   ret = h264_encoder_alloc_buffers(h264_prv);
-  if (H264_NO_ERROR != ret) {
-    goto error;
+  if (ENCODER_NO_ERROR != ret) {
+    goto end;
   }
 
-  h264_prv->encode_state = H264_ENC_OPENED;
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 
-  error:
+  end:
   // clear resources
   gst_h264_encoder_close(encoder);
   return ret;
 
 }
 
-H264Status
-gst_h264_encoder_close(GstH264Encoder* encoder)
+EncoderStatus
+gst_h264_encoder_close(GstVaapiEncoder* encoder)
 {
-  H264Status ret = H264_NO_ERROR;
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
-
-  if (H264_ENC_INIT >= h264_prv->encode_state) {
-    return H264_NO_ERROR;
-  }
+  GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
+  EncoderStatus ret = ENCODER_NO_ERROR;
+  GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
 
   /* release buffers first */
-  if (H264_ENC_OPENED <= h264_prv->encode_state) {
-    h264_encoder_release_buffers(h264_prv);
-  }
+  h264_encoder_release_buffers(h264_prv);
 
   /*remove ref_surface*/
   if (h264_prv->ref_surface) {
@@ -730,7 +650,6 @@ gst_h264_encoder_close(GstH264Encoder* encoder)
   }
 
   h264_prv->frame_count = 0;
-  h264_prv->encode_state = H264_ENC_INIT;
 
   if (h264_prv->sps_data) {
     gst_buffer_unref(h264_prv->sps_data);
@@ -743,68 +662,46 @@ gst_h264_encoder_close(GstH264Encoder* encoder)
   return ret;
 }
 
-static H264Status
+static EncoderStatus
 h264_encoder_alloc_buffers(GstH264EncoderPrivate *h264_prv)
 {
-  H264Status ret = H264_NO_ERROR;
+  EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
   uint32_t i;
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(h264_prv->vaapi_context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  ENCODER_ASSERT(display);
+  ENCODER_ASSERT(h264_prv->vaapi_context);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
   VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
   gboolean is_locked = FALSE;
 
-  GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_LOCK(display);
   is_locked = TRUE;
 
-  /* 1. create sequence parameter set */
-  {
-      VAEncSequenceParameterBufferH264 seq_h264 = {0};
-
-      seq_h264.level_idc = h264_prv->public->level; /* 3.0 */
-      seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
-      seq_h264.picture_width_in_mbs = (h264_prv->public->width+15)/16;
-      seq_h264.picture_height_in_mbs = (h264_prv->public->height+15)/16;
-
-      seq_h264.bits_per_second = h264_prv->public->bitrate;
-      seq_h264.frame_rate = h264_prv->public->frame_rate;
-      seq_h264.initial_qp = h264_prv->public->init_qp; /*qp_value; 15, 24, 26?*/
-      seq_h264.min_qp = h264_prv->public->min_qp;     /*1, 6, 10*/
-      seq_h264.basic_unit_size = 0;
-      seq_h264.intra_period = h264_prv->public->intra_period;
-      seq_h264.intra_idr_period = h264_prv->public->intra_period;
-
-      va_status = vaCreateBuffer(va_dpy, context_id,
-                                 VAEncSequenceParameterBufferType,
-                                 sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
-      H264_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, H264_ENC_RES_ERR, "alloc seq-buffer failed.\n");
-  }
-
-  /* 2. create coded buffers */
+  /* create coded buffers */
   h264_prv->coded_bufs = (VABufferID*)g_malloc0(h264_prv->coded_buf_num * sizeof(h264_prv->coded_bufs[0]));
   { // check width, height  ????
-      uint32_t codedbuf_size = (h264_prv->public->width * h264_prv->public->height * 400) / (16*16);
+      uint32_t codedbuf_size = (ENCODER_WIDTH(h264_prv->public) * ENCODER_HEIGHT(h264_prv->public) * 400) / (16*16);
       for (i = 0; i < h264_prv->coded_buf_num; i++) {
         va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
                                    codedbuf_size, 1, NULL, &h264_prv->coded_bufs[i]);
 
-        H264_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, H264_ENC_RES_ERR, "alloc coded buffer failed.\n");
+        ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_ENC_RES_ERR, "alloc coded buffer failed.\n");
       }
   }
 
   /* unlock here */
-  GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_UNLOCK(display);
   is_locked = FALSE;
 
-  H264_ASSERT(h264_prv->available_code_buffers);
+  ENCODER_ASSERT(h264_prv->available_code_buffers);
 
-  /*3. create slice_param_buffers*/
+  /* create slice_param_buffers */
   h264_prv->slice_param_buffers = (VAEncSliceParameterBuffer*)g_malloc0_n(h264_prv->public->slice_num,
                                                      sizeof(h264_prv->slice_param_buffers[0]));
 
-  /* 4. init queue available_code_buffers */
+  /* init queue available_code_buffers */
   g_mutex_lock(h264_prv->code_buffer_lock);
   for (i = 0; i < h264_prv->coded_buf_num; i++) {
     g_queue_push_tail (h264_prv->available_code_buffers, &h264_prv->coded_bufs[i]);
@@ -812,27 +709,28 @@ h264_encoder_alloc_buffers(GstH264EncoderPrivate *h264_prv)
   g_cond_signal(h264_prv->code_buffer_cond);
   g_mutex_unlock(h264_prv->code_buffer_lock);
 
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 
-  error:
+  end:
   if (is_locked) {
-    GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+    GST_VAAPI_DISPLAY_UNLOCK(display);
     is_locked = FALSE;
   }
   return ret;
 
 }
 
-static H264Status
+static EncoderStatus
 h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv)
 {
   VAStatus va_status = VA_STATUS_SUCCESS;
   uint32_t available_buf_count = h264_prv->coded_buf_num;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
   uint32_t i;
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(h264_prv->vaapi_context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  ENCODER_ASSERT(display);
+  ENCODER_ASSERT(h264_prv->vaapi_context);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
 
   /* wait for all coded buffer freed*/
   g_mutex_lock(h264_prv->code_buffer_lock);
@@ -846,12 +744,12 @@ h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv)
   }
   g_mutex_unlock(h264_prv->code_buffer_lock);
 
-  GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_LOCK(display);
   for (i = 0; i < h264_prv->coded_buf_num; i++) {
     va_status = vaDestroyBuffer(va_dpy, h264_prv->coded_bufs[i]);
   }
   va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
-  GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_UNLOCK(display);
 
   if (h264_prv->coded_bufs) {
     g_free(h264_prv->coded_bufs);
@@ -863,100 +761,98 @@ h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv)
     h264_prv->slice_param_buffers = NULL;
   }
 
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 }
 
-H264Status
-gst_h264_encoder_encode(GstH264Encoder* encoder, GstBuffer *raw_pic, GList **coded_pics)
+EncoderStatus
+gst_h264_encoder_encode(GstVaapiEncoder* encoder, GstBuffer *raw_pic, GList **coded_pics)
 {
-  H264Status ret = H264_NO_ERROR;
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
+  GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
+  GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
+  GstVaapiDisplay *display = ENCODER_DISPLAY(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;
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(h264_prv->vaapi_context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  ENCODER_ASSERT(display);
+  ENCODER_ASSERT(h264_prv->vaapi_context);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
   VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
   GstVaapiSurface *new_surface = NULL;
 
-  H264_CHECK_STATUS(h264_prv->encode_state >= H264_ENC_OPENED, H264_STATE_ERR, "H264 encoder was not opened.\n");
-  if (h264_prv->encode_state < H264_ENC_ENCODING) {
-    h264_prv->encode_state = H264_ENC_ENCODING;
-  }
-
   if (GST_VAAPI_IS_VIDEO_BUFFER(raw_pic)) {
     buffer_surface = h264_get_video_surface(h264_prv, GST_VAAPI_VIDEO_BUFFER(raw_pic));
   } else {
     new_surface = h264_pop_free_surface(h264_prv);
     buffer_surface = new_surface;
-    H264_CHECK_STATUS(buffer_surface, H264_SURFACE_ERR, "h264_pop_free_surface failed.\n");
+    ENCODER_CHECK_STATUS(buffer_surface, ENCODER_SURFACE_ERR, "h264_pop_free_surface failed.\n");
 
     /*input picture to h264_prv->cur_surface_index*/
     va_status = h264_put_raw_buffer_to_surface(h264_prv, raw_pic, buffer_surface);
-    H264_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, H264_PICTURE_ERR, "va put buffer to surface failed.\n");
+    ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "va put buffer to surface failed.\n");
   }
   buffer_surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
-  H264_CHECK_STATUS(buffer_surface_id != VA_INVALID_SURFACE, H264_SURFACE_ERR, "surface id == VA_INVALID_SURFACE.\n");
+  ENCODER_CHECK_STATUS(buffer_surface_id != VA_INVALID_SURFACE, ENCODER_SURFACE_ERR, "surface id == VA_INVALID_SURFACE.\n");
 
   /* begin picture, using default sid 0*/
-  GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_LOCK(display);
   va_status = vaBeginPicture(va_dpy, context_id, buffer_surface_id);
-  GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_UNLOCK(display);
 
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, H264_PICTURE_ERR, "vaBeginPicture error.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaBeginPicture error.\n");
 
   /* set input buffers*/
-  is_key = ((h264_prv->frame_count % encoder->intra_period) == 0);
+  is_key = ((h264_prv->frame_count % h264_encoder->intra_period) == 0);
 
   /*get valid coded buffer*/
   g_mutex_lock(h264_prv->code_buffer_lock);
-  H264_ASSERT(h264_prv->available_code_buffers);
+  ENCODER_ASSERT(h264_prv->available_code_buffers);
   while (g_queue_is_empty(h264_prv->available_code_buffers)) {
     g_cond_wait(h264_prv->code_buffer_cond, h264_prv->code_buffer_lock);
   }
 
   coded_buf = (VABufferID*)g_queue_pop_head (h264_prv->available_code_buffers);
   ret = h264_prepare_encoding(h264_prv, raw_pic, is_key, *coded_buf);
-  if (H264_NO_ERROR != ret) {
+  if (ENCODER_NO_ERROR != ret) {
     g_queue_push_head(h264_prv->available_code_buffers, coded_buf);
   }
   g_mutex_unlock(h264_prv->code_buffer_lock);
 
-  H264_CHECK_STATUS(H264_NO_ERROR == ret, H264_PICTURE_ERR, "h264_prepare_encoding failed.\n");
+  ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ENCODER_PICTURE_ERR, "h264_prepare_encoding failed.\n");
 
   /* end picture */
-  GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_LOCK(display);
   va_status = vaEndPicture(va_dpy, context_id);
-  GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, H264_PICTURE_ERR, "vaEndPicture error.\n");
+  GST_VAAPI_DISPLAY_UNLOCK(display);
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaEndPicture error.\n");
 
   /*query surface result*/
   ret = h264_query_encoding_status(h264_prv, buffer_surface_id,
                                    is_key, GST_BUFFER_TIMESTAMP(raw_pic), GST_BUFFER_DURATION(raw_pic), coded_buf, coded_pics);
-  if (H264_NO_ERROR != ret) {
-    goto error;
+  if (ENCODER_NO_ERROR != ret) {
+    goto end;
   }
 
   h264_prv->frame_count++;
 
 
-  error:
+  end:
   if (new_surface) {
     h264_push_free_surface(h264_prv, new_surface);
   }
   return ret;
 }
 
-static H264Status
+static EncoderStatus
 h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
                                GstBuffer *raw_pic,
                                GstVaapiSurface *surface)
 {
-  H264Status ret = H264_NO_ERROR;
+  EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
   VAImage surface_image;
   VADisplay va_dpy;
@@ -969,9 +865,10 @@ h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
   uint32_t plane_count = 0;
   uint32_t image_width = 0, image_height = 0;
   uint32_t pitchy = 0, pitchu = 0, pitchv = 0;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  ENCODER_ASSERT(display);
+  va_dpy = gst_vaapi_display_get_display(display);
   /*map image*/
   image = gst_vaapi_surface_derive_image(surface);
   gst_vaapi_image_map(image);
@@ -981,10 +878,10 @@ h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
   image_height = gst_vaapi_image_get_height(image);
 
   /* copy buffer to surface */
-  H264_ASSERT(GST_BUFFER_SIZE(raw_pic) >= y_size + (y_size>>1));
+  ENCODER_ASSERT(GST_BUFFER_SIZE(raw_pic) >= y_size + (y_size>>1));
 
-  y_size = h264_prv->public->width * h264_prv->public->height;
-  u_size = ((h264_prv->public->width+1) >> 1) * ((h264_prv->public->height+1) >> 1);
+  y_size = ENCODER_WIDTH(h264_prv->public) * ENCODER_HEIGHT(h264_prv->public);
+  u_size = ((ENCODER_WIDTH(h264_prv->public)+1) >> 1) * ((ENCODER_HEIGHT(h264_prv->public)+1) >> 1);
 
   y_src = GST_BUFFER_DATA(raw_pic);
   u_src = y_src + y_size;
@@ -1006,7 +903,7 @@ h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
   for (row = 0; row < image_height; row++) {
       memcpy(y_dst, y_src, image_width);
       y_dst += pitchy;
-      y_src += h264_prv->public->width;
+      y_src += ENCODER_WIDTH(h264_prv->public);
   }
 
   if (GST_VAAPI_IMAGE_NV12 == image_format) { /* UV plane */
@@ -1018,68 +915,88 @@ h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
           }
 
           u_dst += pitchu;
-          u_src += (h264_prv->public->width>>1);
-          v_src += (h264_prv->public->width>>1);
+          u_src += (ENCODER_WIDTH(h264_prv->public)>>1);
+          v_src += (ENCODER_WIDTH(h264_prv->public)>>1);
       }
     } else if (GST_VAAPI_IMAGE_NV12 == h264_prv->format){
       for (row = 0; row < image_height / 2; row++) {
         memcpy(u_dst, u_src, image_width);
-        u_src += h264_prv->public->width;
+        u_src += ENCODER_WIDTH(h264_prv->public);
         u_dst += pitchu;
       }
     } else {
-      H264_ASSERT(0);
+      ENCODER_ASSERT(0);
     }
   } else {
       /* FIXME: fix this later */
-      H264_ASSERT(0);
+      ENCODER_ASSERT(0);
   }
 
   /*unmap image*/
   g_object_unref(image);
-  error:
+  end:
   return ret;
 }
 
 
-static H264Status
+static EncoderStatus
 h264_prepare_encoding(GstH264EncoderPrivate *h264_prv, GstBuffer *raw_pic, gboolean is_key, VABufferID coded_buf)
 {
-  H264Status ret = H264_NO_ERROR;
+  EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
+  GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
 
   VAEncPictureParameterBufferH264 pic_h264;
   VAEncSliceParameterBuffer *slice_h264 = NULL;
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(h264_prv->vaapi_context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  ENCODER_ASSERT(display);
+  ENCODER_ASSERT(h264_prv->vaapi_context);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
   VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
 
   /* lock display */
-  GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_LOCK(display);
   /*handle first surface_index*/
   /*only need first frame*/
-  if (h264_prv->frame_count == 0) {
+  if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
+    VAEncSequenceParameterBufferH264 seq_h264 = {0};
+
+    seq_h264.level_idc = h264_prv->public->level; /* 3.0 */
+    seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
+    seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_prv->public)+15)/16;
+    seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_prv->public)+15)/16;
+
+    seq_h264.bits_per_second = h264_prv->public->bitrate;
+    seq_h264.frame_rate = ENCODER_FPS(h264_prv->public);
+    seq_h264.initial_qp = h264_prv->public->init_qp; /*qp_value; 15, 24, 26?*/
+    seq_h264.min_qp = h264_prv->public->min_qp;     /*1, 6, 10*/
+    seq_h264.basic_unit_size = 0;
+    seq_h264.intra_period = h264_prv->public->intra_period;
+    seq_h264.intra_idr_period = h264_prv->public->intra_period;
+
+    va_status = vaCreateBuffer(va_dpy, context_id,
+                               VAEncSequenceParameterBufferType,
+                               sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
+    ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.\n");
     va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
-    H264_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, H264_PICTURE_ERR, "vaRenderPicture seq-parameters failed.\n");
+    ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.\n");
   }
 
   /* set pic_parameters*/
   if (!h264_prv->ref_surface) {
     h264_prv->ref_surface = h264_pop_free_surface(h264_prv);
-    H264_CHECK_STATUS(h264_prv->ref_surface, H264_SURFACE_ERR, "reference surface, h264_pop_free_surface failed.\n");
+    ENCODER_CHECK_STATUS(h264_prv->ref_surface, ENCODER_SURFACE_ERR, "reference surface, h264_pop_free_surface failed.\n");
   }
   if (!h264_prv->recon_surface) {
     h264_prv->recon_surface = h264_pop_free_surface(h264_prv);
-    H264_CHECK_STATUS(h264_prv->recon_surface, H264_SURFACE_ERR, "reconstructed surface, h264_pop_free_surface failed.\n");
+    ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR, "reconstructed surface, h264_pop_free_surface failed.\n");
   }
 
   pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface);
   pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
   pic_h264.coded_buf = coded_buf;
-  pic_h264.picture_width = h264_prv->public->width;
-  pic_h264.picture_height = h264_prv->public->height;
+  pic_h264.picture_width = ENCODER_WIDTH(h264_prv->public);
+  pic_h264.picture_height = ENCODER_HEIGHT(h264_prv->public);
   pic_h264.last_picture = 0; // last pic or not
 
   if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
@@ -1089,10 +1006,10 @@ h264_prepare_encoding(GstH264EncoderPrivate *h264_prv, GstBuffer *raw_pic, gbool
   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
                                sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
 
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_PICTURE_ERR, "creating pic-param buffer failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "creating pic-param buffer failed.\n");
 
   va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_PICTURE_ERR, "rendering pic-param buffer failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.\n");
 
   /* set slice parameters, support multiple slices */
   int i = 0;
@@ -1113,7 +1030,7 @@ h264_prepare_encoding(GstH264EncoderPrivate *h264_prv, GstBuffer *raw_pic, gbool
     slice_h264->slice_flags.bits.disable_deblocking_filter_idc = 0;
 
   }
-  H264_ASSERT(last_row_num == (h264_prv->public->height+15)/16);
+  ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_prv->public)+15)/16);
 
   if (VA_INVALID_ID != h264_prv->slice_parameter) {
     vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
@@ -1126,10 +1043,10 @@ h264_prepare_encoding(GstH264EncoderPrivate *h264_prv, GstBuffer *raw_pic, gbool
                              h264_prv->public->slice_num,
                              h264_prv->slice_param_buffers,
                              &h264_prv->slice_parameter);
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_PICTURE_ERR, "creating slice-parameters buffer failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.\n");
 
   va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_PICTURE_ERR, "rendering slice-parameters buffer failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.\n");
 
 
   /*after finished, set ref_surface_index, recon_surface_index */
@@ -1137,12 +1054,12 @@ h264_prepare_encoding(GstH264EncoderPrivate *h264_prv, GstBuffer *raw_pic, gbool
   h264_prv->ref_surface = h264_prv->recon_surface;
   h264_prv->recon_surface = swap;
 
-  error:
-  GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+  end:
+  GST_VAAPI_DISPLAY_UNLOCK(display);
   return ret;
 }
 
-static H264Status
+static EncoderStatus
 h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
                            VASurfaceID surface_id,
                            gboolean is_key,
@@ -1151,7 +1068,7 @@ h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
                            VABufferID *coded_buf,
                            GList **coded_pics)
 {
-  H264Status ret = H264_NO_ERROR;
+  EncoderStatus ret = ENCODER_NO_ERROR;
   VAStatus va_status = VA_STATUS_SUCCESS;
   VASurfaceStatus surface_status = 0;
   VACodedBufferSegment *buf_list = NULL;
@@ -1159,32 +1076,34 @@ h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
   gboolean has_coded_data = FALSE;
   gboolean is_locked = FALSE;
 
-  H264_ASSERT(h264_prv->vaapi_display);
-  H264_ASSERT(h264_prv->vaapi_context);
-  VADisplay va_dpy = gst_vaapi_display_get_display(h264_prv->vaapi_display);
+  GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
+
+  ENCODER_ASSERT(display);
+  ENCODER_ASSERT(h264_prv->vaapi_context);
+  VADisplay va_dpy = gst_vaapi_display_get_display(display);
   //VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
 
-  H264_ASSERT(coded_pics && *coded_pics == NULL);
+  ENCODER_ASSERT(coded_pics && *coded_pics == NULL);
 
   /* lock display */
-  GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+  GST_VAAPI_DISPLAY_LOCK(display);
   is_locked = TRUE;
 
   va_status = vaSyncSurface(va_dpy, surface_id);
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_QUERY_STATUS_ERR, "vaSyncSurface failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaSyncSurface failed.\n");
 
   va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_QUERY_STATUS_ERR, "vaQuerySurfaceStatus failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaQuerySurfaceStatus failed.\n");
   if (VASurfaceSkipped&surface_status) {
-    H264_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT ".\n", GST_TIME_ARGS(timestamp));
+    ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT ".\n", GST_TIME_ARGS(timestamp));
   }
 
   va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
-  H264_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, H264_QUERY_STATUS_ERR, "vaMapBuffer failed.\n");
+  ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaMapBuffer failed.\n");
 
   /*unlock display*/
   if (is_locked) {
-    GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+    GST_VAAPI_DISPLAY_UNLOCK(display);
     is_locked = FALSE;
   }
 
@@ -1200,7 +1119,7 @@ h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
       }
       *coded_pics = g_list_append(*coded_pics, ret_buffer);
       buf_list = (VACodedBufferSegment*)buf_list->next;
-      H264_ASSERT(NULL == buf_list);
+      ENCODER_ASSERT(NULL == buf_list);
       has_coded_data = TRUE;
   }
 
@@ -1209,20 +1128,20 @@ h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
 #endif
   { // if non-related, push back to available_code_buffers
     g_mutex_lock(h264_prv->code_buffer_lock);
-    GST_VAAPI_DISPLAY_LOCK(h264_prv->vaapi_display);
+    GST_VAAPI_DISPLAY_LOCK(display);
     vaUnmapBuffer(va_dpy, *coded_buf);
-    GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+    GST_VAAPI_DISPLAY_UNLOCK(display);
     g_queue_push_head(h264_prv->available_code_buffers, coded_buf);
     g_cond_signal(h264_prv->code_buffer_cond);
     g_mutex_unlock(h264_prv->code_buffer_lock);
   }
 
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 
-  error:
+  end:
   /*unlock display*/
   if (is_locked) {
-    GST_VAAPI_DISPLAY_UNLOCK(h264_prv->vaapi_display);
+    GST_VAAPI_DISPLAY_UNLOCK(display);
     is_locked = FALSE;
   }
   return ret;
@@ -1241,27 +1160,27 @@ h264_encoder_create_coded_buffer(GstH264EncoderPrivate *h264_prv,
 
 #if SHARE_CODED_BUF
   ret_buffer = gst_h264_encode_buffer_new(h264_prv, coded_buf);
-  H264_ASSERT(ret_buffer);
+  ENCODER_ASSERT(ret_buffer);
   GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
   GST_BUFFER_DATA(ret_buffer) = buf_list->buf;
   GST_BUFFER_SIZE(ret_buffer) = buf_list->size;
 #else
   ret_buffer = gst_buffer_new();
-  H264_ASSERT(ret_buffer);
+  ENCODER_ASSERT(ret_buffer);
   H264Bitstream bitstream;
   h264_bitstream_init(&bitstream, (frame_size+32)*8);
   h264_bitstream_align(&bitstream, 0);
-  H264_ASSERT(bitstream.bit_size == 0);
+  ENCODER_ASSERT(bitstream.bit_size == 0);
 
   if (!h264_prv->es_flag) { /*nal format*/
     h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
-    H264_ASSERT(bitstream.bit_size == frame_size*8);
+    ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
   } else { /* elementary format */
     frame_end = frame + frame_size;
     nal_start = frame;
     nal_size = 0;
     while((nal_start = h264_next_nal(nal_start, frame_end-nal_start, &nal_size)) != NULL) {
-      H264_ASSERT(nal_size);
+      ENCODER_ASSERT(nal_size);
       if (!nal_size) {
         nal_start += nal_size;
         continue;
@@ -1283,7 +1202,7 @@ h264_encoder_create_coded_buffer(GstH264EncoderPrivate *h264_prv,
 
 }
 
-static H264Status
+static EncoderStatus
 h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const uint8_t *buf, uint32_t size)
 {
   const uint8_t *end = buf + size;
@@ -1323,17 +1242,17 @@ h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const uint8_t *buf, u
 
   }
   if (!sps || !pps) {
-    return H264_DATA_NOT_READY;
+    return ENCODER_DATA_NOT_READY;
   }
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 }
 
 static gboolean
 h264_read_sps_attributes(const uint8_t *sps_data, uint32_t sps_size,
                                 uint32_t *profile_idc, uint32_t *profile_comp, uint32_t *level_idc)
 {
-  H264_ASSERT(profile_idc && profile_comp && level_idc);
-  H264_ASSERT(sps_size >= 4);
+  ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
+  ENCODER_ASSERT(sps_size >= 4);
   if (sps_size < 4) {
     return FALSE;
   }
@@ -1345,13 +1264,18 @@ h264_read_sps_attributes(const uint8_t *sps_data, uint32_t sps_size,
 }
 
 
-H264Status
-gst_h264_encoder_flush(GstH264Encoder* encoder, GList *coded_pics)
+EncoderStatus
+gst_h264_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics)
 {
-  H264Status ret = H264_NO_ERROR;
-  //GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
+  GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
+  EncoderStatus ret = ENCODER_NO_ERROR;
+  GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
+  GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
+
+  h264_prv->frame_count = 0;
+  /*do we need destroy h264_prv->seq_parameter? */
 
-  //error:
+  //end:
   return ret;
 }
 
@@ -1362,10 +1286,10 @@ static int draw_picture(int width, int height,
                          unsigned char *V_start,
                          int UV_interleave, int box_width, int row_shift);
 
-int main_test(int argc, const char* argv[])
+int main_test(int argc, char* argv[])
 {
-  H264Status ret = H264_NO_ERROR;
-  GstH264Encoder *encoder = NULL;
+  EncoderStatus ret = ENCODER_NO_ERROR;
+  GstVaapiEncoder *encoder = NULL;
 
   GList *coded_pics = NULL;
   GstBuffer **raw_buffer = NULL;
@@ -1381,26 +1305,23 @@ int main_test(int argc, const char* argv[])
   if (!g_thread_supported ())
     g_thread_init (NULL);
 
-  encoder = gst_h264_encoder_new();
-  H264_ASSERT(encoder && ret == H264_NO_ERROR);
-
-  encoder->profile = 64;
-  encoder->level = 30;
-  encoder->width = 1280;
-  encoder->height = 720;
-  encoder->frame_rate = 10;
-  encoder->bitrate = 512*1000;
-  encoder->intra_period = 30;
-  ret = gst_h264_encoder_initialize(encoder);
-  H264_ASSERT(ret == H264_NO_ERROR);
-  #ifdef _MRST_
-  ret = gst_h264_encoder_open(encoder, NULL);
-  #else
-  ret = gst_h264_encoder_open(encoder);
-  #endif
-  H264_ASSERT(ret == H264_NO_ERROR);
-
-  uint32_t buffer_size = encoder->width * encoder->height *3 /2;
+  GstH264Encoder *h264_encoder = gst_h264_encoder_new();
+  encoder = GST_VAAPI_ENCODER(h264_encoder);
+  ENCODER_ASSERT(encoder);
+
+  h264_encoder->profile = 64;
+  h264_encoder->level = 30;
+  h264_encoder->parent.width = 1280;
+  h264_encoder->parent.height = 720;
+  h264_encoder->parent.frame_rate = 10;
+  h264_encoder->bitrate = 512*1000;
+  h264_encoder->intra_period = 30;
+  ret = gst_vaapi_encoder_initialize(encoder);
+  ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
+  ret = gst_vaapi_encoder_open(encoder, NULL);
+  ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
+
+  uint32_t buffer_size = encoder->width * encoder->width *3 /2;
   uint32_t y_width = encoder->width, y_size = encoder->width * encoder->height;
   uint32_t u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
   uint32_t v_width = encoder->width/2;
@@ -1422,14 +1343,14 @@ int main_test(int argc, const char* argv[])
   }
 
   FILE *fp = fopen("tmp.h264", "wb");
-  H264_ASSERT(fp);
+  ENCODER_ASSERT(fp);
 
   k = 0;
 
   for (i = 0; i < 50; i++) {
     coded_pics = NULL;
-    ret = gst_h264_encoder_encode(encoder, raw_buffer[k], &coded_pics);
-    H264_ASSERT(H264_NO_ERROR == ret);
+    ret = gst_vaapi_encoder_encode(encoder, raw_buffer[k], &coded_pics);
+    ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
     ++k;
     if (k >= raw_buffer_num) k = 0;
 
@@ -1437,58 +1358,45 @@ int main_test(int argc, const char* argv[])
       tmp_buffer = coded_pics->data;
       coded_pics = g_list_remove(coded_pics, tmp_buffer);
       fwrite(GST_BUFFER_DATA(tmp_buffer), GST_BUFFER_SIZE(tmp_buffer), 1, fp);
-      printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), h264_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8));
+      printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8));
       gst_buffer_unref(tmp_buffer);
     }
   }
   fclose(fp);
 
-  ret = gst_h264_encoder_close(encoder);
-  H264_ASSERT(H264_NO_ERROR == ret);
+  ret = gst_vaapi_encoder_close(encoder);
+  ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
 
   for (i = 0; i < raw_buffer_num; i++) {
     gst_buffer_unref(raw_buffer[i]);
   }
   g_free(raw_buffer);
-  gst_h264_encoder_unref(encoder);
+  gst_vaapi_encoder_unref(encoder);
 
   return 0;
 }
 
-char *h264_dump_bytes(const uint8_t *buf, uint32_t num)
-{
-  static char tmp[1024];
-  uint32_t i = 0;
-  memset(tmp, 0, sizeof(tmp));
-
-  char *p = tmp;
-  for (i = 0; i < num; i++) {
-    snprintf(p, 1024-(p-tmp), "%02x", (uint8_t)buf[i]);
-    p += strlen(p);
-  }
-  return tmp;
-}
-
-H264Status
-gst_h264_encoder_get_avcC_codec_data(GstH264Encoder *encoder, GstBuffer **buffer)
+EncoderStatus
+gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
 {
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
+  GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
+  GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
   GstBuffer *avc_codec;
   const uint32_t configuration_version = 0x01;
   const uint32_t length_size_minus_one = 0x03;
   uint32_t profile, profile_comp, level_idc;
 
-  H264_ASSERT(buffer);
+  ENCODER_ASSERT(buffer);
   if (!h264_prv->sps_data || !h264_prv->pps_data) {
-    return H264_DATA_NOT_READY;
+    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),
                                    &profile, &profile_comp, &level_idc))
   {
-    H264_ASSERT(0);
-    return H264_DATA_ERR;
+    ENCODER_ASSERT(0);
+    return ENCODER_DATA_ERR;
   }
 
   H264Bitstream bitstream;
@@ -1506,7 +1414,7 @@ gst_h264_encoder_get_avcC_codec_data(GstH264Encoder *encoder, GstBuffer **buffer
 
   /*write sps*/
   h264_bitstream_write_uint(&bitstream, 1, 5);   /* sps count = 1*/
-  H264_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
+  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));
@@ -1525,18 +1433,19 @@ gst_h264_encoder_get_avcC_codec_data(GstH264Encoder *encoder, GstBuffer **buffer
   h264_bitstream_destroy(&bitstream, FALSE);
   *buffer = avc_codec;
 
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 }
 
-H264Status
-gst_h264_encoder_get_nal_codec_data(GstH264Encoder *encoder, GstBuffer **buffer)
+EncoderStatus
+gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
 {
-  GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
+  GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
+  GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
   GstBuffer *nal_sps_pps;
 
-  H264_ASSERT(buffer);
+  ENCODER_ASSERT(buffer);
   if (!h264_prv->sps_data || !h264_prv->pps_data) {
-    return H264_DATA_NOT_READY;
+    return ENCODER_DATA_NOT_READY;
   }
 
   H264Bitstream bitstream;
@@ -1558,7 +1467,7 @@ gst_h264_encoder_get_nal_codec_data(GstH264Encoder *encoder, GstBuffer **buffer)
   GST_BUFFER_SIZE(nal_sps_pps) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
   h264_bitstream_destroy(&bitstream, FALSE);
   *buffer = nal_sps_pps;
-  return H264_NO_ERROR;
+  return ENCODER_NO_ERROR;
 }
 
 static void
@@ -1584,11 +1493,11 @@ h264_bitstream_write_uint(H264Bitstream *bitstream, uint32_t value, uint32_t bit
     return TRUE;
   }
 
-  H264_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, bit_size), FALSE, "h264_bitstream_auto_grow failed.\n");
+  ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, bit_size), FALSE, "h264_bitstream_auto_grow failed.\n");
   byte_pos = (bitstream->bit_size>>3);
   bit_offset = (bitstream->bit_size&0x07);
   cur_byte = bitstream->buffer + byte_pos;
-  H264_ASSERT(bit_offset < 8 && bitstream->bit_size <= bitstream->max_bit_capability);
+  ENCODER_ASSERT(bit_offset < 8 && bitstream->bit_size <= bitstream->max_bit_capability);
 
   while (bit_size) {
     fill_bits = ((8-bit_offset) < bit_size ? (8-bit_offset) : bit_size);
@@ -1599,10 +1508,10 @@ h264_bitstream_write_uint(H264Bitstream *bitstream, uint32_t value, uint32_t bit
     ++cur_byte;
     bit_offset = 0;
   }
-  H264_ASSERT(cur_byte <= bitstream->buffer + bitstream->max_bit_capability/8);
+  ENCODER_ASSERT(cur_byte <= bitstream->buffer + bitstream->max_bit_capability/8);
   return TRUE;
 
-  error:
+  end:
   return FALSE;
 }
 
@@ -1627,12 +1536,12 @@ h264_bitstream_write_byte_array(H264Bitstream *bitstream, const uint8_t *buf, ui
   if (!byte_size) {
     return 0;
   }
-  H264_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, byte_size<<3), FALSE, "h264_bitstream_auto_grow failed.\n");
+  ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, byte_size<<3), FALSE, "h264_bitstream_auto_grow failed.\n");
   if (0 == (bitstream->bit_size&0x07)) {
     memcpy(&bitstream->buffer[bitstream->bit_size>>3], buf, byte_size);
     bitstream->bit_size += (byte_size<<3);
   } else {
-    H264_ASSERT(0);
+    ENCODER_ASSERT(0);
     while(byte_size) {
       h264_bitstream_write_uint(bitstream, *buf, 8);
       --byte_size;
@@ -1641,7 +1550,7 @@ h264_bitstream_write_byte_array(H264Bitstream *bitstream, const uint8_t *buf, ui
   }
   return TRUE;
 
-  error:
+  end:
   return FALSE;
 }
 
@@ -1655,11 +1564,11 @@ h264_bitstream_write_ue(H264Bitstream *bitstream, uint32_t value)
     ++size_in_bits;
     tmp_value >>= 1;
   }
-  H264_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1), FALSE, "h264_bitstream_write_ue failed.\n");
-  H264_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits), FALSE, "h264_bitstream_write_ue failed.\n");
+  ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1), FALSE, "h264_bitstream_write_ue failed.\n");
+  ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits), FALSE, "h264_bitstream_write_ue failed.\n");
   return TRUE;
 
-  error:
+  end:
   return FALSE;
 }
 
@@ -1675,10 +1584,10 @@ h264_bitstream_write_se(H264Bitstream *bitstream, int32_t value)
     new_val = (value<<1) - 1;
   }
 
-  H264_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val), FALSE, "h264_bitstream_write_se failed.\n");
+  ENCODER_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val), FALSE, "h264_bitstream_write_se failed.\n");
   return TRUE;
 
-  error:
+  end:
   return FALSE;
 }
 
@@ -1707,14 +1616,14 @@ h264_bitstream_auto_grow(H264Bitstream *bitstream, uint32_t extra_bit_size)
   uint32_t new_bit_size = extra_bit_size + bitstream->bit_size;
   uint32_t clear_pos;
 
-  H264_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
+  ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
   if (new_bit_size <= bitstream->max_bit_capability) {
     return TRUE;
   }
 
   new_bit_size = ((new_bit_size + H264_BITSTREAM_ALLOC_ALIGN_MASK)
                 &(~H264_BITSTREAM_ALLOC_ALIGN_MASK));
-  H264_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
+  ENCODER_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
   clear_pos = ((bitstream->bit_size+7)>>3);
   bitstream->buffer = realloc(bitstream->buffer, new_bit_size>>3);
   memset(bitstream->buffer+clear_pos, 0, (new_bit_size>>3)-clear_pos);
@@ -1734,8 +1643,8 @@ h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_p
   uint32_t log2_max_pic_order_cnt_lsb_minus4 = 0;  // 2 ? 4?
   uint32_t num_ref_frames = 1;  // only P frames
   uint32_t gaps_in_frame_num_value_allowed_flag = 0; // ??
-  uint32_t mb_width = (h264_prv->public->width+15)/16; // mb_width
-  uint32_t mb_height = (h264_prv->public->height+15)/16; // mb_height
+  uint32_t mb_width = (ENCODER_WIDTH(h264_prv->public)+15)/16; // mb_width
+  uint32_t mb_height = (ENCODER_HEIGHT(h264_prv->public)+15)/16; // mb_height
   int32_t frame_mbs_only_flag = 1; // only mbs
   uint32_t frame_cropping_flag = 0;
   uint32_t frame_crop_bottom_offset = 0;
@@ -1747,10 +1656,10 @@ h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_p
   constraint_set2_flag = 0;
   constraint_set3_flag = 0;
 
-  if (mb_height * 16 - h264_prv->public->height) {
+  if (mb_height * 16 - ENCODER_HEIGHT(h264_prv->public)) {
     frame_cropping_flag = 1;
     frame_crop_bottom_offset =
-        (mb_height * 16 - h264_prv->public->height) / (2 * (!frame_mbs_only_flag + 1));
+        (mb_height * 16 - ENCODER_HEIGHT(h264_prv->public)) / (2 * (!frame_mbs_only_flag + 1));
   }
 
   h264_bitstream_write_uint(bitstream, h264_prv->public->profile, 8); /* profile_idc */
@@ -1764,7 +1673,7 @@ h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_p
 
   if (h264_prv->public->profile >= H264_PROFILE_HIGH) {
       /* FIXME: fix for high profile */
-      H264_ASSERT(0);
+      ENCODER_ASSERT(0);
   }
 
   h264_bitstream_write_ue(bitstream, log2_max_frame_num_minus4);    /* log2_max_frame_num_minus4 */
@@ -1773,7 +1682,7 @@ h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_p
   if (pic_order_cnt_type == 0)
       h264_bitstream_write_ue(bitstream, log2_max_pic_order_cnt_lsb_minus4);/* log2_max_pic_order_cnt_lsb_minus4 */
   else {
-      H264_ASSERT(0);
+      ENCODER_ASSERT(0);
   }
 
   h264_bitstream_write_ue(bitstream, num_ref_frames);                            /* num_ref_frames */
@@ -1784,7 +1693,7 @@ h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_p
   h264_bitstream_write_uint(bitstream, frame_mbs_only_flag, 1);  /* frame_mbs_only_flag */
 
   if (!frame_mbs_only_flag) { //ONLY mbs
-      H264_ASSERT(0);
+      ENCODER_ASSERT(0);
   }
 
   h264_bitstream_write_uint(bitstream, 0, 1);                         /* direct_8x8_inference_flag */
@@ -1801,7 +1710,7 @@ h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_p
   h264_bitstream_write_trailing_bits(bitstream);                             /* rbsp_trailing_bits */
   return TRUE;
 
-  //error:
+  //end:
   //return FALSE;
 
 }
@@ -1815,7 +1724,7 @@ h264_next_nal(const uint8_t *buffer, uint32_t len, uint32_t *nal_size)
     uint32_t flag = 0xFFFFFFFF;
     uint32_t nal_start_len = 0;
 
-    H264_ASSERT(len >= 0 && buffer && nal_size);
+    ENCODER_ASSERT(len >= 0 && buffer && nal_size);
     if (len < 3) {
         *nal_size = len;
         nal_start = (len ? buffer : NULL);
@@ -1857,7 +1766,7 @@ h264_next_nal(const uint8_t *buffer, uint32_t len, uint32_t *nal_size)
 static gboolean
 h264_bitstream_write_pps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv)
 {
-  H264_ASSERT(0);
+  ENCODER_ASSERT(0);
   return TRUE;
 }
 
index fc43522..785a3db 100644 (file)
@@ -2,46 +2,13 @@
 #ifndef _GST_H264_ENCODER_H_
 #define _GST_H264_ENCODER_H_
 
-#include <stdio.h>
-#include <stdint.h>
 
-#include "gst/gstbuffer.h"
-#include "gst/vaapi/gstvaapidisplay.h"
 #include "gst/vaapi/gstvaapisurfacepool.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef DEBUG
-#include <assert.h>
-#define H264_ASSERT(exp) assert(exp)
-#else
-#define H264_ASSERT(exp)
-#endif
-
-#define H264_NO_ERROR       0
-#define H264_MEM_ERR       -1
-#define H264_DISPLAY_ERR   -2
-#define H264_CONFIG_ERR    -3
-#define H264_CONTEXT_ERR    -3
-#define H264_STATE_ERR     -4
-#define H264_ENC_RES_ERR   -5
-#define H264_PICTURE_ERR   -6
-#define H264_SURFACE_ERR   -7
-#define H264_QUERY_STATUS_ERR -8
-#define H264_DATA_NOT_READY   -9
-#define H264_DATA_ERR      -10
-#define H264_PROFILE_ERR   -11
-#define H264_PARAMETER_ERR -12
-
-
-#define H264_LOG_ERROR(...) fprintf(stdout, ## __VA_ARGS__)
-#define H264_LOG_DEBUG(...) fprintf(stdout, ## __VA_ARGS__)
-#define H264_LOG_INFO(...)  fprintf(stdout, ## __VA_ARGS__)
-
-
-typedef int                                 H264Status;
+#include "gstvaapiencoder.h"
+
+G_BEGIN_DECLS
+
 typedef struct _GstH264Encoder              GstH264Encoder;
 typedef struct _GstH264EncoderPrivate       GstH264EncoderPrivate;
 typedef struct _GstH264EncoderClass         GstH264EncoderClass;
@@ -56,13 +23,6 @@ typedef struct _GstH264EncoderClass         GstH264EncoderClass;
 #define GST_H264_ENCODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GST_TYPE_H264_ENCODER,GstH264EncoderPrivate))
 
 typedef enum {
-  H264_ENC_NULL,
-  H264_ENC_INIT,
-  H264_ENC_OPENED,
-  H264_ENC_ENCODING,
-} H264_Encode_State;
-
-typedef enum {
   H264_PROFILE_BASELINE = 66,
   H264_PROFILE_MAIN     = 77,
   H264_PROFILE_EXTENDED = 88,
@@ -100,13 +60,13 @@ typedef enum {
 #define H264_DEFAULT_SLICE_NUM    1
 
 struct _GstH264Encoder {
-  GObject parent;   /*based on gobject*/
+  GstVaapiEncoder parent;   /*based on gobject*/
 
   uint32_t profile;
   uint32_t level;
-  uint32_t width;
-  uint32_t height;
-  uint32_t frame_rate;
+  //uint32_t width;
+  //uint32_t height;
+  //uint32_t frame_rate;
   uint32_t bitrate;
   uint32_t intra_period;
   int32_t  init_qp;  /*default 24*/
@@ -116,7 +76,7 @@ struct _GstH264Encoder {
 };
 
 struct _GstH264EncoderClass {
-    GObjectClass parent_class;
+    GstVaapiEncoderClass parent_class;
 };
 
 
@@ -130,39 +90,9 @@ static inline void gst_h264_encoder_unref (GstH264Encoder * encoder)
 
 void     gst_h264_encoder_set_input_format(GstH264Encoder* encoder, uint32_t format);
 void     gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es);
-gboolean gst_h264_encoder_set_display(GstH264Encoder* encoder, GstVaapiDisplay *display);
-GstVaapiDisplay *gst_h264_encoder_get_display(GstH264Encoder* encoder);
-
-
-H264Status gst_h264_encoder_initialize(GstH264Encoder* encoder);
-H264Status gst_h264_encoder_uninitialize(GstH264Encoder* encoder);
-
-gboolean   gst_h264_validate_parameters(GstH264Encoder *encoder);
 
-/**/
-#ifdef _MRST_
-H264Status gst_h264_encoder_open(GstH264Encoder* encoder, GstVaapiSurfacePool *surfaces_pool);
-#else
-H264Status gst_h264_encoder_open(GstH264Encoder* encoder);
-#endif
 
-H264Status gst_h264_encoder_close(GstH264Encoder* encoder);
-
-
-H264Status gst_h264_encoder_encode(GstH264Encoder* encoder, GstBuffer *raw_pic, GList **coded_pics);
-H264Status gst_h264_encoder_flush(GstH264Encoder* encoder, GList *coded_pics);
-
-H264_Encode_State gst_h264_encoder_get_state(GstH264Encoder* encoder);
-
-/*other functions*/
-char      *h264_dump_bytes(const uint8_t *buf, uint32_t num);
-H264Status gst_h264_encoder_get_avcC_codec_data(GstH264Encoder* encoder, GstBuffer **buffer);
-H264Status gst_h264_encoder_get_nal_codec_data(GstH264Encoder* encoder, GstBuffer **buffer);
-
-
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
 
 #endif /*_GST_H264_ENCODER_H_ */