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
23 #include "gstvaapicompat.h"
24 #include "gstvaapiencoder_h264.h"
25 #include "gstvaapiencoder_h264_priv.h"
26 #include "gstvaapiencoder_priv.h"
27 #include "gstvaapicodedbufferproxy_priv.h"
30 #include <va/va_enc_h264.h>
32 #include "gstvaapicontext.h"
33 #include "gstvaapisurface.h"
34 #include "gstvaapidisplay_priv.h"
37 #include "gstvaapidebug.h"
39 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0
40 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1
41 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2
42 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH 3
46 GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CAVLC = 0,
47 GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC = 1
48 } GstVaapiEncoderH264EntropyMode;
52 GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0,
53 GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1,
54 GST_VAAPI_ENCODER_H264_NAL_IDR = 5, /* ref_idc != 0 */
55 GST_VAAPI_ENCODER_H264_NAL_SEI = 6, /* ref_idc == 0 */
56 GST_VAAPI_ENCODER_H264_NAL_SPS = 7,
57 GST_VAAPI_ENCODER_H264_NAL_PPS = 8
58 } GstVaapiEncoderH264NalType;
69 GstVaapiSurfaceProxy *pic;
72 } GstVaapiEncoderH264Ref;
74 #define GST_VAAPI_H264_CAPS \
76 "framerate = (fraction) [0/1, MAX], " \
77 "width = (int) [ 1, MAX ], " \
78 "height = (int) [ 1, MAX ], " \
79 "stream-format = (string) { avc, byte-stream }, " \
80 "alignment = (string) { au } "
84 GST_VAAPI_ENC_H264_REORD_NONE = 0,
85 GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
86 GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
87 } GstVaapiEncH264ReorderState;
89 static inline gboolean
90 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
92 return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
96 _get_va_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 static inline gboolean
112 _read_sps_attributes (const guint8 * sps_data,
114 guint32 * profile_idc, guint32 * profile_comp, guint32 * level_idc)
116 g_assert (profile_idc && profile_comp && level_idc);
117 g_assert (sps_size >= 4);
121 /* skip sps_data[0], nal_type */
122 *profile_idc = sps_data[1];
123 *profile_comp = sps_data[2];
124 *level_idc = sps_data[3];
129 _get_log2_max_frame_num (guint num)
141 /* must greater than 4 */
146 _profile_to_value (GstVaapiProfile profile)
149 case GST_VAAPI_PROFILE_H264_BASELINE:
151 case GST_VAAPI_PROFILE_H264_MAIN:
153 case GST_VAAPI_PROFILE_H264_HIGH:
162 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
163 const guint8 * nal, guint32 size)
170 if (encoder->sps_data && encoder->pps_data)
173 nal_type = nal[0] & 0x1F;
175 case GST_VAAPI_ENCODER_H264_NAL_SPS:
176 encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
177 ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
178 g_assert (ret == size);
180 case GST_VAAPI_ENCODER_H264_NAL_PPS:
181 encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
182 ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
183 g_assert (ret == size);
191 _set_level (GstVaapiEncoderH264 * encoder)
194 guint MaxDpbMbs, MaxMBPS;
195 guint dbp_level, mbps_level, profile_level;
197 if (encoder->level) {
198 if (encoder->level < GST_VAAPI_ENCODER_H264_LEVEL_10)
199 encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_10;
200 else if (encoder->level > GST_VAAPI_ENCODER_H264_LEVEL_51)
201 encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_51;
205 /* calculate level */
206 pic_mb_size = ((GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16) *
207 ((GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16);
208 MaxDpbMbs = pic_mb_size * ((encoder->b_frame_num) ? 2 : 1);
209 MaxMBPS = pic_mb_size * GST_VAAPI_ENCODER_FPS_N (encoder) /
210 GST_VAAPI_ENCODER_FPS_D (encoder);
212 /* calculate from MaxDbpMbs */
213 if (MaxDpbMbs > 110400)
214 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_51;
215 else if (MaxDpbMbs > 34816)
216 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_50;
217 else if (MaxDpbMbs > 32768)
218 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_42;
219 else if (MaxDpbMbs > 20480) /* 41 or 40 */
220 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
221 else if (MaxDpbMbs > 18000)
222 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_32;
223 else if (MaxDpbMbs > 8100)
224 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_31;
225 else if (MaxDpbMbs > 4752) /* 30 or 22 */
226 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
227 else if (MaxDpbMbs > 2376)
228 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_21;
229 else if (MaxDpbMbs > 900) /* 20, 13, 12 */
230 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
231 else if (MaxDpbMbs > 396)
232 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_11;
234 dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_10;
236 /* calculate from Max Mb processing rate */
237 if (MaxMBPS > 589824)
238 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_51;
239 else if (MaxMBPS > 522240)
240 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_50;
241 else if (MaxMBPS > 245760)
242 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_42;
243 else if (MaxMBPS > 216000) /* 40 or 41 */
244 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
245 else if (MaxMBPS > 108000)
246 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_32;
247 else if (MaxMBPS > 40500)
248 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_31;
249 else if (MaxMBPS > 20250)
250 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
251 else if (MaxMBPS > 19800)
252 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_22;
253 else if (MaxMBPS > 11800)
254 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_21;
255 else if (MaxMBPS > 6000) /*13 or 20 */
256 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
257 else if (MaxMBPS > 3000)
258 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_12;
259 else if (MaxMBPS > 1485)
260 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_11;
262 mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_10;
264 if (encoder->profile == GST_VAAPI_PROFILE_H264_HIGH)
265 profile_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
266 else if (encoder->profile == GST_VAAPI_PROFILE_H264_MAIN)
267 profile_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
269 profile_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
271 encoder->level = (dbp_level > mbps_level ? dbp_level : mbps_level);
272 if (encoder->level < profile_level)
273 encoder->level = profile_level;
277 _reset_gop_start (GstVaapiEncoderH264 * encoder)
280 encoder->frame_index = 1;
281 encoder->cur_frame_num = 0;
282 encoder->cur_present_index = 0;
286 _set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
288 g_assert (pic && encoder);
289 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
290 pic->type = GST_VAAPI_PICTURE_TYPE_B;
291 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
295 _set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
297 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
298 pic->type = GST_VAAPI_PICTURE_TYPE_P;
299 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
303 _set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
305 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
306 pic->type = GST_VAAPI_PICTURE_TYPE_I;
307 pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
308 g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
309 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
313 _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
315 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
316 pic->type = GST_VAAPI_PICTURE_TYPE_I;
319 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
321 g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
322 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
326 _set_key_frame (GstVaapiEncPicture * picture,
327 GstVaapiEncoderH264 * encoder, gboolean is_idr)
330 _reset_gop_start (encoder);
331 _set_idr_frame (picture, encoder);
333 _set_i_frame (picture, encoder);
337 gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value)
339 guint32 size_in_bits = 0;
340 guint32 tmp_value = ++value;
347 && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1))
349 if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits))
355 gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value)
360 new_val = -(value << 1);
362 new_val = (value << 1) - 1;
364 if (!gst_bit_writer_put_ue (bitwriter, new_val))
371 gst_bit_writer_write_nal_header (GstBitWriter * bitwriter,
372 guint32 nal_ref_idc, guint32 nal_unit_type)
374 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
375 gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2);
376 gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5);
381 gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter)
383 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
384 gst_bit_writer_align_bytes_unchecked (bitwriter, 0);
389 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
390 VAEncSequenceParameterBufferH264 * seq, GstVaapiProfile profile)
392 guint32 constraint_set0_flag, constraint_set1_flag;
393 guint32 constraint_set2_flag, constraint_set3_flag;
394 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
395 gboolean nal_hrd_parameters_present_flag;
397 guint32 b_qpprime_y_zero_transform_bypass = 0;
398 guint32 residual_color_transform_flag = 0;
399 guint32 pic_height_in_map_units =
400 (seq->seq_fields.bits.frame_mbs_only_flag ?
401 seq->picture_height_in_mbs : seq->picture_height_in_mbs / 2);
402 guint32 mb_adaptive_frame_field = !seq->seq_fields.bits.frame_mbs_only_flag;
405 constraint_set0_flag = profile == GST_VAAPI_PROFILE_H264_BASELINE;
406 constraint_set1_flag = profile <= GST_VAAPI_PROFILE_H264_MAIN;
407 constraint_set2_flag = 0;
408 constraint_set3_flag = 0;
411 gst_bit_writer_put_bits_uint32 (bitwriter, _profile_to_value (profile), 8);
412 /* constraint_set0_flag */
413 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1);
414 /* constraint_set1_flag */
415 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1);
416 /* constraint_set2_flag */
417 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1);
418 /* constraint_set3_flag */
419 gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1);
420 /* reserved_zero_4bits */
421 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4);
423 gst_bit_writer_put_bits_uint32 (bitwriter, seq->level_idc, 8);
424 /* seq_parameter_set_id */
425 gst_bit_writer_put_ue (bitwriter, seq->seq_parameter_set_id);
427 if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
428 /* for high profile */
429 /* chroma_format_idc = 1, 4:2:0 */
430 gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.chroma_format_idc);
431 if (3 == seq->seq_fields.bits.chroma_format_idc) {
432 gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag,
435 /* bit_depth_luma_minus8 */
436 gst_bit_writer_put_ue (bitwriter, seq->bit_depth_luma_minus8);
437 /* bit_depth_chroma_minus8 */
438 gst_bit_writer_put_ue (bitwriter, seq->bit_depth_chroma_minus8);
439 /* b_qpprime_y_zero_transform_bypass */
440 gst_bit_writer_put_bits_uint32 (bitwriter,
441 b_qpprime_y_zero_transform_bypass, 1);
442 g_assert (seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
443 /*seq_scaling_matrix_present_flag */
444 gst_bit_writer_put_bits_uint32 (bitwriter,
445 seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
448 if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) {
449 for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
451 gst_bit_writer_put_bits_uint8 (bitwriter,
452 seq->seq_fields.bits.seq_scaling_list_present_flag, 1);
453 if (seq->seq_fields.bits.seq_scaling_list_present_flag) {
455 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
462 /* log2_max_frame_num_minus4 */
463 gst_bit_writer_put_ue (bitwriter,
464 seq->seq_fields.bits.log2_max_frame_num_minus4);
465 /* pic_order_cnt_type */
466 gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.pic_order_cnt_type);
468 if (seq->seq_fields.bits.pic_order_cnt_type == 0) {
469 /* log2_max_pic_order_cnt_lsb_minus4 */
470 gst_bit_writer_put_ue (bitwriter,
471 seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
472 } else if (seq->seq_fields.bits.pic_order_cnt_type == 1) {
474 gst_bit_writer_put_bits_uint32 (bitwriter,
475 seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
476 gst_bit_writer_put_se (bitwriter, seq->offset_for_non_ref_pic);
477 gst_bit_writer_put_se (bitwriter, seq->offset_for_top_to_bottom_field);
478 gst_bit_writer_put_ue (bitwriter,
479 seq->num_ref_frames_in_pic_order_cnt_cycle);
480 for (i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) {
481 gst_bit_writer_put_se (bitwriter, seq->offset_for_ref_frame[i]);
486 gst_bit_writer_put_ue (bitwriter, seq->max_num_ref_frames);
487 /* gaps_in_frame_num_value_allowed_flag */
488 gst_bit_writer_put_bits_uint32 (bitwriter,
489 gaps_in_frame_num_value_allowed_flag, 1);
491 /* pic_width_in_mbs_minus1 */
492 gst_bit_writer_put_ue (bitwriter, seq->picture_width_in_mbs - 1);
493 /* pic_height_in_map_units_minus1 */
494 gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1);
495 /* frame_mbs_only_flag */
496 gst_bit_writer_put_bits_uint32 (bitwriter,
497 seq->seq_fields.bits.frame_mbs_only_flag, 1);
499 if (!seq->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
501 gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1);
504 /* direct_8x8_inference_flag */
505 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
506 /* frame_cropping_flag */
507 gst_bit_writer_put_bits_uint32 (bitwriter, seq->frame_cropping_flag, 1);
509 if (seq->frame_cropping_flag) {
510 /* frame_crop_left_offset */
511 gst_bit_writer_put_ue (bitwriter, seq->frame_crop_left_offset);
512 /* frame_crop_right_offset */
513 gst_bit_writer_put_ue (bitwriter, seq->frame_crop_right_offset);
514 /* frame_crop_top_offset */
515 gst_bit_writer_put_ue (bitwriter, seq->frame_crop_top_offset);
516 /* frame_crop_bottom_offset */
517 gst_bit_writer_put_ue (bitwriter, seq->frame_crop_bottom_offset);
520 /* vui_parameters_present_flag */
521 gst_bit_writer_put_bits_uint32 (bitwriter, seq->vui_parameters_present_flag,
523 if (seq->vui_parameters_present_flag) {
524 /* aspect_ratio_info_present_flag */
525 gst_bit_writer_put_bits_uint32 (bitwriter,
526 seq->vui_fields.bits.aspect_ratio_info_present_flag, 1);
527 if (seq->vui_fields.bits.aspect_ratio_info_present_flag) {
528 gst_bit_writer_put_bits_uint32 (bitwriter, seq->aspect_ratio_idc, 8);
529 if (seq->aspect_ratio_idc == 0xFF) {
530 gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_width, 16);
531 gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_height, 16);
535 /* overscan_info_present_flag */
536 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
537 /* video_signal_type_present_flag */
538 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
539 /* chroma_loc_info_present_flag */
540 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
542 /* timing_info_present_flag */
543 gst_bit_writer_put_bits_uint32 (bitwriter,
544 seq->vui_fields.bits.timing_info_present_flag, 1);
545 if (seq->vui_fields.bits.timing_info_present_flag) {
546 gst_bit_writer_put_bits_uint32 (bitwriter, seq->num_units_in_tick, 32);
547 gst_bit_writer_put_bits_uint32 (bitwriter, seq->time_scale, 32);
548 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */
551 nal_hrd_parameters_present_flag = (seq->bits_per_second > 0 ? TRUE : FALSE);
552 /* nal_hrd_parameters_present_flag */
553 gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag,
555 if (nal_hrd_parameters_present_flag) {
558 gst_bit_writer_put_ue (bitwriter, 0);
559 gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */
560 gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */
562 for (i = 0; i < 1; ++i) {
563 /* bit_rate_value_minus1[0] */
564 gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 - 1);
565 /* cpb_size_value_minus1[0] */
566 gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 * 8 - 1);
568 gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
570 /* initial_cpb_removal_delay_length_minus1 */
571 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
572 /* cpb_removal_delay_length_minus1 */
573 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
574 /* dpb_output_delay_length_minus1 */
575 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
576 /* time_offset_length */
577 gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
579 /* vcl_hrd_parameters_present_flag */
580 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
581 if (nal_hrd_parameters_present_flag
582 || 0 /*vcl_hrd_parameters_present_flag */ ) {
583 /* low_delay_hrd_flag */
584 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
586 /* pic_struct_present_flag */
587 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
588 /* bitwriter_restriction_flag */
589 gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
592 /* rbsp_trailing_bits */
593 gst_bit_writer_write_trailing_bits (bitwriter);
598 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
599 VAEncPictureParameterBufferH264 * pic)
601 guint32 num_slice_groups_minus1 = 0;
602 guint32 pic_init_qs_minus26 = 0;
603 guint32 redundant_pic_cnt_present_flag = 0;
605 /* pic_parameter_set_id */
606 gst_bit_writer_put_ue (bitwriter, pic->pic_parameter_set_id);
607 /* seq_parameter_set_id */
608 gst_bit_writer_put_ue (bitwriter, pic->seq_parameter_set_id);
609 /* entropy_coding_mode_flag */
610 gst_bit_writer_put_bits_uint32 (bitwriter,
611 pic->pic_fields.bits.entropy_coding_mode_flag, 1);
612 /* pic_order_present_flag */
613 gst_bit_writer_put_bits_uint32 (bitwriter,
614 pic->pic_fields.bits.pic_order_present_flag, 1);
616 gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1);
618 if (num_slice_groups_minus1 > 0) {
619 /*FIXME*/ g_assert (0);
621 gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l0_active_minus1);
622 gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l1_active_minus1);
623 gst_bit_writer_put_bits_uint32 (bitwriter,
624 pic->pic_fields.bits.weighted_pred_flag, 1);
625 gst_bit_writer_put_bits_uint32 (bitwriter,
626 pic->pic_fields.bits.weighted_bipred_idc, 2);
627 /* pic_init_qp_minus26 */
628 gst_bit_writer_put_se (bitwriter, pic->pic_init_qp - 26);
629 /* pic_init_qs_minus26 */
630 gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26);
631 /*chroma_qp_index_offset */
632 gst_bit_writer_put_se (bitwriter, pic->chroma_qp_index_offset);
634 gst_bit_writer_put_bits_uint32 (bitwriter,
635 pic->pic_fields.bits.deblocking_filter_control_present_flag, 1);
636 gst_bit_writer_put_bits_uint32 (bitwriter,
637 pic->pic_fields.bits.constrained_intra_pred_flag, 1);
638 gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1);
641 gst_bit_writer_put_bits_uint32 (bitwriter,
642 pic->pic_fields.bits.transform_8x8_mode_flag, 1);
643 gst_bit_writer_put_bits_uint32 (bitwriter,
644 pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
645 if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) {
650 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag));
652 gst_bit_writer_put_bits_uint8(bitwriter, pic->pic_fields.bits.pic_scaling_list_present_flag, 1);
657 gst_bit_writer_put_se (bitwriter, pic->second_chroma_qp_index_offset);
658 gst_bit_writer_write_trailing_bits (bitwriter);
664 add_sequence_packed_header (GstVaapiEncoderH264 * encoder,
665 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
667 GstVaapiEncPackedHeader *packed_seq;
669 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
670 VAEncSequenceParameterBufferH264 *seq_param = sequence->param;
671 guint32 data_bit_size;
674 gst_bit_writer_init (&writer, 128 * 8);
675 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
676 gst_bit_writer_write_nal_header (&writer,
677 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
678 gst_bit_writer_write_sps (&writer, seq_param, encoder->profile);
679 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
680 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
681 data = GST_BIT_WRITER_DATA (&writer);
683 packed_header_param_buffer.type = VAEncPackedHeaderSequence;
684 packed_header_param_buffer.bit_length = data_bit_size;
685 packed_header_param_buffer.has_emulation_bytes = 0;
687 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
688 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
689 data, (data_bit_size + 7) / 8);
690 g_assert (packed_seq);
692 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
693 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL);
696 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
698 gst_bit_writer_clear (&writer, TRUE);
704 add_picture_packed_header (GstVaapiEncoderH264 * encoder,
705 GstVaapiEncPicture * picture)
707 GstVaapiEncPackedHeader *packed_pic;
709 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
710 VAEncPictureParameterBufferH264 *pic_param = picture->param;
711 guint32 data_bit_size;
714 gst_bit_writer_init (&writer, 128 * 8);
715 gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32); /* start code */
716 gst_bit_writer_write_nal_header (&writer,
717 GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
718 gst_bit_writer_write_pps (&writer, pic_param);
719 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
720 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
721 data = GST_BIT_WRITER_DATA (&writer);
723 packed_header_param_buffer.type = VAEncPackedHeaderPicture;
724 packed_header_param_buffer.bit_length = data_bit_size;
725 packed_header_param_buffer.has_emulation_bytes = 0;
727 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
728 &packed_header_param_buffer, sizeof (packed_header_param_buffer),
729 data, (data_bit_size + 7) / 8);
730 g_assert (packed_pic);
732 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
733 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_pic, NULL);
736 _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
737 gst_bit_writer_clear (&writer, TRUE);
742 /* reference picture management */
744 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
749 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
750 g_slice_free (GstVaapiEncoderH264Ref, ref);
753 static inline GstVaapiEncoderH264Ref *
754 reference_pic_create (GstVaapiEncoderH264 * encoder,
755 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
757 GstVaapiEncoderH264Ref *ref = g_slice_new0 (GstVaapiEncoderH264Ref);
760 ref->frame_num = picture->frame_num;
761 ref->poc = picture->poc;
766 reference_list_update (GstVaapiEncoderH264 * encoder,
767 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
769 GstVaapiEncoderH264Ref *ref;
771 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
772 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
775 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
776 while (!g_queue_is_empty (&encoder->ref_list))
777 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
778 } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_num) {
779 reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
781 ref = reference_pic_create (encoder, picture, surface);
782 g_queue_push_tail (&encoder->ref_list, ref);
783 g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_num);
788 reference_list_init (GstVaapiEncoderH264 * encoder,
789 GstVaapiEncPicture * picture,
790 GstVaapiEncoderH264Ref ** reflist_0,
791 guint * reflist_0_count,
792 GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
794 GstVaapiEncoderH264Ref *tmp;
795 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
796 guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
799 *reflist_0_count = 0;
800 *reflist_1_count = 0;
801 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
804 iter = g_queue_peek_tail_link (&encoder->ref_list);
805 for (; iter; iter = g_list_previous (iter)) {
806 tmp = (GstVaapiEncoderH264Ref *) iter->data;
807 g_assert (tmp && tmp->poc != picture->poc);
808 if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
810 list_1_start = g_list_next (iter);
815 /* order reflist_0 */
816 g_assert (list_0_start);
819 for (; iter; iter = g_list_previous (iter)) {
820 reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
823 *reflist_0_count = count;
825 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
828 /* order reflist_1 */
831 for (; iter; iter = g_list_next (iter)) {
832 reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
835 *reflist_1_count = count;
839 /* fill the H264 VA encoding parameters */
841 fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
842 GstVaapiEncSequence * sequence)
844 VAEncSequenceParameterBufferH264 *seq = sequence->param;
845 guint width_in_mbs, height_in_mbs;
847 width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
848 height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
850 memset (seq, 0, sizeof (VAEncSequenceParameterBufferH264));
851 seq->seq_parameter_set_id = 0;
852 seq->level_idc = encoder->level;
853 seq->intra_period = encoder->intra_period;
854 seq->ip_period = 0; // ?
855 if (encoder->bitrate > 0)
856 seq->bits_per_second = encoder->bitrate * 1024;
858 seq->bits_per_second = 0;
860 seq->max_num_ref_frames = encoder->max_ref_num;
861 seq->picture_width_in_mbs = width_in_mbs;
862 seq->picture_height_in_mbs = height_in_mbs;
864 /*sequence field values */
865 seq->seq_fields.value = 0;
866 seq->seq_fields.bits.chroma_format_idc = 1;
867 seq->seq_fields.bits.frame_mbs_only_flag = 1;
868 seq->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
869 seq->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
870 /* direct_8x8_inference_flag default false */
871 seq->seq_fields.bits.direct_8x8_inference_flag = FALSE;
872 g_assert (encoder->log2_max_frame_num >= 4);
873 seq->seq_fields.bits.log2_max_frame_num_minus4 =
874 encoder->log2_max_frame_num - 4;
875 /* picture order count */
876 seq->seq_fields.bits.pic_order_cnt_type = 0;
877 g_assert (encoder->log2_max_pic_order_cnt >= 4);
878 seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
879 encoder->log2_max_pic_order_cnt - 4;
881 seq->bit_depth_luma_minus8 = 0;
882 seq->bit_depth_chroma_minus8 = 0;
884 /* not used if pic_order_cnt_type == 0 */
885 if (seq->seq_fields.bits.pic_order_cnt_type == 1) {
886 seq->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
887 seq->num_ref_frames_in_pic_order_cnt_cycle = 0;
888 seq->offset_for_non_ref_pic = 0;
889 seq->offset_for_top_to_bottom_field = 0;
890 memset (seq->offset_for_ref_frame, 0, sizeof (seq->offset_for_ref_frame));
893 if (height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) {
894 seq->frame_cropping_flag = 1;
895 seq->frame_crop_left_offset = 0;
896 seq->frame_crop_right_offset = 0;
897 seq->frame_crop_top_offset = 0;
898 seq->frame_crop_bottom_offset =
899 ((height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) /
900 (2 * (!seq->seq_fields.bits.frame_mbs_only_flag + 1)));
904 seq->vui_parameters_present_flag = (encoder->bitrate > 0 ? TRUE : FALSE);
905 if (seq->vui_parameters_present_flag) {
906 seq->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
907 seq->vui_fields.bits.bitstream_restriction_flag = FALSE;
908 seq->vui_fields.bits.timing_info_present_flag =
909 (encoder->bitrate > 0 ? TRUE : FALSE);
910 if (seq->vui_fields.bits.timing_info_present_flag) {
911 seq->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
912 seq->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
920 fill_va_picture_param (GstVaapiEncoderH264 * encoder,
921 GstVaapiEncPicture * picture,
922 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
924 VAEncPictureParameterBufferH264 *pic = picture->param;
925 GstVaapiEncoderH264Ref *ref_pic;
929 memset (pic, 0, sizeof (VAEncPictureParameterBufferH264));
931 /* reference list, */
932 pic->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
933 pic->CurrPic.TopFieldOrderCnt = picture->poc;
935 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
936 for (reflist = g_queue_peek_head_link (&encoder->ref_list);
937 reflist; reflist = g_list_next (reflist)) {
938 ref_pic = reflist->data;
939 g_assert (ref_pic && ref_pic->pic &&
940 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
942 pic->ReferenceFrames[i].picture_id =
943 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
946 g_assert (i <= 16 && i <= encoder->max_ref_num);
948 for (; i < 16; ++i) {
949 pic->ReferenceFrames[i].picture_id = VA_INVALID_ID;
951 pic->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
953 pic->pic_parameter_set_id = 0;
954 pic->seq_parameter_set_id = 0;
955 pic->last_picture = 0; /* means last encoding picture */
956 pic->frame_num = picture->frame_num;
957 pic->pic_init_qp = encoder->init_qp;
958 pic->num_ref_idx_l0_active_minus1 =
959 (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
960 pic->num_ref_idx_l1_active_minus1 =
961 (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
962 pic->chroma_qp_index_offset = 0;
963 pic->second_chroma_qp_index_offset = 0;
965 /* set picture fields */
966 pic->pic_fields.value = 0;
967 pic->pic_fields.bits.idr_pic_flag = GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
968 pic->pic_fields.bits.reference_pic_flag =
969 (picture->type != GST_VAAPI_PICTURE_TYPE_B);
970 pic->pic_fields.bits.entropy_coding_mode_flag =
971 GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC;
972 pic->pic_fields.bits.weighted_pred_flag = FALSE;
973 pic->pic_fields.bits.weighted_bipred_idc = 0;
974 pic->pic_fields.bits.constrained_intra_pred_flag = 0;
975 pic->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH); /* enable 8x8 */
976 /* enable debloking */
977 pic->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
978 pic->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
979 /* bottom_field_pic_order_in_frame_present_flag */
980 pic->pic_fields.bits.pic_order_present_flag = FALSE;
981 pic->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
987 fill_va_slices_param (GstVaapiEncoderH264 * encoder,
988 GstVaapiEncPicture * picture,
989 GstVaapiEncoderH264Ref ** reflist_0,
990 guint reflist_0_count,
991 GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
993 VAEncSliceParameterBufferH264 *slice_param;
994 GstVaapiEncSlice *slice;
995 guint width_in_mbs, height_in_mbs;
996 guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
999 guint i_slice, i_ref;
1003 width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1004 height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1005 total_mbs = width_in_mbs * height_in_mbs;
1007 g_assert (encoder->slice_num && encoder->slice_num < total_mbs);
1008 slice_of_mbs = total_mbs / encoder->slice_num;
1009 slice_mod_mbs = total_mbs % encoder->slice_num;
1011 for (i_slice = 0; i_slice < encoder->slice_num; ++i_slice) {
1012 cur_slice_mbs = slice_of_mbs;
1013 if (slice_mod_mbs) {
1017 slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1018 g_assert (slice && slice->param_id != VA_INVALID_ID);
1019 slice_param = slice->param;
1021 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1022 slice_param->macroblock_address = last_mb_index;
1023 slice_param->num_macroblocks = cur_slice_mbs;
1024 slice_param->macroblock_info = VA_INVALID_ID;
1025 slice_param->slice_type = _get_va_slice_type (picture->type);
1026 g_assert (slice_param->slice_type != -1);
1027 slice_param->pic_parameter_set_id = 0;
1028 slice_param->idr_pic_id = encoder->idr_num;
1029 slice_param->pic_order_cnt_lsb = picture->poc;
1031 /* not used if pic_order_cnt_type = 0 */
1032 slice_param->delta_pic_order_cnt_bottom = 0;
1033 memset (slice_param->delta_pic_order_cnt,
1034 0, sizeof (slice_param->delta_pic_order_cnt));
1036 /*only works for B frames */
1037 slice_param->direct_spatial_mv_pred_flag = FALSE;
1038 /* default equal to picture parameters */
1039 slice_param->num_ref_idx_active_override_flag = FALSE;
1040 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1041 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1043 slice_param->num_ref_idx_l0_active_minus1 = 0;
1044 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1045 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1047 slice_param->num_ref_idx_l1_active_minus1 = 0;
1048 g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1049 g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1052 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1053 for (; i_ref < reflist_0_count; ++i_ref) {
1054 slice_param->RefPicList0[i_ref].picture_id =
1055 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1057 g_assert (i_ref == 1);
1061 sizeof (slice_param->RefPicList0) /
1062 sizeof (slice_param->RefPicList0[0]); ++i_ref) {
1063 slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1067 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1068 for (; i_ref < reflist_1_count; ++i_ref) {
1069 slice_param->RefPicList1[i_ref].picture_id =
1070 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1072 g_assert (i_ref == 1);
1076 sizeof (slice_param->RefPicList1) /
1077 sizeof (slice_param->RefPicList1[0]); ++i_ref) {
1078 slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1081 /* not used if pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1082 slice_param->luma_log2_weight_denom = 0;
1083 slice_param->chroma_log2_weight_denom = 0;
1084 slice_param->luma_weight_l0_flag = FALSE;
1085 memset (slice_param->luma_weight_l0, 0,
1086 sizeof (slice_param->luma_weight_l0));
1087 memset (slice_param->luma_offset_l0, 0,
1088 sizeof (slice_param->luma_offset_l0));
1089 slice_param->chroma_weight_l0_flag = FALSE;
1090 memset (slice_param->chroma_weight_l0, 0,
1091 sizeof (slice_param->chroma_weight_l0));
1092 memset (slice_param->chroma_offset_l0, 0,
1093 sizeof (slice_param->chroma_offset_l0));
1094 slice_param->luma_weight_l1_flag = FALSE;
1095 memset (slice_param->luma_weight_l1, 0,
1096 sizeof (slice_param->luma_weight_l1));
1097 memset (slice_param->luma_offset_l1, 0,
1098 sizeof (slice_param->luma_offset_l1));
1099 slice_param->chroma_weight_l1_flag = FALSE;
1100 memset (slice_param->chroma_weight_l1, 0,
1101 sizeof (slice_param->chroma_weight_l1));
1102 memset (slice_param->chroma_offset_l1, 0,
1103 sizeof (slice_param->chroma_offset_l1));
1105 slice_param->cabac_init_idc = 0;
1106 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1107 if (slice_param->slice_qp_delta > 4)
1108 slice_param->slice_qp_delta = 4;
1109 slice_param->disable_deblocking_filter_idc = 0;
1110 slice_param->slice_alpha_c0_offset_div2 = 2;
1111 slice_param->slice_beta_offset_div2 = 2;
1113 /* set calculation for next slice */
1114 last_mb_index += cur_slice_mbs;
1116 gst_vaapi_enc_picture_add_slice (picture, slice);
1117 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice, NULL);
1120 g_assert (last_mb_index == total_mbs);
1125 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1127 GstVaapiEncSequence *sequence;
1130 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1131 g_assert (sequence);
1135 if (!fill_va_sequence_param (encoder, sequence))
1138 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1139 !add_sequence_packed_header (encoder, picture, sequence))
1141 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1142 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL);
1146 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL);
1151 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1152 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1154 GstVaapiCodedBuffer *const codedbuf =
1155 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1157 if (!fill_va_picture_param (encoder, picture, codedbuf, surface))
1160 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1161 !add_picture_packed_header (encoder, picture)) {
1162 GST_ERROR ("set picture packed header failed");
1170 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1172 GstVaapiEncoderH264Ref *reflist_0[16];
1173 GstVaapiEncoderH264Ref *reflist_1[16];
1174 guint reflist_0_count = 0, reflist_1_count = 0;
1178 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1179 !reference_list_init (encoder, picture,
1180 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1181 GST_ERROR ("reference list reorder failed");
1185 g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_num);
1186 if (reflist_0_count > encoder->max_reflist0_count)
1187 reflist_0_count = encoder->max_reflist0_count;
1188 if (reflist_1_count > encoder->max_reflist1_count)
1189 reflist_1_count = encoder->max_reflist1_count;
1191 if (!fill_va_slices_param (encoder, picture,
1192 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1199 ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1201 GstVaapiEncMiscParam *misc = NULL;
1202 VAEncMiscParameterHRD *hrd;
1203 VAEncMiscParameterRateControl *rate_control;
1206 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1210 gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1212 if (encoder->bitrate > 0) {
1213 hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4;
1214 hrd->buffer_size = encoder->bitrate * 1024 * 8;
1216 hrd->initial_buffer_fullness = 0;
1217 hrd->buffer_size = 0;
1219 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL);
1221 /* add ratecontrol */
1222 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1223 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1224 misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1228 gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1229 rate_control = misc->impl;
1230 memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1231 if (encoder->bitrate)
1232 rate_control->bits_per_second = encoder->bitrate * 1024;
1234 rate_control->bits_per_second = 0;
1235 rate_control->target_percentage = 70;
1236 rate_control->window_size = 500;
1237 rate_control->initial_qp = encoder->init_qp;
1238 rate_control->min_qp = encoder->min_qp;
1239 rate_control->basic_unit_size = 0;
1240 gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL);
1247 init_encoder_public_attributes (GstVaapiEncoderH264 * encoder)
1249 guint width_mbs, height_mbs, total_mbs;
1251 if (!GST_VAAPI_ENCODER_WIDTH (encoder) ||
1252 !GST_VAAPI_ENCODER_HEIGHT (encoder) ||
1253 !GST_VAAPI_ENCODER_FPS_N (encoder) ||
1254 !GST_VAAPI_ENCODER_FPS_D (encoder)) {
1257 if (!encoder->profile)
1258 encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE;
1260 _set_level (encoder);
1262 if (!encoder->intra_period)
1263 encoder->intra_period = GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD;
1264 else if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD)
1265 encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD;
1267 if (encoder->idr_period < encoder->intra_period)
1268 encoder->idr_period = encoder->intra_period;
1269 if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD)
1270 encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD;
1272 if (-1 == encoder->init_qp)
1273 encoder->init_qp = GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP;
1275 if (-1 == encoder->min_qp) {
1276 if (GST_VAAPI_RATECONTROL_CQP == GST_VAAPI_ENCODER_RATE_CONTROL (encoder))
1277 encoder->min_qp = encoder->init_qp;
1279 encoder->min_qp = GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP;
1282 if (encoder->min_qp > encoder->init_qp)
1283 encoder->min_qp = encoder->init_qp;
1285 /* default compress ratio 1: (4*8*1.5) */
1286 if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
1287 GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
1288 GST_VAAPI_RATECONTROL_VBR_CONSTRAINED ==
1289 GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1290 if (!encoder->bitrate)
1291 encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
1292 GST_VAAPI_ENCODER_HEIGHT (encoder) *
1293 GST_VAAPI_ENCODER_FPS_N (encoder) /
1294 GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
1296 encoder->bitrate = 0;
1298 if (!encoder->slice_num)
1299 encoder->slice_num = GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM;
1301 width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1302 height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1303 total_mbs = width_mbs * height_mbs;
1305 if (encoder->slice_num > (total_mbs + 1) / 2)
1306 encoder->slice_num = (total_mbs + 1) / 2;
1307 g_assert (encoder->slice_num);
1309 if (encoder->b_frame_num > (encoder->intra_period + 1) / 2)
1310 encoder->b_frame_num = (encoder->intra_period + 1) / 2;
1312 if (encoder->b_frame_num > 50)
1313 encoder->b_frame_num = 50;
1319 init_encoder_private_attributes (GstVaapiEncoderH264 * encoder, GstCaps * caps)
1321 if (encoder->b_frame_num)
1322 encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1323 GST_VAAPI_ENCODER_FPS_N (encoder);
1325 encoder->cts_offset = 0;
1327 /* init max_frame_num, max_poc */
1328 encoder->log2_max_frame_num = _get_log2_max_frame_num (encoder->idr_period);
1329 g_assert (encoder->log2_max_frame_num >= 4);
1330 encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1331 encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1332 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1334 encoder->frame_index = 0;
1335 encoder->idr_num = 0;
1336 encoder->max_reflist0_count = 1;
1337 if (encoder->b_frame_num)
1338 encoder->max_reflist1_count = 1;
1340 encoder->max_reflist1_count = 0;
1341 encoder->max_ref_num =
1342 encoder->max_reflist0_count + encoder->max_reflist1_count;
1347 static GstVaapiEncoderStatus
1348 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base,
1349 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1351 GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base);
1352 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1353 GstVaapiSurfaceProxy *reconstruct = NULL;
1355 reconstruct = gst_vaapi_encoder_create_surface (base);
1357 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1359 if (!ensure_sequence (encoder, picture))
1361 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1363 if (!ensure_misc (encoder, picture))
1365 if (!ensure_slices (encoder, picture))
1367 if (!gst_vaapi_enc_picture_encode (picture))
1370 if (!reference_list_update (encoder, picture, reconstruct))
1373 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1376 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1381 static GstVaapiEncoderStatus
1382 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base)
1384 GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base);
1385 GstVaapiEncPicture *pic;
1387 encoder->frame_index = 0;
1388 encoder->cur_frame_num = 0;
1389 encoder->cur_present_index = 0;
1390 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1392 (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list);
1393 gst_vaapi_enc_picture_unref (pic);
1395 g_queue_clear (&encoder->reorder_frame_list);
1397 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1400 static GstVaapiEncoderStatus
1401 gst_vaapi_encoder_h264_get_avcC_codec_data (GstVaapiEncoderH264 * encoder,
1402 GstBuffer ** buffer)
1404 GstBuffer *avc_codec;
1405 const guint32 configuration_version = 0x01;
1406 const guint32 length_size_minus_one = 0x03;
1407 guint32 profile, profile_comp, level_idc;
1408 GstMapInfo sps_info, pps_info;
1409 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS;
1410 GstBitWriter writer;
1413 if (!encoder->sps_data || !encoder->pps_data)
1414 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1416 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1417 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1419 if (FALSE == _read_sps_attributes (sps_info.data, sps_info.size,
1420 &profile, &profile_comp, &level_idc)) {
1421 ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1425 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) {
1426 ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1430 gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8);
1432 gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8);
1433 gst_bit_writer_put_bits_uint32 (&writer, profile, 8);
1434 gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8);
1435 gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8);
1436 gst_bit_writer_put_bits_uint32 (&writer, 0x3F, 6); /*111111 */
1437 gst_bit_writer_put_bits_uint32 (&writer, length_size_minus_one, 2);
1438 gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3); /*111 */
1441 gst_bit_writer_put_bits_uint32 (&writer, 1, 5); /* sps count = 1 */
1442 g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
1443 gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16);
1444 gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size);
1447 gst_bit_writer_put_bits_uint32 (&writer, 1, 8); /*pps count = 1 */
1448 gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16);
1449 gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size);
1451 avc_codec = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer),
1452 GST_BIT_WRITER_BIT_SIZE (&writer) / 8);
1453 g_assert (avc_codec);
1455 ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1458 *buffer = avc_codec;
1460 gst_buffer_unmap (encoder->pps_data, &pps_info);
1461 gst_bit_writer_clear (&writer, FALSE);
1462 ret = GST_VAAPI_ENCODER_STATUS_SUCCESS;
1466 gst_bit_writer_clear (&writer, TRUE);
1469 gst_buffer_unmap (encoder->sps_data, &sps_info);
1474 static GstVaapiEncoderStatus
1475 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base,
1476 GstBuffer ** buffer)
1478 GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base);
1482 if (!encoder->is_avc)
1483 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1485 return gst_vaapi_encoder_h264_get_avcC_codec_data (encoder, buffer);
1488 static GstVaapiEncoderStatus
1489 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base,
1490 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1492 GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base);
1493 GstVaapiEncPicture *picture;
1494 gboolean is_idr = FALSE;
1499 if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1500 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1502 /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1503 dump B frames from queue, sometime, there may also have P frame or I frame */
1504 g_assert (encoder->b_frame_num > 0);
1505 g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1506 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1507 picture = g_queue_pop_head (&encoder->reorder_frame_list);
1509 if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1510 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1515 /* new frame coming */
1516 picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1518 GST_WARNING ("create H264 picture failed, frame timestamp:%"
1519 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1520 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1522 ++encoder->cur_present_index;
1523 picture->poc = ((encoder->cur_present_index * 2) %
1524 encoder->max_pic_order_cnt);
1526 is_idr = (encoder->frame_index == 0 ||
1527 encoder->frame_index >= encoder->idr_period);
1529 /* check key frames */
1530 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1531 (encoder->frame_index % encoder->intra_period) == 0) {
1532 ++encoder->cur_frame_num;
1533 ++encoder->frame_index;
1535 /* b frame enabled, check queue of reorder_frame_list */
1536 if (encoder->b_frame_num
1537 && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1538 GstVaapiEncPicture *p_pic;
1540 p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1541 _set_p_frame (p_pic, encoder);
1542 g_queue_foreach (&encoder->reorder_frame_list,
1543 (GFunc) _set_b_frame, encoder);
1544 ++encoder->cur_frame_num;
1545 _set_key_frame (picture, encoder, is_idr);
1546 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1548 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1549 } else { /* no b frames in queue */
1550 _set_key_frame (picture, encoder, is_idr);
1551 g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1552 if (encoder->b_frame_num)
1553 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1558 /* new p/b frames coming */
1559 ++encoder->frame_index;
1560 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1561 g_queue_get_length (&encoder->reorder_frame_list) <
1562 encoder->b_frame_num) {
1563 g_queue_push_tail (&encoder->reorder_frame_list, picture);
1564 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1567 ++encoder->cur_frame_num;
1568 _set_p_frame (picture, encoder);
1570 if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1571 g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame,
1573 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1574 g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1579 frame = GST_VAAPI_ENC_PICTURE_GET_FRAME (picture);
1580 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1581 frame->pts += encoder->cts_offset;
1584 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1588 gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder)
1590 GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder);
1591 GstVaapiContextInfo *const cip = &base_encoder->context_info;
1592 const guint DEFAULT_SURFACES_COUNT = 3;
1594 /* Maximum sizes for common headers (in bits) */
1597 MAX_SPS_HDR_SIZE = 16473,
1598 MAX_VUI_PARAMS_SIZE = 210,
1599 MAX_HRD_PARAMS_SIZE = 4103,
1600 MAX_PPS_HDR_SIZE = 101,
1601 MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1604 cip->profile = encoder->profile;
1605 cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1607 /* Only YUV 4:2:0 formats are supported for now. This means that we
1608 have a limit of 3200 bits per macroblock. */
1609 /* XXX: check profile and compute RawMbBits */
1610 base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) *
1611 GST_ROUND_UP_16 (cip->height) / 256) * 400;
1613 /* Account for SPS header */
1614 /* XXX: exclude scaling lists, MVC/SVC extensions */
1615 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1616 MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1618 /* Account for PPS header */
1619 /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1620 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1622 /* Account for slice header. At most 200 slices are supported */
1623 base_encoder->codedbuf_size += 200 * (4 +
1624 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1628 gst_vaapi_encoder_h264_set_format (GstVaapiEncoder * base,
1629 GstVideoCodecState * in_state, GstCaps * ref_caps)
1631 GstVaapiEncoderH264 *encoder;
1632 GstCaps *result = NULL, *tmp;
1633 GstStructure *structure;
1634 const GValue *value;
1635 const gchar *stream_format;
1637 encoder = GST_VAAPI_ENCODER_H264 (base);
1639 tmp = gst_caps_from_string ("video/x-h264");
1640 gst_caps_set_simple (tmp,
1641 "width", G_TYPE_INT, GST_VAAPI_ENCODER_WIDTH (encoder),
1642 "height", G_TYPE_INT, GST_VAAPI_ENCODER_HEIGHT (encoder),
1643 "framerate", GST_TYPE_FRACTION,
1644 GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder),
1646 result = gst_caps_intersect (tmp, ref_caps);
1647 gst_caps_unref (tmp);
1649 /* fixed stream-format and choose byte-stream first */
1650 structure = gst_caps_get_structure (result, 0);
1651 value = gst_structure_get_value (structure, "stream-format");
1653 gst_structure_fixate_field_string (structure, "stream-format",
1655 stream_format = gst_structure_get_string (structure, "stream-format");
1657 stream_format = "byte-stream";
1658 gst_structure_set (structure, "stream-format", G_TYPE_STRING, stream_format,
1662 if (strcmp (stream_format, "byte-stream") == 0)
1663 encoder->is_avc = FALSE;
1664 else /* need codec data later */
1665 encoder->is_avc = TRUE;
1667 #if GST_CHECK_VERSION(1,0,0)
1668 result = gst_caps_fixate (result);
1671 if (!init_encoder_public_attributes (encoder)) {
1672 GST_WARNING ("encoder ensure public attributes failed ");
1676 if (!init_encoder_private_attributes (encoder, result)) {
1677 GST_WARNING ("prepare encoding failed ");
1684 gst_caps_unref (result);
1689 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base)
1691 GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base);
1693 /* init attributes */
1694 encoder->profile = 0;
1696 encoder->bitrate = 0;
1697 encoder->idr_period = 0;
1698 encoder->intra_period = 0;
1699 encoder->init_qp = -1;
1700 encoder->min_qp = -1;
1701 encoder->slice_num = 0;
1702 encoder->b_frame_num = 0;
1703 //gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
1705 /* init private values */
1706 encoder->is_avc = FALSE;
1708 g_queue_init (&encoder->reorder_frame_list);
1709 encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1710 encoder->frame_index = 0;
1711 encoder->cur_frame_num = 0;
1712 encoder->cur_present_index = 0;
1714 g_queue_init (&encoder->ref_list);
1715 encoder->max_ref_num = 0;
1716 encoder->max_reflist0_count = 1;
1717 encoder->max_reflist1_count = 1;
1719 encoder->sps_data = NULL;
1720 encoder->pps_data = NULL;
1722 encoder->cts_offset = 0;
1724 encoder->max_frame_num = 0;
1725 encoder->log2_max_frame_num = 0;
1726 encoder->max_pic_order_cnt = 0;
1727 encoder->log2_max_pic_order_cnt = 0;
1728 encoder->idr_num = 0;
1734 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base)
1736 /*free private buffers */
1737 GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base);
1738 GstVaapiEncPicture *pic;
1739 GstVaapiEncoderH264Ref *ref;
1741 gst_buffer_replace (&encoder->sps_data, NULL);
1742 gst_buffer_replace (&encoder->pps_data, NULL);
1744 while (!g_queue_is_empty (&encoder->ref_list)) {
1745 ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&encoder->ref_list);
1746 reference_pic_free (encoder, ref);
1748 g_queue_clear (&encoder->ref_list);
1750 while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1752 (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list);
1753 gst_vaapi_enc_picture_unref (pic);
1755 g_queue_clear (&encoder->reorder_frame_list);
1759 static inline const GstVaapiEncoderClass *
1760 gst_vaapi_encoder_h264_class (void)
1762 static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1763 GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1764 .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1766 return &GstVaapiEncoderH264Class;
1770 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1772 return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1776 gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc)
1778 encoder->is_avc = is_avc;
1782 gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder)
1784 return encoder->is_avc;