2 * gstvaapiencoder_vp8.c - VP8 encoder
4 * Copyright (C) 2015 Intel Corporation
5 * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
24 #include <gst/base/gstbitwriter.h>
25 #include <gst/codecparsers/gstvp8parser.h>
26 #include "gstvaapicompat.h"
27 #include "gstvaapiencoder_priv.h"
28 #include "gstvaapiencoder_vp8.h"
29 #include "gstvaapicodedbufferproxy_priv.h"
30 #include "gstvaapisurface.h"
33 #include "gstvaapidebug.h"
35 /* Define default rate control mode ("constant-qp") */
36 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
38 /* Supported set of VA rate controls, within this implementation */
39 #define SUPPORTED_RATECONTROLS \
40 (GST_VAAPI_RATECONTROL_MASK (CQP) | \
41 GST_VAAPI_RATECONTROL_MASK (CBR) | \
42 GST_VAAPI_RATECONTROL_MASK (VBR))
44 /* Supported set of tuning options, within this implementation */
45 #define SUPPORTED_TUNE_OPTIONS \
46 (GST_VAAPI_ENCODER_TUNE_MASK (NONE))
48 /* Supported set of VA packed headers, within this implementation */
49 #define SUPPORTED_PACKED_HEADERS \
50 (VA_ENC_PACKED_HEADER_NONE)
52 #define DEFAULT_LOOP_FILTER_LEVEL 0
53 #define DEFAULT_SHARPNESS_LEVEL 0
54 #define DEFAULT_YAC_QI 40
56 /* ------------------------------------------------------------------------- */
57 /* --- VP8 Encoder --- */
58 /* ------------------------------------------------------------------------- */
60 struct _GstVaapiEncoderVP8
62 GstVaapiEncoder parent_instance;
63 GstVaapiProfile profile;
64 guint loop_filter_level;
65 guint sharpness_level;
69 GstVaapiSurfaceProxy *last_ref;
70 GstVaapiSurfaceProxy *golden_ref;
71 GstVaapiSurfaceProxy *alt_ref;
74 /* Derives the profile that suits best to the configuration */
75 static GstVaapiEncoderStatus
76 ensure_profile (GstVaapiEncoderVP8 * encoder)
78 /* Always start from "simple" profile for maximum compatibility */
79 encoder->profile = GST_VAAPI_PROFILE_VP8;
81 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
84 /* Derives the profile supported by the underlying hardware */
86 ensure_hw_profile (GstVaapiEncoderVP8 * encoder)
88 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
89 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
90 GstVaapiProfile profile, profiles[2];
91 guint i, num_profiles = 0;
93 profiles[num_profiles++] = encoder->profile;
95 profile = GST_VAAPI_PROFILE_UNKNOWN;
96 for (i = 0; i < num_profiles; i++) {
97 if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
98 profile = profiles[i];
102 if (profile == GST_VAAPI_PROFILE_UNKNOWN)
103 goto error_unsupported_profile;
105 GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
109 error_unsupported_profile:
111 GST_ERROR ("unsupported HW profile %s",
112 gst_vaapi_profile_get_va_name (encoder->profile));
118 ensure_bitrate (GstVaapiEncoderVP8 * encoder)
120 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
122 /* Default compression: 64 bits per macroblock */
123 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
124 case GST_VAAPI_RATECONTROL_CBR:
125 case GST_VAAPI_RATECONTROL_VBR:
126 if (!base_encoder->bitrate) {
127 base_encoder->bitrate =
128 gst_util_uint64_scale (GST_VAAPI_ENCODER_WIDTH (encoder) *
129 GST_VAAPI_ENCODER_HEIGHT (encoder),
130 GST_VAAPI_ENCODER_FPS_N (encoder),
131 GST_VAAPI_ENCODER_FPS_D (encoder)) / (4 * 1000);
135 base_encoder->bitrate = 0;
142 static GstVaapiEncoderStatus
143 set_context_info (GstVaapiEncoder * base_encoder)
145 GstVaapiEncoderVP8 *encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
146 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
148 /* Maximum sizes for common headers (in bytes) */
151 MAX_FRAME_TAG_SIZE = 10,
152 MAX_UPDATE_SEGMENTATION_SIZE = 13,
153 MAX_MB_LF_ADJUSTMENTS_SIZE = 9,
154 MAX_QUANT_INDICES_SIZE = 5,
155 MAX_TOKEN_PROB_UPDATE_SIZE = 1188,
156 MAX_MV_PROBE_UPDATE_SIZE = 38,
157 MAX_REST_OF_FRAME_HDR_SIZE = 15
160 if (!ensure_hw_profile (encoder))
161 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
163 base_encoder->num_ref_frames = 3;
165 /* Only YUV 4:2:0 formats are supported for now. */
166 /* Assumig 4 times compression ratio */
167 base_encoder->codedbuf_size = GST_ROUND_UP_16 (vip->width) *
168 GST_ROUND_UP_16 (vip->height) * 12 / 4;
170 base_encoder->codedbuf_size +=
171 MAX_FRAME_TAG_SIZE + MAX_UPDATE_SEGMENTATION_SIZE +
172 MAX_MB_LF_ADJUSTMENTS_SIZE + MAX_QUANT_INDICES_SIZE +
173 MAX_TOKEN_PROB_UPDATE_SIZE + MAX_MV_PROBE_UPDATE_SIZE +
174 MAX_REST_OF_FRAME_HDR_SIZE;
176 base_encoder->context_info.profile = base_encoder->profile;
177 base_encoder->context_info.entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
179 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
183 clear_ref (GstVaapiEncoderVP8 * encoder, GstVaapiSurfaceProxy ** ref)
186 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), *ref);
192 clear_references (GstVaapiEncoderVP8 * encoder)
194 clear_ref (encoder, &encoder->last_ref);
195 clear_ref (encoder, &encoder->golden_ref);
196 clear_ref (encoder, &encoder->alt_ref);
200 push_reference (GstVaapiEncoderVP8 * encoder, GstVaapiSurfaceProxy * ref)
202 if (encoder->last_ref == NULL) {
203 encoder->golden_ref = gst_vaapi_surface_proxy_ref (ref);
204 encoder->alt_ref = gst_vaapi_surface_proxy_ref (ref);
206 clear_ref (encoder, &encoder->alt_ref);
207 encoder->alt_ref = encoder->golden_ref;
208 encoder->golden_ref = encoder->last_ref;
210 encoder->last_ref = ref;
214 fill_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncSequence * sequence)
216 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
217 VAEncSequenceParameterBufferVP8 *const seq_param = sequence->param;
219 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferVP8));
221 seq_param->frame_width = GST_VAAPI_ENCODER_WIDTH (encoder);
222 seq_param->frame_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
224 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
225 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR)
226 seq_param->bits_per_second = base_encoder->bitrate * 1000;
228 seq_param->intra_period = base_encoder->keyframe_period;
234 ensure_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture)
236 GstVaapiEncSequence *sequence;
240 if (picture->type != GST_VAAPI_PICTURE_TYPE_I)
243 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (VP8, encoder);
247 if (!fill_sequence (encoder, sequence))
250 gst_vaapi_enc_picture_set_sequence (picture, sequence);
251 gst_vaapi_codec_object_replace (&sequence, NULL);
257 gst_vaapi_codec_object_replace (&sequence, NULL);
263 ensure_control_rate_params (GstVaapiEncoderVP8 * encoder)
265 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
267 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP)
270 /* RateControl params */
271 GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->yac_qi;
272 GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = 1;
276 GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) {
277 .buffer_size = base_encoder->bitrate * 1000 * 2,
278 .initial_buffer_fullness = base_encoder->bitrate * 1000,
286 ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture)
288 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
290 if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture))
293 if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture))
300 fill_picture (GstVaapiEncoderVP8 * encoder,
301 GstVaapiEncPicture * picture,
302 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
304 VAEncPictureParameterBufferVP8 *const pic_param = picture->param;
307 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferVP8));
309 pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
310 pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
312 if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
313 pic_param->pic_flags.bits.frame_type = 1;
314 pic_param->ref_arf_frame =
315 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->alt_ref);
316 pic_param->ref_gf_frame =
317 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->golden_ref);
318 pic_param->ref_last_frame =
319 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->last_ref);
320 pic_param->pic_flags.bits.refresh_last = 1;
321 pic_param->pic_flags.bits.refresh_golden_frame = 0;
322 pic_param->pic_flags.bits.copy_buffer_to_golden = 1;
323 pic_param->pic_flags.bits.refresh_alternate_frame = 0;
324 pic_param->pic_flags.bits.copy_buffer_to_alternate = 2;
326 pic_param->ref_last_frame = VA_INVALID_SURFACE;
327 pic_param->ref_gf_frame = VA_INVALID_SURFACE;
328 pic_param->ref_arf_frame = VA_INVALID_SURFACE;
329 pic_param->pic_flags.bits.refresh_last = 1;
330 pic_param->pic_flags.bits.refresh_golden_frame = 1;
331 pic_param->pic_flags.bits.refresh_alternate_frame = 1;
334 pic_param->pic_flags.bits.show_frame = 1;
336 if (encoder->loop_filter_level) {
337 pic_param->pic_flags.bits.version = 1;
338 pic_param->pic_flags.bits.loop_filter_type = 1; /* Enable simple loop filter */
339 /* Disabled segmentation, so what matters is only loop_filter_level[0] */
340 for (i = 0; i < 4; i++)
341 pic_param->loop_filter_level[i] = encoder->loop_filter_level;
344 pic_param->sharpness_level = encoder->sharpness_level;
347 pic_param->clamp_qindex_low = 0;
348 pic_param->clamp_qindex_high = 127;
354 ensure_picture (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture,
355 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
357 GstVaapiCodedBuffer *const codedbuf =
358 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
360 if (!fill_picture (encoder, picture, codedbuf, surface))
367 fill_quantization_table (GstVaapiEncoderVP8 * encoder,
368 GstVaapiEncPicture * picture, GstVaapiEncQMatrix * q_matrix)
370 VAQMatrixBufferVP8 *const qmatrix_param = q_matrix->param;
373 memset (qmatrix_param, 0, sizeof (VAQMatrixBufferVP8));
375 /* DefaultYacQantVal = 8 for I frame, which is ac_qlookup[4] and
376 * DefaultYacQantVAl = 44 for P frame, which is ac_qllookup[40] */
377 for (i = 0; i < 4; i++) {
378 if (encoder->yac_qi == DEFAULT_YAC_QI) {
379 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
380 qmatrix_param->quantization_index[i] = 4;
382 qmatrix_param->quantization_index[i] = 40;
384 qmatrix_param->quantization_index[i] = encoder->yac_qi;
391 ensure_quantization_table (GstVaapiEncoderVP8 * encoder,
392 GstVaapiEncPicture * picture)
396 picture->q_matrix = GST_VAAPI_ENC_Q_MATRIX_NEW (VP8, encoder);
397 if (!picture->q_matrix) {
398 GST_ERROR ("failed to allocate quantiser table");
399 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
402 if (!fill_quantization_table (encoder, picture, picture->q_matrix))
408 static GstVaapiEncoderStatus
409 gst_vaapi_encoder_vp8_encode (GstVaapiEncoder * base_encoder,
410 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
412 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
413 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
414 GstVaapiSurfaceProxy *reconstruct = NULL;
416 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
418 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
420 if (!ensure_sequence (encoder, picture))
422 if (!ensure_misc_params (encoder, picture))
424 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
426 if (!ensure_quantization_table (encoder, picture))
428 if (!gst_vaapi_enc_picture_encode (picture))
431 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
432 clear_references (encoder);
433 push_reference (encoder, reconstruct);
436 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
442 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
448 static GstVaapiEncoderStatus
449 gst_vaapi_encoder_vp8_flush (GstVaapiEncoder * base_encoder)
451 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
453 encoder->frame_num = 0;
454 clear_references (encoder);
456 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
459 static GstVaapiEncoderStatus
460 gst_vaapi_encoder_vp8_reordering (GstVaapiEncoder * base_encoder,
461 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
463 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
464 GstVaapiEncPicture *picture = NULL;
465 GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
468 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
470 picture = GST_VAAPI_ENC_PICTURE_NEW (VP8, encoder, frame);
472 GST_WARNING ("create VP8 picture failed, frame timestamp:%"
473 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
474 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
477 if (encoder->frame_num >= base_encoder->keyframe_period) {
478 encoder->frame_num = 0;
479 clear_references (encoder);
481 if (encoder->frame_num == 0) {
482 picture->type = GST_VAAPI_PICTURE_TYPE_I;
483 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
485 picture->type = GST_VAAPI_PICTURE_TYPE_P;
488 encoder->frame_num++;
493 static GstVaapiEncoderStatus
494 gst_vaapi_encoder_vp8_reconfigure (GstVaapiEncoder * base_encoder)
496 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (base_encoder);
497 GstVaapiEncoderStatus status;
499 status = ensure_profile (encoder);
500 if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
503 if (!ensure_bitrate (encoder))
506 ensure_control_rate_params (encoder);
507 return set_context_info (base_encoder);
512 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
516 struct _GstVaapiEncoderVP8Class
518 GstVaapiEncoderClass parent_class;
521 G_DEFINE_TYPE (GstVaapiEncoderVP8, gst_vaapi_encoder_vp8,
522 GST_TYPE_VAAPI_ENCODER);
525 gst_vaapi_encoder_vp8_init (GstVaapiEncoderVP8 * encoder)
527 encoder->frame_num = 0;
528 encoder->last_ref = NULL;
529 encoder->golden_ref = NULL;
530 encoder->alt_ref = NULL;
534 gst_vaapi_encoder_vp8_finalize (GObject * object)
536 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object);
537 clear_references (encoder);
538 G_OBJECT_CLASS (gst_vaapi_encoder_vp8_parent_class)->finalize (object);
542 * @ENCODER_VP8_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
543 * @ENCODER_VP8_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
544 * @ENCODER_VP8_PROP_LOOP_FILTER_LEVEL: Loop Filter Level(uint).
545 * @ENCODER_VP8_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint).
546 * @ENCODER_VP8_PROP_YAC_Q_INDEX: Quantization table index for luma AC(uint).
548 * The set of VP8 encoder specific configurable properties.
552 ENCODER_VP8_PROP_RATECONTROL = 1,
553 ENCODER_VP8_PROP_TUNE,
554 ENCODER_VP8_PROP_LOOP_FILTER_LEVEL,
555 ENCODER_VP8_PROP_SHARPNESS_LEVEL,
556 ENCODER_VP8_PROP_YAC_Q_INDEX,
557 ENCODER_VP8_N_PROPERTIES
560 static GParamSpec *properties[ENCODER_VP8_N_PROPERTIES];
563 gst_vaapi_encoder_vp8_set_property (GObject * object, guint prop_id,
564 const GValue * value, GParamSpec * pspec)
566 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
567 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object);
569 if (base_encoder->num_codedbuf_queued > 0) {
570 GST_ERROR_OBJECT (object,
571 "failed to set any property after encoding started");
576 case ENCODER_VP8_PROP_RATECONTROL:
577 gst_vaapi_encoder_set_rate_control (base_encoder,
578 g_value_get_enum (value));
580 case ENCODER_VP8_PROP_TUNE:
581 gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
583 case ENCODER_VP8_PROP_LOOP_FILTER_LEVEL:
584 encoder->loop_filter_level = g_value_get_uint (value);
586 case ENCODER_VP8_PROP_SHARPNESS_LEVEL:
587 encoder->sharpness_level = g_value_get_uint (value);
589 case ENCODER_VP8_PROP_YAC_Q_INDEX:
590 encoder->yac_qi = g_value_get_uint (value);
593 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
598 gst_vaapi_encoder_vp8_get_property (GObject * object, guint prop_id,
599 GValue * value, GParamSpec * pspec)
601 GstVaapiEncoderVP8 *const encoder = GST_VAAPI_ENCODER_VP8 (object);
602 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
605 case ENCODER_VP8_PROP_RATECONTROL:
606 g_value_set_enum (value, base_encoder->rate_control);
608 case ENCODER_VP8_PROP_TUNE:
609 g_value_set_enum (value, base_encoder->tune);
611 case ENCODER_VP8_PROP_LOOP_FILTER_LEVEL:
612 g_value_set_uint (value, encoder->loop_filter_level);
614 case ENCODER_VP8_PROP_SHARPNESS_LEVEL:
615 g_value_set_uint (value, encoder->sharpness_level);
617 case ENCODER_VP8_PROP_YAC_Q_INDEX:
618 g_value_set_uint (value, encoder->yac_qi);
621 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
625 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (VP8);
628 gst_vaapi_encoder_vp8_class_init (GstVaapiEncoderVP8Class * klass)
630 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
631 GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
633 encoder_class->class_data = &g_class_data;
634 encoder_class->reconfigure = gst_vaapi_encoder_vp8_reconfigure;
635 encoder_class->reordering = gst_vaapi_encoder_vp8_reordering;
636 encoder_class->encode = gst_vaapi_encoder_vp8_encode;
637 encoder_class->flush = gst_vaapi_encoder_vp8_flush;
639 object_class->set_property = gst_vaapi_encoder_vp8_set_property;
640 object_class->get_property = gst_vaapi_encoder_vp8_get_property;
641 object_class->finalize = gst_vaapi_encoder_vp8_finalize;
643 properties[ENCODER_VP8_PROP_RATECONTROL] =
644 g_param_spec_enum ("rate-control",
645 "Rate Control", "Rate control mode",
646 g_class_data.rate_control_get_type (),
647 g_class_data.default_rate_control,
648 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
649 GST_VAAPI_PARAM_ENCODER_EXPOSURE);
651 properties[ENCODER_VP8_PROP_TUNE] =
652 g_param_spec_enum ("tune", "Encoder Tuning", "Encoder tuning option",
653 g_class_data.encoder_tune_get_type (),
654 g_class_data.default_encoder_tune,
655 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
656 GST_VAAPI_PARAM_ENCODER_EXPOSURE);
658 properties[ENCODER_VP8_PROP_LOOP_FILTER_LEVEL] =
659 g_param_spec_uint ("loop-filter-level", "Loop Filter Level",
660 "Controls the deblocking filter strength", 0, 63,
661 DEFAULT_LOOP_FILTER_LEVEL,
662 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
663 GST_VAAPI_PARAM_ENCODER_EXPOSURE);
665 properties[ENCODER_VP8_PROP_SHARPNESS_LEVEL] =
666 g_param_spec_uint ("sharpness-level", "Sharpness Level",
667 "Controls the deblocking filter sensitivity", 0, 7,
668 DEFAULT_SHARPNESS_LEVEL,
669 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
670 GST_VAAPI_PARAM_ENCODER_EXPOSURE);
672 properties[ENCODER_VP8_PROP_YAC_Q_INDEX] =
673 g_param_spec_uint ("yac-qi",
674 "Luma AC Quant Table index",
675 "Quantization Table index for Luma AC Coefficients,"
676 " (in default case, yac_qi=4 for key frames and yac_qi=40"
678 0, 127, DEFAULT_YAC_QI,
679 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
680 GST_VAAPI_PARAM_ENCODER_EXPOSURE);
682 g_object_class_install_properties (object_class, ENCODER_VP8_N_PROPERTIES,
685 gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type (), 0);
686 gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type (), 0);
690 * gst_vaapi_encoder_vp8_new:
691 * @display: a #GstVaapiDisplay
693 * Creates a new #GstVaapiEncoder for VP8 encoding.
695 * Return value: the newly allocated #GstVaapiEncoder object
698 gst_vaapi_encoder_vp8_new (GstVaapiDisplay * display)
700 return g_object_new (GST_TYPE_VAAPI_ENCODER_VP8, "display", display, NULL);