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) | \
50 GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION))
52 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0
53 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1
54 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2
55 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3
59 GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0,
60 GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1,
61 GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */
62 GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */
63 GST_VAAPI_ENCODER_H264_NAL_SPS = 7,
64 GST_VAAPI_ENCODER_H264_NAL_PPS = 8
65 } GstVaapiEncoderH264NalType;
76 GstVaapiSurfaceProxy *pic;
79 } GstVaapiEncoderH264Ref;
83 GST_VAAPI_ENC_H264_REORD_NONE = 0,
84 GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
85 GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
86 } GstVaapiEncH264ReorderState;
88 static inline gboolean
89 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
91 return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
94 /* Get slice_type value for H.264 specification */
96 h264_get_slice_type (GstVaapiPictureType type)
99 case GST_VAAPI_PICTURE_TYPE_I:
101 case GST_VAAPI_PICTURE_TYPE_P:
103 case GST_VAAPI_PICTURE_TYPE_B:
111 /* Get log2_max_frame_num value for H.264 specification */
113 h264_get_log2_max_frame_num (guint num)
125 /* must greater than 4 */
130 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
131 const guint8 * nal, guint32 size)
138 if (encoder->sps_data && encoder->pps_data)
141 nal_type = nal[0] & 0x1F;
143 case GST_VAAPI_ENCODER_H264_NAL_SPS:
144 encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
145 ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
146 g_assert (ret == size);
148 case GST_VAAPI_ENCODER_H264_NAL_PPS:
149 encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
150 ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
151 g_assert (ret == size);
158 /* Determines the largest supported profile by the underlying hardware */
160 ensure_hw_profile_limits (GstVaapiEncoderH264 * encoder)
162 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
164 guint i, profile_idc, max_profile_idc;
166 if (encoder->hw_max_profile_idc)
169 profiles = gst_vaapi_display_get_encode_profiles (display);
174 for (i = 0; i < profiles->len; i++) {
175 const GstVaapiProfile profile =
176 g_array_index (profiles, GstVaapiProfile, i);
177 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
180 if (max_profile_idc < profile_idc)
181 max_profile_idc = profile_idc;
183 g_array_unref (profiles);
185 encoder->hw_max_profile_idc = max_profile_idc;
189 /* Derives the profile supported by the underlying hardware */
191 ensure_hw_profile (GstVaapiEncoderH264 * encoder)
193 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
194 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
195 GstVaapiProfile profile, profiles[4];
196 guint i, num_profiles = 0;
198 profiles[num_profiles++] = encoder->profile;
199 switch (encoder->profile) {
200 case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
201 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
202 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
204 case GST_VAAPI_PROFILE_H264_MAIN:
205 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
211 profile = GST_VAAPI_PROFILE_UNKNOWN;
212 for (i = 0; i < num_profiles; i++) {
213 if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
214 profile = profiles[i];
218 if (profile == GST_VAAPI_PROFILE_UNKNOWN)
219 goto error_unsupported_profile;
221 GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
225 error_unsupported_profile:
227 GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
232 /* Check target decoder constraints */
234 ensure_profile_limits (GstVaapiEncoderH264 * encoder)
236 GstVaapiProfile profile;
238 if (!encoder->max_profile_idc
239 || encoder->profile_idc <= encoder->max_profile_idc)
242 GST_WARNING ("lowering coding tools to meet target decoder constraints");
244 /* Try Main profile coding tools */
245 if (encoder->max_profile_idc < 100) {
246 encoder->use_dct8x8 = FALSE;
247 profile = GST_VAAPI_PROFILE_H264_MAIN;
250 /* Try Constrained Baseline profile coding tools */
251 if (encoder->max_profile_idc < 77) {
252 encoder->num_bframes = 0;
253 encoder->use_cabac = FALSE;
254 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
257 encoder->profile = profile;
258 encoder->profile_idc = encoder->max_profile_idc;
262 /* Derives the minimum profile from the active coding tools */
264 ensure_profile (GstVaapiEncoderH264 * encoder)
266 GstVaapiProfile profile;
268 /* Always start from "constrained-baseline" profile for maximum
270 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
272 /* Main profile coding tools */
273 if (encoder->num_bframes > 0 || encoder->use_cabac)
274 profile = GST_VAAPI_PROFILE_H264_MAIN;
276 /* High profile coding tools */
277 if (encoder->use_dct8x8)
278 profile = GST_VAAPI_PROFILE_H264_HIGH;
280 encoder->profile = profile;
281 encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
286 ensure_level (GstVaapiEncoderH264 * encoder)
288 const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
289 const GstVaapiH264LevelLimits *limits_table;
290 guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
292 PicSizeMbs = encoder->mb_width * encoder->mb_height;
293 MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
294 MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
295 GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
297 limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
298 for (i = 0; i < num_limits; i++) {
299 const GstVaapiH264LevelLimits *const limits = &limits_table[i];
300 if (PicSizeMbs <= limits->MaxFS &&
301 MaxDpbMbs <= limits->MaxDpbMbs &&
302 MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR))
306 goto error_unsupported_level;
308 encoder->level = limits_table[i].level;
309 encoder->level_idc = limits_table[i].level_idc;
313 error_unsupported_level:
315 GST_ERROR ("failed to find a suitable level matching codec config");
320 /* Enable "high-compression" tuning options */
322 ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder)
326 if (!ensure_hw_profile_limits (encoder))
329 profile_idc = encoder->hw_max_profile_idc;
330 if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
331 profile_idc = encoder->max_profile_idc;
333 /* Tuning options to enable Main profile */
334 if (profile_idc >= 77) {
335 encoder->use_cabac = TRUE;
336 if (!encoder->num_bframes)
337 encoder->num_bframes = 1;
340 /* Tuning options to enable High profile */
341 if (profile_idc >= 100) {
342 encoder->use_dct8x8 = TRUE;
347 /* Ensure tuning options */
349 ensure_tuning (GstVaapiEncoderH264 * encoder)
353 switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
354 case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
355 success = ensure_tuning_high_compression (encoder);
365 _reset_gop_start (GstVaapiEncoderH264 * encoder)
368 encoder->frame_index = 1;
369 encoder->cur_frame_num = 0;
370 encoder->cur_present_index = 0;
374 _set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
376 g_assert (pic && encoder);
377 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
378 pic->type = GST_VAAPI_PICTURE_TYPE_B;
379 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
383 _set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
385 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
386 pic->type = GST_VAAPI_PICTURE_TYPE_P;
387 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
391 _set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
393 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
394 pic->type = GST_VAAPI_PICTURE_TYPE_I;
395 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
397 g_assert (pic->frame);
398 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
402 _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
404 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
405 pic->type = GST_VAAPI_PICTURE_TYPE_I;
408 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
410 g_assert (pic->frame);
411 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
415 _set_key_frame (GstVaapiEncPicture * picture,
416 GstVaapiEncoderH264 * encoder, gboolean is_idr)
419 _reset_gop_start (encoder);
420 _set_idr_frame (picture, encoder);
422 _set_i_frame (picture, encoder);
426 gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value)
428 guint32 size_in_bits = 0;
429 guint32 tmp_value = ++value;
436 && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1))
438 if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits))
444 gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value)
449 new_val = -(value << 1);
451 new_val = (value << 1) - 1;
453 if (!gst_bit_writer_put_ue (bitwriter, new_val))
460 gst_bit_writer_write_nal_header (GstBitWriter * bitwriter,
461 guint32 nal_ref_idc, guint32 nal_unit_type)
463 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
464 gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2);
465 gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5);
470 gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter)
472 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
473 gst_bit_writer_align_bytes_unchecked (bitwriter, 0);
478 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
479 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile)
482 guint32 constraint_set0_flag, constraint_set1_flag;
483 guint32 constraint_set2_flag, constraint_set3_flag;
484 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
485 gboolean nal_hrd_parameters_present_flag;
487 guint32 b_qpprime_y_zero_transform_bypass = 0;
488 guint32 residual_color_transform_flag = 0;
489 guint32 pic_height_in_map_units =
490 (seq_param->seq_fields.bits.frame_mbs_only_flag ?
491 seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
492 guint32 mb_adaptive_frame_field =
493 !seq_param->seq_fields.bits.frame_mbs_only_flag;
496 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
497 constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
498 profile == GST_VAAPI_PROFILE_H264_BASELINE ||
499 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
500 constraint_set1_flag = /* A.2.2 (main profile constraints) */
501 profile == GST_VAAPI_PROFILE_H264_MAIN ||
502 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
503 constraint_set2_flag = 0;
504 constraint_set3_flag = 0;
507 gst_bit_writer_put_bits_uint32 (bitwriter, profile_idc, 8);
508 /* constraint_set0_flag */
509 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1);
510 /* constraint_set1_flag */
511 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1);
512 /* constraint_set2_flag */
513 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1);
514 /* constraint_set3_flag */
515 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1);
516 /* reserved_zero_4bits */
517 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4);
519 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->level_idc, 8);
520 /* seq_parameter_set_id */
521 gst_bit_writer_put_ue (bitwriter, seq_param->seq_parameter_set_id);
523 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
524 /* for high profile */
525 /* chroma_format_idc = 1, 4:2:0 */
526 gst_bit_writer_put_ue (bitwriter,
527 seq_param->seq_fields.bits.chroma_format_idc);
528 if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
529 gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag,
532 /* bit_depth_luma_minus8 */
533 gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_luma_minus8);
534 /* bit_depth_chroma_minus8 */
535 gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_chroma_minus8);
536 /* b_qpprime_y_zero_transform_bypass */
537 gst_bit_writer_put_bits_uint32 (bitwriter,
538 b_qpprime_y_zero_transform_bypass, 1);
539 g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
540 /* seq_scaling_matrix_present_flag */
541 gst_bit_writer_put_bits_uint32 (bitwriter,
542 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
545 if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
547 i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
549 gst_bit_writer_put_bits_uint8 (bitwriter,
550 seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
551 if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
553 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
560 /* log2_max_frame_num_minus4 */
561 gst_bit_writer_put_ue (bitwriter,
562 seq_param->seq_fields.bits.log2_max_frame_num_minus4);
563 /* pic_order_cnt_type */
564 gst_bit_writer_put_ue (bitwriter,
565 seq_param->seq_fields.bits.pic_order_cnt_type);
567 if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
568 /* log2_max_pic_order_cnt_lsb_minus4 */
569 gst_bit_writer_put_ue (bitwriter,
570 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
571 } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
573 gst_bit_writer_put_bits_uint32 (bitwriter,
574 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
575 gst_bit_writer_put_se (bitwriter, seq_param->offset_for_non_ref_pic);
576 gst_bit_writer_put_se (bitwriter,
577 seq_param->offset_for_top_to_bottom_field);
578 gst_bit_writer_put_ue (bitwriter,
579 seq_param->num_ref_frames_in_pic_order_cnt_cycle);
580 for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
581 gst_bit_writer_put_se (bitwriter, seq_param->offset_for_ref_frame[i]);
586 gst_bit_writer_put_ue (bitwriter, seq_param->max_num_ref_frames);
587 /* gaps_in_frame_num_value_allowed_flag */
588 gst_bit_writer_put_bits_uint32 (bitwriter,
589 gaps_in_frame_num_value_allowed_flag, 1);
591 /* pic_width_in_mbs_minus1 */
592 gst_bit_writer_put_ue (bitwriter, seq_param->picture_width_in_mbs - 1);
593 /* pic_height_in_map_units_minus1 */
594 gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1);
595 /* frame_mbs_only_flag */
596 gst_bit_writer_put_bits_uint32 (bitwriter,
597 seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
599 if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
601 gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1);
604 /* direct_8x8_inference_flag */
605 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
606 /* frame_cropping_flag */
607 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->frame_cropping_flag, 1);
609 if (seq_param->frame_cropping_flag) {
610 /* frame_crop_left_offset */
611 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_left_offset);
612 /* frame_crop_right_offset */
613 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_right_offset);
614 /* frame_crop_top_offset */
615 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_top_offset);
616 /* frame_crop_bottom_offset */
617 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_bottom_offset);
620 /* vui_parameters_present_flag */
621 gst_bit_writer_put_bits_uint32 (bitwriter,
622 seq_param->vui_parameters_present_flag, 1);
623 if (seq_param->vui_parameters_present_flag) {
624 /* aspect_ratio_info_present_flag */
625 gst_bit_writer_put_bits_uint32 (bitwriter,
626 seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
627 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
628 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->aspect_ratio_idc,
630 if (seq_param->aspect_ratio_idc == 0xFF) {
631 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_width, 16);
632 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_height, 16);
636 /* overscan_info_present_flag */
637 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
638 /* video_signal_type_present_flag */
639 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
640 /* chroma_loc_info_present_flag */
641 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
643 /* timing_info_present_flag */
644 gst_bit_writer_put_bits_uint32 (bitwriter,
645 seq_param->vui_fields.bits.timing_info_present_flag, 1);
646 if (seq_param->vui_fields.bits.timing_info_present_flag) {
647 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->num_units_in_tick,
649 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->time_scale, 32);
650 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */
653 nal_hrd_parameters_present_flag =
654 (seq_param->bits_per_second > 0 ? TRUE : FALSE);
655 /* nal_hrd_parameters_present_flag */
656 gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag,
658 if (nal_hrd_parameters_present_flag) {
661 gst_bit_writer_put_ue (bitwriter, 0);
662 gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */
663 gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */
665 for (i = 0; i < 1; ++i) {
666 /* bit_rate_value_minus1[0] */
667 gst_bit_writer_put_ue (bitwriter,
668 seq_param->bits_per_second / 1000 - 1);
669 /* cpb_size_value_minus1[0] */
670 gst_bit_writer_put_ue (bitwriter,
671 seq_param->bits_per_second / 1000 * 8 - 1);
673 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
675 /* initial_cpb_removal_delay_length_minus1 */
676 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
677 /* cpb_removal_delay_length_minus1 */
678 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
679 /* dpb_output_delay_length_minus1 */
680 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
681 /* time_offset_length */
682 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
684 /* vcl_hrd_parameters_present_flag */
685 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
686 if (nal_hrd_parameters_present_flag
687 || 0 /*vcl_hrd_parameters_present_flag */ ) {
688 /* low_delay_hrd_flag */
689 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
691 /* pic_struct_present_flag */
692 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
693 /* bitwriter_restriction_flag */
694 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
697 /* rbsp_trailing_bits */
698 gst_bit_writer_write_trailing_bits (bitwriter);
703 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
704 const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
706 guint32 num_slice_groups_minus1 = 0;
707 guint32 pic_init_qs_minus26 = 0;
708 guint32 redundant_pic_cnt_present_flag = 0;
710 /* pic_parameter_set_id */
711 gst_bit_writer_put_ue (bitwriter, pic_param->pic_parameter_set_id);
712 /* seq_parameter_set_id */
713 gst_bit_writer_put_ue (bitwriter, pic_param->seq_parameter_set_id);
714 /* entropy_coding_mode_flag */
715 gst_bit_writer_put_bits_uint32 (bitwriter,
716 pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
717 /* pic_order_present_flag */
718 gst_bit_writer_put_bits_uint32 (bitwriter,
719 pic_param->pic_fields.bits.pic_order_present_flag, 1);
721 gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1);
723 if (num_slice_groups_minus1 > 0) {
724 /*FIXME*/ g_assert (0);
726 gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l0_active_minus1);
727 gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l1_active_minus1);
728 gst_bit_writer_put_bits_uint32 (bitwriter,
729 pic_param->pic_fields.bits.weighted_pred_flag, 1);
730 gst_bit_writer_put_bits_uint32 (bitwriter,
731 pic_param->pic_fields.bits.weighted_bipred_idc, 2);
732 /* pic_init_qp_minus26 */
733 gst_bit_writer_put_se (bitwriter, pic_param->pic_init_qp - 26);
734 /* pic_init_qs_minus26 */
735 gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26);
736 /* chroma_qp_index_offset */
737 gst_bit_writer_put_se (bitwriter, pic_param->chroma_qp_index_offset);
739 gst_bit_writer_put_bits_uint32 (bitwriter,
740 pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
741 gst_bit_writer_put_bits_uint32 (bitwriter,
742 pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
743 gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1);
746 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
747 gst_bit_writer_put_bits_uint32 (bitwriter,
748 pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
749 gst_bit_writer_put_bits_uint32 (bitwriter,
750 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
751 if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
752 g_assert (0 && "unsupported scaling lists");
756 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
758 gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
762 gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset);
765 /* rbsp_trailing_bits */
766 gst_bit_writer_write_trailing_bits (bitwriter);
771 add_sequence_packed_header (GstVaapiEncoderH264 * encoder,
772 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
774 GstVaapiEncPackedHeader *packed_seq;
776 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
777 const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
778 guint32 data_bit_size;
781 gst_bit_writer_init (&writer, 128 * 8);
782 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
783 gst_bit_writer_write_nal_header (&writer,
784 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
785 gst_bit_writer_write_sps (&writer, seq_param, encoder->profile);
786 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
787 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
788 data = GST_BIT_WRITER_DATA (&writer);
790 packed_header_param_buffer.type = VAEncPackedHeaderSequence;
791 packed_header_param_buffer.bit_length = data_bit_size;
792 packed_header_param_buffer.has_emulation_bytes = 0;
794 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
795 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
796 data, (data_bit_size + 7) / 8);
797 g_assert (packed_seq);
799 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
800 gst_vaapi_codec_object_replace (&packed_seq, NULL);
803 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
804 gst_bit_writer_clear (&writer, TRUE);
810 add_picture_packed_header (GstVaapiEncoderH264 * encoder,
811 GstVaapiEncPicture * picture)
813 GstVaapiEncPackedHeader *packed_pic;
815 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
816 const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
817 guint32 data_bit_size;
820 gst_bit_writer_init (&writer, 128 * 8);
821 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
822 gst_bit_writer_write_nal_header (&writer,
823 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
824 gst_bit_writer_write_pps (&writer, pic_param, encoder->profile);
825 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
826 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
827 data = GST_BIT_WRITER_DATA (&writer);
829 packed_header_param_buffer.type = VAEncPackedHeaderPicture;
830 packed_header_param_buffer.bit_length = data_bit_size;
831 packed_header_param_buffer.has_emulation_bytes = 0;
833 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
834 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
835 data, (data_bit_size + 7) / 8);
836 g_assert (packed_pic);
838 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
839 gst_vaapi_codec_object_replace (&packed_pic, NULL);
842 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
843 gst_bit_writer_clear (&writer, TRUE);
848 /* reference picture management */
850 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
855 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
856 g_slice_free (GstVaapiEncoderH264Ref, ref);
859 static inline GstVaapiEncoderH264Ref *
860 reference_pic_create (GstVaapiEncoderH264 * encoder,
861 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
863 GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
866 ref->frame_num = picture->frame_num;
867 ref->poc = picture->poc;
872 reference_list_update (GstVaapiEncoderH264 * encoder,
873 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
875 GstVaapiEncoderH264Ref *ref;
877 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
878 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
881 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
882 while (!g_queue_is_empty (&encoder->ref_list))
883 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
884 } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) {
885 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
887 ref = reference_pic_create (encoder, picture, surface);
888 g_queue_push_tail (&encoder->ref_list, ref);
889 g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames);
894 reference_list_init (GstVaapiEncoderH264 * encoder,
895 GstVaapiEncPicture * picture,
896 GstVaapiEncoderH264Ref ** reflist_0,
897 guint * reflist_0_count,
898 GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
900 GstVaapiEncoderH264Ref *tmp;
901 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
902 guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
905 *reflist_0_count = 0;
906 *reflist_1_count = 0;
907 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
910 iter = g_queue_peek_tail_link (&encoder->ref_list);
911 for (; iter; iter = g_list_previous (iter)) {
912 tmp = (GstVaapiEncoderH264Ref *) iter->data;
913 g_assert (tmp && tmp->poc != picture->poc);
914 if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
916 list_1_start = g_list_next (iter);
921 /* order reflist_0 */
922 g_assert (list_0_start);
925 for (; iter; iter = g_list_previous (iter)) {
926 reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
929 *reflist_0_count = count;
931 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
934 /* order reflist_1 */
937 for (; iter; iter = g_list_next (iter)) {
938 reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
941 *reflist_1_count = count;
945 /* fill the H264 VA encoding parameters */
947 fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
948 GstVaapiEncSequence * sequence)
950 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
951 VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
953 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
954 seq_param->seq_parameter_set_id = 0;
955 seq_param->level_idc = encoder->level_idc;
956 seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
957 seq_param->ip_period = 0; // ?
958 if (base_encoder->bitrate > 0)
959 seq_param->bits_per_second = base_encoder->bitrate * 1000;
961 seq_param->bits_per_second = 0;
963 seq_param->max_num_ref_frames = encoder->max_ref_frames;
964 seq_param->picture_width_in_mbs = encoder->mb_width;
965 seq_param->picture_height_in_mbs = encoder->mb_height;
967 /*sequence field values */
968 seq_param->seq_fields.value = 0;
969 seq_param->seq_fields.bits.chroma_format_idc = 1;
970 seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
971 seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
972 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
973 /* direct_8x8_inference_flag default false */
974 seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
975 g_assert (encoder->log2_max_frame_num >= 4);
976 seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
977 encoder->log2_max_frame_num - 4;
978 /* picture order count */
979 seq_param->seq_fields.bits.pic_order_cnt_type = 0;
980 g_assert (encoder->log2_max_pic_order_cnt >= 4);
981 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
982 encoder->log2_max_pic_order_cnt - 4;
984 seq_param->bit_depth_luma_minus8 = 0;
985 seq_param->bit_depth_chroma_minus8 = 0;
987 /* not used if pic_order_cnt_type == 0 */
988 if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
989 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
990 seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
991 seq_param->offset_for_non_ref_pic = 0;
992 seq_param->offset_for_top_to_bottom_field = 0;
993 memset (seq_param->offset_for_ref_frame, 0,
994 sizeof (seq_param->offset_for_ref_frame));
997 /* frame_cropping_flag */
998 if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
999 (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
1000 static const guint SubWidthC[] = { 1, 2, 2, 1 };
1001 static const guint SubHeightC[] = { 1, 2, 1, 1 };
1002 const guint CropUnitX =
1003 SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
1004 const guint CropUnitY =
1005 SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
1006 (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
1008 seq_param->frame_cropping_flag = 1;
1009 seq_param->frame_crop_left_offset = 0;
1010 seq_param->frame_crop_right_offset =
1011 (16 * encoder->mb_width -
1012 GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX;
1013 seq_param->frame_crop_top_offset = 0;
1014 seq_param->frame_crop_bottom_offset =
1015 (16 * encoder->mb_height -
1016 GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY;
1019 /* VUI parameters are always set, at least for timing_info (framerate) */
1020 seq_param->vui_parameters_present_flag = TRUE;
1021 if (seq_param->vui_parameters_present_flag) {
1022 seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
1023 seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1024 seq_param->vui_fields.bits.timing_info_present_flag = TRUE;
1025 if (seq_param->vui_fields.bits.timing_info_present_flag) {
1026 seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1027 seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
1035 fill_va_picture_param (GstVaapiEncoderH264 * encoder,
1036 GstVaapiEncPicture * picture,
1037 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1039 VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1040 GstVaapiEncoderH264Ref *ref_pic;
1044 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
1046 /* reference list, */
1047 pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1048 pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
1050 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1051 for (reflist = g_queue_peek_head_link (&encoder->ref_list);
1052 reflist; reflist = g_list_next (reflist)) {
1053 ref_pic = reflist->data;
1054 g_assert (ref_pic && ref_pic->pic &&
1055 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1057 pic_param->ReferenceFrames[i].picture_id =
1058 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1061 g_assert (i <= 16 && i <= encoder->max_ref_frames);
1063 for (; i < 16; ++i) {
1064 pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
1066 pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1068 pic_param->pic_parameter_set_id = 0;
1069 pic_param->seq_parameter_set_id = 0;
1070 pic_param->last_picture = 0; /* means last encoding picture */
1071 pic_param->frame_num = picture->frame_num;
1072 pic_param->pic_init_qp = encoder->init_qp;
1073 pic_param->num_ref_idx_l0_active_minus1 =
1074 (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
1075 pic_param->num_ref_idx_l1_active_minus1 =
1076 (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
1077 pic_param->chroma_qp_index_offset = 0;
1078 pic_param->second_chroma_qp_index_offset = 0;
1080 /* set picture fields */
1081 pic_param->pic_fields.value = 0;
1082 pic_param->pic_fields.bits.idr_pic_flag =
1083 GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1084 pic_param->pic_fields.bits.reference_pic_flag =
1085 (picture->type != GST_VAAPI_PICTURE_TYPE_B);
1086 pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
1087 pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
1088 pic_param->pic_fields.bits.weighted_bipred_idc = 0;
1089 pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
1090 pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
1091 /* enable debloking */
1092 pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
1093 pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
1094 /* bottom_field_pic_order_in_frame_present_flag */
1095 pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
1096 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
1102 fill_va_slices_param (GstVaapiEncoderH264 * encoder,
1103 GstVaapiEncPicture * picture,
1104 GstVaapiEncoderH264Ref ** reflist_0,
1105 guint reflist_0_count,
1106 GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
1108 VAEncSliceParameterBufferH264 *slice_param;
1109 GstVaapiEncSlice *slice;
1110 guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
1112 guint last_mb_index;
1113 guint i_slice, i_ref;
1117 mb_size = encoder->mb_width * encoder->mb_height;
1119 g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1120 slice_of_mbs = mb_size / encoder->num_slices;
1121 slice_mod_mbs = mb_size % encoder->num_slices;
1123 for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1124 cur_slice_mbs = slice_of_mbs;
1125 if (slice_mod_mbs) {
1129 slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1130 g_assert (slice && slice->param_id != VA_INVALID_ID);
1131 slice_param = slice->param;
1133 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1134 slice_param->macroblock_address = last_mb_index;
1135 slice_param->num_macroblocks = cur_slice_mbs;
1136 slice_param->macroblock_info = VA_INVALID_ID;
1137 slice_param->slice_type = h264_get_slice_type (picture->type);
1138 g_assert (slice_param->slice_type != -1);
1139 slice_param->pic_parameter_set_id = 0;
1140 slice_param->idr_pic_id = encoder->idr_num;
1141 slice_param->pic_order_cnt_lsb = picture->poc;
1143 /* not used if pic_order_cnt_type = 0 */
1144 slice_param->delta_pic_order_cnt_bottom = 0;
1145 memset (slice_param->delta_pic_order_cnt, 0,
1146 sizeof (slice_param->delta_pic_order_cnt));
1148 /* only works for B frames */
1149 slice_param->direct_spatial_mv_pred_flag = FALSE;
1150 /* default equal to picture parameters */
1151 slice_param->num_ref_idx_active_override_flag = FALSE;
1152 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1153 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1155 slice_param->num_ref_idx_l0_active_minus1 = 0;
1156 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1157 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1159 slice_param->num_ref_idx_l1_active_minus1 = 0;
1160 g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1161 g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1164 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1165 for (; i_ref < reflist_0_count; ++i_ref) {
1166 slice_param->RefPicList0[i_ref].picture_id =
1167 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1169 g_assert (i_ref == 1);
1171 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1172 slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1176 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1177 for (; i_ref < reflist_1_count; ++i_ref) {
1178 slice_param->RefPicList1[i_ref].picture_id =
1179 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1181 g_assert (i_ref == 1);
1183 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1184 slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1187 /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1188 slice_param->luma_log2_weight_denom = 0;
1189 slice_param->chroma_log2_weight_denom = 0;
1190 slice_param->luma_weight_l0_flag = FALSE;
1191 memset (slice_param->luma_weight_l0, 0,
1192 sizeof (slice_param->luma_weight_l0));
1193 memset (slice_param->luma_offset_l0, 0,
1194 sizeof (slice_param->luma_offset_l0));
1195 slice_param->chroma_weight_l0_flag = FALSE;
1196 memset (slice_param->chroma_weight_l0, 0,
1197 sizeof (slice_param->chroma_weight_l0));
1198 memset (slice_param->chroma_offset_l0, 0,
1199 sizeof (slice_param->chroma_offset_l0));
1200 slice_param->luma_weight_l1_flag = FALSE;
1201 memset (slice_param->luma_weight_l1, 0,
1202 sizeof (slice_param->luma_weight_l1));
1203 memset (slice_param->luma_offset_l1, 0,
1204 sizeof (slice_param->luma_offset_l1));
1205 slice_param->chroma_weight_l1_flag = FALSE;
1206 memset (slice_param->chroma_weight_l1, 0,
1207 sizeof (slice_param->chroma_weight_l1));
1208 memset (slice_param->chroma_offset_l1, 0,
1209 sizeof (slice_param->chroma_offset_l1));
1211 slice_param->cabac_init_idc = 0;
1212 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1213 if (slice_param->slice_qp_delta > 4)
1214 slice_param->slice_qp_delta = 4;
1215 slice_param->disable_deblocking_filter_idc = 0;
1216 slice_param->slice_alpha_c0_offset_div2 = 2;
1217 slice_param->slice_beta_offset_div2 = 2;
1219 /* set calculation for next slice */
1220 last_mb_index += cur_slice_mbs;
1222 gst_vaapi_enc_picture_add_slice (picture, slice);
1223 gst_vaapi_codec_object_replace (&slice, NULL);
1225 g_assert (last_mb_index == mb_size);
1230 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1232 GstVaapiEncSequence *sequence;
1235 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1236 g_assert (sequence);
1240 if (!fill_va_sequence_param (encoder, sequence))
1243 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1244 !add_sequence_packed_header (encoder, picture, sequence))
1246 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1247 gst_vaapi_codec_object_replace (&sequence, NULL);
1251 gst_vaapi_codec_object_replace (&sequence, NULL);
1256 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1257 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1259 GstVaapiCodedBuffer *const codedbuf =
1260 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1262 if (!fill_va_picture_param (encoder, picture, codedbuf, surface))
1265 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1266 !add_picture_packed_header (encoder, picture)) {
1267 GST_ERROR ("set picture packed header failed");
1275 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1277 GstVaapiEncoderH264Ref *reflist_0[16];
1278 GstVaapiEncoderH264Ref *reflist_1[16];
1279 guint reflist_0_count = 0, reflist_1_count = 0;
1283 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1284 !reference_list_init (encoder, picture,
1285 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1286 GST_ERROR ("reference list reorder failed");
1290 g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames);
1291 if (reflist_0_count > encoder->max_reflist0_count)
1292 reflist_0_count = encoder->max_reflist0_count;
1293 if (reflist_1_count > encoder->max_reflist1_count)
1294 reflist_1_count = encoder->max_reflist1_count;
1296 if (!fill_va_slices_param (encoder, picture,
1297 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1304 ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1306 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1307 GstVaapiEncMiscParam *misc = NULL;
1308 VAEncMiscParameterHRD *hrd;
1309 VAEncMiscParameterRateControl *rate_control;
1312 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1316 gst_vaapi_enc_picture_add_misc_param (picture, misc);
1318 if (base_encoder->bitrate > 0) {
1319 hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4;
1320 hrd->buffer_size = base_encoder->bitrate * 1000 * 8;
1322 hrd->initial_buffer_fullness = 0;
1323 hrd->buffer_size = 0;
1325 gst_vaapi_codec_object_replace (&misc, NULL);
1327 /* add ratecontrol */
1328 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1329 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1330 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1334 gst_vaapi_enc_picture_add_misc_param (picture, misc);
1335 rate_control = misc->data;
1336 memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1337 if (base_encoder->bitrate)
1338 rate_control->bits_per_second = base_encoder->bitrate * 1000;
1340 rate_control->bits_per_second = 0;
1341 rate_control->target_percentage = 70;
1342 rate_control->window_size = 500;
1343 rate_control->initial_qp = encoder->init_qp;
1344 rate_control->min_qp = encoder->min_qp;
1345 rate_control->basic_unit_size = 0;
1346 gst_vaapi_codec_object_replace (&misc, NULL);
1352 static GstVaapiEncoderStatus
1353 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
1355 ensure_tuning (encoder);
1357 if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
1358 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1360 if (!ensure_level (encoder))
1361 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1363 /* Check HW constraints */
1364 if (!ensure_hw_profile_limits (encoder))
1365 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1366 if (encoder->profile_idc > encoder->hw_max_profile_idc)
1367 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1368 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1372 ensure_bitrate (GstVaapiEncoderH264 * encoder)
1374 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1376 /* Default compression: 48 bits per macroblock in "high-compression" mode */
1377 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1378 case GST_VAAPI_RATECONTROL_CBR:
1379 case GST_VAAPI_RATECONTROL_VBR:
1380 case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
1381 if (!base_encoder->bitrate) {
1382 /* According to the literature and testing, CABAC entropy coding
1383 mode could provide for +10% to +18% improvement in general,
1384 thus estimating +15% here ; and using adaptive 8x8 transforms
1385 in I-frames could bring up to +10% improvement. */
1386 guint bits_per_mb = 48;
1387 if (!encoder->use_cabac)
1388 bits_per_mb += (bits_per_mb * 15) / 100;
1389 if (!encoder->use_dct8x8)
1390 bits_per_mb += (bits_per_mb * 10) / 100;
1392 base_encoder->bitrate =
1393 encoder->mb_width * encoder->mb_height * bits_per_mb *
1394 GST_VAAPI_ENCODER_FPS_N (encoder) /
1395 GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
1396 GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
1400 base_encoder->bitrate = 0;
1407 reset_properties (GstVaapiEncoderH264 * encoder)
1409 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1412 if (encoder->idr_period < base_encoder->keyframe_period)
1413 encoder->idr_period = base_encoder->keyframe_period;
1414 if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD)
1415 encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD;
1417 if (encoder->min_qp > encoder->init_qp ||
1418 (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
1419 encoder->min_qp < encoder->init_qp))
1420 encoder->min_qp = encoder->init_qp;
1422 mb_size = encoder->mb_width * encoder->mb_height;
1423 if (encoder->num_slices > (mb_size + 1) / 2)
1424 encoder->num_slices = (mb_size + 1) / 2;
1425 g_assert (encoder->num_slices);
1427 if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
1428 encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
1430 if (encoder->num_bframes > 50)
1431 encoder->num_bframes = 50;
1433 if (encoder->num_bframes)
1434 encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1435 GST_VAAPI_ENCODER_FPS_N (encoder);
1437 encoder->cts_offset = 0;
1439 /* init max_frame_num, max_poc */
1440 encoder->log2_max_frame_num =
1441 h264_get_log2_max_frame_num (encoder->idr_period);
1442 g_assert (encoder->log2_max_frame_num >= 4);
1443 encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1444 encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1445 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1447 encoder->frame_index = 0;
1448 encoder->idr_num = 0;
1449 encoder->max_reflist0_count = 1;
1450 encoder->max_reflist1_count = encoder->num_bframes > 0;
1451 encoder->max_ref_frames =
1452 encoder->max_reflist0_count + encoder->max_reflist1_count;
1455 static GstVaapiEncoderStatus
1456 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
1457 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1459 GstVaapiEncoderH264 *const encoder =
1460 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1461 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1462 GstVaapiSurfaceProxy *reconstruct = NULL;
1464 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
1466 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1468 if (!ensure_sequence (encoder, picture))
1470 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1472 if (!ensure_misc (encoder, picture))
1474 if (!ensure_slices (encoder, picture))
1476 if (!gst_vaapi_enc_picture_encode (picture))
1479 if (!reference_list_update (encoder, picture, reconstruct))
1482 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1485 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1490 static GstVaapiEncoderStatus
1491 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
1493 GstVaapiEncoderH264 *const encoder =
1494 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1495 GstVaapiEncPicture *pic;
1497 encoder->frame_index = 0;
1498 encoder->cur_frame_num = 0;
1499 encoder->cur_present_index = 0;
1500 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1501 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1502 gst_vaapi_enc_picture_unref (pic);
1504 g_queue_clear (&encoder->reorder_frame_list);
1506 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1509 /* Generate "codec-data" buffer */
1510 static GstVaapiEncoderStatus
1511 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
1512 GstBuffer ** out_buffer_ptr)
1514 GstVaapiEncoderH264 *const encoder =
1515 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1516 const guint32 configuration_version = 0x01;
1517 const guint32 nal_length_size = 4;
1518 guint8 profile_idc, profile_comp, level_idc;
1519 GstMapInfo sps_info, pps_info;
1520 GstBitWriter writer;
1523 if (!encoder->sps_data || !encoder->pps_data)
1524 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1525 if (gst_buffer_get_size (encoder->sps_data) < 4)
1526 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1528 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1529 goto error_map_sps_buffer;
1531 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
1532 goto error_map_pps_buffer;
1534 /* skip sps_data[0], which is the nal_unit_type */
1535 profile_idc = sps_info.data[1];
1536 profile_comp = sps_info.data[2];
1537 level_idc = sps_info.data[3];
1540 gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8);
1541 gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8);
1542 gst_bit_writer_put_bits_uint32 (&writer, profile_idc, 8);
1543 gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8);
1544 gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8);
1545 gst_bit_writer_put_bits_uint32 (&writer, 0x3f, 6); /* 111111 */
1546 gst_bit_writer_put_bits_uint32 (&writer, nal_length_size - 1, 2);
1547 gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /* 111 */
1550 gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* SPS count = 1 */
1551 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
1552 gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16);
1553 gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size);
1556 gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /* PPS count = 1 */
1557 gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16);
1558 gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size);
1560 gst_buffer_unmap (encoder->pps_data, &pps_info);
1561 gst_buffer_unmap (encoder->sps_data, &sps_info);
1563 buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer),
1564 GST_BIT_WRITER_BIT_SIZE (&writer) / 8);
1566 goto error_alloc_buffer;
1567 *out_buffer_ptr = buffer;
1569 gst_bit_writer_clear (&writer, FALSE);
1570 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1573 error_map_sps_buffer:
1575 GST_ERROR ("failed to map SPS packed header");
1576 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1578 error_map_pps_buffer:
1580 GST_ERROR ("failed to map PPS packed header");
1581 gst_buffer_unmap (encoder->sps_data, &sps_info);
1582 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1586 GST_ERROR ("failed to allocate codec-data buffer");
1587 gst_bit_writer_clear (&writer, TRUE);
1588 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1592 static GstVaapiEncoderStatus
1593 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
1594 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1596 GstVaapiEncoderH264 *const encoder =
1597 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1598 GstVaapiEncPicture *picture;
1599 gboolean is_idr = FALSE;
1604 if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1605 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1607 /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1608 dump B frames from queue, sometime, there may also have P frame or I frame */
1609 g_assert (encoder->num_bframes > 0);
1610 g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1611 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1612 picture = g_queue_pop_head (&encoder->reorder_frame_list);
1614 if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1615 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1620 /* new frame coming */
1621 picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1623 GST_WARNING ("create H264 picture failed, frame timestamp:%"
1624 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1625 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1627 ++encoder->cur_present_index;
1628 picture->poc = ((encoder->cur_present_index * 2) %
1629 encoder->max_pic_order_cnt);
1631 is_idr = (encoder->frame_index == 0 ||
1632 encoder->frame_index >= encoder->idr_period);
1634 /* check key frames */
1635 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1636 (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) ==
1638 ++encoder->cur_frame_num;
1639 ++encoder->frame_index;
1641 /* b frame enabled, check queue of reorder_frame_list */
1642 if (encoder->num_bframes
1643 && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1644 GstVaapiEncPicture *p_pic;
1646 p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1647 _set_p_frame (p_pic, encoder);
1648 g_queue_foreach (&encoder->reorder_frame_list,
1649 (GFunc) _set_b_frame, encoder);
1650 ++encoder->cur_frame_num;
1651 _set_key_frame (picture, encoder, is_idr);
1652 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1654 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1655 } else { /* no b frames in queue */
1656 _set_key_frame (picture, encoder, is_idr);
1657 g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1658 if (encoder->num_bframes)
1659 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1664 /* new p/b frames coming */
1665 ++encoder->frame_index;
1666 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1667 g_queue_get_length (&encoder->reorder_frame_list) <
1668 encoder->num_bframes) {
1669 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1670 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1673 ++encoder->cur_frame_num;
1674 _set_p_frame (picture, encoder);
1676 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1677 g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame,
1679 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1680 g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1685 frame = picture->frame;
1686 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1687 frame->pts += encoder->cts_offset;
1690 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1693 static GstVaapiEncoderStatus
1694 set_context_info (GstVaapiEncoder * base_encoder)
1696 GstVaapiEncoderH264 *const encoder =
1697 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1698 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1699 const guint DEFAULT_SURFACES_COUNT = 3;
1701 /* Maximum sizes for common headers (in bits) */
1704 MAX_SPS_HDR_SIZE = 16473,
1705 MAX_VUI_PARAMS_SIZE = 210,
1706 MAX_HRD_PARAMS_SIZE = 4103,
1707 MAX_PPS_HDR_SIZE = 101,
1708 MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1711 if (!ensure_hw_profile (encoder))
1712 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1714 base_encoder->num_ref_frames =
1715 (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1717 /* Only YUV 4:2:0 formats are supported for now. This means that we
1718 have a limit of 3200 bits per macroblock. */
1719 /* XXX: check profile and compute RawMbBits */
1720 base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
1721 GST_ROUND_UP_16 (vip->height) / 256) * 400;
1723 /* Account for SPS header */
1724 /* XXX: exclude scaling lists, MVC/SVC extensions */
1725 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1726 MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1728 /* Account for PPS header */
1729 /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1730 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1732 /* Account for slice header */
1733 base_encoder->codedbuf_size += encoder->num_slices * (4 +
1734 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1736 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1739 static GstVaapiEncoderStatus
1740 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
1742 GstVaapiEncoderH264 *const encoder =
1743 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1744 GstVaapiEncoderStatus status;
1746 encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1747 encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1749 status = ensure_profile_and_level (encoder);
1750 if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
1753 if (!ensure_bitrate (encoder))
1756 reset_properties (encoder);
1757 return set_context_info (base_encoder);
1760 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1764 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
1766 GstVaapiEncoderH264 *const encoder =
1767 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1770 g_queue_init (&encoder->reorder_frame_list);
1771 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1773 /* reference frames */
1774 g_queue_init (&encoder->ref_list);
1775 encoder->max_ref_frames = 0;
1776 encoder->max_reflist0_count = 1;
1777 encoder->max_reflist1_count = 1;
1783 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
1785 /*free private buffers */
1786 GstVaapiEncoderH264 *const encoder =
1787 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1788 GstVaapiEncPicture *pic;
1789 GstVaapiEncoderH264Ref *ref;
1791 gst_buffer_replace (&encoder->sps_data, NULL);
1792 gst_buffer_replace (&encoder->pps_data, NULL);
1794 while (!g_queue_is_empty (&encoder->ref_list)) {
1795 ref = g_queue_pop_head (&encoder->ref_list);
1796 reference_pic_free (encoder, ref);
1798 g_queue_clear (&encoder->ref_list);
1800 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1801 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1802 gst_vaapi_enc_picture_unref (pic);
1804 g_queue_clear (&encoder->reorder_frame_list);
1808 static GstVaapiEncoderStatus
1809 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
1810 gint prop_id, const GValue * value)
1812 GstVaapiEncoderH264 *const encoder =
1813 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1816 case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
1817 encoder->num_bframes = g_value_get_uint (value);
1819 case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
1820 encoder->init_qp = g_value_get_uint (value);
1822 case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
1823 encoder->min_qp = g_value_get_uint (value);
1825 case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
1826 encoder->num_slices = g_value_get_uint (value);
1828 case GST_VAAPI_ENCODER_H264_PROP_CABAC:
1829 encoder->use_cabac = g_value_get_boolean (value);
1831 case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
1832 encoder->use_dct8x8 = g_value_get_boolean (value);
1835 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
1837 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1840 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
1842 static inline const GstVaapiEncoderClass *
1843 gst_vaapi_encoder_h264_class (void)
1845 static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1846 GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1847 .set_property = gst_vaapi_encoder_h264_set_property,
1848 .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1850 return &GstVaapiEncoderH264Class;
1854 * gst_vaapi_encoder_h264_new:
1855 * @display: a #GstVaapiDisplay
1857 * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
1858 * only supported output stream format is "byte-stream" format.
1860 * Return value: the newly allocated #GstVaapiEncoder object
1863 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1865 return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1869 * gst_vaapi_encoder_h264_get_default_properties:
1871 * Determines the set of common and H.264 specific encoder properties.
1872 * The caller owns an extra reference to the resulting array of
1873 * #GstVaapiEncoderPropInfo elements, so it shall be released with
1874 * g_ptr_array_unref() after usage.
1876 * Return value: the set of encoder properties for #GstVaapiEncoderH264,
1877 * or %NULL if an error occurred.
1880 gst_vaapi_encoder_h264_get_default_properties (void)
1882 const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
1885 props = gst_vaapi_encoder_properties_get_default (klass);
1890 * GstVaapiEncoderH264:max-bframes:
1892 * The number of B-frames between I and P.
1894 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1895 GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
1896 g_param_spec_uint ("max-bframes",
1897 "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
1898 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1901 * GstVaapiEncoderH264:init-qp:
1903 * The initial quantizer value.
1905 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1906 GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
1907 g_param_spec_uint ("init-qp",
1908 "Initial QP", "Initial quantizer value", 1, 51, 26,
1909 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1912 * GstVaapiEncoderH264:min-qp:
1914 * The minimum quantizer value.
1916 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1917 GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
1918 g_param_spec_uint ("min-qp",
1919 "Minimum QP", "Minimum quantizer value", 1, 51, 1,
1920 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1923 * GstVaapiEncoderH264:num-slices:
1925 * The number of slices per frame.
1927 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1928 GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
1929 g_param_spec_uint ("num-slices",
1931 "Number of slices per frame",
1932 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1935 * GstVaapiEncoderH264:cabac:
1937 * Enable CABAC entropy coding mode for improved compression ratio,
1938 * at the expense that the minimum target profile is Main. Default
1939 * is CAVLC entropy coding mode.
1941 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1942 GST_VAAPI_ENCODER_H264_PROP_CABAC,
1943 g_param_spec_boolean ("cabac",
1945 "Enable CABAC entropy coding mode",
1946 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1949 * GstVaapiEncoderH264:dct8x8:
1951 * Enable adaptive use of 8x8 transforms in I-frames. This improves
1952 * the compression ratio by the minimum target profile is High.
1953 * Default is to use 4x4 DCT only.
1955 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1956 GST_VAAPI_ENCODER_H264_PROP_DCT8X8,
1957 g_param_spec_boolean ("dct8x8",
1959 "Enable adaptive use of 8x8 transforms in I-frames",
1960 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1966 * gst_vaapi_encoder_h264_set_max_profile:
1967 * @encoder: a #GstVaapiEncoderH264
1968 * @profile: an H.264 #GstVaapiProfile
1970 * Notifies the @encoder to use coding tools from the supplied
1973 * This means that if the minimal profile derived to
1974 * support the specified coding tools is greater than this @profile,
1975 * then an error is returned when the @encoder is configured.
1977 * Return value: %TRUE on success
1980 gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
1981 GstVaapiProfile profile)
1985 g_return_val_if_fail (encoder != NULL, FALSE);
1986 g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
1988 if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
1991 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
1995 encoder->max_profile_idc = profile_idc;
2000 * gst_vaapi_encoder_h264_get_profile_and_level:
2001 * @encoder: a #GstVaapiEncoderH264
2002 * @out_profile_ptr: return location for the #GstVaapiProfile
2003 * @out_level_ptr: return location for the #GstVaapiLevelH264
2005 * Queries the H.264 @encoder for the active profile and level. That
2006 * information is only constructed and valid after the encoder is
2007 * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
2008 * function is called.
2010 * Return value: %TRUE on success
2013 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
2014 GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
2016 g_return_val_if_fail (encoder != NULL, FALSE);
2018 if (!encoder->profile || !encoder->level)
2021 if (out_profile_ptr)
2022 *out_profile_ptr = encoder->profile;
2024 *out_level_ptr = encoder->level;