1 /* GStreamer Intel MSDK plugin
2 * Copyright (c) 2016, Oblong Industries, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * SECTION: element-msdkh264enc
35 * @short_description: Intel MSDK H264 encoder
37 * H264 video encoder based on Intel MFX
39 * ## Example launch line
41 * gst-launch-1.0 videotestsrc num-buffers=90 ! msdkh264enc ! h264parse ! filesink location=output.h264
52 #include "gstmsdkh264enc.h"
54 #include <gst/base/base.h>
55 #include <gst/pbutils/pbutils.h>
58 GST_DEBUG_CATEGORY_EXTERN (gst_msdkh264enc_debug);
59 #define GST_CAT_DEFAULT gst_msdkh264enc_debug
63 PROP_CABAC = GST_MSDKENC_PROP_MAX,
64 #ifndef GST_REMOVE_DEPRECATED
68 PROP_RC_LA_DOWNSAMPLING,
76 PROP_INTRA_REFRESH_TYPE,
77 PROP_INTRA_REFRESH_CYCLE_SIZE,
78 PROP_INTRA_REFRESH_QP_DELTA,
79 PROP_INTRA_REFRESH_CYCLE_DIST,
85 GST_MSDK_FLAG_LOW_POWER = 1 << 0,
86 GST_MSDK_FLAG_TUNE_MODE = 1 << 1,
89 #define PROP_CABAC_DEFAULT TRUE
90 #define PROP_LOWPOWER_DEFAULT FALSE
91 #define PROP_FRAME_PACKING_DEFAULT -1
92 #define PROP_RC_LA_DOWNSAMPLING_DEFAULT MFX_LOOKAHEAD_DS_UNKNOWN
93 #define PROP_TRELLIS_DEFAULT _MFX_TRELLIS_NONE
94 #define PROP_MAX_SLICE_SIZE_DEFAULT 0
95 #define PROP_B_PYRAMID_DEFAULT FALSE
96 #define PROP_TUNE_MODE_DEFAULT MFX_CODINGOPTION_UNKNOWN
97 #define PROP_P_PYRAMID_DEFAULT FALSE
98 #define PROP_MIN_QP_DEFAULT 0
99 #define PROP_MAX_QP_DEFAULT 0
100 #define PROP_INTRA_REFRESH_TYPE_DEFAULT MFX_REFRESH_NO
101 #define PROP_INTRA_REFRESH_CYCLE_SIZE_DEFAULT 0
102 #define PROP_INTRA_REFRESH_QP_DELTA_DEFAULT 0
103 #define PROP_INTRA_REFRESH_CYCLE_DIST_DEFAULT 0
104 #define PROP_DBLK_IDC_DEFAULT 0
106 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
109 GST_STATIC_CAPS ("video/x-h264, "
110 "framerate = (fraction) [0/1, MAX], "
111 "width = (int) [ 1, MAX ], height = (int) [ 1, MAX ], "
112 "stream-format = (string) byte-stream , alignment = (string) au , "
113 "profile = (string) { high, main, baseline, constrained-baseline }")
117 gst_msdkh264enc_frame_packing_get_type (void)
119 static GType format_type = 0;
120 static const GEnumValue format_types[] = {
121 {GST_VIDEO_MULTIVIEW_FRAME_PACKING_NONE, "None (default)", "none"},
122 {GST_VIDEO_MULTIVIEW_FRAME_PACKING_SIDE_BY_SIDE, "Side by Side",
124 {GST_VIDEO_MULTIVIEW_FRAME_PACKING_TOP_BOTTOM, "Top Bottom", "top-bottom"},
130 g_enum_register_static ("GstMsdkH264EncFramePacking", format_types);
136 #define gst_msdkh264enc_parent_class parent_class
137 G_DEFINE_TYPE (GstMsdkH264Enc, gst_msdkh264enc, GST_TYPE_MSDKENC);
140 gst_msdkh264enc_insert_sei (GstMsdkH264Enc * thiz, GstVideoCodecFrame * frame,
143 GstBuffer *new_buffer;
146 thiz->parser = gst_h264_nal_parser_new ();
148 new_buffer = gst_h264_parser_insert_sei (thiz->parser,
149 frame->output_buffer, sei_mem);
152 GST_WARNING_OBJECT (thiz, "Cannot insert SEI nal into AU buffer");
156 gst_buffer_unref (frame->output_buffer);
157 frame->output_buffer = new_buffer;
161 gst_msdkh264enc_add_cc (GstMsdkH264Enc * thiz, GstVideoCodecFrame * frame)
163 GstVideoCaptionMeta *cc_meta;
164 gpointer iter = NULL;
165 GstBuffer *in_buf = frame->input_buffer;
166 GstMemory *mem = NULL;
168 if (thiz->cc_sei_array)
169 g_array_set_size (thiz->cc_sei_array, 0);
172 (GstVideoCaptionMeta *) gst_buffer_iterate_meta_filtered (in_buf,
173 &iter, GST_VIDEO_CAPTION_META_API_TYPE))) {
174 GstH264SEIMessage sei;
175 GstH264RegisteredUserData *rud;
178 if (cc_meta->caption_type != GST_VIDEO_CAPTION_TYPE_CEA708_RAW)
181 memset (&sei, 0, sizeof (GstH264SEIMessage));
182 sei.payloadType = GST_H264_SEI_REGISTERED_USER_DATA;
183 rud = &sei.payload.registered_user_data;
185 rud->country_code = 181;
186 rud->size = cc_meta->size + 10;
188 data = g_malloc (rud->size);
189 memcpy (data + 9, cc_meta->data, cc_meta->size);
191 data[0] = 0; /* 16-bits itu_t_t35_provider_code */
193 data[2] = 'G'; /* 32-bits ATSC_user_identifier */
197 data[6] = 3; /* 8-bits ATSC1_data_user_data_type_code */
199 * 1 bit process_em_data_flag (0)
200 * 1 bit process_cc_data_flag (1)
201 * 1 bit additional_data_flag (0)
204 data[7] = ((cc_meta->size / 3) & 0x1f) | 0x40;
205 data[8] = 255; /* 8 bits em_data, unused */
206 data[cc_meta->size + 9] = 255; /* 8 marker bits */
210 if (!thiz->cc_sei_array) {
212 g_array_new (FALSE, FALSE, sizeof (GstH264SEIMessage));
213 g_array_set_clear_func (thiz->cc_sei_array,
214 (GDestroyNotify) gst_h264_sei_clear);
217 g_array_append_val (thiz->cc_sei_array, sei);
220 if (!thiz->cc_sei_array || !thiz->cc_sei_array->len)
223 mem = gst_h264_create_sei_memory (4, thiz->cc_sei_array);
226 GST_WARNING_OBJECT (thiz, "Cannot create SEI nal unit");
230 GST_DEBUG_OBJECT (thiz,
231 "Inserting %d closed caption SEI message(s)", thiz->cc_sei_array->len);
233 gst_msdkh264enc_insert_sei (thiz, frame, mem);
234 gst_memory_unref (mem);
238 gst_msdkh264enc_pre_push (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
240 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (encoder);
242 if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && thiz->frame_packing_sei) {
243 /* Insert frame packing SEI
244 * FIXME: This assumes it does not exist in the stream, which is not
245 * going to be true anymore once this is fixed:
246 * https://github.com/Intel-Media-SDK/MediaSDK/issues/13
248 GST_DEBUG_OBJECT (thiz, "Inserting SEI Frame Packing for multiview");
249 gst_msdkh264enc_insert_sei (thiz, frame, thiz->frame_packing_sei);
252 gst_msdkh264enc_add_cc (thiz, frame);
258 gst_msdkh264enc_set_format (GstMsdkEnc * encoder)
260 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (encoder);
261 GstCaps *template_caps;
262 GstCaps *allowed_caps = NULL;
267 template_caps = gst_static_pad_template_get_caps (&src_factory);
268 allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
270 /* If downstream has ANY caps let encoder decide profile and level */
271 if (allowed_caps == template_caps) {
272 GST_INFO_OBJECT (thiz,
273 "downstream has ANY caps, profile/level set to auto");
274 } else if (allowed_caps) {
276 const gchar *profile;
279 if (gst_caps_is_empty (allowed_caps)) {
280 gst_caps_unref (allowed_caps);
281 gst_caps_unref (template_caps);
285 allowed_caps = gst_caps_make_writable (allowed_caps);
286 allowed_caps = gst_caps_fixate (allowed_caps);
287 s = gst_caps_get_structure (allowed_caps, 0);
289 profile = gst_structure_get_string (s, "profile");
291 if (!strcmp (profile, "high")) {
292 thiz->profile = MFX_PROFILE_AVC_HIGH;
293 } else if (!strcmp (profile, "main")) {
294 thiz->profile = MFX_PROFILE_AVC_MAIN;
295 } else if (!strcmp (profile, "baseline")) {
296 thiz->profile = MFX_PROFILE_AVC_BASELINE;
297 } else if (!strcmp (profile, "constrained-baseline")) {
298 thiz->profile = MFX_PROFILE_AVC_CONSTRAINED_BASELINE;
300 g_assert_not_reached ();
304 level = gst_structure_get_string (s, "level");
306 thiz->level = gst_codec_utils_h264_get_level_idc (level);
309 gst_caps_unref (allowed_caps);
312 gst_caps_unref (template_caps);
314 if (thiz->frame_packing_sei) {
315 gst_memory_unref (thiz->frame_packing_sei);
316 thiz->frame_packing_sei = NULL;
319 /* prepare frame packing SEI message */
320 if (encoder->input_state) {
321 GstVideoMultiviewMode mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
323 /* use property value if any */
324 if (thiz->frame_packing != GST_VIDEO_MULTIVIEW_MODE_NONE) {
325 mode = (GstVideoMultiviewMode) thiz->frame_packing;
327 mode = GST_VIDEO_INFO_MULTIVIEW_MODE (&encoder->input_state->info);
330 if (mode == GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE ||
331 mode == GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM) {
332 GstH264SEIMessage sei;
333 GstH264FramePacking *frame_packing;
334 GArray *array = g_array_new (FALSE, FALSE, sizeof (GstH264SEIMessage));
336 g_array_set_clear_func (thiz->cc_sei_array,
337 (GDestroyNotify) gst_h264_sei_clear);
339 GST_DEBUG_OBJECT (thiz,
340 "Prepare frame packing SEI data for multiview mode %d", mode);
342 memset (&sei, 0, sizeof (GstH264SEIMessage));
344 sei.payloadType = GST_H264_SEI_FRAME_PACKING;
345 frame_packing = &sei.payload.frame_packing;
346 frame_packing->frame_packing_id = 0;
347 frame_packing->frame_packing_cancel_flag = 0;
348 frame_packing->frame_packing_type =
349 (mode == GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE ?
350 GST_H264_FRAME_PACKING_SIDE_BY_SIDE :
351 GST_H264_FRAME_PACKING_TOP_BOTTOM);
352 /* we don't do this */
353 frame_packing->quincunx_sampling_flag = 0;
355 /* 1: frame 0 will be left view and frame 1 will be right view */
356 frame_packing->content_interpretation_type = 1;
357 /* we didn't do flip */
358 frame_packing->spatial_flipping_flag = 0;
359 frame_packing->frame0_flipped_flag = 0;
360 /* must be zero for frame_packing_type != 2 */
361 frame_packing->field_views_flag = 0;
362 /* must be zero for frame_packing_type != 5 */
363 frame_packing->current_frame_is_frame0_flag = 0;
364 /* may or may not used to reference each other */
365 frame_packing->frame0_self_contained_flag = 0;
366 frame_packing->frame1_self_contained_flag = 0;
368 frame_packing->frame0_grid_position_x = 0;
369 frame_packing->frame0_grid_position_y = 0;
370 frame_packing->frame1_grid_position_x = 0;
371 frame_packing->frame1_grid_position_y = 0;
373 /* will be applied to this GOP */
374 frame_packing->frame_packing_repetition_period = 1;
376 g_array_append_val (array, sei);
378 thiz->frame_packing_sei = gst_h264_create_sei_memory (4, array);
379 g_array_unref (array);
387 gst_msdkh264enc_configure (GstMsdkEnc * encoder)
389 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (encoder);
391 encoder->param.mfx.LowPower = thiz->tune_mode;
392 encoder->param.mfx.CodecId = MFX_CODEC_AVC;
393 encoder->param.mfx.CodecProfile = thiz->profile;
394 encoder->param.mfx.CodecLevel = thiz->level;
396 thiz->option.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
397 thiz->option.Header.BufferSz = sizeof (thiz->option);
398 if (thiz->profile == MFX_PROFILE_AVC_CONSTRAINED_BASELINE ||
399 thiz->profile == MFX_PROFILE_AVC_BASELINE ||
400 thiz->profile == MFX_PROFILE_AVC_EXTENDED) {
401 thiz->option.CAVLC = MFX_CODINGOPTION_ON;
404 (thiz->cabac ? MFX_CODINGOPTION_OFF : MFX_CODINGOPTION_ON);
407 if (encoder->option3.LowDelayBRC == MFX_CODINGOPTION_ON) {
408 thiz->option.NalHrdConformance = MFX_CODINGOPTION_OFF;
411 gst_msdkenc_add_extra_param (encoder, (mfxExtBuffer *) & thiz->option);
413 encoder->option2.Trellis = thiz->trellis ? thiz->trellis : MFX_TRELLIS_OFF;
414 encoder->option2.MaxSliceSize = thiz->max_slice_size;
415 encoder->option2.MinQPI = encoder->option2.MinQPP = encoder->option2.MinQPB =
417 encoder->option2.MaxQPI = encoder->option2.MaxQPP = encoder->option2.MaxQPB =
419 encoder->option2.IntRefType = thiz->intra_refresh_type;
420 encoder->option2.IntRefCycleSize = thiz->intra_refresh_cycle_size;
421 encoder->option2.IntRefQPDelta = thiz->intra_refresh_qp_delta;
422 encoder->option2.DisableDeblockingIdc = thiz->dblk_idc;
424 if (encoder->rate_control == MFX_RATECONTROL_LA ||
425 encoder->rate_control == MFX_RATECONTROL_LA_HRD ||
426 encoder->rate_control == MFX_RATECONTROL_LA_ICQ)
427 encoder->option2.LookAheadDS = thiz->lookahead_ds;
429 if (thiz->b_pyramid) {
430 encoder->option2.BRefType = MFX_B_REF_PYRAMID;
431 /* Don't define Gop structure for B-pyramid, otherwise EncodeInit
432 * will throw Invalid param error */
433 encoder->param.mfx.GopRefDist = 0;
436 if (thiz->p_pyramid) {
437 encoder->option3.PRefType = MFX_P_REF_PYRAMID;
438 /* MFX_P_REF_PYRAMID is available for GopRefDist = 1 */
439 encoder->param.mfx.GopRefDist = 1;
440 /* SDK decides the DPB size for P pyramid */
441 encoder->param.mfx.NumRefFrame = 0;
443 if (thiz->intra_refresh_cycle_dist) {
444 encoder->option3.IntRefCycleDist = thiz->intra_refresh_cycle_dist;
445 encoder->enable_extopt3 = TRUE;
448 /* Enable Extended coding options */
449 gst_msdkenc_ensure_extended_coding_options (encoder);
454 static inline const gchar *
455 profile_to_string (gint profile)
458 case MFX_PROFILE_AVC_HIGH:
460 case MFX_PROFILE_AVC_MAIN:
462 case MFX_PROFILE_AVC_BASELINE:
464 case MFX_PROFILE_AVC_CONSTRAINED_BASELINE:
465 return "constrained-baseline";
473 static inline const gchar *
474 level_to_string (gint level)
477 case MFX_LEVEL_AVC_1:
479 case MFX_LEVEL_AVC_1b:
481 case MFX_LEVEL_AVC_11:
483 case MFX_LEVEL_AVC_12:
485 case MFX_LEVEL_AVC_13:
487 case MFX_LEVEL_AVC_2:
489 case MFX_LEVEL_AVC_21:
491 case MFX_LEVEL_AVC_22:
493 case MFX_LEVEL_AVC_3:
495 case MFX_LEVEL_AVC_31:
497 case MFX_LEVEL_AVC_32:
499 case MFX_LEVEL_AVC_4:
501 case MFX_LEVEL_AVC_41:
503 case MFX_LEVEL_AVC_42:
505 case MFX_LEVEL_AVC_5:
507 case MFX_LEVEL_AVC_51:
509 case MFX_LEVEL_AVC_52:
519 gst_msdkh264enc_set_src_caps (GstMsdkEnc * encoder)
522 GstStructure *structure;
523 const gchar *profile;
526 caps = gst_caps_new_empty_simple ("video/x-h264");
527 structure = gst_caps_get_structure (caps, 0);
529 gst_structure_set (structure, "stream-format", G_TYPE_STRING, "byte-stream",
532 gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL);
534 profile = profile_to_string (encoder->param.mfx.CodecProfile);
536 gst_structure_set (structure, "profile", G_TYPE_STRING, profile, NULL);
538 level = level_to_string (encoder->param.mfx.CodecLevel);
540 gst_structure_set (structure, "level", G_TYPE_STRING, level, NULL);
546 gst_msdkh264enc_dispose (GObject * object)
548 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (object);
550 if (thiz->frame_packing_sei) {
551 gst_memory_unref (thiz->frame_packing_sei);
552 thiz->frame_packing_sei = NULL;
555 G_OBJECT_CLASS (parent_class)->dispose (object);
559 gst_msdkh264enc_finalize (GObject * object)
561 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (object);
564 gst_h264_nal_parser_free (thiz->parser);
565 if (thiz->cc_sei_array)
566 g_array_unref (thiz->cc_sei_array);
568 G_OBJECT_CLASS (parent_class)->finalize (object);
572 gst_msdkh264enc_set_property (GObject * object, guint prop_id,
573 const GValue * value, GParamSpec * pspec)
575 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (object);
577 if (gst_msdkenc_set_common_property (object, prop_id, value, pspec))
580 GST_OBJECT_LOCK (thiz);
584 thiz->cabac = g_value_get_boolean (value);
586 #ifndef GST_REMOVE_DEPRECATED
588 thiz->lowpower = g_value_get_boolean (value);
589 thiz->prop_flag |= GST_MSDK_FLAG_LOW_POWER;
591 /* Ignore it if user set tune mode explicitly */
592 if (!(thiz->prop_flag & GST_MSDK_FLAG_TUNE_MODE))
594 thiz->lowpower ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
598 case PROP_FRAME_PACKING:
599 thiz->frame_packing = g_value_get_enum (value);
601 case PROP_RC_LA_DOWNSAMPLING:
602 thiz->lookahead_ds = g_value_get_enum (value);
605 thiz->trellis = g_value_get_flags (value);
607 case PROP_MAX_SLICE_SIZE:
608 thiz->max_slice_size = g_value_get_uint (value);
611 thiz->b_pyramid = g_value_get_boolean (value);
614 thiz->tune_mode = g_value_get_enum (value);
615 thiz->prop_flag |= GST_MSDK_FLAG_TUNE_MODE;
618 thiz->p_pyramid = g_value_get_boolean (value);
621 thiz->min_qp = g_value_get_uint (value);
624 thiz->max_qp = g_value_get_uint (value);
626 case PROP_INTRA_REFRESH_TYPE:
627 thiz->intra_refresh_type = g_value_get_enum (value);
629 case PROP_INTRA_REFRESH_CYCLE_SIZE:
630 thiz->intra_refresh_cycle_size = g_value_get_uint (value);
632 case PROP_INTRA_REFRESH_QP_DELTA:
633 thiz->intra_refresh_qp_delta = g_value_get_int (value);
635 case PROP_INTRA_REFRESH_CYCLE_DIST:
636 thiz->intra_refresh_cycle_dist = g_value_get_uint (value);
639 thiz->dblk_idc = g_value_get_uint (value);
642 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
645 GST_OBJECT_UNLOCK (thiz);
650 gst_msdkh264enc_get_property (GObject * object, guint prop_id, GValue * value,
653 GstMsdkH264Enc *thiz = GST_MSDKH264ENC (object);
655 if (gst_msdkenc_get_common_property (object, prop_id, value, pspec))
658 GST_OBJECT_LOCK (thiz);
661 g_value_set_boolean (value, thiz->cabac);
663 #ifndef GST_REMOVE_DEPRECATED
665 g_value_set_boolean (value, thiz->lowpower);
668 case PROP_FRAME_PACKING:
669 g_value_set_enum (value, thiz->frame_packing);
671 case PROP_RC_LA_DOWNSAMPLING:
672 g_value_set_enum (value, thiz->lookahead_ds);
675 g_value_set_flags (value, thiz->trellis);
677 case PROP_MAX_SLICE_SIZE:
678 g_value_set_uint (value, thiz->max_slice_size);
681 g_value_set_boolean (value, thiz->b_pyramid);
684 g_value_set_enum (value, thiz->tune_mode);
687 g_value_set_boolean (value, thiz->p_pyramid);
690 g_value_set_uint (value, thiz->min_qp);
693 g_value_set_uint (value, thiz->max_qp);
695 case PROP_INTRA_REFRESH_TYPE:
696 g_value_set_enum (value, thiz->intra_refresh_type);
698 case PROP_INTRA_REFRESH_CYCLE_SIZE:
699 g_value_set_uint (value, thiz->intra_refresh_cycle_size);
701 case PROP_INTRA_REFRESH_QP_DELTA:
702 g_value_set_int (value, thiz->intra_refresh_qp_delta);
704 case PROP_INTRA_REFRESH_CYCLE_DIST:
705 g_value_set_uint (value, thiz->intra_refresh_cycle_dist);
708 g_value_set_uint (value, thiz->dblk_idc);
711 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
714 GST_OBJECT_UNLOCK (thiz);
718 gst_msdkh264enc_need_reconfig (GstMsdkEnc * encoder, GstVideoCodecFrame * frame)
720 GstMsdkH264Enc *h264enc = GST_MSDKH264ENC (encoder);
722 return gst_msdkenc_get_roi_params (encoder, frame, h264enc->roi);
726 gst_msdkh264enc_set_extra_params (GstMsdkEnc * encoder,
727 GstVideoCodecFrame * frame)
729 GstMsdkH264Enc *h264enc = GST_MSDKH264ENC (encoder);
731 if (h264enc->roi[0].NumROI)
732 gst_msdkenc_add_extra_param (encoder, (mfxExtBuffer *) & h264enc->roi[0]);
736 gst_msdkh264enc_class_init (GstMsdkH264EncClass * klass)
738 GObjectClass *gobject_class;
739 GstElementClass *element_class;
740 GstVideoEncoderClass *videoencoder_class;
741 GstMsdkEncClass *encoder_class;
743 gobject_class = G_OBJECT_CLASS (klass);
744 element_class = GST_ELEMENT_CLASS (klass);
745 videoencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
746 encoder_class = GST_MSDKENC_CLASS (klass);
748 gobject_class->dispose = gst_msdkh264enc_dispose;
749 gobject_class->finalize = gst_msdkh264enc_finalize;
750 gobject_class->set_property = gst_msdkh264enc_set_property;
751 gobject_class->get_property = gst_msdkh264enc_get_property;
753 videoencoder_class->pre_push = gst_msdkh264enc_pre_push;
755 encoder_class->set_format = gst_msdkh264enc_set_format;
756 encoder_class->configure = gst_msdkh264enc_configure;
757 encoder_class->set_src_caps = gst_msdkh264enc_set_src_caps;
758 encoder_class->need_reconfig = gst_msdkh264enc_need_reconfig;
759 encoder_class->set_extra_params = gst_msdkh264enc_set_extra_params;
761 gst_msdkenc_install_common_properties (encoder_class);
763 g_object_class_install_property (gobject_class, PROP_CABAC,
764 g_param_spec_boolean ("cabac", "CABAC", "Enable CABAC entropy coding",
765 PROP_CABAC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
767 #ifndef GST_REMOVE_DEPRECATED
768 g_object_class_install_property (gobject_class, PROP_LOW_POWER,
769 g_param_spec_boolean ("low-power", "Low power",
770 "Enable low power mode (DEPRECATED, use tune instead)",
771 PROP_LOWPOWER_DEFAULT,
772 G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
775 g_object_class_install_property (gobject_class, PROP_FRAME_PACKING,
776 g_param_spec_enum ("frame-packing", "Frame Packing",
777 "Set frame packing mode for Stereoscopic content",
778 gst_msdkh264enc_frame_packing_get_type (), PROP_FRAME_PACKING_DEFAULT,
779 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
781 g_object_class_install_property (gobject_class, PROP_RC_LA_DOWNSAMPLING,
782 g_param_spec_enum ("rc-lookahead-ds", "Look-ahead Downsampling",
783 "Down sampling mode in look ahead bitrate control",
784 gst_msdkenc_rc_lookahead_ds_get_type (),
785 PROP_RC_LA_DOWNSAMPLING_DEFAULT,
786 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
788 g_object_class_install_property (gobject_class, PROP_TRELLIS,
789 g_param_spec_flags ("trellis", "Trellis",
790 "Enable Trellis Quantization",
791 gst_msdkenc_trellis_quantization_get_type (), _MFX_TRELLIS_NONE,
792 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
794 g_object_class_install_property (gobject_class, PROP_MAX_SLICE_SIZE,
795 g_param_spec_uint ("max-slice-size", "Max Slice Size",
796 "Maximum slice size in bytes (if enabled MSDK will ignore the control over num-slices)",
797 0, G_MAXUINT32, PROP_MAX_SLICE_SIZE_DEFAULT,
798 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
800 g_object_class_install_property (gobject_class, PROP_B_PYRAMID,
801 g_param_spec_boolean ("b-pyramid", "B-pyramid",
802 "Enable B-Pyramid Reference structure", FALSE,
803 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
805 g_object_class_install_property (gobject_class, PROP_TUNE_MODE,
806 g_param_spec_enum ("tune", "Encoder tuning",
807 "Encoder tuning option",
808 gst_msdkenc_tune_mode_get_type (), PROP_TUNE_MODE_DEFAULT,
809 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
811 g_object_class_install_property (gobject_class, PROP_P_PYRAMID,
812 g_param_spec_boolean ("p-pyramid", "P-pyramid",
813 "Enable P-Pyramid Reference structure", FALSE,
814 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
816 g_object_class_install_property (gobject_class, PROP_MIN_QP,
817 g_param_spec_uint ("min-qp", "Min QP",
818 "Minimal quantizer for I/P/B frames",
819 0, 51, PROP_MIN_QP_DEFAULT,
820 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
822 g_object_class_install_property (gobject_class, PROP_MAX_QP,
823 g_param_spec_uint ("max-qp", "Max QP",
824 "Maximum quantizer for I/P/B frames",
825 0, 51, PROP_MAX_QP_DEFAULT,
826 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
828 g_object_class_install_property (gobject_class, PROP_INTRA_REFRESH_TYPE,
829 g_param_spec_enum ("intra-refresh-type", "Intra refresh type",
830 "Set intra refresh type",
831 gst_msdkenc_intra_refresh_type_get_type (),
832 PROP_INTRA_REFRESH_TYPE_DEFAULT,
833 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
835 g_object_class_install_property (gobject_class, PROP_INTRA_REFRESH_CYCLE_SIZE,
836 g_param_spec_uint ("intra-refresh-cycle-size", "Intra refresh cycle size",
837 "Set intra refresh cycle size, valid value starts from 2",
838 0, G_MAXUINT16, PROP_INTRA_REFRESH_CYCLE_SIZE_DEFAULT,
839 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
841 g_object_class_install_property (gobject_class, PROP_INTRA_REFRESH_QP_DELTA,
842 g_param_spec_int ("intra-refresh-qp-delta", "Intra refresh qp delta",
843 "Set intra refresh qp delta",
844 -51, 51, PROP_INTRA_REFRESH_QP_DELTA_DEFAULT,
845 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
847 g_object_class_install_property (gobject_class, PROP_INTRA_REFRESH_CYCLE_DIST,
848 g_param_spec_uint ("intra-refresh-cycle-dist", "Intra refresh cycle dist",
849 "Set intra refresh cycle dist",
850 0, G_MAXUINT16, PROP_INTRA_REFRESH_CYCLE_DIST_DEFAULT,
851 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
853 g_object_class_install_property (gobject_class, PROP_DBLK_IDC,
854 g_param_spec_uint ("dblk-idc", "Disable Deblocking Idc",
855 "Option of disable deblocking idc",
856 0, 2, PROP_DBLK_IDC_DEFAULT,
857 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
859 gst_element_class_set_static_metadata (element_class,
860 "Intel MSDK H264 encoder", "Codec/Encoder/Video/Hardware",
861 "H264 video encoder based on " MFX_API_SDK,
862 "Josep Torra <jtorra@oblong.com>");
863 gst_element_class_add_static_pad_template (element_class, &src_factory);
867 gst_msdkh264enc_init (GstMsdkH264Enc * thiz)
869 thiz->cabac = PROP_CABAC_DEFAULT;
870 thiz->lowpower = PROP_LOWPOWER_DEFAULT;
871 thiz->frame_packing = PROP_FRAME_PACKING_DEFAULT;
872 thiz->lookahead_ds = PROP_RC_LA_DOWNSAMPLING_DEFAULT;
873 thiz->trellis = PROP_TRELLIS_DEFAULT;
874 thiz->max_slice_size = PROP_MAX_SLICE_SIZE_DEFAULT;
875 thiz->b_pyramid = PROP_B_PYRAMID_DEFAULT;
876 thiz->tune_mode = PROP_TUNE_MODE_DEFAULT;
877 thiz->p_pyramid = PROP_P_PYRAMID_DEFAULT;
878 thiz->min_qp = PROP_MIN_QP_DEFAULT;
879 thiz->max_qp = PROP_MAX_QP_DEFAULT;
880 thiz->intra_refresh_type = PROP_INTRA_REFRESH_TYPE_DEFAULT;
881 thiz->intra_refresh_cycle_size = PROP_INTRA_REFRESH_CYCLE_SIZE_DEFAULT;
882 thiz->intra_refresh_qp_delta = PROP_INTRA_REFRESH_QP_DELTA_DEFAULT;
883 thiz->intra_refresh_cycle_dist = PROP_INTRA_REFRESH_CYCLE_DIST_DEFAULT;
884 thiz->dblk_idc = PROP_DBLK_IDC_DEFAULT;