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);
396 g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
397 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
401 _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
403 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
404 pic->type = GST_VAAPI_PICTURE_TYPE_I;
407 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
409 g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
410 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
414 _set_key_frame (GstVaapiEncPicture * picture,
415 GstVaapiEncoderH264 * encoder, gboolean is_idr)
418 _reset_gop_start (encoder);
419 _set_idr_frame (picture, encoder);
421 _set_i_frame (picture, encoder);
425 gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value)
427 guint32 size_in_bits = 0;
428 guint32 tmp_value = ++value;
435 && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1))
437 if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits))
443 gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value)
448 new_val = -(value << 1);
450 new_val = (value << 1) - 1;
452 if (!gst_bit_writer_put_ue (bitwriter, new_val))
459 gst_bit_writer_write_nal_header (GstBitWriter * bitwriter,
460 guint32 nal_ref_idc, guint32 nal_unit_type)
462 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
463 gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2);
464 gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5);
469 gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter)
471 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
472 gst_bit_writer_align_bytes_unchecked (bitwriter, 0);
477 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
478 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile)
481 guint32 constraint_set0_flag, constraint_set1_flag;
482 guint32 constraint_set2_flag, constraint_set3_flag;
483 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
484 gboolean nal_hrd_parameters_present_flag;
486 guint32 b_qpprime_y_zero_transform_bypass = 0;
487 guint32 residual_color_transform_flag = 0;
488 guint32 pic_height_in_map_units =
489 (seq_param->seq_fields.bits.frame_mbs_only_flag ?
490 seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
491 guint32 mb_adaptive_frame_field =
492 !seq_param->seq_fields.bits.frame_mbs_only_flag;
495 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
496 constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
497 profile == GST_VAAPI_PROFILE_H264_BASELINE ||
498 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
499 constraint_set1_flag = /* A.2.2 (main profile constraints) */
500 profile == GST_VAAPI_PROFILE_H264_MAIN ||
501 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
502 constraint_set2_flag = 0;
503 constraint_set3_flag = 0;
506 gst_bit_writer_put_bits_uint32 (bitwriter, profile_idc, 8);
507 /* constraint_set0_flag */
508 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1);
509 /* constraint_set1_flag */
510 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1);
511 /* constraint_set2_flag */
512 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1);
513 /* constraint_set3_flag */
514 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1);
515 /* reserved_zero_4bits */
516 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4);
518 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->level_idc, 8);
519 /* seq_parameter_set_id */
520 gst_bit_writer_put_ue (bitwriter, seq_param->seq_parameter_set_id);
522 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
523 /* for high profile */
524 /* chroma_format_idc = 1, 4:2:0 */
525 gst_bit_writer_put_ue (bitwriter,
526 seq_param->seq_fields.bits.chroma_format_idc);
527 if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
528 gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag,
531 /* bit_depth_luma_minus8 */
532 gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_luma_minus8);
533 /* bit_depth_chroma_minus8 */
534 gst_bit_writer_put_ue (bitwriter, seq_param->bit_depth_chroma_minus8);
535 /* b_qpprime_y_zero_transform_bypass */
536 gst_bit_writer_put_bits_uint32 (bitwriter,
537 b_qpprime_y_zero_transform_bypass, 1);
538 g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
539 /* seq_scaling_matrix_present_flag */
540 gst_bit_writer_put_bits_uint32 (bitwriter,
541 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
544 if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
546 i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
548 gst_bit_writer_put_bits_uint8 (bitwriter,
549 seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
550 if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
552 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
559 /* log2_max_frame_num_minus4 */
560 gst_bit_writer_put_ue (bitwriter,
561 seq_param->seq_fields.bits.log2_max_frame_num_minus4);
562 /* pic_order_cnt_type */
563 gst_bit_writer_put_ue (bitwriter,
564 seq_param->seq_fields.bits.pic_order_cnt_type);
566 if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
567 /* log2_max_pic_order_cnt_lsb_minus4 */
568 gst_bit_writer_put_ue (bitwriter,
569 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
570 } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
572 gst_bit_writer_put_bits_uint32 (bitwriter,
573 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
574 gst_bit_writer_put_se (bitwriter, seq_param->offset_for_non_ref_pic);
575 gst_bit_writer_put_se (bitwriter,
576 seq_param->offset_for_top_to_bottom_field);
577 gst_bit_writer_put_ue (bitwriter,
578 seq_param->num_ref_frames_in_pic_order_cnt_cycle);
579 for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
580 gst_bit_writer_put_se (bitwriter, seq_param->offset_for_ref_frame[i]);
585 gst_bit_writer_put_ue (bitwriter, seq_param->max_num_ref_frames);
586 /* gaps_in_frame_num_value_allowed_flag */
587 gst_bit_writer_put_bits_uint32 (bitwriter,
588 gaps_in_frame_num_value_allowed_flag, 1);
590 /* pic_width_in_mbs_minus1 */
591 gst_bit_writer_put_ue (bitwriter, seq_param->picture_width_in_mbs - 1);
592 /* pic_height_in_map_units_minus1 */
593 gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1);
594 /* frame_mbs_only_flag */
595 gst_bit_writer_put_bits_uint32 (bitwriter,
596 seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
598 if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
600 gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1);
603 /* direct_8x8_inference_flag */
604 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
605 /* frame_cropping_flag */
606 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->frame_cropping_flag, 1);
608 if (seq_param->frame_cropping_flag) {
609 /* frame_crop_left_offset */
610 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_left_offset);
611 /* frame_crop_right_offset */
612 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_right_offset);
613 /* frame_crop_top_offset */
614 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_top_offset);
615 /* frame_crop_bottom_offset */
616 gst_bit_writer_put_ue (bitwriter, seq_param->frame_crop_bottom_offset);
619 /* vui_parameters_present_flag */
620 gst_bit_writer_put_bits_uint32 (bitwriter,
621 seq_param->vui_parameters_present_flag, 1);
622 if (seq_param->vui_parameters_present_flag) {
623 /* aspect_ratio_info_present_flag */
624 gst_bit_writer_put_bits_uint32 (bitwriter,
625 seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
626 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
627 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->aspect_ratio_idc,
629 if (seq_param->aspect_ratio_idc == 0xFF) {
630 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_width, 16);
631 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->sar_height, 16);
635 /* overscan_info_present_flag */
636 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
637 /* video_signal_type_present_flag */
638 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
639 /* chroma_loc_info_present_flag */
640 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
642 /* timing_info_present_flag */
643 gst_bit_writer_put_bits_uint32 (bitwriter,
644 seq_param->vui_fields.bits.timing_info_present_flag, 1);
645 if (seq_param->vui_fields.bits.timing_info_present_flag) {
646 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->num_units_in_tick,
648 gst_bit_writer_put_bits_uint32 (bitwriter, seq_param->time_scale, 32);
649 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */
652 nal_hrd_parameters_present_flag =
653 (seq_param->bits_per_second > 0 ? TRUE : FALSE);
654 /* nal_hrd_parameters_present_flag */
655 gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag,
657 if (nal_hrd_parameters_present_flag) {
660 gst_bit_writer_put_ue (bitwriter, 0);
661 gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */
662 gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */
664 for (i = 0; i < 1; ++i) {
665 /* bit_rate_value_minus1[0] */
666 gst_bit_writer_put_ue (bitwriter,
667 seq_param->bits_per_second / 1000 - 1);
668 /* cpb_size_value_minus1[0] */
669 gst_bit_writer_put_ue (bitwriter,
670 seq_param->bits_per_second / 1000 * 8 - 1);
672 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
674 /* initial_cpb_removal_delay_length_minus1 */
675 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
676 /* cpb_removal_delay_length_minus1 */
677 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
678 /* dpb_output_delay_length_minus1 */
679 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
680 /* time_offset_length */
681 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
683 /* vcl_hrd_parameters_present_flag */
684 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
685 if (nal_hrd_parameters_present_flag
686 || 0 /*vcl_hrd_parameters_present_flag */ ) {
687 /* low_delay_hrd_flag */
688 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
690 /* pic_struct_present_flag */
691 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
692 /* bitwriter_restriction_flag */
693 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
696 /* rbsp_trailing_bits */
697 gst_bit_writer_write_trailing_bits (bitwriter);
702 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
703 const VAEncPictureParameterBufferH264 * pic_param)
705 guint32 num_slice_groups_minus1 = 0;
706 guint32 pic_init_qs_minus26 = 0;
707 guint32 redundant_pic_cnt_present_flag = 0;
709 /* pic_parameter_set_id */
710 gst_bit_writer_put_ue (bitwriter, pic_param->pic_parameter_set_id);
711 /* seq_parameter_set_id */
712 gst_bit_writer_put_ue (bitwriter, pic_param->seq_parameter_set_id);
713 /* entropy_coding_mode_flag */
714 gst_bit_writer_put_bits_uint32 (bitwriter,
715 pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
716 /* pic_order_present_flag */
717 gst_bit_writer_put_bits_uint32 (bitwriter,
718 pic_param->pic_fields.bits.pic_order_present_flag, 1);
720 gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1);
722 if (num_slice_groups_minus1 > 0) {
723 /*FIXME*/ g_assert (0);
725 gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l0_active_minus1);
726 gst_bit_writer_put_ue (bitwriter, pic_param->num_ref_idx_l1_active_minus1);
727 gst_bit_writer_put_bits_uint32 (bitwriter,
728 pic_param->pic_fields.bits.weighted_pred_flag, 1);
729 gst_bit_writer_put_bits_uint32 (bitwriter,
730 pic_param->pic_fields.bits.weighted_bipred_idc, 2);
731 /* pic_init_qp_minus26 */
732 gst_bit_writer_put_se (bitwriter, pic_param->pic_init_qp - 26);
733 /* pic_init_qs_minus26 */
734 gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26);
735 /* chroma_qp_index_offset */
736 gst_bit_writer_put_se (bitwriter, pic_param->chroma_qp_index_offset);
738 gst_bit_writer_put_bits_uint32 (bitwriter,
739 pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
740 gst_bit_writer_put_bits_uint32 (bitwriter,
741 pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
742 gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1);
745 gst_bit_writer_put_bits_uint32 (bitwriter,
746 pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
747 gst_bit_writer_put_bits_uint32 (bitwriter,
748 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
749 if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
754 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
756 gst_bit_writer_put_bits_uint8(bitwriter, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
761 gst_bit_writer_put_se (bitwriter, pic_param->second_chroma_qp_index_offset);
762 gst_bit_writer_write_trailing_bits (bitwriter);
768 add_sequence_packed_header (GstVaapiEncoderH264 * encoder,
769 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
771 GstVaapiEncPackedHeader *packed_seq;
773 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
774 const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
775 guint32 data_bit_size;
778 gst_bit_writer_init (&writer, 128 * 8);
779 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
780 gst_bit_writer_write_nal_header (&writer,
781 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
782 gst_bit_writer_write_sps (&writer, seq_param, encoder->profile);
783 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
784 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
785 data = GST_BIT_WRITER_DATA (&writer);
787 packed_header_param_buffer.type = VAEncPackedHeaderSequence;
788 packed_header_param_buffer.bit_length = data_bit_size;
789 packed_header_param_buffer.has_emulation_bytes = 0;
791 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
792 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
793 data, (data_bit_size + 7) / 8);
794 g_assert (packed_seq);
796 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
797 gst_vaapi_codec_object_replace (&packed_seq, NULL);
800 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
801 gst_bit_writer_clear (&writer, TRUE);
807 add_picture_packed_header (GstVaapiEncoderH264 * encoder,
808 GstVaapiEncPicture * picture)
810 GstVaapiEncPackedHeader *packed_pic;
812 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
813 const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
814 guint32 data_bit_size;
817 gst_bit_writer_init (&writer, 128 * 8);
818 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
819 gst_bit_writer_write_nal_header (&writer,
820 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
821 gst_bit_writer_write_pps (&writer, pic_param);
822 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
823 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
824 data = GST_BIT_WRITER_DATA (&writer);
826 packed_header_param_buffer.type = VAEncPackedHeaderPicture;
827 packed_header_param_buffer.bit_length = data_bit_size;
828 packed_header_param_buffer.has_emulation_bytes = 0;
830 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
831 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
832 data, (data_bit_size + 7) / 8);
833 g_assert (packed_pic);
835 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
836 gst_vaapi_codec_object_replace (&packed_pic, NULL);
839 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
840 gst_bit_writer_clear (&writer, TRUE);
845 /* reference picture management */
847 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
852 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
853 g_slice_free (GstVaapiEncoderH264Ref, ref);
856 static inline GstVaapiEncoderH264Ref *
857 reference_pic_create (GstVaapiEncoderH264 * encoder,
858 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
860 GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
863 ref->frame_num = picture->frame_num;
864 ref->poc = picture->poc;
869 reference_list_update (GstVaapiEncoderH264 * encoder,
870 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
872 GstVaapiEncoderH264Ref *ref;
874 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
875 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
878 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
879 while (!g_queue_is_empty (&encoder->ref_list))
880 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
881 } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) {
882 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
884 ref = reference_pic_create (encoder, picture, surface);
885 g_queue_push_tail (&encoder->ref_list, ref);
886 g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames);
891 reference_list_init (GstVaapiEncoderH264 * encoder,
892 GstVaapiEncPicture * picture,
893 GstVaapiEncoderH264Ref ** reflist_0,
894 guint * reflist_0_count,
895 GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
897 GstVaapiEncoderH264Ref *tmp;
898 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
899 guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
902 *reflist_0_count = 0;
903 *reflist_1_count = 0;
904 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
907 iter = g_queue_peek_tail_link (&encoder->ref_list);
908 for (; iter; iter = g_list_previous (iter)) {
909 tmp = (GstVaapiEncoderH264Ref *) iter->data;
910 g_assert (tmp && tmp->poc != picture->poc);
911 if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
913 list_1_start = g_list_next (iter);
918 /* order reflist_0 */
919 g_assert (list_0_start);
922 for (; iter; iter = g_list_previous (iter)) {
923 reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
926 *reflist_0_count = count;
928 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
931 /* order reflist_1 */
934 for (; iter; iter = g_list_next (iter)) {
935 reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
938 *reflist_1_count = count;
942 /* fill the H264 VA encoding parameters */
944 fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
945 GstVaapiEncSequence * sequence)
947 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
948 VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
950 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
951 seq_param->seq_parameter_set_id = 0;
952 seq_param->level_idc = encoder->level_idc;
953 seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
954 seq_param->ip_period = 0; // ?
955 if (base_encoder->bitrate > 0)
956 seq_param->bits_per_second = base_encoder->bitrate * 1000;
958 seq_param->bits_per_second = 0;
960 seq_param->max_num_ref_frames = encoder->max_ref_frames;
961 seq_param->picture_width_in_mbs = encoder->mb_width;
962 seq_param->picture_height_in_mbs = encoder->mb_height;
964 /*sequence field values */
965 seq_param->seq_fields.value = 0;
966 seq_param->seq_fields.bits.chroma_format_idc = 1;
967 seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
968 seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
969 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
970 /* direct_8x8_inference_flag default false */
971 seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
972 g_assert (encoder->log2_max_frame_num >= 4);
973 seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
974 encoder->log2_max_frame_num - 4;
975 /* picture order count */
976 seq_param->seq_fields.bits.pic_order_cnt_type = 0;
977 g_assert (encoder->log2_max_pic_order_cnt >= 4);
978 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
979 encoder->log2_max_pic_order_cnt - 4;
981 seq_param->bit_depth_luma_minus8 = 0;
982 seq_param->bit_depth_chroma_minus8 = 0;
984 /* not used if pic_order_cnt_type == 0 */
985 if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
986 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
987 seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
988 seq_param->offset_for_non_ref_pic = 0;
989 seq_param->offset_for_top_to_bottom_field = 0;
990 memset (seq_param->offset_for_ref_frame, 0,
991 sizeof (seq_param->offset_for_ref_frame));
994 if (encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) {
995 seq_param->frame_cropping_flag = 1;
996 seq_param->frame_crop_left_offset = 0;
997 seq_param->frame_crop_right_offset = 0;
998 seq_param->frame_crop_top_offset = 0;
999 seq_param->frame_crop_bottom_offset =
1000 ((encoder->mb_height * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) /
1001 (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)));
1005 seq_param->vui_parameters_present_flag =
1006 (base_encoder->bitrate > 0 ? TRUE : FALSE);
1007 if (seq_param->vui_parameters_present_flag) {
1008 seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
1009 seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1010 seq_param->vui_fields.bits.timing_info_present_flag =
1011 (base_encoder->bitrate > 0 ? TRUE : FALSE);
1012 if (seq_param->vui_fields.bits.timing_info_present_flag) {
1013 seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1014 seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
1022 fill_va_picture_param (GstVaapiEncoderH264 * encoder,
1023 GstVaapiEncPicture * picture,
1024 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1026 VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1027 GstVaapiEncoderH264Ref *ref_pic;
1031 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
1033 /* reference list, */
1034 pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1035 pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
1037 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1038 for (reflist = g_queue_peek_head_link (&encoder->ref_list);
1039 reflist; reflist = g_list_next (reflist)) {
1040 ref_pic = reflist->data;
1041 g_assert (ref_pic && ref_pic->pic &&
1042 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1044 pic_param->ReferenceFrames[i].picture_id =
1045 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1048 g_assert (i <= 16 && i <= encoder->max_ref_frames);
1050 for (; i < 16; ++i) {
1051 pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
1053 pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1055 pic_param->pic_parameter_set_id = 0;
1056 pic_param->seq_parameter_set_id = 0;
1057 pic_param->last_picture = 0; /* means last encoding picture */
1058 pic_param->frame_num = picture->frame_num;
1059 pic_param->pic_init_qp = encoder->init_qp;
1060 pic_param->num_ref_idx_l0_active_minus1 =
1061 (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
1062 pic_param->num_ref_idx_l1_active_minus1 =
1063 (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
1064 pic_param->chroma_qp_index_offset = 0;
1065 pic_param->second_chroma_qp_index_offset = 0;
1067 /* set picture fields */
1068 pic_param->pic_fields.value = 0;
1069 pic_param->pic_fields.bits.idr_pic_flag =
1070 GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1071 pic_param->pic_fields.bits.reference_pic_flag =
1072 (picture->type != GST_VAAPI_PICTURE_TYPE_B);
1073 pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
1074 pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
1075 pic_param->pic_fields.bits.weighted_bipred_idc = 0;
1076 pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
1077 pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
1078 /* enable debloking */
1079 pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
1080 pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
1081 /* bottom_field_pic_order_in_frame_present_flag */
1082 pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
1083 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
1089 fill_va_slices_param (GstVaapiEncoderH264 * encoder,
1090 GstVaapiEncPicture * picture,
1091 GstVaapiEncoderH264Ref ** reflist_0,
1092 guint reflist_0_count,
1093 GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
1095 VAEncSliceParameterBufferH264 *slice_param;
1096 GstVaapiEncSlice *slice;
1097 guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
1099 guint last_mb_index;
1100 guint i_slice, i_ref;
1104 mb_size = encoder->mb_width * encoder->mb_height;
1106 g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1107 slice_of_mbs = mb_size / encoder->num_slices;
1108 slice_mod_mbs = mb_size % encoder->num_slices;
1110 for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1111 cur_slice_mbs = slice_of_mbs;
1112 if (slice_mod_mbs) {
1116 slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1117 g_assert (slice && slice->param_id != VA_INVALID_ID);
1118 slice_param = slice->param;
1120 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1121 slice_param->macroblock_address = last_mb_index;
1122 slice_param->num_macroblocks = cur_slice_mbs;
1123 slice_param->macroblock_info = VA_INVALID_ID;
1124 slice_param->slice_type = h264_get_slice_type (picture->type);
1125 g_assert (slice_param->slice_type != -1);
1126 slice_param->pic_parameter_set_id = 0;
1127 slice_param->idr_pic_id = encoder->idr_num;
1128 slice_param->pic_order_cnt_lsb = picture->poc;
1130 /* not used if pic_order_cnt_type = 0 */
1131 slice_param->delta_pic_order_cnt_bottom = 0;
1132 memset (slice_param->delta_pic_order_cnt, 0,
1133 sizeof (slice_param->delta_pic_order_cnt));
1135 /* only works for B frames */
1136 slice_param->direct_spatial_mv_pred_flag = FALSE;
1137 /* default equal to picture parameters */
1138 slice_param->num_ref_idx_active_override_flag = FALSE;
1139 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1140 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1142 slice_param->num_ref_idx_l0_active_minus1 = 0;
1143 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1144 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1146 slice_param->num_ref_idx_l1_active_minus1 = 0;
1147 g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1148 g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1151 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1152 for (; i_ref < reflist_0_count; ++i_ref) {
1153 slice_param->RefPicList0[i_ref].picture_id =
1154 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1156 g_assert (i_ref == 1);
1158 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1159 slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1163 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1164 for (; i_ref < reflist_1_count; ++i_ref) {
1165 slice_param->RefPicList1[i_ref].picture_id =
1166 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1168 g_assert (i_ref == 1);
1170 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1171 slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1174 /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1175 slice_param->luma_log2_weight_denom = 0;
1176 slice_param->chroma_log2_weight_denom = 0;
1177 slice_param->luma_weight_l0_flag = FALSE;
1178 memset (slice_param->luma_weight_l0, 0,
1179 sizeof (slice_param->luma_weight_l0));
1180 memset (slice_param->luma_offset_l0, 0,
1181 sizeof (slice_param->luma_offset_l0));
1182 slice_param->chroma_weight_l0_flag = FALSE;
1183 memset (slice_param->chroma_weight_l0, 0,
1184 sizeof (slice_param->chroma_weight_l0));
1185 memset (slice_param->chroma_offset_l0, 0,
1186 sizeof (slice_param->chroma_offset_l0));
1187 slice_param->luma_weight_l1_flag = FALSE;
1188 memset (slice_param->luma_weight_l1, 0,
1189 sizeof (slice_param->luma_weight_l1));
1190 memset (slice_param->luma_offset_l1, 0,
1191 sizeof (slice_param->luma_offset_l1));
1192 slice_param->chroma_weight_l1_flag = FALSE;
1193 memset (slice_param->chroma_weight_l1, 0,
1194 sizeof (slice_param->chroma_weight_l1));
1195 memset (slice_param->chroma_offset_l1, 0,
1196 sizeof (slice_param->chroma_offset_l1));
1198 slice_param->cabac_init_idc = 0;
1199 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1200 if (slice_param->slice_qp_delta > 4)
1201 slice_param->slice_qp_delta = 4;
1202 slice_param->disable_deblocking_filter_idc = 0;
1203 slice_param->slice_alpha_c0_offset_div2 = 2;
1204 slice_param->slice_beta_offset_div2 = 2;
1206 /* set calculation for next slice */
1207 last_mb_index += cur_slice_mbs;
1209 gst_vaapi_enc_picture_add_slice (picture, slice);
1210 gst_vaapi_codec_object_replace (&slice, NULL);
1212 g_assert (last_mb_index == mb_size);
1217 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1219 GstVaapiEncSequence *sequence;
1222 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1223 g_assert (sequence);
1227 if (!fill_va_sequence_param (encoder, sequence))
1230 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1231 !add_sequence_packed_header (encoder, picture, sequence))
1233 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1234 gst_vaapi_codec_object_replace (&sequence, NULL);
1238 gst_vaapi_codec_object_replace (&sequence, NULL);
1243 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1244 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1246 GstVaapiCodedBuffer *const codedbuf =
1247 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1249 if (!fill_va_picture_param (encoder, picture, codedbuf, surface))
1252 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1253 !add_picture_packed_header (encoder, picture)) {
1254 GST_ERROR ("set picture packed header failed");
1262 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1264 GstVaapiEncoderH264Ref *reflist_0[16];
1265 GstVaapiEncoderH264Ref *reflist_1[16];
1266 guint reflist_0_count = 0, reflist_1_count = 0;
1270 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1271 !reference_list_init (encoder, picture,
1272 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1273 GST_ERROR ("reference list reorder failed");
1277 g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames);
1278 if (reflist_0_count > encoder->max_reflist0_count)
1279 reflist_0_count = encoder->max_reflist0_count;
1280 if (reflist_1_count > encoder->max_reflist1_count)
1281 reflist_1_count = encoder->max_reflist1_count;
1283 if (!fill_va_slices_param (encoder, picture,
1284 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1291 ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1293 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1294 GstVaapiEncMiscParam *misc = NULL;
1295 VAEncMiscParameterHRD *hrd;
1296 VAEncMiscParameterRateControl *rate_control;
1299 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1303 gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1305 if (base_encoder->bitrate > 0) {
1306 hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4;
1307 hrd->buffer_size = base_encoder->bitrate * 1000 * 8;
1309 hrd->initial_buffer_fullness = 0;
1310 hrd->buffer_size = 0;
1312 gst_vaapi_codec_object_replace (&misc, NULL);
1314 /* add ratecontrol */
1315 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1316 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1317 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1321 gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1322 rate_control = misc->impl;
1323 memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1324 if (base_encoder->bitrate)
1325 rate_control->bits_per_second = base_encoder->bitrate * 1000;
1327 rate_control->bits_per_second = 0;
1328 rate_control->target_percentage = 70;
1329 rate_control->window_size = 500;
1330 rate_control->initial_qp = encoder->init_qp;
1331 rate_control->min_qp = encoder->min_qp;
1332 rate_control->basic_unit_size = 0;
1333 gst_vaapi_codec_object_replace (&misc, NULL);
1339 static GstVaapiEncoderStatus
1340 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
1342 ensure_tuning (encoder);
1344 if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
1345 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1347 if (!ensure_level (encoder))
1348 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1350 /* Check HW constraints */
1351 if (!ensure_hw_profile_limits (encoder))
1352 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1353 if (encoder->profile_idc > encoder->hw_max_profile_idc)
1354 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1355 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1359 ensure_bitrate (GstVaapiEncoderH264 * encoder)
1361 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1363 /* Default compression: 48 bits per macroblock in "high-compression" mode */
1364 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1365 case GST_VAAPI_RATECONTROL_CBR:
1366 case GST_VAAPI_RATECONTROL_VBR:
1367 case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
1368 if (!base_encoder->bitrate) {
1369 /* According to the literature and testing, CABAC entropy coding
1370 mode could provide for +10% to +18% improvement in general,
1371 thus estimating +15% here ; and using adaptive 8x8 transforms
1372 in I-frames could bring up to +10% improvement. */
1373 guint bits_per_mb = 48;
1374 if (!encoder->use_cabac)
1375 bits_per_mb += (bits_per_mb * 15) / 100;
1376 if (!encoder->use_dct8x8)
1377 bits_per_mb += (bits_per_mb * 10) / 100;
1379 base_encoder->bitrate =
1380 encoder->mb_width * encoder->mb_height * bits_per_mb *
1381 GST_VAAPI_ENCODER_FPS_N (encoder) /
1382 GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
1383 GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
1387 base_encoder->bitrate = 0;
1394 reset_properties (GstVaapiEncoderH264 * encoder)
1396 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1399 if (encoder->idr_period < base_encoder->keyframe_period)
1400 encoder->idr_period = base_encoder->keyframe_period;
1401 if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD)
1402 encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD;
1404 if (encoder->min_qp > encoder->init_qp ||
1405 (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
1406 encoder->min_qp < encoder->init_qp))
1407 encoder->min_qp = encoder->init_qp;
1409 mb_size = encoder->mb_width * encoder->mb_height;
1410 if (encoder->num_slices > (mb_size + 1) / 2)
1411 encoder->num_slices = (mb_size + 1) / 2;
1412 g_assert (encoder->num_slices);
1414 if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
1415 encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
1417 if (encoder->num_bframes > 50)
1418 encoder->num_bframes = 50;
1420 if (encoder->num_bframes)
1421 encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1422 GST_VAAPI_ENCODER_FPS_N (encoder);
1424 encoder->cts_offset = 0;
1426 /* init max_frame_num, max_poc */
1427 encoder->log2_max_frame_num =
1428 h264_get_log2_max_frame_num (encoder->idr_period);
1429 g_assert (encoder->log2_max_frame_num >= 4);
1430 encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1431 encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1432 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1434 encoder->frame_index = 0;
1435 encoder->idr_num = 0;
1436 encoder->max_reflist0_count = 1;
1437 encoder->max_reflist1_count = encoder->num_bframes > 0;
1438 encoder->max_ref_frames =
1439 encoder->max_reflist0_count + encoder->max_reflist1_count;
1442 static GstVaapiEncoderStatus
1443 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
1444 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1446 GstVaapiEncoderH264 *const encoder =
1447 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1448 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1449 GstVaapiSurfaceProxy *reconstruct = NULL;
1451 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
1453 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1455 if (!ensure_sequence (encoder, picture))
1457 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1459 if (!ensure_misc (encoder, picture))
1461 if (!ensure_slices (encoder, picture))
1463 if (!gst_vaapi_enc_picture_encode (picture))
1466 if (!reference_list_update (encoder, picture, reconstruct))
1469 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1472 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1477 static GstVaapiEncoderStatus
1478 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
1480 GstVaapiEncoderH264 *const encoder =
1481 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1482 GstVaapiEncPicture *pic;
1484 encoder->frame_index = 0;
1485 encoder->cur_frame_num = 0;
1486 encoder->cur_present_index = 0;
1487 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1488 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1489 gst_vaapi_enc_picture_unref (pic);
1491 g_queue_clear (&encoder->reorder_frame_list);
1493 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1496 /* Generate "codec-data" buffer */
1497 static GstVaapiEncoderStatus
1498 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
1499 GstBuffer ** out_buffer_ptr)
1501 GstVaapiEncoderH264 *const encoder =
1502 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1503 const guint32 configuration_version = 0x01;
1504 const guint32 nal_length_size = 4;
1505 guint8 profile_idc, profile_comp, level_idc;
1506 GstMapInfo sps_info, pps_info;
1507 GstBitWriter writer;
1510 if (!encoder->sps_data || !encoder->pps_data)
1511 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1512 if (gst_buffer_get_size (encoder->sps_data) < 4)
1513 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1515 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1516 goto error_map_sps_buffer;
1518 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
1519 goto error_map_pps_buffer;
1521 /* skip sps_data[0], which is the nal_unit_type */
1522 profile_idc = sps_info.data[1];
1523 profile_comp = sps_info.data[2];
1524 level_idc = sps_info.data[3];
1527 gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8);
1528 gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8);
1529 gst_bit_writer_put_bits_uint32 (&writer, profile_idc, 8);
1530 gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8);
1531 gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8);
1532 gst_bit_writer_put_bits_uint32 (&writer, 0x3f, 6); /* 111111 */
1533 gst_bit_writer_put_bits_uint32 (&writer, nal_length_size - 1, 2);
1534 gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /* 111 */
1537 gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* SPS count = 1 */
1538 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
1539 gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16);
1540 gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size);
1543 gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /* PPS count = 1 */
1544 gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16);
1545 gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size);
1547 gst_buffer_unmap (encoder->pps_data, &pps_info);
1548 gst_buffer_unmap (encoder->sps_data, &sps_info);
1550 buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer),
1551 GST_BIT_WRITER_BIT_SIZE (&writer) / 8);
1553 goto error_alloc_buffer;
1554 *out_buffer_ptr = buffer;
1556 gst_bit_writer_clear (&writer, FALSE);
1557 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1560 error_map_sps_buffer:
1562 GST_ERROR ("failed to map SPS packed header");
1563 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1565 error_map_pps_buffer:
1567 GST_ERROR ("failed to map PPS packed header");
1568 gst_buffer_unmap (encoder->sps_data, &sps_info);
1569 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1573 GST_ERROR ("failed to allocate codec-data buffer");
1574 gst_bit_writer_clear (&writer, TRUE);
1575 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1579 static GstVaapiEncoderStatus
1580 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
1581 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1583 GstVaapiEncoderH264 *const encoder =
1584 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1585 GstVaapiEncPicture *picture;
1586 gboolean is_idr = FALSE;
1591 if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1592 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1594 /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1595 dump B frames from queue, sometime, there may also have P frame or I frame */
1596 g_assert (encoder->num_bframes > 0);
1597 g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1598 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1599 picture = g_queue_pop_head (&encoder->reorder_frame_list);
1601 if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1602 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1607 /* new frame coming */
1608 picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1610 GST_WARNING ("create H264 picture failed, frame timestamp:%"
1611 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1612 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1614 ++encoder->cur_present_index;
1615 picture->poc = ((encoder->cur_present_index * 2) %
1616 encoder->max_pic_order_cnt);
1618 is_idr = (encoder->frame_index == 0 ||
1619 encoder->frame_index >= encoder->idr_period);
1621 /* check key frames */
1622 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1623 (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) ==
1625 ++encoder->cur_frame_num;
1626 ++encoder->frame_index;
1628 /* b frame enabled, check queue of reorder_frame_list */
1629 if (encoder->num_bframes
1630 && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1631 GstVaapiEncPicture *p_pic;
1633 p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1634 _set_p_frame (p_pic, encoder);
1635 g_queue_foreach (&encoder->reorder_frame_list,
1636 (GFunc) _set_b_frame, encoder);
1637 ++encoder->cur_frame_num;
1638 _set_key_frame (picture, encoder, is_idr);
1639 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1641 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1642 } else { /* no b frames in queue */
1643 _set_key_frame (picture, encoder, is_idr);
1644 g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1645 if (encoder->num_bframes)
1646 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1651 /* new p/b frames coming */
1652 ++encoder->frame_index;
1653 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1654 g_queue_get_length (&encoder->reorder_frame_list) <
1655 encoder->num_bframes) {
1656 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1657 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1660 ++encoder->cur_frame_num;
1661 _set_p_frame (picture, encoder);
1663 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1664 g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame,
1666 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1667 g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1672 frame = GST_VAAPI_ENC_PICTURE_GET_FRAME (picture);
1673 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1674 frame->pts += encoder->cts_offset;
1677 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1680 static GstVaapiEncoderStatus
1681 set_context_info (GstVaapiEncoder * base_encoder)
1683 GstVaapiEncoderH264 *const encoder =
1684 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1685 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1686 const guint DEFAULT_SURFACES_COUNT = 3;
1688 /* Maximum sizes for common headers (in bits) */
1691 MAX_SPS_HDR_SIZE = 16473,
1692 MAX_VUI_PARAMS_SIZE = 210,
1693 MAX_HRD_PARAMS_SIZE = 4103,
1694 MAX_PPS_HDR_SIZE = 101,
1695 MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1698 if (!ensure_hw_profile (encoder))
1699 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1701 base_encoder->num_ref_frames =
1702 (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1704 /* Only YUV 4:2:0 formats are supported for now. This means that we
1705 have a limit of 3200 bits per macroblock. */
1706 /* XXX: check profile and compute RawMbBits */
1707 base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
1708 GST_ROUND_UP_16 (vip->height) / 256) * 400;
1710 /* Account for SPS header */
1711 /* XXX: exclude scaling lists, MVC/SVC extensions */
1712 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1713 MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1715 /* Account for PPS header */
1716 /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1717 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1719 /* Account for slice header */
1720 base_encoder->codedbuf_size += encoder->num_slices * (4 +
1721 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1723 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1726 static GstVaapiEncoderStatus
1727 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
1729 GstVaapiEncoderH264 *const encoder =
1730 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1731 GstVaapiEncoderStatus status;
1733 encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1734 encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1736 status = ensure_profile_and_level (encoder);
1737 if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
1740 if (!ensure_bitrate (encoder))
1743 reset_properties (encoder);
1744 return set_context_info (base_encoder);
1747 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1751 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
1753 GstVaapiEncoderH264 *const encoder =
1754 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1757 g_queue_init (&encoder->reorder_frame_list);
1758 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1760 /* reference frames */
1761 g_queue_init (&encoder->ref_list);
1762 encoder->max_ref_frames = 0;
1763 encoder->max_reflist0_count = 1;
1764 encoder->max_reflist1_count = 1;
1770 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
1772 /*free private buffers */
1773 GstVaapiEncoderH264 *const encoder =
1774 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1775 GstVaapiEncPicture *pic;
1776 GstVaapiEncoderH264Ref *ref;
1778 gst_buffer_replace (&encoder->sps_data, NULL);
1779 gst_buffer_replace (&encoder->pps_data, NULL);
1781 while (!g_queue_is_empty (&encoder->ref_list)) {
1782 ref = g_queue_pop_head (&encoder->ref_list);
1783 reference_pic_free (encoder, ref);
1785 g_queue_clear (&encoder->ref_list);
1787 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1788 pic = g_queue_pop_head (&encoder->reorder_frame_list);
1789 gst_vaapi_enc_picture_unref (pic);
1791 g_queue_clear (&encoder->reorder_frame_list);
1795 static GstVaapiEncoderStatus
1796 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
1797 gint prop_id, const GValue * value)
1799 GstVaapiEncoderH264 *const encoder =
1800 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1803 case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
1804 encoder->num_bframes = g_value_get_uint (value);
1806 case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
1807 encoder->init_qp = g_value_get_uint (value);
1809 case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
1810 encoder->min_qp = g_value_get_uint (value);
1812 case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
1813 encoder->num_slices = g_value_get_uint (value);
1815 case GST_VAAPI_ENCODER_H264_PROP_CABAC:
1816 encoder->use_cabac = g_value_get_boolean (value);
1818 case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
1819 encoder->use_dct8x8 = g_value_get_boolean (value);
1822 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
1824 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1827 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
1829 static inline const GstVaapiEncoderClass *
1830 gst_vaapi_encoder_h264_class (void)
1832 static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1833 GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1834 .set_property = gst_vaapi_encoder_h264_set_property,
1835 .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1837 return &GstVaapiEncoderH264Class;
1841 * gst_vaapi_encoder_h264_new:
1842 * @display: a #GstVaapiDisplay
1844 * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
1845 * only supported output stream format is "byte-stream" format.
1847 * Return value: the newly allocated #GstVaapiEncoder object
1850 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1852 return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1856 * gst_vaapi_encoder_h264_get_default_properties:
1858 * Determines the set of common and H.264 specific encoder properties.
1859 * The caller owns an extra reference to the resulting array of
1860 * #GstVaapiEncoderPropInfo elements, so it shall be released with
1861 * g_ptr_array_unref() after usage.
1863 * Return value: the set of encoder properties for #GstVaapiEncoderH264,
1864 * or %NULL if an error occurred.
1867 gst_vaapi_encoder_h264_get_default_properties (void)
1869 const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
1872 props = gst_vaapi_encoder_properties_get_default (klass);
1877 * GstVaapiEncoderH264:max-bframes:
1879 * The number of B-frames between I and P.
1881 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1882 GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
1883 g_param_spec_uint ("max-bframes",
1884 "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
1885 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1888 * GstVaapiEncoderH264:init-qp:
1890 * The initial quantizer value.
1892 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1893 GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
1894 g_param_spec_uint ("init-qp",
1895 "Initial QP", "Initial quantizer value", 1, 51, 26,
1896 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1899 * GstVaapiEncoderH264:min-qp:
1901 * The minimum quantizer value.
1903 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1904 GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
1905 g_param_spec_uint ("min-qp",
1906 "Minimum QP", "Minimum quantizer value", 1, 51, 1,
1907 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1910 * GstVaapiEncoderH264:num-slices:
1912 * The number of slices per frame.
1914 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1915 GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
1916 g_param_spec_uint ("num-slices",
1918 "Number of slices per frame",
1919 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1922 * GstVaapiEncoderH264:cabac:
1924 * Enable CABAC entropy coding mode for improved compression ratio,
1925 * at the expense that the minimum target profile is Main. Default
1926 * is CAVLC entropy coding mode.
1928 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1929 GST_VAAPI_ENCODER_H264_PROP_CABAC,
1930 g_param_spec_boolean ("cabac",
1932 "Enable CABAC entropy coding mode",
1933 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1936 * GstVaapiEncoderH264:dct8x8:
1938 * Enable adaptive use of 8x8 transforms in I-frames. This improves
1939 * the compression ratio by the minimum target profile is High.
1940 * Default is to use 4x4 DCT only.
1942 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
1943 GST_VAAPI_ENCODER_H264_PROP_DCT8X8,
1944 g_param_spec_boolean ("dct8x8",
1946 "Enable adaptive use of 8x8 transforms in I-frames",
1947 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1953 * gst_vaapi_encoder_h264_set_max_profile:
1954 * @encoder: a #GstVaapiEncoderH264
1955 * @profile: an H.264 #GstVaapiProfile
1957 * Notifies the @encoder to use coding tools from the supplied
1960 * This means that if the minimal profile derived to
1961 * support the specified coding tools is greater than this @profile,
1962 * then an error is returned when the @encoder is configured.
1964 * Return value: %TRUE on success
1967 gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
1968 GstVaapiProfile profile)
1972 g_return_val_if_fail (encoder != NULL, FALSE);
1973 g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
1975 if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
1978 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
1982 encoder->max_profile_idc = profile_idc;
1987 * gst_vaapi_encoder_h264_get_profile_and_level:
1988 * @encoder: a #GstVaapiEncoderH264
1989 * @out_profile_ptr: return location for the #GstVaapiProfile
1990 * @out_level_ptr: return location for the #GstVaapiLevelH264
1992 * Queries the H.264 @encoder for the active profile and level. That
1993 * information is only constructed and valid after the encoder is
1994 * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
1995 * function is called.
1997 * Return value: %TRUE on success
2000 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
2001 GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
2003 g_return_val_if_fail (encoder != NULL, FALSE);
2005 if (!encoder->profile || !encoder->level)
2008 if (out_profile_ptr)
2009 *out_profile_ptr = encoder->profile;
2011 *out_level_ptr = encoder->level;