Merge branch 'move_subdir_editing-services' into tizen_gst_1.19.2_mono
[platform/upstream/gstreamer.git] / subprojects / gstreamer-vaapi / gst-libs / gst / vaapi / gstvaapiencoder_h265.c
1 /*
2  *  gstvaapiencoder_h265.c - H.265 encoder
3  *
4  *  Copyright (C) 2015 Intel Corporation
5  *    Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 #include "sysdeps.h"
24 #include <math.h>
25 #include <gst/base/gstbitwriter.h>
26 #include <gst/codecparsers/gsth265parser.h>
27 #include "gstvaapicompat.h"
28 #include "gstvaapiencoder_priv.h"
29 #include "gstvaapiencoder_h265.h"
30 #include "gstvaapiutils_h265.h"
31 #include "gstvaapiutils_h265_priv.h"
32 #include "gstvaapiutils_h26x_priv.h"
33 #include "gstvaapicodedbufferproxy_priv.h"
34 #include "gstvaapisurface.h"
35
36 #define DEBUG 1
37 #include "gstvaapidebug.h"
38
39 /* Supported set of VA rate controls, within this implementation */
40 #define SUPPORTED_RATECONTROLS                          \
41   (GST_VAAPI_RATECONTROL_MASK (CQP) |                   \
42    GST_VAAPI_RATECONTROL_MASK (CBR) |                   \
43    GST_VAAPI_RATECONTROL_MASK (VBR) |                   \
44    GST_VAAPI_RATECONTROL_MASK (ICQ) |                   \
45    GST_VAAPI_RATECONTROL_MASK (QVBR))
46
47 /* Supported set of tuning options, within this implementation */
48 #define SUPPORTED_TUNE_OPTIONS                          \
49   (GST_VAAPI_ENCODER_TUNE_MASK (NONE) |                 \
50    GST_VAAPI_ENCODER_TUNE_MASK (LOW_POWER))
51
52 /* Supported set of VA packed headers, within this implementation */
53 #define SUPPORTED_PACKED_HEADERS                \
54   (VA_ENC_PACKED_HEADER_SEQUENCE |              \
55    VA_ENC_PACKED_HEADER_PICTURE  |              \
56    VA_ENC_PACKED_HEADER_SLICE)
57
58 typedef struct
59 {
60   GstVaapiSurfaceProxy *pic;
61   guint poc;
62 } GstVaapiEncoderH265Ref;
63
64 typedef enum
65 {
66   GST_VAAPI_ENC_H265_REORD_NONE = 0,
67   GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES = 1,
68   GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES = 2
69 } GstVaapiEncH265ReorderState;
70
71 typedef struct _GstVaapiH265RefPool
72 {
73   GQueue ref_list;
74   guint max_ref_frames;
75   guint max_reflist0_count;
76   guint max_reflist1_count;
77 } GstVaapiH265RefPool;
78
79 typedef struct _GstVaapiH265ReorderPool
80 {
81   GQueue reorder_frame_list;
82   guint reorder_state;
83   guint frame_index;
84   guint cur_present_index;
85 } GstVaapiH265ReorderPool;
86
87 /* ------------------------------------------------------------------------- */
88 /* --- H.265 Encoder                                                     --- */
89 /* ------------------------------------------------------------------------- */
90
91 struct _GstVaapiEncoderH265
92 {
93   GstVaapiEncoder parent_instance;
94
95   GstVaapiProfile profile;
96   GstVaapiTierH265 tier;
97   GstVaapiLevelH265 level;
98   GstVaapiEntrypoint entrypoint;
99   guint8 profile_idc;
100   GArray *allowed_profiles;
101   guint8 level_idc;
102   guint32 idr_period;
103   guint32 init_qp;
104   guint32 min_qp;
105   guint32 max_qp;
106   guint32 qp_i;
107   guint32 qp_ip;
108   guint32 qp_ib;
109   guint32 num_slices;
110   guint32 num_bframes;
111   guint32 ctu_width;            /* CTU == Coding Tree Unit */
112   guint32 ctu_height;
113   guint32 luma_width;
114   guint32 luma_height;
115   guint32 quality_factor;
116   GstClockTime cts_offset;
117   gboolean config_changed;
118   /* Always need two reference lists for inter frame */
119   gboolean no_p_frame;
120   guint32 num_tile_cols;
121   guint32 num_tile_rows;
122   /* CTUs start address used in stream pack */
123   guint32 *tile_slice_address;
124   /* CTUs in this slice */
125   guint32 *tile_slice_ctu_num;
126   /* map the tile_slice_address to CTU start address in picture,
127      which is used by VA API. */
128   guint32 *tile_slice_address_map;
129
130   /* maximum required size of the decoded picture buffer */
131   guint32 max_dec_pic_buffering;
132   /* maximum allowed number of pictures that can precede any picture in
133    * the CVS in decoding order and follow that picture in output order */
134   guint32 max_num_reorder_pics;
135
136   /* frame, poc */
137   guint32 max_pic_order_cnt;
138   guint32 log2_max_pic_order_cnt;
139   guint32 idr_num;
140   guint num_ref_frames;
141
142   GstBuffer *vps_data;
143   GstBuffer *sps_data;
144   GstBuffer *pps_data;
145
146   guint bitrate_bits;           // bitrate (bits)
147   guint cpb_length;             // length of CPB buffer (ms)
148   guint cpb_length_bits;        // length of CPB buffer (bits)
149   GstVaapiEncoderMbbrc mbbrc;   // macroblock bitrate control
150
151   /* Crop rectangle */
152   guint conformance_window_flag:1;
153   guint32 conf_win_left_offset;
154   guint32 conf_win_right_offset;
155   guint32 conf_win_top_offset;
156   guint32 conf_win_bottom_offset;
157
158   GstVaapiH265RefPool ref_pool;
159   GstVaapiH265ReorderPool reorder_pool;
160   guint first_slice_segment_in_pic_flag:1;
161   guint sps_temporal_mvp_enabled_flag:1;
162   guint sample_adaptive_offset_enabled_flag:1;
163 };
164
165 static inline gboolean
166 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
167 {
168   return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
169 }
170
171 /* Get slice_type value for H.265 specification */
172 static guint8
173 h265_get_slice_type (GstVaapiPictureType type)
174 {
175   switch (type) {
176     case GST_VAAPI_PICTURE_TYPE_I:
177       return GST_H265_I_SLICE;
178     case GST_VAAPI_PICTURE_TYPE_P:
179       return GST_H265_P_SLICE;
180     case GST_VAAPI_PICTURE_TYPE_B:
181       return GST_H265_B_SLICE;
182     default:
183       break;
184   }
185   return -1;
186 }
187
188 static gboolean
189 h265_is_scc (GstVaapiEncoderH265 * encoder)
190 {
191   if (encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN ||
192       encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10 ||
193       encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444 ||
194       encoder->profile == GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10)
195     return TRUE;
196
197   return FALSE;
198 }
199
200 static gboolean
201 h265_is_tile_enabled (GstVaapiEncoderH265 * encoder)
202 {
203   return encoder->num_tile_cols * encoder->num_tile_rows > 1;
204 }
205
206 /* Get log2_max_pic_order_cnt value for H.265 specification */
207 static guint
208 h265_get_log2_max_pic_order_cnt (guint num)
209 {
210   guint ret = 0;
211
212   while (num) {
213     ++ret;
214     num >>= 1;
215   }
216   if (ret <= 4)
217     ret = 4;
218   else if (ret > 16)
219     ret = 16;
220   /* must be greater than 4 */
221   return ret;
222 }
223
224 /* Write the NAL unit header */
225 static gboolean
226 bs_write_nal_header (GstBitWriter * bs, guint32 nal_unit_type)
227 {
228   guint8 nuh_layer_id = 0;
229   guint8 nuh_temporal_id_plus1 = 1;
230
231   WRITE_UINT32 (bs, 0, 1);
232   WRITE_UINT32 (bs, nal_unit_type, 6);
233   WRITE_UINT32 (bs, nuh_layer_id, 6);
234   WRITE_UINT32 (bs, nuh_temporal_id_plus1, 3);
235
236   return TRUE;
237
238   /* ERRORS */
239 bs_error:
240   {
241     GST_WARNING ("failed to write NAL unit header");
242     return FALSE;
243   }
244 }
245
246 /* Write the NAL unit trailing bits */
247 static gboolean
248 bs_write_trailing_bits (GstBitWriter * bs)
249 {
250   if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
251     goto bs_error;
252   gst_bit_writer_align_bytes_unchecked (bs, 0);
253   return TRUE;
254
255   /* ERRORS */
256 bs_error:
257   {
258     GST_WARNING ("failed to write NAL unit trailing bits");
259     return FALSE;
260   }
261 }
262
263 /* Write profile_tier_level()  */
264 static gboolean
265 bs_write_profile_tier_level (GstBitWriter * bs,
266     const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile)
267 {
268   guint i;
269
270   /* general_profile_space */
271   WRITE_UINT32 (bs, 0, 2);
272   /* general_tier_flag */
273   WRITE_UINT32 (bs, seq_param->general_tier_flag, 1);
274   /* general_profile_idc */
275   WRITE_UINT32 (bs, seq_param->general_profile_idc, 5);
276
277   /* general_profile_compatibility_flag[0] */
278   WRITE_UINT32 (bs, 0, 1);
279   /* general_profile_compatibility_flag[1] */
280   if (seq_param->general_profile_idc == 1       /* Main profile */
281       /* In A.3.4, NOTE: When general_profile_compatibility_flag[ 3 ] is equal
282          to 1, general_profile_compatibility_flag[ 1 ] and
283          general_profile_compatibility_flag[ 2 ] should also be equal to 1. */
284       || seq_param->general_profile_idc == 3    /* Main Still Picture profile */
285       ) {
286     WRITE_UINT32 (bs, 1, 1);
287   } else {
288     WRITE_UINT32 (bs, 0, 1);
289   }
290   /* general_profile_compatibility_flag[2] */
291   if (
292       /* In A.3.2, NOTE: When general_profile_compatibility_flag[ 1 ] is equal
293          to 1, general_profile_compatibility_flag[ 2 ] should also be equal to
294          1. */
295       seq_param->general_profile_idc == 1       /* Main profile */
296       || seq_param->general_profile_idc == 2    /* Main 10 profile */
297       /* In A.3.4, NOTE: When general_profile_compatibility_flag[ 3 ] is equal
298          to 1, general_profile_compatibility_flag[ 1 ] and
299          general_profile_compatibility_flag[ 2 ] should also be equal to 1. */
300       || seq_param->general_profile_idc == 3    /* Main Still Picture profile */
301       ) {
302     WRITE_UINT32 (bs, 1, 1);
303   } else {
304     WRITE_UINT32 (bs, 0, 1);
305   }
306   /* general_profile_compatibility_flag[3] */
307   if (seq_param->general_profile_idc == 3) {
308     WRITE_UINT32 (bs, 1, 1);
309   } else {
310     WRITE_UINT32 (bs, 0, 1);
311   }
312
313   /* general_profile_compatibility_flag[4] */
314   if (seq_param->general_profile_idc == 4) {    /* format range extensions profiles */
315     WRITE_UINT32 (bs, 1, 1);
316   } else {
317     WRITE_UINT32 (bs, 0, 1);
318   }
319
320   /* general_profile_compatibility_flag[5~8] */
321   WRITE_UINT32 (bs, 0, 4);
322
323   /* general_profile_compatibility_flag[9] */
324   if (seq_param->general_profile_idc == 9) {    /* screen content coding profiles */
325     WRITE_UINT32 (bs, 1, 1);
326   } else {
327     WRITE_UINT32 (bs, 0, 1);
328   }
329
330   /* general_profile_compatibility_flag[10~32] */
331   WRITE_UINT32 (bs, 0, 22);
332
333   /* general_progressive_source_flag */
334   WRITE_UINT32 (bs, 1, 1);
335   /* general_interlaced_source_flag */
336   WRITE_UINT32 (bs, 0, 1);
337   /* general_non_packed_constraint_flag */
338   WRITE_UINT32 (bs, 0, 1);
339   /* general_frame_only_constraint_flag */
340   WRITE_UINT32 (bs, 1, 1);
341
342   /* additional indications specified for general_profile_idc from 4~10 */
343   if (seq_param->general_profile_idc == 4) {
344     /* In A.3.5, Format range extensions profiles.
345        Just support main444, main444-10 and main422-10 profile now, may add
346        more profiles when needed. */
347     switch (profile) {
348       case GST_VAAPI_PROFILE_H265_MAIN_444:
349         /* max_12bit_constraint_flag */
350         WRITE_UINT32 (bs, 1, 1);
351         /* max_10bit_constraint_flag */
352         WRITE_UINT32 (bs, 1, 1);
353         /* max_8bit_constraint_flag */
354         WRITE_UINT32 (bs, 1, 1);
355         /* max_422chroma_constraint_flag */
356         WRITE_UINT32 (bs, 0, 1);
357         /* max_420chroma_constraint_flag */
358         WRITE_UINT32 (bs, 0, 1);
359         /* max_monochrome_constraint_flag */
360         WRITE_UINT32 (bs, 0, 1);
361         /* intra_constraint_flag */
362         WRITE_UINT32 (bs, 0, 1);
363         /* one_picture_only_constraint_flag */
364         WRITE_UINT32 (bs, 0, 1);
365         /* lower_bit_rate_constraint_flag */
366         WRITE_UINT32 (bs, 1, 1);
367         break;
368       case GST_VAAPI_PROFILE_H265_MAIN_444_10:
369         /* max_12bit_constraint_flag */
370         WRITE_UINT32 (bs, 1, 1);
371         /* max_10bit_constraint_flag */
372         WRITE_UINT32 (bs, 1, 1);
373         /* max_8bit_constraint_flag */
374         WRITE_UINT32 (bs, 0, 1);
375         /* max_422chroma_constraint_flag */
376         WRITE_UINT32 (bs, 0, 1);
377         /* max_420chroma_constraint_flag */
378         WRITE_UINT32 (bs, 0, 1);
379         /* max_monochrome_constraint_flag */
380         WRITE_UINT32 (bs, 0, 1);
381         /* intra_constraint_flag */
382         WRITE_UINT32 (bs, 0, 1);
383         /* one_picture_only_constraint_flag */
384         WRITE_UINT32 (bs, 0, 1);
385         /* lower_bit_rate_constraint_flag */
386         WRITE_UINT32 (bs, 1, 1);
387         break;
388       case GST_VAAPI_PROFILE_H265_MAIN_422_10:
389         /* max_12bit_constraint_flag */
390         WRITE_UINT32 (bs, 1, 1);
391         /* max_10bit_constraint_flag */
392         WRITE_UINT32 (bs, 1, 1);
393         /* max_8bit_constraint_flag */
394         WRITE_UINT32 (bs, 0, 1);
395         /* max_422chroma_constraint_flag */
396         WRITE_UINT32 (bs, 1, 1);
397         /* max_420chroma_constraint_flag */
398         WRITE_UINT32 (bs, 0, 1);
399         /* max_monochrome_constraint_flag */
400         WRITE_UINT32 (bs, 0, 1);
401         /* intra_constraint_flag */
402         WRITE_UINT32 (bs, 0, 1);
403         /* one_picture_only_constraint_flag */
404         WRITE_UINT32 (bs, 0, 1);
405         /* lower_bit_rate_constraint_flag */
406         WRITE_UINT32 (bs, 1, 1);
407         break;
408       case GST_VAAPI_PROFILE_H265_MAIN12:
409         /* max_12bit_constraint_flag */
410         WRITE_UINT32 (bs, 1, 1);
411         /* max_10bit_constraint_flag */
412         WRITE_UINT32 (bs, 0, 1);
413         /* max_8bit_constraint_flag */
414         WRITE_UINT32 (bs, 0, 1);
415         /* max_422chroma_constraint_flag */
416         WRITE_UINT32 (bs, 1, 1);
417         /* max_420chroma_constraint_flag */
418         WRITE_UINT32 (bs, 1, 1);
419         /* max_monochrome_constraint_flag */
420         WRITE_UINT32 (bs, 0, 1);
421         /* intra_constraint_flag */
422         WRITE_UINT32 (bs, 0, 1);
423         /* one_picture_only_constraint_flag */
424         WRITE_UINT32 (bs, 0, 1);
425         /* lower_bit_rate_constraint_flag */
426         WRITE_UINT32 (bs, 1, 1);
427         break;
428       default:
429         GST_WARNING ("do not support the profile: %s of range extensions",
430             gst_vaapi_profile_get_va_name (profile));
431         goto bs_error;
432     }
433
434     /* general_reserved_zero_34bits */
435     for (i = 0; i < 34; i++)
436       WRITE_UINT32 (bs, 0, 1);
437   } else if (seq_param->general_profile_idc == 9) {
438     /*  In A.3.7, Screen content coding extensions profiles. */
439     switch (profile) {
440       case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN:
441         /* max_12bit_constraint_flag */
442         WRITE_UINT32 (bs, 1, 1);
443         /* max_10bit_constraint_flag */
444         WRITE_UINT32 (bs, 1, 1);
445         /* max_8bit_constraint_flag */
446         WRITE_UINT32 (bs, 1, 1);
447         /* max_422chroma_constraint_flag */
448         WRITE_UINT32 (bs, 1, 1);
449         /* max_420chroma_constraint_flag */
450         WRITE_UINT32 (bs, 1, 1);
451         /* max_monochrome_constraint_flag */
452         WRITE_UINT32 (bs, 0, 1);
453         /* intra_constraint_flag */
454         WRITE_UINT32 (bs, 0, 1);
455         /* one_picture_only_constraint_flag */
456         WRITE_UINT32 (bs, 0, 1);
457         /* lower_bit_rate_constraint_flag */
458         WRITE_UINT32 (bs, 1, 1);
459         /* general_max_14bit_constraint_flag */
460         WRITE_UINT32 (bs, 1, 1);
461         break;
462       case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10:
463         /* max_12bit_constraint_flag */
464         WRITE_UINT32 (bs, 1, 1);
465         /* max_10bit_constraint_flag */
466         WRITE_UINT32 (bs, 1, 1);
467         /* max_8bit_constraint_flag */
468         WRITE_UINT32 (bs, 0, 1);
469         /* max_422chroma_constraint_flag */
470         WRITE_UINT32 (bs, 1, 1);
471         /* max_420chroma_constraint_flag */
472         WRITE_UINT32 (bs, 1, 1);
473         /* max_monochrome_constraint_flag */
474         WRITE_UINT32 (bs, 0, 1);
475         /* intra_constraint_flag */
476         WRITE_UINT32 (bs, 0, 1);
477         /* one_picture_only_constraint_flag */
478         WRITE_UINT32 (bs, 0, 1);
479         /* lower_bit_rate_constraint_flag */
480         WRITE_UINT32 (bs, 1, 1);
481         /* general_max_14bit_constraint_flag */
482         WRITE_UINT32 (bs, 1, 1);
483         break;
484       case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444:
485         /* max_12bit_constraint_flag */
486         WRITE_UINT32 (bs, 1, 1);
487         /* max_10bit_constraint_flag */
488         WRITE_UINT32 (bs, 1, 1);
489         /* max_8bit_constraint_flag */
490         WRITE_UINT32 (bs, 1, 1);
491         /* max_422chroma_constraint_flag */
492         WRITE_UINT32 (bs, 0, 1);
493         /* max_420chroma_constraint_flag */
494         WRITE_UINT32 (bs, 0, 1);
495         /* max_monochrome_constraint_flag */
496         WRITE_UINT32 (bs, 0, 1);
497         /* intra_constraint_flag */
498         WRITE_UINT32 (bs, 0, 1);
499         /* one_picture_only_constraint_flag */
500         WRITE_UINT32 (bs, 0, 1);
501         /* lower_bit_rate_constraint_flag */
502         WRITE_UINT32 (bs, 1, 1);
503         /* general_max_14bit_constraint_flag */
504         WRITE_UINT32 (bs, 1, 1);
505         break;
506       case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10:
507         /* max_12bit_constraint_flag */
508         WRITE_UINT32 (bs, 1, 1);
509         /* max_10bit_constraint_flag */
510         WRITE_UINT32 (bs, 1, 1);
511         /* max_8bit_constraint_flag */
512         WRITE_UINT32 (bs, 0, 1);
513         /* max_422chroma_constraint_flag */
514         WRITE_UINT32 (bs, 0, 1);
515         /* max_420chroma_constraint_flag */
516         WRITE_UINT32 (bs, 0, 1);
517         /* max_monochrome_constraint_flag */
518         WRITE_UINT32 (bs, 0, 1);
519         /* intra_constraint_flag */
520         WRITE_UINT32 (bs, 0, 1);
521         /* one_picture_only_constraint_flag */
522         WRITE_UINT32 (bs, 0, 1);
523         /* lower_bit_rate_constraint_flag */
524         WRITE_UINT32 (bs, 1, 1);
525         /* general_max_14bit_constraint_flag */
526         WRITE_UINT32 (bs, 1, 1);
527         break;
528       default:
529         GST_WARNING ("do not support the profile: %s of screen"
530             " content coding extensions",
531             gst_vaapi_profile_get_va_name (profile));
532         goto bs_error;
533     }
534
535     /* general_reserved_zero_33bits */
536     for (i = 0; i < 33; i++)
537       WRITE_UINT32 (bs, 0, 1);
538   } else {
539     /* general_reserved_zero_43bits */
540     for (i = 0; i < 43; i++)
541       WRITE_UINT32 (bs, 0, 1);
542   }
543
544   /* general_inbld_flag */
545   WRITE_UINT32 (bs, 0, 1);
546   /* general_level_idc */
547   WRITE_UINT32 (bs, seq_param->general_level_idc, 8);
548
549   return TRUE;
550
551   /* ERRORS */
552 bs_error:
553   {
554     GST_WARNING ("failed to write Profile Tier Level");
555     return FALSE;
556   }
557 }
558
559 /* Write an VPS NAL unit */
560 static gboolean
561 bs_write_vps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
562     GstVaapiEncPicture * picture,
563     const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile)
564 {
565   guint32 video_parameter_set_id = 0;
566   guint32 vps_max_layers_minus1 = 0;
567   guint32 vps_max_sub_layers_minus1 = 0;
568   guint32 vps_temporal_id_nesting_flag = 1;
569   guint32 vps_sub_layer_ordering_info_present_flag = 0;
570   guint32 vps_max_latency_increase_plus1 = 0;
571   guint32 vps_max_layer_id = 0;
572   guint32 vps_num_layer_sets_minus1 = 0;
573   guint32 vps_timing_info_present_flag = 0;
574   guint32 vps_extension_flag = 0;
575   guint32 vps_base_layer_internal_flag = 1;
576   guint32 vps_base_layer_available_flag = 1;
577
578   /* video_parameter_set_id */
579   WRITE_UINT32 (bs, video_parameter_set_id, 4);
580   /* vps_base_layer_internal_flag */
581   WRITE_UINT32 (bs, vps_base_layer_internal_flag, 1);
582   /* vps_base_layer_available_flag */
583   WRITE_UINT32 (bs, vps_base_layer_available_flag, 1);
584   /* vps_max_layers_minus1 */
585   WRITE_UINT32 (bs, vps_max_layers_minus1, 6);
586   /* vps_max_sub_layers_minus1 */
587   WRITE_UINT32 (bs, vps_max_sub_layers_minus1, 3);
588   /* vps_temporal_id_nesting_flag */
589   WRITE_UINT32 (bs, vps_temporal_id_nesting_flag, 1);
590   /* vps_reserved_0xffff_16bits */
591   WRITE_UINT32 (bs, 0xffff, 16);
592
593   /* profile_tier_level */
594   bs_write_profile_tier_level (bs, seq_param, profile);
595
596   /* vps_sub_layer_ordering_info_present_flag */
597   WRITE_UINT32 (bs, vps_sub_layer_ordering_info_present_flag, 1);
598   /* vps_max_dec_pic_buffering_minus1 */
599   WRITE_UE (bs, encoder->max_dec_pic_buffering - 1);
600   /* vps_max_num_reorder_pics */
601   WRITE_UE (bs, encoder->max_num_reorder_pics);
602   /* vps_max_latency_increase_plus1 */
603   WRITE_UE (bs, vps_max_latency_increase_plus1);
604   /* vps_max_layer_id */
605   WRITE_UINT32 (bs, vps_max_layer_id, 6);
606   /* vps_num_layer_sets_minus1 */
607   WRITE_UE (bs, vps_num_layer_sets_minus1);
608   /* vps_timing_info_present_flag */
609   WRITE_UINT32 (bs, vps_timing_info_present_flag, 1);
610   /* vps_extension_flag */
611   WRITE_UINT32 (bs, vps_extension_flag, 1);
612
613   return TRUE;
614
615   /* ERRORS */
616 bs_error:
617   {
618     GST_WARNING ("failed to write VPS NAL unit");
619     return FALSE;
620   }
621 }
622
623 static gboolean
624 bs_write_vps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
625     GstVaapiEncPicture * picture,
626     const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile)
627 {
628   if (!bs_write_vps_data (bs, encoder, picture, seq_param, profile))
629     return FALSE;
630
631   /* rbsp_trailing_bits */
632   bs_write_trailing_bits (bs);
633
634   return FALSE;
635 }
636
637 /* Write an SPS NAL unit */
638 static gboolean
639 bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
640     GstVaapiEncPicture * picture,
641     const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile,
642     GstVaapiRateControl rate_control, const VAEncMiscParameterHRD * hrd_params)
643 {
644   guint32 video_parameter_set_id = 0;
645   guint32 max_sub_layers_minus1 = 0;
646   guint32 temporal_id_nesting_flag = 1;
647   guint32 separate_colour_plane_flag = 0;
648   guint32 seq_parameter_set_id = 0;
649   guint32 sps_sub_layer_ordering_info_present_flag = 0;
650   guint32 sps_max_latency_increase_plus1 = 0;
651   guint32 num_short_term_ref_pic_sets = 0;
652   guint32 long_term_ref_pics_present_flag = 0;
653   guint32 sps_extension_flag = 0;
654   guint32 nal_hrd_parameters_present_flag = 0;
655   guint maxNumSubLayers = 1, i;
656   guint32 cbr_flag = rate_control == GST_VAAPI_RATECONTROL_CBR ? 1 : 0;
657
658   /* video_parameter_set_id */
659   WRITE_UINT32 (bs, video_parameter_set_id, 4);
660   /* max_sub_layers_minus1 */
661   WRITE_UINT32 (bs, max_sub_layers_minus1, 3);
662   /* temporal_id_nesting_flag */
663   WRITE_UINT32 (bs, temporal_id_nesting_flag, 1);
664
665   /* profile_tier_level */
666   bs_write_profile_tier_level (bs, seq_param, profile);
667
668   /* seq_parameter_set_id */
669   WRITE_UE (bs, seq_parameter_set_id);
670   /* chroma_format_idc  = 1, 4:2:0 */
671   WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
672   if (seq_param->seq_fields.bits.chroma_format_idc == 3)
673     /* if( chroma_format_idc == 3 )  separate_colour_plane_flag */
674     WRITE_UINT32 (bs, separate_colour_plane_flag, 1);
675   /* pic_width_in_luma_samples */
676   WRITE_UE (bs, seq_param->pic_width_in_luma_samples);
677   /* pic_height_in_luma_samples */
678   WRITE_UE (bs, seq_param->pic_height_in_luma_samples);
679
680   /* conformance_window_flag */
681   WRITE_UINT32 (bs, encoder->conformance_window_flag, 1);
682   if (encoder->conformance_window_flag) {
683     WRITE_UE (bs, encoder->conf_win_left_offset);
684     WRITE_UE (bs, encoder->conf_win_right_offset);
685     WRITE_UE (bs, encoder->conf_win_top_offset);
686     WRITE_UE (bs, encoder->conf_win_bottom_offset);
687   }
688
689   /* bit_depth_luma_minus8 */
690   WRITE_UE (bs, seq_param->seq_fields.bits.bit_depth_luma_minus8);
691   /* bit_depth_chroma_minus8 */
692   WRITE_UE (bs, seq_param->seq_fields.bits.bit_depth_chroma_minus8);
693   /* log2_max_pic_order_cnt_lsb_minus4  */
694   WRITE_UE (bs, encoder->log2_max_pic_order_cnt - 4);
695
696   /* sps_sub_layer_ordering_info_present_flag */
697   WRITE_UINT32 (bs, sps_sub_layer_ordering_info_present_flag, 1);
698   /* sps_max_dec_pic_buffering_minus1 */
699   WRITE_UE (bs, encoder->max_dec_pic_buffering - 1);
700   /* sps_max_num_reorder_pics */
701   WRITE_UE (bs, encoder->max_num_reorder_pics);
702   /* sps_max_latency_increase_plus1 */
703   WRITE_UE (bs, sps_max_latency_increase_plus1);
704
705   /* log2_min_luma_coding_block_size_minus3 */
706   WRITE_UE (bs, seq_param->log2_min_luma_coding_block_size_minus3);
707   /* log2_diff_max_min_luma_coding_block_size */
708   WRITE_UE (bs, seq_param->log2_diff_max_min_luma_coding_block_size);
709   /* log2_min_transform_block_size_minus2 */
710   WRITE_UE (bs, seq_param->log2_min_transform_block_size_minus2);
711   /* log2_diff_max_min_transform_block_size */
712   WRITE_UE (bs, seq_param->log2_diff_max_min_transform_block_size);
713   /* max_transform_hierarchy_depth_inter */
714   WRITE_UE (bs, seq_param->max_transform_hierarchy_depth_inter);
715   /*max_transform_hierarchy_depth_intra */
716   WRITE_UE (bs, seq_param->max_transform_hierarchy_depth_intra);
717
718   /* scaling_list_enabled_flag */
719   WRITE_UINT32 (bs, seq_param->seq_fields.bits.scaling_list_enabled_flag, 1);
720   /* amp_enabled_flag */
721   WRITE_UINT32 (bs, seq_param->seq_fields.bits.amp_enabled_flag, 1);
722   /* sample_adaptive_offset_enabled_flag */
723   WRITE_UINT32 (bs,
724       seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag, 1);
725   /* pcm_enabled_flag */
726   WRITE_UINT32 (bs, seq_param->seq_fields.bits.pcm_enabled_flag, 1);
727
728   /* num_short_term_ref_pic_sets  */
729   WRITE_UE (bs, num_short_term_ref_pic_sets);
730
731   /* long_term_ref_pics_present_flag */
732   WRITE_UINT32 (bs, long_term_ref_pics_present_flag, 1);
733
734   /* sps_temporal_mvp_enabled_flag */
735   WRITE_UINT32 (bs, seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag,
736       1);
737   /* strong_intra_smoothing_enabled_flag */
738   WRITE_UINT32 (bs,
739       seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag, 1);
740
741   /* vui_parameters_present_flag */
742   WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
743
744   /*--------------- Write VUI Parameters--------------- */
745   if (seq_param->vui_parameters_present_flag) {
746     gboolean vui_hrd_parameters_present_flag;
747     /* aspect_ratio_info_present_flag */
748     WRITE_UINT32 (bs,
749         seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
750     if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
751       WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
752       if (seq_param->aspect_ratio_idc == 0xFF) {
753         WRITE_UINT32 (bs, seq_param->sar_width, 16);
754         WRITE_UINT32 (bs, seq_param->sar_height, 16);
755       }
756     }
757     /* overscan_info_present_flag */
758     WRITE_UINT32 (bs, 0, 1);
759     /* video_signal_type_present_flag */
760     WRITE_UINT32 (bs, 0, 1);
761     /* chroma_loc_info_present_flag */
762     WRITE_UINT32 (bs, 0, 1);
763     /* neutral_chroma_indication_flag */
764     WRITE_UINT32 (bs, seq_param->vui_fields.bits.neutral_chroma_indication_flag,
765         1);
766     /* field_seq_flag */
767     WRITE_UINT32 (bs, seq_param->vui_fields.bits.field_seq_flag, 1);
768     /* frame_field_info_present_flag */
769     WRITE_UINT32 (bs, 0, 1);
770     /* default_display_window_flag */
771     WRITE_UINT32 (bs, 0, 1);
772
773     /* timing_info_present_flag */
774     WRITE_UINT32 (bs, seq_param->vui_fields.bits.vui_timing_info_present_flag,
775         1);
776     if (seq_param->vui_fields.bits.vui_timing_info_present_flag) {
777       /* vui_num_units_in_tick */
778       WRITE_UINT32 (bs, seq_param->vui_num_units_in_tick, 32);
779       /* vui_time_scale */
780       WRITE_UINT32 (bs, seq_param->vui_time_scale, 32);
781       /* vui_poc_proportional_to_timing_flag */
782       WRITE_UINT32 (bs, 0, 1);
783
784       /* vui_hrd_parameters_present_flag */
785       vui_hrd_parameters_present_flag = seq_param->bits_per_second > 0;
786       WRITE_UINT32 (bs, vui_hrd_parameters_present_flag, 1);
787
788       if (vui_hrd_parameters_present_flag) {
789         nal_hrd_parameters_present_flag = 1;
790         /* nal_hrd_parameters_present_flag */
791         WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
792         /* vcl_hrd_parameters_present_flag */
793         WRITE_UINT32 (bs, 0, 1);
794
795         if (nal_hrd_parameters_present_flag) {
796           /* sub_pic_hrd_params_present_flag */
797           WRITE_UINT32 (bs, 0, 1);
798           /* bit_rate_scale */
799           WRITE_UINT32 (bs, SX_BITRATE - 6, 4);
800           /* cpb_size_scale */
801           WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4);
802           /* initial_cpb_removal_delay_length_minus1 */
803           WRITE_UINT32 (bs, 23, 5);
804           /* au_cpb_removal_delay_length_minus1 */
805           WRITE_UINT32 (bs, 23, 5);
806           /* dpb_output_delay_length_minus1 */
807           WRITE_UINT32 (bs, 23, 5);
808
809           for (i = 0; i < maxNumSubLayers; i++) {
810             /* fixed_pic_rate_general_flag */
811             WRITE_UINT32 (bs, 0, 1);
812             /* fixed_pic_rate_within_cvs_flag */
813             WRITE_UINT32 (bs, 0, 1);
814             /* low_delay_hrd_flag */
815             WRITE_UINT32 (bs, 1, 1);
816             /* bit_rate_value_minus1 */
817             WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
818             /* cpb_size_value_minus1 */
819             WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
820             /* cbr_flag */
821             WRITE_UINT32 (bs, cbr_flag, 1);
822           }
823         }
824       }
825     }
826     /* bitstream_restriction_flag */
827     WRITE_UINT32 (bs, seq_param->vui_fields.bits.bitstream_restriction_flag, 1);
828   }
829
830   if (h265_is_scc (encoder)) {
831     /* sps_extension_flag */
832     WRITE_UINT32 (bs, 1, 1);
833     /* sps_range_extension_flag */
834     WRITE_UINT32 (bs, 0, 1);
835     /* sps_multilayer_extension_flag */
836     WRITE_UINT32 (bs, 0, 1);
837     /* sps_3d_extension_flag */
838     WRITE_UINT32 (bs, 0, 1);
839     /* sps_scc_extension_flag */
840     WRITE_UINT32 (bs, 1, 1);
841     /* sps_extension_4bits */
842     WRITE_UINT32 (bs, 0, 4);
843
844     /* sps_scc_extension() */
845     /* sps_curr_pic_ref_enabled_flag */
846     WRITE_UINT32 (bs, 1, 1);
847     /* palette_mode_enabled_flag */
848     WRITE_UINT32 (bs, 1, 1);
849     /* palette_max_size */
850     WRITE_UE (bs, 64);
851     /* delta_palette_max_predictor_size */
852     WRITE_UE (bs, 32);
853     /* sps_palette_predictor_initializers_present_flag */
854     WRITE_UINT32 (bs, 0, 1);
855     /* motion_vector_resolution_control_idc */
856     WRITE_UINT32 (bs, 0, 2);
857     /* intra_boundary_filtering_disabled_flag */
858     WRITE_UINT32 (bs, 0, 1);
859   } else {
860     /* sps_extension_flag */
861     WRITE_UINT32 (bs, sps_extension_flag, 1);
862   }
863
864   return TRUE;
865
866   /* ERRORS */
867 bs_error:
868   {
869     GST_WARNING ("failed to write SPS NAL unit");
870     return FALSE;
871   }
872 }
873
874 static gboolean
875 bs_write_sps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
876     GstVaapiEncPicture * picture,
877     const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile,
878     GstVaapiRateControl rate_control, const VAEncMiscParameterHRD * hrd_params)
879 {
880   if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile,
881           rate_control, hrd_params))
882     return FALSE;
883
884   /* rbsp_trailing_bits */
885   bs_write_trailing_bits (bs);
886
887   return FALSE;
888 }
889
890 /* Write a PPS NAL unit */
891 static gboolean
892 bs_write_pps (GstBitWriter * bs, gboolean is_scc,
893     const VAEncPictureParameterBufferHEVC * pic_param)
894 {
895   guint32 pic_parameter_set_id = 0;
896   guint32 seq_parameter_set_id = 0;
897   guint32 output_flag_present_flag = 0;
898   guint32 num_extra_slice_header_bits = 0;
899   guint32 cabac_init_present_flag = 0;
900   guint32 pps_slice_chroma_qp_offsets_present_flag = 0;
901   guint32 deblocking_filter_control_present_flag = 0;
902   guint32 lists_modification_present_flag = 0;
903   guint32 slice_segment_header_extension_present_flag = 0;
904   guint32 pps_extension_flag = 0;
905
906   /* pic_parameter_set_id */
907   WRITE_UE (bs, pic_parameter_set_id);
908   /* seq_parameter_set_id */
909   WRITE_UE (bs, seq_parameter_set_id);
910   /* dependent_slice_segments_enabled_flag */
911   WRITE_UINT32 (bs,
912       pic_param->pic_fields.bits.dependent_slice_segments_enabled_flag, 1);
913   /* output_flag_present_flag */
914   WRITE_UINT32 (bs, output_flag_present_flag, 1);
915   /* num_extra_slice_header_bits */
916   WRITE_UINT32 (bs, num_extra_slice_header_bits, 3);
917   /* sign_data_hiding_enabled_flag */
918   WRITE_UINT32 (bs, pic_param->pic_fields.bits.sign_data_hiding_enabled_flag,
919       1);
920   /* cabac_init_present_flag */
921   WRITE_UINT32 (bs, cabac_init_present_flag, 1);
922   /* num_ref_idx_l0_default_active_minus1 */
923   WRITE_UE (bs, pic_param->num_ref_idx_l0_default_active_minus1);
924   /* num_ref_idx_l1_default_active_minus1 */
925   WRITE_UE (bs, pic_param->num_ref_idx_l1_default_active_minus1);
926   /* pic_init_qp_minus26 */
927   WRITE_SE (bs, pic_param->pic_init_qp - 26);
928   /* constrained_intra_pred_flag */
929   WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
930   /* transform_skip_enabled_flag */
931   WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_skip_enabled_flag, 1);
932   /* cu_qp_delta_enabled_flag */
933   WRITE_UINT32 (bs, pic_param->pic_fields.bits.cu_qp_delta_enabled_flag, 1);
934   /* diff_cu_qp_delta_depth */
935   if (pic_param->pic_fields.bits.cu_qp_delta_enabled_flag)
936     WRITE_UE (bs, pic_param->diff_cu_qp_delta_depth);
937
938   /* pps_cb_qp_offset */
939   WRITE_SE (bs, pic_param->pps_cb_qp_offset);
940   /* pps_cr_qp_offset */
941   WRITE_SE (bs, pic_param->pps_cr_qp_offset);
942   /* pps_slice_chroma_qp_offsets_present_flag */
943   WRITE_UINT32 (bs, pps_slice_chroma_qp_offsets_present_flag, 1);
944   /* weighted_pred_flag */
945   WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
946   /* weighted_bipred_flag */
947   WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_flag, 1);
948   /* transquant_bypass_enabled_flag */
949   WRITE_UINT32 (bs, pic_param->pic_fields.bits.transquant_bypass_enabled_flag,
950       1);
951   /* tiles_enabled_flag */
952   WRITE_UINT32 (bs, pic_param->pic_fields.bits.tiles_enabled_flag, 1);
953   /* entropy_coding_sync_enabled_flag */
954   WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag,
955       1);
956
957   /* tiles info */
958   if (pic_param->pic_fields.bits.tiles_enabled_flag) {
959     WRITE_UE (bs, pic_param->num_tile_columns_minus1);
960     WRITE_UE (bs, pic_param->num_tile_rows_minus1);
961     /* uniform_spacing_flag is 1 now */
962     WRITE_UINT32 (bs, 1, 1);
963     /* if (!uniform_spacing_flag) {
964        for (i = 0; i < num_tile_columns_minus1; i++)
965        column_width_minus1[i]
966        ue (v)
967        for (i = 0; i < num_tile_rows_minus1; i++)
968        row_height_minus1[i]
969        ue (v)
970        } */
971     WRITE_UINT32 (bs,
972         pic_param->pic_fields.bits.loop_filter_across_tiles_enabled_flag, 1);
973   }
974
975   /* pps_loop_filter_across_slices_enabled_flag */
976   WRITE_UINT32 (bs,
977       pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag, 1);
978   /* deblocking_filter_control_present_flag */
979   WRITE_UINT32 (bs, deblocking_filter_control_present_flag, 1);
980   /* pps_scaling_list_data_present_flag */
981   WRITE_UINT32 (bs, pic_param->pic_fields.bits.scaling_list_data_present_flag,
982       1);
983   /* lists_modification_present_flag */
984   WRITE_UINT32 (bs, lists_modification_present_flag, 1);
985   /* log2_parallel_merge_level_minus2 */
986   WRITE_UE (bs, pic_param->log2_parallel_merge_level_minus2);
987   /* slice_segment_header_extension_present_flag */
988   WRITE_UINT32 (bs, slice_segment_header_extension_present_flag, 1);
989
990   if (is_scc) {
991 #if VA_CHECK_VERSION(1,8,0)
992     /* pps_extension_flag */
993     WRITE_UINT32 (bs, 1, 1);
994     /* pps_range_extension_flag */
995     WRITE_UINT32 (bs, 0, 1);
996     /* pps_multilayer_extension_flag */
997     WRITE_UINT32 (bs, 0, 1);
998     /* pps_3d_extension_flag */
999     WRITE_UINT32 (bs, 0, 1);
1000     /* pps_scc_extension_flag */
1001     WRITE_UINT32 (bs, 1, 1);
1002     /* pps_extension_4bits */
1003     WRITE_UINT32 (bs, 0, 4);
1004
1005     /* pps_scc_extension() */
1006     /* pps_curr_pic_ref_enabled_flag */
1007     WRITE_UINT32 (bs,
1008         pic_param->scc_fields.bits.pps_curr_pic_ref_enabled_flag, 1);
1009     /* residual_adaptive_colour_transform_enabled_flag */
1010     WRITE_UINT32 (bs, 0, 1);
1011     /* pps_palette_predictor_initializers_present_flag */
1012     WRITE_UINT32 (bs, 0, 1);
1013 #else
1014     /* SCC profile should not be selected. */
1015     g_assert_not_reached ();
1016     return FALSE;
1017 #endif
1018   } else {
1019     /* pps_extension_flag */
1020     WRITE_UINT32 (bs, pps_extension_flag, 1);
1021   }
1022
1023   /* rbsp_trailing_bits */
1024   bs_write_trailing_bits (bs);
1025
1026   return TRUE;
1027
1028   /* ERRORS */
1029 bs_error:
1030   {
1031     GST_WARNING ("failed to write PPS NAL unit");
1032     return FALSE;
1033   }
1034 }
1035
1036 /* Write a Slice NAL unit */
1037 static gboolean
1038 bs_write_slice (GstBitWriter * bs,
1039     const VAEncSliceParameterBufferHEVC * slice_param,
1040     GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
1041     guint8 nal_unit_type)
1042 {
1043   const VAEncPictureParameterBufferHEVC *const pic_param = picture->param;
1044
1045   guint8 no_output_of_prior_pics_flag = 0;
1046   guint8 dependent_slice_segment_flag = 0;
1047   guint8 short_term_ref_pic_set_sps_flag = 0;
1048   guint8 slice_deblocking_filter_disabled_flag = 0;
1049   guint8 num_ref_idx_active_override_flag =
1050       slice_param->slice_fields.bits.num_ref_idx_active_override_flag;
1051
1052   if (h265_is_scc (encoder)) {
1053     /* If scc, need to add the current picture itself. */
1054     num_ref_idx_active_override_flag = 1;
1055   }
1056
1057   /* first_slice_segment_in_pic_flag */
1058   WRITE_UINT32 (bs, encoder->first_slice_segment_in_pic_flag, 1);
1059
1060   /* FIXME: For all IRAP pics */
1061   /* no_output_of_prior_pics_flag */
1062   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
1063     WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1);
1064
1065   /* slice_pic_parameter_set_id */
1066   WRITE_UE (bs, slice_param->slice_pic_parameter_set_id);
1067
1068   /* slice_segment_address , bits_size = Ceil(Log2(PicSizeInCtbsY)) */
1069   if (!encoder->first_slice_segment_in_pic_flag) {
1070     guint pic_size_ctb = encoder->ctu_width * encoder->ctu_height;
1071     guint bits_size = (guint) ceil ((log2 (pic_size_ctb)));
1072     WRITE_UINT32 (bs, slice_param->slice_segment_address, bits_size);
1073   }
1074
1075   if (!dependent_slice_segment_flag) {
1076     /* slice_type */
1077     WRITE_UE (bs, slice_param->slice_type);
1078
1079     if (!pic_param->pic_fields.bits.idr_pic_flag) {
1080       /* slice_pic_order_cnt_lsb */
1081       WRITE_UINT32 (bs, picture->poc, encoder->log2_max_pic_order_cnt);
1082       /* short_term_ref_pic_set_sps_flag */
1083       WRITE_UINT32 (bs, short_term_ref_pic_set_sps_flag, 1);
1084
1085     /*---------- Write short_term_ref_pic_set(0) ----------- */
1086       {
1087         guint num_positive_pics = 0, num_negative_pics = 0;
1088         guint delta_poc_s0_minus1 = 0, delta_poc_s1_minus1 = 0;
1089         guint used_by_curr_pic_s0_flag = 0, used_by_curr_pic_s1_flag = 0;
1090         guint reflist_0_count = 0, reflist_1_count = 0;
1091         gint i;
1092
1093         /* Get count of ref_pic_list */
1094         if (picture->type == GST_VAAPI_PICTURE_TYPE_P
1095             || picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1096           for (i = 0; i < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i) {
1097             if (slice_param->ref_pic_list0[i].picture_id == VA_INVALID_SURFACE)
1098               break;
1099           }
1100           reflist_0_count = i;
1101
1102           if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1103             for (i = 0; i < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i) {
1104               if (slice_param->ref_pic_list1[i].picture_id ==
1105                   VA_INVALID_SURFACE)
1106                 break;
1107             }
1108             reflist_1_count = i;
1109           }
1110         }
1111
1112         if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
1113           delta_poc_s0_minus1 =
1114               picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1;
1115           used_by_curr_pic_s0_flag = 1;
1116           delta_poc_s1_minus1 = 0;
1117           used_by_curr_pic_s1_flag = 0;
1118         }
1119         if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1120           delta_poc_s0_minus1 =
1121               picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1;
1122           used_by_curr_pic_s0_flag = 1;
1123           delta_poc_s1_minus1 =
1124               slice_param->ref_pic_list1[0].pic_order_cnt - picture->poc - 1;
1125           used_by_curr_pic_s1_flag = 1;
1126         }
1127
1128         num_negative_pics = reflist_0_count;
1129         num_positive_pics = reflist_1_count;
1130
1131         /* num_negative_pics */
1132         WRITE_UE (bs, num_negative_pics);
1133         /* num_positive_pics */
1134         WRITE_UE (bs, num_positive_pics);
1135
1136         for (i = 0; i < num_negative_pics; i++) {
1137           /* delta_poc_s0_minus1 */
1138           if (i == 0) {
1139             WRITE_UE (bs, delta_poc_s0_minus1);
1140           } else {
1141             WRITE_UE (bs,
1142                 slice_param->ref_pic_list0[i - 1].pic_order_cnt -
1143                 slice_param->ref_pic_list0[i].pic_order_cnt - 1);
1144           }
1145           /* used_by_curr_pic_s0_flag */
1146           WRITE_UINT32 (bs, used_by_curr_pic_s0_flag, 1);
1147         }
1148         for (i = 0; i < num_positive_pics; i++) {
1149           /* delta_poc_s1_minus1 */
1150           if (i == 0) {
1151             WRITE_UE (bs, delta_poc_s1_minus1);
1152           } else {
1153             WRITE_UE (bs,
1154                 slice_param->ref_pic_list1[i - 1].pic_order_cnt -
1155                 slice_param->ref_pic_list1[i].pic_order_cnt - 1);
1156           }
1157           /* used_by_curr_pic_s1_flag */
1158           WRITE_UINT32 (bs, used_by_curr_pic_s1_flag, 1);
1159         }
1160       }
1161
1162       /* slice_temporal_mvp_enabled_flag */
1163       if (encoder->sps_temporal_mvp_enabled_flag)
1164         WRITE_UINT32 (bs,
1165             slice_param->slice_fields.bits.slice_temporal_mvp_enabled_flag, 1);
1166     }
1167
1168     if (encoder->sample_adaptive_offset_enabled_flag) {
1169       WRITE_UINT32 (bs, slice_param->slice_fields.bits.slice_sao_luma_flag, 1);
1170       WRITE_UINT32 (bs, slice_param->slice_fields.bits.slice_sao_chroma_flag,
1171           1);
1172     }
1173
1174     if (slice_param->slice_type == GST_H265_P_SLICE ||
1175         slice_param->slice_type == GST_H265_B_SLICE) {
1176       /* num_ref_idx_active_override_flag */
1177       WRITE_UINT32 (bs, num_ref_idx_active_override_flag, 1);
1178       if (num_ref_idx_active_override_flag) {
1179         if (h265_is_scc (encoder)) {
1180           if (picture->type == GST_VAAPI_PICTURE_TYPE_I) {
1181             g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1182             /* Let num_ref_idx_l0_active_minus1 = 0 and
1183                NumRpsCurrTempList0 = 1 to include current picture itself */
1184             WRITE_UE (bs, 0);
1185           } else {
1186             /* For scc, need to add 1 for current picture itself when
1187                calculating NumRpsCurrTempList0. */
1188             WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1 + 1);
1189           }
1190         } else {
1191           WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1);
1192         }
1193         if (slice_param->slice_type == GST_H265_B_SLICE)
1194           WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1);
1195       }
1196
1197       /* mvd_l1_zero_flag */
1198       if (slice_param->slice_type == GST_H265_B_SLICE)
1199         WRITE_UINT32 (bs, slice_param->slice_fields.bits.mvd_l1_zero_flag, 1);
1200
1201       /* cabac_init_present_flag == FALSE */
1202       /* cabac_init_flag  = FALSE */
1203
1204       /* collocated_from_l0_flag */
1205       if (slice_param->slice_fields.bits.slice_temporal_mvp_enabled_flag) {
1206         if (slice_param->slice_type == GST_H265_B_SLICE)
1207           WRITE_UINT32 (bs,
1208               slice_param->slice_fields.bits.collocated_from_l0_flag, 1);
1209       }
1210       /* five_minus_max_num_merge_cand */
1211       WRITE_UE (bs, 5 - slice_param->max_num_merge_cand);
1212     }
1213
1214     /* slice_qp_delta */
1215     WRITE_SE (bs, slice_param->slice_qp_delta);
1216     if (pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag &&
1217         (slice_param->slice_fields.bits.slice_sao_luma_flag
1218             || slice_param->slice_fields.bits.slice_sao_chroma_flag
1219             || !slice_deblocking_filter_disabled_flag))
1220       WRITE_UINT32 (bs,
1221           slice_param->slice_fields.bits.
1222           slice_loop_filter_across_slices_enabled_flag, 1);
1223   }
1224
1225   if (pic_param->pic_fields.bits.tiles_enabled_flag
1226       || pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag) {
1227     /* output a num_entry_point_offsets, which should be 0 here */
1228     WRITE_UE (bs, 0);
1229   }
1230
1231   /* byte_alignment() */
1232   {
1233     /* alignment_bit_equal_to_one */
1234     WRITE_UINT32 (bs, 1, 1);
1235     while (GST_BIT_WRITER_BIT_SIZE (bs) % 8 != 0) {
1236       /* alignment_bit_equal_to_zero */
1237       WRITE_UINT32 (bs, 0, 1);
1238     }
1239   }
1240
1241   return TRUE;
1242
1243   /* ERRORS */
1244 bs_error:
1245   {
1246     GST_WARNING ("failed to write Slice NAL unit");
1247     return FALSE;
1248   }
1249 }
1250
1251 static inline void
1252 _check_vps_sps_pps_status (GstVaapiEncoderH265 * encoder,
1253     const guint8 * nal, guint32 size)
1254 {
1255   guint8 nal_type;
1256   G_GNUC_UNUSED gsize ret;      /* FIXME */
1257   g_assert (size);
1258
1259   if (encoder->vps_data && encoder->sps_data && encoder->pps_data)
1260     return;
1261
1262   nal_type = (nal[0] & 0x7E) >> 1;
1263   switch (nal_type) {
1264     case GST_H265_NAL_VPS:
1265       encoder->vps_data = gst_buffer_new_allocate (NULL, size, NULL);
1266       ret = gst_buffer_fill (encoder->vps_data, 0, nal, size);
1267       g_assert (ret == size);
1268       break;
1269     case GST_H265_NAL_SPS:
1270       encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
1271       ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
1272       g_assert (ret == size);
1273       break;
1274     case GST_H265_NAL_PPS:
1275       encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
1276       ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
1277       g_assert (ret == size);
1278       break;
1279     default:
1280       break;
1281   }
1282 }
1283
1284 static gboolean
1285 is_profile_allowed (GstVaapiEncoderH265 * encoder, GstVaapiProfile profile)
1286 {
1287   guint i;
1288
1289   if (encoder->allowed_profiles == NULL)
1290     return TRUE;
1291
1292   for (i = 0; i < encoder->allowed_profiles->len; i++)
1293     if (profile ==
1294         g_array_index (encoder->allowed_profiles, GstVaapiProfile, i))
1295       return TRUE;
1296
1297   return FALSE;
1298 }
1299
1300 /* Derives the profile from the active coding tools. */
1301 static gboolean
1302 ensure_profile (GstVaapiEncoderH265 * encoder)
1303 {
1304   GstVaapiProfile profile;
1305   const GstVideoFormat format =
1306       GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder));
1307   guint depth, chrome;
1308   GstVaapiProfile profile_candidates[6];
1309   guint num, i;
1310
1311   g_assert (GST_VIDEO_FORMAT_INFO_IS_YUV (gst_video_format_get_info (format)));
1312   depth = GST_VIDEO_FORMAT_INFO_DEPTH (gst_video_format_get_info (format), 0);
1313   chrome = gst_vaapi_utils_h265_get_chroma_format_idc
1314       (gst_vaapi_video_format_get_chroma_type (format));
1315
1316   num = 0;
1317
1318   if (chrome == 3) {
1319     /* 4:4:4 */
1320     if (depth == 8)
1321       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_444;
1322     if (depth <= 10)
1323       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_444_10;
1324 #if VA_CHECK_VERSION(1,8,0)
1325     /* Consider SCREEN_EXTENDED_MAIN_444 and SCREEN_EXTENDED_MAIN_444_10 */
1326     if (depth == 8)
1327       profile_candidates[num++] =
1328           GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444;
1329     if (depth <= 10)
1330       profile_candidates[num++] =
1331           GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10;
1332 #endif
1333   } else if (chrome == 2) {
1334     /* 4:2:2 */
1335     profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_422_10;
1336   } else if (chrome == 1 || chrome == 0) {
1337     /* 4:2:0 or 4:0:0 */
1338     if (depth == 8)
1339       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN;
1340     if (depth <= 10)
1341       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN10;
1342     if (depth <= 12)
1343       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN12;
1344     /* Always add STILL_PICTURE as a candidate for Main and Main10. */
1345     if (depth <= 10)
1346       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE;
1347 #if VA_CHECK_VERSION(1,8,0)
1348     /* Consider SCREEN_EXTENDED_MAIN and SCREEN_EXTENDED_MAIN_10 */
1349     if (depth == 8)
1350       profile_candidates[num++] = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN;
1351     if (depth <= 10)
1352       profile_candidates[num++] =
1353           GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10;
1354 #endif
1355   }
1356
1357   if (num == 0) {
1358     GST_ERROR ("Fail to find a profile for format %s.",
1359         gst_video_format_to_string (format));
1360     return FALSE;
1361   }
1362
1363   profile = GST_VAAPI_PROFILE_UNKNOWN;
1364   for (i = 0; i < num; i++) {
1365     if (!is_profile_allowed (encoder, profile_candidates[i]))
1366       continue;
1367     /* If we can get valid entrypoint, hw must support this profile. */
1368     if (gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder),
1369             profile_candidates[i]) == GST_VAAPI_ENTRYPOINT_INVALID)
1370       continue;
1371
1372     profile = profile_candidates[i];
1373     break;
1374   }
1375
1376   if (profile == GST_VAAPI_PROFILE_UNKNOWN) {
1377     GST_ERROR ("Fail to find a supported profile %sfor format %s.",
1378         GST_VAAPI_ENCODER_TUNE (encoder) == GST_VAAPI_ENCODER_TUNE_LOW_POWER ?
1379         "in low power mode " : "", gst_video_format_to_string (format));
1380     return FALSE;
1381   }
1382
1383   encoder->profile = profile;
1384   encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile);
1385   return TRUE;
1386 }
1387
1388 /* Derives the level and tier from the currently set limits */
1389 static gboolean
1390 ensure_tier_level (GstVaapiEncoderH265 * encoder)
1391 {
1392   guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
1393   guint i, num_limits, PicSizeInSamplesY;
1394   guint LumaSr;
1395   const GstVaapiH265LevelLimits *limits_table;
1396   const GstVaapiH265LevelLimits *limits;
1397
1398   PicSizeInSamplesY = encoder->luma_width * encoder->luma_height;
1399   LumaSr =
1400       gst_util_uint64_scale (PicSizeInSamplesY,
1401       GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
1402
1403   limits_table = gst_vaapi_utils_h265_get_level_limits_table (&num_limits);
1404   for (i = 0; i < num_limits; i++) {
1405     limits = &limits_table[i];
1406     /* Choose level by luma picture size and luma sample rate */
1407     if (PicSizeInSamplesY <= limits->MaxLumaPs && LumaSr <= limits->MaxLumaSr)
1408       break;
1409   }
1410
1411   if (i == num_limits)
1412     goto error_unsupported_level;
1413
1414   /* may need to promote the level by tile setting */
1415   if (h265_is_tile_enabled (encoder)) {
1416     for (; i < num_limits; i++) {
1417       limits = &limits_table[i];
1418       if (encoder->num_tile_cols <= limits->MaxTileColumns &&
1419           encoder->num_tile_rows <= limits->MaxTileRows)
1420         break;
1421     }
1422
1423     if (i == num_limits)
1424       goto error_promote_level;
1425   }
1426
1427   if (bitrate <= limits_table[i].MaxBRTierMain) {
1428     encoder->tier = GST_VAAPI_TIER_H265_MAIN;
1429   } else {
1430     encoder->tier = GST_VAAPI_TIER_H265_HIGH;
1431     if (bitrate > limits_table[i].MaxBRTierHigh) {
1432       GST_INFO ("The bitrate of the stream is %d kbps, larger than"
1433           " %s profile %s level %s tier's max bit rate %d kbps",
1434           bitrate,
1435           gst_vaapi_utils_h265_get_profile_string (encoder->profile),
1436           gst_vaapi_utils_h265_get_level_string (limits_table[i].level),
1437           gst_vaapi_utils_h265_get_tier_string (GST_VAAPI_TIER_H265_HIGH),
1438           limits_table[i].MaxBRTierHigh);
1439     }
1440   }
1441
1442   encoder->level = limits_table[i].level;
1443   encoder->level_idc = limits_table[i].level_idc;
1444   return TRUE;
1445
1446   /* ERRORS */
1447 error_promote_level:
1448   {
1449     GST_ERROR ("failed to promote level for num-tile-cols is %d,"
1450         " num-tile-rows %d", encoder->num_tile_cols, encoder->num_tile_rows);
1451     return FALSE;
1452   }
1453 error_unsupported_level:
1454   {
1455     GST_ERROR ("failed to find a suitable level matching codec config");
1456     return FALSE;
1457   }
1458 }
1459
1460 /* Handle new GOP starts */
1461 static void
1462 reset_gop_start (GstVaapiEncoderH265 * encoder)
1463 {
1464   GstVaapiH265ReorderPool *const reorder_pool = &encoder->reorder_pool;
1465
1466   reorder_pool->frame_index = 1;
1467   reorder_pool->cur_present_index = 0;
1468   ++encoder->idr_num;
1469 }
1470
1471 /* Marks the supplied picture as a B-frame */
1472 static void
1473 set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1474 {
1475   g_assert (pic && encoder);
1476   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1477   pic->type = GST_VAAPI_PICTURE_TYPE_B;
1478 }
1479
1480 /* Marks the supplied picture as a P-frame */
1481 static void
1482 set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1483 {
1484   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1485   pic->type = GST_VAAPI_PICTURE_TYPE_P;
1486 }
1487
1488 /* Marks the supplied picture as an I-frame */
1489 static void
1490 set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1491 {
1492   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1493   pic->type = GST_VAAPI_PICTURE_TYPE_I;
1494
1495   g_assert (pic->frame);
1496   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1497 }
1498
1499 /* Marks the supplied picture as an IDR frame */
1500 static void
1501 set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1502 {
1503   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1504   pic->type = GST_VAAPI_PICTURE_TYPE_I;
1505   pic->poc = 0;
1506   GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
1507
1508   g_assert (pic->frame);
1509   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1510 }
1511
1512 /* Marks the supplied picture a a key-frame */
1513 static void
1514 set_key_frame (GstVaapiEncPicture * picture,
1515     GstVaapiEncoderH265 * encoder, gboolean is_idr)
1516 {
1517   if (is_idr) {
1518     reset_gop_start (encoder);
1519     set_idr_frame (picture, encoder);
1520   } else
1521     set_i_frame (picture, encoder);
1522 }
1523
1524 /* Fills in VA HRD parameters */
1525 static void
1526 fill_hrd_params (GstVaapiEncoderH265 * encoder, VAEncMiscParameterHRD * hrd)
1527 {
1528   if (encoder->bitrate_bits > 0) {
1529     hrd->buffer_size = encoder->cpb_length_bits;
1530     hrd->initial_buffer_fullness = hrd->buffer_size / 2;
1531   } else {
1532     hrd->buffer_size = 0;
1533     hrd->initial_buffer_fullness = 0;
1534   }
1535 }
1536
1537 /* Adds the supplied video parameter set header (VPS) to the list of packed
1538    headers to pass down as-is to the encoder */
1539 static gboolean
1540 add_packed_vps_header (GstVaapiEncoderH265 * encoder,
1541     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1542 {
1543   GstVaapiEncPackedHeader *packed_vps;
1544   GstBitWriter bs;
1545   VAEncPackedHeaderParameterBuffer packed_vps_param = { 0 };
1546   const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param;
1547   GstVaapiProfile profile = encoder->profile;
1548
1549   guint32 data_bit_size;
1550   guint8 *data;
1551
1552   gst_bit_writer_init_with_size (&bs, 128, FALSE);
1553   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1554   bs_write_nal_header (&bs, GST_H265_NAL_VPS);
1555
1556   bs_write_vps (&bs, encoder, picture, seq_param, profile);
1557
1558   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1559   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1560   data = GST_BIT_WRITER_DATA (&bs);
1561
1562   packed_vps_param.type = VAEncPackedHeaderSequence;
1563   packed_vps_param.bit_length = data_bit_size;
1564   packed_vps_param.has_emulation_bytes = 0;
1565
1566   packed_vps = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1567       &packed_vps_param, sizeof (packed_vps_param),
1568       data, (data_bit_size + 7) / 8);
1569   g_assert (packed_vps);
1570
1571   gst_vaapi_enc_picture_add_packed_header (picture, packed_vps);
1572   gst_vaapi_codec_object_replace (&packed_vps, NULL);
1573
1574   /* store vps data */
1575   _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1576   gst_bit_writer_reset (&bs);
1577   return TRUE;
1578
1579   /* ERRORS */
1580 bs_error:
1581   {
1582     GST_WARNING ("failed to write VPS NAL unit");
1583     gst_bit_writer_reset (&bs);
1584     return FALSE;
1585   }
1586 }
1587
1588 /* Adds the supplied sequence header (SPS) to the list of packed
1589    headers to pass down as-is to the encoder */
1590 static gboolean
1591 add_packed_sequence_header (GstVaapiEncoderH265 * encoder,
1592     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1593 {
1594   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1595   GstVaapiEncPackedHeader *packed_seq;
1596   GstBitWriter bs;
1597   VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
1598   const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param;
1599   GstVaapiProfile profile = encoder->profile;
1600
1601   VAEncMiscParameterHRD hrd_params;
1602   guint32 data_bit_size;
1603   guint8 *data;
1604
1605   fill_hrd_params (encoder, &hrd_params);
1606
1607   gst_bit_writer_init_with_size (&bs, 128, FALSE);
1608   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1609   bs_write_nal_header (&bs, GST_H265_NAL_SPS);
1610
1611   bs_write_sps (&bs, encoder, picture, seq_param, profile,
1612       base_encoder->rate_control, &hrd_params);
1613
1614   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1615   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1616   data = GST_BIT_WRITER_DATA (&bs);
1617
1618   packed_seq_param.type = VAEncPackedHeaderSequence;
1619   packed_seq_param.bit_length = data_bit_size;
1620   packed_seq_param.has_emulation_bytes = 0;
1621
1622   packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1623       &packed_seq_param, sizeof (packed_seq_param),
1624       data, (data_bit_size + 7) / 8);
1625   g_assert (packed_seq);
1626
1627   gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
1628   gst_vaapi_codec_object_replace (&packed_seq, NULL);
1629
1630   /* store sps data */
1631   _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1632   gst_bit_writer_reset (&bs);
1633   return TRUE;
1634
1635   /* ERRORS */
1636 bs_error:
1637   {
1638     GST_WARNING ("failed to write SPS NAL unit");
1639     gst_bit_writer_reset (&bs);
1640     return FALSE;
1641   }
1642 }
1643
1644 /* Adds the supplied picture header (PPS) to the list of packed
1645    headers to pass down as-is to the encoder */
1646 static gboolean
1647 add_packed_picture_header (GstVaapiEncoderH265 * encoder,
1648     GstVaapiEncPicture * picture)
1649 {
1650   GstVaapiEncPackedHeader *packed_pic;
1651   GstBitWriter bs;
1652   VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
1653   const VAEncPictureParameterBufferHEVC *const pic_param = picture->param;
1654   guint32 data_bit_size;
1655   guint8 *data;
1656
1657   gst_bit_writer_init_with_size (&bs, 128, FALSE);
1658   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1659   bs_write_nal_header (&bs, GST_H265_NAL_PPS);
1660   bs_write_pps (&bs, h265_is_scc (encoder), pic_param);
1661   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1662   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1663   data = GST_BIT_WRITER_DATA (&bs);
1664
1665   packed_pic_param.type = VAEncPackedHeaderPicture;
1666   packed_pic_param.bit_length = data_bit_size;
1667   packed_pic_param.has_emulation_bytes = 0;
1668
1669   packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1670       &packed_pic_param, sizeof (packed_pic_param),
1671       data, (data_bit_size + 7) / 8);
1672   g_assert (packed_pic);
1673
1674   gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
1675   gst_vaapi_codec_object_replace (&packed_pic, NULL);
1676
1677   /* store pps data */
1678   _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1679   gst_bit_writer_reset (&bs);
1680   return TRUE;
1681
1682   /* ERRORS */
1683 bs_error:
1684   {
1685     GST_WARNING ("failed to write PPS NAL unit");
1686     gst_bit_writer_reset (&bs);
1687     return FALSE;
1688   }
1689 }
1690
1691 static gboolean
1692 get_nal_unit_type (GstVaapiEncPicture * picture, guint8 * nal_unit_type)
1693 {
1694   switch (picture->type) {
1695     case GST_VAAPI_PICTURE_TYPE_I:
1696       if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
1697         *nal_unit_type = GST_H265_NAL_SLICE_IDR_W_RADL;
1698       else
1699         *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_R;
1700       break;
1701     case GST_VAAPI_PICTURE_TYPE_P:
1702       *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_R;
1703       break;
1704     case GST_VAAPI_PICTURE_TYPE_B:
1705       *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_N;
1706       break;
1707     default:
1708       return FALSE;
1709   }
1710   return TRUE;
1711 }
1712
1713 /* Adds the supplied slice header to the list of packed
1714    headers to pass down as-is to the encoder */
1715 static gboolean
1716 add_packed_slice_header (GstVaapiEncoderH265 * encoder,
1717     GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
1718 {
1719   GstVaapiEncPackedHeader *packed_slice;
1720   GstBitWriter bs;
1721   VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 };
1722   const VAEncSliceParameterBufferHEVC *const slice_param = slice->param;
1723   guint32 data_bit_size;
1724   guint8 *data;
1725   guint8 nal_unit_type;
1726
1727   gst_bit_writer_init_with_size (&bs, 128, FALSE);
1728   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1729
1730   if (!get_nal_unit_type (picture, &nal_unit_type))
1731     goto bs_error;
1732   bs_write_nal_header (&bs, nal_unit_type);
1733
1734   bs_write_slice (&bs, slice_param, encoder, picture, nal_unit_type);
1735   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1736   data = GST_BIT_WRITER_DATA (&bs);
1737
1738   packed_slice_param.type = VAEncPackedHeaderSlice;
1739   packed_slice_param.bit_length = data_bit_size;
1740   packed_slice_param.has_emulation_bytes = 0;
1741
1742   packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1743       &packed_slice_param, sizeof (packed_slice_param),
1744       data, (data_bit_size + 7) / 8);
1745   g_assert (packed_slice);
1746
1747   gst_vaapi_enc_slice_add_packed_header (slice, packed_slice);
1748   gst_vaapi_codec_object_replace (&packed_slice, NULL);
1749
1750   gst_bit_writer_reset (&bs);
1751   return TRUE;
1752
1753   /* ERRORS */
1754 bs_error:
1755   {
1756     GST_WARNING ("failed to write Slice NAL unit header");
1757     gst_bit_writer_reset (&bs);
1758     return FALSE;
1759   }
1760 }
1761
1762 /* Reference picture management */
1763 static void
1764 reference_pic_free (GstVaapiEncoderH265 * encoder, GstVaapiEncoderH265Ref * ref)
1765 {
1766   if (!ref)
1767     return;
1768   if (ref->pic)
1769     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
1770   g_slice_free (GstVaapiEncoderH265Ref, ref);
1771 }
1772
1773 static inline GstVaapiEncoderH265Ref *
1774 reference_pic_create (GstVaapiEncoderH265 * encoder,
1775     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1776 {
1777   GstVaapiEncoderH265Ref *const ref = g_slice_new0 (GstVaapiEncoderH265Ref);
1778
1779   ref->pic = surface;
1780   ref->poc = picture->poc;
1781   return ref;
1782 }
1783
1784 static gboolean
1785 reference_list_update (GstVaapiEncoderH265 * encoder,
1786     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1787 {
1788   GstVaapiEncoderH265Ref *ref;
1789   GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1790
1791   if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
1792     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
1793     return TRUE;
1794   }
1795
1796   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
1797     while (!g_queue_is_empty (&ref_pool->ref_list))
1798       reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1799   } else if (g_queue_get_length (&ref_pool->ref_list) >=
1800       ref_pool->max_ref_frames) {
1801     reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1802   }
1803   ref = reference_pic_create (encoder, picture, surface);
1804   g_queue_push_tail (&ref_pool->ref_list, ref);
1805   g_assert (g_queue_get_length (&ref_pool->ref_list) <=
1806       ref_pool->max_ref_frames);
1807   return TRUE;
1808 }
1809
1810 static gboolean
1811 reference_list_init (GstVaapiEncoderH265 * encoder,
1812     GstVaapiEncPicture * picture,
1813     GstVaapiEncoderH265Ref ** reflist_0,
1814     guint * reflist_0_count,
1815     GstVaapiEncoderH265Ref ** reflist_1, guint * reflist_1_count)
1816 {
1817   GstVaapiEncoderH265Ref *tmp;
1818   GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1819   GList *iter, *list_0_start = NULL, *list_1_start = NULL;
1820   guint count;
1821
1822   *reflist_0_count = 0;
1823   *reflist_1_count = 0;
1824   if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
1825     return TRUE;
1826
1827   iter = g_queue_peek_tail_link (&ref_pool->ref_list);
1828   for (; iter; iter = g_list_previous (iter)) {
1829     tmp = (GstVaapiEncoderH265Ref *) iter->data;
1830     g_assert (tmp && tmp->poc != picture->poc);
1831     if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) {
1832       list_0_start = iter;
1833       list_1_start = g_list_next (iter);
1834       break;
1835     }
1836   }
1837
1838   /* order reflist_0 */
1839   g_assert (list_0_start);
1840   iter = list_0_start;
1841   count = 0;
1842   for (; iter; iter = g_list_previous (iter)) {
1843     reflist_0[count] = (GstVaapiEncoderH265Ref *) iter->data;
1844     ++count;
1845   }
1846   *reflist_0_count = count;
1847
1848   if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1849     return TRUE;
1850
1851   /* order reflist_1 */
1852   count = 0;
1853   iter = list_1_start;
1854   for (; iter; iter = g_list_next (iter)) {
1855     reflist_1[count] = (GstVaapiEncoderH265Ref *) iter->data;
1856     ++count;
1857   }
1858   *reflist_1_count = count;
1859   return TRUE;
1860 }
1861
1862 /* Fills in VA sequence parameter buffer */
1863 static gboolean
1864 fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence)
1865 {
1866   VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param;
1867   const GstVideoFormat format =
1868       GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder));
1869   guint bits_depth_luma_minus8 =
1870       GST_VIDEO_FORMAT_INFO_DEPTH (gst_video_format_get_info (format), 0);
1871   if (bits_depth_luma_minus8 < 8)
1872     return FALSE;
1873   bits_depth_luma_minus8 -= 8;
1874
1875   memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferHEVC));
1876
1877   seq_param->general_profile_idc = encoder->profile_idc;
1878   seq_param->general_level_idc = encoder->level_idc;
1879   seq_param->general_tier_flag = encoder->tier;
1880
1881   seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
1882   seq_param->intra_idr_period = encoder->idr_period;
1883   seq_param->ip_period = seq_param->intra_period > 1 ?
1884       (1 + encoder->num_bframes) : 0;
1885   seq_param->bits_per_second = encoder->bitrate_bits;
1886
1887   seq_param->pic_width_in_luma_samples = encoder->luma_width;
1888   seq_param->pic_height_in_luma_samples = encoder->luma_height;
1889
1890   /*sequence field values */
1891   seq_param->seq_fields.value = 0;
1892   seq_param->seq_fields.bits.chroma_format_idc =
1893       gst_vaapi_utils_h265_get_chroma_format_idc
1894       (gst_vaapi_video_format_get_chroma_type (GST_VIDEO_INFO_FORMAT
1895           (GST_VAAPI_ENCODER_VIDEO_INFO (encoder))));
1896   /* the 4:4:4 chrome format */
1897   if (seq_param->seq_fields.bits.chroma_format_idc == 3)
1898     seq_param->seq_fields.bits.separate_colour_plane_flag = 0;
1899   seq_param->seq_fields.bits.separate_colour_plane_flag = 0;
1900   seq_param->seq_fields.bits.bit_depth_luma_minus8 = bits_depth_luma_minus8;
1901   seq_param->seq_fields.bits.bit_depth_chroma_minus8 = bits_depth_luma_minus8;
1902   seq_param->seq_fields.bits.scaling_list_enabled_flag = FALSE;
1903   seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag = TRUE;
1904   seq_param->seq_fields.bits.amp_enabled_flag = TRUE;
1905   seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag =
1906       encoder->sample_adaptive_offset_enabled_flag = FALSE;
1907   seq_param->seq_fields.bits.pcm_enabled_flag = FALSE;
1908   seq_param->seq_fields.bits.pcm_loop_filter_disabled_flag = FALSE;
1909   seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag =
1910       encoder->sps_temporal_mvp_enabled_flag = TRUE;
1911
1912   /* Based on 32x32 CTU (64x64 when using lowpower mode for hardware limitation) */
1913   seq_param->log2_min_luma_coding_block_size_minus3 = 0;
1914   if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)
1915     seq_param->log2_diff_max_min_luma_coding_block_size = 3;
1916   else
1917     seq_param->log2_diff_max_min_luma_coding_block_size = 2;
1918   seq_param->log2_min_transform_block_size_minus2 = 0;
1919   seq_param->log2_diff_max_min_transform_block_size = 3;
1920   /*
1921    * Intel HW supports up to 2, we can provide a quirk for other HWs in future
1922    * if other HW may support other values
1923    *
1924    * Refer to https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol10-hevc.pdf
1925    */
1926   seq_param->max_transform_hierarchy_depth_inter = 2;
1927   seq_param->max_transform_hierarchy_depth_intra = 2;
1928
1929   seq_param->pcm_sample_bit_depth_luma_minus1 = 0;
1930   seq_param->pcm_sample_bit_depth_chroma_minus1 = 0;
1931   seq_param->log2_min_pcm_luma_coding_block_size_minus3 = 0;
1932   seq_param->log2_max_pcm_luma_coding_block_size_minus3 = 0;
1933
1934   /* VUI parameters are always set, at least for timing_info (framerate) */
1935   seq_param->vui_parameters_present_flag = TRUE;
1936   if (seq_param->vui_parameters_present_flag) {
1937     seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE;
1938     if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
1939       const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1940       seq_param->aspect_ratio_idc = 0xff;
1941       seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip);
1942       seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip);
1943     }
1944     seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1945     seq_param->vui_fields.bits.vui_timing_info_present_flag = TRUE;
1946     if (seq_param->vui_fields.bits.vui_timing_info_present_flag) {
1947       seq_param->vui_num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1948       seq_param->vui_time_scale = GST_VAAPI_ENCODER_FPS_N (encoder);
1949     }
1950   }
1951
1952   if (h265_is_scc (encoder)) {
1953 #if VA_CHECK_VERSION(1,8,0)
1954     seq_param->scc_fields.bits.palette_mode_enabled_flag = 1;
1955 #else
1956     /* SCC profile should not be selected. */
1957     g_assert_not_reached ();
1958     return FALSE;
1959 #endif
1960   }
1961
1962   return TRUE;
1963 }
1964
1965 /* CTUs in each tile column */
1966 static guint32 tile_ctu_cols[GST_VAAPI_H265_MAX_COL_TILES];
1967 /* CTUs in each tile row */
1968 static guint32 tile_ctu_rows[GST_VAAPI_H265_MAX_ROW_TILES];
1969
1970 /* Fills in VA picture parameter buffer */
1971 static gboolean
1972 fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
1973     GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1974 {
1975   VAEncPictureParameterBufferHEVC *const pic_param = picture->param;
1976   GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1977   GstVaapiEncoderH265Ref *ref_pic;
1978   GList *reflist;
1979   guint i;
1980   guint8 nal_unit_type, no_output_of_prior_pics_flag = 0;
1981
1982   memset (pic_param, 0, sizeof (VAEncPictureParameterBufferHEVC));
1983
1984   pic_param->decoded_curr_pic.picture_id =
1985       GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1986   pic_param->decoded_curr_pic.pic_order_cnt = picture->poc;
1987   pic_param->decoded_curr_pic.flags = 0;
1988
1989   i = 0;
1990   if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1991     for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
1992         reflist; reflist = g_list_next (reflist)) {
1993       ref_pic = reflist->data;
1994       g_assert (ref_pic && ref_pic->pic &&
1995           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1996
1997       pic_param->reference_frames[i].picture_id =
1998           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1999       pic_param->reference_frames[i].pic_order_cnt = ref_pic->poc;
2000       ++i;
2001     }
2002     g_assert (i <= 15 && i <= ref_pool->max_ref_frames);
2003   }
2004   for (; i < 15; ++i) {
2005     pic_param->reference_frames[i].picture_id = VA_INVALID_SURFACE;
2006     pic_param->reference_frames[i].flags = VA_PICTURE_HEVC_INVALID;
2007   }
2008   pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
2009
2010   /* slice_temporal_mvp_enable_flag == FALSE */
2011   pic_param->collocated_ref_pic_index = 0xFF;
2012
2013   pic_param->last_picture = 0;
2014   pic_param->pic_init_qp = encoder->qp_i;
2015   pic_param->num_ref_idx_l0_default_active_minus1 =
2016       (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0);
2017   pic_param->num_ref_idx_l1_default_active_minus1 =
2018       (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0);
2019
2020   if (!get_nal_unit_type (picture, &nal_unit_type))
2021     return FALSE;
2022   pic_param->nal_unit_type = nal_unit_type;
2023
2024   /* set picture fields */
2025   pic_param->pic_fields.value = 0;
2026   pic_param->pic_fields.bits.idr_pic_flag =
2027       GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
2028   pic_param->pic_fields.bits.coding_type = picture->type;
2029   if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
2030     pic_param->pic_fields.bits.reference_pic_flag = TRUE;
2031   pic_param->pic_fields.bits.sign_data_hiding_enabled_flag = FALSE;
2032   pic_param->pic_fields.bits.transform_skip_enabled_flag = TRUE;
2033   /* it seems driver requires enablement of cu_qp_delta_enabled_flag
2034    * to modifiy QP values in CBR mode or low power encoding */
2035   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP
2036       || picture->has_roi
2037       || encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP)
2038     pic_param->pic_fields.bits.cu_qp_delta_enabled_flag = 1;
2039
2040   /* XXX: Intel's media-driver, when using low-power mode, requires
2041    * that diff_cu_qp_delta_depth has to be equal to
2042    * log2_diff_max_min_luma_coding_block_size, meaning 3.
2043    *
2044    * For now we assume that on only Intel's media-drivers supports
2045    * H265 low-power */
2046   if ((encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) &&
2047       (pic_param->pic_fields.bits.cu_qp_delta_enabled_flag))
2048     pic_param->diff_cu_qp_delta_depth = 3;
2049
2050   pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE;
2051
2052   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
2053     no_output_of_prior_pics_flag = 1;
2054   pic_param->pic_fields.bits.no_output_of_prior_pics_flag =
2055       no_output_of_prior_pics_flag;
2056
2057   /* Setup tile info */
2058   pic_param->pic_fields.bits.tiles_enabled_flag =
2059       h265_is_tile_enabled (encoder);
2060   if (pic_param->pic_fields.bits.tiles_enabled_flag) {
2061     /* Always set loop filter across tiles enabled now */
2062     pic_param->pic_fields.bits.loop_filter_across_tiles_enabled_flag = 1;
2063
2064     pic_param->num_tile_columns_minus1 = encoder->num_tile_cols - 1;
2065     pic_param->num_tile_rows_minus1 = encoder->num_tile_rows - 1;
2066
2067     /* The VA row_height_minus1 and column_width_minus1 size is 1 smaller
2068        than the MAX_COL_TILES and MAX_ROW_TILES, which means the driver
2069        can deduce the last tile's size based on the picture info. We need
2070        to take care of the array size here. */
2071     for (i = 0; i < MIN (encoder->num_tile_cols, 19); ++i)
2072       pic_param->column_width_minus1[i] = tile_ctu_cols[i] - 1;
2073     for (i = 0; i < MIN (encoder->num_tile_rows, 21); ++i)
2074       pic_param->row_height_minus1[i] = tile_ctu_rows[i] - 1;
2075   }
2076
2077   if (h265_is_scc (encoder)) {
2078 #if VA_CHECK_VERSION(1,8,0)
2079     pic_param->scc_fields.bits.pps_curr_pic_ref_enabled_flag = 1;
2080 #else
2081     /* SCC profile should not be selected. */
2082     g_assert_not_reached ();
2083     return FALSE;
2084 #endif
2085   }
2086
2087   return TRUE;
2088 }
2089
2090 static GstVaapiEncSlice *
2091 create_and_fill_one_slice (GstVaapiEncoderH265 * encoder,
2092     GstVaapiEncPicture * picture,
2093     GstVaapiEncoderH265Ref ** reflist_0, guint reflist_0_count,
2094     GstVaapiEncoderH265Ref ** reflist_1, guint reflist_1_count)
2095 {
2096   VAEncSliceParameterBufferHEVC *slice_param;
2097   GstVaapiEncSlice *slice;
2098   guint i_ref;
2099
2100   slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder);
2101   g_assert (slice && slice->param_id != VA_INVALID_ID);
2102   slice_param = slice->param;
2103   memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC));
2104
2105   slice_param->slice_type = h265_get_slice_type (picture->type);
2106   if (encoder->no_p_frame && slice_param->slice_type == GST_H265_P_SLICE) {
2107     slice_param->slice_type = GST_H265_B_SLICE;
2108   } else if (h265_is_scc (encoder) &&
2109       slice_param->slice_type == GST_H265_I_SLICE) {
2110     /* In scc mode, the I frame can ref to itself and so need the L0
2111        reference list enabled. Just set the I frame to P_SLICE type
2112        and leaving all reference unchanged. So all ref_pic_list0's
2113        picture is invalid, the only ref is itself enabled by
2114        pic_param->scc_fields.bits.pps_curr_pic_ref_enabled_flag. */
2115     slice_param->slice_type = GST_H265_P_SLICE;
2116   }
2117
2118   slice_param->slice_pic_parameter_set_id = 0;
2119
2120   slice_param->slice_fields.bits.num_ref_idx_active_override_flag =
2121       reflist_0_count || reflist_1_count;
2122   if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
2123     slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
2124   else
2125     slice_param->num_ref_idx_l0_active_minus1 = 0;
2126   if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
2127     slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
2128   else
2129     slice_param->num_ref_idx_l1_active_minus1 = 0;
2130   if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->no_p_frame)
2131     slice_param->num_ref_idx_l1_active_minus1 =
2132         slice_param->num_ref_idx_l0_active_minus1;
2133
2134   i_ref = 0;
2135   if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
2136     for (; i_ref < reflist_0_count; ++i_ref) {
2137       slice_param->ref_pic_list0[i_ref].picture_id =
2138           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
2139       slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc;
2140     }
2141   }
2142   for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) {
2143     slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE;
2144     slice_param->ref_pic_list0[i_ref].flags = VA_PICTURE_HEVC_INVALID;
2145   }
2146
2147   i_ref = 0;
2148   if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
2149     for (; i_ref < reflist_1_count; ++i_ref) {
2150       slice_param->ref_pic_list1[i_ref].picture_id =
2151           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
2152       slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc;
2153     }
2154   } else if (picture->type == GST_VAAPI_PICTURE_TYPE_P && encoder->no_p_frame) {
2155     for (; i_ref < reflist_0_count; ++i_ref) {
2156       slice_param->ref_pic_list1[i_ref].picture_id =
2157           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
2158       slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_0[i_ref]->poc;
2159     }
2160   }
2161   for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) {
2162     slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE;
2163     slice_param->ref_pic_list1[i_ref].flags = VA_PICTURE_HEVC_INVALID;
2164   }
2165
2166   slice_param->max_num_merge_cand = 5;  /* MaxNumMergeCand      */
2167   slice_param->slice_qp_delta = encoder->qp_i - encoder->init_qp;
2168   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) {
2169     if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
2170       slice_param->slice_qp_delta += encoder->qp_ip;
2171     } else if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
2172       slice_param->slice_qp_delta += encoder->qp_ib;
2173     }
2174     if ((gint) encoder->init_qp + slice_param->slice_qp_delta <
2175         (gint) encoder->min_qp) {
2176       slice_param->slice_qp_delta = encoder->min_qp - encoder->init_qp;
2177     }
2178     if ((gint) encoder->init_qp + slice_param->slice_qp_delta >
2179         (gint) encoder->max_qp) {
2180       slice_param->slice_qp_delta = encoder->max_qp - encoder->init_qp;
2181     }
2182   }
2183
2184   slice_param->slice_fields.bits.slice_loop_filter_across_slices_enabled_flag =
2185       TRUE;
2186
2187   return slice;
2188 }
2189
2190 /* Adds slice headers to picture */
2191 static gboolean
2192 add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
2193     GstVaapiEncoderH265Ref ** reflist_0, guint reflist_0_count,
2194     GstVaapiEncoderH265Ref ** reflist_1, guint reflist_1_count)
2195 {
2196   VAEncSliceParameterBufferHEVC *slice_param;
2197   GstVaapiEncSlice *slice;
2198   guint slice_of_ctus, slice_mod_ctus, cur_slice_ctus;
2199   guint ctu_size;
2200   guint ctu_width_round_factor;
2201   guint last_ctu_index;
2202   guint i_slice;
2203
2204   g_assert (picture);
2205
2206   if (h265_is_tile_enabled (encoder)) {
2207     for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
2208       encoder->first_slice_segment_in_pic_flag = (i_slice == 0);
2209
2210       slice = create_and_fill_one_slice (encoder, picture, reflist_0,
2211           reflist_0_count, reflist_1, reflist_1_count);
2212       slice_param = slice->param;
2213
2214       slice_param->slice_segment_address =
2215           encoder->tile_slice_address_map[encoder->tile_slice_address[i_slice]];
2216       slice_param->num_ctu_in_slice = encoder->tile_slice_ctu_num[i_slice];
2217       GST_LOG ("slice %d start tile address is %d, start address is %d,"
2218           " CTU num %d", i_slice, encoder->tile_slice_address[i_slice],
2219           slice_param->slice_segment_address, slice_param->num_ctu_in_slice);
2220
2221       if (i_slice == encoder->num_slices - 1)
2222         slice_param->slice_fields.bits.last_slice_of_pic_flag = 1;
2223
2224       if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
2225               VA_ENC_PACKED_HEADER_SLICE)
2226           && !add_packed_slice_header (encoder, picture, slice))
2227         goto error_create_packed_slice_hdr;
2228
2229       gst_vaapi_enc_picture_add_slice (picture, slice);
2230       gst_vaapi_codec_object_replace (&slice, NULL);
2231     }
2232   } else {
2233     ctu_size = encoder->ctu_width * encoder->ctu_height;
2234
2235     g_assert (encoder->num_slices && encoder->num_slices < ctu_size);
2236     slice_of_ctus = ctu_size / encoder->num_slices;
2237     slice_mod_ctus = ctu_size % encoder->num_slices;
2238     last_ctu_index = 0;
2239
2240     for (i_slice = 0;
2241         i_slice < encoder->num_slices && (last_ctu_index < ctu_size);
2242         ++i_slice) {
2243       cur_slice_ctus = slice_of_ctus;
2244       if (slice_mod_ctus) {
2245         ++cur_slice_ctus;
2246         --slice_mod_ctus;
2247       }
2248
2249       slice = create_and_fill_one_slice (encoder, picture, reflist_0,
2250           reflist_0_count, reflist_1, reflist_1_count);
2251       slice_param = slice->param;
2252
2253       /* Work-around for satisfying the VA-Intel driver.
2254        * The driver only support multi slice begin from row start address */
2255       ctu_width_round_factor =
2256           encoder->ctu_width - (cur_slice_ctus % encoder->ctu_width);
2257       cur_slice_ctus += ctu_width_round_factor;
2258       if ((last_ctu_index + cur_slice_ctus) > ctu_size)
2259         cur_slice_ctus = ctu_size - last_ctu_index;
2260
2261       if (i_slice == 0) {
2262         encoder->first_slice_segment_in_pic_flag = TRUE;
2263         slice_param->slice_segment_address = 0;
2264       } else {
2265         encoder->first_slice_segment_in_pic_flag = FALSE;
2266         slice_param->slice_segment_address = last_ctu_index;
2267       }
2268       slice_param->num_ctu_in_slice = cur_slice_ctus;
2269
2270       /* set calculation for next slice */
2271       last_ctu_index += cur_slice_ctus;
2272
2273       if ((i_slice == encoder->num_slices - 1) || (last_ctu_index == ctu_size))
2274         slice_param->slice_fields.bits.last_slice_of_pic_flag = 1;
2275
2276       if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
2277               VA_ENC_PACKED_HEADER_SLICE)
2278           && !add_packed_slice_header (encoder, picture, slice))
2279         goto error_create_packed_slice_hdr;
2280
2281       gst_vaapi_enc_picture_add_slice (picture, slice);
2282       gst_vaapi_codec_object_replace (&slice, NULL);
2283     }
2284
2285     if (i_slice < encoder->num_slices)
2286       GST_WARNING
2287           ("Using less number of slices than requested, Number of slices per"
2288           " pictures is %d", i_slice);
2289     g_assert (last_ctu_index == ctu_size);
2290   }
2291
2292   return TRUE;
2293
2294 error_create_packed_slice_hdr:
2295   {
2296     GST_ERROR ("failed to create packed slice header buffer");
2297     gst_vaapi_codec_object_replace (&slice, NULL);
2298     return FALSE;
2299   }
2300 }
2301
2302 /* Generates and submits SPS header accordingly into the bitstream */
2303 static gboolean
2304 ensure_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture)
2305 {
2306   GstVaapiEncSequence *sequence = NULL;
2307
2308   /* submit an SPS header before every new I-frame, if codec config changed */
2309   if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I)
2310     return TRUE;
2311
2312   sequence = GST_VAAPI_ENC_SEQUENCE_NEW (HEVC, encoder);
2313   if (!sequence || !fill_sequence (encoder, sequence))
2314     goto error_create_seq_param;
2315
2316   /* add packed vps and sps headers */
2317   if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
2318           VA_ENC_PACKED_HEADER_SEQUENCE)
2319       && !(add_packed_vps_header (encoder, picture, sequence)
2320           && add_packed_sequence_header (encoder, picture, sequence))) {
2321     goto error_create_packed_seq_hdr;
2322   }
2323
2324   if (sequence) {
2325     gst_vaapi_enc_picture_set_sequence (picture, sequence);
2326     gst_vaapi_codec_object_replace (&sequence, NULL);
2327   }
2328
2329   encoder->config_changed = FALSE;
2330   return TRUE;
2331
2332   /* ERRORS */
2333 error_create_seq_param:
2334   {
2335     GST_ERROR ("failed to create sequence parameter buffer (SPS)");
2336     gst_vaapi_codec_object_replace (&sequence, NULL);
2337     return FALSE;
2338   }
2339 error_create_packed_seq_hdr:
2340   {
2341     GST_ERROR ("failed to create packed sequence header buffer");
2342     gst_vaapi_codec_object_replace (&sequence, NULL);
2343     return FALSE;
2344   }
2345 }
2346
2347 static gboolean
2348 ensure_control_rate_params (GstVaapiEncoderH265 * encoder)
2349 {
2350   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP)
2351     return TRUE;
2352
2353 #if VA_CHECK_VERSION(1,1,0)
2354   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_ICQ) {
2355     GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).ICQ_quality_factor =
2356         encoder->quality_factor;
2357     return TRUE;
2358   }
2359 #endif
2360
2361   /* RateControl params */
2362   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).bits_per_second =
2363       encoder->bitrate_bits;
2364   /* CPB (Coded picture buffer) length in milliseconds, which could be
2365    * provided as a property */
2366   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length;
2367   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp;
2368   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp;
2369
2370 #if VA_CHECK_VERSION(1,1,0)
2371   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).max_qp = encoder->max_qp;
2372 #endif
2373
2374 #if VA_CHECK_VERSION(1,0,0)
2375   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).rc_flags.bits.mb_rate_control =
2376       (guint) encoder->mbbrc;
2377 #endif
2378
2379 #if VA_CHECK_VERSION(1,3,0)
2380   GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).quality_factor =
2381       encoder->quality_factor;
2382 #endif
2383
2384   /* HRD params */
2385   fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder));
2386
2387   return TRUE;
2388 }
2389
2390 static gboolean
2391 ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture)
2392 {
2393   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2394
2395   if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture))
2396     return FALSE;
2397   if (!gst_vaapi_encoder_ensure_param_roi_regions (base_encoder, picture))
2398     return FALSE;
2399   if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture))
2400     return FALSE;
2401   return TRUE;
2402 }
2403
2404 /* Generates and submits PPS header accordingly into the bitstream */
2405 static gboolean
2406 ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
2407     GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
2408 {
2409   GstVaapiCodedBuffer *const codedbuf =
2410       GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
2411   gboolean res = FALSE;
2412
2413   res = fill_picture (encoder, picture, codedbuf, surface);
2414
2415   if (!res)
2416     return FALSE;
2417
2418   if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
2419       (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
2420           VA_ENC_PACKED_HEADER_PICTURE)
2421       && !add_packed_picture_header (encoder, picture)) {
2422     GST_ERROR ("set picture packed header failed");
2423     return FALSE;
2424   }
2425   return TRUE;
2426 }
2427
2428
2429 /* Generates slice headers */
2430 static gboolean
2431 ensure_slices (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture)
2432 {
2433   GstVaapiEncoderH265Ref *reflist_0[15];
2434   GstVaapiEncoderH265Ref *reflist_1[15];
2435   GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
2436   guint reflist_0_count = 0, reflist_1_count = 0;
2437
2438   g_assert (picture);
2439
2440   if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
2441       !reference_list_init (encoder, picture,
2442           reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
2443     GST_ERROR ("reference list reorder failed");
2444     return FALSE;
2445   }
2446
2447   g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
2448   if (reflist_0_count > ref_pool->max_reflist0_count)
2449     reflist_0_count = ref_pool->max_reflist0_count;
2450   if (reflist_1_count > ref_pool->max_reflist1_count)
2451     reflist_1_count = ref_pool->max_reflist1_count;
2452
2453   if (!add_slice_headers (encoder, picture,
2454           reflist_0, reflist_0_count, reflist_1, reflist_1_count))
2455     return FALSE;
2456
2457   return TRUE;
2458 }
2459
2460 /* Normalizes bitrate (and CPB size) for HRD conformance */
2461 static void
2462 ensure_bitrate_hrd (GstVaapiEncoderH265 * encoder)
2463 {
2464   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2465   guint bitrate, cpb_size;
2466
2467   if (!base_encoder->bitrate) {
2468     encoder->bitrate_bits = 0;
2469     return;
2470   }
2471
2472   /* Round down bitrate. This is a hard limit mandated by the user */
2473   g_assert (SX_BITRATE >= 6);
2474   bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
2475   if (bitrate != encoder->bitrate_bits) {
2476     GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
2477     encoder->bitrate_bits = bitrate;
2478     encoder->config_changed = TRUE;
2479   }
2480
2481   /* Round up CPB size. This is an HRD compliance detail */
2482   g_assert (SX_CPB_SIZE >= 4);
2483   cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) &
2484       ~((1U << SX_CPB_SIZE) - 1);
2485   if (cpb_size != encoder->cpb_length_bits) {
2486     GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
2487     encoder->cpb_length_bits = cpb_size;
2488     encoder->config_changed = TRUE;
2489   }
2490 }
2491
2492 /* Estimates a good enough bitrate if none was supplied */
2493 static void
2494 ensure_bitrate (GstVaapiEncoderH265 * encoder)
2495 {
2496   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2497
2498   switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
2499     case GST_VAAPI_RATECONTROL_CBR:
2500     case GST_VAAPI_RATECONTROL_VBR:
2501     case GST_VAAPI_RATECONTROL_QVBR:
2502       if (!base_encoder->bitrate) {
2503         /* FIXME: Provide better estimation */
2504         /* Using a 1/6 compression ratio */
2505         /* 12 bits per pixel for YUV420 */
2506         guint64 factor;
2507
2508         factor = (guint64) encoder->luma_width * encoder->luma_height * 12 / 6;
2509         base_encoder->bitrate =
2510             gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder),
2511             GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000;
2512         GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
2513       }
2514       break;
2515     default:
2516       base_encoder->bitrate = 0;
2517       break;
2518   }
2519   ensure_bitrate_hrd (encoder);
2520 }
2521
2522 /* Constructs profile, tier and level information based on user-defined limits */
2523 static GstVaapiEncoderStatus
2524 ensure_profile_tier_level (GstVaapiEncoderH265 * encoder)
2525 {
2526   const GstVaapiProfile profile = encoder->profile;
2527   const GstVaapiTierH265 tier = encoder->tier;
2528   const GstVaapiLevelH265 level = encoder->level;
2529
2530   if (!ensure_profile (encoder))
2531     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2532
2533   encoder->entrypoint =
2534       gst_vaapi_encoder_get_entrypoint (GST_VAAPI_ENCODER_CAST (encoder),
2535       encoder->profile);
2536   g_assert (encoder->entrypoint != GST_VAAPI_ENTRYPOINT_INVALID);
2537
2538   /* Ensure bitrate if not set already and derive the right level to use */
2539   ensure_bitrate (encoder);
2540
2541   if (!ensure_tier_level (encoder))
2542     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
2543
2544   if (encoder->profile != profile || encoder->level != level
2545       || encoder->tier != tier) {
2546     GST_DEBUG ("selected %s profile at tier %s and level %s",
2547         gst_vaapi_utils_h265_get_profile_string (encoder->profile),
2548         gst_vaapi_utils_h265_get_tier_string (encoder->tier),
2549         gst_vaapi_utils_h265_get_level_string (encoder->level));
2550     encoder->config_changed = TRUE;
2551   }
2552   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2553 }
2554
2555 static gboolean
2556 check_ref_list (GstVaapiEncoderH265 * encoder)
2557 {
2558 #if VA_CHECK_VERSION(1,9,0)
2559   /* Some driver require both r0 and r1 list are non NULL, i.e. no p frame
2560      in the stream. The traditional P frame can be converted to B frame with
2561      forward dependency only. The new B frame has only forward reference in
2562      both r0 and r1 list, which conforms to H265 spec. This can get some gain
2563      because there are 2 MVs for each frame and can generate better motion
2564      estimation. */
2565   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (encoder);
2566   guint value = 0;
2567   VAProfile va_profile = gst_vaapi_profile_get_va_profile (encoder->profile);
2568   VAEntrypoint va_entrypoint =
2569       gst_vaapi_entrypoint_get_va_entrypoint (encoder->entrypoint);
2570
2571   encoder->no_p_frame = FALSE;
2572   if (gst_vaapi_get_config_attribute (base_encoder->display, va_profile,
2573           va_entrypoint, VAConfigAttribPredictionDirection, &value)) {
2574     gboolean double_ref_list =
2575         ((value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) != 0);
2576     if (double_ref_list) {
2577       GST_INFO ("driver does not support P frame, we need to convert P"
2578           " frame to forward dependency B frame.");
2579       encoder->no_p_frame = double_ref_list;
2580     }
2581   }
2582
2583   if (encoder->no_p_frame == TRUE && base_encoder->max_num_ref_frames_1 < 1) {
2584     GST_WARNING ("P frame should be converted to forward dependent B,"
2585         " but reference list 1 is disabled here. Should be an invalid"
2586         " setting or a driver error.");
2587     return FALSE;
2588   }
2589 #endif
2590
2591   return TRUE;
2592 }
2593
2594 static GstVaapiEncoderStatus
2595 reset_properties (GstVaapiEncoderH265 * encoder)
2596 {
2597   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2598   GstVaapiH265ReorderPool *reorder_pool;
2599   GstVaapiH265RefPool *ref_pool;
2600   guint ctu_size;
2601   gboolean ret;
2602
2603   if (encoder->idr_period < base_encoder->keyframe_period)
2604     encoder->idr_period = base_encoder->keyframe_period;
2605
2606   if (encoder->min_qp > encoder->init_qp)
2607     encoder->min_qp = encoder->init_qp;
2608   if (encoder->max_qp < encoder->init_qp)
2609     encoder->max_qp = encoder->init_qp;
2610
2611   encoder->qp_i = encoder->init_qp;
2612
2613   ctu_size = encoder->ctu_width * encoder->ctu_height;
2614   ret = gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile,
2615       encoder->entrypoint, (ctu_size + 1) / 2, &encoder->num_slices);
2616   g_assert (ret);
2617
2618   gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile,
2619       encoder->entrypoint);
2620
2621   if (!check_ref_list (encoder))
2622     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2623
2624   if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) {
2625     GST_WARNING ("Disabling b-frame since the driver doesn't support it");
2626     encoder->num_bframes = 0;
2627   }
2628
2629   if (encoder->num_ref_frames > base_encoder->max_num_ref_frames_0) {
2630     GST_INFO ("Lowering the number of reference frames to %d",
2631         base_encoder->max_num_ref_frames_0);
2632     encoder->num_ref_frames = base_encoder->max_num_ref_frames_0;
2633   }
2634
2635   if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
2636     encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
2637
2638   if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0)
2639     encoder->cts_offset = gst_util_uint64_scale (GST_SECOND,
2640         GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder));
2641   else
2642     encoder->cts_offset = 0;
2643
2644   /* init max_poc */
2645   encoder->log2_max_pic_order_cnt =
2646       h265_get_log2_max_pic_order_cnt (encoder->idr_period);
2647   g_assert (encoder->log2_max_pic_order_cnt >= 4);
2648   encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
2649   encoder->idr_num = 0;
2650
2651   /* Only Supporting a maximum of two reference frames */
2652   if (encoder->num_bframes) {
2653     encoder->max_dec_pic_buffering = encoder->num_ref_frames + 2;
2654     encoder->max_num_reorder_pics = 1;
2655   } else {
2656     encoder->max_dec_pic_buffering = encoder->num_ref_frames + 1;
2657     encoder->max_num_reorder_pics = 0;
2658   }
2659
2660   ref_pool = &encoder->ref_pool;
2661   ref_pool->max_reflist0_count = encoder->num_ref_frames;
2662   ref_pool->max_reflist1_count = encoder->num_bframes > 0;
2663   ref_pool->max_ref_frames = ref_pool->max_reflist0_count
2664       + ref_pool->max_reflist1_count;
2665
2666   reorder_pool = &encoder->reorder_pool;
2667   reorder_pool->frame_index = 0;
2668
2669   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2670 }
2671
2672 static void
2673 reset_tile (GstVaapiEncoderH265 * encoder)
2674 {
2675   memset (tile_ctu_cols, 0, sizeof (tile_ctu_cols));
2676   memset (tile_ctu_rows, 0, sizeof (tile_ctu_rows));
2677
2678   if (encoder->tile_slice_address)
2679     g_free (encoder->tile_slice_address);
2680   encoder->tile_slice_address = NULL;
2681
2682   if (encoder->tile_slice_ctu_num)
2683     g_free (encoder->tile_slice_ctu_num);
2684   encoder->tile_slice_ctu_num = NULL;
2685
2686   if (encoder->tile_slice_address_map)
2687     g_free (encoder->tile_slice_address_map);
2688   encoder->tile_slice_address_map = NULL;
2689 }
2690
2691 static void
2692 recalculate_slices_num_by_tile (GstVaapiEncoderH265 * encoder)
2693 {
2694   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
2695
2696   /* If driver has the requirement that the slice should not span tiles,
2697      we need to increase slice number if needed. */
2698   if (gst_vaapi_display_has_driver_quirks (display,
2699           GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE)) {
2700     if (encoder->num_slices < encoder->num_tile_cols * encoder->num_tile_rows) {
2701       /* encoder->num_slices > 1 means user set it */
2702       if (encoder->num_slices > 1)
2703         GST_WARNING ("user set num-slices to %d, which is smaller than tile"
2704             " num %d. We should make slice not span tiles, just set the"
2705             " num-slices to tile num here.",
2706             encoder->num_slices,
2707             encoder->num_tile_cols * encoder->num_tile_rows);
2708       else
2709         GST_INFO ("set default slice num to %d, the same as the tile num.",
2710             encoder->num_tile_cols * encoder->num_tile_rows);
2711       encoder->num_slices = encoder->num_tile_cols * encoder->num_tile_rows;
2712     }
2713   }
2714 }
2715
2716 static GstVaapiEncoderStatus
2717 calculate_slices_start_address (GstVaapiEncoderH265 * encoder)
2718 {
2719   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
2720   guint32 ctu_per_slice;
2721   guint32 left_slices;
2722   gint32 i, j, k;
2723
2724   /* If driver has the requirement that the slice should not span tiles,
2725      firstly we should scatter slices uniformly into each tile, bigger
2726      tile gets more slices. Then we should assign CTUs within one tile
2727      uniformly to each slice in that tile. */
2728   if (gst_vaapi_display_has_driver_quirks (display,
2729           GST_VAAPI_DRIVER_QUIRK_HEVC_ENC_SLICE_NOT_SPAN_TILE)) {
2730     guint32 *slices_per_tile = g_malloc (encoder->num_tile_cols *
2731         encoder->num_tile_rows * sizeof (guint32));
2732     if (!slices_per_tile)
2733       return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2734
2735     ctu_per_slice = (encoder->ctu_width * encoder->ctu_height +
2736         encoder->num_slices - 1) / encoder->num_slices;
2737     g_assert (ctu_per_slice > 0);
2738     left_slices = encoder->num_slices;
2739
2740     for (i = 0; i < encoder->num_tile_cols * encoder->num_tile_rows; i++) {
2741       slices_per_tile[i] = 1;
2742       left_slices--;
2743     }
2744     while (left_slices) {
2745       /* Find the biggest CTUs/slices, and assign more. */
2746       gfloat largest = 0.0f;
2747       k = -1;
2748       for (i = 0; i < encoder->num_tile_cols * encoder->num_tile_rows; i++) {
2749         gfloat f;
2750         f = ((gfloat) (tile_ctu_cols[i % encoder->num_tile_cols] *
2751                 tile_ctu_rows[i / encoder->num_tile_cols])) /
2752             (gfloat) slices_per_tile[i];
2753         g_assert (f >= 1.0f);
2754         if (f > largest) {
2755           k = i;
2756           largest = f;
2757         }
2758       }
2759
2760       g_assert (k >= 0);
2761       slices_per_tile[k]++;
2762       left_slices--;
2763     }
2764
2765     /* Assign CTUs in one tile uniformly to each slice. Note: the slice start
2766        address is CTB address in tile scan(see spec 6.5), that is, we accumulate
2767        all CTUs in tile0, then tile1, and tile2..., not from the picture's
2768        perspective. */
2769     encoder->tile_slice_address[0] = 0;
2770     k = 1;
2771     for (i = 0; i < encoder->num_tile_rows; i++) {
2772       for (j = 0; j < encoder->num_tile_cols; j++) {
2773         guint32 s_num = slices_per_tile[i * encoder->num_tile_cols + j];
2774         guint32 one_tile_ctus = tile_ctu_cols[j] * tile_ctu_rows[i];
2775         guint32 s;
2776
2777         GST_LOG ("Tile(row %d col %d), has CTU in col %d,"
2778             " CTU in row is %d, total CTU %d, assigned %d slices", i, j,
2779             tile_ctu_cols[j], tile_ctu_rows[i], one_tile_ctus, s_num);
2780
2781         g_assert (s_num > 0);
2782         for (s = 0; s < s_num; s++) {
2783           encoder->tile_slice_address[k] =
2784               encoder->tile_slice_address[k - 1] + ((s +
2785                   1) * one_tile_ctus) / s_num - (s * one_tile_ctus) / s_num;
2786           encoder->tile_slice_ctu_num[k - 1] =
2787               encoder->tile_slice_address[k] - encoder->tile_slice_address[k -
2788               1];
2789           k++;
2790         }
2791       }
2792     }
2793
2794     g_assert (k == encoder->num_slices + 1);
2795     /* Calculate the last one */
2796     encoder->tile_slice_ctu_num[encoder->num_slices - 1] =
2797         encoder->ctu_width * encoder->ctu_height -
2798         encoder->tile_slice_address[encoder->num_slices - 1];
2799
2800     g_free (slices_per_tile);
2801   }
2802   /* The easy way, just assign CTUs to each slice uniformly */
2803   else {
2804     ctu_per_slice = (encoder->ctu_width * encoder->ctu_height +
2805         encoder->num_slices - 1) / encoder->num_slices;
2806     g_assert (ctu_per_slice > 0);
2807
2808     for (i = 0; i < encoder->num_slices - 1; i++)
2809       encoder->tile_slice_ctu_num[i] = ctu_per_slice;
2810     encoder->tile_slice_ctu_num[encoder->num_slices - 1] =
2811         encoder->ctu_width * encoder->ctu_height -
2812         (encoder->num_slices - 1) * ctu_per_slice;
2813
2814     encoder->tile_slice_address[0] = 0;
2815     for (i = 1; i <= encoder->num_slices; i++)
2816       encoder->tile_slice_address[i] = encoder->tile_slice_address[i - 1] +
2817           encoder->tile_slice_ctu_num[i - 1];
2818   }
2819
2820   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2821 }
2822
2823 static GstVaapiEncoderStatus
2824 ensure_tile (GstVaapiEncoderH265 * encoder)
2825 {
2826   gint32 i, j, k;
2827   guint32 ctu_tile_width_accu[GST_VAAPI_H265_MAX_COL_TILES + 1];
2828   guint32 ctu_tile_height_accu[GST_VAAPI_H265_MAX_ROW_TILES + 1];
2829   guint32 num_slices;
2830   GstVaapiEncoderStatus ret;
2831
2832   reset_tile (encoder);
2833
2834   if (!h265_is_tile_enabled (encoder))
2835     return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2836
2837   if (!gst_vaapi_encoder_ensure_tile_support (GST_VAAPI_ENCODER (encoder),
2838           encoder->profile, encoder->entrypoint)) {
2839     GST_ERROR ("The profile:%s, entrypoint:%d does not support tile.",
2840         gst_vaapi_utils_h265_get_profile_string (encoder->profile),
2841         encoder->entrypoint);
2842     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2843   }
2844
2845   if (encoder->num_tile_cols >
2846       gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileColumns) {
2847     GST_ERROR ("num_tile_cols:%d exceeds MaxTileColumns:%d",
2848         encoder->num_tile_cols,
2849         gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileColumns);
2850     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2851   }
2852   if (encoder->num_tile_rows >
2853       gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileRows) {
2854     GST_ERROR ("num_tile_rows:%d exceeds MaxTileRows:%d",
2855         encoder->num_tile_rows,
2856         gst_vaapi_utils_h265_get_level_limits (encoder->level)->MaxTileRows);
2857     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2858   }
2859
2860   if (encoder->ctu_width < encoder->num_tile_cols) {
2861     GST_WARNING
2862         ("Only %d CTUs in width, not enough to split into %d tile columns",
2863         encoder->ctu_width, encoder->num_tile_cols);
2864     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2865   }
2866   if (encoder->ctu_height < encoder->num_tile_rows) {
2867     GST_WARNING
2868         ("Only %d CTUs in height, not enough to split into %d tile rows",
2869         encoder->ctu_height, encoder->num_tile_rows);
2870     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2871   }
2872
2873   recalculate_slices_num_by_tile (encoder);
2874
2875   /* ensure not exceed max supported slices */
2876   num_slices = encoder->num_slices;
2877   gst_vaapi_encoder_ensure_num_slices (GST_VAAPI_ENCODER_CAST (encoder),
2878       encoder->profile, encoder->entrypoint,
2879       (encoder->ctu_width * encoder->ctu_height + 1) / 2, &num_slices);
2880   if (num_slices != encoder->num_slices) {
2881     GST_ERROR ("The tile setting need at least %d slices, but the max"
2882         " slice number is just %d", encoder->num_slices, num_slices);
2883     return GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2884   }
2885
2886   encoder->tile_slice_address =
2887       /* Add one as sentinel, hold val to calculate ctu_num */
2888       g_malloc ((encoder->num_slices + 1) * sizeof (guint32));
2889   if (!encoder->tile_slice_address)
2890     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2891   encoder->tile_slice_ctu_num =
2892       g_malloc (encoder->num_slices * sizeof (guint32));
2893   if (!encoder->tile_slice_ctu_num)
2894     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2895   encoder->tile_slice_address_map =
2896       g_malloc (encoder->ctu_width * encoder->ctu_height * sizeof (guint32));
2897   if (!encoder->tile_slice_address_map)
2898     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2899
2900   /* firstly uniformly separate CTUs into tiles, as the spec 6.5.1 define */
2901   for (i = 0; i < encoder->num_tile_cols; i++)
2902     tile_ctu_cols[i] =
2903         ((i + 1) * encoder->ctu_width) / encoder->num_tile_cols -
2904         (i * encoder->ctu_width) / encoder->num_tile_cols;
2905   for (i = 0; i < encoder->num_tile_rows; i++)
2906     tile_ctu_rows[i] =
2907         ((i + 1) * encoder->ctu_height) / encoder->num_tile_rows -
2908         (i * encoder->ctu_height) / encoder->num_tile_rows;
2909
2910   ret = calculate_slices_start_address (encoder);
2911   if (ret != GST_VAAPI_ENCODER_STATUS_SUCCESS)
2912     return ret;
2913
2914   /* Build the map to specifying the conversion between a CTB address in CTB
2915      raster scan of a picture and a CTB address in tile scan(see spec 6.5.1
2916      for details). */
2917   ctu_tile_width_accu[0] = 0;
2918   for (i = 1; i <= encoder->num_tile_cols; i++)
2919     ctu_tile_width_accu[i] = ctu_tile_width_accu[i - 1] + tile_ctu_cols[i - 1];
2920   ctu_tile_height_accu[0] = 0;
2921   for (i = 1; i <= encoder->num_tile_rows; i++)
2922     ctu_tile_height_accu[i] =
2923         ctu_tile_height_accu[i - 1] + tile_ctu_rows[i - 1];
2924
2925   for (k = 0; k < encoder->ctu_width * encoder->ctu_height; k++) {
2926     /* The ctu coordinate in the picture. */
2927     guint32 x = k % encoder->ctu_width;
2928     guint32 y = k / encoder->ctu_width;
2929     /* The ctu coordinate in the tile mode. */
2930     guint32 tile_x = 0;
2931     guint32 tile_y = 0;
2932     /* The index of the CTU in the tile mode. */
2933     guint32 tso = 0;
2934
2935     for (i = 0; i < encoder->num_tile_cols; i++)
2936       if (x >= ctu_tile_width_accu[i])
2937         tile_x = i;
2938     g_assert (tile_x <= encoder->num_tile_cols - 1);
2939
2940     for (j = 0; j < encoder->num_tile_rows; j++)
2941       if (y >= ctu_tile_height_accu[j])
2942         tile_y = j;
2943     g_assert (tile_y <= encoder->num_tile_rows - 1);
2944
2945     /* add all ctus in the tiles the same line before us */
2946     for (i = 0; i < tile_x; i++)
2947       tso += tile_ctu_rows[tile_y] * tile_ctu_cols[i];
2948
2949     /* add all ctus in the tiles above us */
2950     for (j = 0; j < tile_y; j++)
2951       tso += encoder->ctu_width * tile_ctu_rows[j];
2952
2953     /* add the ctus inside the same tile before us */
2954     tso += (y - ctu_tile_height_accu[tile_y]) * tile_ctu_cols[tile_x]
2955         + x - ctu_tile_width_accu[tile_x];
2956
2957     g_assert (tso < encoder->ctu_width * encoder->ctu_height);
2958
2959     encoder->tile_slice_address_map[tso] = k;
2960   }
2961
2962   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2963 }
2964
2965 static GstVaapiEncoderStatus
2966 gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder,
2967     GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
2968 {
2969   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2970   GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2971   GstVaapiSurfaceProxy *reconstruct = NULL;
2972
2973   reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
2974
2975   g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
2976
2977   if (!ensure_sequence (encoder, picture))
2978     goto error;
2979   if (!ensure_misc_params (encoder, picture))
2980     goto error;
2981   if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
2982     goto error;
2983   if (!ensure_slices (encoder, picture))
2984     goto error;
2985   if (!gst_vaapi_enc_picture_encode (picture))
2986     goto error;
2987
2988   if (!reference_list_update (encoder, picture, reconstruct))
2989     goto error;
2990
2991   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2992
2993   /* ERRORS */
2994 error:
2995   {
2996     if (reconstruct)
2997       gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
2998           reconstruct);
2999     return ret;
3000   }
3001 }
3002
3003 struct _PendingIterState
3004 {
3005   GstVaapiPictureType pic_type;
3006 };
3007
3008 static gboolean
3009 gst_vaapi_encoder_h265_get_pending_reordered (GstVaapiEncoder * base_encoder,
3010     GstVaapiEncPicture ** picture, gpointer * state)
3011 {
3012   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
3013   GstVaapiH265ReorderPool *reorder_pool;
3014   GstVaapiEncPicture *pic;
3015   struct _PendingIterState *iter;
3016
3017   g_return_val_if_fail (state, FALSE);
3018
3019   if (!*state) {
3020     iter = g_new0 (struct _PendingIterState, 1);
3021     iter->pic_type = GST_VAAPI_PICTURE_TYPE_P;
3022     *state = iter;
3023   } else {
3024     iter = *state;
3025   }
3026
3027   *picture = NULL;
3028
3029   reorder_pool = &encoder->reorder_pool;
3030   if (g_queue_is_empty (&reorder_pool->reorder_frame_list))
3031     return FALSE;
3032
3033   pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
3034   g_assert (pic);
3035   if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_P) {
3036     set_p_frame (pic, encoder);
3037     iter->pic_type = GST_VAAPI_PICTURE_TYPE_B;
3038   } else if (iter->pic_type == GST_VAAPI_PICTURE_TYPE_B) {
3039     set_b_frame (pic, encoder);
3040   } else {
3041     GST_WARNING ("Unhandled pending picture type");
3042   }
3043
3044   if (GST_CLOCK_TIME_IS_VALID (pic->frame->pts))
3045     pic->frame->pts += encoder->cts_offset;
3046
3047   *picture = pic;
3048   return TRUE;
3049 }
3050
3051 static GstVaapiEncoderStatus
3052 gst_vaapi_encoder_h265_flush (GstVaapiEncoder * base_encoder)
3053 {
3054   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
3055   GstVaapiH265ReorderPool *reorder_pool;
3056   GstVaapiEncPicture *pic;
3057
3058   reorder_pool = &encoder->reorder_pool;
3059   reorder_pool->frame_index = 0;
3060   reorder_pool->cur_present_index = 0;
3061
3062   while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
3063     pic = (GstVaapiEncPicture *)
3064         g_queue_pop_head (&reorder_pool->reorder_frame_list);
3065     gst_vaapi_enc_picture_unref (pic);
3066   }
3067   g_queue_clear (&reorder_pool->reorder_frame_list);
3068
3069   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
3070 }
3071
3072 /* Generate "codec-data" buffer */
3073 static GstVaapiEncoderStatus
3074 gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder,
3075     GstBuffer ** out_buffer_ptr)
3076 {
3077   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
3078   const guint32 configuration_version = 0x01;
3079   const guint32 nal_length_size = 4;
3080   GstMapInfo vps_info, sps_info, pps_info;
3081   GstBitWriter bs;
3082   GstBuffer *buffer;
3083   guint min_spatial_segmentation_idc = 0;
3084   guint num_arrays = 3;
3085
3086   if (!encoder->vps_data || !encoder->sps_data || !encoder->pps_data)
3087     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
3088   if (gst_buffer_get_size (encoder->sps_data) < 4)
3089     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
3090
3091   if (!gst_buffer_map (encoder->vps_data, &vps_info, GST_MAP_READ))
3092     goto error_map_vps_buffer;
3093
3094   if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
3095     goto error_map_sps_buffer;
3096
3097   if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
3098     goto error_map_pps_buffer;
3099
3100   /* Header */
3101   gst_bit_writer_init_with_size (&bs,
3102       (vps_info.size + sps_info.size + pps_info.size + 64), FALSE);
3103   WRITE_UINT32 (&bs, configuration_version, 8);
3104   WRITE_UINT32 (&bs, sps_info.data[4], 8);      /* profile_space | tier_flag | profile_idc */
3105   WRITE_UINT32 (&bs, sps_info.data[5], 32);     /* profile_compatibility_flag [0-31] */
3106   /* progressive_source_flag | interlaced_source_flag | non_packed_constraint_flag |
3107    * frame_only_constraint_flag | reserved_zero_bits[0-27] */
3108   WRITE_UINT32 (&bs, sps_info.data[9], 32);
3109   WRITE_UINT32 (&bs, sps_info.data[13], 16);    /* reserved_zero_bits [28-43] */
3110   WRITE_UINT32 (&bs, sps_info.data[15], 8);     /* level_idc */
3111   WRITE_UINT32 (&bs, 0x0f, 4);  /* 1111 */
3112   WRITE_UINT32 (&bs, min_spatial_segmentation_idc, 12); /* min_spatial_segmentation_idc */
3113   WRITE_UINT32 (&bs, 0x3f, 6);  /* 111111 */
3114   WRITE_UINT32 (&bs, 0x00, 2);  /* parallelismType */
3115   WRITE_UINT32 (&bs, 0x3f, 6);  /* 111111 */
3116   WRITE_UINT32 (&bs, 0x01, 2);  /* chroma_format_idc */
3117   WRITE_UINT32 (&bs, 0x1f, 5);  /* 11111 */
3118   WRITE_UINT32 (&bs, 0x01, 3);  /* bit_depth_luma_minus8 */
3119   WRITE_UINT32 (&bs, 0x1f, 5);  /* 11111 */
3120   WRITE_UINT32 (&bs, 0x01, 3);  /* bit_depth_chroma_minus8 */
3121   WRITE_UINT32 (&bs, 0x00, 16); /* avgFramerate */
3122   WRITE_UINT32 (&bs, 0x00, 2);  /* constatnFramerate */
3123   WRITE_UINT32 (&bs, 0x00, 3);  /* numTemporalLayers */
3124   WRITE_UINT32 (&bs, 0x00, 1);  /* temporalIdNested */
3125   WRITE_UINT32 (&bs, nal_length_size - 1, 2);   /* lengthSizeMinusOne */
3126   WRITE_UINT32 (&bs, 0x00, 8);  /* numOfArrays */
3127
3128   WRITE_UINT32 (&bs, num_arrays, 8);    /* numOfArrays */
3129
3130   /* Write VPS */
3131   WRITE_UINT32 (&bs, 0x00, 1);  /* array_completeness */
3132   WRITE_UINT32 (&bs, 0x00, 1);  /* reserved zero */
3133   WRITE_UINT32 (&bs, GST_H265_NAL_VPS, 6);      /* Nal_unit_type */
3134   WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, VPS count = 1 */
3135   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
3136   /* Write Nal unit length and data of VPS */
3137   if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, vps_info.data, vps_info.size))
3138     goto nal_to_byte_stream_error;
3139
3140   /* Write SPS */
3141   WRITE_UINT32 (&bs, 0x00, 1);  /* array_completeness */
3142   WRITE_UINT32 (&bs, 0x00, 1);  /* reserved zero */
3143   WRITE_UINT32 (&bs, GST_H265_NAL_SPS, 6);      /* Nal_unit_type */
3144   WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, SPS count = 1 */
3145   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
3146   /* Write Nal unit length and data of SPS */
3147   if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, sps_info.data, sps_info.size))
3148     goto nal_to_byte_stream_error;
3149
3150   /* Write PPS */
3151   WRITE_UINT32 (&bs, 0x00, 1);  /* array_completeness */
3152   WRITE_UINT32 (&bs, 0x00, 1);  /* reserved zero */
3153   WRITE_UINT32 (&bs, GST_H265_NAL_PPS, 6);      /* Nal_unit_type */
3154   WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, PPS count = 1 */
3155   /* Write Nal unit length and data of PPS */
3156   if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, pps_info.data, pps_info.size))
3157     goto nal_to_byte_stream_error;
3158
3159   gst_buffer_unmap (encoder->pps_data, &pps_info);
3160   gst_buffer_unmap (encoder->sps_data, &sps_info);
3161   gst_buffer_unmap (encoder->vps_data, &vps_info);
3162
3163   buffer = gst_bit_writer_reset_and_get_buffer (&bs);
3164   if (!buffer)
3165     goto error_alloc_buffer;
3166   if (gst_buffer_n_memory (buffer) == 0) {
3167     gst_buffer_unref (buffer);
3168     goto error_alloc_buffer;
3169   }
3170   *out_buffer_ptr = buffer;
3171
3172   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
3173
3174   /* ERRORS */
3175 bs_error:
3176   {
3177     GST_ERROR ("failed to write codec-data");
3178     gst_buffer_unmap (encoder->vps_data, &vps_info);
3179     gst_buffer_unmap (encoder->sps_data, &sps_info);
3180     gst_buffer_unmap (encoder->pps_data, &pps_info);
3181     gst_bit_writer_reset (&bs);
3182     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
3183   }
3184 nal_to_byte_stream_error:
3185   {
3186     GST_ERROR ("failed to write nal unit");
3187     gst_buffer_unmap (encoder->vps_data, &vps_info);
3188     gst_buffer_unmap (encoder->sps_data, &sps_info);
3189     gst_buffer_unmap (encoder->pps_data, &pps_info);
3190     gst_bit_writer_reset (&bs);
3191     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
3192   }
3193 error_map_vps_buffer:
3194   {
3195     GST_ERROR ("failed to map VPS packed header");
3196     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
3197   }
3198 error_map_sps_buffer:
3199   {
3200     GST_ERROR ("failed to map SPS packed header");
3201     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
3202   }
3203 error_map_pps_buffer:
3204   {
3205     GST_ERROR ("failed to map PPS packed header");
3206     gst_buffer_unmap (encoder->sps_data, &sps_info);
3207     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
3208   }
3209 error_alloc_buffer:
3210   {
3211     GST_ERROR ("failed to allocate codec-data buffer");
3212     gst_bit_writer_reset (&bs);
3213     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
3214   }
3215 }
3216
3217 /* TODO */
3218 /* The re-ordering algorithm is similar to what we implemented for
3219  * h264 encoder. But We could have a better algorithm for hevc encoder
3220  * by having B-frames as reference pictures */
3221 static GstVaapiEncoderStatus
3222 gst_vaapi_encoder_h265_reordering (GstVaapiEncoder * base_encoder,
3223     GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
3224 {
3225   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
3226   GstVaapiH265ReorderPool *reorder_pool = NULL;
3227   GstVaapiEncPicture *picture;
3228   gboolean is_idr = FALSE;
3229
3230   *output = NULL;
3231
3232   reorder_pool = &encoder->reorder_pool;
3233
3234   if (!frame) {
3235     if (reorder_pool->reorder_state != GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES)
3236       return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
3237
3238     /* reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES
3239        dump B frames from queue, sometime, there may also have P frame or I frame */
3240     g_assert (encoder->num_bframes > 0);
3241     g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list),
3242         GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
3243     picture = g_queue_pop_head (&reorder_pool->reorder_frame_list);
3244     g_assert (picture);
3245     if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
3246       reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES;
3247     }
3248     goto end;
3249   }
3250
3251   /* new frame coming */
3252   picture = GST_VAAPI_ENC_PICTURE_NEW (HEVC, encoder, frame);
3253   if (!picture) {
3254     GST_WARNING ("create H265 picture failed, frame timestamp:%"
3255         GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
3256     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
3257   }
3258   ++reorder_pool->cur_present_index;
3259   picture->poc = ((reorder_pool->cur_present_index * 1) %
3260       encoder->max_pic_order_cnt);
3261
3262   is_idr = (reorder_pool->frame_index == 0 ||
3263       reorder_pool->frame_index >= encoder->idr_period);
3264
3265   /* check key frames */
3266   if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
3267       (reorder_pool->frame_index %
3268           GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) {
3269     ++reorder_pool->frame_index;
3270
3271     /* b frame enabled,  check queue of reorder_frame_list */
3272     if (encoder->num_bframes
3273         && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
3274       GstVaapiEncPicture *p_pic;
3275
3276       p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
3277       set_p_frame (p_pic, encoder);
3278       g_queue_foreach (&reorder_pool->reorder_frame_list,
3279           (GFunc) set_b_frame, encoder);
3280       set_key_frame (picture, encoder, is_idr);
3281       g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
3282       picture = p_pic;
3283       reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES;
3284     } else {                    /* no b frames in queue */
3285       set_key_frame (picture, encoder, is_idr);
3286       g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list));
3287       if (encoder->num_bframes)
3288         reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES;
3289     }
3290     goto end;
3291   }
3292
3293   /* new p/b frames coming */
3294   ++reorder_pool->frame_index;
3295   if (reorder_pool->reorder_state == GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES &&
3296       g_queue_get_length (&reorder_pool->reorder_frame_list) <
3297       encoder->num_bframes) {
3298     g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
3299     return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
3300   }
3301
3302   set_p_frame (picture, encoder);
3303
3304   if (reorder_pool->reorder_state == GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES) {
3305     g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame,
3306         encoder);
3307     reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES;
3308     g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list));
3309   }
3310
3311 end:
3312   g_assert (picture);
3313   frame = picture->frame;
3314   if (GST_CLOCK_TIME_IS_VALID (frame->pts))
3315     frame->pts += encoder->cts_offset;
3316   *output = picture;
3317
3318   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
3319 }
3320
3321 static GstVaapiEncoderStatus
3322 set_context_info (GstVaapiEncoder * base_encoder)
3323 {
3324   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
3325   GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
3326   const guint DEFAULT_SURFACES_COUNT = 3;
3327
3328   /* FIXME: Using only a rough approximation for bitstream headers.
3329    * Not taken into account: ScalingList, RefPicListModification,
3330    * PredWeightTable */
3331   /* Maximum sizes for common headers (in bits) */
3332   enum
3333   {
3334     MAX_PROFILE_TIER_LEVEL_SIZE = 684,
3335     MAX_VPS_HDR_SIZE = 13781,
3336     MAX_SPS_HDR_SIZE = 615,
3337     MAX_SHORT_TERM_REFPICSET_SIZE = 55,
3338     MAX_VUI_PARAMS_SIZE = 267,
3339     MAX_HRD_PARAMS_SIZE = 8196,
3340     MAX_PPS_HDR_SIZE = 274,
3341     MAX_SLICE_HDR_SIZE = 33660
3342   };
3343
3344   /* Account for VPS header */
3345   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_VPS_HDR_SIZE +
3346       MAX_PROFILE_TIER_LEVEL_SIZE + MAX_HRD_PARAMS_SIZE) / 8;
3347
3348   /* Account for SPS header */
3349   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
3350       MAX_PROFILE_TIER_LEVEL_SIZE + 64 * MAX_SHORT_TERM_REFPICSET_SIZE +
3351       MAX_VUI_PARAMS_SIZE + MAX_HRD_PARAMS_SIZE) / 8;
3352
3353   /* Account for PPS header */
3354   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
3355
3356   /* Account for slice header */
3357   base_encoder->codedbuf_size += encoder->num_slices * (4 +
3358       GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE + MAX_SHORT_TERM_REFPICSET_SIZE) / 8);
3359
3360   GST_VAAPI_ENCODER_CAST (encoder)->profile = encoder->profile;
3361
3362   base_encoder->num_ref_frames = (encoder->num_ref_frames
3363       + (encoder->num_bframes > 0 ? 1 : 0) + DEFAULT_SURFACES_COUNT);
3364
3365   /* Only YUV 4:2:0 formats are supported for now. */
3366   base_encoder->codedbuf_size += GST_ROUND_UP_16 (vip->width) *
3367       GST_ROUND_UP_16 (vip->height) * 3 / 2;
3368
3369   base_encoder->context_info.profile = base_encoder->profile;
3370   base_encoder->context_info.entrypoint = encoder->entrypoint;
3371
3372   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
3373 }
3374
3375 static GstVaapiEncoderStatus
3376 gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder)
3377 {
3378   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
3379   GstVaapiEncoderStatus status;
3380   guint luma_width, luma_height;
3381
3382   luma_width = GST_VAAPI_ENCODER_WIDTH (encoder);
3383   luma_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
3384
3385   if (luma_width != encoder->luma_width || luma_height != encoder->luma_height) {
3386     GST_DEBUG ("resolution: %d %d", GST_VAAPI_ENCODER_WIDTH (encoder),
3387         GST_VAAPI_ENCODER_HEIGHT (encoder));
3388     encoder->luma_width = GST_ROUND_UP_16 (luma_width);
3389     encoder->luma_height = GST_ROUND_UP_16 (luma_height);
3390     encoder->config_changed = TRUE;
3391     /* Frame Cropping */
3392     if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
3393         (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
3394       /* 6.1, Table 6-1 */
3395       static const guint SubWidthC[] = { 1, 2, 2, 1 };
3396       static const guint SubHeightC[] = { 1, 2, 1, 1 };
3397       guint index = gst_vaapi_utils_h265_get_chroma_format_idc
3398           (gst_vaapi_video_format_get_chroma_type (GST_VIDEO_INFO_FORMAT
3399               (GST_VAAPI_ENCODER_VIDEO_INFO (encoder))));
3400
3401       encoder->conformance_window_flag = 1;
3402       encoder->conf_win_left_offset = 0;
3403       encoder->conf_win_right_offset =
3404           (encoder->luma_width -
3405           GST_VAAPI_ENCODER_WIDTH (encoder)) / SubWidthC[index];
3406       encoder->conf_win_top_offset = 0;
3407       encoder->conf_win_bottom_offset =
3408           (encoder->luma_height -
3409           GST_VAAPI_ENCODER_HEIGHT (encoder)) / SubHeightC[index];
3410     }
3411   }
3412
3413   status = ensure_profile_tier_level (encoder);
3414   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
3415     return status;
3416
3417   /* Set ctu size based on entrypoint. */
3418   if (encoder->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP) {
3419     encoder->ctu_width = (encoder->luma_width + 63) / 64;
3420     encoder->ctu_height = (encoder->luma_height + 63) / 64;
3421   } else {
3422     encoder->ctu_width = (encoder->luma_width + 31) / 32;
3423     encoder->ctu_height = (encoder->luma_height + 31) / 32;
3424   }
3425
3426   status = reset_properties (encoder);
3427   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
3428     return status;
3429
3430   status = ensure_tile (encoder);
3431   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
3432     return status;
3433   ensure_control_rate_params (encoder);
3434   return set_context_info (base_encoder);
3435 }
3436
3437 static void
3438 gst_vaapi_encoder_h265_init (GstVaapiEncoderH265 * encoder)
3439 {
3440   GstVaapiH265ReorderPool *reorder_pool;
3441   GstVaapiH265RefPool *ref_pool;
3442
3443   /* Default encoding entrypoint */
3444   encoder->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
3445   encoder->tier = GST_VAAPI_TIER_H265_UNKNOWN;
3446
3447   encoder->conformance_window_flag = 0;
3448   encoder->num_slices = 1;
3449   encoder->no_p_frame = FALSE;
3450
3451   /* re-ordering  list initialize */
3452   reorder_pool = &encoder->reorder_pool;
3453   g_queue_init (&reorder_pool->reorder_frame_list);
3454   reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_NONE;
3455   reorder_pool->frame_index = 0;
3456   reorder_pool->cur_present_index = 0;
3457
3458   /* reference list info initialize */
3459   ref_pool = &encoder->ref_pool;
3460   g_queue_init (&ref_pool->ref_list);
3461   ref_pool->max_ref_frames = 0;
3462   ref_pool->max_reflist0_count = 1;
3463   ref_pool->max_reflist1_count = 1;
3464
3465   encoder->allowed_profiles = NULL;
3466 }
3467
3468 struct _GstVaapiEncoderH265Class
3469 {
3470   GstVaapiEncoderClass parent_class;
3471 };
3472
3473 G_DEFINE_TYPE (GstVaapiEncoderH265, gst_vaapi_encoder_h265,
3474     GST_TYPE_VAAPI_ENCODER);
3475
3476 static void
3477 gst_vaapi_encoder_h265_finalize (GObject * object)
3478 {
3479   /*free private buffers */
3480   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (object);
3481   GstVaapiEncPicture *pic;
3482   GstVaapiEncoderH265Ref *ref;
3483   GstVaapiH265RefPool *ref_pool;
3484   GstVaapiH265ReorderPool *reorder_pool;
3485
3486   gst_buffer_replace (&encoder->vps_data, NULL);
3487   gst_buffer_replace (&encoder->sps_data, NULL);
3488   gst_buffer_replace (&encoder->pps_data, NULL);
3489
3490   /* reference list info de-init */
3491   ref_pool = &encoder->ref_pool;
3492   while (!g_queue_is_empty (&ref_pool->ref_list)) {
3493     ref = (GstVaapiEncoderH265Ref *) g_queue_pop_head (&ref_pool->ref_list);
3494     reference_pic_free (encoder, ref);
3495   }
3496   g_queue_clear (&ref_pool->ref_list);
3497
3498   /* re-ordering  list initialize */
3499   reorder_pool = &encoder->reorder_pool;
3500   while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
3501     pic = (GstVaapiEncPicture *)
3502         g_queue_pop_head (&reorder_pool->reorder_frame_list);
3503     gst_vaapi_enc_picture_unref (pic);
3504   }
3505   g_queue_clear (&reorder_pool->reorder_frame_list);
3506
3507   reset_tile (encoder);
3508
3509   if (encoder->allowed_profiles)
3510     g_array_unref (encoder->allowed_profiles);
3511
3512   G_OBJECT_CLASS (gst_vaapi_encoder_h265_parent_class)->finalize (object);
3513 }
3514
3515 /**
3516  * @ENCODER_H265_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
3517  * @ENCODER_H265_PROP_TUNE: The tuning options (#GstVaapiEncoderTune).
3518  * @ENCODER_H265_PROP_MAX_BFRAMES: Number of B-frames between I
3519  *   and P (uint).
3520  * @ENCODER_H265_PROP_INIT_QP: Initial quantizer value (uint).
3521  * @ENCODER_H265_PROP_MIN_QP: Minimal quantizer value (uint).
3522  * @ENCODER_H265_PROP_NUM_SLICES: Number of slices per frame (uint).
3523  * @ENCODER_H265_PROP_NUM_REF_FRAMES: Maximum number of reference frames.
3524  * @ENCODER_H265_PROP_CPB_LENGTH: Length of the CPB buffer
3525  *   in milliseconds (uint).
3526  * @ENCODER_H265_PROP_MBBRC: Macroblock level Bitrate Control.
3527  * @ENCODER_H265_PROP_QP_IP: Difference of QP between I and P frame.
3528  * @ENCODER_H265_PROP_QP_IB: Difference of QP between I and B frame.
3529  * @ENCODER_H265_PROP_LOW_DELAY_B: use low delay b feature.
3530  * @ENCODER_H265_PROP_MAX_QP: Maximal quantizer value (uint).
3531  *
3532  * The set of H.265 encoder specific configurable properties.
3533  */
3534 enum
3535 {
3536   ENCODER_H265_PROP_RATECONTROL = 1,
3537   ENCODER_H265_PROP_TUNE,
3538   ENCODER_H265_PROP_MAX_BFRAMES,
3539   ENCODER_H265_PROP_INIT_QP,
3540   ENCODER_H265_PROP_MIN_QP,
3541   ENCODER_H265_PROP_NUM_SLICES,
3542   ENCODER_H265_PROP_NUM_REF_FRAMES,
3543   ENCODER_H265_PROP_CPB_LENGTH,
3544   ENCODER_H265_PROP_MBBRC,
3545   ENCODER_H265_PROP_QP_IP,
3546   ENCODER_H265_PROP_QP_IB,
3547 #ifndef GST_REMOVE_DEPRECATED
3548   ENCODER_H265_PROP_LOW_DELAY_B,
3549 #endif
3550   ENCODER_H265_PROP_MAX_QP,
3551   ENCODER_H265_PROP_QUALITY_FACTOR,
3552   ENCODER_H265_PROP_NUM_TILE_COLS,
3553   ENCODER_H265_PROP_NUM_TILE_ROWS,
3554   ENCODER_H265_N_PROPERTIES
3555 };
3556
3557 static GParamSpec *properties[ENCODER_H265_N_PROPERTIES];
3558
3559 static void
3560 gst_vaapi_encoder_h265_set_property (GObject * object, guint prop_id,
3561     const GValue * value, GParamSpec * pspec)
3562 {
3563   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
3564   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (object);
3565
3566   if (base_encoder->num_codedbuf_queued > 0) {
3567     GST_ERROR_OBJECT (object,
3568         "failed to set any property after encoding started");
3569     return;
3570   }
3571
3572   switch (prop_id) {
3573     case ENCODER_H265_PROP_RATECONTROL:
3574       gst_vaapi_encoder_set_rate_control (base_encoder,
3575           g_value_get_enum (value));
3576       break;
3577     case ENCODER_H265_PROP_TUNE:
3578       gst_vaapi_encoder_set_tuning (base_encoder, g_value_get_enum (value));
3579       break;
3580     case ENCODER_H265_PROP_MAX_BFRAMES:
3581       encoder->num_bframes = g_value_get_uint (value);
3582       break;
3583     case ENCODER_H265_PROP_INIT_QP:
3584       encoder->init_qp = g_value_get_uint (value);
3585       break;
3586     case ENCODER_H265_PROP_MIN_QP:
3587       encoder->min_qp = g_value_get_uint (value);
3588       break;
3589     case ENCODER_H265_PROP_QP_IP:
3590       encoder->qp_ip = g_value_get_int (value);
3591       break;
3592     case ENCODER_H265_PROP_QP_IB:
3593       encoder->qp_ib = g_value_get_int (value);
3594       break;
3595     case ENCODER_H265_PROP_NUM_SLICES:
3596       encoder->num_slices = g_value_get_uint (value);
3597       break;
3598     case ENCODER_H265_PROP_CPB_LENGTH:
3599       encoder->cpb_length = g_value_get_uint (value);
3600       break;
3601     case ENCODER_H265_PROP_NUM_REF_FRAMES:
3602       encoder->num_ref_frames = g_value_get_uint (value);
3603       break;
3604     case ENCODER_H265_PROP_MBBRC:
3605       encoder->mbbrc = g_value_get_enum (value);
3606       break;
3607 #ifndef GST_REMOVE_DEPRECATED
3608     case ENCODER_H265_PROP_LOW_DELAY_B:
3609 #if !VA_CHECK_VERSION(1,9,0)
3610       encoder->no_p_frame = g_value_get_boolean (value);
3611 #else
3612       if (g_value_get_boolean (value) == TRUE) {
3613         GST_WARNING ("Deprecate low-delay-b property. Driver now already"
3614             " has the ability to detect whether supporting P frames. this"
3615             " value should not be set manually and will take no effect.");
3616       }
3617 #endif
3618       break;
3619 #endif
3620     case ENCODER_H265_PROP_MAX_QP:
3621       encoder->max_qp = g_value_get_uint (value);
3622       break;
3623     case ENCODER_H265_PROP_QUALITY_FACTOR:
3624       encoder->quality_factor = g_value_get_uint (value);
3625       break;
3626     case ENCODER_H265_PROP_NUM_TILE_COLS:
3627       encoder->num_tile_cols = g_value_get_uint (value);
3628       break;
3629     case ENCODER_H265_PROP_NUM_TILE_ROWS:
3630       encoder->num_tile_rows = g_value_get_uint (value);
3631       break;
3632     default:
3633       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3634   }
3635 }
3636
3637 static void
3638 gst_vaapi_encoder_h265_get_property (GObject * object, guint prop_id,
3639     GValue * value, GParamSpec * pspec)
3640 {
3641   GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (object);
3642   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER (object);
3643
3644   switch (prop_id) {
3645     case ENCODER_H265_PROP_RATECONTROL:
3646       g_value_set_enum (value, base_encoder->rate_control);
3647       break;
3648     case ENCODER_H265_PROP_TUNE:
3649       g_value_set_enum (value, base_encoder->tune);
3650       break;
3651     case ENCODER_H265_PROP_MAX_BFRAMES:
3652       g_value_set_uint (value, encoder->num_bframes);
3653       break;
3654     case ENCODER_H265_PROP_INIT_QP:
3655       g_value_set_uint (value, encoder->init_qp);
3656       break;
3657     case ENCODER_H265_PROP_MIN_QP:
3658       g_value_set_uint (value, encoder->min_qp);
3659       break;
3660     case ENCODER_H265_PROP_QP_IP:
3661       g_value_set_int (value, encoder->qp_ip);
3662       break;
3663     case ENCODER_H265_PROP_QP_IB:
3664       g_value_set_int (value, encoder->qp_ib);
3665       break;
3666     case ENCODER_H265_PROP_NUM_SLICES:
3667       g_value_set_uint (value, encoder->num_slices);
3668       break;
3669     case ENCODER_H265_PROP_CPB_LENGTH:
3670       g_value_set_uint (value, encoder->cpb_length);
3671       break;
3672     case ENCODER_H265_PROP_NUM_REF_FRAMES:
3673       g_value_set_uint (value, encoder->num_ref_frames);
3674       break;
3675     case ENCODER_H265_PROP_MBBRC:
3676       g_value_set_enum (value, encoder->mbbrc);
3677       break;
3678 #ifndef GST_REMOVE_DEPRECATED
3679     case ENCODER_H265_PROP_LOW_DELAY_B:
3680       g_value_set_boolean (value, encoder->no_p_frame);
3681       break;
3682 #endif
3683     case ENCODER_H265_PROP_MAX_QP:
3684       g_value_set_uint (value, encoder->max_qp);
3685       break;
3686     case ENCODER_H265_PROP_QUALITY_FACTOR:
3687       g_value_set_uint (value, encoder->quality_factor);
3688       break;
3689     case ENCODER_H265_PROP_NUM_TILE_COLS:
3690       g_value_set_uint (value, encoder->num_tile_cols);
3691       break;
3692     case ENCODER_H265_PROP_NUM_TILE_ROWS:
3693       g_value_set_uint (value, encoder->num_tile_rows);
3694       break;
3695     default:
3696       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3697   }
3698 }
3699
3700 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H265);
3701
3702 static void
3703 gst_vaapi_encoder_h265_class_init (GstVaapiEncoderH265Class * klass)
3704 {
3705   GObjectClass *const object_class = G_OBJECT_CLASS (klass);
3706   GstVaapiEncoderClass *const encoder_class = GST_VAAPI_ENCODER_CLASS (klass);
3707
3708   encoder_class->class_data = &g_class_data;
3709   encoder_class->reconfigure = gst_vaapi_encoder_h265_reconfigure;
3710   encoder_class->reordering = gst_vaapi_encoder_h265_reordering;
3711   encoder_class->encode = gst_vaapi_encoder_h265_encode;
3712   encoder_class->flush = gst_vaapi_encoder_h265_flush;
3713   encoder_class->get_codec_data = gst_vaapi_encoder_h265_get_codec_data;
3714   encoder_class->get_pending_reordered =
3715       gst_vaapi_encoder_h265_get_pending_reordered;
3716
3717   object_class->set_property = gst_vaapi_encoder_h265_set_property;
3718   object_class->get_property = gst_vaapi_encoder_h265_get_property;
3719   object_class->finalize = gst_vaapi_encoder_h265_finalize;
3720
3721   /**
3722    * GstVaapiEncoderH265:rate-control:
3723    *
3724    * The desired rate control mode, expressed as a #GstVaapiRateControl.
3725    */
3726   properties[ENCODER_H265_PROP_RATECONTROL] =
3727       g_param_spec_enum ("rate-control",
3728       "Rate Control", "Rate control mode",
3729       g_class_data.rate_control_get_type (),
3730       g_class_data.default_rate_control,
3731       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3732       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3733
3734   /**
3735    * GstVaapiEncoderH265:tune:
3736    *
3737    * The desired encoder tuning option.
3738    */
3739   properties[ENCODER_H265_PROP_TUNE] =
3740       g_param_spec_enum ("tune",
3741       "Encoder Tuning",
3742       "Encoder tuning option",
3743       g_class_data.encoder_tune_get_type (),
3744       g_class_data.default_encoder_tune,
3745       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3746       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3747
3748   /**
3749    * GstVaapiEncoderH265:max-bframes:
3750    *
3751    * The number of B-frames between I and P.
3752    */
3753   properties[ENCODER_H265_PROP_MAX_BFRAMES] =
3754       g_param_spec_uint ("max-bframes",
3755       "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
3756       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3757       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3758
3759   /**
3760    * GstVaapiEncoderH265:refs:
3761    *
3762    * The number of reference frames.
3763    * If B frame is encoded, it will add 1 reference frame more.
3764    */
3765   properties[ENCODER_H265_PROP_NUM_REF_FRAMES] =
3766       g_param_spec_uint ("refs",
3767       "Number of Reference Frames", "Number of reference frames", 1, 3, 1,
3768       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3769       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3770
3771   /**
3772    * GstVaapiEncoderH265:init-qp:
3773    *
3774    * The initial quantizer value.
3775    */
3776   properties[ENCODER_H265_PROP_INIT_QP] =
3777       g_param_spec_uint ("init-qp",
3778       "Initial QP", "Initial quantizer value", 0, 51, 26,
3779       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3780       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3781
3782   /**
3783    * GstVaapiEncoderH265:min-qp:
3784    *
3785    * The minimum quantizer value.
3786    */
3787   properties[ENCODER_H265_PROP_MIN_QP] =
3788       g_param_spec_uint ("min-qp",
3789       "Minimum QP", "Minimum quantizer value", 0, 51, 1,
3790       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3791       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3792
3793   /**
3794    * GstVaapiEncoderH265:max-qp:
3795    *
3796    * The maximum quantizer value.
3797    *
3798    * Since: 1.18
3799    */
3800   properties[ENCODER_H265_PROP_MAX_QP] =
3801       g_param_spec_uint ("max-qp",
3802       "Maximum QP", "Maximum quantizer value", 0, 51, 51,
3803       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3804       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3805
3806   /**
3807    * GstVaapiEncoderH265:qp-ip:
3808    *
3809    * The difference of QP between I and P Frame.
3810    * This is available only on CQP mode.
3811    */
3812   properties[ENCODER_H265_PROP_QP_IP] =
3813       g_param_spec_int ("qp-ip",
3814       "Difference of QP between I and P frame",
3815       "Difference of QP between I and P frame (available only on CQP)",
3816       -51, 51, 0,
3817       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3818       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3819
3820   /**
3821    * GstVaapiEncoderH265:qp-ib:
3822    *
3823    * The difference of QP between I and B Frame.
3824    * This is available only on CQP mode.
3825    */
3826   properties[ENCODER_H265_PROP_QP_IB] =
3827       g_param_spec_int ("qp-ib",
3828       "Difference of QP between I and B frame",
3829       "Difference of QP between I and B frame (available only on CQP)",
3830       -51, 51, 0,
3831       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3832       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3833
3834   /* FIXME: there seems to be issues with multi-slice encoding */
3835   /**
3836    * GstVaapiEncoderH265:num-slices:
3837    *
3838    * The number of slices per frame.
3839    */
3840   properties[ENCODER_H265_PROP_NUM_SLICES] =
3841       g_param_spec_uint ("num-slices",
3842       "Number of Slices",
3843       "Number of slices per frame",
3844       1, 200, 1,
3845       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3846       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3847
3848   /**
3849    * GstVaapiEncoderH265:cpb-length:
3850    *
3851    * The size of the CPB buffer in milliseconds.
3852    */
3853   properties[ENCODER_H265_PROP_CPB_LENGTH] =
3854       g_param_spec_uint ("cpb-length",
3855       "CPB Length", "Length of the CPB buffer in milliseconds",
3856       1, 10000, DEFAULT_CPB_LENGTH,
3857       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3858       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3859
3860   /**
3861    * GstVaapiEncoderH265:mbbrc:
3862    *
3863    * Macroblock level bitrate control.
3864    * This is not compatible with Constant QP rate control.
3865    */
3866   properties[ENCODER_H265_PROP_MBBRC] =
3867       g_param_spec_enum ("mbbrc",
3868       "Macroblock level Bitrate Control",
3869       "Macroblock level Bitrate Control",
3870       GST_VAAPI_TYPE_ENCODER_MBBRC, GST_VAAPI_ENCODER_MBBRC_AUTO,
3871       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3872       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3873
3874 #ifndef GST_REMOVE_DEPRECATED
3875   /**
3876    * GstVaapiEncoderH265:low_delay_b:
3877    *
3878    * Enable low delay b frame, which will change P frame with B frame.
3879    */
3880   properties[ENCODER_H265_PROP_LOW_DELAY_B] =
3881       g_param_spec_boolean ("low-delay-b",
3882       "Enable low delay b",
3883       "Transforms P frames into predictive B frames."
3884       " Enable it when P frames are not supported.",
3885       FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3886       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3887 #endif
3888
3889   /**
3890    * GstVaapiEncoderH265:quality_factor:
3891    *
3892    * Quality factor used with ICQ/QVBR bitrate control mode.
3893    */
3894   properties[ENCODER_H265_PROP_QUALITY_FACTOR] =
3895       g_param_spec_uint ("quality-factor",
3896       "Quality factor for ICQ/QVBR",
3897       "quality factor for ICQ/QBVR bitrate control mode"
3898       " (lower value means higher quality, higher value means lower quality)",
3899       1, 51, 26,
3900       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3901       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3902
3903   /**
3904    * GstVaapiEncoderH265:num-tile-cols:
3905    *
3906    * The number of tile columns when tile encoding is enabled.
3907    */
3908   properties[ENCODER_H265_PROP_NUM_TILE_COLS] =
3909       g_param_spec_uint ("num-tile-cols",
3910       "number of tile columns",
3911       "the number of columns for tile encoding", 1,
3912       GST_VAAPI_H265_MAX_COL_TILES, 1,
3913       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3914       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3915
3916   /**
3917    * GstVaapiEncoderH265:num-tile-rows:
3918    *
3919    * The number of tile rows when tile encoding is enabled.
3920    */
3921   properties[ENCODER_H265_PROP_NUM_TILE_ROWS] =
3922       g_param_spec_uint ("num-tile-rows",
3923       "number of tile rows",
3924       "the number of rows for tile encoding", 1,
3925       GST_VAAPI_H265_MAX_ROW_TILES, 1,
3926       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
3927       GST_VAAPI_PARAM_ENCODER_EXPOSURE);
3928
3929   g_object_class_install_properties (object_class, ENCODER_H265_N_PROPERTIES,
3930       properties);
3931
3932   gst_type_mark_as_plugin_api (g_class_data.rate_control_get_type (), 0);
3933   gst_type_mark_as_plugin_api (g_class_data.encoder_tune_get_type (), 0);
3934 }
3935
3936 /**
3937  * gst_vaapi_encoder_h265_new:
3938  * @display: a #GstVaapiDisplay
3939  *
3940  * Creates a new #GstVaapiEncoder for H.265 encoding. Note that the
3941  * only supported output stream format is "byte-stream" format.
3942  *
3943  * Return value: the newly allocated #GstVaapiEncoder object
3944  */
3945 GstVaapiEncoder *
3946 gst_vaapi_encoder_h265_new (GstVaapiDisplay * display)
3947 {
3948   return g_object_new (GST_TYPE_VAAPI_ENCODER_H265, "display", display, NULL);
3949 }
3950
3951 /**
3952  * gst_vaapi_encoder_h265_set_allowed_profiles:
3953  * @encoder: a #GstVaapiEncoderH265
3954  * @profiles: a #GArray of all allowed #GstVaapiProfile.
3955  *
3956  * Set the all allowed profiles for the encoder.
3957  *
3958  * Return value: %TRUE on success
3959  */
3960 gboolean
3961 gst_vaapi_encoder_h265_set_allowed_profiles (GstVaapiEncoderH265 * encoder,
3962     GArray * profiles)
3963 {
3964   g_return_val_if_fail (encoder != NULL, FALSE);
3965   g_return_val_if_fail (profiles, FALSE);
3966
3967   encoder->allowed_profiles = g_array_ref (profiles);
3968   return TRUE;
3969 }
3970
3971 /**
3972  * gst_vaapi_encoder_h265_get_profile_tier_level:
3973  * @encoder: a #GstVaapiEncoderH265
3974  * @out_profile_ptr: return location for the #GstVaapiProfile
3975  * @out_level_ptr: return location for the #GstVaapiLevelH265
3976  * @out_tier_ptr: return location for the #GstVaapiTierH265
3977  *
3978  * Queries the H.265 @encoder for the active profile and level. That
3979  * information is only constructed and valid after the encoder is
3980  * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
3981  * function is called.
3982  *
3983  * Return value: %TRUE on success
3984  */
3985 gboolean
3986 gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder,
3987     GstVaapiProfile * out_profile_ptr, GstVaapiTierH265 * out_tier_ptr,
3988     GstVaapiLevelH265 * out_level_ptr)
3989 {
3990   g_return_val_if_fail (encoder != NULL, FALSE);
3991
3992   if (!encoder->profile || encoder->tier == GST_VAAPI_TIER_H265_UNKNOWN
3993       || !encoder->level)
3994     return FALSE;
3995
3996   if (out_profile_ptr)
3997     *out_profile_ptr = encoder->profile;
3998   if (out_level_ptr)
3999     *out_level_ptr = encoder->level;
4000   if (out_tier_ptr)
4001     *out_tier_ptr = encoder->tier;
4002
4003   return TRUE;
4004 }