2 * gstvaapiencoder_h264.c - H.264 encoder
4 * Copyright (C) 2012-2014 Intel Corporation
5 * Author: Wind Yuan <feng.yuan@intel.com>
6 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA
26 #include <va/va_enc_h264.h>
27 #include <gst/base/gstbitwriter.h>
28 #include <gst/codecparsers/gsth264parser.h>
29 #include "gstvaapicompat.h"
30 #include "gstvaapiencoder_priv.h"
31 #include "gstvaapiencoder_h264.h"
32 #include "gstvaapiutils_h264.h"
33 #include "gstvaapiutils_h264_priv.h"
34 #include "gstvaapicodedbufferproxy_priv.h"
35 #include "gstvaapisurface.h"
38 #include "gstvaapidebug.h"
40 /* Define the maximum number of views supported */
41 #define MAX_NUM_VIEWS 2
43 /* Define the maximum IDR period */
44 #define MAX_IDR_PERIOD 512
46 /* Default CPB length (in milliseconds) */
47 #define DEFAULT_CPB_LENGTH 1500
49 /* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */
52 /* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */
55 /* Define default rate control mode ("constant-qp") */
56 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
58 /* Supported set of VA rate controls, within this implementation */
59 #define SUPPORTED_RATECONTROLS \
60 (GST_VAAPI_RATECONTROL_MASK (CQP) | \
61 GST_VAAPI_RATECONTROL_MASK (CBR) | \
62 GST_VAAPI_RATECONTROL_MASK (VBR) | \
63 GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
65 /* Supported set of tuning options, within this implementation */
66 #define SUPPORTED_TUNE_OPTIONS \
67 (GST_VAAPI_ENCODER_TUNE_MASK (NONE) | \
68 GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION))
70 /* Supported set of VA packed headers, within this implementation */
71 #define SUPPORTED_PACKED_HEADERS \
72 (VA_ENC_PACKED_HEADER_SEQUENCE | \
73 VA_ENC_PACKED_HEADER_PICTURE | \
74 VA_ENC_PACKED_HEADER_SLICE | \
75 VA_ENC_PACKED_HEADER_RAW_DATA)
77 #define GST_H264_NAL_REF_IDC_NONE 0
78 #define GST_H264_NAL_REF_IDC_LOW 1
79 #define GST_H264_NAL_REF_IDC_MEDIUM 2
80 #define GST_H264_NAL_REF_IDC_HIGH 3
84 GstVaapiSurfaceProxy *pic;
87 } GstVaapiEncoderH264Ref;
91 GST_VAAPI_ENC_H264_REORD_NONE = 0,
92 GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
93 GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
94 } GstVaapiEncH264ReorderState;
96 typedef struct _GstVaapiH264ViewRefPool
100 guint max_reflist0_count;
101 guint max_reflist1_count;
102 } GstVaapiH264ViewRefPool;
104 typedef struct _GstVaapiH264ViewReorderPool
106 GQueue reorder_frame_list;
110 guint cur_present_index;
111 } GstVaapiH264ViewReorderPool;
113 static inline gboolean
114 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
116 return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
119 /* Get slice_type value for H.264 specification */
121 h264_get_slice_type (GstVaapiPictureType type)
124 case GST_VAAPI_PICTURE_TYPE_I:
125 return GST_H264_I_SLICE;
126 case GST_VAAPI_PICTURE_TYPE_P:
127 return GST_H264_P_SLICE;
128 case GST_VAAPI_PICTURE_TYPE_B:
129 return GST_H264_B_SLICE;
136 /* Get log2_max_frame_num value for H.264 specification */
138 h264_get_log2_max_frame_num (guint num)
150 /* must be greater than 4 */
154 /* Determines the cpbBrNalFactor based on the supplied profile */
156 h264_get_cpb_nal_factor (GstVaapiProfile profile)
162 case GST_VAAPI_PROFILE_H264_HIGH:
165 case GST_VAAPI_PROFILE_H264_HIGH10:
168 case GST_VAAPI_PROFILE_H264_HIGH_422:
169 case GST_VAAPI_PROFILE_H264_HIGH_444:
172 case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH:
173 case GST_VAAPI_PROFILE_H264_STEREO_HIGH:
174 f = 1500; /* H.10.2.1 (r) */
183 /* ------------------------------------------------------------------------- */
184 /* --- H.264 Bitstream Writer --- */
185 /* ------------------------------------------------------------------------- */
187 #define WRITE_UINT32(bs, val, nbits) do { \
188 if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) { \
189 GST_WARNING ("failed to write uint32, nbits: %d", nbits); \
194 #define WRITE_UE(bs, val) do { \
195 if (!bs_write_ue (bs, val)) { \
196 GST_WARNING ("failed to write ue(v)"); \
201 #define WRITE_SE(bs, val) do { \
202 if (!bs_write_se (bs, val)) { \
203 GST_WARNING ("failed to write se(v)"); \
208 /* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */
210 bs_write_ue (GstBitWriter * bs, guint32 value)
212 guint32 size_in_bits = 0;
213 guint32 tmp_value = ++value;
220 && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1))
222 if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits))
227 /* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */
229 bs_write_se (GstBitWriter * bs, gint32 value)
234 new_val = -(value << 1);
236 new_val = (value << 1) - 1;
238 if (!bs_write_ue (bs, new_val))
243 /* Write the NAL unit header */
245 bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc,
246 guint32 nal_unit_type)
248 WRITE_UINT32 (bs, 0, 1);
249 WRITE_UINT32 (bs, nal_ref_idc, 2);
250 WRITE_UINT32 (bs, nal_unit_type, 5);
256 GST_WARNING ("failed to write NAL unit header");
261 /* Write the MVC NAL unit header extension */
263 bs_write_nal_header_mvc_extension (GstBitWriter * bs,
264 GstVaapiEncPicture * picture, guint32 view_id)
266 guint32 svc_extension_flag = 0;
267 guint32 non_idr_flag = 1;
268 guint32 priority_id = 0;
269 guint32 temporal_id = 0;
270 guint32 anchor_pic_flag = 0;
271 guint32 inter_view_flag = 0;
273 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
276 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
278 /* svc_extension_flag == 0 for mvc stream */
279 WRITE_UINT32 (bs, svc_extension_flag, 1);
281 WRITE_UINT32 (bs, non_idr_flag, 1);
282 WRITE_UINT32 (bs, priority_id, 6);
283 WRITE_UINT32 (bs, view_id, 10);
284 WRITE_UINT32 (bs, temporal_id, 3);
285 WRITE_UINT32 (bs, anchor_pic_flag, 1);
286 WRITE_UINT32 (bs, inter_view_flag, 1);
287 WRITE_UINT32 (bs, 1, 1);
294 GST_WARNING ("failed to write NAL unit header");
299 /* Write the NAL unit trailing bits */
301 bs_write_trailing_bits (GstBitWriter * bs)
303 if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
305 gst_bit_writer_align_bytes_unchecked (bs, 0);
311 GST_WARNING ("failed to write NAL unit trailing bits");
316 /* Write an SPS NAL unit */
318 bs_write_sps_data (GstBitWriter * bs,
319 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
320 const VAEncMiscParameterHRD * hrd_params)
323 guint32 constraint_set0_flag, constraint_set1_flag;
324 guint32 constraint_set2_flag, constraint_set3_flag;
325 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
326 gboolean nal_hrd_parameters_present_flag;
328 guint32 b_qpprime_y_zero_transform_bypass = 0;
329 guint32 residual_color_transform_flag = 0;
330 guint32 pic_height_in_map_units =
331 (seq_param->seq_fields.bits.frame_mbs_only_flag ?
332 seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
333 guint32 mb_adaptive_frame_field =
334 !seq_param->seq_fields.bits.frame_mbs_only_flag;
337 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
338 constraint_set0_flag = /* A.2.1 (baseline profile constraints) */
339 profile == GST_VAAPI_PROFILE_H264_BASELINE ||
340 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
341 constraint_set1_flag = /* A.2.2 (main profile constraints) */
342 profile == GST_VAAPI_PROFILE_H264_MAIN ||
343 profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
344 constraint_set2_flag = 0;
345 constraint_set3_flag = 0;
348 WRITE_UINT32 (bs, profile_idc, 8);
349 /* constraint_set0_flag */
350 WRITE_UINT32 (bs, constraint_set0_flag, 1);
351 /* constraint_set1_flag */
352 WRITE_UINT32 (bs, constraint_set1_flag, 1);
353 /* constraint_set2_flag */
354 WRITE_UINT32 (bs, constraint_set2_flag, 1);
355 /* constraint_set3_flag */
356 WRITE_UINT32 (bs, constraint_set3_flag, 1);
357 /* reserved_zero_4bits */
358 WRITE_UINT32 (bs, 0, 4);
360 WRITE_UINT32 (bs, seq_param->level_idc, 8);
361 /* seq_parameter_set_id */
362 WRITE_UE (bs, seq_param->seq_parameter_set_id);
364 if (profile == GST_VAAPI_PROFILE_H264_HIGH ||
365 profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
366 profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) {
367 /* for high profile */
368 /* chroma_format_idc = 1, 4:2:0 */
369 WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
370 if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
371 WRITE_UINT32 (bs, residual_color_transform_flag, 1);
373 /* bit_depth_luma_minus8 */
374 WRITE_UE (bs, seq_param->bit_depth_luma_minus8);
375 /* bit_depth_chroma_minus8 */
376 WRITE_UE (bs, seq_param->bit_depth_chroma_minus8);
377 /* b_qpprime_y_zero_transform_bypass */
378 WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1);
380 /* seq_scaling_matrix_present_flag */
381 g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
383 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
386 if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
388 i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
390 gst_bit_writer_put_bits_uint8 (bs,
391 seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
392 if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
394 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
401 /* log2_max_frame_num_minus4 */
402 WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4);
403 /* pic_order_cnt_type */
404 WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type);
406 if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
407 /* log2_max_pic_order_cnt_lsb_minus4 */
408 WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
409 } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
410 g_assert (0 && "only POC type 0 is supported");
412 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
413 WRITE_SE (bs, seq_param->offset_for_non_ref_pic);
414 WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field);
415 WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle);
416 for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
417 WRITE_SE (bs, seq_param->offset_for_ref_frame[i]);
422 WRITE_UE (bs, seq_param->max_num_ref_frames);
423 /* gaps_in_frame_num_value_allowed_flag */
424 WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1);
426 /* pic_width_in_mbs_minus1 */
427 WRITE_UE (bs, seq_param->picture_width_in_mbs - 1);
428 /* pic_height_in_map_units_minus1 */
429 WRITE_UE (bs, pic_height_in_map_units - 1);
430 /* frame_mbs_only_flag */
431 WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
433 if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
434 g_assert (0 && "only progressive frames encoding is supported");
435 WRITE_UINT32 (bs, mb_adaptive_frame_field, 1);
438 /* direct_8x8_inference_flag */
439 WRITE_UINT32 (bs, 0, 1);
440 /* frame_cropping_flag */
441 WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1);
443 if (seq_param->frame_cropping_flag) {
444 /* frame_crop_left_offset */
445 WRITE_UE (bs, seq_param->frame_crop_left_offset);
446 /* frame_crop_right_offset */
447 WRITE_UE (bs, seq_param->frame_crop_right_offset);
448 /* frame_crop_top_offset */
449 WRITE_UE (bs, seq_param->frame_crop_top_offset);
450 /* frame_crop_bottom_offset */
451 WRITE_UE (bs, seq_param->frame_crop_bottom_offset);
454 /* vui_parameters_present_flag */
455 WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
456 if (seq_param->vui_parameters_present_flag) {
457 /* aspect_ratio_info_present_flag */
459 seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
460 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
461 WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
462 if (seq_param->aspect_ratio_idc == 0xFF) {
463 WRITE_UINT32 (bs, seq_param->sar_width, 16);
464 WRITE_UINT32 (bs, seq_param->sar_height, 16);
468 /* overscan_info_present_flag */
469 WRITE_UINT32 (bs, 0, 1);
470 /* video_signal_type_present_flag */
471 WRITE_UINT32 (bs, 0, 1);
472 /* chroma_loc_info_present_flag */
473 WRITE_UINT32 (bs, 0, 1);
475 /* timing_info_present_flag */
476 WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1);
477 if (seq_param->vui_fields.bits.timing_info_present_flag) {
478 WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32);
479 WRITE_UINT32 (bs, seq_param->time_scale, 32);
480 WRITE_UINT32 (bs, 1, 1); /* fixed_frame_rate_flag */
483 /* nal_hrd_parameters_present_flag */
484 nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0;
485 nal_hrd_parameters_present_flag = FALSE; /* XXX: disabled for now */
486 WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
487 if (nal_hrd_parameters_present_flag) {
491 WRITE_UINT32 (bs, SX_BITRATE - 6, 4); /* bit_rate_scale */
492 WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4); /* cpb_size_scale */
494 for (i = 0; i < 1; ++i) {
495 /* bit_rate_value_minus1[0] */
496 WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
497 /* cpb_size_value_minus1[0] */
498 WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
500 WRITE_UINT32 (bs, 1, 1);
502 /* initial_cpb_removal_delay_length_minus1 */
503 WRITE_UINT32 (bs, 23, 5);
504 /* cpb_removal_delay_length_minus1 */
505 WRITE_UINT32 (bs, 23, 5);
506 /* dpb_output_delay_length_minus1 */
507 WRITE_UINT32 (bs, 23, 5);
508 /* time_offset_length */
509 WRITE_UINT32 (bs, 23, 5);
512 /* vcl_hrd_parameters_present_flag */
513 WRITE_UINT32 (bs, 0, 1);
515 if (nal_hrd_parameters_present_flag
516 || 0 /*vcl_hrd_parameters_present_flag */ ) {
517 /* low_delay_hrd_flag */
518 WRITE_UINT32 (bs, 0, 1);
520 /* pic_struct_present_flag */
521 WRITE_UINT32 (bs, 0, 1);
522 /* bs_restriction_flag */
523 WRITE_UINT32 (bs, 0, 1);
530 GST_WARNING ("failed to write SPS NAL unit");
536 bs_write_sps (GstBitWriter * bs,
537 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
538 const VAEncMiscParameterHRD * hrd_params)
540 if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
543 /* rbsp_trailing_bits */
544 bs_write_trailing_bits (bs);
550 bs_write_subset_sps (GstBitWriter * bs,
551 const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
552 guint num_views, const VAEncMiscParameterHRD * hrd_params)
556 if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
559 if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH ||
560 profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) {
561 guint32 num_views_minus1, num_level_values_signalled_minus1;
563 num_views_minus1 = num_views - 1;
564 g_assert (num_views_minus1 < 1024);
566 /* bit equal to one */
567 WRITE_UINT32 (bs, 1, 1);
569 WRITE_UE (bs, num_views_minus1);
571 for (i = 0; i <= num_views_minus1; i++)
574 for (i = 1; i <= num_views_minus1; i++) {
575 guint32 num_anchor_refs_l0 = 0;
576 WRITE_UE (bs, num_anchor_refs_l0);
577 for (j = 0; j < num_anchor_refs_l0; j++)
580 guint32 num_anchor_refs_l1 = 0;
581 WRITE_UE (bs, num_anchor_refs_l1);
582 for (j = 0; j < num_anchor_refs_l1; j++)
586 for (i = 1; i <= num_views_minus1; i++) {
587 guint32 num_non_anchor_refs_l0 = 0;
588 WRITE_UE (bs, num_non_anchor_refs_l0);
589 for (j = 0; j < num_non_anchor_refs_l0; j++)
592 guint32 num_non_anchor_refs_l1 = 0;
593 WRITE_UE (bs, num_non_anchor_refs_l1);
594 for (j = 0; j < num_non_anchor_refs_l1; j++)
598 /* num level values signalled minus1 */
599 num_level_values_signalled_minus1 = 0;
600 g_assert (num_level_values_signalled_minus1 < 64);
601 WRITE_UE (bs, num_level_values_signalled_minus1);
603 for (i = 0; i <= num_level_values_signalled_minus1; i++) {
604 guint16 num_applicable_ops_minus1 = 0;
605 g_assert (num_applicable_ops_minus1 < 1024);
607 WRITE_UINT32 (bs, seq_param->level_idc, 8);
608 WRITE_UE (bs, num_applicable_ops_minus1);
610 for (j = 0; j <= num_applicable_ops_minus1; j++) {
611 guint8 temporal_id = 0;
612 guint16 num_target_views_minus1 = 1;
614 WRITE_UINT32 (bs, temporal_id, 3);
615 WRITE_UE (bs, num_target_views_minus1);
617 for (k = 0; k <= num_target_views_minus1; k++)
620 WRITE_UE (bs, num_views_minus1);
624 /* mvc_vui_parameters_present_flag */
625 WRITE_UINT32 (bs, 0, 1);
628 /* additional_extension2_flag */
629 WRITE_UINT32 (bs, 0, 1);
631 /* rbsp_trailing_bits */
632 bs_write_trailing_bits (bs);
638 GST_WARNING ("failed to write subset SPS NAL unit");
644 /* Write a PPS NAL unit */
646 bs_write_pps (GstBitWriter * bs,
647 const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
649 guint32 num_slice_groups_minus1 = 0;
650 guint32 pic_init_qs_minus26 = 0;
651 guint32 redundant_pic_cnt_present_flag = 0;
653 /* pic_parameter_set_id */
654 WRITE_UE (bs, pic_param->pic_parameter_set_id);
655 /* seq_parameter_set_id */
656 WRITE_UE (bs, pic_param->seq_parameter_set_id);
657 /* entropy_coding_mode_flag */
658 WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
659 /* pic_order_present_flag */
660 WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1);
662 WRITE_UE (bs, num_slice_groups_minus1);
664 if (num_slice_groups_minus1 > 0) {
665 /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)");
667 WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1);
668 WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1);
669 WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
670 WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);
671 /* pic_init_qp_minus26 */
672 WRITE_SE (bs, pic_param->pic_init_qp - 26);
673 /* pic_init_qs_minus26 */
674 WRITE_SE (bs, pic_init_qs_minus26);
675 /* chroma_qp_index_offset */
676 WRITE_SE (bs, pic_param->chroma_qp_index_offset);
679 pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
680 WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
681 WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1);
684 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
685 WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
687 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
688 if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
689 g_assert (0 && "unsupported scaling lists");
693 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
695 gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
699 WRITE_SE (bs, pic_param->second_chroma_qp_index_offset);
702 /* rbsp_trailing_bits */
703 bs_write_trailing_bits (bs);
709 GST_WARNING ("failed to write PPS NAL unit");
714 /* ------------------------------------------------------------------------- */
715 /* --- H.264 Encoder --- */
716 /* ------------------------------------------------------------------------- */
718 #define GST_VAAPI_ENCODER_H264_CAST(encoder) \
719 ((GstVaapiEncoderH264 *)(encoder))
721 struct _GstVaapiEncoderH264
723 GstVaapiEncoder parent_instance;
725 GstVaapiProfile profile;
726 GstVaapiLevelH264 level;
728 guint8 max_profile_idc;
729 guint8 hw_max_profile_idc;
740 GstClockTime cts_offset;
741 gboolean config_changed;
744 guint32 max_frame_num;
745 guint32 log2_max_frame_num;
746 guint32 max_pic_order_cnt;
747 guint32 log2_max_pic_order_cnt;
749 guint8 pic_order_cnt_type;
750 guint8 delta_pic_order_always_zero_flag;
753 GstBuffer *subset_sps_data;
756 guint bitrate_bits; // bitrate (bits)
757 guint cpb_length; // length of CPB buffer (ms)
758 guint cpb_length_bits; // length of CPB buffer (bits)
764 GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS];
765 GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS];
768 /* Write a Slice NAL unit */
770 bs_write_slice (GstBitWriter * bs,
771 const VAEncSliceParameterBufferH264 * slice_param,
772 GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
774 const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
775 guint32 field_pic_flag = 0;
776 guint32 ref_pic_list_modification_flag_l0 = 0;
777 guint32 ref_pic_list_modification_flag_l1 = 0;
778 guint32 no_output_of_prior_pics_flag = 0;
779 guint32 long_term_reference_flag = 0;
780 guint32 adaptive_ref_pic_marking_mode_flag = 0;
782 /* first_mb_in_slice */
783 WRITE_UE (bs, slice_param->macroblock_address);
785 WRITE_UE (bs, slice_param->slice_type);
786 /* pic_parameter_set_id */
787 WRITE_UE (bs, slice_param->pic_parameter_set_id);
789 WRITE_UINT32 (bs, picture->frame_num, encoder->log2_max_frame_num);
791 /* XXX: only frames (i.e. non-interlaced) are supported for now */
792 /* frame_mbs_only_flag == 0 */
795 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
796 WRITE_UE (bs, slice_param->idr_pic_id);
798 /* XXX: only POC type 0 is supported */
799 if (!encoder->pic_order_cnt_type) {
800 WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb,
801 encoder->log2_max_pic_order_cnt);
802 /* bottom_field_pic_order_in_frame_present_flag is FALSE */
803 if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
804 WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom);
805 } else if (encoder->pic_order_cnt_type == 1 &&
806 !encoder->delta_pic_order_always_zero_flag) {
807 WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]);
808 if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
809 WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]);
811 /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */
813 /* only works for B-frames */
814 if (slice_param->slice_type == 1)
815 WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1);
817 /* not supporting SP slices */
818 if (slice_param->slice_type == 0 || slice_param->slice_type == 1) {
819 WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1);
820 if (slice_param->num_ref_idx_active_override_flag) {
821 WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1);
822 if (slice_param->slice_type == 1)
823 WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1);
826 /* XXX: not supporting custom reference picture list modifications */
827 if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4))
828 WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1);
829 if (slice_param->slice_type == 1)
830 WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1);
832 /* we have: weighted_pred_flag == FALSE and */
833 /* : weighted_bipred_idc == FALSE */
834 if ((pic_param->pic_fields.bits.weighted_pred_flag &&
835 (slice_param->slice_type == 0)) ||
836 ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) &&
837 (slice_param->slice_type == 1))) {
838 /* XXXX: add pred_weight_table() */
841 /* dec_ref_pic_marking() */
842 if (slice_param->slice_type == 0 || slice_param->slice_type == 2) {
843 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
844 /* no_output_of_prior_pics_flag = 0 */
845 WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1);
846 /* long_term_reference_flag = 0 */
847 WRITE_UINT32 (bs, long_term_reference_flag, 1);
849 /* only sliding_window reference picture marking mode is supported */
850 /* adpative_ref_pic_marking_mode_flag = 0 */
851 WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1);
856 if (pic_param->pic_fields.bits.entropy_coding_mode_flag &&
857 slice_param->slice_type != 2)
858 WRITE_UE (bs, slice_param->cabac_init_idc);
860 WRITE_SE (bs, slice_param->slice_qp_delta);
862 /* XXX: only supporting I, P and B type slices */
863 /* no sp_for_switch_flag and no slice_qs_delta */
865 if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) {
866 /* disable_deblocking_filter_idc */
867 WRITE_UE (bs, slice_param->disable_deblocking_filter_idc);
868 if (slice_param->disable_deblocking_filter_idc != 1) {
869 WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2);
870 WRITE_SE (bs, slice_param->slice_beta_offset_div2);
874 /* XXX: unsupported arbitrary slice ordering (ASO) */
875 /* num_slic_groups_minus1 should be zero */
881 GST_WARNING ("failed to write Slice NAL unit");
887 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
888 const guint8 * nal, guint32 size)
892 gboolean has_subset_sps;
896 has_subset_sps = !encoder->is_mvc || (encoder->subset_sps_data != NULL);
897 if (encoder->sps_data && encoder->pps_data && has_subset_sps)
900 nal_type = nal[0] & 0x1F;
902 case GST_H264_NAL_SPS:
903 encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
904 ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
905 g_assert (ret == size);
907 case GST_H264_NAL_SUBSET_SPS:
908 encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL);
909 ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size);
910 g_assert (ret == size);
912 case GST_H264_NAL_PPS:
913 encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
914 ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
915 g_assert (ret == size);
922 /* Determines the largest supported profile by the underlying hardware */
924 ensure_hw_profile_limits (GstVaapiEncoderH264 * encoder)
926 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
928 guint i, profile_idc, max_profile_idc;
930 if (encoder->hw_max_profile_idc)
933 profiles = gst_vaapi_display_get_encode_profiles (display);
938 for (i = 0; i < profiles->len; i++) {
939 const GstVaapiProfile profile =
940 g_array_index (profiles, GstVaapiProfile, i);
941 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
944 if (max_profile_idc < profile_idc)
945 max_profile_idc = profile_idc;
947 g_array_unref (profiles);
949 encoder->hw_max_profile_idc = max_profile_idc;
953 /* Derives the profile supported by the underlying hardware */
955 ensure_hw_profile (GstVaapiEncoderH264 * encoder)
957 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
958 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
959 GstVaapiProfile profile, profiles[4];
960 guint i, num_profiles = 0;
962 profiles[num_profiles++] = encoder->profile;
963 switch (encoder->profile) {
964 case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
965 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
966 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
968 case GST_VAAPI_PROFILE_H264_MAIN:
969 profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
975 profile = GST_VAAPI_PROFILE_UNKNOWN;
976 for (i = 0; i < num_profiles; i++) {
977 if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
978 profile = profiles[i];
982 if (profile == GST_VAAPI_PROFILE_UNKNOWN)
983 goto error_unsupported_profile;
985 GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
989 error_unsupported_profile:
991 GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
996 /* Check target decoder constraints */
998 ensure_profile_limits (GstVaapiEncoderH264 * encoder)
1000 GstVaapiProfile profile;
1002 if (!encoder->max_profile_idc
1003 || encoder->profile_idc <= encoder->max_profile_idc)
1006 GST_WARNING ("lowering coding tools to meet target decoder constraints");
1008 profile = GST_VAAPI_PROFILE_UNKNOWN;
1010 /* Try Main profile coding tools */
1011 if (encoder->max_profile_idc < 100) {
1012 encoder->use_dct8x8 = FALSE;
1013 profile = GST_VAAPI_PROFILE_H264_MAIN;
1016 /* Try Constrained Baseline profile coding tools */
1017 if (encoder->max_profile_idc < 77) {
1018 encoder->num_bframes = 0;
1019 encoder->use_cabac = FALSE;
1020 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
1024 encoder->profile = profile;
1025 encoder->profile_idc = encoder->max_profile_idc;
1030 /* Derives the minimum profile from the active coding tools */
1032 ensure_profile (GstVaapiEncoderH264 * encoder)
1034 GstVaapiProfile profile;
1036 /* Always start from "constrained-baseline" profile for maximum
1038 profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
1040 /* Main profile coding tools */
1041 if (encoder->num_bframes > 0 || encoder->use_cabac)
1042 profile = GST_VAAPI_PROFILE_H264_MAIN;
1044 /* High profile coding tools */
1045 if (encoder->use_dct8x8)
1046 profile = GST_VAAPI_PROFILE_H264_HIGH;
1048 /* MVC profiles coding tools */
1049 if (encoder->num_views == 2)
1050 profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH;
1051 else if (encoder->num_views > 2)
1052 profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH;
1054 encoder->profile = profile;
1055 encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
1059 /* Derives the level from the currently set limits */
1061 ensure_level (GstVaapiEncoderH264 * encoder)
1063 const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile);
1064 const GstVaapiH264LevelLimits *limits_table;
1065 guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
1067 PicSizeMbs = encoder->mb_width * encoder->mb_height;
1068 MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
1069 MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
1070 GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
1072 limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
1073 for (i = 0; i < num_limits; i++) {
1074 const GstVaapiH264LevelLimits *const limits = &limits_table[i];
1075 if (PicSizeMbs <= limits->MaxFS &&
1076 MaxDpbMbs <= limits->MaxDpbMbs &&
1077 MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits
1078 || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) &&
1079 (!encoder->cpb_length_bits ||
1080 encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor)))
1083 if (i == num_limits)
1084 goto error_unsupported_level;
1086 encoder->level = limits_table[i].level;
1087 encoder->level_idc = limits_table[i].level_idc;
1091 error_unsupported_level:
1093 GST_ERROR ("failed to find a suitable level matching codec config");
1098 /* Enable "high-compression" tuning options */
1100 ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder)
1104 if (!ensure_hw_profile_limits (encoder))
1107 profile_idc = encoder->hw_max_profile_idc;
1108 if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
1109 profile_idc = encoder->max_profile_idc;
1111 /* Tuning options to enable Main profile */
1112 if (profile_idc >= 77 && profile_idc != 88) {
1113 encoder->use_cabac = TRUE;
1114 if (!encoder->num_bframes)
1115 encoder->num_bframes = 1;
1118 /* Tuning options to enable High profile */
1119 if (profile_idc >= 100) {
1120 encoder->use_dct8x8 = TRUE;
1125 /* Ensure tuning options */
1127 ensure_tuning (GstVaapiEncoderH264 * encoder)
1131 switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
1132 case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
1133 success = ensure_tuning_high_compression (encoder);
1142 /* Handle new GOP starts */
1144 reset_gop_start (GstVaapiEncoderH264 * encoder)
1146 GstVaapiH264ViewReorderPool *const reorder_pool =
1147 &encoder->reorder_pools[encoder->view_idx];
1149 reorder_pool->frame_index = 1;
1150 reorder_pool->cur_frame_num = 0;
1151 reorder_pool->cur_present_index = 0;
1155 /* Marks the supplied picture as a B-frame */
1157 set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1159 GstVaapiH264ViewReorderPool *const reorder_pool =
1160 &encoder->reorder_pools[encoder->view_idx];
1162 g_assert (pic && encoder);
1163 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1164 pic->type = GST_VAAPI_PICTURE_TYPE_B;
1165 pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
1168 /* Marks the supplied picture as a P-frame */
1170 set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1172 GstVaapiH264ViewReorderPool *const reorder_pool =
1173 &encoder->reorder_pools[encoder->view_idx];
1175 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1176 pic->type = GST_VAAPI_PICTURE_TYPE_P;
1177 pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
1180 /* Marks the supplied picture as an I-frame */
1182 set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1184 GstVaapiH264ViewReorderPool *const reorder_pool =
1185 &encoder->reorder_pools[encoder->view_idx];
1187 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1188 pic->type = GST_VAAPI_PICTURE_TYPE_I;
1189 pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
1191 g_assert (pic->frame);
1192 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1195 /* Marks the supplied picture as an IDR frame */
1197 set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1199 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1200 pic->type = GST_VAAPI_PICTURE_TYPE_I;
1203 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
1205 g_assert (pic->frame);
1206 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1209 /* Marks the supplied picture a a key-frame */
1211 set_key_frame (GstVaapiEncPicture * picture,
1212 GstVaapiEncoderH264 * encoder, gboolean is_idr)
1215 reset_gop_start (encoder);
1216 set_idr_frame (picture, encoder);
1218 set_i_frame (picture, encoder);
1221 /* Fills in VA HRD parameters */
1223 fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd)
1225 if (encoder->bitrate_bits > 0) {
1226 hrd->buffer_size = encoder->cpb_length_bits;
1227 hrd->initial_buffer_fullness = hrd->buffer_size / 2;
1229 hrd->buffer_size = 0;
1230 hrd->initial_buffer_fullness = 0;
1234 /* Adds the supplied sequence header (SPS) to the list of packed
1235 headers to pass down as-is to the encoder */
1237 add_packed_sequence_header (GstVaapiEncoderH264 * encoder,
1238 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1240 GstVaapiEncPackedHeader *packed_seq;
1242 VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
1243 const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1244 GstVaapiProfile profile = encoder->profile;
1246 VAEncMiscParameterHRD hrd_params;
1247 guint32 data_bit_size;
1250 fill_hrd_params (encoder, &hrd_params);
1252 gst_bit_writer_init (&bs, 128 * 8);
1253 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1254 bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS);
1256 /* Set High profile for encoding the MVC base view. Otherwise, some
1257 traditional decoder cannot recognize MVC profile streams with
1258 only the base view in there */
1259 if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
1260 profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH)
1261 profile = GST_VAAPI_PROFILE_H264_HIGH;
1263 bs_write_sps (&bs, seq_param, profile, &hrd_params);
1265 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1266 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1267 data = GST_BIT_WRITER_DATA (&bs);
1269 packed_seq_param.type = VAEncPackedHeaderSequence;
1270 packed_seq_param.bit_length = data_bit_size;
1271 packed_seq_param.has_emulation_bytes = 0;
1273 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1274 &packed_seq_param, sizeof (packed_seq_param),
1275 data, (data_bit_size + 7) / 8);
1276 g_assert (packed_seq);
1278 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
1279 gst_vaapi_codec_object_replace (&packed_seq, NULL);
1281 /* store sps data */
1282 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1283 gst_bit_writer_clear (&bs, TRUE);
1289 GST_WARNING ("failed to write SPS NAL unit");
1290 gst_bit_writer_clear (&bs, TRUE);
1296 add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder,
1297 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1299 GstVaapiEncPackedHeader *packed_seq;
1301 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
1302 const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1303 VAEncMiscParameterHRD hrd_params;
1304 guint32 data_bit_size;
1307 fill_hrd_params (encoder, &hrd_params);
1309 /* non-base layer, pack one subset sps */
1310 gst_bit_writer_init (&bs, 128 * 8);
1311 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1312 bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS);
1314 bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views,
1317 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1318 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1319 data = GST_BIT_WRITER_DATA (&bs);
1321 packed_header_param_buffer.type = VAEncPackedHeaderSequence;
1322 packed_header_param_buffer.bit_length = data_bit_size;
1323 packed_header_param_buffer.has_emulation_bytes = 0;
1325 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1326 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
1327 data, (data_bit_size + 7) / 8);
1328 g_assert (packed_seq);
1330 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
1331 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL);
1333 /* store subset sps data */
1334 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1335 gst_bit_writer_clear (&bs, TRUE);
1341 GST_WARNING ("failed to write SPS NAL unit");
1342 gst_bit_writer_clear (&bs, TRUE);
1347 /* Adds the supplied picture header (PPS) to the list of packed
1348 headers to pass down as-is to the encoder */
1350 add_packed_picture_header (GstVaapiEncoderH264 * encoder,
1351 GstVaapiEncPicture * picture)
1353 GstVaapiEncPackedHeader *packed_pic;
1355 VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
1356 const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1357 guint32 data_bit_size;
1360 gst_bit_writer_init (&bs, 128 * 8);
1361 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1362 bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS);
1363 bs_write_pps (&bs, pic_param, encoder->profile);
1364 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1365 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1366 data = GST_BIT_WRITER_DATA (&bs);
1368 packed_pic_param.type = VAEncPackedHeaderPicture;
1369 packed_pic_param.bit_length = data_bit_size;
1370 packed_pic_param.has_emulation_bytes = 0;
1372 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1373 &packed_pic_param, sizeof (packed_pic_param),
1374 data, (data_bit_size + 7) / 8);
1375 g_assert (packed_pic);
1377 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
1378 gst_vaapi_codec_object_replace (&packed_pic, NULL);
1380 /* store pps data */
1381 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1382 gst_bit_writer_clear (&bs, TRUE);
1388 GST_WARNING ("failed to write PPS NAL unit");
1389 gst_bit_writer_clear (&bs, TRUE);
1395 get_nal_hdr_attributes (GstVaapiEncPicture * picture,
1396 guint8 * nal_ref_idc, guint8 * nal_unit_type)
1398 switch (picture->type) {
1399 case GST_VAAPI_PICTURE_TYPE_I:
1400 *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH;
1401 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
1402 *nal_unit_type = GST_H264_NAL_SLICE_IDR;
1404 *nal_unit_type = GST_H264_NAL_SLICE;
1406 case GST_VAAPI_PICTURE_TYPE_P:
1407 *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM;
1408 *nal_unit_type = GST_H264_NAL_SLICE;
1410 case GST_VAAPI_PICTURE_TYPE_B:
1411 *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE;
1412 *nal_unit_type = GST_H264_NAL_SLICE;
1420 /* Adds the supplied prefix nal header to the list of packed
1421 headers to pass down as-is to the encoder */
1423 add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder,
1424 GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
1426 GstVaapiEncPackedHeader *packed_prefix_nal;
1428 VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 };
1429 guint32 data_bit_size;
1431 guint8 nal_ref_idc, nal_unit_type;
1433 gst_bit_writer_init (&bs, 128 * 8);
1434 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1436 if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
1438 nal_unit_type = GST_H264_NAL_PREFIX_UNIT;
1440 bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
1441 bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx);
1442 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1443 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1444 data = GST_BIT_WRITER_DATA (&bs);
1446 packed_prefix_nal_param.type = VAEncPackedHeaderRawData;
1447 packed_prefix_nal_param.bit_length = data_bit_size;
1448 packed_prefix_nal_param.has_emulation_bytes = 0;
1451 gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1452 &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data,
1453 (data_bit_size + 7) / 8);
1454 g_assert (packed_prefix_nal);
1456 gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal);
1457 gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL);
1459 gst_bit_writer_clear (&bs, TRUE);
1466 GST_WARNING ("failed to write Prefix NAL unit header");
1467 gst_bit_writer_clear (&bs, TRUE);
1472 /* Adds the supplied slice header to the list of packed
1473 headers to pass down as-is to the encoder */
1475 add_packed_slice_header (GstVaapiEncoderH264 * encoder,
1476 GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
1478 GstVaapiEncPackedHeader *packed_slice;
1480 VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 };
1481 const VAEncSliceParameterBufferH264 *const slice_param = slice->param;
1482 guint32 data_bit_size;
1484 guint8 nal_ref_idc, nal_unit_type;
1486 gst_bit_writer_init (&bs, 128 * 8);
1487 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1489 if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
1491 /* pack nal_unit_header_mvc_extension() for the non base view */
1492 if (encoder->is_mvc && encoder->view_idx) {
1493 bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT);
1494 bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx);
1496 bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
1498 bs_write_slice (&bs, slice_param, encoder, picture);
1499 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1500 data = GST_BIT_WRITER_DATA (&bs);
1502 packed_slice_param.type = VAEncPackedHeaderSlice;
1503 packed_slice_param.bit_length = data_bit_size;
1504 packed_slice_param.has_emulation_bytes = 0;
1506 packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1507 &packed_slice_param, sizeof (packed_slice_param),
1508 data, (data_bit_size + 7) / 8);
1509 g_assert (packed_slice);
1511 gst_vaapi_enc_slice_add_packed_header (slice, packed_slice);
1512 gst_vaapi_codec_object_replace (&packed_slice, NULL);
1514 gst_bit_writer_clear (&bs, TRUE);
1520 GST_WARNING ("failed to write Slice NAL unit header");
1521 gst_bit_writer_clear (&bs, TRUE);
1526 /* Reference picture management */
1528 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
1533 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
1534 g_slice_free (GstVaapiEncoderH264Ref, ref);
1537 static inline GstVaapiEncoderH264Ref *
1538 reference_pic_create (GstVaapiEncoderH264 * encoder,
1539 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1541 GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
1544 ref->frame_num = picture->frame_num;
1545 ref->poc = picture->poc;
1550 reference_list_update (GstVaapiEncoderH264 * encoder,
1551 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1553 GstVaapiEncoderH264Ref *ref;
1554 GstVaapiH264ViewRefPool *const ref_pool =
1555 &encoder->ref_pools[encoder->view_idx];
1557 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
1558 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
1561 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
1562 while (!g_queue_is_empty (&ref_pool->ref_list))
1563 reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1564 } else if (g_queue_get_length (&ref_pool->ref_list) >=
1565 ref_pool->max_ref_frames) {
1566 reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1568 ref = reference_pic_create (encoder, picture, surface);
1569 g_queue_push_tail (&ref_pool->ref_list, ref);
1570 g_assert (g_queue_get_length (&ref_pool->ref_list) <=
1571 ref_pool->max_ref_frames);
1576 reference_list_init (GstVaapiEncoderH264 * encoder,
1577 GstVaapiEncPicture * picture,
1578 GstVaapiEncoderH264Ref ** reflist_0,
1579 guint * reflist_0_count,
1580 GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
1582 GstVaapiEncoderH264Ref *tmp;
1583 GstVaapiH264ViewRefPool *const ref_pool =
1584 &encoder->ref_pools[encoder->view_idx];
1585 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
1588 *reflist_0_count = 0;
1589 *reflist_1_count = 0;
1590 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
1593 iter = g_queue_peek_tail_link (&ref_pool->ref_list);
1594 for (; iter; iter = g_list_previous (iter)) {
1595 tmp = (GstVaapiEncoderH264Ref *) iter->data;
1596 g_assert (tmp && tmp->poc != picture->poc);
1597 if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) {
1598 list_0_start = iter;
1599 list_1_start = g_list_next (iter);
1604 /* order reflist_0 */
1605 g_assert (list_0_start);
1606 iter = list_0_start;
1608 for (; iter; iter = g_list_previous (iter)) {
1609 reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
1612 *reflist_0_count = count;
1614 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1617 /* order reflist_1 */
1619 iter = list_1_start;
1620 for (; iter; iter = g_list_next (iter)) {
1621 reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
1624 *reflist_1_count = count;
1628 /* Fills in VA sequence parameter buffer */
1630 fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence)
1632 VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1633 GstVaapiH264ViewRefPool *const ref_pool =
1634 &encoder->ref_pools[encoder->view_idx];
1636 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
1637 seq_param->seq_parameter_set_id = encoder->view_idx;
1638 seq_param->level_idc = encoder->level_idc;
1639 seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
1640 seq_param->ip_period = 1 + encoder->num_bframes;
1641 seq_param->bits_per_second = encoder->bitrate_bits;
1643 seq_param->max_num_ref_frames = ref_pool->max_ref_frames;
1644 seq_param->picture_width_in_mbs = encoder->mb_width;
1645 seq_param->picture_height_in_mbs = encoder->mb_height;
1647 /*sequence field values */
1648 seq_param->seq_fields.value = 0;
1649 seq_param->seq_fields.bits.chroma_format_idc = 1;
1650 seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
1651 seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
1652 seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
1653 /* direct_8x8_inference_flag default false */
1654 seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
1655 g_assert (encoder->log2_max_frame_num >= 4);
1656 seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
1657 encoder->log2_max_frame_num - 4;
1658 /* picture order count */
1659 encoder->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type =
1661 g_assert (encoder->log2_max_pic_order_cnt >= 4);
1662 seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
1663 encoder->log2_max_pic_order_cnt - 4;
1665 seq_param->bit_depth_luma_minus8 = 0;
1666 seq_param->bit_depth_chroma_minus8 = 0;
1668 /* not used if pic_order_cnt_type == 0 */
1669 if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
1670 encoder->delta_pic_order_always_zero_flag =
1671 seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
1672 seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
1673 seq_param->offset_for_non_ref_pic = 0;
1674 seq_param->offset_for_top_to_bottom_field = 0;
1675 memset (seq_param->offset_for_ref_frame, 0,
1676 sizeof (seq_param->offset_for_ref_frame));
1679 /* frame_cropping_flag */
1680 if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
1681 (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
1682 static const guint SubWidthC[] = { 1, 2, 2, 1 };
1683 static const guint SubHeightC[] = { 1, 2, 1, 1 };
1684 const guint CropUnitX =
1685 SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
1686 const guint CropUnitY =
1687 SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
1688 (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
1690 seq_param->frame_cropping_flag = 1;
1691 seq_param->frame_crop_left_offset = 0;
1692 seq_param->frame_crop_right_offset =
1693 (16 * encoder->mb_width -
1694 GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX;
1695 seq_param->frame_crop_top_offset = 0;
1696 seq_param->frame_crop_bottom_offset =
1697 (16 * encoder->mb_height -
1698 GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY;
1701 /* VUI parameters are always set, at least for timing_info (framerate) */
1702 seq_param->vui_parameters_present_flag = TRUE;
1703 if (seq_param->vui_parameters_present_flag) {
1704 seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE;
1705 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
1706 const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1707 seq_param->aspect_ratio_idc = 0xff;
1708 seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip);
1709 seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip);
1711 seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1712 /* if vui_parameters_present_flag is TRUE and sps data belongs to
1713 * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */
1714 seq_param->vui_fields.bits.timing_info_present_flag = !encoder->view_idx;
1715 if (seq_param->vui_fields.bits.timing_info_present_flag) {
1716 seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1717 seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
1723 /* Fills in VA picture parameter buffer */
1725 fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1726 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1728 VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1729 GstVaapiH264ViewRefPool *const ref_pool =
1730 &encoder->ref_pools[encoder->view_idx];
1731 GstVaapiEncoderH264Ref *ref_pic;
1735 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
1737 /* reference list, */
1738 pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1739 pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
1741 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1742 for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
1743 reflist; reflist = g_list_next (reflist)) {
1744 ref_pic = reflist->data;
1745 g_assert (ref_pic && ref_pic->pic &&
1746 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1748 pic_param->ReferenceFrames[i].picture_id =
1749 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1752 g_assert (i <= 16 && i <= ref_pool->max_ref_frames);
1754 for (; i < 16; ++i) {
1755 pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
1757 pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1759 pic_param->pic_parameter_set_id = encoder->view_idx;
1760 pic_param->seq_parameter_set_id = encoder->view_idx;
1761 pic_param->last_picture = 0; /* means last encoding picture */
1762 pic_param->frame_num = picture->frame_num;
1763 pic_param->pic_init_qp = encoder->init_qp;
1764 pic_param->num_ref_idx_l0_active_minus1 =
1765 (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0);
1766 pic_param->num_ref_idx_l1_active_minus1 =
1767 (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0);
1768 pic_param->chroma_qp_index_offset = 0;
1769 pic_param->second_chroma_qp_index_offset = 0;
1771 /* set picture fields */
1772 pic_param->pic_fields.value = 0;
1773 pic_param->pic_fields.bits.idr_pic_flag =
1774 GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1775 pic_param->pic_fields.bits.reference_pic_flag =
1776 (picture->type != GST_VAAPI_PICTURE_TYPE_B);
1777 pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
1778 pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
1779 pic_param->pic_fields.bits.weighted_bipred_idc = 0;
1780 pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
1781 pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
1782 /* enable debloking */
1783 pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
1784 pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
1785 /* bottom_field_pic_order_in_frame_present_flag */
1786 pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
1787 pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
1792 /* Adds slice headers to picture */
1794 add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1795 GstVaapiEncoderH264Ref ** reflist_0, guint reflist_0_count,
1796 GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
1798 VAEncSliceParameterBufferH264 *slice_param;
1799 GstVaapiEncSlice *slice;
1800 guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
1802 guint last_mb_index;
1803 guint i_slice, i_ref;
1807 mb_size = encoder->mb_width * encoder->mb_height;
1809 g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1810 slice_of_mbs = mb_size / encoder->num_slices;
1811 slice_mod_mbs = mb_size % encoder->num_slices;
1813 for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1814 cur_slice_mbs = slice_of_mbs;
1815 if (slice_mod_mbs) {
1819 slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1820 g_assert (slice && slice->param_id != VA_INVALID_ID);
1821 slice_param = slice->param;
1823 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1824 slice_param->macroblock_address = last_mb_index;
1825 slice_param->num_macroblocks = cur_slice_mbs;
1826 slice_param->macroblock_info = VA_INVALID_ID;
1827 slice_param->slice_type = h264_get_slice_type (picture->type);
1828 g_assert (slice_param->slice_type != -1);
1829 slice_param->pic_parameter_set_id = encoder->view_idx;
1830 slice_param->idr_pic_id = encoder->idr_num;
1831 slice_param->pic_order_cnt_lsb = picture->poc;
1833 /* not used if pic_order_cnt_type = 0 */
1834 slice_param->delta_pic_order_cnt_bottom = 0;
1835 memset (slice_param->delta_pic_order_cnt, 0,
1836 sizeof (slice_param->delta_pic_order_cnt));
1838 /* only works for B frames */
1839 slice_param->direct_spatial_mv_pred_flag = FALSE;
1840 /* default equal to picture parameters */
1841 slice_param->num_ref_idx_active_override_flag = FALSE;
1842 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1843 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1845 slice_param->num_ref_idx_l0_active_minus1 = 0;
1846 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1847 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1849 slice_param->num_ref_idx_l1_active_minus1 = 0;
1850 g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1851 g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1854 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1855 for (; i_ref < reflist_0_count; ++i_ref) {
1856 slice_param->RefPicList0[i_ref].picture_id =
1857 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1859 g_assert (i_ref == 1);
1861 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1862 slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1866 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1867 for (; i_ref < reflist_1_count; ++i_ref) {
1868 slice_param->RefPicList1[i_ref].picture_id =
1869 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1871 g_assert (i_ref == 1);
1873 for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1874 slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1877 /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1878 slice_param->luma_log2_weight_denom = 0;
1879 slice_param->chroma_log2_weight_denom = 0;
1880 slice_param->luma_weight_l0_flag = FALSE;
1881 memset (slice_param->luma_weight_l0, 0,
1882 sizeof (slice_param->luma_weight_l0));
1883 memset (slice_param->luma_offset_l0, 0,
1884 sizeof (slice_param->luma_offset_l0));
1885 slice_param->chroma_weight_l0_flag = FALSE;
1886 memset (slice_param->chroma_weight_l0, 0,
1887 sizeof (slice_param->chroma_weight_l0));
1888 memset (slice_param->chroma_offset_l0, 0,
1889 sizeof (slice_param->chroma_offset_l0));
1890 slice_param->luma_weight_l1_flag = FALSE;
1891 memset (slice_param->luma_weight_l1, 0,
1892 sizeof (slice_param->luma_weight_l1));
1893 memset (slice_param->luma_offset_l1, 0,
1894 sizeof (slice_param->luma_offset_l1));
1895 slice_param->chroma_weight_l1_flag = FALSE;
1896 memset (slice_param->chroma_weight_l1, 0,
1897 sizeof (slice_param->chroma_weight_l1));
1898 memset (slice_param->chroma_offset_l1, 0,
1899 sizeof (slice_param->chroma_offset_l1));
1901 slice_param->cabac_init_idc = 0;
1902 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1903 if (slice_param->slice_qp_delta > 4)
1904 slice_param->slice_qp_delta = 4;
1905 slice_param->disable_deblocking_filter_idc = 0;
1906 slice_param->slice_alpha_c0_offset_div2 = 2;
1907 slice_param->slice_beta_offset_div2 = 2;
1909 /* set calculation for next slice */
1910 last_mb_index += cur_slice_mbs;
1912 /* add packed Prefix NAL unit before each Coded slice NAL in base view */
1913 if (encoder->is_mvc && !encoder->view_idx &&
1914 (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1915 VA_ENC_PACKED_HEADER_RAW_DATA)
1916 && !add_packed_prefix_nal_header (encoder, picture, slice))
1917 goto error_create_packed_prefix_nal_hdr;
1918 if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1919 VA_ENC_PACKED_HEADER_SLICE)
1920 && !add_packed_slice_header (encoder, picture, slice))
1921 goto error_create_packed_slice_hdr;
1923 gst_vaapi_enc_picture_add_slice (picture, slice);
1924 gst_vaapi_codec_object_replace (&slice, NULL);
1926 g_assert (last_mb_index == mb_size);
1929 error_create_packed_slice_hdr:
1931 GST_ERROR ("failed to create packed slice header buffer");
1932 gst_vaapi_codec_object_replace (&slice, NULL);
1935 error_create_packed_prefix_nal_hdr:
1937 GST_ERROR ("failed to create packed prefix nal header buffer");
1938 gst_vaapi_codec_object_replace (&slice, NULL);
1943 /* Generates and submits SPS header accordingly into the bitstream */
1945 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1947 GstVaapiEncSequence *sequence = NULL;
1949 /* submit an SPS header before every new I-frame, if codec config changed */
1950 if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I)
1953 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1954 if (!sequence || !fill_sequence (encoder, sequence))
1955 goto error_create_seq_param;
1957 /* add subset sps for non-base view and sps for base view */
1958 if (encoder->is_mvc && encoder->view_idx) {
1959 if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS)
1960 && !add_packed_sequence_header_mvc (encoder, picture, sequence))
1961 goto error_create_packed_seq_hdr;
1963 if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS)
1964 && !add_packed_sequence_header (encoder, picture, sequence))
1965 goto error_create_packed_seq_hdr;
1969 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1970 gst_vaapi_codec_object_replace (&sequence, NULL);
1973 if (!encoder->is_mvc || encoder->view_idx > 0)
1974 encoder->config_changed = FALSE;
1978 error_create_seq_param:
1980 GST_ERROR ("failed to create sequence parameter buffer (SPS)");
1981 gst_vaapi_codec_object_replace (&sequence, NULL);
1984 error_create_packed_seq_hdr:
1986 GST_ERROR ("failed to create packed sequence header buffer");
1987 gst_vaapi_codec_object_replace (&sequence, NULL);
1992 /* Generates additional control parameters */
1994 ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1996 GstVaapiEncMiscParam *misc = NULL;
1997 VAEncMiscParameterRateControl *rate_control;
2000 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
2004 fill_hrd_params (encoder, misc->data);
2005 gst_vaapi_enc_picture_add_misc_param (picture, misc);
2006 gst_vaapi_codec_object_replace (&misc, NULL);
2008 /* RateControl params */
2009 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
2010 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
2011 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
2015 rate_control = misc->data;
2016 memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
2017 rate_control->bits_per_second = encoder->bitrate_bits;
2018 rate_control->target_percentage = 70;
2019 rate_control->window_size = encoder->cpb_length;
2020 rate_control->initial_qp = encoder->init_qp;
2021 rate_control->min_qp = encoder->min_qp;
2022 rate_control->basic_unit_size = 0;
2023 gst_vaapi_enc_picture_add_misc_param (picture, misc);
2024 gst_vaapi_codec_object_replace (&misc, NULL);
2029 /* Generates and submits PPS header accordingly into the bitstream */
2031 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
2032 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
2034 GstVaapiCodedBuffer *const codedbuf =
2035 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
2036 gboolean res = FALSE;
2038 res = fill_picture (encoder, picture, codedbuf, surface);
2043 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
2044 (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_PPS)
2045 && !add_packed_picture_header (encoder, picture)) {
2046 GST_ERROR ("set picture packed header failed");
2052 /* Generates slice headers */
2054 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
2056 GstVaapiEncoderH264Ref *reflist_0[16];
2057 GstVaapiEncoderH264Ref *reflist_1[16];
2058 GstVaapiH264ViewRefPool *const ref_pool =
2059 &encoder->ref_pools[encoder->view_idx];
2060 guint reflist_0_count = 0, reflist_1_count = 0;
2064 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
2065 !reference_list_init (encoder, picture,
2066 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
2067 GST_ERROR ("reference list reorder failed");
2071 g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
2072 if (reflist_0_count > ref_pool->max_reflist0_count)
2073 reflist_0_count = ref_pool->max_reflist0_count;
2074 if (reflist_1_count > ref_pool->max_reflist1_count)
2075 reflist_1_count = ref_pool->max_reflist1_count;
2077 if (!add_slice_headers (encoder, picture,
2078 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
2084 /* Normalizes bitrate (and CPB size) for HRD conformance */
2086 ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder)
2088 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2089 guint bitrate, cpb_size;
2091 if (!base_encoder->bitrate) {
2092 encoder->bitrate_bits = 0;
2096 /* Round down bitrate. This is a hard limit mandated by the user */
2097 g_assert (SX_BITRATE >= 6);
2098 bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
2099 if (bitrate != encoder->bitrate_bits) {
2100 GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
2101 encoder->bitrate_bits = bitrate;
2102 encoder->config_changed = TRUE;
2105 /* Round up CPB size. This is an HRD compliance detail */
2106 g_assert (SX_CPB_SIZE >= 4);
2107 cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) &
2108 ~((1U << SX_CPB_SIZE) - 1);
2109 if (cpb_size != encoder->cpb_length_bits) {
2110 GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
2111 encoder->cpb_length_bits = cpb_size;
2112 encoder->config_changed = TRUE;
2116 /* Estimates a good enough bitrate if none was supplied */
2118 ensure_bitrate (GstVaapiEncoderH264 * encoder)
2120 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2122 /* Default compression: 48 bits per macroblock in "high-compression" mode */
2123 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
2124 case GST_VAAPI_RATECONTROL_CBR:
2125 case GST_VAAPI_RATECONTROL_VBR:
2126 case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
2127 if (!base_encoder->bitrate) {
2128 /* According to the literature and testing, CABAC entropy coding
2129 mode could provide for +10% to +18% improvement in general,
2130 thus estimating +15% here ; and using adaptive 8x8 transforms
2131 in I-frames could bring up to +10% improvement. */
2132 guint bits_per_mb = 48;
2133 if (!encoder->use_cabac)
2134 bits_per_mb += (bits_per_mb * 15) / 100;
2135 if (!encoder->use_dct8x8)
2136 bits_per_mb += (bits_per_mb * 10) / 100;
2138 base_encoder->bitrate =
2139 encoder->mb_width * encoder->mb_height * bits_per_mb *
2140 GST_VAAPI_ENCODER_FPS_N (encoder) /
2141 GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
2142 GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
2146 base_encoder->bitrate = 0;
2149 ensure_bitrate_hrd (encoder);
2152 /* Constructs profile and level information based on user-defined limits */
2153 static GstVaapiEncoderStatus
2154 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
2156 const GstVaapiProfile profile = encoder->profile;
2157 const GstVaapiLevelH264 level = encoder->level;
2159 ensure_tuning (encoder);
2161 if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
2162 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2164 /* Check HW constraints */
2165 if (!ensure_hw_profile_limits (encoder))
2166 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2167 if (encoder->profile_idc > encoder->hw_max_profile_idc)
2168 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2170 /* Ensure bitrate if not set already and derive the right level to use */
2171 ensure_bitrate (encoder);
2172 if (!ensure_level (encoder))
2173 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
2175 if (encoder->profile != profile || encoder->level != level) {
2176 GST_DEBUG ("selected %s profile at level %s",
2177 gst_vaapi_utils_h264_get_profile_string (encoder->profile),
2178 gst_vaapi_utils_h264_get_level_string (encoder->level));
2179 encoder->config_changed = TRUE;
2181 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2185 reset_properties (GstVaapiEncoderH264 * encoder)
2187 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2190 if (encoder->idr_period < base_encoder->keyframe_period)
2191 encoder->idr_period = base_encoder->keyframe_period;
2192 if (encoder->idr_period > MAX_IDR_PERIOD)
2193 encoder->idr_period = MAX_IDR_PERIOD;
2195 if (encoder->min_qp > encoder->init_qp ||
2196 (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
2197 encoder->min_qp < encoder->init_qp))
2198 encoder->min_qp = encoder->init_qp;
2200 mb_size = encoder->mb_width * encoder->mb_height;
2201 if (encoder->num_slices > (mb_size + 1) / 2)
2202 encoder->num_slices = (mb_size + 1) / 2;
2203 g_assert (encoder->num_slices);
2205 if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
2206 encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
2208 if (encoder->num_bframes)
2209 encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
2210 GST_VAAPI_ENCODER_FPS_N (encoder);
2212 encoder->cts_offset = 0;
2214 /* init max_frame_num, max_poc */
2215 encoder->log2_max_frame_num =
2216 h264_get_log2_max_frame_num (encoder->idr_period);
2217 g_assert (encoder->log2_max_frame_num >= 4);
2218 encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
2219 encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
2220 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
2221 encoder->idr_num = 0;
2223 encoder->is_mvc = encoder->num_views > 1;
2224 for (i = 0; i < encoder->num_views; i++) {
2225 GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
2226 ref_pool->max_reflist0_count = 1;
2227 ref_pool->max_reflist1_count = encoder->num_bframes > 0;
2228 ref_pool->max_ref_frames = ref_pool->max_reflist0_count
2229 + ref_pool->max_reflist1_count;
2231 GstVaapiH264ViewReorderPool *const reorder_pool =
2232 &encoder->reorder_pools[i];
2233 reorder_pool->frame_index = 0;
2237 static GstVaapiEncoderStatus
2238 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
2239 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
2241 GstVaapiEncoderH264 *const encoder =
2242 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2243 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2244 GstVaapiSurfaceProxy *reconstruct = NULL;
2246 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
2248 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
2250 if (!ensure_sequence (encoder, picture))
2252 if (!ensure_misc_params (encoder, picture))
2254 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
2256 if (!ensure_slices (encoder, picture))
2258 if (!gst_vaapi_enc_picture_encode (picture))
2261 if (!reference_list_update (encoder, picture, reconstruct))
2264 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2267 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
2272 static GstVaapiEncoderStatus
2273 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
2275 GstVaapiEncoderH264 *const encoder =
2276 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2277 GstVaapiH264ViewReorderPool *reorder_pool;
2278 GstVaapiEncPicture *pic;
2281 for (i = 0; i < encoder->num_views; i++) {
2282 reorder_pool = &encoder->reorder_pools[i];
2283 reorder_pool->frame_index = 0;
2284 reorder_pool->cur_frame_num = 0;
2285 reorder_pool->cur_present_index = 0;
2287 while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2288 pic = (GstVaapiEncPicture *)
2289 g_queue_pop_head (&reorder_pool->reorder_frame_list);
2290 gst_vaapi_enc_picture_unref (pic);
2292 g_queue_clear (&reorder_pool->reorder_frame_list);
2295 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2298 /* Generate "codec-data" buffer */
2299 static GstVaapiEncoderStatus
2300 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
2301 GstBuffer ** out_buffer_ptr)
2303 GstVaapiEncoderH264 *const encoder =
2304 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2305 const guint32 configuration_version = 0x01;
2306 const guint32 nal_length_size = 4;
2307 guint8 profile_idc, profile_comp, level_idc;
2308 GstMapInfo sps_info, pps_info;
2312 if (!encoder->sps_data || !encoder->pps_data)
2313 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
2314 if (gst_buffer_get_size (encoder->sps_data) < 4)
2315 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
2317 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
2318 goto error_map_sps_buffer;
2320 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
2321 goto error_map_pps_buffer;
2323 /* skip sps_data[0], which is the nal_unit_type */
2324 profile_idc = sps_info.data[1];
2325 profile_comp = sps_info.data[2];
2326 level_idc = sps_info.data[3];
2329 gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8);
2330 WRITE_UINT32 (&bs, configuration_version, 8);
2331 WRITE_UINT32 (&bs, profile_idc, 8);
2332 WRITE_UINT32 (&bs, profile_comp, 8);
2333 WRITE_UINT32 (&bs, level_idc, 8);
2334 WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */
2335 WRITE_UINT32 (&bs, nal_length_size - 1, 2);
2336 WRITE_UINT32 (&bs, 0x07, 3); /* 111 */
2339 WRITE_UINT32 (&bs, 1, 5); /* SPS count = 1 */
2340 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
2341 WRITE_UINT32 (&bs, sps_info.size, 16);
2342 gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size);
2345 WRITE_UINT32 (&bs, 1, 8); /* PPS count = 1 */
2346 WRITE_UINT32 (&bs, pps_info.size, 16);
2347 gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size);
2349 gst_buffer_unmap (encoder->pps_data, &pps_info);
2350 gst_buffer_unmap (encoder->sps_data, &sps_info);
2352 buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs),
2353 GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
2355 goto error_alloc_buffer;
2356 *out_buffer_ptr = buffer;
2358 gst_bit_writer_clear (&bs, FALSE);
2359 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2364 GST_ERROR ("failed to write codec-data");
2365 gst_buffer_unmap (encoder->sps_data, &sps_info);
2366 gst_buffer_unmap (encoder->pps_data, &pps_info);
2367 gst_bit_writer_clear (&bs, TRUE);
2370 error_map_sps_buffer:
2372 GST_ERROR ("failed to map SPS packed header");
2373 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2375 error_map_pps_buffer:
2377 GST_ERROR ("failed to map PPS packed header");
2378 gst_buffer_unmap (encoder->sps_data, &sps_info);
2379 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2383 GST_ERROR ("failed to allocate codec-data buffer");
2384 gst_bit_writer_clear (&bs, TRUE);
2385 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2389 static GstVaapiEncoderStatus
2390 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
2391 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
2393 GstVaapiEncoderH264 *const encoder =
2394 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2395 GstVaapiH264ViewReorderPool *reorder_pool = NULL;
2396 GstVaapiEncPicture *picture;
2397 gboolean is_idr = FALSE;
2401 /* encoding views alternatively for MVC */
2402 if (encoder->is_mvc) {
2404 encoder->view_idx = frame->system_frame_number % MAX_NUM_VIEWS;
2406 encoder->view_idx = (encoder->view_idx + 1) % MAX_NUM_VIEWS;
2408 reorder_pool = &encoder->reorder_pools[encoder->view_idx];
2411 if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
2412 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
2414 /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
2415 dump B frames from queue, sometime, there may also have P frame or I frame */
2416 g_assert (encoder->num_bframes > 0);
2417 g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list),
2418 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
2419 picture = g_queue_pop_head (&reorder_pool->reorder_frame_list);
2421 if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2422 reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
2427 /* new frame coming */
2428 picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
2430 GST_WARNING ("create H264 picture failed, frame timestamp:%"
2431 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
2432 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2434 ++reorder_pool->cur_present_index;
2435 picture->poc = ((reorder_pool->cur_present_index * 2) %
2436 encoder->max_pic_order_cnt);
2438 is_idr = (reorder_pool->frame_index == 0 ||
2439 reorder_pool->frame_index >= encoder->idr_period);
2441 /* check key frames */
2442 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
2443 (reorder_pool->frame_index %
2444 GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) {
2445 ++reorder_pool->cur_frame_num;
2446 ++reorder_pool->frame_index;
2448 /* b frame enabled, check queue of reorder_frame_list */
2449 if (encoder->num_bframes
2450 && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2451 GstVaapiEncPicture *p_pic;
2453 p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
2454 set_p_frame (p_pic, encoder);
2455 g_queue_foreach (&reorder_pool->reorder_frame_list,
2456 (GFunc) set_b_frame, encoder);
2457 ++reorder_pool->cur_frame_num;
2458 set_key_frame (picture, encoder, is_idr);
2459 g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
2461 reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
2462 } else { /* no b frames in queue */
2463 set_key_frame (picture, encoder, is_idr);
2464 g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list));
2465 if (encoder->num_bframes)
2466 reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
2471 /* new p/b frames coming */
2472 ++reorder_pool->frame_index;
2473 if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
2474 g_queue_get_length (&reorder_pool->reorder_frame_list) <
2475 encoder->num_bframes) {
2476 g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
2477 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
2480 ++reorder_pool->cur_frame_num;
2481 set_p_frame (picture, encoder);
2483 if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
2484 g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame,
2486 reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
2487 g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list));
2492 frame = picture->frame;
2493 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
2494 frame->pts += encoder->cts_offset;
2497 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2500 static GstVaapiEncoderStatus
2501 set_context_info (GstVaapiEncoder * base_encoder)
2503 GstVaapiEncoderH264 *const encoder =
2504 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2505 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
2506 const guint DEFAULT_SURFACES_COUNT = 3;
2508 /* Maximum sizes for common headers (in bits) */
2511 MAX_SPS_HDR_SIZE = 16473,
2512 MAX_VUI_PARAMS_SIZE = 210,
2513 MAX_HRD_PARAMS_SIZE = 4103,
2514 MAX_PPS_HDR_SIZE = 101,
2515 MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
2518 if (!ensure_hw_profile (encoder))
2519 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2521 base_encoder->num_ref_frames =
2522 ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT)
2523 * encoder->num_views;
2525 /* Only YUV 4:2:0 formats are supported for now. This means that we
2526 have a limit of 3200 bits per macroblock. */
2527 /* XXX: check profile and compute RawMbBits */
2528 base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
2529 GST_ROUND_UP_16 (vip->height) / 256) * 400;
2531 /* Account for SPS header */
2532 /* XXX: exclude scaling lists, MVC/SVC extensions */
2533 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
2534 MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
2536 /* Account for PPS header */
2537 /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
2538 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
2540 /* Account for slice header */
2541 base_encoder->codedbuf_size += encoder->num_slices * (4 +
2542 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
2544 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2547 static GstVaapiEncoderStatus
2548 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
2550 GstVaapiEncoderH264 *const encoder =
2551 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2552 GstVaapiEncoderStatus status;
2553 guint mb_width, mb_height;
2555 mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
2556 mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
2557 if (mb_width != encoder->mb_width || mb_height != encoder->mb_height) {
2558 GST_DEBUG ("resolution: %dx%d", GST_VAAPI_ENCODER_WIDTH (encoder),
2559 GST_VAAPI_ENCODER_HEIGHT (encoder));
2560 encoder->mb_width = mb_width;
2561 encoder->mb_height = mb_height;
2562 encoder->config_changed = TRUE;
2565 status = ensure_profile_and_level (encoder);
2566 if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
2569 reset_properties (encoder);
2570 return set_context_info (base_encoder);
2574 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
2576 GstVaapiEncoderH264 *const encoder =
2577 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2580 /* Multi-view coding information */
2581 encoder->is_mvc = FALSE;
2582 encoder->num_views = 1;
2583 encoder->view_idx = 0;
2585 /* re-ordering list initialize */
2586 for (i = 0; i < MAX_NUM_VIEWS; i++) {
2587 GstVaapiH264ViewReorderPool *const reorder_pool =
2588 &encoder->reorder_pools[i];
2589 g_queue_init (&reorder_pool->reorder_frame_list);
2590 reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
2591 reorder_pool->frame_index = 0;
2592 reorder_pool->cur_frame_num = 0;
2593 reorder_pool->cur_present_index = 0;
2596 /* reference list info initialize */
2597 for (i = 0; i < MAX_NUM_VIEWS; i++) {
2598 GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
2599 g_queue_init (&ref_pool->ref_list);
2600 ref_pool->max_ref_frames = 0;
2601 ref_pool->max_reflist0_count = 1;
2602 ref_pool->max_reflist1_count = 1;
2609 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
2611 /*free private buffers */
2612 GstVaapiEncoderH264 *const encoder =
2613 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2614 GstVaapiEncPicture *pic;
2615 GstVaapiEncoderH264Ref *ref;
2618 gst_buffer_replace (&encoder->sps_data, NULL);
2619 gst_buffer_replace (&encoder->subset_sps_data, NULL);
2620 gst_buffer_replace (&encoder->pps_data, NULL);
2622 /* reference list info de-init */
2623 for (i = 0; i < MAX_NUM_VIEWS; i++) {
2624 GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
2625 while (!g_queue_is_empty (&ref_pool->ref_list)) {
2626 ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&ref_pool->ref_list);
2627 reference_pic_free (encoder, ref);
2629 g_queue_clear (&ref_pool->ref_list);
2632 /* re-ordering list initialize */
2633 for (i = 0; i < MAX_NUM_VIEWS; i++) {
2634 GstVaapiH264ViewReorderPool *const reorder_pool =
2635 &encoder->reorder_pools[i];
2636 while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2637 pic = (GstVaapiEncPicture *)
2638 g_queue_pop_head (&reorder_pool->reorder_frame_list);
2639 gst_vaapi_enc_picture_unref (pic);
2641 g_queue_clear (&reorder_pool->reorder_frame_list);
2645 static GstVaapiEncoderStatus
2646 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
2647 gint prop_id, const GValue * value)
2649 GstVaapiEncoderH264 *const encoder =
2650 GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2653 case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
2654 encoder->num_bframes = g_value_get_uint (value);
2656 case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
2657 encoder->init_qp = g_value_get_uint (value);
2659 case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
2660 encoder->min_qp = g_value_get_uint (value);
2662 case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
2663 encoder->num_slices = g_value_get_uint (value);
2665 case GST_VAAPI_ENCODER_H264_PROP_CABAC:
2666 encoder->use_cabac = g_value_get_boolean (value);
2668 case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
2669 encoder->use_dct8x8 = g_value_get_boolean (value);
2671 case GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH:
2672 encoder->cpb_length = g_value_get_uint (value);
2674 case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS:
2675 encoder->num_views = g_value_get_uint (value);
2678 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
2680 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2683 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
2685 static inline const GstVaapiEncoderClass *
2686 gst_vaapi_encoder_h264_class (void)
2688 static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
2689 GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
2690 .set_property = gst_vaapi_encoder_h264_set_property,
2691 .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
2693 return &GstVaapiEncoderH264Class;
2697 * gst_vaapi_encoder_h264_new:
2698 * @display: a #GstVaapiDisplay
2700 * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
2701 * only supported output stream format is "byte-stream" format.
2703 * Return value: the newly allocated #GstVaapiEncoder object
2706 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
2708 return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
2712 * gst_vaapi_encoder_h264_get_default_properties:
2714 * Determines the set of common and H.264 specific encoder properties.
2715 * The caller owns an extra reference to the resulting array of
2716 * #GstVaapiEncoderPropInfo elements, so it shall be released with
2717 * g_ptr_array_unref() after usage.
2719 * Return value: the set of encoder properties for #GstVaapiEncoderH264,
2720 * or %NULL if an error occurred.
2723 gst_vaapi_encoder_h264_get_default_properties (void)
2725 const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
2728 props = gst_vaapi_encoder_properties_get_default (klass);
2733 * GstVaapiEncoderH264:max-bframes:
2735 * The number of B-frames between I and P.
2737 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2738 GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
2739 g_param_spec_uint ("max-bframes",
2740 "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
2741 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2744 * GstVaapiEncoderH264:init-qp:
2746 * The initial quantizer value.
2748 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2749 GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
2750 g_param_spec_uint ("init-qp",
2751 "Initial QP", "Initial quantizer value", 1, 51, 26,
2752 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2755 * GstVaapiEncoderH264:min-qp:
2757 * The minimum quantizer value.
2759 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2760 GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
2761 g_param_spec_uint ("min-qp",
2762 "Minimum QP", "Minimum quantizer value", 1, 51, 1,
2763 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2766 * GstVaapiEncoderH264:num-slices:
2768 * The number of slices per frame.
2770 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2771 GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
2772 g_param_spec_uint ("num-slices",
2774 "Number of slices per frame",
2775 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2778 * GstVaapiEncoderH264:cabac:
2780 * Enable CABAC entropy coding mode for improved compression ratio,
2781 * at the expense that the minimum target profile is Main. Default
2782 * is CAVLC entropy coding mode.
2784 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2785 GST_VAAPI_ENCODER_H264_PROP_CABAC,
2786 g_param_spec_boolean ("cabac",
2788 "Enable CABAC entropy coding mode",
2789 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2792 * GstVaapiEncoderH264:dct8x8:
2794 * Enable adaptive use of 8x8 transforms in I-frames. This improves
2795 * the compression ratio by the minimum target profile is High.
2796 * Default is to use 4x4 DCT only.
2798 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2799 GST_VAAPI_ENCODER_H264_PROP_DCT8X8,
2800 g_param_spec_boolean ("dct8x8",
2802 "Enable adaptive use of 8x8 transforms in I-frames",
2803 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2806 * GstVaapiEncoderH264:cpb-length:
2808 * The size of the CPB buffer in milliseconds.
2810 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2811 GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH,
2812 g_param_spec_uint ("cpb-length",
2813 "CPB Length", "Length of the CPB buffer in milliseconds",
2814 1, 10000, DEFAULT_CPB_LENGTH,
2815 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2818 * GstVaapiEncoderH264:num-views:
2820 * The number of views for MVC encoding .
2822 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2823 GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS,
2824 g_param_spec_uint ("num-views",
2826 "Number of Views for MVC encoding",
2827 1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2833 * gst_vaapi_encoder_h264_set_max_profile:
2834 * @encoder: a #GstVaapiEncoderH264
2835 * @profile: an H.264 #GstVaapiProfile
2837 * Notifies the @encoder to use coding tools from the supplied
2840 * This means that if the minimal profile derived to
2841 * support the specified coding tools is greater than this @profile,
2842 * then an error is returned when the @encoder is configured.
2844 * Return value: %TRUE on success
2847 gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
2848 GstVaapiProfile profile)
2852 g_return_val_if_fail (encoder != NULL, FALSE);
2853 g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
2855 if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
2858 profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
2862 encoder->max_profile_idc = profile_idc;
2867 * gst_vaapi_encoder_h264_get_profile_and_level:
2868 * @encoder: a #GstVaapiEncoderH264
2869 * @out_profile_ptr: return location for the #GstVaapiProfile
2870 * @out_level_ptr: return location for the #GstVaapiLevelH264
2872 * Queries the H.264 @encoder for the active profile and level. That
2873 * information is only constructed and valid after the encoder is
2874 * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
2875 * function is called.
2877 * Return value: %TRUE on success
2880 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
2881 GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
2883 g_return_val_if_fail (encoder != NULL, FALSE);
2885 if (!encoder->profile || !encoder->level)
2888 if (out_profile_ptr)
2889 *out_profile_ptr = encoder->profile;
2891 *out_level_ptr = encoder->level;