2 * gstvaapibaseencoder.c - VA-API base encoder
4 * Copyright (C) 2011 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
22 #include "gstvaapibaseencoder.h"
30 #include "va/va_x11.h"
32 #include "gst/gstclock.h"
33 #include "gst/gstvalue.h"
35 #include "gstvaapiobject.h"
36 #include "gstvaapiobject_priv.h"
37 #include "gstvaapicontext.h"
38 #include "gstvaapisurface.h"
39 #include "gstvaapisurfacepool.h"
40 #include "gstvaapivideobuffer.h"
41 #include "gstvaapidisplay_priv.h"
42 #include "gstvaapidebug.h"
44 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_base_encoder_debug);
45 #define GST_CAT_DEFAULT gst_vaapi_base_encoder_debug
47 #define VA_INVALID_PROFILE 0xffffffff
48 #define DEFAULT_VA_CODEDBUF_NUM 4
50 struct _GstVaapiBaseEncoderPrivate {
51 guint32 format; /*NV12, I420,*/
53 /*total encoded frames*/
55 VABufferID *coded_bufs;
56 guint32 coded_buf_num;
57 GMutex *code_buffer_lock;
58 GCond *code_buffer_cond;
59 GQueue *available_code_buffers;
61 GstVaapiSurfacePool *surfaces_pool;
63 guint frame_notify_flag : 1;
67 G_DEFINE_TYPE(GstVaapiBaseEncoder, gst_vaapi_base_encoder, GST_TYPE_VAAPI_ENCODER)
70 pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv);
73 push_available_coded_buffer(
74 GstVaapiBaseEncoderPrivate *priv,
79 gst_vaapi_base_encoder_set_frame_notify(
80 GstVaapiBaseEncoder *encoder,
84 GstVaapiBaseEncoderPrivate *priv = encoder->priv;
85 priv->frame_notify_flag = flag;
89 gst_vaapi_base_encoder_set_va_profile(
90 GstVaapiBaseEncoder *encoder,
94 GstVaapiBaseEncoderPrivate *priv = encoder->priv;
95 priv->profile = profile;
100 gst_vaapi_base_encoder_set_input_format(
101 GstVaapiBaseEncoder* encoder,
105 GstVaapiBaseEncoderPrivate *priv = encoder->priv;
106 priv->format = format;
110 default_validate_encoder_parameters(
111 GstVaapiBaseEncoder *encoder
114 if (!ENCODER_WIDTH(encoder) ||
115 !ENCODER_HEIGHT(encoder) ||
116 !ENCODER_FPS(encoder)) {
123 base_encoder_alloc_coded_buffers(
124 GstVaapiBaseEncoder *base_encoder,
125 GstVaapiContext *context
128 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
129 GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
131 VAContextID context_id;
132 VAStatus va_status = VA_STATUS_SUCCESS;
133 gboolean is_locked = FALSE;
136 guint32 buffer_size =
137 (ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder) * 400) /
140 ENCODER_ASSERT(display && context);
141 ENCODER_ASSERT(priv->available_code_buffers);
142 ENCODER_ASSERT(!priv->coded_bufs);
144 va_dpy = ENCODER_VA_DISPLAY(base_encoder);
145 context_id = gst_vaapi_context_get_id(context);
147 priv->coded_bufs = (VABufferID*)
148 g_malloc0(priv->coded_buf_num * sizeof(priv->coded_bufs[0]));
150 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
151 for (i = 0; i < priv->coded_buf_num; i++) {
152 va_status = vaCreateBuffer(va_dpy,
154 VAEncCodedBufferType,
157 &priv->coded_bufs[i]);
158 if (VA_STATUS_SUCCESS != va_status)
161 ENCODER_RELEASE_DISPLAY_LOCK(display);
162 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
164 "create coded buffer failed.");
166 /* init queue available_code_buffers */
167 g_mutex_lock(priv->code_buffer_lock);
168 for (i = 0; i < priv->coded_buf_num; i++) {
169 g_queue_push_head(priv->available_code_buffers, &priv->coded_bufs[i]);
171 g_cond_signal(priv->code_buffer_cond);
172 g_mutex_unlock(priv->code_buffer_lock);
180 release_coded_buffers(GstVaapiBaseEncoder *base_encoder)
182 VAStatus va_status = VA_STATUS_SUCCESS;
183 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
184 GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
185 guint32 available_buf_count = priv->coded_buf_num;
187 gboolean is_locked = FALSE;
189 ENCODER_ASSERT(display);
190 VAAPI_UNUSED_ARG(va_status);
191 VADisplay va_dpy = gst_vaapi_display_get_display(display);
193 /* wait clear all available coded buffers*/
194 g_mutex_lock(priv->code_buffer_lock);
195 while (available_buf_count) {
196 if (g_queue_is_empty(priv->available_code_buffers)) {
197 g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
199 g_queue_pop_head(priv->available_code_buffers);
200 available_buf_count--;
203 g_mutex_unlock(priv->code_buffer_lock);
205 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
206 for (i = 0; i < priv->coded_buf_num; i++) {
207 va_status = vaDestroyBuffer(va_dpy, priv->coded_bufs[i]);
209 ENCODER_RELEASE_DISPLAY_LOCK(display);
211 return ENCODER_NO_ERROR;
215 gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder)
217 GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
218 GstVaapiBaseEncoderClass *base_class =
219 GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
220 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
221 EncoderStatus ret = ENCODER_NO_ERROR;
223 /* release buffers first */
224 priv->need_flush = FALSE;
226 if (base_class->release_resource) {
227 base_class->release_resource(base_encoder);
229 release_coded_buffers(base_encoder);
230 priv->frame_count = 0;
235 static GstVaapiContext *
237 GstVaapiDisplay *display,
238 GstVaapiProfile profile,
241 GstVaapiRateControl rate_control
244 GstVaapiContextInfo info;
246 info.profile = profile;
247 info.entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
248 info.rate_control = rate_control;
250 info.height = height;
252 return gst_vaapi_context_new_full(display, &info);
256 gst_vaapi_base_encoder_open_default(
257 GstVaapiEncoder* encoder,
258 GstVaapiContext **context
261 GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
262 GstVaapiBaseEncoderClass *base_class =
263 GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
264 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
265 GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
267 GstVaapiContext *out_context = NULL;
269 EncoderStatus ret = ENCODER_NO_ERROR;
270 gboolean check_attri_ret = TRUE;
271 /*check and set default values*/
272 if (base_class->validate_attributes) {
273 check_attri_ret = base_class->validate_attributes(base_encoder);
275 check_attri_ret = default_validate_encoder_parameters(base_encoder);
277 ENCODER_CHECK_STATUS(check_attri_ret,
278 ENCODER_PARAMETER_ERR,
279 "vaapi encoder paramerter error.");
280 ENCODER_CHECK_STATUS(VA_INVALID_PROFILE != priv->profile,
282 "vaapi encoder profile not set.");
284 ENCODER_ASSERT(ENCODER_DISPLAY(encoder));
286 out_context = _create_context(display,
287 gst_vaapi_profile(priv->profile),
288 ENCODER_WIDTH(encoder),
289 ENCODER_HEIGHT(encoder),
290 ENCODER_RATE_CONTROL(encoder));
291 ENCODER_CHECK_STATUS(out_context,
293 "gst_vaapi_context_new failed.");
294 ENCODER_CHECK_STATUS(VA_INVALID_ID != GST_VAAPI_OBJECT_ID(out_context),
296 "gst_vaapi_context_new failed.");
298 if (base_class->pre_alloc_resource) {
299 ENCODER_CHECK_STATUS(
300 base_class->pre_alloc_resource(base_encoder, out_context),
302 "encoder <pre_alloc_resource> failed."
305 ENCODER_CHECK_STATUS(
306 base_encoder_alloc_coded_buffers(base_encoder, out_context),
308 "encoder <base_encoder_alloc_coded_buffers> failed."
310 *context = out_context;
312 return ENCODER_NO_ERROR;
316 if (ENCODER_NO_ERROR != ret) {
317 gst_vaapi_base_encoder_close_default(encoder);
319 g_object_unref(out_context);
326 gst_vaapi_base_encoder_copy_buffer_default(
327 GstVaapiBaseEncoder *encoder,
330 VABufferID *coded_buf
333 GstBuffer *ret_buffer = NULL;
335 ret_buffer = gst_base_encode_share_buffer_new(encoder, coded_buf);
336 ENCODER_ASSERT(ret_buffer);
337 GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
338 GST_BUFFER_DATA(ret_buffer) = frame;
339 GST_BUFFER_SIZE(ret_buffer) = frame_size;
341 ret_buffer = gst_buffer_new_and_alloc(frame_size);
342 memcpy(GST_BUFFER_DATA(ret_buffer),frame, frame_size);
348 base_query_encoding_status(
349 GstVaapiBaseEncoder *base_encoder,
350 GstVaapiSurface *buffer_surface,
352 GstVaapiVideoBuffer *surface_buffer,
353 VABufferID *coded_buf,
357 EncoderStatus ret = ENCODER_NO_ERROR;
358 VAStatus va_status = VA_STATUS_SUCCESS;
359 VASurfaceStatus surface_status = 0;
360 VACodedBufferSegment *buf_list = NULL;
361 GstBuffer* ret_buffer = NULL;
362 gboolean has_coded_data = FALSE;
363 gboolean is_locked = FALSE;
364 GstVaapiBaseEncoderClass *base_class =
365 GST_VAAPI_BASE_ENCODER_GET_CLASS(base_encoder);
366 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
367 GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
369 ENCODER_ASSERT(display);
370 VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
371 VADisplay va_dpy = ENCODER_VA_DISPLAY(base_encoder);
373 ENCODER_ASSERT(coded_pics);
374 VAAPI_UNUSED_ARG(has_coded_data);
377 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
379 va_status = vaSyncSurface(va_dpy, surface_id);
380 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
381 ENCODER_QUERY_STATUS_ERR,
382 "vaSyncSurface failed.");
384 va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
385 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
386 ENCODER_QUERY_STATUS_ERR,
387 "vaQuerySurfaceStatus failed.");
388 if (VASurfaceSkipped & surface_status) {
389 ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT,
390 GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(surface_buffer)));
393 va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
394 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
395 ENCODER_QUERY_STATUS_ERR,
396 "vaMapBuffer failed.");
399 ENCODER_RELEASE_DISPLAY_LOCK(display);
401 while (buf_list != NULL) {
402 GstBuffer *new_data = NULL;
403 if (priv->frame_notify_flag && base_class->notify_frame) {
404 base_class->notify_frame(base_encoder,
409 if (base_class->copy_coded_frame) {
410 new_data = base_class->copy_coded_frame(
416 new_data = gst_vaapi_base_encoder_copy_buffer_default(
424 ret_buffer = new_data;
426 ret_buffer = gst_buffer_join(ret_buffer, new_data);
427 buf_list = (VACodedBufferSegment*)buf_list->next;
428 has_coded_data = TRUE;
432 GST_BUFFER_TIMESTAMP(ret_buffer) = GST_BUFFER_TIMESTAMP(surface_buffer);
433 GST_BUFFER_DURATION(ret_buffer) = GST_BUFFER_DURATION(surface_buffer);
435 GST_BUFFER_FLAG_SET(ret_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
437 GST_BUFFER_OFFSET_END(ret_buffer) =
438 GST_BUFFER_OFFSET_END(surface_buffer);
439 *coded_pics = g_list_append(*coded_pics, ret_buffer);
441 FPS_CALCULATION(vaapiencode);
446 { // if non-related, push back to available_code_buffers
447 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
448 vaUnmapBuffer(va_dpy, *coded_buf);
449 ENCODER_RELEASE_DISPLAY_LOCK(display);
450 push_available_coded_buffer(priv, coded_buf);
453 return ENCODER_NO_ERROR;
457 ENCODER_RELEASE_DISPLAY_LOCK(display);
462 gst_vaapi_base_encoder_encode_default(
463 GstVaapiEncoder* encoder,
468 GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
469 GstVaapiBaseEncoderClass *base_class =
470 GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
471 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
472 GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
473 GstVaapiContext *context = ENCODER_CONTEXT(encoder);
474 EncoderStatus ret = ENCODER_NO_ERROR;
475 gboolean is_key = FALSE;
476 VABufferID* coded_buf = NULL;
477 VAStatus va_status = VA_STATUS_SUCCESS;
478 VASurfaceID buffer_surface_id = VA_INVALID_SURFACE;
479 GstVaapiSurface *buffer_surface = NULL;
480 gboolean is_locked = FALSE;
482 VAContextID context_id;
484 ENCODER_ASSERT(display && context);
485 va_dpy = ENCODER_VA_DISPLAY(encoder);
486 context_id = ENCODER_VA_CONTEXT(encoder);
489 GstVaapiVideoBuffer *video_buffer = NULL;
491 ENCODER_CHECK_STATUS(raw_pic || base_class->prepare_next_input_buffer,
493 "Need a picture to encode");
495 /* load picture to surface */
496 if (GST_VAAPI_IS_VIDEO_BUFFER(raw_pic)) {
497 video_buffer = GST_VAAPI_VIDEO_BUFFER(raw_pic);
498 gst_buffer_ref(GST_BUFFER_CAST(video_buffer));
500 /* do something else */
503 priv->need_flush = TRUE;
507 if (base_class->prepare_next_input_buffer) {
508 GstVaapiVideoBuffer* tmp_buf = NULL;
509 ret = base_class->prepare_next_input_buffer(base_encoder,
513 priv->need_flush = FALSE;
515 gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
518 if (ret != ENCODER_NO_ERROR || !tmp_buf)
520 video_buffer = tmp_buf;
523 buffer_surface = gst_vaapi_video_buffer_get_surface(video_buffer);
524 buffer_surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
525 ENCODER_CHECK_STATUS(buffer_surface_id != VA_INVALID_SURFACE,
527 "surface id == VA_INVALID_SURFACE");
530 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
531 va_status = vaBeginPicture(va_dpy, context_id, buffer_surface_id);
532 //ENCODER_RELEASE_DISPLAY_LOCK(display);
534 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
536 "vaBeginPicture error");
538 /*get valid coded buffer*/
539 coded_buf = pop_available_coded_buffer(priv);
540 ENCODER_CHECK_STATUS(coded_buf,
542 "dequeue_available_coded_buffer error");
545 ret = base_class->render_frame(base_encoder,
550 /* prepare failed, push back */
551 if (ENCODER_NO_ERROR != ret) {
552 push_available_coded_buffer(priv, coded_buf);
554 ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
556 "base_prepare_encoding failed");
559 //ENCODER_ACQUIRE_DISPLAY_LOCK(display);
560 va_status = vaEndPicture(va_dpy, context_id);
561 ENCODER_RELEASE_DISPLAY_LOCK(display);
562 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
564 "vaEndPicture error");
566 /*query surface result*/
567 ret = base_query_encoding_status(base_encoder,
573 if (ENCODER_NO_ERROR != ret) {
579 if (base_class->prepare_next_input_buffer) {
581 gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
584 buffer_surface = NULL;
589 ENCODER_RELEASE_DISPLAY_LOCK(display);
590 if (ret > ENCODER_NO_ERROR) {
591 ret = ENCODER_NO_ERROR;
593 if (ret < 0 && base_class->encode_frame_failed) {
594 base_class->encode_frame_failed(base_encoder, video_buffer);
597 gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
604 pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv)
606 VABufferID *coded_buf = NULL;
609 g_mutex_lock(priv->code_buffer_lock);
611 ENCODER_CHECK_STATUS(priv->available_code_buffers,
613 "coded buffer not found");
614 while (g_queue_is_empty(priv->available_code_buffers)) {
615 g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
617 coded_buf = (VABufferID*)g_queue_pop_head (priv->available_code_buffers);
620 g_mutex_unlock(priv->code_buffer_lock);
621 VAAPI_UNUSED_ARG(ret);
626 push_available_coded_buffer(
627 GstVaapiBaseEncoderPrivate *priv,
631 g_mutex_lock(priv->code_buffer_lock);
632 g_queue_push_head(priv->available_code_buffers, buf);
633 g_cond_signal(priv->code_buffer_cond);
634 g_mutex_unlock(priv->code_buffer_lock);
640 base_put_raw_buffer_to_surface(GstVaapiBaseEncoder *base_encoder,
641 GstVaapiDisplay *display,
643 GstVaapiSurface *surface)
645 EncoderStatus ret = ENCODER_NO_ERROR;
646 GstVaapiImage *image;
647 GstVaapiImageFormat image_format;
648 guint8 *y_src = NULL, *u_src = NULL, *v_src = NULL;
649 guint8 *y_dst = NULL, *u_dst = NULL, *v_dst = NULL;
650 int y_size = 0, u_size = 0;
651 int row = 0, col = 0;
652 guint32 plane_count = 0;
653 guint32 image_width = 0, image_height = 0;
654 guint32 pitchy = 0, pitchu = 0, pitchv = 0;
655 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
657 ENCODER_ASSERT(display);
658 VAAPI_UNUSED_ARG(pitchv);
659 VAAPI_UNUSED_ARG(v_dst);
661 image = gst_vaapi_surface_derive_image(surface);
662 gst_vaapi_image_map(image);
664 image_format = gst_vaapi_image_get_format(image);
665 image_width = gst_vaapi_image_get_width(image);
666 image_height = gst_vaapi_image_get_height(image);
668 /* copy buffer to surface */
669 ENCODER_ASSERT(GST_BUFFER_SIZE(raw_pic) >= y_size + (y_size>>1));
671 y_size = ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder);
672 u_size = ((ENCODER_WIDTH(base_encoder)+1) >> 1) * ((ENCODER_HEIGHT(base_encoder)+1) >> 1);
674 y_src = GST_BUFFER_DATA(raw_pic);
675 u_src = y_src + y_size;
676 v_src = u_src + u_size;
678 plane_count = gst_vaapi_image_get_plane_count(image);
679 y_dst = gst_vaapi_image_get_plane(image, 0);
680 u_dst = gst_vaapi_image_get_plane(image, 1);
681 pitchy = gst_vaapi_image_get_pitch(image, 0);
682 pitchu = gst_vaapi_image_get_pitch(image, 1);
684 if (plane_count > 2) {
685 v_dst = gst_vaapi_image_get_plane(image, 2);
686 pitchv = gst_vaapi_image_get_pitch(image, 2);
689 /* copy from avcenc.c*/
691 for (row = 0; row < image_height; row++) {
692 memcpy(y_dst, y_src, image_width);
694 y_src += ENCODER_WIDTH(base_encoder);
697 if (GST_VAAPI_IMAGE_NV12 == image_format) { /* UV plane */
698 if (GST_VAAPI_IMAGE_I420 == priv->format) {
699 for (row = 0; row < image_height / 2; row++) {
700 for (col = 0; col < image_width / 2; col++) {
701 u_dst[col * 2] = u_src[col];
702 u_dst[col * 2 + 1] = v_src[col];
706 u_src += (ENCODER_WIDTH(base_encoder)>>1);
707 v_src += (ENCODER_WIDTH(base_encoder)>>1);
709 } else if (GST_VAAPI_IMAGE_NV12 == priv->format){
710 for (row = 0; row < image_height / 2; row++) {
711 memcpy(u_dst, u_src, image_width);
712 u_src += ENCODER_WIDTH(base_encoder);
719 /* FIXME: fix this later */
724 g_object_unref(image);
731 gst_vaapi_base_encoder_flush_default(
732 GstVaapiEncoder* encoder,
736 GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
737 EncoderStatus ret = ENCODER_NO_ERROR;
738 GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
740 priv->frame_count = 0;
741 priv->need_flush = TRUE;
742 /*do we need destroy priv->seq_parameter? */
750 gst_vaapi_base_encoder_finalize(GObject *object)
752 /*free private buffers*/
753 GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
754 GstVaapiBaseEncoderPrivate *priv =
755 GST_VAAPI_BASE_ENCODER_GET_PRIVATE(object);
757 if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
758 gst_vaapi_encoder_uninitialize(encoder);
761 g_mutex_free(priv->code_buffer_lock);
762 g_cond_free(priv->code_buffer_cond);
763 if (priv->available_code_buffers) {
764 g_queue_free(priv->available_code_buffers);
765 priv->available_code_buffers = NULL;
768 G_OBJECT_CLASS(gst_vaapi_base_encoder_parent_class)->finalize(object);
772 gst_vaapi_base_encoder_init(GstVaapiBaseEncoder *encoder)
774 GstVaapiBaseEncoderPrivate *priv =
775 GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
776 ENCODER_ASSERT(priv);
777 encoder->priv = priv;
779 /* init private values*/
781 priv->profile= VA_INVALID_PROFILE;
782 priv->frame_count = 0;
783 priv->frame_notify_flag = FALSE;
785 priv->coded_bufs = NULL;
786 priv->coded_buf_num = DEFAULT_VA_CODEDBUF_NUM;
787 priv->code_buffer_lock = g_mutex_new();
788 priv->code_buffer_cond = g_cond_new();
789 priv->available_code_buffers = g_queue_new();
791 priv->need_flush = FALSE;
795 gst_vaapi_base_encoder_class_init(GstVaapiBaseEncoderClass *klass)
797 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
798 GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
799 g_type_class_add_private(klass, sizeof(GstVaapiBaseEncoderPrivate));
801 GST_DEBUG_CATEGORY_INIT (gst_vaapi_base_encoder_debug,
802 "gst_vaapi_base_encoder",
804 "gst_vaapi_base_encoder element");
806 object_class->finalize = gst_vaapi_base_encoder_finalize;
808 encoder_class->open = gst_vaapi_base_encoder_open_default;
809 encoder_class->close = gst_vaapi_base_encoder_close_default;
810 encoder_class->encode = gst_vaapi_base_encoder_encode_default;
811 encoder_class->flush = gst_vaapi_base_encoder_flush_default;
812 encoder_class->get_codec_data = NULL;
814 /* user defined functions*/
815 klass->validate_attributes = NULL;
816 klass->pre_alloc_resource = NULL;
817 klass->release_resource = NULL;
818 klass->prepare_next_input_buffer = NULL;
819 klass->render_frame = NULL;
820 klass->notify_frame = NULL;
821 klass->copy_coded_frame = NULL;
822 klass->encode_frame_failed = NULL;
825 object_class->set_property = gst_vaapi_base_encoder_set_property;
826 object_class->get_property = gst_vaapi_base_encoder_get_property;