G_DEFINE_TYPE(GstVaapiBaseEncoder, gst_vaapi_base_encoder, GST_TYPE_VAAPI_ENCODER);
-static EncoderStatus gst_vaapi_base_encoder_initialize_default(
- GstVaapiEncoder* encoder, GstVaapiDisplay *display);
-static EncoderStatus gst_vaapi_base_encoder_uninitialize_default(
- GstVaapiEncoder* encoder, GstVaapiDisplay *display);
-static EncoderStatus gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder,
- GstVaapiDisplay *display,
- GstVaapiContext **context);
-static EncoderStatus gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder,
- GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder,
- GstVaapiDisplay *display, GstVaapiContext *context,
- GstBuffer *raw_pic, GList **coded_pics);
-static EncoderStatus gst_vaapi_base_encoder_flush_default(GstVaapiEncoder* encoder,
- GstVaapiDisplay *display,
- GstVaapiContext *context,
- GList **coded_pics);
-static GstBuffer *gst_vaapi_base_encoder_copy_buffer_default(GstVaapiBaseEncoder *encoder,
- guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
-
-
-static gboolean base_encoder_alloc_coded_buffers(GstVaapiBaseEncoder *base_encoder,
- GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus base_encoder_release_coded_buffers(GstVaapiBaseEncoder *base_encoder,
- GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus base_query_encoding_status(GstVaapiBaseEncoder *base_encoder,
- GstVaapiDisplay *display, GstVaapiSurface *buffer_surface,
- gboolean is_key, GstVaapiVideoBuffer *surface_buffer,
- VABufferID *coded_buf, GList **coded_pics);
-
-static VABufferID *pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *base_prv);
+static VABufferID *pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv);
static gboolean push_available_coded_buffer(
- GstVaapiBaseEncoderPrivate *base_prv, VABufferID *buf);
+ GstVaapiBaseEncoderPrivate *priv, VABufferID *buf);
+void
+gst_vaapi_base_encoder_set_frame_notify(GstVaapiBaseEncoder *encoder, gboolean flag)
+{
+ GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+ priv->frame_notify_flag = flag;
+}
-static void
-gst_vaapi_base_encoder_finalize(GObject *object)
+gboolean
+gst_vaapi_base_encoder_set_va_profile(GstVaapiBaseEncoder *encoder, guint profile)
{
- /*free private buffers*/
- GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(object);
+ GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+ priv->profile = profile;
+ return TRUE;
+}
- if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
- gst_vaapi_encoder_uninitialize(encoder);
- }
+void
+gst_vaapi_base_encoder_set_input_format(GstVaapiBaseEncoder* encoder, guint32 format)
+{
+ GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+ priv->format = format;
+}
- g_mutex_free(base_prv->code_buffer_lock);
- g_cond_free(base_prv->code_buffer_cond);
- if (base_prv->available_code_buffers) {
- g_queue_free(base_prv->available_code_buffers);
- base_prv->available_code_buffers = NULL;
+static gboolean
+default_validate_encoder_parameters(GstVaapiBaseEncoder *encoder)
+{
+ if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
+ return FALSE;
}
-
- G_OBJECT_CLASS(gst_vaapi_base_encoder_parent_class)->finalize(object);
+ return TRUE;
}
-
-static void
-gst_vaapi_base_encoder_class_init(GstVaapiBaseEncoderClass *klass)
+static gboolean
+base_encoder_alloc_coded_buffers(
+ GstVaapiBaseEncoder *base_encoder,
+ GstVaapiContext *context
+)
{
- GObjectClass * const object_class = G_OBJECT_CLASS(klass);
- GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
- g_type_class_add_private(klass, sizeof(GstVaapiBaseEncoderPrivate));
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+ VADisplay va_dpy;
+ VAContextID context_id;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ gboolean is_locked = FALSE;
+ guint i = 0;
+ gboolean ret = TRUE;
+ guint32 buffer_size = (ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder) * 400) / (16*16);
- GST_DEBUG_CATEGORY_INIT (gst_vaapi_base_encoder_debug, "gst_vaapi_base_encoder", 0,
- "gst_vaapi_base_encoder element");
+ ENCODER_ASSERT(display && context);
+ ENCODER_ASSERT(priv->available_code_buffers);
+ ENCODER_ASSERT(!priv->coded_bufs);
- object_class->finalize = gst_vaapi_base_encoder_finalize;
+ va_dpy = ENCODER_VA_DISPLAY(base_encoder);
+ context_id = gst_vaapi_context_get_id(context);
- encoder_class->initialize = gst_vaapi_base_encoder_initialize_default;
- encoder_class->uninitialize = gst_vaapi_base_encoder_uninitialize_default;
- encoder_class->open = gst_vaapi_base_encoder_open_default;
- encoder_class->close = gst_vaapi_base_encoder_close_default;
- encoder_class->encode = gst_vaapi_base_encoder_encode_default;
- encoder_class->flush = gst_vaapi_base_encoder_flush_default;
- encoder_class->get_codec_data = NULL;
+ priv->coded_bufs = (VABufferID*)g_malloc0(priv->coded_buf_num * sizeof(priv->coded_bufs[0]));
- /* user defined functions*/
- klass->validate_attributes = NULL;
- klass->pre_alloc_resource = NULL;
- klass->release_resource = NULL;
- klass->prepare_next_input_buffer = NULL;
- klass->render_frame = NULL;
- klass->notify_frame = NULL;
- klass->copy_coded_frame = NULL;
- klass->encode_frame_failed = NULL;
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ for (i = 0; i < priv->coded_buf_num; i++) {
+ va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
+ buffer_size, 1, NULL, &priv->coded_bufs[i]);
+ if (VA_STATUS_SUCCESS != va_status)
+ break;
+ }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, FALSE, "create coded buffer failed.");
- /*
- object_class->set_property = gst_vaapi_base_encoder_set_property;
- object_class->get_property = gst_vaapi_base_encoder_get_property;
- */
-}
+ /* init queue available_code_buffers */
+ g_mutex_lock(priv->code_buffer_lock);
+ for (i = 0; i < priv->coded_buf_num; i++) {
+ g_queue_push_head(priv->available_code_buffers, &priv->coded_bufs[i]);
+ }
+ g_cond_signal(priv->code_buffer_cond);
+ g_mutex_unlock(priv->code_buffer_lock);
-static void
-gst_vaapi_base_encoder_init(GstVaapiBaseEncoder *encoder)
-{
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
- ENCODER_ASSERT(base_prv);
+end:
+ return ret;
- /* init private values*/
- base_prv->format = 0;
- base_prv->profile= VA_INVALID_PROFILE;
- base_prv->frame_count = 0;
- base_prv->frame_notify_flag = FALSE;
-
- base_prv->coded_bufs = NULL;
- base_prv->coded_buf_num = DEFAULT_VA_CODEDBUF_NUM;
- base_prv->code_buffer_lock = g_mutex_new();
- base_prv->code_buffer_cond = g_cond_new();
- base_prv->available_code_buffers = g_queue_new();
-
- base_prv->need_flush = FALSE;
}
-void
-gst_vaapi_base_encoder_set_frame_notify(GstVaapiBaseEncoder *encoder, gboolean flag)
+static EncoderStatus
+base_encoder_release_coded_buffers(GstVaapiBaseEncoder *base_encoder)
{
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
- base_prv->frame_notify_flag = flag;
-}
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+ guint32 available_buf_count = priv->coded_buf_num;
+ guint32 i;
+ gboolean is_locked = FALSE;
-gboolean
-gst_vaapi_base_encoder_set_va_profile(GstVaapiBaseEncoder *encoder, guint profile)
-{
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
- base_prv->profile = profile;
- return TRUE;
-}
+ ENCODER_ASSERT(display);
+ VAAPI_UNUSED_ARG(va_status);
+ VADisplay va_dpy = gst_vaapi_display_get_display(display);
-void
-gst_vaapi_base_encoder_set_input_format(GstVaapiBaseEncoder* encoder, guint32 format)
-{
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
- base_prv->format = format;
-}
+ /* wait clear all available coded buffers*/
+ g_mutex_lock(priv->code_buffer_lock);
+ while (available_buf_count) {
+ if (g_queue_is_empty(priv->available_code_buffers)) {
+ g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
+ } else {
+ g_queue_pop_head(priv->available_code_buffers);
+ available_buf_count--;
+ }
+ }
+ g_mutex_unlock(priv->code_buffer_lock);
+
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ for (i = 0; i < priv->coded_buf_num; i++) {
+ va_status = vaDestroyBuffer(va_dpy, priv->coded_bufs[i]);
+ }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
-EncoderStatus
-gst_vaapi_base_encoder_initialize_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
-{
return ENCODER_NO_ERROR;
}
-EncoderStatus
-gst_vaapi_base_encoder_uninitialize_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
+static EncoderStatus
+gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder)
{
- return ENCODER_NO_ERROR;
+ GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
+ GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ EncoderStatus ret = ENCODER_NO_ERROR;
-}
+ /* release buffers first */
+ priv->need_flush = FALSE;
-gboolean
-default_validate_encoder_parameters(GstVaapiBaseEncoder *encoder)
-{
- if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
- return FALSE;
+ if (base_class->release_resource) {
+ base_class->release_resource(base_encoder);
}
- return TRUE;
+ base_encoder_release_coded_buffers(base_encoder);
+ priv->frame_count = 0;
+
+ return ret;
}
-EncoderStatus
-gst_vaapi_base_encoder_open_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext **context)
+static EncoderStatus
+gst_vaapi_base_encoder_open_default(
+ GstVaapiEncoder* encoder,
+ GstVaapiContext **context
+)
{
GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
GstVaapiContext *out_context = NULL;
check_attri_ret = default_validate_encoder_parameters(base_encoder);
}
ENCODER_CHECK_STATUS(check_attri_ret, ENCODER_PARAMETER_ERR, "vaapi encoder paramerter error.");
- ENCODER_CHECK_STATUS(VA_INVALID_PROFILE != base_prv->profile, ENCODER_PROFILE_ERR, "vaapi encoder profile not set.");
+ ENCODER_CHECK_STATUS(VA_INVALID_PROFILE != priv->profile, ENCODER_PROFILE_ERR, "vaapi encoder profile not set.");
ENCODER_ASSERT(ENCODER_DISPLAY(encoder));
out_context = gst_vaapi_context_new(display,
- gst_vaapi_profile(base_prv->profile),
+ gst_vaapi_profile(priv->profile),
gst_vaapi_entrypoint(VAEntrypointEncSlice),
ENCODER_WIDTH(encoder),
ENCODER_HEIGHT(encoder));
ENCODER_CHECK_STATUS(VA_INVALID_ID != GST_VAAPI_OBJECT_ID(out_context), ENCODER_CONTEXT_ERR, "gst_vaapi_context_new failed.");
if (base_class->pre_alloc_resource) {
- ENCODER_CHECK_STATUS(base_class->pre_alloc_resource(base_encoder, display, out_context),
+ ENCODER_CHECK_STATUS(base_class->pre_alloc_resource(base_encoder, out_context),
ENCODER_MEM_ERR, "encoder <pre_alloc_resource> failed.");
}
ENCODER_CHECK_STATUS(
- base_encoder_alloc_coded_buffers(base_encoder, display, out_context),
+ base_encoder_alloc_coded_buffers(base_encoder, out_context),
ENCODER_MEM_ERR,
"encoder <base_encoder_alloc_coded_buffers> failed."
);
end:
// clear resources
if (ENCODER_NO_ERROR != ret) {
- gst_vaapi_base_encoder_close_default(encoder, display, out_context);
+ gst_vaapi_base_encoder_close_default(encoder);
if (out_context) {
g_object_unref(out_context);
}
return ret;
}
-EncoderStatus
-gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+static GstBuffer *
+gst_vaapi_base_encoder_copy_buffer_default(GstVaapiBaseEncoder *encoder,
+ guint8 *frame,
+ guint32 frame_size,
+ VABufferID *coded_buf)
{
- GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
- GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
- EncoderStatus ret = ENCODER_NO_ERROR;
-
- /* release buffers first */
- base_prv->need_flush = FALSE;
-
- if (base_class->release_resource) {
- base_class->release_resource(base_encoder, display, context);
- }
- base_encoder_release_coded_buffers(base_encoder, display, context);
- base_prv->frame_count = 0;
-
- return ret;
+ GstBuffer *ret_buffer = NULL;
+#if SHARE_CODED_BUF
+ ret_buffer = gst_base_encode_share_buffer_new(encoder, coded_buf);
+ ENCODER_ASSERT(ret_buffer);
+ GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
+ GST_BUFFER_DATA(ret_buffer) = frame;
+ GST_BUFFER_SIZE(ret_buffer) = frame_size;
+#else
+ ret_buffer = gst_buffer_new_and_alloc(frame_size);
+ memcpy(GST_BUFFER_DATA(ret_buffer),frame, frame_size);
+#endif
+ return ret_buffer;
}
-static gboolean
-base_encoder_alloc_coded_buffers(GstVaapiBaseEncoder *base_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+static EncoderStatus
+base_query_encoding_status(GstVaapiBaseEncoder *base_encoder,
+ GstVaapiSurface *buffer_surface,
+ gboolean is_key,
+ GstVaapiVideoBuffer *surface_buffer,
+ VABufferID *coded_buf,
+ GList **coded_pics)
{
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-
- ENCODER_ASSERT(display && context);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ EncoderStatus ret = ENCODER_NO_ERROR;
VAStatus va_status = VA_STATUS_SUCCESS;
+ VASurfaceStatus surface_status = 0;
+ VACodedBufferSegment *buf_list = NULL;
+ GstBuffer* ret_buffer = NULL;
+ gboolean has_coded_data = FALSE;
gboolean is_locked = FALSE;
- guint i = 0;
- gboolean ret = TRUE;
- guint32 buffer_size = (ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder) * 400) / (16*16);
+ GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(base_encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
- ENCODER_ASSERT(base_prv->available_code_buffers);
- ENCODER_ASSERT(!base_prv->coded_bufs);
+ ENCODER_ASSERT(display);
+ VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(base_encoder);
- base_prv->coded_bufs = (VABufferID*)g_malloc0(base_prv->coded_buf_num * sizeof(base_prv->coded_bufs[0]));
+ ENCODER_ASSERT(coded_pics);
+ VAAPI_UNUSED_ARG(has_coded_data);
+ /* lock display */
ENCODER_ACQUIRE_DISPLAY_LOCK(display);
- for (i = 0; i < base_prv->coded_buf_num; i++) {
- va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
- buffer_size, 1, NULL, &base_prv->coded_bufs[i]);
- if (VA_STATUS_SUCCESS != va_status)
- break;
- }
- ENCODER_RELEASE_DISPLAY_LOCK(display);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, FALSE, "create coded buffer failed.");
- /* init queue available_code_buffers */
- g_mutex_lock(base_prv->code_buffer_lock);
- for (i = 0; i < base_prv->coded_buf_num; i++) {
- g_queue_push_head(base_prv->available_code_buffers, &base_prv->coded_bufs[i]);
- }
- g_cond_signal(base_prv->code_buffer_cond);
- g_mutex_unlock(base_prv->code_buffer_lock);
+ va_status = vaSyncSurface(va_dpy, surface_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaSyncSurface failed.");
-end:
- return ret;
+ va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaQuerySurfaceStatus failed.");
+ if (VASurfaceSkipped&surface_status) {
+ ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(surface_buffer)));
+ }
-}
+ va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaMapBuffer failed.");
-static EncoderStatus
-base_encoder_release_coded_buffers(GstVaapiBaseEncoder *base_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
-{
- VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
- guint32 available_buf_count = base_prv->coded_buf_num;
- guint32 i;
- gboolean is_locked = FALSE;
+ /*unlock display*/
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
- ENCODER_ASSERT(display);
- ENCODER_ASSERT(context);
- VAAPI_UNUSED_ARG(va_status);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
+ while (buf_list != NULL) {
+ if (priv->frame_notify_flag && base_class->notify_frame) {
+ base_class->notify_frame(base_encoder, buf_list->buf, buf_list->size);
+ }
- /* wait clear all available coded buffers*/
- g_mutex_lock(base_prv->code_buffer_lock);
- while (available_buf_count) {
- if (g_queue_is_empty(base_prv->available_code_buffers)) {
- g_cond_wait(base_prv->code_buffer_cond, base_prv->code_buffer_lock);
- } else {
- g_queue_pop_head(base_prv->available_code_buffers);
- available_buf_count--;
- }
+ if (base_class->copy_coded_frame) {
+ ret_buffer = base_class->copy_coded_frame(
+ base_encoder, buf_list->buf,
+ buf_list->size, coded_buf);
+ } else {
+ ret_buffer = gst_vaapi_base_encoder_copy_buffer_default(
+ base_encoder, buf_list->buf,
+ buf_list->size, coded_buf);
+ }
+ GST_BUFFER_TIMESTAMP(ret_buffer) = GST_BUFFER_TIMESTAMP(surface_buffer);
+ GST_BUFFER_DURATION(ret_buffer) = GST_BUFFER_DURATION(surface_buffer);
+ if (!is_key) {
+ GST_BUFFER_FLAG_SET(ret_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ }
+ GST_BUFFER_OFFSET_END(ret_buffer) = GST_BUFFER_OFFSET_END(surface_buffer);
+ *coded_pics = g_list_append(*coded_pics, ret_buffer);
+ buf_list = (VACodedBufferSegment*)buf_list->next;
+ ENCODER_ASSERT(NULL == buf_list);
+ has_coded_data = TRUE;
+ FPS_CALCULATION(vaapiencode);
}
- g_mutex_unlock(base_prv->code_buffer_lock);
- ENCODER_ACQUIRE_DISPLAY_LOCK(display);
- for (i = 0; i < base_prv->coded_buf_num; i++) {
- va_status = vaDestroyBuffer(va_dpy, base_prv->coded_bufs[i]);
+#if SHARE_CODED_BUF
+ if (!has_coded_data)
+#endif
+ { // if non-related, push back to available_code_buffers
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ vaUnmapBuffer(va_dpy, *coded_buf);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ push_available_coded_buffer(priv, coded_buf);
}
- ENCODER_RELEASE_DISPLAY_LOCK(display);
return ENCODER_NO_ERROR;
+
+end:
+ /*unlock display*/
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ return ret;
}
-EncoderStatus
-gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstBuffer *raw_pic, GList **coded_pics)
+static EncoderStatus
+gst_vaapi_base_encoder_encode_default(GstVaapiEncoder* encoder,
+ GstBuffer *raw_pic,
+ GList **coded_pics
+)
{
GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+ GstVaapiContext *context = ENCODER_CONTEXT(encoder);
EncoderStatus ret = ENCODER_NO_ERROR;
gboolean is_key = FALSE;
VABufferID* coded_buf = NULL;
VAStatus va_status = VA_STATUS_SUCCESS;
VASurfaceID buffer_surface_id = VA_INVALID_SURFACE;
GstVaapiSurface *buffer_surface = NULL;
-
gboolean is_locked = FALSE;
+ VADisplay va_dpy;
+ VAContextID context_id;
ENCODER_ASSERT(display && context);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ va_dpy = ENCODER_VA_DISPLAY(encoder);
+ context_id = ENCODER_VA_CONTEXT(encoder);
/* Video Buffer */
GstVaapiVideoBuffer *video_buffer = NULL;
/* do something else */
}
} else {
- base_prv->need_flush = TRUE;
+ priv->need_flush = TRUE;
}
again:
if (base_class->prepare_next_input_buffer) {
GstVaapiVideoBuffer* tmp_buf = NULL;
- ret = base_class->prepare_next_input_buffer(base_encoder, video_buffer, base_prv->need_flush, &tmp_buf);
- base_prv->need_flush = FALSE;
+ ret = base_class->prepare_next_input_buffer(base_encoder, video_buffer, priv->need_flush, &tmp_buf);
+ priv->need_flush = FALSE;
if (video_buffer) {
gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
video_buffer = NULL;
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaBeginPicture error.");
/*get valid coded buffer*/
- coded_buf = pop_available_coded_buffer(base_prv);
+ coded_buf = pop_available_coded_buffer(priv);
ENCODER_CHECK_STATUS(coded_buf, ENCODER_ENC_RES_ERR, "dequeue_available_coded_buffer error.");
/* prepare frame*/
- ret = base_class->render_frame(base_encoder, display, context,
- buffer_surface, base_prv->frame_count,
- *coded_buf, &is_key);
+ ret = base_class->render_frame(base_encoder,
+ buffer_surface,
+ priv->frame_count,
+ *coded_buf,
+ &is_key);
/* prepare failed, push back */
if (ENCODER_NO_ERROR != ret) {
- push_available_coded_buffer(base_prv, coded_buf);
+ push_available_coded_buffer(priv, coded_buf);
}
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ENCODER_PICTURE_ERR, "base_prepare_encoding failed.");
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaEndPicture error.");
/*query surface result*/
- ret = base_query_encoding_status(base_encoder, display, buffer_surface,
+ ret = base_query_encoding_status(base_encoder, buffer_surface,
is_key, video_buffer, coded_buf, coded_pics);
if (ENCODER_NO_ERROR != ret) {
goto end;
}
- base_prv->frame_count++;
+ priv->frame_count++;
if (base_class->prepare_next_input_buffer) {
if (video_buffer) {
}
static VABufferID *
-pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *base_prv)
+pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv)
{
VABufferID *coded_buf = NULL;
gboolean ret = TRUE;
- g_mutex_lock(base_prv->code_buffer_lock);
+ g_mutex_lock(priv->code_buffer_lock);
- ENCODER_CHECK_STATUS(base_prv->available_code_buffers, FALSE, "coded buffer not found");
- while (g_queue_is_empty(base_prv->available_code_buffers)) {
- g_cond_wait(base_prv->code_buffer_cond, base_prv->code_buffer_lock);
+ ENCODER_CHECK_STATUS(priv->available_code_buffers, FALSE, "coded buffer not found");
+ while (g_queue_is_empty(priv->available_code_buffers)) {
+ g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
}
- coded_buf = (VABufferID*)g_queue_pop_head (base_prv->available_code_buffers);
+ coded_buf = (VABufferID*)g_queue_pop_head (priv->available_code_buffers);
end:
- g_mutex_unlock(base_prv->code_buffer_lock);
+ g_mutex_unlock(priv->code_buffer_lock);
VAAPI_UNUSED_ARG(ret);
return coded_buf;
}
static gboolean
-push_available_coded_buffer(GstVaapiBaseEncoderPrivate *base_prv, VABufferID *buf)
+push_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv, VABufferID *buf)
{
- g_mutex_lock(base_prv->code_buffer_lock);
- g_queue_push_head(base_prv->available_code_buffers, buf);
- g_cond_signal(base_prv->code_buffer_cond);
- g_mutex_unlock(base_prv->code_buffer_lock);
+ g_mutex_lock(priv->code_buffer_lock);
+ g_queue_push_head(priv->available_code_buffers, buf);
+ g_cond_signal(priv->code_buffer_cond);
+ g_mutex_unlock(priv->code_buffer_lock);
return TRUE;
}
guint32 plane_count = 0;
guint32 image_width = 0, image_height = 0;
guint32 pitchy = 0, pitchu = 0, pitchv = 0;
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
ENCODER_ASSERT(display);
VAAPI_UNUSED_ARG(pitchv);
}
if (GST_VAAPI_IMAGE_NV12 == image_format) { /* UV plane */
- if (GST_VAAPI_IMAGE_I420 == base_prv->format) {
+ if (GST_VAAPI_IMAGE_I420 == priv->format) {
for (row = 0; row < image_height / 2; row++) {
for (col = 0; col < image_width / 2; col++) {
u_dst[col * 2] = u_src[col];
u_src += (ENCODER_WIDTH(base_encoder)>>1);
v_src += (ENCODER_WIDTH(base_encoder)>>1);
}
- } else if (GST_VAAPI_IMAGE_NV12 == base_prv->format){
+ } else if (GST_VAAPI_IMAGE_NV12 == priv->format){
for (row = 0; row < image_height / 2; row++) {
memcpy(u_dst, u_src, image_width);
u_src += ENCODER_WIDTH(base_encoder);
#endif
static EncoderStatus
-base_query_encoding_status(GstVaapiBaseEncoder *base_encoder,
- GstVaapiDisplay *display,
- GstVaapiSurface *buffer_surface,
- gboolean is_key,
- GstVaapiVideoBuffer *surface_buffer,
- VABufferID *coded_buf,
- GList **coded_pics)
+gst_vaapi_base_encoder_flush_default(
+ GstVaapiEncoder* encoder,
+ GList **coded_pics
+)
{
+ GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
EncoderStatus ret = ENCODER_NO_ERROR;
- VAStatus va_status = VA_STATUS_SUCCESS;
- VASurfaceStatus surface_status = 0;
- VACodedBufferSegment *buf_list = NULL;
- GstBuffer* ret_buffer = NULL;
- gboolean has_coded_data = FALSE;
- gboolean is_locked = FALSE;
- GstVaapiBaseEncoderClass *base_class = GST_VAAPI_BASE_ENCODER_GET_CLASS(base_encoder);
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
-
- ENCODER_ASSERT(display);
- VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
-
- ENCODER_ASSERT(coded_pics);
- VAAPI_UNUSED_ARG(has_coded_data);
-
- /* lock display */
- ENCODER_ACQUIRE_DISPLAY_LOCK(display);
-
- va_status = vaSyncSurface(va_dpy, surface_id);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaSyncSurface failed.");
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
- va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaQuerySurfaceStatus failed.");
- if (VASurfaceSkipped&surface_status) {
- ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(surface_buffer)));
- }
+ priv->frame_count = 0;
+ priv->need_flush = TRUE;
+ /*do we need destroy priv->seq_parameter? */
- va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaMapBuffer failed.");
+ //end:
+ return ret;
+}
- /*unlock display*/
- ENCODER_RELEASE_DISPLAY_LOCK(display);
- while (buf_list != NULL) {
- if (base_prv->frame_notify_flag && base_class->notify_frame) {
- base_class->notify_frame(base_encoder, buf_list->buf, buf_list->size);
- }
+static void
+gst_vaapi_base_encoder_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+ GstVaapiBaseEncoderPrivate *priv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(object);
- if (base_class->copy_coded_frame) {
- ret_buffer = base_class->copy_coded_frame(
- base_encoder, buf_list->buf,
- buf_list->size, coded_buf);
- } else {
- ret_buffer = gst_vaapi_base_encoder_copy_buffer_default(
- base_encoder, buf_list->buf,
- buf_list->size, coded_buf);
- }
- GST_BUFFER_TIMESTAMP(ret_buffer) = GST_BUFFER_TIMESTAMP(surface_buffer);
- GST_BUFFER_DURATION(ret_buffer) = GST_BUFFER_DURATION(surface_buffer);
- if (!is_key) {
- GST_BUFFER_FLAG_SET(ret_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
- }
- GST_BUFFER_OFFSET_END(ret_buffer) = GST_BUFFER_OFFSET_END(surface_buffer);
- *coded_pics = g_list_append(*coded_pics, ret_buffer);
- buf_list = (VACodedBufferSegment*)buf_list->next;
- ENCODER_ASSERT(NULL == buf_list);
- has_coded_data = TRUE;
- FPS_CALCULATION(vaapiencode);
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
}
-#if SHARE_CODED_BUF
- if (!has_coded_data)
-#endif
- { // if non-related, push back to available_code_buffers
- ENCODER_ACQUIRE_DISPLAY_LOCK(display);
- vaUnmapBuffer(va_dpy, *coded_buf);
- ENCODER_RELEASE_DISPLAY_LOCK(display);
- push_available_coded_buffer(base_prv, coded_buf);
+ g_mutex_free(priv->code_buffer_lock);
+ g_cond_free(priv->code_buffer_cond);
+ if (priv->available_code_buffers) {
+ g_queue_free(priv->available_code_buffers);
+ priv->available_code_buffers = NULL;
}
- return ENCODER_NO_ERROR;
-
-end:
- /*unlock display*/
- ENCODER_RELEASE_DISPLAY_LOCK(display);
- return ret;
+ G_OBJECT_CLASS(gst_vaapi_base_encoder_parent_class)->finalize(object);
}
-static GstBuffer *
-gst_vaapi_base_encoder_copy_buffer_default(GstVaapiBaseEncoder *encoder,
- guint8 *frame,
- guint32 frame_size,
- VABufferID *coded_buf)
+static void
+gst_vaapi_base_encoder_init(GstVaapiBaseEncoder *encoder)
{
- GstBuffer *ret_buffer = NULL;
-#if SHARE_CODED_BUF
- ret_buffer = gst_base_encode_share_buffer_new(encoder, coded_buf);
- ENCODER_ASSERT(ret_buffer);
- GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
- GST_BUFFER_DATA(ret_buffer) = frame;
- GST_BUFFER_SIZE(ret_buffer) = frame_size;
-#else
- ret_buffer = gst_buffer_new_and_alloc(frame_size);
- memcpy(GST_BUFFER_DATA(ret_buffer),frame, frame_size);
-#endif
- return ret_buffer;
+ GstVaapiBaseEncoderPrivate *priv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
+ ENCODER_ASSERT(priv);
+ encoder->priv = priv;
+
+ /* init private values*/
+ priv->format = 0;
+ priv->profile= VA_INVALID_PROFILE;
+ priv->frame_count = 0;
+ priv->frame_notify_flag = FALSE;
+
+ priv->coded_bufs = NULL;
+ priv->coded_buf_num = DEFAULT_VA_CODEDBUF_NUM;
+ priv->code_buffer_lock = g_mutex_new();
+ priv->code_buffer_cond = g_cond_new();
+ priv->available_code_buffers = g_queue_new();
+
+ priv->need_flush = FALSE;
}
-EncoderStatus
-gst_vaapi_base_encoder_flush_default(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GList **coded_pics)
+static void
+gst_vaapi_base_encoder_class_init(GstVaapiBaseEncoderClass *klass)
{
- GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
- EncoderStatus ret = ENCODER_NO_ERROR;
- GstVaapiBaseEncoderPrivate *base_prv = GST_VAAPI_BASE_ENCODER_GET_PRIVATE(base_encoder);
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ g_type_class_add_private(klass, sizeof(GstVaapiBaseEncoderPrivate));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_base_encoder_debug, "gst_vaapi_base_encoder", 0,
+ "gst_vaapi_base_encoder element");
- base_prv->frame_count = 0;
- base_prv->need_flush = TRUE;
- /*do we need destroy base_prv->seq_parameter? */
+ object_class->finalize = gst_vaapi_base_encoder_finalize;
- //end:
- return ret;
-}
+ encoder_class->open = gst_vaapi_base_encoder_open_default;
+ encoder_class->close = gst_vaapi_base_encoder_close_default;
+ encoder_class->encode = gst_vaapi_base_encoder_encode_default;
+ encoder_class->flush = gst_vaapi_base_encoder_flush_default;
+ encoder_class->get_codec_data = NULL;
+ /* user defined functions*/
+ klass->validate_attributes = NULL;
+ klass->pre_alloc_resource = NULL;
+ klass->release_resource = NULL;
+ klass->prepare_next_input_buffer = NULL;
+ klass->render_frame = NULL;
+ klass->notify_frame = NULL;
+ klass->copy_coded_frame = NULL;
+ klass->encode_frame_failed = NULL;
+ /*
+ object_class->set_property = gst_vaapi_base_encoder_set_property;
+ object_class->get_property = gst_vaapi_base_encoder_get_property;
+ */
+}
#define GST_VAAPI_BASE_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_BASE_ENCODER, GstVaapiBaseEncoderClass))
#define GST_VAAPI_BASE_ENCODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GST_TYPE_VAAPI_BASE_ENCODER, GstVaapiBaseEncoderPrivate))
-
struct _GstVaapiBaseEncoder {
GstVaapiEncoder parent;
+
+ GstVaapiBaseEncoderPrivate *priv;
};
struct _GstVaapiBaseEncoderClass {
/* in <open> function*/
gboolean (*validate_attributes) (GstVaapiBaseEncoder* encoder);
- gboolean (*pre_alloc_resource) (GstVaapiBaseEncoder *base_encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+ gboolean (*pre_alloc_resource) (GstVaapiBaseEncoder *encoder, GstVaapiContext* context);
/* in <close> function */
- gboolean (*release_resource) (GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+ gboolean (*release_resource) (GstVaapiBaseEncoder* encoder);
/* in <encode> function */
- EncoderStatus (*prepare_next_input_buffer)(GstVaapiBaseEncoder* encoder, GstVaapiVideoBuffer *display_buf,
- gboolean need_flush, GstVaapiVideoBuffer **out_buf);
- EncoderStatus (*render_frame) (GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstVaapiSurface *surface,
+ EncoderStatus (*prepare_next_input_buffer)(GstVaapiBaseEncoder* encoder,
+ GstVaapiVideoBuffer *display_buf,
+ gboolean need_flush,
+ GstVaapiVideoBuffer **out_buf);
+ EncoderStatus (*render_frame) (GstVaapiBaseEncoder *encoder, GstVaapiSurface *surface,
guint frame_index, VABufferID coded_buf, gboolean *is_key);
void (*encode_frame_failed) (GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer);
void (*notify_frame) (GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
GstBuffer *(*copy_coded_frame) (GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size, VABufferID *coded_buf);
};
-/*
-struct _GstVaapiBaseEncoderPrivate {
- GstVaapiDisplay *display;
- GstVaapiContext *context;
- //VAAPI_Encode_State state;
-};
-*/
-
GType gst_vaapi_base_encoder_get_type(void);
void gst_vaapi_base_encoder_set_frame_notify(GstVaapiBaseEncoder *encoder, gboolean flag);
gboolean gst_vaapi_base_encoder_set_va_profile(GstVaapiBaseEncoder *encoder, guint profile);
G_DEFINE_TYPE(GstVaapiEncoder, gst_vaapi_encoder, G_TYPE_OBJECT);
-static void gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass);
-static void gst_vaapi_encoder_init(GstVaapiEncoder *encoder);
-static void gst_vaapi_encoder_finalize(GObject *object);
-
-static void
-gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass)
-{
- GObjectClass * const object_class = G_OBJECT_CLASS(kclass);
- g_type_class_add_private(kclass, sizeof(GstVaapiEncoderPrivate));
-
-
- GST_DEBUG_CATEGORY_INIT (gst_vaapi_encoder_debug, "gst_va_encoder", 0,
- "gst_va_encoder element");
-
- object_class->finalize = gst_vaapi_encoder_finalize;
- kclass->initialize = NULL;
- kclass->uninitialize = NULL;
- kclass->open = NULL;
- kclass->close = NULL;
- kclass->encode = NULL;
- kclass->flush = NULL;
- kclass->get_codec_data = NULL;
-}
-
-static void
-gst_vaapi_encoder_init(GstVaapiEncoder *encoder)
-{
- GstVaapiEncoderPrivate *priv;
-
- encoder->priv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
- priv = encoder->priv;
- ENCODER_ASSERT(priv);
-
- priv->display = NULL;
- priv->context = NULL;
- priv->state = VAAPI_ENC_NULL;
-
- encoder->width = 0;
- encoder->height = 0;
- encoder->frame_rate = 0;
-}
-
-static void
-gst_vaapi_encoder_finalize(GObject *object)
-{
- GstVaapiEncoder* encoder = GST_VAAPI_ENCODER(object);
- GstVaapiEncoderPrivate *priv = encoder->priv;
- if (VAAPI_ENC_NULL != priv->state) {
- gst_vaapi_encoder_uninitialize(encoder);
- }
-
- if (priv->context) {
- g_object_unref(priv->context);
- priv->context = NULL;
- }
-
- if (priv->display) {
- g_object_unref(priv->display);
- priv->display = NULL;
- }
-
- G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object);
-}
-
-
gboolean
gst_vaapi_encoder_set_display(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
{
if (priv->display) {
g_object_unref(priv->display);
priv->display = NULL;
+ priv->va_display = NULL;
+ }
+ if (display) {
+ priv->display = g_object_ref(display);
+ priv->va_display = gst_vaapi_display_get_display(display);
}
- priv->display = g_object_ref(display);
return TRUE;
}
if (!priv->display) {
priv->display = gst_vaapi_display_x11_new(NULL);
ENCODER_CHECK_STATUS(priv->display, ENCODER_DISPLAY_ERR, "gst_vaapi_display_x11_new failed.");
+ priv->va_display = gst_vaapi_display_get_display(priv->display);
}
if (encoder_class->initialize) {
- ret = encoder_class->initialize(encoder, priv->display);
+ ret = encoder_class->initialize(encoder);
ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == ret, ret, "encoder <initialize> failed.");
}
priv->state = VAAPI_ENC_INIT;
ENCODER_ASSERT(!priv->context);
ENCODER_CHECK_STATUS(encoder_class->open, ENCODER_FUNC_PTR_ERR, "encoder <open> function pointer empty.");
- ret = encoder_class->open(encoder, priv->display, &priv->context);
+ ret = encoder_class->open(encoder, &priv->context);
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <open> failed.");
ENCODER_CHECK_STATUS(priv->context, ENCODER_CONTEXT_ERR, "encoder <open> context failed.");
-
+ priv->va_context = gst_vaapi_context_get_id(priv->context);
priv->state = VAAPI_ENC_OPENED;
end:
ENCODER_CHECK_STATUS(priv->state >= VAAPI_ENC_OPENED, ENCODER_STATE_ERR, "encoder was not opened before <encode>.");
ENCODER_CHECK_STATUS(encoder_class->encode, ENCODER_FUNC_PTR_ERR, "encoder <encode> function pointer empty.");
- ret = encoder_class->encode(encoder, priv->display, priv->context, raw_pic, coded_pics);
+ ret = encoder_class->encode(encoder, raw_pic, coded_pics);
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <encode> failed.");
if (priv->state < VAAPI_ENC_ENCODING) {
priv->state = VAAPI_ENC_ENCODING;
return ENCODER_STATE_ERR;
}
ENCODER_CHECK_STATUS(encoder_class->flush, ENCODER_FUNC_PTR_ERR, "encoder <flush> function pointer empty.");
- ret = encoder_class->flush(encoder, priv->display, priv->context, coded_pics);
+ ret = encoder_class->flush(encoder, coded_pics);
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <flush> failed.");
if (priv->state > VAAPI_ENC_OPENED) {
priv->state = VAAPI_ENC_OPENED;
return ENCODER_NO_ERROR;
}
ENCODER_CHECK_STATUS(encoder_class->close, ENCODER_FUNC_PTR_ERR, "encoder <close> function pointers empty.");
- ret = encoder_class->close(encoder, priv->display, priv->context);
+ ret = encoder_class->close(encoder);
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <close> failed.");
end:
if (priv->context) {
g_object_unref(priv->context);
priv->context = NULL;
+ priv->va_context = VA_INVALID_ID;
}
priv->state = VAAPI_ENC_INIT;
}
ENCODER_ASSERT(VAAPI_ENC_INIT == priv->state);
if (encoder_class->uninitialize) {
- ret = encoder_class->uninitialize(encoder, priv->display);
+ ret = encoder_class->uninitialize(encoder);
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <uninitialize> failed.");
}
+
end:
if (priv->display) {
g_object_unref(priv->display);
priv->display = NULL;
+ priv->va_display = NULL;
}
priv->state = VAAPI_ENC_NULL;
return ret;
return tmp;
}
+static void
+gst_vaapi_encoder_init(GstVaapiEncoder *encoder)
+{
+ GstVaapiEncoderPrivate *priv;
+
+ encoder->priv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
+ priv = encoder->priv;
+ ENCODER_ASSERT(priv);
+
+ priv->display = NULL;
+ priv->va_display = NULL;
+ priv->context = NULL;
+ priv->va_context = VA_INVALID_ID;
+ priv->state = VAAPI_ENC_NULL;
+
+ encoder->width = 0;
+ encoder->height = 0;
+ encoder->frame_rate = 0;
+}
+
+static void
+gst_vaapi_encoder_finalize(GObject *object)
+{
+ GstVaapiEncoder* encoder = GST_VAAPI_ENCODER(object);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+ if (VAAPI_ENC_NULL != priv->state) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+
+ if (priv->context) {
+ g_object_unref(priv->context);
+ priv->context = NULL;
+ priv->va_context = VA_INVALID_ID;
+ }
+
+ if (priv->display) {
+ g_object_unref(priv->display);
+ priv->display = NULL;
+ priv->va_display = NULL;
+ }
+
+ G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object);
+}
+
+static void
+gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(kclass);
+ g_type_class_add_private(kclass, sizeof(GstVaapiEncoderPrivate));
+
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_encoder_debug, "gst_va_encoder", 0,
+ "gst_va_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_finalize;
+}
#include "gst/gstinfo.h"
#include "gst/gstbuffer.h"
-#include "gst/vaapi/gstvaapidisplay.h"
-#include "gst/vaapi/gstvaapicontext.h"
+#include "gstvaapidisplay.h"
+#include "gstvaapicontext.h"
G_BEGIN_DECLS
#define GST_VAAPI_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_ENCODER, GstVaapiEncoderClass))
#define GST_VAAPI_ENCODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),GST_TYPE_VAAPI_ENCODER, GstVaapiEncoderPrivate))
-#define ENCODER_DISPLAY(encoder) (((GstVaapiEncoder*)(encoder))->priv->display)
-#define ENCODER_CONTEXT(encoder) (((GstVaapiEncoder*)(encoder))->priv->context)
+#define GST_VAAPI_ENCODER_CAST(encoder) ((GstVaapiEncoder *)(encoder))
+
+#define ENCODER_DISPLAY(encoder) (((GstVaapiEncoder*)(encoder))->priv->display)
+#define ENCODER_VA_DISPLAY(encoder) (((GstVaapiEncoder*)(encoder))->priv->va_display)
+
+#define ENCODER_CONTEXT(encoder) (((GstVaapiEncoder*)(encoder))->priv->context)
+#define ENCODER_VA_CONTEXT(encoder) (((GstVaapiEncoder*)(encoder))->priv->va_context)
+
#define ENCODER_WIDTH(encoder) (((GstVaapiEncoder*)(encoder))->width)
#define ENCODER_HEIGHT(encoder) (((GstVaapiEncoder*)(encoder))->height)
#define ENCODER_FPS(encoder) (((GstVaapiEncoder*)(encoder))->frame_rate)
struct _GstVaapiEncoderClass {
GObjectClass parent_class;
- EncoderStatus (*initialize) (GstVaapiEncoder* encoder, GstVaapiDisplay *display); /* can be NULL */
- EncoderStatus (*uninitialize) (GstVaapiEncoder* encoder, GstVaapiDisplay *display); /* can be NULL */
+ EncoderStatus (*initialize) (GstVaapiEncoder* encoder); /* can be NULL */
+ EncoderStatus (*uninitialize) (GstVaapiEncoder* encoder); /* can be NULL */
/* context [out] */
- EncoderStatus (*open) (GstVaapiEncoder* encoder, GstVaapiDisplay *display,
+ EncoderStatus (*open) (GstVaapiEncoder* encoder,
GstVaapiContext **context);
- EncoderStatus (*close) (GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+ EncoderStatus (*close) (GstVaapiEncoder* encoder);
/* coded_pics [out] */
- EncoderStatus (*encode) (GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstBuffer *raw_pic, GList **coded_pics);
+ EncoderStatus (*encode) (GstVaapiEncoder* encoder,
+ GstBuffer *raw_pic,
+ GList **coded_pics);
/* coded_pics [out] */
- EncoderStatus (*flush) (GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GList **coded_pics);
+ EncoderStatus (*flush) (GstVaapiEncoder* encoder, GList **coded_pics);
- EncoderStatus (*get_codec_data)(GstVaapiEncoder* encoder, GstBuffer **codec_data); /* can be NULL */
+ /* get_codec_data can be NULL */
+ EncoderStatus (*get_codec_data)(GstVaapiEncoder* encoder, GstBuffer **codec_data);
};
struct _GstVaapiEncoderPrivate {
GstVaapiDisplay *display;
+ VADisplay va_display;
GstVaapiContext *context;
+ VAContextID va_context;
VAAPI_Encode_State state;
};
GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h263_encoder_debug);
#define GST_CAT_DEFAULT gst_vaapi_h263_encoder_debug
+#define GST_VAAPI_ENCODER_H263_CAST(encoder) ((GstVaapiEncoderH263 *)(encoder))
+
struct _GstVaapiEncoderH263Private {
GstVaapiSurface *ref_surface; /* reference buffer*/
GstVaapiSurface *recon_surface; /* reconstruct buffer*/
G_DEFINE_TYPE(GstVaapiEncoderH263, gst_vaapi_encoder_h263, GST_TYPE_VAAPI_BASE_ENCODER);
-/*
-static EncoderStatus gst_vaapi_encoder_h263_flush(GstVaapiEncoder* encoder,
- GstVaapiDisplay *display, GstVaapiContext *context,
- GList **coded_pics);
-*/
-
-static void gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass);
-static void gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *encoder);
-static void gst_vaapi_encoder_h263_finalize(GObject *object);
-
-static gboolean gst_h263_validate_parameters(GstVaapiBaseEncoder* encoder);
-static gboolean gst_vaapi_encoder_h263_release_resource(
- GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context);
-static EncoderStatus gst_vaapi_encoder_h263_rendering(GstVaapiBaseEncoder *encoder,
- GstVaapiDisplay *display, GstVaapiContext *context,
- GstVaapiSurface *surface, guint frame_index,
- VABufferID coded_buf, gboolean *is_key);
-
GstVaapiEncoderH263 *
gst_vaapi_encoder_h263_new(void)
{
- return GST_VAAPI_ENCODER_H263(g_object_new(GST_TYPE_VAAPI_ENCODER_H263, NULL));
-}
-
-
-static void
-gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass)
-{
- GObjectClass * const object_class = G_OBJECT_CLASS(klass);
- GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
- GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
- g_type_class_add_private(klass, sizeof(GstVaapiEncoderH263Private));
-
- GST_DEBUG_CATEGORY_INIT (gst_vaapi_h263_encoder_debug, "gst_va_h263_encoder", 0,
- "gst_va_h263_encoder element");
-
- object_class->finalize = gst_vaapi_encoder_h263_finalize;
-
- base_class->validate_attributes = gst_h263_validate_parameters;
- base_class->pre_alloc_resource = NULL;
- base_class->release_resource = gst_vaapi_encoder_h263_release_resource;
- base_class->render_frame = gst_vaapi_encoder_h263_rendering;
- base_class->notify_frame = NULL;
- base_class->copy_coded_frame = NULL;
-
- /*
- encoder_class->flush = gst_vaapi_encoder_h263_flush;
- */
- encoder_class->get_codec_data = NULL;
-
-}
-
-static void
-gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *h263_encoder)
-{
- GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
- ENCODER_ASSERT(h263_prv);
-
- /* init public */
- h263_encoder->bitrate = 0;
- h263_encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
- h263_encoder->init_qp = H263_DEFAULT_INIT_QP;
- h263_encoder->min_qp = H263_DEFAULT_MIN_QP;
-
- /* init private */
- h263_prv->ref_surface = NULL;
- h263_prv->recon_surface = NULL;
-
- h263_prv->seq_parameter = VA_INVALID_ID;
- h263_prv->pic_parameter = VA_INVALID_ID;
- h263_prv->slice_parameter = VA_INVALID_ID;
-}
-
-static void
-gst_vaapi_encoder_h263_finalize(GObject *object)
-{
- /*free private buffers*/
- GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
-
- if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
- gst_vaapi_encoder_uninitialize(encoder);
- }
- G_OBJECT_CLASS(gst_vaapi_encoder_h263_parent_class)->finalize(object);
+ return GST_VAAPI_ENCODER_H263_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_H263, NULL));
}
static gboolean
-gst_h263_validate_parameters(GstVaapiBaseEncoder* encoder)
+gst_h263_validate_parameters(GstVaapiBaseEncoder* base)
{
- GstVaapiEncoderH263 *h263_encoder = GST_VAAPI_ENCODER_H263(encoder);
- if (!ENCODER_WIDTH(h263_encoder) || !ENCODER_HEIGHT(h263_encoder) || !ENCODER_FPS(h263_encoder)) {
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+ if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
return FALSE;
}
- if (!h263_encoder->intra_period) {
- h263_encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
+ if (!encoder->intra_period) {
+ encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
}
- if (-1 == h263_encoder->init_qp) {
- h263_encoder->init_qp = H263_DEFAULT_INIT_QP;
+ if (-1 == encoder->init_qp) {
+ encoder->init_qp = H263_DEFAULT_INIT_QP;
}
- if (-1 == h263_encoder->min_qp) {
- h263_encoder->min_qp = H263_DEFAULT_MIN_QP;
+ if (-1 == encoder->min_qp) {
+ encoder->min_qp = H263_DEFAULT_MIN_QP;
}
/* default compress ratio 1: (4*8*1.5) */
- if (!h263_encoder->bitrate) {
- h263_encoder->bitrate = ENCODER_WIDTH(h263_encoder)*ENCODER_HEIGHT(h263_encoder)*ENCODER_FPS(h263_encoder)/4;
+ if (!encoder->bitrate) {
+ encoder->bitrate = ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
}
- gst_vaapi_base_encoder_set_va_profile(GST_VAAPI_BASE_ENCODER(h263_encoder), VAProfileH263Baseline);
+ gst_vaapi_base_encoder_set_va_profile(GST_VAAPI_BASE_ENCODER(encoder), VAProfileH263Baseline);
return TRUE;
}
static void
-h263_release_parameters(GstVaapiEncoderH263 *h263_encoder, GstVaapiDisplay *display)
+h263_release_parameters(GstVaapiEncoderH263 *encoder)
{
- GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
+ GstVaapiEncoderH263Private *priv = encoder->priv;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
VAStatus va_status = VA_STATUS_SUCCESS;
VAAPI_UNUSED_ARG(va_status);
- if (VA_INVALID_ID != h263_prv->seq_parameter) {
- va_status = vaDestroyBuffer(va_dpy, h263_prv->seq_parameter);
- h263_prv->seq_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->seq_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->seq_parameter);
+ priv->seq_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h263_prv->pic_parameter) {
- va_status = vaDestroyBuffer(va_dpy, h263_prv->pic_parameter);
- h263_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h263_prv->slice_parameter) {
- va_status = vaDestroyBuffer(va_dpy, h263_prv->slice_parameter);
- h263_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
}
static gboolean
-gst_vaapi_encoder_h263_release_resource(GstVaapiBaseEncoder* encoder,
- GstVaapiDisplay *display,
- GstVaapiContext *context)
+gst_vaapi_encoder_h263_release_resource(GstVaapiBaseEncoder* base)
{
- GstVaapiEncoderH263 *h263_encoder = GST_VAAPI_ENCODER_H263(encoder);
- GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+ GstVaapiEncoderH263Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
- h263_release_parameters(h263_encoder, display);
+ h263_release_parameters(encoder);
/*remove ref_surface*/
- if (h263_prv->ref_surface) {
+ if (priv->ref_surface) {
if (context) {
- gst_vaapi_context_put_surface(context, h263_prv->ref_surface);
+ gst_vaapi_context_put_surface(context, priv->ref_surface);
} else {
- g_object_unref(h263_prv->ref_surface);
+ g_object_unref(priv->ref_surface);
}
- h263_prv->ref_surface = NULL;
+ priv->ref_surface = NULL;
}
/*remove recon_surface*/
- if (h263_prv->recon_surface) {
+ if (priv->recon_surface) {
if (context) {
- gst_vaapi_context_put_surface(context, h263_prv->recon_surface);
+ gst_vaapi_context_put_surface(context, priv->recon_surface);
} else {
- g_object_unref(h263_prv->recon_surface);
+ g_object_unref(priv->recon_surface);
}
- h263_prv->recon_surface = NULL;
+ priv->recon_surface = NULL;
}
return TRUE;
}
static EncoderStatus
-gst_vaapi_encoder_h263_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstVaapiSurface *surface,
- guint frame_index, VABufferID coded_buf, gboolean *is_key)
+gst_vaapi_encoder_h263_rendering(
+ GstVaapiBaseEncoder *base,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key
+)
{
- GstVaapiEncoderH263 *h263_encoder = GST_VAAPI_ENCODER_H263(encoder);
- GstVaapiEncoderH263Private *h263_prv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(h263_encoder);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+ GstVaapiEncoderH263Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(base);
+ VAContextID context_id = ENCODER_VA_CONTEXT(base);
VAStatus va_status = VA_STATUS_SUCCESS;
EncoderStatus ret = ENCODER_NO_ERROR;
- *is_key = (frame_index % h263_encoder->intra_period == 0);
+ *is_key = (frame_index % encoder->intra_period == 0);
/* initialize sequence parameter set, only first time */
- if (VA_INVALID_ID == h263_prv->seq_parameter) { /*only the first time*/
+ if (VA_INVALID_ID == priv->seq_parameter) { /*only the first time*/
VAEncSequenceParameterBufferH263 seq_h263 = {0};
- seq_h263.intra_period = h263_encoder->intra_period;
- seq_h263.bits_per_second = h263_encoder->bitrate;
- seq_h263.frame_rate = ENCODER_FPS(h263_encoder);
- seq_h263.initial_qp = h263_encoder->init_qp;
- seq_h263.min_qp = h263_encoder->min_qp;
+ seq_h263.intra_period = encoder->intra_period;
+ seq_h263.bits_per_second = encoder->bitrate;
+ seq_h263.frame_rate = ENCODER_FPS(encoder);
+ seq_h263.initial_qp = encoder->init_qp;
+ seq_h263.min_qp = encoder->min_qp;
va_status = vaCreateBuffer(va_dpy, context_id,
VAEncSequenceParameterBufferType,
- sizeof(seq_h263), 1, &seq_h263, &h263_prv->seq_parameter);
+ sizeof(seq_h263), 1, &seq_h263, &priv->seq_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_ENC_RES_ERR, "h263 alloc seq-buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &h263_prv->seq_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "h263 vaRenderPicture seq-parameters failed.");
}
/* set reference and reconstructed surfaces */
- if (!h263_prv->ref_surface) {
- h263_prv->ref_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h263_prv->ref_surface, ENCODER_SURFACE_ERR, "h263 reference surface, h263_pop_free_surface failed.");
+ if (!priv->ref_surface) {
+ priv->ref_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface, ENCODER_SURFACE_ERR, "h263 reference surface, h263_pop_free_surface failed.");
}
- if (!h263_prv->recon_surface) {
- h263_prv->recon_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h263_prv->recon_surface, ENCODER_SURFACE_ERR, "h263 reconstructed surface, h263_pop_free_surface failed.");
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface, ENCODER_SURFACE_ERR, "h263 reconstructed surface, h263_pop_free_surface failed.");
}
/* initialize picture, every time, every frame */
VAEncPictureParameterBufferH263 pic_h263 = {0};
- pic_h263.reference_picture = GST_VAAPI_OBJECT_ID(h263_prv->ref_surface);
- pic_h263.reconstructed_picture = GST_VAAPI_OBJECT_ID(h263_prv->recon_surface);
+ pic_h263.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface);
+ pic_h263.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
pic_h263.coded_buf = coded_buf;
- pic_h263.picture_width = ENCODER_WIDTH(h263_encoder);
- pic_h263.picture_height = ENCODER_HEIGHT(h263_encoder);
+ pic_h263.picture_width = ENCODER_WIDTH(encoder);
+ pic_h263.picture_height = ENCODER_HEIGHT(encoder);
pic_h263.picture_type = (*is_key) ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
- if (VA_INVALID_ID != h263_prv->pic_parameter) { /* destroy first*/
- va_status = vaDestroyBuffer(va_dpy, h263_prv->pic_parameter);
- h263_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) { /* destroy first*/
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
- sizeof(pic_h263), 1, &pic_h263, &h263_prv->pic_parameter);
+ sizeof(pic_h263), 1, &pic_h263, &priv->pic_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_ENC_RES_ERR, "h263 creating pic-param buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &h263_prv->pic_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR, "h263 rendering pic-param buffer failed.");
/*initialize slice parameters, only ONE slice for h263*/
VAEncSliceParameterBuffer slice_h263 = { 0 };
slice_h263.start_row_number = 0;
- slice_h263.slice_height = (ENCODER_HEIGHT(h263_encoder)+15)/16; /*MB?*/
+ slice_h263.slice_height = (ENCODER_HEIGHT(encoder)+15)/16; /*MB?*/
slice_h263.slice_flags.bits.is_intra = *is_key;
slice_h263.slice_flags.bits.disable_deblocking_filter_idc = 0;
- if (VA_INVALID_ID != h263_prv->slice_parameter) {
- vaDestroyBuffer(va_dpy, h263_prv->slice_parameter);
- h263_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy,
sizeof(slice_h263),
1,
&slice_h263,
- &h263_prv->slice_parameter);
+ &priv->slice_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_ENC_RES_ERR,
"h263 creating slice-parameters buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &h263_prv->slice_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR,
"h263 rendering slice-parameters buffer failed.");
/*swap ref_surface and recon_surface */
- GstVaapiSurface *swap = h263_prv->ref_surface;
- h263_prv->ref_surface = h263_prv->recon_surface;
- h263_prv->recon_surface = swap;
+ GstVaapiSurface *swap = priv->ref_surface;
+ priv->ref_surface = priv->recon_surface;
+ priv->recon_surface = swap;
end:
return ret;
}
+static void
+gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *encoder)
+{
+ GstVaapiEncoderH263Private *priv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(encoder);
+ encoder->priv = priv;
+ ENCODER_ASSERT(priv);
+
+ /* init public */
+ encoder->bitrate = 0;
+ encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
+ encoder->init_qp = H263_DEFAULT_INIT_QP;
+ encoder->min_qp = H263_DEFAULT_MIN_QP;
+
+ /* init private */
+ priv->ref_surface = NULL;
+ priv->recon_surface = NULL;
+
+ priv->seq_parameter = VA_INVALID_ID;
+ priv->pic_parameter = VA_INVALID_ID;
+ priv->slice_parameter = VA_INVALID_ID;
+}
+
+static void
+gst_vaapi_encoder_h263_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+ G_OBJECT_CLASS(gst_vaapi_encoder_h263_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ g_type_class_add_private(klass, sizeof(GstVaapiEncoderH263Private));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_h263_encoder_debug, "gst_va_h263_encoder", 0,
+ "gst_va_h263_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_h263_finalize;
+
+ base_class->validate_attributes = gst_h263_validate_parameters;
+ base_class->pre_alloc_resource = NULL;
+ base_class->release_resource = gst_vaapi_encoder_h263_release_resource;
+ base_class->render_frame = gst_vaapi_encoder_h263_rendering;
+ base_class->notify_frame = NULL;
+ base_class->copy_coded_frame = NULL;
+
+ /*
+ encoder_class->flush = gst_vaapi_encoder_h263_flush;
+ */
+ encoder_class->get_codec_data = NULL;
+
+}
guint32 intra_period;
guint32 init_qp; /*default 15, 1~31*/
guint32 min_qp; /*default 1, 1~31*/
+
+ GstVaapiEncoderH263Private *priv;
};
struct _GstVaapiEncoderH263Class {
GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
#define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
+#define GST_VAAPI_ENCODER_H264_CAST(encoder) ((GstVaapiEncoderH264 *)(encoder))
+
#define SHARE_CODED_BUF 0
#define DEFAULT_SURFACE_NUMBER 3
static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
-static EncoderStatus gst_vaapi_encoder_h264_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GList **coded_pics);
-
-/*other functions*/
/*other functions*/
-static EncoderStatus gst_vaapi_encoder_h264_get_codec_data(
- GstVaapiEncoder* encoder, GstBuffer **buffer);
-static gboolean gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
-static void gst_vaapi_encoder_h264_finalize(GObject *object);
static void gst_vaapi_encoder_h264_init_public_values(GstVaapiEncoderH264* encoder);
-static gboolean gst_vaapi_encoder_h264_alloc_slices(GstVaapiBaseEncoder *encoder,
- GstVaapiDisplay *display, GstVaapiContext *context);
-static gboolean gst_vaapi_encoder_h264_release_resource(GstVaapiBaseEncoder* encoder,
- GstVaapiDisplay *display, GstVaapiContext *context);
-static EncoderStatus gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
- GstVaapiVideoBuffer *display_buf, gboolean need_flush,
- GstVaapiVideoBuffer **out_buf);
-static void gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *encoder,
- GstVaapiVideoBuffer* buffer);
-static EncoderStatus gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstVaapiSurface *surface,
- guint frame_index, VABufferID coded_buf, gboolean *is_key);
-static void gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
-//static EncoderStatus h264_encoder_read_sps_pps(
-// GstVaapiEncoderH264Private *h264_prv, const guint8 *buf, guint32 size);
-static GstBuffer *gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
- guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
-
/* h264 bitstream functions */
static void h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
-static void
-gst_vaapi_encoder_h264_class_init(GstVaapiEncoderH264Class *klass)
-{
- GObjectClass * const object_class = G_OBJECT_CLASS(klass);
- GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
- GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
-
- g_type_class_add_private(klass, sizeof(GstVaapiEncoderH264Private));
-
- GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
- "gst_va_h264_encoder element");
-
- object_class->finalize = gst_vaapi_encoder_h264_finalize;
-
- base_class->validate_attributes = gst_h264_validate_parameters;
- base_class->pre_alloc_resource = gst_vaapi_encoder_h264_alloc_slices;
- base_class->release_resource = gst_vaapi_encoder_h264_release_resource;
- base_class->prepare_next_input_buffer = gst_vaapi_encoder_h264_prepare_next_buffer;
- base_class->render_frame = gst_vaapi_encoder_h264_rendering;
- base_class->notify_frame = gst_h264_notify_frame;
- base_class->copy_coded_frame = gst_vaapi_encoder_h264_copy_coded_buffer;
- base_class->encode_frame_failed = gst_vaapi_encoder_h264_frame_failed;
-
- encoder_class->flush = gst_vaapi_encoder_h264_flush;
- encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data;
-}
-
static VAProfile
h264_get_va_profile(guint32 profile)
{
return (-1);
}
-static void
-gst_vaapi_encoder_h264_init(GstVaapiEncoderH264 *encoder)
-{
- GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder);
- ENCODER_ASSERT(h264_prv);
- h264_prv->public = encoder;
- encoder->priv = h264_prv;
-
- /* init public attributes */
- gst_vaapi_encoder_h264_init_public_values(encoder);
- gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
-
- /* init private values*/
- h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
- h264_prv->avc_flag = FALSE;
-
- h264_prv->ref_surface1 = NULL;
- h264_prv->ref_surface2 = NULL;
- h264_prv->recon_surface = NULL;
-
- h264_prv->seq_parameter = VA_INVALID_ID;
- h264_prv->pic_parameter = VA_INVALID_ID;
- h264_prv->slice_parameter = VA_INVALID_ID;
- h264_prv->packed_sps_par_buf = VA_INVALID_ID;
- h264_prv->packed_sps_data_buf = VA_INVALID_ID;
- h264_prv->packed_pps_par_buf = VA_INVALID_ID;
- h264_prv->packed_pps_data_buf = VA_INVALID_ID;
- h264_prv->slice_param_buffers = NULL;
- h264_prv->default_slice_height = 0;
- h264_prv->slice_mod_mb_num = 0;
-
- h264_prv->sps_data = NULL;
- h264_prv->pps_data = NULL;
-
- h264_prv->queued_buffers = g_queue_new();
- h264_prv->gop_count = 0;
- h264_prv->cur_display_num = 0;
- h264_prv->cur_decode_num = 0;
- h264_prv->cur_slice_type = SLICE_TYPE_I;
- h264_prv->last_decode_time = 0LL;
- h264_prv->default_cts_offset = 0;
-
- h264_prv->max_frame_num = 0;
- h264_prv->max_pic_order_cnt = 0;
- h264_prv->idr_num = 0;
-}
-
-static void
-gst_vaapi_encoder_h264_finalize(GObject *object)
-{
- /*free private buffers*/
- GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
- GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(object);
-
- if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
- gst_vaapi_encoder_uninitialize(encoder);
- }
-
- if (h264_prv->sps_data) {
- gst_buffer_unref(h264_prv->sps_data);
- h264_prv->sps_data = NULL;
- }
- if (h264_prv->pps_data) {
- gst_buffer_unref(h264_prv->pps_data);
- h264_prv->pps_data = NULL;
- }
- if (h264_prv->slice_param_buffers) {
- g_free(h264_prv->slice_param_buffers);
- h264_prv->slice_param_buffers = NULL;
- }
-
- if (h264_prv->queued_buffers) {
- ENCODER_ASSERT(g_queue_is_empty(h264_prv->queued_buffers));
- g_queue_free(h264_prv->queued_buffers);
- h264_prv->queued_buffers = NULL;
- }
-
- G_OBJECT_CLASS(gst_vaapi_encoder_h264_parent_class)->finalize(object);
-}
-
-
GstVaapiEncoderH264 *
gst_vaapi_encoder_h264_new(void)
{
- return GST_VAAPI_ENCODER_H264(g_object_new(GST_TYPE_VAAPI_ENCODER_H264, NULL));
+ return GST_VAAPI_ENCODER_H264_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_H264, NULL));
}
static void
void
gst_vaapi_encoder_h264_set_avc_flag(GstVaapiEncoderH264* encoder, gboolean avc)
{
- GstVaapiEncoderH264Private *h264_prv = encoder->priv;
- h264_prv->avc_flag = avc;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ priv->avc_flag = avc;
}
gboolean
gst_vaapi_encoder_h264_get_avc_flag(GstVaapiEncoderH264* encoder)
{
- GstVaapiEncoderH264Private *h264_prv = encoder->priv;
- return h264_prv->avc_flag;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ return priv->avc_flag;
}
gboolean
-gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
+gst_h264_validate_parameters(GstVaapiBaseEncoder *base)
{
- GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264(base_encoder);
- GstVaapiEncoderH264Private *h264_prv = encoder->priv;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
return FALSE;
}
if (!encoder->profile) {
encoder->profile = H264_DEFAULT_PROFILE;
}
- gst_vaapi_base_encoder_set_va_profile(base_encoder, h264_get_va_profile(encoder->profile));
+ gst_vaapi_base_encoder_set_va_profile(base, h264_get_va_profile(encoder->profile));
if (!encoder->level) {
if (encoder->profile <= H264_PROFILE_BASELINE)
encoder->level = H264_LEVEL_30;
slice_7_height = 1
slice_8_height = 1
*/
- h264_prv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
- if (0 == h264_prv->default_slice_height) { /* special value */
- h264_prv->default_slice_height = 1;
- h264_prv->slice_mod_mb_num = 0;
+ priv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
+ if (0 == priv->default_slice_height) { /* special value */
+ priv->default_slice_height = 1;
+ priv->slice_mod_mb_num = 0;
encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
} else {
- h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
+ priv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
}
if (encoder->b_frame_num) {
- h264_prv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
+ priv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
} else {
- h264_prv->default_cts_offset = 0;
+ priv->default_cts_offset = 0;
}
return TRUE;
}
static gboolean
-h264_encoder_release_parameters(GstVaapiEncoderH264 *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+h264_encoder_release_parameters(GstVaapiEncoderH264 *encoder)
{
VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+ GstVaapiContext *context = ENCODER_CONTEXT(encoder);
gboolean is_locked = FALSE;
VADisplay va_dpy = gst_vaapi_display_get_display(display);
ENCODER_ACQUIRE_DISPLAY_LOCK(display);
- if (VA_INVALID_ID != h264_prv->seq_parameter) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
- h264_prv->seq_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->seq_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->seq_parameter);
+ priv->seq_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h264_prv->pic_parameter) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
- h264_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h264_prv->slice_parameter) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
- h264_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_par_buf);
- h264_prv->packed_sps_par_buf = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->packed_sps_par_buf) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_sps_par_buf);
+ priv->packed_sps_par_buf = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_data_buf);
- h264_prv->packed_sps_data_buf = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->packed_sps_data_buf) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_sps_data_buf);
+ priv->packed_sps_data_buf = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_par_buf);
- h264_prv->packed_pps_par_buf = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->packed_pps_par_buf) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_pps_par_buf);
+ priv->packed_pps_par_buf = VA_INVALID_ID;
}
- if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_data_buf);
- h264_prv->packed_pps_data_buf = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->packed_pps_data_buf) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_pps_data_buf);
+ priv->packed_pps_data_buf = VA_INVALID_ID;
}
ENCODER_RELEASE_DISPLAY_LOCK(display);
- if (h264_prv->slice_param_buffers) {
- g_free(h264_prv->slice_param_buffers);
- h264_prv->slice_param_buffers = NULL;
+ if (priv->slice_param_buffers) {
+ g_free(priv->slice_param_buffers);
+ priv->slice_param_buffers = NULL;
}
- if (h264_prv->sps_data) {
- gst_buffer_unref(h264_prv->sps_data);
- h264_prv->sps_data = NULL;
+ if (priv->sps_data) {
+ gst_buffer_unref(priv->sps_data);
+ priv->sps_data = NULL;
}
- if (h264_prv->pps_data) {
- gst_buffer_unref(h264_prv->pps_data);
- h264_prv->pps_data = NULL;
+ if (priv->pps_data) {
+ gst_buffer_unref(priv->pps_data);
+ priv->pps_data = NULL;
}
return TRUE;
}
static void
-h264_release_queued_buffers(GstVaapiEncoderH264Private *h264_prv)
+h264_release_queued_buffers(GstVaapiEncoderH264Private *priv)
{
- while (!g_queue_is_empty(h264_prv->queued_buffers)) {
- GstBuffer* tmp = g_queue_pop_head(h264_prv->queued_buffers);
+ while (!g_queue_is_empty(priv->queued_buffers)) {
+ GstBuffer* tmp = g_queue_pop_head(priv->queued_buffers);
if (tmp)
gst_buffer_unref(tmp);
}
static gboolean
-gst_vaapi_encoder_h264_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+gst_vaapi_encoder_h264_release_resource(
+ GstVaapiBaseEncoder* base
+)
{
- GstVaapiEncoderH264* h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
+ GstVaapiEncoderH264* encoder = GST_VAAPI_ENCODER_H264_CAST(base);
gboolean ret = TRUE;
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
/* release buffers first */
- h264_encoder_release_parameters(h264_encoder, display, context);
- h264_release_queued_buffers(h264_prv);
- h264_prv->cur_display_num = 0;
- h264_prv->cur_decode_num = 0;
- h264_prv->cur_slice_type = SLICE_TYPE_I;
- h264_prv->gop_count = 0;
- h264_prv->last_decode_time = 0LL;
- h264_prv->default_cts_offset = 0;
+ h264_encoder_release_parameters(encoder);
+ h264_release_queued_buffers(priv);
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->gop_count = 0;
+ priv->last_decode_time = 0LL;
+ priv->default_cts_offset = 0;
/*remove ref_surface1*/
- if (h264_prv->ref_surface1) {
+ if (priv->ref_surface1) {
if (context) {
- gst_vaapi_context_put_surface(context, h264_prv->ref_surface1);
+ gst_vaapi_context_put_surface(context, priv->ref_surface1);
} else {
- g_object_unref(h264_prv->ref_surface1);
+ g_object_unref(priv->ref_surface1);
}
- h264_prv->ref_surface1 = NULL;
+ priv->ref_surface1 = NULL;
}
- if (h264_prv->ref_surface2) {
+ if (priv->ref_surface2) {
if (context) {
- gst_vaapi_context_put_surface(context, h264_prv->ref_surface2);
+ gst_vaapi_context_put_surface(context, priv->ref_surface2);
} else {
- g_object_unref(h264_prv->ref_surface2);
+ g_object_unref(priv->ref_surface2);
}
- h264_prv->ref_surface2 = NULL;
+ priv->ref_surface2 = NULL;
}
/*remove recon_surface*/
- if (h264_prv->recon_surface) {
+ if (priv->recon_surface) {
if (context) {
- gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
+ gst_vaapi_context_put_surface(context, priv->recon_surface);
} else {
- g_object_unref(h264_prv->recon_surface);
+ g_object_unref(priv->recon_surface);
}
- h264_prv->recon_surface = NULL;
+ priv->recon_surface = NULL;
}
return ret;
}
static gboolean
-gst_vaapi_encoder_h264_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display, GstVaapiContext *context)
+gst_vaapi_encoder_h264_alloc_slices(
+ GstVaapiBaseEncoder *base,
+ GstVaapiContext *context
+)
{
gboolean ret = TRUE;
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
- h264_prv->slice_param_buffers =
+ priv->slice_param_buffers =
#ifdef _SIMPLE_LIB_VA_
(VAEncSliceParameterBuffer*)
#else
(VAEncSliceParameterBufferH264*)
#endif
- g_malloc0_n(h264_encoder->slice_num,
- sizeof(h264_prv->slice_param_buffers[0]));
+ g_malloc0_n(encoder->slice_num,
+ sizeof(priv->slice_param_buffers[0]));
return ret;
}
static void
-gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer)
+gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *base, GstVaapiVideoBuffer* buffer)
{
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
-
- h264_release_queued_buffers(h264_prv);
- h264_prv->cur_display_num = 0;
- h264_prv->cur_decode_num = 0;
- h264_prv->cur_slice_type = SLICE_TYPE_I;
- h264_prv->gop_count = 0;
- h264_prv->last_decode_time = 0LL;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ h264_release_queued_buffers(priv);
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->gop_count = 0;
+ priv->last_decode_time = 0LL;
}
static EncoderStatus
-gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
+gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* base,
GstVaapiVideoBuffer *display_buf, gboolean need_flush,
GstVaapiVideoBuffer **out_buf)
{
EncoderStatus ret = ENCODER_NO_ERROR;
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
GstVaapiVideoBuffer *return_buf = NULL;
//guint64 pts = 0;
- if (NULL == display_buf && g_queue_is_empty(h264_prv->queued_buffers)) {
+ if (NULL == display_buf && g_queue_is_empty(priv->queued_buffers)) {
ret = ENCODER_BUFFER_EMPTY;
- if (h264_prv->gop_count >= h264_encoder->intra_period || need_flush)
- h264_prv->gop_count = 0;
+ if (priv->gop_count >= encoder->intra_period || need_flush)
+ priv->gop_count = 0;
goto end;
}
if (display_buf) {
- ++h264_prv->gop_count;
+ ++priv->gop_count;
gst_buffer_ref(GST_BUFFER_CAST(display_buf));
- h264_prv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
+ priv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
}
/* first frame */
- if (h264_prv->gop_count == 1) {
+ if (priv->gop_count == 1) {
ENCODER_ASSERT(display_buf);
- h264_prv->cur_display_num = 0;
- h264_prv->cur_decode_num = 0;
- h264_prv->cur_slice_type = SLICE_TYPE_I;
- ++h264_prv->idr_num;
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ ++priv->idr_num;
return_buf = display_buf;
goto end;
}
if (display_buf) {
- if (h264_encoder->b_frame_num &&
- h264_prv->gop_count < h264_encoder->intra_period &&
- g_queue_get_length(h264_prv->queued_buffers) < h264_encoder->b_frame_num
+ if (encoder->b_frame_num &&
+ priv->gop_count < encoder->intra_period &&
+ g_queue_get_length(priv->queued_buffers) < encoder->b_frame_num
)
{
- g_queue_push_tail(h264_prv->queued_buffers, display_buf);
+ g_queue_push_tail(priv->queued_buffers, display_buf);
ret = ENCODER_BUFFER_WAITING;
goto end;
}
- h264_prv->cur_slice_type = SLICE_TYPE_P;
- h264_prv->cur_display_num = h264_prv->gop_count-1;
- ++h264_prv->cur_decode_num;
+ priv->cur_slice_type = SLICE_TYPE_P;
+ priv->cur_display_num = priv->gop_count-1;
+ ++priv->cur_decode_num;
return_buf = display_buf;
} else {
if (need_flush) {
- return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(h264_prv->queued_buffers);
- h264_prv->cur_slice_type = SLICE_TYPE_P;
- h264_prv->cur_display_num = h264_prv->gop_count - 1;
- ++h264_prv->cur_decode_num;
+ return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(priv->queued_buffers);
+ priv->cur_slice_type = SLICE_TYPE_P;
+ priv->cur_display_num = priv->gop_count - 1;
+ ++priv->cur_decode_num;
} else {
- return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(h264_prv->queued_buffers);
- h264_prv->cur_slice_type = SLICE_TYPE_B;
- h264_prv->cur_display_num = h264_prv->gop_count - 2 - g_queue_get_length(h264_prv->queued_buffers);
+ return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(priv->queued_buffers);
+ priv->cur_slice_type = SLICE_TYPE_B;
+ priv->cur_display_num = priv->gop_count - 2 - g_queue_get_length(priv->queued_buffers);
}
}
return ret;
}
+static inline void
+h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
+{
+ GstVaapiSurface *tmp;
+
+ g_return_if_fail(s1 && s2);
+ tmp = *s1;
+ *s1 = *s2;
+ *s2 = tmp;
+}
#ifdef _SIMPLE_LIB_VA_
+
static EncoderStatus
gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
GstVaapiContext *context, GstVaapiSurface *surface,
{
EncoderStatus ret = ENCODER_NO_ERROR;
VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264_CAST(encoder);
+ GstVaapiEncoderH264Private *priv = h264_encoder->priv;
VAEncPictureParameterBufferH264 pic_h264;
VAEncSliceParameterBuffer *slice_h264 = NULL;
VADisplay va_dpy = gst_vaapi_display_get_display(display);
VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
- *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
+ *is_key = (priv->cur_slice_type == SLICE_TYPE_I);
/* lock display */
ENCODER_ACQUIRE_DISPLAY_LOCK(display);
/*handle first surface_index*/
/*only need first frame*/
- if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
+ if (VA_INVALID_ID == priv->seq_parameter) { /*first time*/
VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
seq_h264.level_idc = h264_encoder->level; /* 3.0 */
seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
va_status = vaCreateBuffer(va_dpy, context_id,
VAEncSequenceParameterBufferType,
- sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
+ sizeof(seq_h264), 1, &seq_h264, &priv->seq_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.");
}
/* set pic_parameters*/
- if (!h264_prv->ref_surface1) {
- h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h264_prv->ref_surface1, ENCODER_SURFACE_ERR,
+ if (!priv->ref_surface1) {
+ priv->ref_surface1 = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface1, ENCODER_SURFACE_ERR,
"reference surface, h264_pop_free_surface failed.");
}
- if (!h264_prv->recon_surface) {
- h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR,
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface, ENCODER_SURFACE_ERR,
"reconstructed surface, h264_pop_free_surface failed.");
}
- pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
- pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
+ pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
pic_h264.coded_buf = coded_buf;
pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
pic_h264.last_picture = 0; // last pic or not
- if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
- vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
- h264_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) { /* share the same pic_parameter*/
+ vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
- sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
+ sizeof(pic_h264), 1, &pic_h264, &priv->pic_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR, "creating pic-param buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.");
/* set slice parameters, support multiple slices */
int i = 0;
guint32 last_row_num = 0;
- guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
+ guint32 slice_mod_num = priv->slice_mod_mb_num;
- memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
+ memset(priv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(priv->slice_param_buffers[0]));
for (i = 0; i < h264_encoder->slice_num; ++i) {
- slice_h264 = &h264_prv->slice_param_buffers[i];
+ slice_h264 = &priv->slice_param_buffers[i];
slice_h264->start_row_number = last_row_num; /* unit MB*/
- slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
+ slice_h264->slice_height = priv->default_slice_height; /* unit MB */
if (slice_mod_num) {
++slice_h264->slice_height;
--slice_mod_num;
}
ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
- if (VA_INVALID_ID != h264_prv->slice_parameter) {
- vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
- h264_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy,
context_id,
VAEncSliceParameterBufferType,
- sizeof(h264_prv->slice_param_buffers[0]),
+ sizeof(priv->slice_param_buffers[0]),
h264_encoder->slice_num,
- h264_prv->slice_param_buffers,
- &h264_prv->slice_parameter);
+ priv->slice_param_buffers,
+ &priv->slice_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.");
/*after finished, set ref_surface1_index, recon_surface_index */
- GstVaapiSurface *swap = h264_prv->ref_surface1;
- h264_prv->ref_surface1 = h264_prv->recon_surface;
- h264_prv->recon_surface = swap;
+ GstVaapiSurface *swap = priv->ref_surface1;
+ priv->ref_surface1 = priv->recon_surface;
+ priv->recon_surface = swap;
end:
ENCODER_RELEASE_DISPLAY_LOCK(display);
#else /* extended libva, new parameter structures*/
-static void h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
-{
- GstVaapiSurface *tmp;
-
- g_return_if_fail(s1 && s2);
- tmp = *s1;
- *s1 = *s2;
- *s2 = tmp;
-}
-
static gboolean
-set_sequence_parameters(GstVaapiEncoderH264 *h264_encoder,
+set_sequence_parameters(GstVaapiEncoderH264 *encoder,
VAEncSequenceParameterBufferH264 *seq_param)
{
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
guint width_in_mbs, height_in_mbs;
- width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
- height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
+ width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+ height_in_mbs = (ENCODER_HEIGHT(encoder)+15)/16;
seq_param->seq_parameter_set_id = 0;
- seq_param->level_idc = h264_encoder->level; /* 3.0 */
- seq_param->intra_period = h264_encoder->intra_period;
+ seq_param->level_idc = encoder->level; /* 3.0 */
+ seq_param->intra_period = encoder->intra_period;
seq_param->ip_period = 0; // ?
- if (h264_encoder->bitrate> 0)
- seq_param->bits_per_second = h264_encoder->bitrate; /* use kbps as input */
+ if (encoder->bitrate> 0)
+ seq_param->bits_per_second = encoder->bitrate; /* use kbps as input */
else
seq_param->bits_per_second = 0;
- seq_param->max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1); // ?, why 4
+ seq_param->max_num_ref_frames = (encoder->b_frame_num < 2 ? 3 : encoder->b_frame_num+1); // ?, why 4
seq_param->picture_width_in_mbs = width_in_mbs;
seq_param->picture_height_in_mbs = height_in_mbs;
seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 2;
seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
- h264_prv->max_frame_num = 1<<(seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4);
- h264_prv->max_pic_order_cnt = 1 <<(seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
+ priv->max_frame_num = 1<<(seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4);
+ priv->max_pic_order_cnt = 1 <<(seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
seq_param->bit_depth_luma_minus8 = 0;
seq_param->bit_depth_chroma_minus8 = 0;
seq_param->offset_for_top_to_bottom_field = 0;
memset(seq_param->offset_for_ref_frame, 0, sizeof(seq_param->offset_for_ref_frame));
- if (height_in_mbs*16 - ENCODER_HEIGHT(h264_encoder)) {
+ if (height_in_mbs*16 - ENCODER_HEIGHT(encoder)) {
seq_param->frame_cropping_flag = 1;
seq_param->frame_crop_left_offset = 0;
seq_param->frame_crop_right_offset = 0;
seq_param->frame_crop_top_offset = 0;
seq_param->frame_crop_bottom_offset =
- (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1));
+ ((height_in_mbs * 16 - ENCODER_HEIGHT(encoder))/
+ (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)));
}
#if 0
if (h264_encoder->init_qp == -1)
}
static gboolean
-h264_fill_sequence_buffer(GstVaapiEncoderH264 *h264_encoder,
- VADisplay va_dpy, VAContextID context_id)
+h264_fill_sequence_buffer(GstVaapiEncoderH264 *encoder)
{
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
gboolean ret = TRUE;
VAStatus va_status = VA_STATUS_SUCCESS;
/* only once */
- if (VA_INVALID_ID != h264_prv->seq_parameter)
+ if (VA_INVALID_ID != priv->seq_parameter)
return TRUE;
- set_sequence_parameters(h264_encoder, &seq_h264);
+ set_sequence_parameters(encoder, &seq_h264);
va_status = vaCreateBuffer(va_dpy, context_id,
VAEncSequenceParameterBufferType,
sizeof(seq_h264), 1,
- &seq_h264, &h264_prv->seq_parameter);
+ &seq_h264, &priv->seq_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE, "alloc seq-buffer failed.");
/*pack sps header buffer/data */
- if (NULL == h264_prv->sps_data) {
+ if (NULL == priv->sps_data) {
VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
guint32 length_in_bits;
guint8 *packed_seq_buffer = NULL;
h264_bitstream_init(&bitstream, 128*8);
h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
- h264_bitstream_write_sps(&bitstream, &seq_h264, h264_encoder->profile);
+ h264_bitstream_write_sps(&bitstream, &seq_h264, encoder->profile);
ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
/* set codec data sps */
- h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
- GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
- memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, GST_BUFFER_SIZE(h264_prv->sps_data));
+ priv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+ GST_BUFFER_SIZE(priv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
+ memcpy(GST_BUFFER_DATA(priv->sps_data), packed_seq_buffer+4, GST_BUFFER_SIZE(priv->sps_data));
packed_header_param_buffer.type = VAEncPackedHeaderSequence;
packed_header_param_buffer.bit_length = length_in_bits;
VAEncPackedHeaderParameterBufferType,
sizeof(packed_header_param_buffer), 1,
&packed_header_param_buffer,
- &h264_prv->packed_sps_par_buf);
+ &priv->packed_sps_par_buf);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE,
"EncPackedSeqHeaderParameterBuffer failed");
VAEncPackedHeaderDataBufferType,
(length_in_bits + 7) / 8, 1,
packed_seq_buffer,
- &h264_prv->packed_sps_data_buf);
+ &priv->packed_sps_data_buf);
h264_bitstream_destroy(&bitstream, TRUE);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE,
}
static gboolean
-set_picture_parameters(GstVaapiEncoderH264 *h264_encoder,
- VAEncPictureParameterBufferH264 *pic_param)
+set_picture_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncPictureParameterBufferH264 *pic_param
+)
{
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
pic_param->pic_parameter_set_id = 0;
pic_param->seq_parameter_set_id = 0;
pic_param->last_picture = 0; /* means last encoding picture */
- pic_param->frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ?
- (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num);
+ pic_param->frame_num = (priv->cur_slice_type == SLICE_TYPE_B ?
+ (priv->cur_decode_num + 1) : priv->cur_decode_num);
//pic_h264.coding_type = 0;
- pic_param->pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26);
+ pic_param->pic_init_qp = (encoder->init_qp >= 0 ? encoder->init_qp : 26);
pic_param->num_ref_idx_l0_active_minus1 = 0; /* only 1 reference */
pic_param->num_ref_idx_l1_active_minus1 = 0; /* B frames only have 1 backward and 1 forward reference*/
pic_param->chroma_qp_index_offset = 0;
/* set picture fields */
pic_param->pic_fields.value = 0;
- pic_param->pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I);
- pic_param->pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B);
+ pic_param->pic_fields.bits.idr_pic_flag = (priv->cur_slice_type == SLICE_TYPE_I);
+ pic_param->pic_fields.bits.reference_pic_flag = (priv->cur_slice_type != SLICE_TYPE_B);
pic_param->pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC;
pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
pic_param->pic_fields.bits.weighted_bipred_idc = 0;
}
static gboolean
-h264_fill_picture_buffer(GstVaapiEncoderH264 *h264_encoder,
- VADisplay va_dpy, VAContextID context_id,
- VABufferID coded_buf)
+h264_fill_picture_buffer(
+ GstVaapiEncoderH264 *encoder,
+ VABufferID coded_buf
+)
{
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
VAEncPictureParameterBufferH264 pic_h264;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
gboolean ret = TRUE;
VAStatus va_status = VA_STATUS_SUCCESS;
VAAPI_UNUSED_ARG(va_status);
memset(&pic_h264, 0, sizeof(pic_h264));
- set_picture_parameters(h264_encoder, &pic_h264);
- pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
- pic_h264.CurrPic.TopFieldOrderCnt = h264_prv->cur_display_num * 2; // ??? /**/
- pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
- pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
+ set_picture_parameters(encoder, &pic_h264);
+ pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_h264.CurrPic.TopFieldOrderCnt = priv->cur_display_num * 2; // ??? /**/
+ pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
pic_h264.ReferenceFrames[2].picture_id = VA_INVALID_ID;
pic_h264.coded_buf = coded_buf;
char *frame_type = "I";
- if (h264_prv->cur_slice_type == SLICE_TYPE_P)
+ if (priv->cur_slice_type == SLICE_TYPE_P)
frame_type = "P";
- if (h264_prv->cur_slice_type == SLICE_TYPE_B)
+ if (priv->cur_slice_type == SLICE_TYPE_B)
frame_type = "B";
ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
frame_type, pic_h264.frame_num, pic_h264.CurrPic.TopFieldOrderCnt);
- if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
- vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
- h264_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) { /* share the same pic_parameter*/
+ vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
- sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
+ sizeof(pic_h264), 1, &pic_h264, &priv->pic_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
FALSE, "creating pic-param buffer failed.");
- if (VA_INVALID_ID == h264_prv->packed_pps_data_buf) {
+ if (VA_INVALID_ID == priv->packed_pps_data_buf) {
VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
guint32 length_in_bits;
guint8 *packed_pic_buffer = NULL;
packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
/*set codec data pps*/
- h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
- GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4;
- memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, GST_BUFFER_SIZE(h264_prv->pps_data));
+ priv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+ GST_BUFFER_SIZE(priv->pps_data) = (length_in_bits+7)/8-4;
+ memcpy(GST_BUFFER_DATA(priv->pps_data), packed_pic_buffer+4, GST_BUFFER_SIZE(priv->pps_data));
packed_header_param_buffer.type = VAEncPackedHeaderPicture;
packed_header_param_buffer.bit_length = length_in_bits;
VAEncPackedHeaderParameterBufferType,
sizeof(packed_header_param_buffer), 1,
&packed_header_param_buffer,
- &h264_prv->packed_pps_par_buf);
+ &priv->packed_pps_par_buf);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE,
"EncPackedPicHeaderParameterBuffer failed");
VAEncPackedHeaderDataBufferType,
(length_in_bits + 7) / 8, 1,
packed_pic_buffer,
- &h264_prv->packed_pps_data_buf);
+ &priv->packed_pps_data_buf);
h264_bitstream_destroy(&bitstream, TRUE);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE,
static gboolean
-h264_fill_slice_buffers(GstVaapiEncoderH264 *h264_encoder,
- VADisplay va_dpy, VAContextID context_id)
+h264_fill_slice_buffers(
+ GstVaapiEncoderH264 *encoder
+)
{
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
VAEncSliceParameterBufferH264 *slice_h264 = NULL;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
guint width_in_mbs;
gboolean ret = TRUE;
VAStatus va_status = VA_STATUS_SUCCESS;
- width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
+ width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
int i = 0;
guint32 last_row_num = 0;
- guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
+ guint32 slice_mod_num = priv->slice_mod_mb_num;
- memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
- for (i = 0; i < h264_encoder->slice_num; ++i) {
+ memset(priv->slice_param_buffers,
+ 0,
+ encoder->slice_num*sizeof(priv->slice_param_buffers[0]));
+ for (i = 0; i < encoder->slice_num; ++i) {
int i_pic = 0;
- slice_h264 = &h264_prv->slice_param_buffers[i];
+ slice_h264 = &priv->slice_param_buffers[i];
slice_h264->macroblock_address = last_row_num*width_in_mbs;
- slice_h264->num_macroblocks = width_in_mbs*h264_prv->default_slice_height;
- last_row_num += h264_prv->default_slice_height;
+ slice_h264->num_macroblocks = width_in_mbs*priv->default_slice_height;
+ last_row_num += priv->default_slice_height;
if (slice_mod_num) {
slice_h264->num_macroblocks += width_in_mbs;
++last_row_num;
--slice_mod_num;
}
slice_h264->macroblock_info = VA_INVALID_ID;
- slice_h264->slice_type = h264_prv->cur_slice_type;
+ slice_h264->slice_type = priv->cur_slice_type;
slice_h264->pic_parameter_set_id = 0;
- slice_h264->idr_pic_id = h264_prv->idr_num;
- slice_h264->pic_order_cnt_lsb = (h264_prv->cur_display_num*2) % h264_prv->max_pic_order_cnt;
+ slice_h264->idr_pic_id = priv->idr_num;
+ slice_h264->pic_order_cnt_lsb = (priv->cur_display_num*2) % priv->max_pic_order_cnt;
/* not used if pic_order_cnt_type = 0 */
slice_h264->delta_pic_order_cnt_bottom = 0;
slice_h264->num_ref_idx_l0_active_minus1 = 0;
slice_h264->num_ref_idx_l1_active_minus1 = 0;
- slice_h264->RefPicList0[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
+ slice_h264->RefPicList0[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
for (i_pic = 1;
i_pic < sizeof(slice_h264->RefPicList0)/sizeof(slice_h264->RefPicList0[0]);
i_pic++) {
slice_h264->RefPicList0[i_pic].picture_id = VA_INVALID_ID;
}
- if (SLICE_TYPE_B == h264_prv->cur_slice_type) {
- slice_h264->RefPicList1[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
+ if (SLICE_TYPE_B == priv->cur_slice_type) {
+ slice_h264->RefPicList1[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
i_pic = 1;
} else
i_pic = 0;
slice_h264->slice_beta_offset_div2 = 2;
}
- ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
+ ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(encoder)+15)/16);
- if (VA_INVALID_ID != h264_prv->slice_parameter) {
- vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
- h264_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy,
context_id,
VAEncSliceParameterBufferType,
- sizeof(h264_prv->slice_param_buffers[0]),
- h264_encoder->slice_num,
- h264_prv->slice_param_buffers,
- &h264_prv->slice_parameter);
+ sizeof(priv->slice_param_buffers[0]),
+ encoder->slice_num,
+ priv->slice_param_buffers,
+ &priv->slice_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
FALSE, "creating slice-parameters buffer failed.");
}
static EncoderStatus
-gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstVaapiSurface *surface,
- guint frame_index, VABufferID coded_buf, gboolean *is_key)
+gst_vaapi_encoder_h264_rendering(
+ GstVaapiBaseEncoder *base,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key
+)
{
EncoderStatus ret = ENCODER_NO_ERROR;
VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base);
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+ VADisplay va_dpy;
+ VAContextID context_id;
VABufferID va_buffers[64];
guint32 va_buffers_count = 0;
gboolean is_params_ok = TRUE;
-
gboolean is_locked = FALSE;
- ENCODER_ASSERT(display && context);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ ENCODER_ASSERT(context);
+
+ va_dpy = ENCODER_VA_DISPLAY(base);
+ context_id = ENCODER_VA_CONTEXT(base);
- *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
+ *is_key = (priv->cur_slice_type == SLICE_TYPE_I);
- if (!h264_prv->ref_surface1) {
- h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h264_prv->ref_surface1,
+ if (!priv->ref_surface1) {
+ priv->ref_surface1 = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface1,
ENCODER_SURFACE_ERR,
"reference surface, h264_pop_free_surface failed.");
}
- if (!h264_prv->ref_surface2) {
- h264_prv->ref_surface2 = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h264_prv->ref_surface2,
+ if (!priv->ref_surface2) {
+ priv->ref_surface2 = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface2,
ENCODER_SURFACE_ERR,
"reference surface, h264_pop_free_surface failed.");
}
- if (!h264_prv->recon_surface) {
- h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(h264_prv->recon_surface,
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface,
ENCODER_SURFACE_ERR,
"reconstructed surface, h264_pop_free_surface failed.");
}
- if (SLICE_TYPE_P == h264_prv->cur_slice_type) {
- h264_swap_surface(&h264_prv->ref_surface1, &h264_prv->ref_surface2);
+ if (SLICE_TYPE_P == priv->cur_slice_type) {
+ h264_swap_surface(&priv->ref_surface1, &priv->ref_surface2);
}
/* fill sequence parameters, need set every time */
- is_params_ok = h264_fill_sequence_buffer(h264_encoder, va_dpy, context_id);
+ is_params_ok = h264_fill_sequence_buffer(encoder);
ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
"h264_recreate_seq_param failed");
/* set pic_parameters*/
- is_params_ok = h264_fill_picture_buffer(h264_encoder, va_dpy, context_id, coded_buf);
+ is_params_ok = h264_fill_picture_buffer(encoder, coded_buf);
ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
"h264_recreate_pic_param failed");
/* set slice parameters, support multiple slices */
- is_params_ok = h264_fill_slice_buffers(h264_encoder, va_dpy, context_id);
+ is_params_ok = h264_fill_slice_buffers(encoder);
ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
"h264_recreate_slice_param failed");
ENCODER_ACQUIRE_DISPLAY_LOCK(display);
/*render all buffers*/
- if (VA_INVALID_ID != h264_prv->seq_parameter) {
- va_buffers[va_buffers_count++] = h264_prv->seq_parameter;
+ if (VA_INVALID_ID != priv->seq_parameter) {
+ va_buffers[va_buffers_count++] = priv->seq_parameter;
}
- if (VA_INVALID_ID != h264_prv->pic_parameter) {
- va_buffers[va_buffers_count++] = h264_prv->pic_parameter;
+ if (VA_INVALID_ID != priv->pic_parameter) {
+ va_buffers[va_buffers_count++] = priv->pic_parameter;
}
- if (VA_INVALID_ID != h264_prv->slice_parameter) {
- va_buffers[va_buffers_count++] = h264_prv->slice_parameter;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ va_buffers[va_buffers_count++] = priv->slice_parameter;
}
- if (SLICE_TYPE_I == h264_prv->cur_slice_type) {
- if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
- va_buffers[va_buffers_count++] = h264_prv->packed_sps_par_buf;
+ if (SLICE_TYPE_I == priv->cur_slice_type) {
+ if (VA_INVALID_ID != priv->packed_sps_par_buf) {
+ va_buffers[va_buffers_count++] = priv->packed_sps_par_buf;
}
- if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
- va_buffers[va_buffers_count++] = h264_prv->packed_sps_data_buf;
+ if (VA_INVALID_ID != priv->packed_sps_data_buf) {
+ va_buffers[va_buffers_count++] = priv->packed_sps_data_buf;
}
- if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
- va_buffers[va_buffers_count++] = h264_prv->packed_pps_par_buf;
+ if (VA_INVALID_ID != priv->packed_pps_par_buf) {
+ va_buffers[va_buffers_count++] = priv->packed_pps_par_buf;
}
- if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
- va_buffers[va_buffers_count++] = h264_prv->packed_pps_data_buf;
+ if (VA_INVALID_ID != priv->packed_pps_data_buf) {
+ va_buffers[va_buffers_count++] = priv->packed_pps_data_buf;
}
}
"vaRenderH264Picture failed.");
/*after finished, swap recon and surface2*/
- if (SLICE_TYPE_P == h264_prv->cur_slice_type ||
- SLICE_TYPE_I == h264_prv->cur_slice_type) {
- h264_swap_surface(&h264_prv->recon_surface, &h264_prv->ref_surface2);
+ if (SLICE_TYPE_P == priv->cur_slice_type ||
+ SLICE_TYPE_I == priv->cur_slice_type) {
+ h264_swap_surface(&priv->recon_surface, &priv->ref_surface2);
}
end:
#endif
static GstBuffer *
-gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
+gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *base,
guint8 *frame,
guint32 frame_size,
VABufferID *coded_buf)
{
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
GstBuffer *ret_buffer;
guint32 nal_size;
const guint8 *nal_start;
h264_bitstream_align(&bitstream, 0);
ENCODER_ASSERT(bitstream.bit_size == 0);
- if (!h264_prv->avc_flag) { /*nal format*/
+ if (!priv->avc_flag) { /*nal format*/
h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
} else { /* elementary format */
}
static EncoderStatus
-h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *h264_prv, const guint8 *buf, guint32 size)
+h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *priv, const guint8 *buf, guint32 size)
{
const guint8 *end = buf + size;
const guint8 *nal_start = buf;
case NAL_SPS: {
sps = gst_buffer_new_and_alloc(nal_size);
memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
- gst_buffer_replace(&h264_prv->sps_data, sps);
+ gst_buffer_replace(&priv->sps_data, sps);
gst_buffer_unref(sps); /*don't set to NULL*/
break;
}
case NAL_PPS: {
pps = gst_buffer_new_and_alloc(nal_size);
memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
- gst_buffer_replace(&h264_prv->pps_data, pps);
+ gst_buffer_replace(&priv->pps_data, pps);
gst_buffer_unref(pps);
break;
}
}
static void
-gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
+gst_h264_notify_frame(GstVaapiBaseEncoder *base, guint8 *buf, guint32 size)
{
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
- if (!h264_prv->sps_data || !h264_prv->pps_data) {
- h264_encoder_read_sps_pps(h264_prv, buf, size);
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ if (!priv->sps_data || !priv->pps_data) {
+ h264_encoder_read_sps_pps(priv, buf, size);
}
- if (h264_prv->sps_data && h264_prv->pps_data) {
- gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
+ if (priv->sps_data && priv->pps_data) {
+ gst_vaapi_base_encoder_set_frame_notify(base, FALSE);
}
}
static EncoderStatus
-gst_vaapi_encoder_h264_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GList **coded_pics)
+gst_vaapi_encoder_h264_flush(
+ GstVaapiEncoder* base,
+ GList **coded_pics
+)
{
- GstVaapiEncoderH264* h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
+ GstVaapiEncoderH264* encoder = GST_VAAPI_ENCODER_H264_CAST(base);
EncoderStatus ret = ENCODER_NO_ERROR;
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
- //h264_prv->frame_count = 0;
- h264_prv->cur_display_num = 0;
- h264_prv->cur_decode_num = 0;
- h264_prv->cur_slice_type = SLICE_TYPE_I;
- h264_prv->gop_count = g_queue_get_length(h264_prv->queued_buffers);
+ //priv->frame_count = 0;
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->gop_count = g_queue_get_length(priv->queued_buffers);
//gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
//end:
return ret;
}
-EncoderStatus
-gst_vaapi_encoder_h264_get_avcC_codec_data(GstVaapiEncoderH264 *h264_encoder, GstBuffer **buffer)
+static EncoderStatus
+gst_vaapi_encoder_h264_get_avcC_codec_data(
+ GstVaapiEncoderH264 *encoder,
+ GstBuffer **buffer
+)
{
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
GstBuffer *avc_codec;
const guint32 configuration_version = 0x01;
const guint32 length_size_minus_one = 0x03;
guint32 profile, profile_comp, level_idc;
ENCODER_ASSERT(buffer);
- if (!h264_prv->sps_data || !h264_prv->pps_data) {
+ if (!priv->sps_data || !priv->pps_data) {
return ENCODER_DATA_NOT_READY;
}
- if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(h264_prv->sps_data),
- GST_BUFFER_SIZE(h264_prv->sps_data),
+ if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(priv->sps_data),
+ GST_BUFFER_SIZE(priv->sps_data),
&profile, &profile_comp, &level_idc))
{
ENCODER_ASSERT(0);
H264Bitstream bitstream;
h264_bitstream_init(&bitstream,
- (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 32)*8);
+ (GST_BUFFER_SIZE(priv->sps_data)+GST_BUFFER_SIZE(priv->pps_data) + 32)*8);
/*codec_data*/
h264_bitstream_write_uint(&bitstream, configuration_version, 8);
/*write sps*/
h264_bitstream_write_uint(&bitstream, 1, 5); /* sps count = 1*/
ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
- h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->sps_data), 16);
- h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
- GST_BUFFER_SIZE(h264_prv->sps_data));
+ h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(priv->sps_data), 16);
+ h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(priv->sps_data),
+ GST_BUFFER_SIZE(priv->sps_data));
/*write pps*/
h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
- h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->pps_data), 16);
- h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
- GST_BUFFER_SIZE(h264_prv->pps_data));
+ h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(priv->pps_data), 16);
+ h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(priv->pps_data),
+ GST_BUFFER_SIZE(priv->pps_data));
avc_codec = gst_buffer_new();
GST_BUFFER_MALLOCDATA(avc_codec) =
}
static EncoderStatus
-gst_vaapi_encoder_h264_get_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer)
+gst_vaapi_encoder_h264_get_codec_data(
+ GstVaapiEncoder* base,
+ GstBuffer **buffer)
{
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder);
- GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
- if (h264_prv->avc_flag)
- return gst_vaapi_encoder_h264_get_avcC_codec_data(h264_encoder, buffer);
+ if (priv->avc_flag)
+ return gst_vaapi_encoder_h264_get_avcC_codec_data(encoder, buffer);
return ENCODER_NO_DATA;
}
static void
+gst_vaapi_encoder_h264_init(GstVaapiEncoderH264 *encoder)
+{
+ GstVaapiEncoderH264Private *priv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder);
+ ENCODER_ASSERT(priv);
+ priv->public = encoder;
+ encoder->priv = priv;
+
+ /* init public attributes */
+ gst_vaapi_encoder_h264_init_public_values(encoder);
+ gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
+
+ /* init private values*/
+ priv->format = GST_MAKE_FOURCC('N','V','1','2');
+ priv->avc_flag = FALSE;
+
+ priv->ref_surface1 = NULL;
+ priv->ref_surface2 = NULL;
+ priv->recon_surface = NULL;
+
+ priv->seq_parameter = VA_INVALID_ID;
+ priv->pic_parameter = VA_INVALID_ID;
+ priv->slice_parameter = VA_INVALID_ID;
+ priv->packed_sps_par_buf = VA_INVALID_ID;
+ priv->packed_sps_data_buf = VA_INVALID_ID;
+ priv->packed_pps_par_buf = VA_INVALID_ID;
+ priv->packed_pps_data_buf = VA_INVALID_ID;
+ priv->slice_param_buffers = NULL;
+ priv->default_slice_height = 0;
+ priv->slice_mod_mb_num = 0;
+
+ priv->sps_data = NULL;
+ priv->pps_data = NULL;
+
+ priv->queued_buffers = g_queue_new();
+ priv->gop_count = 0;
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->last_decode_time = 0LL;
+ priv->default_cts_offset = 0;
+
+ priv->max_frame_num = 0;
+ priv->max_pic_order_cnt = 0;
+ priv->idr_num = 0;
+}
+
+static void
+gst_vaapi_encoder_h264_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+ GstVaapiEncoderH264Private *priv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+
+ if (priv->sps_data) {
+ gst_buffer_unref(priv->sps_data);
+ priv->sps_data = NULL;
+ }
+ if (priv->pps_data) {
+ gst_buffer_unref(priv->pps_data);
+ priv->pps_data = NULL;
+ }
+ if (priv->slice_param_buffers) {
+ g_free(priv->slice_param_buffers);
+ priv->slice_param_buffers = NULL;
+ }
+
+ if (priv->queued_buffers) {
+ ENCODER_ASSERT(g_queue_is_empty(priv->queued_buffers));
+ g_queue_free(priv->queued_buffers);
+ priv->queued_buffers = NULL;
+ }
+
+ G_OBJECT_CLASS(gst_vaapi_encoder_h264_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_h264_class_init(GstVaapiEncoderH264Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GstVaapiEncoderH264Private));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
+ "gst_va_h264_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_h264_finalize;
+
+ base_class->validate_attributes = gst_h264_validate_parameters;
+ base_class->pre_alloc_resource = gst_vaapi_encoder_h264_alloc_slices;
+ base_class->release_resource = gst_vaapi_encoder_h264_release_resource;
+ base_class->prepare_next_input_buffer = gst_vaapi_encoder_h264_prepare_next_buffer;
+ base_class->render_frame = gst_vaapi_encoder_h264_rendering;
+ base_class->notify_frame = gst_h264_notify_frame;
+ base_class->copy_coded_frame = gst_vaapi_encoder_h264_copy_coded_buffer;
+ base_class->encode_frame_failed = gst_vaapi_encoder_h264_frame_failed;
+
+ encoder_class->flush = gst_vaapi_encoder_h264_flush;
+ encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data;
+}
+
+static void
h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
{
bitstream->bit_size = 0;
GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg4_encoder_debug);
#define GST_CAT_DEFAULT gst_vaapi_mpeg4_encoder_debug
+#define GST_VAAPI_ENCODER_MPEG4_CAST(encoder) ((GstVaapiEncoderMpeg4 *)(encoder))
+
+#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0
+#define VISUAL_OBJECT_SEQUENCE_END_CODE 0x000001B1
+#define VISUAL_OBJECT_START_CODE 0x000001B5
+#define VIDEO_OBJECT_PLANE_START_CODE 0x000001B6
+/* Video Object Start Code range */
+#define VIDEO_OBJECT_START_CODE_MIN 0x00000100
+#define VIDEO_OBJECT_START_CODE_MAX 0x0000011F
+/* Video Object Layer Start Code range 0x00000120 ~ 0x0000012F*/
+#define VIDEO_OBJECT_LAYER_START_CODE 0x00000120
+#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0
+
struct _GstVaapiEncoderMpeg4Private {
GstVaapiSurface *ref_surface; /* reference buffer*/
G_DEFINE_TYPE(GstVaapiEncoderMpeg4, gst_vaapi_encoder_mpeg4, GST_TYPE_VAAPI_BASE_ENCODER);
-/*
-static EncoderStatus gst_vaapi_encoder_mpeg4_flush(GstVaapiEncoder* encoder,
- GstVaapiDisplay *display, GstVaapiContext *context,
- GList **coded_pics);
-*/
-static EncoderStatus gst_vaapi_encoder_mpeg4_get_codec_data(
- GstVaapiEncoder *encoder, GstBuffer **buffer);
-static gboolean gst_mpeg4_validate_parameters(GstVaapiBaseEncoder *encoder);
-static gboolean gst_vaapi_encoder_mpeg4_release_resource(
- GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context);
-static void gst_mpeg4_notify_frame(GstVaapiBaseEncoder *encoder,
- guint8 *buf, guint32 size);
-
-static EncoderStatus gst_vaapi_encoder_mpeg4_rendering(GstVaapiBaseEncoder *encoder,
- GstVaapiDisplay *display, GstVaapiContext *context,
- GstVaapiSurface *surface, guint frame_index,
- VABufferID coded_buf, gboolean *is_key);
-
-
-static void gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass);
-static void gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *encoder);
-static void gst_vaapi_encoder_mpeg4_finalize(GObject *object);
-
-static gboolean mpeg4_encoder_generate_codec_data(const guint8 *in_buffer,
- guint32 in_size, GstBuffer **out_buffer);
-
GstVaapiEncoderMpeg4 *
gst_vaapi_encoder_mpeg4_new(void)
{
- return GST_VAAPI_ENCODER_MPEG4(g_object_new(GST_TYPE_VAAPI_ENCODER_MPEG4, NULL));
-}
-
-
-static void
-gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass)
-{
- GObjectClass * const object_class = G_OBJECT_CLASS(klass);
- GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
- GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
-
- g_type_class_add_private(klass, sizeof(GstVaapiEncoderMpeg4Private));
-
- GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg4_encoder_debug, "gst_va_mpeg4_encoder", 0,
- "gst_va_mpeg4_encoder element");
-
- object_class->finalize = gst_vaapi_encoder_mpeg4_finalize;
-
- base_class->validate_attributes = gst_mpeg4_validate_parameters;
- base_class->pre_alloc_resource = NULL;
- base_class->release_resource = gst_vaapi_encoder_mpeg4_release_resource;
- base_class->render_frame = gst_vaapi_encoder_mpeg4_rendering;
- base_class->notify_frame = gst_mpeg4_notify_frame;
- base_class->copy_coded_frame = NULL;
-
- /*
- encoder_class->flush = gst_vaapi_encoder_mpeg4_flush;
- */
- encoder_class->get_codec_data = gst_vaapi_encoder_mpeg4_get_codec_data;
-}
-
-static void
-gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *mpeg4_encoder)
-{
- GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
- ENCODER_ASSERT(mpeg4_prv);
-
- /* init public */
- mpeg4_encoder->profile = VAProfileMPEG4Simple;
- mpeg4_encoder->bitrate = 0;
- mpeg4_encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
- mpeg4_encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
- mpeg4_encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
-
- gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(mpeg4_encoder), TRUE);
- /* init private */
- mpeg4_prv->ref_surface = NULL;
- mpeg4_prv->recon_surface = NULL;
-
- mpeg4_prv->seq_parameter = VA_INVALID_ID;
- mpeg4_prv->pic_parameter = VA_INVALID_ID;
- mpeg4_prv->slice_parameter = VA_INVALID_ID;
-
- mpeg4_prv->codec_data = NULL;
-}
-
-static void
-gst_vaapi_encoder_mpeg4_finalize(GObject *object)
-{
- /*free private buffers*/
- GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
-
- if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
- gst_vaapi_encoder_uninitialize(encoder);
- }
- G_OBJECT_CLASS(gst_vaapi_encoder_mpeg4_parent_class)->finalize(object);
+ return GST_VAAPI_ENCODER_MPEG4_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_MPEG4, NULL));
}
gboolean
-gst_mpeg4_validate_parameters(GstVaapiBaseEncoder *encoder)
+gst_mpeg4_validate_parameters(GstVaapiBaseEncoder *base)
{
- GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
- if (!ENCODER_WIDTH(mpeg4_encoder) || !ENCODER_HEIGHT(mpeg4_encoder) || !ENCODER_FPS(mpeg4_encoder)) {
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
return FALSE;
}
- if (VAProfileMPEG4Simple != mpeg4_encoder->profile && VAProfileMPEG4AdvancedSimple != mpeg4_encoder->profile) {
+ if (VAProfileMPEG4Simple != encoder->profile && VAProfileMPEG4AdvancedSimple != encoder->profile) {
return FALSE;
}
- gst_vaapi_base_encoder_set_va_profile(encoder, mpeg4_encoder->profile);
+ gst_vaapi_base_encoder_set_va_profile(base, encoder->profile);
- if (!mpeg4_encoder->intra_period) {
- mpeg4_encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
+ if (!encoder->intra_period) {
+ encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
}
- if (-1 == mpeg4_encoder->init_qp) {
- mpeg4_encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
+ if (-1 == encoder->init_qp) {
+ encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
}
- if (-1 == mpeg4_encoder->min_qp) {
- mpeg4_encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
+ if (-1 == encoder->min_qp) {
+ encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
}
/* default compress ratio 1: (4*8*1.5) */
- if (!mpeg4_encoder->bitrate) {
- mpeg4_encoder->bitrate = ENCODER_WIDTH(mpeg4_encoder)*ENCODER_HEIGHT(mpeg4_encoder)*ENCODER_FPS(mpeg4_encoder)/4;
+ if (!encoder->bitrate) {
+ encoder->bitrate = ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
}
return TRUE;
}
static void
-mpeg4_release_parameters(GstVaapiEncoderMpeg4 *mpeg4_encoder, GstVaapiDisplay *display)
+mpeg4_release_parameters(GstVaapiEncoderMpeg4 *encoder)
{
- GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ VADisplay va_dpy = ENCODER_DISPLAY(encoder);
VAStatus va_status = VA_STATUS_SUCCESS;
VAAPI_UNUSED_ARG(va_status);
- if (VA_INVALID_ID != mpeg4_prv->seq_parameter) {
- va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->seq_parameter);
- mpeg4_prv->seq_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->seq_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->seq_parameter);
+ priv->seq_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != mpeg4_prv->pic_parameter) {
- va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->pic_parameter);
- mpeg4_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
- if (VA_INVALID_ID != mpeg4_prv->slice_parameter) {
- va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->slice_parameter);
- mpeg4_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ va_status = vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
}
static gboolean
-gst_vaapi_encoder_mpeg4_release_resource(GstVaapiBaseEncoder* encoder,
- GstVaapiDisplay *display,
- GstVaapiContext *context)
+gst_vaapi_encoder_mpeg4_release_resource(GstVaapiBaseEncoder* base)
{
- GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
- GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
- mpeg4_release_parameters(mpeg4_encoder, display);
+ mpeg4_release_parameters(encoder);
/*remove ref_surface*/
- if (mpeg4_prv->ref_surface) {
+ if (priv->ref_surface) {
if (context) {
- gst_vaapi_context_put_surface(context, mpeg4_prv->ref_surface);
+ gst_vaapi_context_put_surface(context, priv->ref_surface);
} else {
- g_object_unref(mpeg4_prv->ref_surface);
+ g_object_unref(priv->ref_surface);
}
- mpeg4_prv->ref_surface = NULL;
+ priv->ref_surface = NULL;
}
/*remove recon_surface*/
- if (mpeg4_prv->recon_surface) {
+ if (priv->recon_surface) {
if (context) {
- gst_vaapi_context_put_surface(context, mpeg4_prv->recon_surface);
+ gst_vaapi_context_put_surface(context, priv->recon_surface);
} else {
- g_object_unref(mpeg4_prv->recon_surface);
+ g_object_unref(priv->recon_surface);
}
- mpeg4_prv->recon_surface = NULL;
+ priv->recon_surface = NULL;
}
- if (mpeg4_prv->codec_data) {
- gst_buffer_unref(mpeg4_prv->codec_data);
- mpeg4_prv->codec_data = NULL;
+ if (priv->codec_data) {
+ gst_buffer_unref(priv->codec_data);
+ priv->codec_data = NULL;
}
return TRUE;
static EncoderStatus
-gst_vaapi_encoder_mpeg4_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstVaapiSurface *surface,
- guint frame_index, VABufferID coded_buf, gboolean *is_key)
+gst_vaapi_encoder_mpeg4_rendering(
+ GstVaapiBaseEncoder *base,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key
+)
{
- GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
- GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(mpeg4_encoder);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
VAStatus va_status = VA_STATUS_SUCCESS;
EncoderStatus ret = ENCODER_NO_ERROR;
- *is_key = (frame_index % mpeg4_encoder->intra_period == 0);
+ *is_key = (frame_index % encoder->intra_period == 0);
/* initialize sequence parameter set, only first time */
- if (VA_INVALID_ID == mpeg4_prv->seq_parameter) { /*only the first time*/
+ if (VA_INVALID_ID == priv->seq_parameter) { /*only the first time*/
VAEncSequenceParameterBufferMPEG4 seq_mpeg4 = {0};
- seq_mpeg4.profile_and_level_indication = mpeg4_get_profile_level_indication(mpeg4_encoder->profile);
- seq_mpeg4.intra_period = mpeg4_encoder->intra_period;
- seq_mpeg4.video_object_layer_width = ENCODER_WIDTH(mpeg4_encoder);
- seq_mpeg4.video_object_layer_height = ENCODER_HEIGHT(mpeg4_encoder);
- seq_mpeg4.vop_time_increment_resolution = ENCODER_FPS(mpeg4_encoder);
+ seq_mpeg4.profile_and_level_indication = mpeg4_get_profile_level_indication(encoder->profile);
+ seq_mpeg4.intra_period = encoder->intra_period;
+ seq_mpeg4.video_object_layer_width = ENCODER_WIDTH(encoder);
+ seq_mpeg4.video_object_layer_height = ENCODER_HEIGHT(encoder);
+ seq_mpeg4.vop_time_increment_resolution = ENCODER_FPS(encoder);
seq_mpeg4.fixed_vop_rate = MPEG4_DEFAULT_FIXED_VOP_RATE;
if (seq_mpeg4.fixed_vop_rate) {
seq_mpeg4.fixed_vop_time_increment = 1;
}
- seq_mpeg4.bits_per_second = mpeg4_encoder->bitrate;
- seq_mpeg4.frame_rate = ENCODER_FPS(mpeg4_encoder);
- seq_mpeg4.initial_qp = mpeg4_encoder->init_qp;
- seq_mpeg4.min_qp = mpeg4_encoder->min_qp; //mpeg4_encoder->min_qp;
+ seq_mpeg4.bits_per_second = encoder->bitrate;
+ seq_mpeg4.frame_rate = ENCODER_FPS(encoder);
+ seq_mpeg4.initial_qp = encoder->init_qp;
+ seq_mpeg4.min_qp = encoder->min_qp; //mpeg4_encoder->min_qp;
va_status = vaCreateBuffer(va_dpy, context_id,
VAEncSequenceParameterBufferType,
- sizeof(seq_mpeg4), 1, &seq_mpeg4, &mpeg4_prv->seq_parameter);
+ sizeof(seq_mpeg4), 1, &seq_mpeg4, &priv->seq_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
ENCODER_ENC_RES_ERR, "mpeg4 alloc seq-buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &mpeg4_prv->seq_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
ENCODER_PICTURE_ERR,
"mpeg4 vaRenderPicture seq-parameters failed.");
}
/* set reference and reconstructed surfaces */
- if (!mpeg4_prv->ref_surface) {
- mpeg4_prv->ref_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(mpeg4_prv->ref_surface,
+ if (!priv->ref_surface) {
+ priv->ref_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface,
ENCODER_SURFACE_ERR,
"mpeg4 reference surface, mpeg4_pop_free_surface failed.");
}
- if (!mpeg4_prv->recon_surface) {
- mpeg4_prv->recon_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(mpeg4_prv->recon_surface,
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface,
ENCODER_SURFACE_ERR,
"mpeg4 reconstructed surface, mpeg4_pop_free_surface failed.");
}
/* initialize picture, every time, every frame */
VAEncPictureParameterBufferMPEG4 pic_mpeg4 = {0};
- pic_mpeg4.reference_picture = GST_VAAPI_OBJECT_ID(mpeg4_prv->ref_surface);
- pic_mpeg4.reconstructed_picture = GST_VAAPI_OBJECT_ID(mpeg4_prv->recon_surface);
+ pic_mpeg4.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface);
+ pic_mpeg4.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
pic_mpeg4.coded_buf = coded_buf;
- pic_mpeg4.picture_width = ENCODER_WIDTH(mpeg4_encoder);
- pic_mpeg4.picture_height = ENCODER_HEIGHT(mpeg4_encoder);
+ pic_mpeg4.picture_width = ENCODER_WIDTH(encoder);
+ pic_mpeg4.picture_height = ENCODER_HEIGHT(encoder);
if (0 == frame_index) {
pic_mpeg4.modulo_time_base = 0;
} else {
- pic_mpeg4.modulo_time_base = ((frame_index%ENCODER_FPS(mpeg4_encoder)) == 0 ? 1 : 0);
+ pic_mpeg4.modulo_time_base = ((frame_index%ENCODER_FPS(encoder)) == 0 ? 1 : 0);
}
- pic_mpeg4.vop_time_increment = 301%ENCODER_FPS(mpeg4_encoder);
+ pic_mpeg4.vop_time_increment = 301%ENCODER_FPS(encoder);
pic_mpeg4.picture_type = *is_key ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
- if (VA_INVALID_ID != mpeg4_prv->pic_parameter) { /* destroy first*/
- va_status = vaDestroyBuffer(va_dpy, mpeg4_prv->pic_parameter);
- mpeg4_prv->pic_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->pic_parameter) { /* destroy first*/
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_parameter);
+ priv->pic_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
- sizeof(pic_mpeg4), 1, &pic_mpeg4, &mpeg4_prv->pic_parameter);
+ sizeof(pic_mpeg4), 1, &pic_mpeg4, &priv->pic_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_ENC_RES_ERR,
"mpeg4 creating pic-param buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &mpeg4_prv->pic_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR,
"mpeg4 rendering pic-param buffer failed.");
/*initialize slice parameters, only ONE slice for mpeg4*/
VAEncSliceParameterBuffer slice_mpeg4 = { 0 };
slice_mpeg4.start_row_number = 0;
- slice_mpeg4.slice_height = (ENCODER_HEIGHT(mpeg4_encoder)+15)/16; /*MB?*/
+ slice_mpeg4.slice_height = (ENCODER_HEIGHT(encoder)+15)/16; /*MB?*/
slice_mpeg4.slice_flags.bits.is_intra = *is_key;
slice_mpeg4.slice_flags.bits.disable_deblocking_filter_idc = 0;
- if (VA_INVALID_ID != mpeg4_prv->slice_parameter) {
- vaDestroyBuffer(va_dpy, mpeg4_prv->slice_parameter);
- mpeg4_prv->slice_parameter = VA_INVALID_ID;
+ if (VA_INVALID_ID != priv->slice_parameter) {
+ vaDestroyBuffer(va_dpy, priv->slice_parameter);
+ priv->slice_parameter = VA_INVALID_ID;
}
va_status = vaCreateBuffer(va_dpy,
sizeof(slice_mpeg4),
1,
&slice_mpeg4,
- &mpeg4_prv->slice_parameter);
+ &priv->slice_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_ENC_RES_ERR,
"mpeg4 creating slice-parameters buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &mpeg4_prv->slice_parameter, 1);
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
ENCODER_PICTURE_ERR,
"mpeg4 rendering slice-parameters buffer failed.");
/*swap ref_surface and recon_surface */
- GstVaapiSurface *swap = mpeg4_prv->ref_surface;
- mpeg4_prv->ref_surface = mpeg4_prv->recon_surface;
- mpeg4_prv->recon_surface = swap;
+ GstVaapiSurface *swap = priv->ref_surface;
+ priv->ref_surface = priv->recon_surface;
+ priv->recon_surface = swap;
end:
return ret;
memcpy(GST_BUFFER_DATA(buffer), frame, frame_size);
#if 0
- GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
+ GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4_CAST(encoder);
if (mpeg4_encoder->profile == VAProfileMPEG4AdvancedSimple) {
guint8 *start_code = GST_BUFFER_DATA(buffer)+16; /*fix old issue of ASP in mrst platform*/
if (start_code[0] == 0x01 && start_code[1] == 0x20
}
#endif
-static void
-gst_mpeg4_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
-{
- GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
- if (!mpeg4_prv->codec_data) {
- if (!mpeg4_encoder_generate_codec_data(buf, size, &mpeg4_prv->codec_data)) {
- ENCODER_LOG_ERROR("mpeg4 encoder coded data error, please check <mpeg4_encoder_generate_codec_data>.");
- }
- }
- if (mpeg4_prv->codec_data) {
- gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
- }
-}
-
-
-static EncoderStatus
-gst_vaapi_encoder_mpeg4_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GList **coded_pics)
-{
- GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4(encoder);
-
- mpeg4_release_parameters(mpeg4_encoder, display);
- return ENCODER_NO_ERROR;
-}
-
-
-static EncoderStatus
-gst_vaapi_encoder_mpeg4_get_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
-{
- GstVaapiEncoderMpeg4Private *mpeg4_prv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
-
- if (!mpeg4_prv->codec_data)
- return ENCODER_DATA_NOT_READY;
- *buffer = gst_buffer_ref(mpeg4_prv->codec_data);
- return ENCODER_NO_ERROR;
-}
-
-#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0
-#define VISUAL_OBJECT_SEQUENCE_END_CODE 0x000001B1
-#define VISUAL_OBJECT_START_CODE 0x000001B5
-#define VIDEO_OBJECT_PLANE_START_CODE 0x000001B6
-/* Video Object Start Code range */
-#define VIDEO_OBJECT_START_CODE_MIN 0x00000100
-#define VIDEO_OBJECT_START_CODE_MAX 0x0000011F
-/* Video Object Layer Start Code range 0x00000120 ~ 0x0000012F*/
-#define VIDEO_OBJECT_LAYER_START_CODE 0x00000120
-#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0
-
-
static gboolean
find_video_object_configuration_info(const guint8 *in_buffer, guint32 in_size,
const guint8 **out_buffer, guint32 *out_size)
}
static gboolean
-mpeg4_encoder_generate_codec_data(const guint8 *in_buffer, guint32 in_size, GstBuffer **out_buffer)
+mpeg4_encoder_generate_codec_data(
+ const guint8 *in_buffer,
+ guint32 in_size,
+ GstBuffer **out_buffer
+)
{
const guint8 *codec_buffer = NULL;
guint32 codec_size = 0;
guint8 *visual_obj_seq_end = NULL;
- if (!find_video_object_configuration_info(in_buffer, in_size, &codec_buffer, &codec_size)) {
+ if (!find_video_object_configuration_info(in_buffer,
+ in_size,
+ &codec_buffer,
+ &codec_size)
+ ) {
return FALSE;
}
ENCODER_ASSERT(codec_size);
return TRUE;
}
+static void
+gst_mpeg4_notify_frame(GstVaapiBaseEncoder *base, guint8 *buf, guint32 size)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ if (!priv->codec_data) {
+ if (!mpeg4_encoder_generate_codec_data(buf, size, &priv->codec_data)) {
+ ENCODER_LOG_ERROR("mpeg4 encoder coded data error, please check <mpeg4_encoder_generate_codec_data>.");
+ }
+ }
+ if (priv->codec_data) {
+ gst_vaapi_base_encoder_set_frame_notify(base, FALSE);
+ }
+}
+
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_flush(
+ GstVaapiEncoder* base,
+ GList **coded_pics)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+
+ mpeg4_release_parameters(encoder);
+ return ENCODER_NO_ERROR;
+}
+
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_get_codec_data(GstVaapiEncoder *base, GstBuffer **buffer)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+
+ if (!priv->codec_data)
+ return ENCODER_DATA_NOT_READY;
+ *buffer = gst_buffer_ref(priv->codec_data);
+ return ENCODER_NO_ERROR;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *encoder)
+{
+ GstVaapiEncoderMpeg4Private *priv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
+ ENCODER_ASSERT(priv);
+ encoder->priv = priv;
+
+ /* init public */
+ encoder->profile = VAProfileMPEG4Simple;
+ encoder->bitrate = 0;
+ encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
+ encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
+ encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
+
+ gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
+ /* init private */
+ priv->ref_surface = NULL;
+ priv->recon_surface = NULL;
+
+ priv->seq_parameter = VA_INVALID_ID;
+ priv->pic_parameter = VA_INVALID_ID;
+ priv->slice_parameter = VA_INVALID_ID;
+
+ priv->codec_data = NULL;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+ G_OBJECT_CLASS(gst_vaapi_encoder_mpeg4_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GstVaapiEncoderMpeg4Private));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg4_encoder_debug, "gst_va_mpeg4_encoder", 0,
+ "gst_va_mpeg4_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_mpeg4_finalize;
+
+ base_class->validate_attributes = gst_mpeg4_validate_parameters;
+ base_class->pre_alloc_resource = NULL;
+ base_class->release_resource = gst_vaapi_encoder_mpeg4_release_resource;
+ base_class->render_frame = gst_vaapi_encoder_mpeg4_rendering;
+ base_class->notify_frame = gst_mpeg4_notify_frame;
+ base_class->copy_coded_frame = NULL;
+
+ encoder_class->flush = gst_vaapi_encoder_mpeg4_flush;
+ encoder_class->get_codec_data = gst_vaapi_encoder_mpeg4_get_codec_data;
+}
guint32 intra_period;
guint32 init_qp; /*default 15, 1~31*/
guint32 min_qp; /*default 1, 1~31*/
+
+ GstVaapiEncoderMpeg4Private *priv;
};
struct _GstVaapiEncoderMpeg4Class {