1 #include "gstvaapiencoder.h"
5 #include "gst/vaapi/gstvaapidisplay_x11.h"
7 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_encoder_debug);
8 #define GST_CAT_DEFAULT gst_vaapi_encoder_debug
11 G_DEFINE_TYPE(GstVaapiEncoder, gst_vaapi_encoder, G_TYPE_OBJECT);
13 static void gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass);
14 static voidgst_vaapi_encoder_init(GstVaapiEncoder *encoder);
15 static void gst_vaapi_encoder_finalize(GObject *object);
18 gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass)
20 GObjectClass * const object_class = G_OBJECT_CLASS(kclass);
21 g_type_class_add_private(kclass, sizeof(GstVaapiEncoderPrivate));
24 GST_DEBUG_CATEGORY_INIT (gst_vaapi_encoder_debug, "gst_va_encoder", 0,
25 "gst_va_encoder element");
27 object_class->finalize = gst_vaapi_encoder_finalize;
28 kclass->initialize = NULL;
29 kclass->uninitialize = NULL;
32 kclass->encode = NULL;
34 kclass->get_codec_data = NULL;
38 gst_vaapi_encoder_init(GstVaapiEncoder *encoder)
40 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
41 ENCODER_ASSERT(encoder_prv);
42 encoder_prv->display = NULL;
43 encoder_prv->context = NULL;
44 encoder_prv->state = VAAPI_ENC_NULL;
48 encoder->frame_rate = 0;
52 gst_vaapi_encoder_finalize(GObject *object)
54 GstVaapiEncoder* encoder = GST_VAAPI_ENCODER(object);
55 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(object);
56 if (VAAPI_ENC_NULL != encoder_prv->state) {
57 gst_vaapi_encoder_uninitialize(encoder);
60 if (encoder_prv->context) {
61 g_object_unref(encoder_prv->context);
62 encoder_prv->context = NULL;
65 if (encoder_prv->display) {
66 g_object_unref(encoder_prv->display);
67 encoder_prv->display = NULL;
70 G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object);
75 gst_vaapi_encoder_set_display(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
77 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
78 if (display == encoder_prv->display) {
82 if (VAAPI_ENC_INIT < encoder_prv->state) {
85 if (encoder_prv->display) {
86 g_object_unref(encoder_prv->display);
87 encoder_prv->display = NULL;
89 encoder_prv->display = g_object_ref(display);
94 gst_vaapi_encoder_get_display(GstVaapiEncoder* encoder)
96 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
97 return (encoder_prv->display ? g_object_ref(encoder_prv->display) : NULL);
101 gst_vaapi_encoder_get_context(GstVaapiEncoder* encoder)
103 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
104 return (encoder_prv->context ? g_object_ref(encoder_prv->context) : NULL);
109 gst_vaapi_encoder_get_state(GstVaapiEncoder* encoder)
111 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
112 return encoder_prv->state;
117 gst_vaapi_encoder_initialize(GstVaapiEncoder* encoder)
119 EncoderStatus ret = ENCODER_NO_ERROR;
120 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
121 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
124 if (VAAPI_ENC_INIT == encoder_prv->state) {
125 return ENCODER_NO_ERROR;
127 ENCODER_ASSERT(VAAPI_ENC_NULL == encoder_prv->state);
128 if (VAAPI_ENC_NULL != encoder_prv->state) {
129 return ENCODER_STATE_ERR;
133 if (!encoder_prv->display) {
134 encoder_prv->display = gst_vaapi_display_x11_new(NULL);
135 ENCODER_CHECK_STATUS(encoder_prv->display, ENCODER_DISPLAY_ERR, "gst_vaapi_display_x11_new failed.\n");
138 if (encoder_class->initialize) {
139 ret = encoder_class->initialize(encoder, encoder_prv->display);
140 ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == ret, ret, "encoder <initialize> failed.\n");
142 encoder_prv->state = VAAPI_ENC_INIT;
149 gst_vaapi_encoder_open(GstVaapiEncoder* encoder, void* private_data)
151 EncoderStatus ret = ENCODER_NO_ERROR;
152 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
153 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
156 if (VAAPI_ENC_OPENED == encoder_prv->state) {
157 return ENCODER_NO_ERROR;
159 ENCODER_ASSERT(VAAPI_ENC_INIT == encoder_prv->state);
160 if (VAAPI_ENC_INIT != encoder_prv->state) {
161 return ENCODER_STATE_ERR;
163 ENCODER_ASSERT(encoder_prv->context);
165 ENCODER_CHECK_STATUS(encoder_class->open, ENCODER_FUNC_PTR_ERR, "encoder <open> function pointer empty.\n");
166 ret = encoder_class->open(encoder, encoder_prv->display, private_data, &encoder_prv->context);
167 ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <open> failed.\n");
168 ENCODER_CHECK_STATUS(encoder_prv->context, ENCODER_CONTEXT_ERR, "encoder <open> context failed.\n");
170 encoder_prv->state = VAAPI_ENC_OPENED;
177 gst_vaapi_encoder_encode(GstVaapiEncoder* encoder, GstBuffer *raw_pic, GList **coded_pics)
179 EncoderStatus ret = ENCODER_NO_ERROR;
180 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
181 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
183 ENCODER_CHECK_STATUS(encoder_prv->state >= VAAPI_ENC_OPENED, ENCODER_STATE_ERR, "encoder was not opened before <encode>.\n");
184 ENCODER_CHECK_STATUS(encoder_class->encode, ENCODER_FUNC_PTR_ERR, "encoder <encode> function pointer empty.\n");
185 ret = encoder_class->encode(encoder, encoder_prv->display, encoder_prv->context, raw_pic, coded_pics);
186 ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <encode> failed.\n");
187 if (encoder_prv->state < VAAPI_ENC_ENCODING) {
188 encoder_prv->state = VAAPI_ENC_ENCODING;
194 EncoderStatus gst_vaapi_encoder_get_codec_data(GstVaapiEncoder* encoder, GstBuffer **codec_data)
196 EncoderStatus ret = ENCODER_NO_ERROR;
197 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
198 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
200 ENCODER_CHECK_STATUS(encoder_prv->state >= VAAPI_ENC_OPENED, ENCODER_STATE_ERR, "encoder was not opened before <get_codec_data>.\n");
201 if (!encoder_class->get_codec_data) {
203 ENCODER_LOG_INFO("There's no codec_data");
206 ret = encoder_class->get_codec_data(encoder, codec_data);
213 gst_vaapi_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics)
215 EncoderStatus ret = ENCODER_NO_ERROR;
216 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
217 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
219 if (encoder_prv->state < VAAPI_ENC_OPENED) {
220 return ENCODER_STATE_ERR;
222 ENCODER_CHECK_STATUS(encoder_class->flush, ENCODER_FUNC_PTR_ERR, "encoder <flush> function pointer empty.\n");
223 ret = encoder_class->flush(encoder, encoder_prv->display, encoder_prv->context, coded_pics);
224 ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <flush> failed.\n");
225 if (encoder_prv->state > VAAPI_ENC_OPENED) {
226 encoder_prv->state = VAAPI_ENC_OPENED;
233 gst_vaapi_encoder_close(GstVaapiEncoder* encoder)
235 EncoderStatus ret = ENCODER_NO_ERROR;
236 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
237 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
239 if (VAAPI_ENC_INIT >= encoder_prv->state) {
240 return ENCODER_NO_ERROR;
242 ENCODER_CHECK_STATUS(encoder_class->close, ENCODER_FUNC_PTR_ERR, "encoder <close> function pointers empty.\n");
243 ret = encoder_class->close(encoder, encoder_prv->display, encoder_prv->context);
244 ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <close> failed.\n");
246 if (encoder_prv->context) {
247 g_object_unref(encoder_prv->context);
248 encoder_prv->context = NULL;
251 encoder_prv->state = VAAPI_ENC_INIT;
256 gst_vaapi_encoder_uninitialize(GstVaapiEncoder* encoder)
258 EncoderStatus ret = ENCODER_NO_ERROR;
259 GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
260 GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
262 if (VAAPI_ENC_NULL == encoder_prv->state) {
263 return ENCODER_NO_ERROR;
266 if (VAAPI_ENC_INIT < encoder_prv->state) {
267 ret = gst_vaapi_encoder_close(encoder);
269 ENCODER_ASSERT(VAAPI_ENC_INIT == encoder_prv->state);
270 if (encoder_class->uninitialize) {
271 ret = encoder_class->uninitialize(encoder, encoder_prv->display);
272 ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ret, "encoder <uninitialize> failed.\n");
275 if (encoder_prv->display) {
276 g_object_unref(encoder_prv->display);
277 encoder_prv->display = NULL;
279 encoder_prv->state = VAAPI_ENC_NULL;
284 char *vaapi_encoder_dump_bytes(const guint8 *buf, guint32 num)
286 static char tmp[1024];
288 memset(tmp, 0, sizeof(tmp));
291 for (i = 0; i < num; i++) {
292 snprintf(p, 1024-(p-tmp), "%02x", (guint8)buf[i]);