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_priv.h"
28 #include "gstvaapiencoder_h264.h"
29 #include "gstvaapiutils_h264.h"
30 #include "gstvaapiutils_h264_priv.h"
31 #include "gstvaapicodedbufferproxy_priv.h"
32 #include "gstvaapisurface.h"
35 #include "gstvaapidebug.h"
37 /* Define the maximum IDR period */
38 #define MAX_IDR_PERIOD 512
40 /* Define default rate control mode ("constant-qp") */
41 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
43 /* Supported set of VA rate controls, within this implementation */
44 #define SUPPORTED_RATECONTROLS \
45 (GST_VAAPI_RATECONTROL_MASK (NONE) | \
46 GST_VAAPI_RATECONTROL_MASK (CQP) | \
47 GST_VAAPI_RATECONTROL_MASK (CBR) | \
48 GST_VAAPI_RATECONTROL_MASK (VBR) | \
49 GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
51 /* Supported set of tuning options, within this implementation */
52 #define SUPPORTED_TUNE_OPTIONS \
53 (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \
54 GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION))
56 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0
57 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1
58 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2
59 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3
63 GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0,
64 GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1,
65 GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */
66 GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */
67 GST_VAAPI_ENCODER_H264_NAL_SPS = 7,
68 GST_VAAPI_ENCODER_H264_NAL_PPS = 8
69 } GstVaapiEncoderH264NalType;
73 GstVaapiSurfaceProxy *pic;
76 } GstVaapiEncoderH264Ref;
80 GST_VAAPI_ENC_H264_REORD_NONE = 0,
81 GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
82 GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
83 } GstVaapiEncH264ReorderState;
85 static inline gboolean
86 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
88 return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
91 /* Get slice_type value for H.264 specification */
93 h264_get_slice_type (GstVaapiPictureType type)
96 case GST_VAAPI_PICTURE_TYPE_I:
98 case GST_VAAPI_PICTURE_TYPE_P:
100 case GST_VAAPI_PICTURE_TYPE_B:
108 /* Get log2_max_frame_num value for H.264 specification */
110 h264_get_log2_max_frame_num (guint num)
122 /* must be greater than 4 */
126 /* ------------------------------------------------------------------------- */
127 /* --- H.264 Bitstream Writer --- */
128 /* ------------------------------------------------------------------------- */
130 #define WRITE_UINT32(bs, val, nbits) do { \
131 if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \
132 GST_WARNING ("failed to write uint32, nbits: %d", nbits); \
137 #define WRITE_UE(bs, val) do { \
138 if (!bs_write_ue (bs, val)) { \
139 GST_WARNING ("failed to write ue(v)"); \
144 #define WRITE_SE(bs, val) do { \
145 if (!bs_write_se (bs, val)) { \
146 GST_WARNING ("failed to write se(v)"); \
151 /* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */
153 bs_write_ue (GstBitWriter * bs, guint32 value)
155 guint32 size_in_bits = 0;
156 guint32 tmp_value = ++value;
163 && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1))
165 if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits))
170 /* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */
172 bs_write_se (GstBitWriter * bs, gint32 value)
177 new_val = -(value << 1);
179 new_val = (value << 1) - 1;
181 if (!bs_write_ue (bs, new_val))
186 /* Write the NAL unit header */
188 bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc,
189 guint32 nal_unit_type)
191 WRITE_UINT32 (bs, 0, 1);
192 WRITE_UINT32 (bs, nal_ref_idc, 2);
193 WRITE_UINT32 (bs, nal_unit_type, 5);
199 GST_WARNING ("failed to write NAL unit header");
204 /* Write the NAL unit trailing bits */
206 bs_write_trailing_bits (GstBitWriter * bs)
208 if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
210 gst_bit_writer_align_bytes_unchecked (bs, 0);
216 GST_WARNING ("failed to write NAL unit trailing bits");
221 /* Write an SPS NAL unit */
223 bs_write_sps (GstBitWriter * bs,
224 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile)
227 guint32 constraint_set0_flag, constraint_set1_flag;
228 guint32 constraint_set2_flag, constraint_set3_flag;
229 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
230 gboolean nal_hrd_parameters_present_flag;
232 guint32 b_qpprime_y_zero_transform_bypass = 0;
233 guint32 residual_color_transform_flag = 0;
234 guint32 pic_height_in_map_units =
235 (seq_param->seq_fields.bits.frame_mbs_only_flag ?
236 seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
237 guint32 mb_adaptive_frame_field =
238 !seq_param->seq_fields.bits.frame_mbs_only_flag;
241 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
242 constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
243 profile == GST_VAAPI_PROFILE_H264_BASELINE ||
244 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
245 constraint_set1_flag = /* A.2.2 (main profile constraints) */
246 profile == GST_VAAPI_PROFILE_H264_MAIN ||
247 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
248 constraint_set2_flag = 0;
249 constraint_set3_flag = 0;
252 WRITE_UINT32 (bs, profile_idc, 8);
253 /* constraint_set0_flag */
254 WRITE_UINT32 (bs, constraint_set0_flag, 1);
255 /* constraint_set1_flag */
256 WRITE_UINT32 (bs, constraint_set1_flag, 1);
257 /* constraint_set2_flag */
258 WRITE_UINT32 (bs, constraint_set2_flag, 1);
259 /* constraint_set3_flag */
260 WRITE_UINT32 (bs, constraint_set3_flag, 1);
261 /* reserved_zero_4bits */
262 WRITE_UINT32 (bs, 0, 4);
264 WRITE_UINT32 (bs, seq_param->level_idc, 8);
265 /* seq_parameter_set_id */
266 WRITE_UE (bs, seq_param->seq_parameter_set_id);
268 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
269 /* for high profile */
270 /* chroma_format_idc = 1, 4:2:0 */
271 WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
272 if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
273 WRITE_UINT32 (bs, residual_color_transform_flag, 1);
275 /* bit_depth_luma_minus8 */
276 WRITE_UE (bs, seq_param->bit_depth_luma_minus8);
277 /* bit_depth_chroma_minus8 */
278 WRITE_UE (bs, seq_param->bit_depth_chroma_minus8);
279 /* b_qpprime_y_zero_transform_bypass */
280 WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1);
282 /* seq_scaling_matrix_present_flag */
283 g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
285 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
288 if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
290 i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
292 gst_bit_writer_put_bits_uint8 (bs,
293 seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
294 if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
296 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
303 /* log2_max_frame_num_minus4 */
304 WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4);
305 /* pic_order_cnt_type */
306 WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type);
308 if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
309 /* log2_max_pic_order_cnt_lsb_minus4 */
310 WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
311 } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
312 g_assert (0 && "only POC type 0 is supported");
314 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
315 WRITE_SE (bs, seq_param->offset_for_non_ref_pic);
316 WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field);
317 WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle);
318 for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
319 WRITE_SE (bs, seq_param->offset_for_ref_frame[i]);
324 WRITE_UE (bs, seq_param->max_num_ref_frames);
325 /* gaps_in_frame_num_value_allowed_flag */
326 WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1);
328 /* pic_width_in_mbs_minus1 */
329 WRITE_UE (bs, seq_param->picture_width_in_mbs - 1);
330 /* pic_height_in_map_units_minus1 */
331 WRITE_UE (bs, pic_height_in_map_units - 1);
332 /* frame_mbs_only_flag */
333 WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
335 if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
336 g_assert (0 && "only progressive frames encoding is supported");
337 WRITE_UINT32 (bs, mb_adaptive_frame_field, 1);
340 /* direct_8x8_inference_flag */
341 WRITE_UINT32 (bs, 0, 1);
342 /* frame_cropping_flag */
343 WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1);
345 if (seq_param->frame_cropping_flag) {
346 /* frame_crop_left_offset */
347 WRITE_UE (bs, seq_param->frame_crop_left_offset);
348 /* frame_crop_right_offset */
349 WRITE_UE (bs, seq_param->frame_crop_right_offset);
350 /* frame_crop_top_offset */
351 WRITE_UE (bs, seq_param->frame_crop_top_offset);
352 /* frame_crop_bottom_offset */
353 WRITE_UE (bs, seq_param->frame_crop_bottom_offset);
356 /* vui_parameters_present_flag */
357 WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
358 if (seq_param->vui_parameters_present_flag) {
359 /* aspect_ratio_info_present_flag */
361 seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
362 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
363 WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
364 if (seq_param->aspect_ratio_idc == 0xFF) {
365 WRITE_UINT32 (bs, seq_param->sar_width, 16);
366 WRITE_UINT32 (bs, seq_param->sar_height, 16);
370 /* overscan_info_present_flag */
371 WRITE_UINT32 (bs, 0, 1);
372 /* video_signal_type_present_flag */
373 WRITE_UINT32 (bs, 0, 1);
374 /* chroma_loc_info_present_flag */
375 WRITE_UINT32 (bs, 0, 1);
377 /* timing_info_present_flag */
378 WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1);
379 if (seq_param->vui_fields.bits.timing_info_present_flag) {
380 WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32);
381 WRITE_UINT32 (bs, seq_param->time_scale, 32);
382 WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */
385 nal_hrd_parameters_present_flag =
386 (seq_param->bits_per_second > 0 ? TRUE : FALSE);
387 /* nal_hrd_parameters_present_flag */
388 WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
389 if (nal_hrd_parameters_present_flag) {
393 WRITE_UINT32 (bs, 4, 4); /* bit_rate_scale */
394 WRITE_UINT32 (bs, 6, 4); /* cpb_size_scale */
396 for (i = 0; i < 1; ++i) {
397 /* bit_rate_value_minus1[0] */
398 WRITE_UE (bs, seq_param->bits_per_second / 1000 - 1);
399 /* cpb_size_value_minus1[0] */
400 WRITE_UE (bs, seq_param->bits_per_second / 1000 * 8 - 1);
402 WRITE_UINT32 (bs, 1, 1);
404 /* initial_cpb_removal_delay_length_minus1 */
405 WRITE_UINT32 (bs, 23, 5);
406 /* cpb_removal_delay_length_minus1 */
407 WRITE_UINT32 (bs, 23, 5);
408 /* dpb_output_delay_length_minus1 */
409 WRITE_UINT32 (bs, 23, 5);
410 /* time_offset_length */
411 WRITE_UINT32 (bs, 23, 5);
413 /* vcl_hrd_parameters_present_flag */
414 WRITE_UINT32 (bs, 0, 1);
415 if (nal_hrd_parameters_present_flag
416 || 0 /*vcl_hrd_parameters_present_flag */ ) {
417 /* low_delay_hrd_flag */
418 WRITE_UINT32 (bs, 0, 1);
420 /* pic_struct_present_flag */
421 WRITE_UINT32 (bs, 0, 1);
422 /* bs_restriction_flag */
423 WRITE_UINT32 (bs, 0, 1);
426 /* rbsp_trailing_bits */
427 bs_write_trailing_bits (bs);
433 GST_WARNING ("failed to write SPS NAL unit");
438 /* Write a PPS NAL unit */
440 bs_write_pps (GstBitWriter * bs,
441 const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
443 guint32 num_slice_groups_minus1 = 0;
444 guint32 pic_init_qs_minus26 = 0;
445 guint32 redundant_pic_cnt_present_flag = 0;
447 /* pic_parameter_set_id */
448 WRITE_UE (bs, pic_param->pic_parameter_set_id);
449 /* seq_parameter_set_id */
450 WRITE_UE (bs, pic_param->seq_parameter_set_id);
451 /* entropy_coding_mode_flag */
452 WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
453 /* pic_order_present_flag */
454 WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1);
456 WRITE_UE (bs, num_slice_groups_minus1);
458 if (num_slice_groups_minus1 > 0) {
459 /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)");
461 WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1);
462 WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1);
463 WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
464 WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);
465 /* pic_init_qp_minus26 */
466 WRITE_SE (bs, pic_param->pic_init_qp - 26);
467 /* pic_init_qs_minus26 */
468 WRITE_SE (bs, pic_init_qs_minus26);
469 /* chroma_qp_index_offset */
470 WRITE_SE (bs, pic_param->chroma_qp_index_offset);
473 pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
474 WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
475 WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1);
478 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
479 WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
481 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
482 if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
483 g_assert (0 && "unsupported scaling lists");
487 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
489 gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
493 WRITE_SE (bs, pic_param->second_chroma_qp_index_offset);
496 /* rbsp_trailing_bits */
497 bs_write_trailing_bits (bs);
503 GST_WARNING ("failed to write PPS NAL unit");
508 /* ------------------------------------------------------------------------- */
509 /* --- H.264 Encoder --- */
510 /* ------------------------------------------------------------------------- */
512 #define GST_VAAPI_ENCODER_H264_CAST(encoder) \
513 ((GstVaapiEncoderH264 *)(encoder))
515 struct _GstVaapiEncoderH264
517 GstVaapiEncoder parent_instance;
519 GstVaapiProfile profile;
520 GstVaapiLevelH264 level;
522 guint8 max_profile_idc;
523 guint8 hw_max_profile_idc;
536 GQueue reorder_frame_list;
540 guint cur_present_index;
541 GstClockTime cts_offset;
545 guint max_ref_frames;
546 /* max reflist count */
547 guint max_reflist0_count;
548 guint max_reflist1_count;
551 guint32 max_frame_num;
552 guint32 log2_max_frame_num;
553 guint32 max_pic_order_cnt;
554 guint32 log2_max_pic_order_cnt;
562 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
563 const guint8 * nal, guint32 size)
570 if (encoder->sps_data && encoder->pps_data)
573 nal_type = nal[0] & 0x1F;
575 case GST_VAAPI_ENCODER_H264_NAL_SPS:
576 encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
577 ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
578 g_assert (ret == size);
580 case GST_VAAPI_ENCODER_H264_NAL_PPS:
581 encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
582 ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
583 g_assert (ret == size);
590 /* Determines the largest supported profile by the underlying hardware */
592 ensure_hw_profile_limits (GstVaapiEncoderH264 * encoder)
594 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
596 guint i, profile_idc, max_profile_idc;
598 if (encoder->hw_max_profile_idc)
601 profiles = gst_vaapi_display_get_encode_profiles (display);
606 for (i = 0; i < profiles->len; i++) {
607 const GstVaapiProfile profile =
608 g_array_index (profiles, GstVaapiProfile, i);
609 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
612 if (max_profile_idc < profile_idc)
613 max_profile_idc = profile_idc;
615 g_array_unref (profiles);
617 encoder->hw_max_profile_idc = max_profile_idc;
621 /* Derives the profile supported by the underlying hardware */
623 ensure_hw_profile (GstVaapiEncoderH264 * encoder)
625 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
626 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
627 GstVaapiProfile profile, profiles[4];
628 guint i, num_profiles = 0;
630 profiles[num_profiles++] = encoder->profile;
631 switch (encoder->profile) {
632 case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
633 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
634 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
636 case GST_VAAPI_PROFILE_H264_MAIN:
637 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
643 profile = GST_VAAPI_PROFILE_UNKNOWN;
644 for (i = 0; i < num_profiles; i++) {
645 if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
646 profile = profiles[i];
650 if (profile == GST_VAAPI_PROFILE_UNKNOWN)
651 goto error_unsupported_profile;
653 GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
657 error_unsupported_profile:
659 GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
664 /* Check target decoder constraints */
666 ensure_profile_limits (GstVaapiEncoderH264 * encoder)
668 GstVaapiProfile profile;
670 if (!encoder->max_profile_idc
671 || encoder->profile_idc <= encoder->max_profile_idc)
674 GST_WARNING ("lowering coding tools to meet target decoder constraints");
676 /* Try Main profile coding tools */
677 if (encoder->max_profile_idc < 100) {
678 encoder->use_dct8x8 = FALSE;
679 profile = GST_VAAPI_PROFILE_H264_MAIN;
682 /* Try Constrained Baseline profile coding tools */
683 if (encoder->max_profile_idc < 77) {
684 encoder->num_bframes = 0;
685 encoder->use_cabac = FALSE;
686 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
689 encoder->profile = profile;
690 encoder->profile_idc = encoder->max_profile_idc;
694 /* Derives the minimum profile from the active coding tools */
696 ensure_profile (GstVaapiEncoderH264 * encoder)
698 GstVaapiProfile profile;
700 /* Always start from "constrained-baseline" profile for maximum
702 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
704 /* Main profile coding tools */
705 if (encoder->num_bframes > 0 || encoder->use_cabac)
706 profile = GST_VAAPI_PROFILE_H264_MAIN;
708 /* High profile coding tools */
709 if (encoder->use_dct8x8)
710 profile = GST_VAAPI_PROFILE_H264_HIGH;
712 encoder->profile = profile;
713 encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
717 /* Derives the level from the currently set limits */
719 ensure_level (GstVaapiEncoderH264 * encoder)
721 const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
722 const GstVaapiH264LevelLimits *limits_table;
723 guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
725 PicSizeMbs = encoder->mb_width * encoder->mb_height;
726 MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
727 MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
728 GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
730 limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
731 for (i = 0; i < num_limits; i++) {
732 const GstVaapiH264LevelLimits *const limits = &limits_table[i];
733 if (PicSizeMbs <= limits->MaxFS &&
734 MaxDpbMbs <= limits->MaxDpbMbs &&
735 MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR))
739 goto error_unsupported_level;
741 encoder->level = limits_table[i].level;
742 encoder->level_idc = limits_table[i].level_idc;
746 error_unsupported_level:
748 GST_ERROR ("failed to find a suitable level matching codec config");
753 /* Enable "high-compression" tuning options */
755 ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder)
759 if (!ensure_hw_profile_limits (encoder))
762 profile_idc = encoder->hw_max_profile_idc;
763 if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
764 profile_idc = encoder->max_profile_idc;
766 /* Tuning options to enable Main profile */
767 if (profile_idc >= 77) {
768 encoder->use_cabac = TRUE;
769 if (!encoder->num_bframes)
770 encoder->num_bframes = 1;
773 /* Tuning options to enable High profile */
774 if (profile_idc >= 100) {
775 encoder->use_dct8x8 = TRUE;
780 /* Ensure tuning options */
782 ensure_tuning (GstVaapiEncoderH264 * encoder)
786 switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
787 case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
788 success = ensure_tuning_high_compression (encoder);
797 /* Handle new GOP starts */
799 reset_gop_start (GstVaapiEncoderH264 * encoder)
802 encoder->frame_index = 1;
803 encoder->cur_frame_num = 0;
804 encoder->cur_present_index = 0;
807 /* Marks the supplied picture as a B-frame */
809 set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
811 g_assert (pic && encoder);
812 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
813 pic->type = GST_VAAPI_PICTURE_TYPE_B;
814 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
817 /* Marks the supplied picture as a P-frame */
819 set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
821 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
822 pic->type = GST_VAAPI_PICTURE_TYPE_P;
823 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
826 /* Marks the supplied picture as an I-frame */
828 set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
830 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
831 pic->type = GST_VAAPI_PICTURE_TYPE_I;
832 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
834 g_assert (pic->frame);
835 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
838 /* Marks the supplied picture as an IDR frame */
840 set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
842 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
843 pic->type = GST_VAAPI_PICTURE_TYPE_I;
846 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
848 g_assert (pic->frame);
849 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
852 /* Marks the supplied picture a a key-frame */
854 set_key_frame (GstVaapiEncPicture * picture,
855 GstVaapiEncoderH264 * encoder, gboolean is_idr)
858 reset_gop_start (encoder);
859 set_idr_frame (picture, encoder);
861 set_i_frame (picture, encoder);
864 /* Fills in VA HRD parameters */
866 fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd)
868 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
870 if (base_encoder->bitrate > 0) {
871 hrd->buffer_size = base_encoder->bitrate * 1000 * 8;
872 hrd->initial_buffer_fullness = hrd->buffer_size / 2;
874 hrd->buffer_size = 0;
875 hrd->initial_buffer_fullness = 0;
879 /* Adds the supplied sequence header (SPS) to the list of packed
880 headers to pass down as-is to the encoder */
882 add_packed_sequence_header (GstVaapiEncoderH264 * encoder,
883 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
885 GstVaapiEncPackedHeader *packed_seq;
887 VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
888 const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
889 guint32 data_bit_size;
892 gst_bit_writer_init (&bs, 128 * 8);
893 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
894 bs_write_nal_header (&bs,
895 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
896 bs_write_sps (&bs, seq_param, encoder->profile);
897 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
898 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
899 data = GST_BIT_WRITER_DATA (&bs);
901 packed_seq_param.type = VAEncPackedHeaderSequence;
902 packed_seq_param.bit_length = data_bit_size;
903 packed_seq_param.has_emulation_bytes = 0;
905 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
906 &packed_seq_param, sizeof (packed_seq_param),
907 data, (data_bit_size + 7) / 8);
908 g_assert (packed_seq);
910 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
911 gst_vaapi_codec_object_replace (&packed_seq, NULL);
914 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
915 gst_bit_writer_clear (&bs, TRUE);
921 GST_WARNING ("failed to write SPS NAL unit");
922 gst_bit_writer_clear (&bs, TRUE);
927 /* Adds the supplied picture header (PPS) to the list of packed
928 headers to pass down as-is to the encoder */
930 add_packed_picture_header (GstVaapiEncoderH264 * encoder,
931 GstVaapiEncPicture * picture)
933 GstVaapiEncPackedHeader *packed_pic;
935 VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
936 const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
937 guint32 data_bit_size;
940 gst_bit_writer_init (&bs, 128 * 8);
941 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
942 bs_write_nal_header (&bs,
943 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
944 bs_write_pps (&bs, pic_param, encoder->profile);
945 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
946 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
947 data = GST_BIT_WRITER_DATA (&bs);
949 packed_pic_param.type = VAEncPackedHeaderPicture;
950 packed_pic_param.bit_length = data_bit_size;
951 packed_pic_param.has_emulation_bytes = 0;
953 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
954 &packed_pic_param, sizeof (packed_pic_param),
955 data, (data_bit_size + 7) / 8);
956 g_assert (packed_pic);
958 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
959 gst_vaapi_codec_object_replace (&packed_pic, NULL);
962 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
963 gst_bit_writer_clear (&bs, TRUE);
969 GST_WARNING ("failed to write PPS NAL unit");
970 gst_bit_writer_clear (&bs, TRUE);
975 /* Reference picture management */
977 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
982 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
983 g_slice_free (GstVaapiEncoderH264Ref, ref);
986 static inline GstVaapiEncoderH264Ref *
987 reference_pic_create (GstVaapiEncoderH264 * encoder,
988 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
990 GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
993 ref->frame_num = picture->frame_num;
994 ref->poc = picture->poc;
999 reference_list_update (GstVaapiEncoderH264 * encoder,
1000 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1002 GstVaapiEncoderH264Ref *ref;
1004 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
1005 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
1008 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
1009 while (!g_queue_is_empty (&encoder->ref_list))
1010 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
1011 } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) {
1012 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
1014 ref = reference_pic_create (encoder, picture, surface);
1015 g_queue_push_tail (&encoder->ref_list, ref);
1016 g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames);
1021 reference_list_init (GstVaapiEncoderH264 * encoder,
1022 GstVaapiEncPicture * picture,
1023 GstVaapiEncoderH264Ref ** reflist_0,
1024 guint * reflist_0_count,
1025 GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
1027 GstVaapiEncoderH264Ref *tmp;
1028 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
1029 guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1032 *reflist_0_count = 0;
1033 *reflist_1_count = 0;
1034 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
1037 iter = g_queue_peek_tail_link (&encoder->ref_list);
1038 for (; iter; iter = g_list_previous (iter)) {
1039 tmp = (GstVaapiEncoderH264Ref *) iter->data;
1040 g_assert (tmp && tmp->poc != picture->poc);
1041 if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
1042 list_0_start = iter;
1043 list_1_start = g_list_next (iter);
1048 /* order reflist_0 */
1049 g_assert (list_0_start);
1050 iter = list_0_start;
1052 for (; iter; iter = g_list_previous (iter)) {
1053 reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
1056 *reflist_0_count = count;
1058 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1061 /* order reflist_1 */
1063 iter = list_1_start;
1064 for (; iter; iter = g_list_next (iter)) {
1065 reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
1068 *reflist_1_count = count;
1072 /* Fills in VA sequence parameter buffer */
1074 fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence)
1076 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1077 VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1079 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
1080 seq_param->seq_parameter_set_id = 0;
1081 seq_param->level_idc = encoder->level_idc;
1082 seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
1083 seq_param->ip_period = 0; // ?
1084 if (base_encoder->bitrate > 0)
1085 seq_param->bits_per_second = base_encoder->bitrate * 1000;
1087 seq_param->bits_per_second = 0;
1089 seq_param->max_num_ref_frames = encoder->max_ref_frames;
1090 seq_param->picture_width_in_mbs = encoder->mb_width;
1091 seq_param->picture_height_in_mbs = encoder->mb_height;
1093 /*sequence field values */
1094 seq_param->seq_fields.value = 0;
1095 seq_param->seq_fields.bits.chroma_format_idc = 1;
1096 seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
1097 seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
1098 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
1099 /* direct_8x8_inference_flag default false */
1100 seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
1101 g_assert (encoder->log2_max_frame_num >= 4);
1102 seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
1103 encoder->log2_max_frame_num - 4;
1104 /* picture order count */
1105 seq_param->seq_fields.bits.pic_order_cnt_type = 0;
1106 g_assert (encoder->log2_max_pic_order_cnt >= 4);
1107 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
1108 encoder->log2_max_pic_order_cnt - 4;
1110 seq_param->bit_depth_luma_minus8 = 0;
1111 seq_param->bit_depth_chroma_minus8 = 0;
1113 /* not used if pic_order_cnt_type == 0 */
1114 if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
1115 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
1116 seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
1117 seq_param->offset_for_non_ref_pic = 0;
1118 seq_param->offset_for_top_to_bottom_field = 0;
1119 memset (seq_param->offset_for_ref_frame, 0,
1120 sizeof (seq_param->offset_for_ref_frame));
1123 /* frame_cropping_flag */
1124 if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
1125 (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
1126 static const guint SubWidthC[] = { 1, 2, 2, 1 };
1127 static const guint SubHeightC[] = { 1, 2, 1, 1 };
1128 const guint CropUnitX =
1129 SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
1130 const guint CropUnitY =
1131 SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
1132 (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
1134 seq_param->frame_cropping_flag = 1;
1135 seq_param->frame_crop_left_offset = 0;
1136 seq_param->frame_crop_right_offset =
1137 (16 * encoder->mb_width -
1138 GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX;
1139 seq_param->frame_crop_top_offset = 0;
1140 seq_param->frame_crop_bottom_offset =
1141 (16 * encoder->mb_height -
1142 GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY;
1145 /* VUI parameters are always set, at least for timing_info (framerate) */
1146 seq_param->vui_parameters_present_flag = TRUE;
1147 if (seq_param->vui_parameters_present_flag) {
1148 seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
1149 seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1150 seq_param->vui_fields.bits.timing_info_present_flag = TRUE;
1151 if (seq_param->vui_fields.bits.timing_info_present_flag) {
1152 seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1153 seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
1159 /* Fills in VA picture parameter buffer */
1161 fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1162 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1164 VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1165 GstVaapiEncoderH264Ref *ref_pic;
1169 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
1171 /* reference list, */
1172 pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1173 pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
1175 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1176 for (reflist = g_queue_peek_head_link (&encoder->ref_list);
1177 reflist; reflist = g_list_next (reflist)) {
1178 ref_pic = reflist->data;
1179 g_assert (ref_pic && ref_pic->pic &&
1180 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1182 pic_param->ReferenceFrames[i].picture_id =
1183 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1186 g_assert (i <= 16 && i <= encoder->max_ref_frames);
1188 for (; i < 16; ++i) {
1189 pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
1191 pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1193 pic_param->pic_parameter_set_id = 0;
1194 pic_param->seq_parameter_set_id = 0;
1195 pic_param->last_picture = 0; /* means last encoding picture */
1196 pic_param->frame_num = picture->frame_num;
1197 pic_param->pic_init_qp = encoder->init_qp;
1198 pic_param->num_ref_idx_l0_active_minus1 =
1199 (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
1200 pic_param->num_ref_idx_l1_active_minus1 =
1201 (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
1202 pic_param->chroma_qp_index_offset = 0;
1203 pic_param->second_chroma_qp_index_offset = 0;
1205 /* set picture fields */
1206 pic_param->pic_fields.value = 0;
1207 pic_param->pic_fields.bits.idr_pic_flag =
1208 GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1209 pic_param->pic_fields.bits.reference_pic_flag =
1210 (picture->type != GST_VAAPI_PICTURE_TYPE_B);
1211 pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
1212 pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
1213 pic_param->pic_fields.bits.weighted_bipred_idc = 0;
1214 pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
1215 pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
1216 /* enable debloking */
1217 pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
1218 pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
1219 /* bottom_field_pic_order_in_frame_present_flag */
1220 pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
1221 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
1226 /* Adds slice headers to picture */
1228 add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1229 GstVaapiEncoderH264Ref ** reflist_0, guint reflist_0_count,
1230 GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
1232 VAEncSliceParameterBufferH264 *slice_param;
1233 GstVaapiEncSlice *slice;
1234 guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
1236 guint last_mb_index;
1237 guint i_slice, i_ref;
1241 mb_size = encoder->mb_width * encoder->mb_height;
1243 g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1244 slice_of_mbs = mb_size / encoder->num_slices;
1245 slice_mod_mbs = mb_size % encoder->num_slices;
1247 for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1248 cur_slice_mbs = slice_of_mbs;
1249 if (slice_mod_mbs) {
1253 slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1254 g_assert (slice && slice->param_id != VA_INVALID_ID);
1255 slice_param = slice->param;
1257 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1258 slice_param->macroblock_address = last_mb_index;
1259 slice_param->num_macroblocks = cur_slice_mbs;
1260 slice_param->macroblock_info = VA_INVALID_ID;
1261 slice_param->slice_type = h264_get_slice_type (picture->type);
1262 g_assert (slice_param->slice_type != -1);
1263 slice_param->pic_parameter_set_id = 0;
1264 slice_param->idr_pic_id = encoder->idr_num;
1265 slice_param->pic_order_cnt_lsb = picture->poc;
1267 /* not used if pic_order_cnt_type = 0 */
1268 slice_param->delta_pic_order_cnt_bottom = 0;
1269 memset (slice_param->delta_pic_order_cnt, 0,
1270 sizeof (slice_param->delta_pic_order_cnt));
1272 /* only works for B frames */
1273 slice_param->direct_spatial_mv_pred_flag = FALSE;
1274 /* default equal to picture parameters */
1275 slice_param->num_ref_idx_active_override_flag = FALSE;
1276 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1277 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1279 slice_param->num_ref_idx_l0_active_minus1 = 0;
1280 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1281 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1283 slice_param->num_ref_idx_l1_active_minus1 = 0;
1284 g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1285 g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1288 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1289 for (; i_ref < reflist_0_count; ++i_ref) {
1290 slice_param->RefPicList0[i_ref].picture_id =
1291 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1293 g_assert (i_ref == 1);
1295 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1296 slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1300 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1301 for (; i_ref < reflist_1_count; ++i_ref) {
1302 slice_param->RefPicList1[i_ref].picture_id =
1303 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1305 g_assert (i_ref == 1);
1307 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1308 slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1311 /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1312 slice_param->luma_log2_weight_denom = 0;
1313 slice_param->chroma_log2_weight_denom = 0;
1314 slice_param->luma_weight_l0_flag = FALSE;
1315 memset (slice_param->luma_weight_l0, 0,
1316 sizeof (slice_param->luma_weight_l0));
1317 memset (slice_param->luma_offset_l0, 0,
1318 sizeof (slice_param->luma_offset_l0));
1319 slice_param->chroma_weight_l0_flag = FALSE;
1320 memset (slice_param->chroma_weight_l0, 0,
1321 sizeof (slice_param->chroma_weight_l0));
1322 memset (slice_param->chroma_offset_l0, 0,
1323 sizeof (slice_param->chroma_offset_l0));
1324 slice_param->luma_weight_l1_flag = FALSE;
1325 memset (slice_param->luma_weight_l1, 0,
1326 sizeof (slice_param->luma_weight_l1));
1327 memset (slice_param->luma_offset_l1, 0,
1328 sizeof (slice_param->luma_offset_l1));
1329 slice_param->chroma_weight_l1_flag = FALSE;
1330 memset (slice_param->chroma_weight_l1, 0,
1331 sizeof (slice_param->chroma_weight_l1));
1332 memset (slice_param->chroma_offset_l1, 0,
1333 sizeof (slice_param->chroma_offset_l1));
1335 slice_param->cabac_init_idc = 0;
1336 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1337 if (slice_param->slice_qp_delta > 4)
1338 slice_param->slice_qp_delta = 4;
1339 slice_param->disable_deblocking_filter_idc = 0;
1340 slice_param->slice_alpha_c0_offset_div2 = 2;
1341 slice_param->slice_beta_offset_div2 = 2;
1343 /* set calculation for next slice */
1344 last_mb_index += cur_slice_mbs;
1346 gst_vaapi_enc_picture_add_slice (picture, slice);
1347 gst_vaapi_codec_object_replace (&slice, NULL);
1349 g_assert (last_mb_index == mb_size);
1353 /* Generates and submits SPS header accordingly into the bitstream */
1355 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1357 GstVaapiEncSequence *sequence;
1360 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1361 g_assert (sequence);
1365 if (!fill_sequence (encoder, sequence))
1368 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1369 !add_packed_sequence_header (encoder, picture, sequence))
1371 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1372 gst_vaapi_codec_object_replace (&sequence, NULL);
1376 gst_vaapi_codec_object_replace (&sequence, NULL);
1380 /* Generates additional control parameters */
1382 ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1384 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1385 GstVaapiEncMiscParam *misc = NULL;
1386 VAEncMiscParameterRateControl *rate_control;
1389 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1393 fill_hrd_params (encoder, misc->data);
1394 gst_vaapi_enc_picture_add_misc_param (picture, misc);
1395 gst_vaapi_codec_object_replace (&misc, NULL);
1397 /* RateControl params */
1398 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1399 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1400 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1404 rate_control = misc->data;
1405 memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1406 if (base_encoder->bitrate)
1407 rate_control->bits_per_second = base_encoder->bitrate * 1000;
1409 rate_control->bits_per_second = 0;
1410 rate_control->target_percentage = 70;
1411 rate_control->window_size = 500;
1412 rate_control->initial_qp = encoder->init_qp;
1413 rate_control->min_qp = encoder->min_qp;
1414 rate_control->basic_unit_size = 0;
1415 gst_vaapi_enc_picture_add_misc_param (picture, misc);
1416 gst_vaapi_codec_object_replace (&misc, NULL);
1421 /* Generates and submits PPS header accordingly into the bitstream */
1423 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1424 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1426 GstVaapiCodedBuffer *const codedbuf =
1427 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1429 if (!fill_picture (encoder, picture, codedbuf, surface))
1432 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1433 !add_packed_picture_header (encoder, picture)) {
1434 GST_ERROR ("set picture packed header failed");
1440 /* Generates slice headers */
1442 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1444 GstVaapiEncoderH264Ref *reflist_0[16];
1445 GstVaapiEncoderH264Ref *reflist_1[16];
1446 guint reflist_0_count = 0, reflist_1_count = 0;
1450 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1451 !reference_list_init (encoder, picture,
1452 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1453 GST_ERROR ("reference list reorder failed");
1457 g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames);
1458 if (reflist_0_count > encoder->max_reflist0_count)
1459 reflist_0_count = encoder->max_reflist0_count;
1460 if (reflist_1_count > encoder->max_reflist1_count)
1461 reflist_1_count = encoder->max_reflist1_count;
1463 if (!add_slice_headers (encoder, picture,
1464 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1470 /* Estimates a good enough bitrate if none was supplied */
1472 ensure_bitrate (GstVaapiEncoderH264 * encoder)
1474 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1476 /* Default compression: 48 bits per macroblock in "high-compression" mode */
1477 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1478 case GST_VAAPI_RATECONTROL_CBR:
1479 case GST_VAAPI_RATECONTROL_VBR:
1480 case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
1481 if (!base_encoder->bitrate) {
1482 /* According to the literature and testing, CABAC entropy coding
1483 mode could provide for +10% to +18% improvement in general,
1484 thus estimating +15% here ; and using adaptive 8x8 transforms
1485 in I-frames could bring up to +10% improvement. */
1486 guint bits_per_mb = 48;
1487 if (!encoder->use_cabac)
1488 bits_per_mb += (bits_per_mb * 15) / 100;
1489 if (!encoder->use_dct8x8)
1490 bits_per_mb += (bits_per_mb * 10) / 100;
1492 base_encoder->bitrate =
1493 encoder->mb_width * encoder->mb_height * bits_per_mb *
1494 GST_VAAPI_ENCODER_FPS_N (encoder) /
1495 GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
1496 GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
1500 base_encoder->bitrate = 0;
1505 /* Constructs profile and level information based on user-defined limits */
1506 static GstVaapiEncoderStatus
1507 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
1509 ensure_tuning (encoder);
1511 if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
1512 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1514 /* Check HW constraints */
1515 if (!ensure_hw_profile_limits (encoder))
1516 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1517 if (encoder->profile_idc > encoder->hw_max_profile_idc)
1518 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1520 /* Ensure bitrate if not set already and derive the right level to use */
1521 ensure_bitrate (encoder);
1522 if (!ensure_level (encoder))
1523 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1524 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1528 reset_properties (GstVaapiEncoderH264 * encoder)
1530 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1533 if (encoder->idr_period < base_encoder->keyframe_period)
1534 encoder->idr_period = base_encoder->keyframe_period;
1535 if (encoder->idr_period > MAX_IDR_PERIOD)
1536 encoder->idr_period = MAX_IDR_PERIOD;
1538 if (encoder->min_qp > encoder->init_qp ||
1539 (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
1540 encoder->min_qp < encoder->init_qp))
1541 encoder->min_qp = encoder->init_qp;
1543 mb_size = encoder->mb_width * encoder->mb_height;
1544 if (encoder->num_slices > (mb_size + 1) / 2)
1545 encoder->num_slices = (mb_size + 1) / 2;
1546 g_assert (encoder->num_slices);
1548 if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
1549 encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
1551 if (encoder->num_bframes)
1552 encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1553 GST_VAAPI_ENCODER_FPS_N (encoder);
1555 encoder->cts_offset = 0;
1557 /* init max_frame_num, max_poc */
1558 encoder->log2_max_frame_num =
1559 h264_get_log2_max_frame_num (encoder->idr_period);
1560 g_assert (encoder->log2_max_frame_num >= 4);
1561 encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1562 encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1563 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1565 encoder->frame_index = 0;
1566 encoder->idr_num = 0;
1567 encoder->max_reflist0_count = 1;
1568 encoder->max_reflist1_count = encoder->num_bframes > 0;
1569 encoder->max_ref_frames =
1570 encoder->max_reflist0_count + encoder->max_reflist1_count;
1573 static GstVaapiEncoderStatus
1574 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
1575 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1577 GstVaapiEncoderH264 *const encoder =
1578 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1579 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1580 GstVaapiSurfaceProxy *reconstruct = NULL;
1582 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
1584 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1586 if (!ensure_sequence (encoder, picture))
1588 if (!ensure_misc_params (encoder, picture))
1590 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1592 if (!ensure_slices (encoder, picture))
1594 if (!gst_vaapi_enc_picture_encode (picture))
1597 if (!reference_list_update (encoder, picture, reconstruct))
1600 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1603 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1608 static GstVaapiEncoderStatus
1609 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
1611 GstVaapiEncoderH264 *const encoder =
1612 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1613 GstVaapiEncPicture *pic;
1615 encoder->frame_index = 0;
1616 encoder->cur_frame_num = 0;
1617 encoder->cur_present_index = 0;
1618 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1619 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1620 gst_vaapi_enc_picture_unref (pic);
1622 g_queue_clear (&encoder->reorder_frame_list);
1624 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1627 /* Generate "codec-data" buffer */
1628 static GstVaapiEncoderStatus
1629 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
1630 GstBuffer ** out_buffer_ptr)
1632 GstVaapiEncoderH264 *const encoder =
1633 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1634 const guint32 configuration_version = 0x01;
1635 const guint32 nal_length_size = 4;
1636 guint8 profile_idc, profile_comp, level_idc;
1637 GstMapInfo sps_info, pps_info;
1641 if (!encoder->sps_data || !encoder->pps_data)
1642 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1643 if (gst_buffer_get_size (encoder->sps_data) < 4)
1644 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1646 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1647 goto error_map_sps_buffer;
1649 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
1650 goto error_map_pps_buffer;
1652 /* skip sps_data[0], which is the nal_unit_type */
1653 profile_idc = sps_info.data[1];
1654 profile_comp = sps_info.data[2];
1655 level_idc = sps_info.data[3];
1658 gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8);
1659 WRITE_UINT32 (&bs, configuration_version, 8);
1660 WRITE_UINT32 (&bs, profile_idc, 8);
1661 WRITE_UINT32 (&bs, profile_comp, 8);
1662 WRITE_UINT32 (&bs, level_idc, 8);
1663 WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */
1664 WRITE_UINT32 (&bs, nal_length_size - 1, 2);
1665 WRITE_UINT32 (&bs, 0x07, 3); /* 111 */
1668 WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */
1669 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1670 WRITE_UINT32 (&bs, sps_info.size, 16);
1671 gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size);
1674 WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */
1675 WRITE_UINT32 (&bs, pps_info.size, 16);
1676 gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size);
1678 gst_buffer_unmap (encoder->pps_data, &pps_info);
1679 gst_buffer_unmap (encoder->sps_data, &sps_info);
1681 buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs),
1682 GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
1684 goto error_alloc_buffer;
1685 *out_buffer_ptr = buffer;
1687 gst_bit_writer_clear (&bs, FALSE);
1688 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1693 GST_ERROR ("failed to write codec-data");
1694 gst_buffer_unmap (encoder->sps_data, &sps_info);
1695 gst_buffer_unmap (encoder->pps_data, &pps_info);
1696 gst_bit_writer_clear (&bs, TRUE);
1699 error_map_sps_buffer:
1701 GST_ERROR ("failed to map SPS packed header");
1702 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1704 error_map_pps_buffer:
1706 GST_ERROR ("failed to map PPS packed header");
1707 gst_buffer_unmap (encoder->sps_data, &sps_info);
1708 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1712 GST_ERROR ("failed to allocate codec-data buffer");
1713 gst_bit_writer_clear (&bs, TRUE);
1714 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1718 static GstVaapiEncoderStatus
1719 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
1720 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1722 GstVaapiEncoderH264 *const encoder =
1723 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1724 GstVaapiEncPicture *picture;
1725 gboolean is_idr = FALSE;
1730 if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1731 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1733 /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1734 dump B frames from queue, sometime, there may also have P frame or I frame */
1735 g_assert (encoder->num_bframes > 0);
1736 g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1737 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1738 picture = g_queue_pop_head (&encoder->reorder_frame_list);
1740 if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1741 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1746 /* new frame coming */
1747 picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1749 GST_WARNING ("create H264 picture failed, frame timestamp:%"
1750 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1751 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1753 ++encoder->cur_present_index;
1754 picture->poc = ((encoder->cur_present_index * 2) %
1755 encoder->max_pic_order_cnt);
1757 is_idr = (encoder->frame_index == 0 ||
1758 encoder->frame_index >= encoder->idr_period);
1760 /* check key frames */
1761 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1762 (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) ==
1764 ++encoder->cur_frame_num;
1765 ++encoder->frame_index;
1767 /* b frame enabled, check queue of reorder_frame_list */
1768 if (encoder->num_bframes
1769 && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1770 GstVaapiEncPicture *p_pic;
1772 p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1773 set_p_frame (p_pic, encoder);
1774 g_queue_foreach (&encoder->reorder_frame_list,
1775 (GFunc) set_b_frame, encoder);
1776 ++encoder->cur_frame_num;
1777 set_key_frame (picture, encoder, is_idr);
1778 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1780 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1781 } else { /* no b frames in queue */
1782 set_key_frame (picture, encoder, is_idr);
1783 g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1784 if (encoder->num_bframes)
1785 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1790 /* new p/b frames coming */
1791 ++encoder->frame_index;
1792 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1793 g_queue_get_length (&encoder->reorder_frame_list) <
1794 encoder->num_bframes) {
1795 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1796 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1799 ++encoder->cur_frame_num;
1800 set_p_frame (picture, encoder);
1802 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1803 g_queue_foreach (&encoder->reorder_frame_list, (GFunc) set_b_frame,
1805 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1806 g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1811 frame = picture->frame;
1812 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1813 frame->pts += encoder->cts_offset;
1816 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1819 static GstVaapiEncoderStatus
1820 set_context_info (GstVaapiEncoder * base_encoder)
1822 GstVaapiEncoderH264 *const encoder =
1823 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1824 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1825 const guint DEFAULT_SURFACES_COUNT = 3;
1827 /* Maximum sizes for common headers (in bits) */
1830 MAX_SPS_HDR_SIZE = 16473,
1831 MAX_VUI_PARAMS_SIZE = 210,
1832 MAX_HRD_PARAMS_SIZE = 4103,
1833 MAX_PPS_HDR_SIZE = 101,
1834 MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1837 if (!ensure_hw_profile (encoder))
1838 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1840 base_encoder->num_ref_frames =
1841 (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1843 /* Only YUV 4:2:0 formats are supported for now. This means that we
1844 have a limit of 3200 bits per macroblock. */
1845 /* XXX: check profile and compute RawMbBits */
1846 base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
1847 GST_ROUND_UP_16 (vip->height) / 256) * 400;
1849 /* Account for SPS header */
1850 /* XXX: exclude scaling lists, MVC/SVC extensions */
1851 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1852 MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1854 /* Account for PPS header */
1855 /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1856 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1858 /* Account for slice header */
1859 base_encoder->codedbuf_size += encoder->num_slices * (4 +
1860 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1862 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1865 static GstVaapiEncoderStatus
1866 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
1868 GstVaapiEncoderH264 *const encoder =
1869 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1870 GstVaapiEncoderStatus status;
1872 encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1873 encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1875 status = ensure_profile_and_level (encoder);
1876 if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
1879 reset_properties (encoder);
1880 return set_context_info (base_encoder);
1884 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
1886 GstVaapiEncoderH264 *const encoder =
1887 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1890 g_queue_init (&encoder->reorder_frame_list);
1891 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1893 /* reference frames */
1894 g_queue_init (&encoder->ref_list);
1895 encoder->max_ref_frames = 0;
1896 encoder->max_reflist0_count = 1;
1897 encoder->max_reflist1_count = 1;
1903 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
1905 /*free private buffers */
1906 GstVaapiEncoderH264 *const encoder =
1907 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1908 GstVaapiEncPicture *pic;
1909 GstVaapiEncoderH264Ref *ref;
1911 gst_buffer_replace (&encoder->sps_data, NULL);
1912 gst_buffer_replace (&encoder->pps_data, NULL);
1914 while (!g_queue_is_empty (&encoder->ref_list)) {
1915 ref = g_queue_pop_head (&encoder->ref_list);
1916 reference_pic_free (encoder, ref);
1918 g_queue_clear (&encoder->ref_list);
1920 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1921 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1922 gst_vaapi_enc_picture_unref (pic);
1924 g_queue_clear (&encoder->reorder_frame_list);
1928 static GstVaapiEncoderStatus
1929 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
1930 gint prop_id, const GValue * value)
1932 GstVaapiEncoderH264 *const encoder =
1933 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1936 case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
1937 encoder->num_bframes = g_value_get_uint (value);
1939 case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
1940 encoder->init_qp = g_value_get_uint (value);
1942 case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
1943 encoder->min_qp = g_value_get_uint (value);
1945 case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
1946 encoder->num_slices = g_value_get_uint (value);
1948 case GST_VAAPI_ENCODER_H264_PROP_CABAC:
1949 encoder->use_cabac = g_value_get_boolean (value);
1951 case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
1952 encoder->use_dct8x8 = g_value_get_boolean (value);
1955 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
1957 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1960 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
1962 static inline const GstVaapiEncoderClass *
1963 gst_vaapi_encoder_h264_class (void)
1965 static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1966 GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1967 .set_property = gst_vaapi_encoder_h264_set_property,
1968 .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1970 return &GstVaapiEncoderH264Class;
1974 * gst_vaapi_encoder_h264_new:
1975 * @display: a #GstVaapiDisplay
1977 * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
1978 * only supported output stream format is "byte-stream" format.
1980 * Return value: the newly allocated #GstVaapiEncoder object
1983 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1985 return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1989 * gst_vaapi_encoder_h264_get_default_properties:
1991 * Determines the set of common and H.264 specific encoder properties.
1992 * The caller owns an extra reference to the resulting array of
1993 * #GstVaapiEncoderPropInfo elements, so it shall be released with
1994 * g_ptr_array_unref() after usage.
1996 * Return value: the set of encoder properties for #GstVaapiEncoderH264,
1997 * or %NULL if an error occurred.
2000 gst_vaapi_encoder_h264_get_default_properties (void)
2002 const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
2005 props = gst_vaapi_encoder_properties_get_default (klass);
2010 * GstVaapiEncoderH264:max-bframes:
2012 * The number of B-frames between I and P.
2014 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2015 GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
2016 g_param_spec_uint ("max-bframes",
2017 "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
2018 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2021 * GstVaapiEncoderH264:init-qp:
2023 * The initial quantizer value.
2025 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2026 GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
2027 g_param_spec_uint ("init-qp",
2028 "Initial QP", "Initial quantizer value", 1, 51, 26,
2029 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2032 * GstVaapiEncoderH264:min-qp:
2034 * The minimum quantizer value.
2036 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2037 GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
2038 g_param_spec_uint ("min-qp",
2039 "Minimum QP", "Minimum quantizer value", 1, 51, 1,
2040 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2043 * GstVaapiEncoderH264:num-slices:
2045 * The number of slices per frame.
2047 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2048 GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
2049 g_param_spec_uint ("num-slices",
2051 "Number of slices per frame",
2052 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2055 * GstVaapiEncoderH264:cabac:
2057 * Enable CABAC entropy coding mode for improved compression ratio,
2058 * at the expense that the minimum target profile is Main. Default
2059 * is CAVLC entropy coding mode.
2061 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2062 GST_VAAPI_ENCODER_H264_PROP_CABAC,
2063 g_param_spec_boolean ("cabac",
2065 "Enable CABAC entropy coding mode",
2066 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2069 * GstVaapiEncoderH264:dct8x8:
2071 * Enable adaptive use of 8x8 transforms in I-frames. This improves
2072 * the compression ratio by the minimum target profile is High.
2073 * Default is to use 4x4 DCT only.
2075 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2076 GST_VAAPI_ENCODER_H264_PROP_DCT8X8,
2077 g_param_spec_boolean ("dct8x8",
2079 "Enable adaptive use of 8x8 transforms in I-frames",
2080 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2086 * gst_vaapi_encoder_h264_set_max_profile:
2087 * @encoder: a #GstVaapiEncoderH264
2088 * @profile: an H.264 #GstVaapiProfile
2090 * Notifies the @encoder to use coding tools from the supplied
2093 * This means that if the minimal profile derived to
2094 * support the specified coding tools is greater than this @profile,
2095 * then an error is returned when the @encoder is configured.
2097 * Return value: %TRUE on success
2100 gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
2101 GstVaapiProfile profile)
2105 g_return_val_if_fail (encoder != NULL, FALSE);
2106 g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
2108 if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
2111 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
2115 encoder->max_profile_idc = profile_idc;
2120 * gst_vaapi_encoder_h264_get_profile_and_level:
2121 * @encoder: a #GstVaapiEncoderH264
2122 * @out_profile_ptr: return location for the #GstVaapiProfile
2123 * @out_level_ptr: return location for the #GstVaapiLevelH264
2125 * Queries the H.264 @encoder for the active profile and level. That
2126 * information is only constructed and valid after the encoder is
2127 * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
2128 * function is called.
2130 * Return value: %TRUE on success
2133 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
2134 GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
2136 g_return_val_if_fail (encoder != NULL, FALSE);
2138 if (!encoder->profile || !encoder->level)
2141 if (out_profile_ptr)
2142 *out_profile_ptr = encoder->profile;
2144 *out_level_ptr = encoder->level;