2 * gstvaapiencoder_h264.c - H.264 encoder
4 * Copyright (C) 2012-2013 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
24 #include <va/va_enc_h264.h>
25 #include <gst/base/gstbitwriter.h>
26 #include "gstvaapicompat.h"
27 #include "gstvaapiencoder_h264.h"
28 #include "gstvaapiencoder_h264_priv.h"
29 #include "gstvaapiutils_h264_priv.h"
30 #include "gstvaapicodedbufferproxy_priv.h"
31 #include "gstvaapisurface.h"
34 #include "gstvaapidebug.h"
36 /* Define default rate control mode ("constant-qp") */
37 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
39 /* Supported set of VA rate controls, within this implementation */
40 #define SUPPORTED_RATECONTROLS \
41 (GST_VAAPI_RATECONTROL_MASK (NONE) | \
42 GST_VAAPI_RATECONTROL_MASK (CQP) | \
43 GST_VAAPI_RATECONTROL_MASK (CBR) | \
44 GST_VAAPI_RATECONTROL_MASK (VBR) | \
45 GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
47 /* Supported set of tuning options, within this implementation */
48 #define SUPPORTED_TUNE_OPTIONS \
49 (GST_VAAPI_ENCODER_TUNE_MASK (NONE))
51 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0
52 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1
53 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2
54 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3
58 GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CAVLC = 0,
59 GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC = 1
60 } GstVaapiEncoderH264EntropyMode;
64 GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0,
65 GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1,
66 GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */
67 GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */
68 GST_VAAPI_ENCODER_H264_NAL_SPS = 7,
69 GST_VAAPI_ENCODER_H264_NAL_PPS = 8
70 } GstVaapiEncoderH264NalType;
81 GstVaapiSurfaceProxy *pic;
84 } GstVaapiEncoderH264Ref;
88 GST_VAAPI_ENC_H264_REORD_NONE = 0,
89 GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
90 GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
91 } GstVaapiEncH264ReorderState;
93 static inline gboolean
94 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
96 return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
99 /* Get slice_type value for H.264 specification */
101 h264_get_slice_type (GstVaapiPictureType type)
104 case GST_VAAPI_PICTURE_TYPE_I:
106 case GST_VAAPI_PICTURE_TYPE_P:
108 case GST_VAAPI_PICTURE_TYPE_B:
116 /* Get log2_max_frame_num value for H.264 specification */
118 h264_get_log2_max_frame_num (guint num)
130 /* must greater than 4 */
135 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
136 const guint8 * nal, guint32 size)
143 if (encoder->sps_data && encoder->pps_data)
146 nal_type = nal[0] & 0x1F;
148 case GST_VAAPI_ENCODER_H264_NAL_SPS:
149 encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
150 ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
151 g_assert (ret == size);
153 case GST_VAAPI_ENCODER_H264_NAL_PPS:
154 encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
155 ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
156 g_assert (ret == size);
163 /* Derives the profile supported by the underlying hardware */
165 ensure_hw_profile (GstVaapiEncoderH264 * encoder)
167 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
168 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
169 GstVaapiProfile profile, profiles[4];
170 guint i, num_profiles = 0;
172 profiles[num_profiles++] = encoder->profile;
173 switch (encoder->profile) {
174 case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
175 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
176 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
178 case GST_VAAPI_PROFILE_H264_MAIN:
179 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
185 profile = GST_VAAPI_PROFILE_UNKNOWN;
186 for (i = 0; i < num_profiles; i++) {
187 if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
188 profile = profiles[i];
192 if (profile == GST_VAAPI_PROFILE_UNKNOWN)
193 goto error_unsupported_profile;
195 GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
199 error_unsupported_profile:
201 GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
206 /* Derives the minimum profile from the active coding tools */
208 ensure_profile (GstVaapiEncoderH264 * encoder)
210 GstVaapiProfile profile;
212 /* Always start from "constrained-baseline" profile for maximum
214 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
216 /* Main profile coding tools */
217 if (encoder->num_bframes > 0)
218 profile = GST_VAAPI_PROFILE_H264_MAIN;
220 encoder->profile = profile;
221 encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
226 ensure_level (GstVaapiEncoderH264 * encoder)
228 const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
229 const GstVaapiH264LevelLimits *limits_table;
230 guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
232 PicSizeMbs = encoder->mb_width * encoder->mb_height;
233 MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
234 MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
235 GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
237 limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
238 for (i = 0; i < num_limits; i++) {
239 const GstVaapiH264LevelLimits *const limits = &limits_table[i];
240 if (PicSizeMbs <= limits->MaxFS &&
241 MaxDpbMbs <= limits->MaxDpbMbs &&
242 MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR))
246 goto error_unsupported_level;
248 encoder->level = limits_table[i].level;
249 encoder->level_idc = limits_table[i].level_idc;
253 error_unsupported_level:
255 GST_ERROR ("failed to find a suitable level matching codec config");
261 _reset_gop_start (GstVaapiEncoderH264 * encoder)
264 encoder->frame_index = 1;
265 encoder->cur_frame_num = 0;
266 encoder->cur_present_index = 0;
270 _set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
272 g_assert (pic && encoder);
273 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
274 pic->type = GST_VAAPI_PICTURE_TYPE_B;
275 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
279 _set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
281 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
282 pic->type = GST_VAAPI_PICTURE_TYPE_P;
283 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
287 _set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
289 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
290 pic->type = GST_VAAPI_PICTURE_TYPE_I;
291 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
292 g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
293 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
297 _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
299 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
300 pic->type = GST_VAAPI_PICTURE_TYPE_I;
303 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
305 g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
306 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
310 _set_key_frame (GstVaapiEncPicture * picture,
311 GstVaapiEncoderH264 * encoder, gboolean is_idr)
314 _reset_gop_start (encoder);
315 _set_idr_frame (picture, encoder);
317 _set_i_frame (picture, encoder);
321 gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value)
323 guint32 size_in_bits = 0;
324 guint32 tmp_value = ++value;
331 && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1))
333 if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits))
339 gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value)
344 new_val = -(value << 1);
346 new_val = (value << 1) - 1;
348 if (!gst_bit_writer_put_ue (bitwriter, new_val))
355 gst_bit_writer_write_nal_header (GstBitWriter * bitwriter,
356 guint32 nal_ref_idc, guint32 nal_unit_type)
358 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
359 gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2);
360 gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5);
365 gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter)
367 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
368 gst_bit_writer_align_bytes_unchecked (bitwriter, 0);
373 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
374 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile)
377 guint32 constraint_set0_flag, constraint_set1_flag;
378 guint32 constraint_set2_flag, constraint_set3_flag;
379 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
380 gboolean nal_hrd_parameters_present_flag;
382 guint32 b_qpprime_y_zero_transform_bypass = 0;
383 guint32 residual_color_transform_flag = 0;
384 guint32 pic_height_in_map_units =
385 (seq_param->seq_fields.bits.frame_mbs_only_flag ?
386 seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
387 guint32 mb_adaptive_frame_field =
388 !seq_param->seq_fields.bits.frame_mbs_only_flag;
391 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
392 constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
393 profile == GST_VAAPI_PROFILE_H264_BASELINE ||
394 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
395 constraint_set1_flag = /* A.2.2 (main profile constraints) */
396 profile == GST_VAAPI_PROFILE_H264_MAIN ||
397 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
398 constraint_set2_flag = 0;
399 constraint_set3_flag = 0;
402 gst_bit_writer_put_bits_uint32 (bitwriter, profile_idc, 8);
403 /* constraint_set0_flag */
404 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1);
405 /* constraint_set1_flag */
406 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1);
407 /* constraint_set2_flag */
408 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1);
409 /* constraint_set3_flag */
410 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1);
411 /* reserved_zero_4bits */
412 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4);
414 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->level_idc, 8);
415 /* seq_parameter_set_id */
416 gst_bit_writer_put_ue (bitwriter, seq_param->seq_parameter_set_id);
418 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
419 /* for high profile */
420 /* chroma_format_idc = 1, 4:2:0 */
421 gst_bit_writer_put_ue (bitwriter,
422 seq_param->seq_fields.bits.chroma_format_idc);
423 if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
424 gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag,
427 /* bit_depth_luma_minus8 */
428 gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_luma_minus8);
429 /* bit_depth_chroma_minus8 */
430 gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_chroma_minus8);
431 /* b_qpprime_y_zero_transform_bypass */
432 gst_bit_writer_put_bits_uint32 (bitwriter,
433 b_qpprime_y_zero_transform_bypass, 1);
434 g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
435 /* seq_scaling_matrix_present_flag */
436 gst_bit_writer_put_bits_uint32 (bitwriter,
437 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
440 if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
442 i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
444 gst_bit_writer_put_bits_uint8 (bitwriter,
445 seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
446 if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
448 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
455 /* log2_max_frame_num_minus4 */
456 gst_bit_writer_put_ue (bitwriter,
457 seq_param->seq_fields.bits.log2_max_frame_num_minus4);
458 /* pic_order_cnt_type */
459 gst_bit_writer_put_ue (bitwriter,
460 seq_param->seq_fields.bits.pic_order_cnt_type);
462 if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
463 /* log2_max_pic_order_cnt_lsb_minus4 */
464 gst_bit_writer_put_ue (bitwriter,
465 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
466 } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
468 gst_bit_writer_put_bits_uint32 (bitwriter,
469 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
470 gst_bit_writer_put_se (bitwriter, seq_param->offset_for_non_ref_pic);
471 gst_bit_writer_put_se (bitwriter,
472 seq_param->offset_for_top_to_bottom_field);
473 gst_bit_writer_put_ue (bitwriter,
474 seq_param->num_ref_frames_in_pic_order_cnt_cycle);
475 for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
476 gst_bit_writer_put_se (bitwriter, seq_param->offset_for_ref_frame[i]);
481 gst_bit_writer_put_ue (bitwriter, seq_param->max_num_ref_frames);
482 /* gaps_in_frame_num_value_allowed_flag */
483 gst_bit_writer_put_bits_uint32 (bitwriter,
484 gaps_in_frame_num_value_allowed_flag, 1);
486 /* pic_width_in_mbs_minus1 */
487 gst_bit_writer_put_ue (bitwriter, seq_param->picture_width_in_mbs - 1);
488 /* pic_height_in_map_units_minus1 */
489 gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1);
490 /* frame_mbs_only_flag */
491 gst_bit_writer_put_bits_uint32 (bitwriter,
492 seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
494 if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
496 gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1);
499 /* direct_8x8_inference_flag */
500 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
501 /* frame_cropping_flag */
502 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->frame_cropping_flag, 1);
504 if (seq_param->frame_cropping_flag) {
505 /* frame_crop_left_offset */
506 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_left_offset);
507 /* frame_crop_right_offset */
508 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_right_offset);
509 /* frame_crop_top_offset */
510 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_top_offset);
511 /* frame_crop_bottom_offset */
512 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_bottom_offset);
515 /* vui_parameters_present_flag */
516 gst_bit_writer_put_bits_uint32 (bitwriter,
517 seq_param->vui_parameters_present_flag, 1);
518 if (seq_param->vui_parameters_present_flag) {
519 /* aspect_ratio_info_present_flag */
520 gst_bit_writer_put_bits_uint32 (bitwriter,
521 seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
522 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
523 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->aspect_ratio_idc,
525 if (seq_param->aspect_ratio_idc == 0xFF) {
526 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_width, 16);
527 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_height, 16);
531 /* overscan_info_present_flag */
532 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
533 /* video_signal_type_present_flag */
534 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
535 /* chroma_loc_info_present_flag */
536 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
538 /* timing_info_present_flag */
539 gst_bit_writer_put_bits_uint32 (bitwriter,
540 seq_param->vui_fields.bits.timing_info_present_flag, 1);
541 if (seq_param->vui_fields.bits.timing_info_present_flag) {
542 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->num_units_in_tick,
544 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->time_scale, 32);
545 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */
548 nal_hrd_parameters_present_flag =
549 (seq_param->bits_per_second > 0 ? TRUE : FALSE);
550 /* nal_hrd_parameters_present_flag */
551 gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag,
553 if (nal_hrd_parameters_present_flag) {
556 gst_bit_writer_put_ue (bitwriter, 0);
557 gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */
558 gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */
560 for (i = 0; i < 1; ++i) {
561 /* bit_rate_value_minus1[0] */
562 gst_bit_writer_put_ue (bitwriter,
563 seq_param->bits_per_second / 1000 - 1);
564 /* cpb_size_value_minus1[0] */
565 gst_bit_writer_put_ue (bitwriter,
566 seq_param->bits_per_second / 1000 * 8 - 1);
568 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
570 /* initial_cpb_removal_delay_length_minus1 */
571 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
572 /* cpb_removal_delay_length_minus1 */
573 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
574 /* dpb_output_delay_length_minus1 */
575 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
576 /* time_offset_length */
577 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
579 /* vcl_hrd_parameters_present_flag */
580 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
581 if (nal_hrd_parameters_present_flag
582 || 0 /*vcl_hrd_parameters_present_flag */ ) {
583 /* low_delay_hrd_flag */
584 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
586 /* pic_struct_present_flag */
587 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
588 /* bitwriter_restriction_flag */
589 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
592 /* rbsp_trailing_bits */
593 gst_bit_writer_write_trailing_bits (bitwriter);
598 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
599 const VAEncPictureParameterBufferH264 * pic_param)
601 guint32 num_slice_groups_minus1 = 0;
602 guint32 pic_init_qs_minus26 = 0;
603 guint32 redundant_pic_cnt_present_flag = 0;
605 /* pic_parameter_set_id */
606 gst_bit_writer_put_ue (bitwriter, pic_param->pic_parameter_set_id);
607 /* seq_parameter_set_id */
608 gst_bit_writer_put_ue (bitwriter, pic_param->seq_parameter_set_id);
609 /* entropy_coding_mode_flag */
610 gst_bit_writer_put_bits_uint32 (bitwriter,
611 pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
612 /* pic_order_present_flag */
613 gst_bit_writer_put_bits_uint32 (bitwriter,
614 pic_param->pic_fields.bits.pic_order_present_flag, 1);
616 gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1);
618 if (num_slice_groups_minus1 > 0) {
619 /*FIXME*/ g_assert (0);
621 gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l0_active_minus1);
622 gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l1_active_minus1);
623 gst_bit_writer_put_bits_uint32 (bitwriter,
624 pic_param->pic_fields.bits.weighted_pred_flag, 1);
625 gst_bit_writer_put_bits_uint32 (bitwriter,
626 pic_param->pic_fields.bits.weighted_bipred_idc, 2);
627 /* pic_init_qp_minus26 */
628 gst_bit_writer_put_se (bitwriter, pic_param->pic_init_qp - 26);
629 /* pic_init_qs_minus26 */
630 gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26);
631 /* chroma_qp_index_offset */
632 gst_bit_writer_put_se (bitwriter, pic_param->chroma_qp_index_offset);
634 gst_bit_writer_put_bits_uint32 (bitwriter,
635 pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
636 gst_bit_writer_put_bits_uint32 (bitwriter,
637 pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
638 gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1);
641 gst_bit_writer_put_bits_uint32 (bitwriter,
642 pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
643 gst_bit_writer_put_bits_uint32 (bitwriter,
644 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
645 if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
650 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
652 gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
657 gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset);
658 gst_bit_writer_write_trailing_bits (bitwriter);
664 add_sequence_packed_header (GstVaapiEncoderH264 * encoder,
665 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
667 GstVaapiEncPackedHeader *packed_seq;
669 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
670 const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
671 guint32 data_bit_size;
674 gst_bit_writer_init (&writer, 128 * 8);
675 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
676 gst_bit_writer_write_nal_header (&writer,
677 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
678 gst_bit_writer_write_sps (&writer, seq_param, encoder->profile);
679 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
680 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
681 data = GST_BIT_WRITER_DATA (&writer);
683 packed_header_param_buffer.type = VAEncPackedHeaderSequence;
684 packed_header_param_buffer.bit_length = data_bit_size;
685 packed_header_param_buffer.has_emulation_bytes = 0;
687 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
688 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
689 data, (data_bit_size + 7) / 8);
690 g_assert (packed_seq);
692 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
693 gst_vaapi_codec_object_replace (&packed_seq, NULL);
696 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
697 gst_bit_writer_clear (&writer, TRUE);
703 add_picture_packed_header (GstVaapiEncoderH264 * encoder,
704 GstVaapiEncPicture * picture)
706 GstVaapiEncPackedHeader *packed_pic;
708 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
709 const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
710 guint32 data_bit_size;
713 gst_bit_writer_init (&writer, 128 * 8);
714 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
715 gst_bit_writer_write_nal_header (&writer,
716 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
717 gst_bit_writer_write_pps (&writer, pic_param);
718 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
719 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
720 data = GST_BIT_WRITER_DATA (&writer);
722 packed_header_param_buffer.type = VAEncPackedHeaderPicture;
723 packed_header_param_buffer.bit_length = data_bit_size;
724 packed_header_param_buffer.has_emulation_bytes = 0;
726 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
727 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
728 data, (data_bit_size + 7) / 8);
729 g_assert (packed_pic);
731 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
732 gst_vaapi_codec_object_replace (&packed_pic, NULL);
735 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
736 gst_bit_writer_clear (&writer, TRUE);
741 /* reference picture management */
743 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
748 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
749 g_slice_free (GstVaapiEncoderH264Ref, ref);
752 static inline GstVaapiEncoderH264Ref *
753 reference_pic_create (GstVaapiEncoderH264 * encoder,
754 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
756 GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
759 ref->frame_num = picture->frame_num;
760 ref->poc = picture->poc;
765 reference_list_update (GstVaapiEncoderH264 * encoder,
766 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
768 GstVaapiEncoderH264Ref *ref;
770 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
771 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
774 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
775 while (!g_queue_is_empty (&encoder->ref_list))
776 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
777 } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) {
778 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
780 ref = reference_pic_create (encoder, picture, surface);
781 g_queue_push_tail (&encoder->ref_list, ref);
782 g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames);
787 reference_list_init (GstVaapiEncoderH264 * encoder,
788 GstVaapiEncPicture * picture,
789 GstVaapiEncoderH264Ref ** reflist_0,
790 guint * reflist_0_count,
791 GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
793 GstVaapiEncoderH264Ref *tmp;
794 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
795 guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
798 *reflist_0_count = 0;
799 *reflist_1_count = 0;
800 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
803 iter = g_queue_peek_tail_link (&encoder->ref_list);
804 for (; iter; iter = g_list_previous (iter)) {
805 tmp = (GstVaapiEncoderH264Ref *) iter->data;
806 g_assert (tmp && tmp->poc != picture->poc);
807 if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
809 list_1_start = g_list_next (iter);
814 /* order reflist_0 */
815 g_assert (list_0_start);
818 for (; iter; iter = g_list_previous (iter)) {
819 reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
822 *reflist_0_count = count;
824 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
827 /* order reflist_1 */
830 for (; iter; iter = g_list_next (iter)) {
831 reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
834 *reflist_1_count = count;
838 /* fill the H264 VA encoding parameters */
840 fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
841 GstVaapiEncSequence * sequence)
843 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
844 VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
846 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
847 seq_param->seq_parameter_set_id = 0;
848 seq_param->level_idc = encoder->level_idc;
849 seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
850 seq_param->ip_period = 0; // ?
851 if (base_encoder->bitrate > 0)
852 seq_param->bits_per_second = base_encoder->bitrate * 1000;
854 seq_param->bits_per_second = 0;
856 seq_param->max_num_ref_frames = encoder->max_ref_frames;
857 seq_param->picture_width_in_mbs = encoder->mb_width;
858 seq_param->picture_height_in_mbs = encoder->mb_height;
860 /*sequence field values */
861 seq_param->seq_fields.value = 0;
862 seq_param->seq_fields.bits.chroma_format_idc = 1;
863 seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
864 seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
865 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
866 /* direct_8x8_inference_flag default false */
867 seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
868 g_assert (encoder->log2_max_frame_num >= 4);
869 seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
870 encoder->log2_max_frame_num - 4;
871 /* picture order count */
872 seq_param->seq_fields.bits.pic_order_cnt_type = 0;
873 g_assert (encoder->log2_max_pic_order_cnt >= 4);
874 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
875 encoder->log2_max_pic_order_cnt - 4;
877 seq_param->bit_depth_luma_minus8 = 0;
878 seq_param->bit_depth_chroma_minus8 = 0;
880 /* not used if pic_order_cnt_type == 0 */
881 if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
882 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
883 seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
884 seq_param->offset_for_non_ref_pic = 0;
885 seq_param->offset_for_top_to_bottom_field = 0;
886 memset (seq_param->offset_for_ref_frame, 0,
887 sizeof (seq_param->offset_for_ref_frame));
890 if (encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) {
891 seq_param->frame_cropping_flag = 1;
892 seq_param->frame_crop_left_offset = 0;
893 seq_param->frame_crop_right_offset = 0;
894 seq_param->frame_crop_top_offset = 0;
895 seq_param->frame_crop_bottom_offset =
896 ((encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) /
897 (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)));
901 seq_param->vui_parameters_present_flag =
902 (base_encoder->bitrate > 0 ? TRUE : FALSE);
903 if (seq_param->vui_parameters_present_flag) {
904 seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
905 seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
906 seq_param->vui_fields.bits.timing_info_present_flag =
907 (base_encoder->bitrate > 0 ? TRUE : FALSE);
908 if (seq_param->vui_fields.bits.timing_info_present_flag) {
909 seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
910 seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
918 fill_va_picture_param (GstVaapiEncoderH264 * encoder,
919 GstVaapiEncPicture * picture,
920 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
922 VAEncPictureParameterBufferH264 *const pic_param = picture->param;
923 GstVaapiEncoderH264Ref *ref_pic;
927 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
929 /* reference list, */
930 pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
931 pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
933 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
934 for (reflist = g_queue_peek_head_link (&encoder->ref_list);
935 reflist; reflist = g_list_next (reflist)) {
936 ref_pic = reflist->data;
937 g_assert (ref_pic && ref_pic->pic &&
938 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
940 pic_param->ReferenceFrames[i].picture_id =
941 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
944 g_assert (i <= 16 && i <= encoder->max_ref_frames);
946 for (; i < 16; ++i) {
947 pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
949 pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
951 pic_param->pic_parameter_set_id = 0;
952 pic_param->seq_parameter_set_id = 0;
953 pic_param->last_picture = 0; /* means last encoding picture */
954 pic_param->frame_num = picture->frame_num;
955 pic_param->pic_init_qp = encoder->init_qp;
956 pic_param->num_ref_idx_l0_active_minus1 =
957 (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
958 pic_param->num_ref_idx_l1_active_minus1 =
959 (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
960 pic_param->chroma_qp_index_offset = 0;
961 pic_param->second_chroma_qp_index_offset = 0;
963 /* set picture fields */
964 pic_param->pic_fields.value = 0;
965 pic_param->pic_fields.bits.idr_pic_flag =
966 GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
967 pic_param->pic_fields.bits.reference_pic_flag =
968 (picture->type != GST_VAAPI_PICTURE_TYPE_B);
969 pic_param->pic_fields.bits.entropy_coding_mode_flag =
970 GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC;
971 pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
972 pic_param->pic_fields.bits.weighted_bipred_idc = 0;
973 pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
974 pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile_idc >= 100); /* enable 8x8 */
975 /* enable debloking */
976 pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
977 pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
978 /* bottom_field_pic_order_in_frame_present_flag */
979 pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
980 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
986 fill_va_slices_param (GstVaapiEncoderH264 * encoder,
987 GstVaapiEncPicture * picture,
988 GstVaapiEncoderH264Ref ** reflist_0,
989 guint reflist_0_count,
990 GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
992 VAEncSliceParameterBufferH264 *slice_param;
993 GstVaapiEncSlice *slice;
994 guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
997 guint i_slice, i_ref;
1001 mb_size = encoder->mb_width * encoder->mb_height;
1003 g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1004 slice_of_mbs = mb_size / encoder->num_slices;
1005 slice_mod_mbs = mb_size % encoder->num_slices;
1007 for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1008 cur_slice_mbs = slice_of_mbs;
1009 if (slice_mod_mbs) {
1013 slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1014 g_assert (slice && slice->param_id != VA_INVALID_ID);
1015 slice_param = slice->param;
1017 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1018 slice_param->macroblock_address = last_mb_index;
1019 slice_param->num_macroblocks = cur_slice_mbs;
1020 slice_param->macroblock_info = VA_INVALID_ID;
1021 slice_param->slice_type = h264_get_slice_type (picture->type);
1022 g_assert (slice_param->slice_type != -1);
1023 slice_param->pic_parameter_set_id = 0;
1024 slice_param->idr_pic_id = encoder->idr_num;
1025 slice_param->pic_order_cnt_lsb = picture->poc;
1027 /* not used if pic_order_cnt_type = 0 */
1028 slice_param->delta_pic_order_cnt_bottom = 0;
1029 memset (slice_param->delta_pic_order_cnt, 0,
1030 sizeof (slice_param->delta_pic_order_cnt));
1032 /* only works for B frames */
1033 slice_param->direct_spatial_mv_pred_flag = FALSE;
1034 /* default equal to picture parameters */
1035 slice_param->num_ref_idx_active_override_flag = FALSE;
1036 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1037 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1039 slice_param->num_ref_idx_l0_active_minus1 = 0;
1040 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1041 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1043 slice_param->num_ref_idx_l1_active_minus1 = 0;
1044 g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1045 g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1048 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1049 for (; i_ref < reflist_0_count; ++i_ref) {
1050 slice_param->RefPicList0[i_ref].picture_id =
1051 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1053 g_assert (i_ref == 1);
1055 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1056 slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1060 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1061 for (; i_ref < reflist_1_count; ++i_ref) {
1062 slice_param->RefPicList1[i_ref].picture_id =
1063 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1065 g_assert (i_ref == 1);
1067 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1068 slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1071 /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1072 slice_param->luma_log2_weight_denom = 0;
1073 slice_param->chroma_log2_weight_denom = 0;
1074 slice_param->luma_weight_l0_flag = FALSE;
1075 memset (slice_param->luma_weight_l0, 0,
1076 sizeof (slice_param->luma_weight_l0));
1077 memset (slice_param->luma_offset_l0, 0,
1078 sizeof (slice_param->luma_offset_l0));
1079 slice_param->chroma_weight_l0_flag = FALSE;
1080 memset (slice_param->chroma_weight_l0, 0,
1081 sizeof (slice_param->chroma_weight_l0));
1082 memset (slice_param->chroma_offset_l0, 0,
1083 sizeof (slice_param->chroma_offset_l0));
1084 slice_param->luma_weight_l1_flag = FALSE;
1085 memset (slice_param->luma_weight_l1, 0,
1086 sizeof (slice_param->luma_weight_l1));
1087 memset (slice_param->luma_offset_l1, 0,
1088 sizeof (slice_param->luma_offset_l1));
1089 slice_param->chroma_weight_l1_flag = FALSE;
1090 memset (slice_param->chroma_weight_l1, 0,
1091 sizeof (slice_param->chroma_weight_l1));
1092 memset (slice_param->chroma_offset_l1, 0,
1093 sizeof (slice_param->chroma_offset_l1));
1095 slice_param->cabac_init_idc = 0;
1096 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1097 if (slice_param->slice_qp_delta > 4)
1098 slice_param->slice_qp_delta = 4;
1099 slice_param->disable_deblocking_filter_idc = 0;
1100 slice_param->slice_alpha_c0_offset_div2 = 2;
1101 slice_param->slice_beta_offset_div2 = 2;
1103 /* set calculation for next slice */
1104 last_mb_index += cur_slice_mbs;
1106 gst_vaapi_enc_picture_add_slice (picture, slice);
1107 gst_vaapi_codec_object_replace (&slice, NULL);
1109 g_assert (last_mb_index == mb_size);
1114 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1116 GstVaapiEncSequence *sequence;
1119 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1120 g_assert (sequence);
1124 if (!fill_va_sequence_param (encoder, sequence))
1127 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1128 !add_sequence_packed_header (encoder, picture, sequence))
1130 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1131 gst_vaapi_codec_object_replace (&sequence, NULL);
1135 gst_vaapi_codec_object_replace (&sequence, NULL);
1140 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1141 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1143 GstVaapiCodedBuffer *const codedbuf =
1144 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1146 if (!fill_va_picture_param (encoder, picture, codedbuf, surface))
1149 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1150 !add_picture_packed_header (encoder, picture)) {
1151 GST_ERROR ("set picture packed header failed");
1159 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1161 GstVaapiEncoderH264Ref *reflist_0[16];
1162 GstVaapiEncoderH264Ref *reflist_1[16];
1163 guint reflist_0_count = 0, reflist_1_count = 0;
1167 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1168 !reference_list_init (encoder, picture,
1169 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1170 GST_ERROR ("reference list reorder failed");
1174 g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames);
1175 if (reflist_0_count > encoder->max_reflist0_count)
1176 reflist_0_count = encoder->max_reflist0_count;
1177 if (reflist_1_count > encoder->max_reflist1_count)
1178 reflist_1_count = encoder->max_reflist1_count;
1180 if (!fill_va_slices_param (encoder, picture,
1181 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1188 ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1190 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1191 GstVaapiEncMiscParam *misc = NULL;
1192 VAEncMiscParameterHRD *hrd;
1193 VAEncMiscParameterRateControl *rate_control;
1196 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1200 gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1202 if (base_encoder->bitrate > 0) {
1203 hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4;
1204 hrd->buffer_size = base_encoder->bitrate * 1000 * 8;
1206 hrd->initial_buffer_fullness = 0;
1207 hrd->buffer_size = 0;
1209 gst_vaapi_codec_object_replace (&misc, NULL);
1211 /* add ratecontrol */
1212 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1213 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1214 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1218 gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1219 rate_control = misc->impl;
1220 memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1221 if (base_encoder->bitrate)
1222 rate_control->bits_per_second = base_encoder->bitrate * 1000;
1224 rate_control->bits_per_second = 0;
1225 rate_control->target_percentage = 70;
1226 rate_control->window_size = 500;
1227 rate_control->initial_qp = encoder->init_qp;
1228 rate_control->min_qp = encoder->min_qp;
1229 rate_control->basic_unit_size = 0;
1230 gst_vaapi_codec_object_replace (&misc, NULL);
1237 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
1239 if (!ensure_profile (encoder))
1241 if (!ensure_level (encoder))
1247 ensure_bitrate (GstVaapiEncoderH264 * encoder)
1249 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1251 /* Default compression: 64 bits per macroblock */
1252 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1253 case GST_VAAPI_RATECONTROL_CBR:
1254 case GST_VAAPI_RATECONTROL_VBR:
1255 case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
1256 if (!base_encoder->bitrate)
1257 base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
1258 GST_VAAPI_ENCODER_HEIGHT (encoder) *
1259 GST_VAAPI_ENCODER_FPS_N (encoder) /
1260 GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1000;
1263 base_encoder->bitrate = 0;
1270 reset_properties (GstVaapiEncoderH264 * encoder)
1272 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1275 if (encoder->idr_period < base_encoder->keyframe_period)
1276 encoder->idr_period = base_encoder->keyframe_period;
1277 if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD)
1278 encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD;
1280 if (encoder->min_qp > encoder->init_qp ||
1281 (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
1282 encoder->min_qp < encoder->init_qp))
1283 encoder->min_qp = encoder->init_qp;
1285 mb_size = encoder->mb_width * encoder->mb_height;
1286 if (encoder->num_slices > (mb_size + 1) / 2)
1287 encoder->num_slices = (mb_size + 1) / 2;
1288 g_assert (encoder->num_slices);
1290 if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
1291 encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
1293 if (encoder->num_bframes > 50)
1294 encoder->num_bframes = 50;
1296 if (encoder->num_bframes)
1297 encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1298 GST_VAAPI_ENCODER_FPS_N (encoder);
1300 encoder->cts_offset = 0;
1302 /* init max_frame_num, max_poc */
1303 encoder->log2_max_frame_num =
1304 h264_get_log2_max_frame_num (encoder->idr_period);
1305 g_assert (encoder->log2_max_frame_num >= 4);
1306 encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1307 encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1308 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1310 encoder->frame_index = 0;
1311 encoder->idr_num = 0;
1312 encoder->max_reflist0_count = 1;
1313 encoder->max_reflist1_count = encoder->num_bframes > 0;
1314 encoder->max_ref_frames =
1315 encoder->max_reflist0_count + encoder->max_reflist1_count;
1318 static GstVaapiEncoderStatus
1319 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
1320 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1322 GstVaapiEncoderH264 *const encoder =
1323 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1324 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1325 GstVaapiSurfaceProxy *reconstruct = NULL;
1327 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
1329 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1331 if (!ensure_sequence (encoder, picture))
1333 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1335 if (!ensure_misc (encoder, picture))
1337 if (!ensure_slices (encoder, picture))
1339 if (!gst_vaapi_enc_picture_encode (picture))
1342 if (!reference_list_update (encoder, picture, reconstruct))
1345 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1348 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1353 static GstVaapiEncoderStatus
1354 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
1356 GstVaapiEncoderH264 *const encoder =
1357 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1358 GstVaapiEncPicture *pic;
1360 encoder->frame_index = 0;
1361 encoder->cur_frame_num = 0;
1362 encoder->cur_present_index = 0;
1363 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1364 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1365 gst_vaapi_enc_picture_unref (pic);
1367 g_queue_clear (&encoder->reorder_frame_list);
1369 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1372 /* Generate "codec-data" buffer */
1373 static GstVaapiEncoderStatus
1374 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
1375 GstBuffer ** out_buffer_ptr)
1377 GstVaapiEncoderH264 *const encoder =
1378 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1379 const guint32 configuration_version = 0x01;
1380 const guint32 nal_length_size = 4;
1381 guint8 profile_idc, profile_comp, level_idc;
1382 GstMapInfo sps_info, pps_info;
1383 GstBitWriter writer;
1386 if (!encoder->sps_data || !encoder->pps_data)
1387 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1388 if (gst_buffer_get_size (encoder->sps_data) < 4)
1389 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1391 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1392 goto error_map_sps_buffer;
1394 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
1395 goto error_map_pps_buffer;
1397 /* skip sps_data[0], which is the nal_unit_type */
1398 profile_idc = sps_info.data[1];
1399 profile_comp = sps_info.data[2];
1400 level_idc = sps_info.data[3];
1403 gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8);
1404 gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8);
1405 gst_bit_writer_put_bits_uint32 (&writer, profile_idc, 8);
1406 gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8);
1407 gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8);
1408 gst_bit_writer_put_bits_uint32 (&writer, 0x3f, 6); /* 111111 */
1409 gst_bit_writer_put_bits_uint32 (&writer, nal_length_size - 1, 2);
1410 gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /* 111 */
1413 gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* SPS count = 1 */
1414 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
1415 gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16);
1416 gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size);
1419 gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /* PPS count = 1 */
1420 gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16);
1421 gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size);
1423 gst_buffer_unmap (encoder->pps_data, &pps_info);
1424 gst_buffer_unmap (encoder->sps_data, &sps_info);
1426 buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer),
1427 GST_BIT_WRITER_BIT_SIZE (&writer) / 8);
1429 goto error_alloc_buffer;
1430 *out_buffer_ptr = buffer;
1432 gst_bit_writer_clear (&writer, FALSE);
1433 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1436 error_map_sps_buffer:
1438 GST_ERROR ("failed to map SPS packed header");
1439 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1441 error_map_pps_buffer:
1443 GST_ERROR ("failed to map PPS packed header");
1444 gst_buffer_unmap (encoder->sps_data, &sps_info);
1445 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1449 GST_ERROR ("failed to allocate codec-data buffer");
1450 gst_bit_writer_clear (&writer, TRUE);
1451 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1455 static GstVaapiEncoderStatus
1456 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
1457 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1459 GstVaapiEncoderH264 *const encoder =
1460 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1461 GstVaapiEncPicture *picture;
1462 gboolean is_idr = FALSE;
1467 if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1468 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1470 /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1471 dump B frames from queue, sometime, there may also have P frame or I frame */
1472 g_assert (encoder->num_bframes > 0);
1473 g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1474 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1475 picture = g_queue_pop_head (&encoder->reorder_frame_list);
1477 if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1478 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1483 /* new frame coming */
1484 picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1486 GST_WARNING ("create H264 picture failed, frame timestamp:%"
1487 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1488 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1490 ++encoder->cur_present_index;
1491 picture->poc = ((encoder->cur_present_index * 2) %
1492 encoder->max_pic_order_cnt);
1494 is_idr = (encoder->frame_index == 0 ||
1495 encoder->frame_index >= encoder->idr_period);
1497 /* check key frames */
1498 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1499 (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) ==
1501 ++encoder->cur_frame_num;
1502 ++encoder->frame_index;
1504 /* b frame enabled, check queue of reorder_frame_list */
1505 if (encoder->num_bframes
1506 && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1507 GstVaapiEncPicture *p_pic;
1509 p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1510 _set_p_frame (p_pic, encoder);
1511 g_queue_foreach (&encoder->reorder_frame_list,
1512 (GFunc) _set_b_frame, encoder);
1513 ++encoder->cur_frame_num;
1514 _set_key_frame (picture, encoder, is_idr);
1515 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1517 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1518 } else { /* no b frames in queue */
1519 _set_key_frame (picture, encoder, is_idr);
1520 g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1521 if (encoder->num_bframes)
1522 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1527 /* new p/b frames coming */
1528 ++encoder->frame_index;
1529 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1530 g_queue_get_length (&encoder->reorder_frame_list) <
1531 encoder->num_bframes) {
1532 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1533 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1536 ++encoder->cur_frame_num;
1537 _set_p_frame (picture, encoder);
1539 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1540 g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame,
1542 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1543 g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1548 frame = GST_VAAPI_ENC_PICTURE_GET_FRAME (picture);
1549 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1550 frame->pts += encoder->cts_offset;
1553 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1556 static GstVaapiEncoderStatus
1557 set_context_info (GstVaapiEncoder * base_encoder)
1559 GstVaapiEncoderH264 *const encoder =
1560 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1561 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1562 const guint DEFAULT_SURFACES_COUNT = 3;
1564 /* Maximum sizes for common headers (in bits) */
1567 MAX_SPS_HDR_SIZE = 16473,
1568 MAX_VUI_PARAMS_SIZE = 210,
1569 MAX_HRD_PARAMS_SIZE = 4103,
1570 MAX_PPS_HDR_SIZE = 101,
1571 MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1574 if (!ensure_hw_profile (encoder))
1575 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1577 base_encoder->num_ref_frames =
1578 (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1580 /* Only YUV 4:2:0 formats are supported for now. This means that we
1581 have a limit of 3200 bits per macroblock. */
1582 /* XXX: check profile and compute RawMbBits */
1583 base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
1584 GST_ROUND_UP_16 (vip->height) / 256) * 400;
1586 /* Account for SPS header */
1587 /* XXX: exclude scaling lists, MVC/SVC extensions */
1588 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1589 MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1591 /* Account for PPS header */
1592 /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1593 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1595 /* Account for slice header. At most 200 slices are supported */
1596 base_encoder->codedbuf_size += 200 * (4 +
1597 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1599 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1602 static GstVaapiEncoderStatus
1603 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
1605 GstVaapiEncoderH264 *const encoder =
1606 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1608 encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1609 encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1611 if (!ensure_profile_and_level (encoder))
1613 if (!ensure_bitrate (encoder))
1616 reset_properties (encoder);
1617 return set_context_info (base_encoder);
1620 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1624 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
1626 GstVaapiEncoderH264 *const encoder =
1627 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1630 g_queue_init (&encoder->reorder_frame_list);
1631 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1633 /* reference frames */
1634 g_queue_init (&encoder->ref_list);
1635 encoder->max_ref_frames = 0;
1636 encoder->max_reflist0_count = 1;
1637 encoder->max_reflist1_count = 1;
1643 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
1645 /*free private buffers */
1646 GstVaapiEncoderH264 *const encoder =
1647 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1648 GstVaapiEncPicture *pic;
1649 GstVaapiEncoderH264Ref *ref;
1651 gst_buffer_replace (&encoder->sps_data, NULL);
1652 gst_buffer_replace (&encoder->pps_data, NULL);
1654 while (!g_queue_is_empty (&encoder->ref_list)) {
1655 ref = g_queue_pop_head (&encoder->ref_list);
1656 reference_pic_free (encoder, ref);
1658 g_queue_clear (&encoder->ref_list);
1660 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1661 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1662 gst_vaapi_enc_picture_unref (pic);
1664 g_queue_clear (&encoder->reorder_frame_list);
1668 static GstVaapiEncoderStatus
1669 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
1670 gint prop_id, const GValue * value)
1672 GstVaapiEncoderH264 *const encoder =
1673 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1676 case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
1677 encoder->num_bframes = g_value_get_uint (value);
1679 case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
1680 encoder->init_qp = g_value_get_uint (value);
1682 case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
1683 encoder->min_qp = g_value_get_uint (value);
1685 case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
1686 encoder->num_slices = g_value_get_uint (value);
1689 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
1691 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1694 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
1696 static inline const GstVaapiEncoderClass *
1697 gst_vaapi_encoder_h264_class (void)
1699 static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1700 GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1701 .set_property = gst_vaapi_encoder_h264_set_property,
1702 .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1704 return &GstVaapiEncoderH264Class;
1708 * gst_vaapi_encoder_h264_new:
1709 * @display: a #GstVaapiDisplay
1711 * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
1712 * only supported output stream format is "byte-stream" format.
1714 * Return value: the newly allocated #GstVaapiEncoder object
1717 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1719 return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1723 * gst_vaapi_encoder_h264_get_default_properties:
1725 * Determines the set of common and H.264 specific encoder properties.
1726 * The caller owns an extra reference to the resulting array of
1727 * #GstVaapiEncoderPropInfo elements, so it shall be released with
1728 * g_ptr_array_unref() after usage.
1730 * Return value: the set of encoder properties for #GstVaapiEncoderH264,
1731 * or %NULL if an error occurred.
1734 gst_vaapi_encoder_h264_get_default_properties (void)
1736 const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
1739 props = gst_vaapi_encoder_properties_get_default (klass);
1744 * GstVaapiEncoderH264:max-bframes:
1746 * The number of B-frames between I and P.
1748 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1749 GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
1750 g_param_spec_uint ("max-bframes",
1751 "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
1752 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1755 * GstVaapiEncoderH264:init-qp:
1757 * The initial quantizer value.
1759 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1760 GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
1761 g_param_spec_uint ("init-qp",
1762 "Initial QP", "Initial quantizer value", 1, 51, 26,
1763 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1766 * GstVaapiEncoderH264:min-qp:
1768 * The minimum quantizer value.
1770 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1771 GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
1772 g_param_spec_uint ("min-qp",
1773 "Minimum QP", "Minimum quantizer value", 1, 51, 1,
1774 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1777 * GstVaapiEncoderH264:num-slices:
1779 * The number of slices per frame.
1781 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1782 GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
1783 g_param_spec_uint ("num-slices",
1785 "Number of slices per frame",
1786 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1792 * gst_vaapi_encoder_h264_get_profile_and_level:
1793 * @encoder: a #GstVaapiEncoderH264
1794 * @out_profile_ptr: return location for the #GstVaapiProfile
1795 * @out_level_ptr: return location for the #GstVaapiLevelH264
1797 * Queries the H.264 @encoder for the active profile and level. That
1798 * information is only constructed and valid after the encoder is
1799 * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
1800 * function is called.
1802 * Return value: %TRUE on success
1805 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
1806 GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
1808 g_return_val_if_fail (encoder != NULL, FALSE);
1810 if (!encoder->profile || !encoder->level)
1813 if (out_profile_ptr)
1814 *out_profile_ptr = encoder->profile;
1816 *out_level_ptr = encoder->level;