encoder: h264: fix level when bitrate is automatically computed.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapiencoder_h264.c
1 /*
2  *  gstvaapiencoder_h264.c - H.264 encoder
3  *
4  *  Copyright (C) 2012-2013 Intel Corporation
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public License
8  *  as published by the Free Software Foundation; either version 2.1
9  *  of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free
18  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301 USA
20  */
21
22 #include "sysdeps.h"
23 #include <va/va.h>
24 #include <va/va_enc_h264.h>
25 #include <gst/base/gstbitwriter.h>
26 #include "gstvaapicompat.h"
27 #include "gstvaapiencoder_priv.h"
28 #include "gstvaapiencoder_h264.h"
29 #include "gstvaapiutils_h264.h"
30 #include "gstvaapiutils_h264_priv.h"
31 #include "gstvaapicodedbufferproxy_priv.h"
32 #include "gstvaapisurface.h"
33
34 #define DEBUG 1
35 #include "gstvaapidebug.h"
36
37 /* Define the maximum IDR period */
38 #define MAX_IDR_PERIOD 512
39
40 /* Define default rate control mode ("constant-qp") */
41 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
42
43 /* Supported set of VA rate controls, within this implementation */
44 #define SUPPORTED_RATECONTROLS                          \
45   (GST_VAAPI_RATECONTROL_MASK (NONE) |                  \
46    GST_VAAPI_RATECONTROL_MASK (CQP)  |                  \
47    GST_VAAPI_RATECONTROL_MASK (CBR)  |                  \
48    GST_VAAPI_RATECONTROL_MASK (VBR)  |                  \
49    GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
50
51 /* Supported set of tuning options, within this implementation */
52 #define SUPPORTED_TUNE_OPTIONS                          \
53   (GST_VAAPI_ENCODER_TUNE_MASK (NONE) |                 \
54    GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION))
55
56 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE        0
57 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW         1
58 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM      2
59 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH        3
60
61 typedef enum
62 {
63   GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0,
64   GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1,
65   GST_VAAPI_ENCODER_H264_NAL_IDR = 5,   /* ref_idc != 0 */
66   GST_VAAPI_ENCODER_H264_NAL_SEI = 6,   /* ref_idc == 0 */
67   GST_VAAPI_ENCODER_H264_NAL_SPS = 7,
68   GST_VAAPI_ENCODER_H264_NAL_PPS = 8
69 } GstVaapiEncoderH264NalType;
70
71 typedef struct
72 {
73   GstVaapiSurfaceProxy *pic;
74   guint poc;
75   guint frame_num;
76 } GstVaapiEncoderH264Ref;
77
78 typedef enum
79 {
80   GST_VAAPI_ENC_H264_REORD_NONE = 0,
81   GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
82   GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
83 } GstVaapiEncH264ReorderState;
84
85 static inline gboolean
86 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
87 {
88   return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
89 }
90
91 /* Get slice_type value for H.264 specification */
92 static guint8
93 h264_get_slice_type (GstVaapiPictureType type)
94 {
95   switch (type) {
96     case GST_VAAPI_PICTURE_TYPE_I:
97       return 2;
98     case GST_VAAPI_PICTURE_TYPE_P:
99       return 0;
100     case GST_VAAPI_PICTURE_TYPE_B:
101       return 1;
102     default:
103       return -1;
104   }
105   return -1;
106 }
107
108 /* Get log2_max_frame_num value for H.264 specification */
109 static guint
110 h264_get_log2_max_frame_num (guint num)
111 {
112   guint ret = 0;
113
114   while (num) {
115     ++ret;
116     num >>= 1;
117   }
118   if (ret <= 4)
119     ret = 4;
120   else if (ret > 10)
121     ret = 10;
122   /* must be greater than 4 */
123   return ret;
124 }
125
126 /* ------------------------------------------------------------------------- */
127 /* --- H.264 Bitstream Writer                                            --- */
128 /* ------------------------------------------------------------------------- */
129
130 #define WRITE_UINT32(bs, val, nbits) do {                       \
131     if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) {     \
132       GST_WARNING ("failed to write uint32, nbits: %d", nbits); \
133       goto bs_error;                                            \
134     }                                                           \
135   } while (0)
136
137 #define WRITE_UE(bs, val) do {                  \
138     if (!bs_write_ue (bs, val)) {               \
139       GST_WARNING ("failed to write ue(v)");    \
140       goto bs_error;                            \
141     }                                           \
142   } while (0)
143
144 #define WRITE_SE(bs, val) do {                  \
145     if (!bs_write_se (bs, val)) {               \
146       GST_WARNING ("failed to write se(v)");    \
147       goto bs_error;                            \
148     }                                           \
149   } while (0)
150
151 /* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */
152 static gboolean
153 bs_write_ue (GstBitWriter * bs, guint32 value)
154 {
155   guint32 size_in_bits = 0;
156   guint32 tmp_value = ++value;
157
158   while (tmp_value) {
159     ++size_in_bits;
160     tmp_value >>= 1;
161   }
162   if (size_in_bits > 1
163       && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1))
164     return FALSE;
165   if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits))
166     return FALSE;
167   return TRUE;
168 }
169
170 /* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */
171 static gboolean
172 bs_write_se (GstBitWriter * bs, gint32 value)
173 {
174   guint32 new_val;
175
176   if (value <= 0)
177     new_val = -(value << 1);
178   else
179     new_val = (value << 1) - 1;
180
181   if (!bs_write_ue (bs, new_val))
182     return FALSE;
183   return TRUE;
184 }
185
186 /* Write the NAL unit header */
187 static gboolean
188 bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc,
189     guint32 nal_unit_type)
190 {
191   WRITE_UINT32 (bs, 0, 1);
192   WRITE_UINT32 (bs, nal_ref_idc, 2);
193   WRITE_UINT32 (bs, nal_unit_type, 5);
194   return TRUE;
195
196   /* ERRORS */
197 bs_error:
198   {
199     GST_WARNING ("failed to write NAL unit header");
200     return FALSE;
201   }
202 }
203
204 /* Write the NAL unit trailing bits */
205 static gboolean
206 bs_write_trailing_bits (GstBitWriter * bs)
207 {
208   if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
209     goto bs_error;
210   gst_bit_writer_align_bytes_unchecked (bs, 0);
211   return TRUE;
212
213   /* ERRORS */
214 bs_error:
215   {
216     GST_WARNING ("failed to write NAL unit trailing bits");
217     return FALSE;
218   }
219 }
220
221 /* Write an SPS NAL unit */
222 static gboolean
223 bs_write_sps (GstBitWriter * bs,
224     const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile)
225 {
226   guint8 profile_idc;
227   guint32 constraint_set0_flag, constraint_set1_flag;
228   guint32 constraint_set2_flag, constraint_set3_flag;
229   guint32 gaps_in_frame_num_value_allowed_flag = 0;     // ??
230   gboolean nal_hrd_parameters_present_flag;
231
232   guint32 b_qpprime_y_zero_transform_bypass = 0;
233   guint32 residual_color_transform_flag = 0;
234   guint32 pic_height_in_map_units =
235       (seq_param->seq_fields.bits.frame_mbs_only_flag ?
236       seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
237   guint32 mb_adaptive_frame_field =
238       !seq_param->seq_fields.bits.frame_mbs_only_flag;
239   guint32 i = 0;
240
241   profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
242   constraint_set0_flag =        /* A.2.1 (baseline profile constraints) */
243       profile == GST_VAAPI_PROFILE_H264_BASELINE ||
244       profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
245   constraint_set1_flag =        /* A.2.2 (main profile constraints) */
246       profile == GST_VAAPI_PROFILE_H264_MAIN ||
247       profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
248   constraint_set2_flag = 0;
249   constraint_set3_flag = 0;
250
251   /* profile_idc */
252   WRITE_UINT32 (bs, profile_idc, 8);
253   /* constraint_set0_flag */
254   WRITE_UINT32 (bs, constraint_set0_flag, 1);
255   /* constraint_set1_flag */
256   WRITE_UINT32 (bs, constraint_set1_flag, 1);
257   /* constraint_set2_flag */
258   WRITE_UINT32 (bs, constraint_set2_flag, 1);
259   /* constraint_set3_flag */
260   WRITE_UINT32 (bs, constraint_set3_flag, 1);
261   /* reserved_zero_4bits */
262   WRITE_UINT32 (bs, 0, 4);
263   /* level_idc */
264   WRITE_UINT32 (bs, seq_param->level_idc, 8);
265   /* seq_parameter_set_id */
266   WRITE_UE (bs, seq_param->seq_parameter_set_id);
267
268   if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
269     /* for high profile */
270     /* chroma_format_idc  = 1, 4:2:0 */
271     WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
272     if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
273       WRITE_UINT32 (bs, residual_color_transform_flag, 1);
274     }
275     /* bit_depth_luma_minus8 */
276     WRITE_UE (bs, seq_param->bit_depth_luma_minus8);
277     /* bit_depth_chroma_minus8 */
278     WRITE_UE (bs, seq_param->bit_depth_chroma_minus8);
279     /* b_qpprime_y_zero_transform_bypass */
280     WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1);
281
282     /* seq_scaling_matrix_present_flag  */
283     g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
284     WRITE_UINT32 (bs,
285         seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
286
287 #if 0
288     if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
289       for (i = 0;
290           i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
291           i++) {
292         gst_bit_writer_put_bits_uint8 (bs,
293             seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
294         if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
295           g_assert (0);
296           /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
297         }
298       }
299     }
300 #endif
301   }
302
303   /* log2_max_frame_num_minus4 */
304   WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4);
305   /* pic_order_cnt_type */
306   WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type);
307
308   if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
309     /* log2_max_pic_order_cnt_lsb_minus4 */
310     WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
311   } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
312     g_assert (0 && "only POC type 0 is supported");
313     WRITE_UINT32 (bs,
314         seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
315     WRITE_SE (bs, seq_param->offset_for_non_ref_pic);
316     WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field);
317     WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle);
318     for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
319       WRITE_SE (bs, seq_param->offset_for_ref_frame[i]);
320     }
321   }
322
323   /* num_ref_frames */
324   WRITE_UE (bs, seq_param->max_num_ref_frames);
325   /* gaps_in_frame_num_value_allowed_flag */
326   WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1);
327
328   /* pic_width_in_mbs_minus1 */
329   WRITE_UE (bs, seq_param->picture_width_in_mbs - 1);
330   /* pic_height_in_map_units_minus1 */
331   WRITE_UE (bs, pic_height_in_map_units - 1);
332   /* frame_mbs_only_flag */
333   WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
334
335   if (!seq_param->seq_fields.bits.frame_mbs_only_flag) {        //ONLY mbs
336     g_assert (0 && "only progressive frames encoding is supported");
337     WRITE_UINT32 (bs, mb_adaptive_frame_field, 1);
338   }
339
340   /* direct_8x8_inference_flag */
341   WRITE_UINT32 (bs, 0, 1);
342   /* frame_cropping_flag */
343   WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1);
344
345   if (seq_param->frame_cropping_flag) {
346     /* frame_crop_left_offset */
347     WRITE_UE (bs, seq_param->frame_crop_left_offset);
348     /* frame_crop_right_offset */
349     WRITE_UE (bs, seq_param->frame_crop_right_offset);
350     /* frame_crop_top_offset */
351     WRITE_UE (bs, seq_param->frame_crop_top_offset);
352     /* frame_crop_bottom_offset */
353     WRITE_UE (bs, seq_param->frame_crop_bottom_offset);
354   }
355
356   /* vui_parameters_present_flag */
357   WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
358   if (seq_param->vui_parameters_present_flag) {
359     /* aspect_ratio_info_present_flag */
360     WRITE_UINT32 (bs,
361         seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
362     if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
363       WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
364       if (seq_param->aspect_ratio_idc == 0xFF) {
365         WRITE_UINT32 (bs, seq_param->sar_width, 16);
366         WRITE_UINT32 (bs, seq_param->sar_height, 16);
367       }
368     }
369
370     /* overscan_info_present_flag */
371     WRITE_UINT32 (bs, 0, 1);
372     /* video_signal_type_present_flag */
373     WRITE_UINT32 (bs, 0, 1);
374     /* chroma_loc_info_present_flag */
375     WRITE_UINT32 (bs, 0, 1);
376
377     /* timing_info_present_flag */
378     WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1);
379     if (seq_param->vui_fields.bits.timing_info_present_flag) {
380       WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32);
381       WRITE_UINT32 (bs, seq_param->time_scale, 32);
382       WRITE_UINT32 (bs, 1, 1);  /* fixed_frame_rate_flag */
383     }
384
385     nal_hrd_parameters_present_flag =
386         (seq_param->bits_per_second > 0 ? TRUE : FALSE);
387     /* nal_hrd_parameters_present_flag */
388     WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
389     if (nal_hrd_parameters_present_flag) {
390       /* hrd_parameters */
391       /* cpb_cnt_minus1 */
392       WRITE_UE (bs, 0);
393       WRITE_UINT32 (bs, 4, 4);  /* bit_rate_scale */
394       WRITE_UINT32 (bs, 6, 4);  /* cpb_size_scale */
395
396       for (i = 0; i < 1; ++i) {
397         /* bit_rate_value_minus1[0] */
398         WRITE_UE (bs, seq_param->bits_per_second / 1000 - 1);
399         /* cpb_size_value_minus1[0] */
400         WRITE_UE (bs, seq_param->bits_per_second / 1000 * 8 - 1);
401         /* cbr_flag[0] */
402         WRITE_UINT32 (bs, 1, 1);
403       }
404       /* initial_cpb_removal_delay_length_minus1 */
405       WRITE_UINT32 (bs, 23, 5);
406       /* cpb_removal_delay_length_minus1 */
407       WRITE_UINT32 (bs, 23, 5);
408       /* dpb_output_delay_length_minus1 */
409       WRITE_UINT32 (bs, 23, 5);
410       /* time_offset_length  */
411       WRITE_UINT32 (bs, 23, 5);
412     }
413     /* vcl_hrd_parameters_present_flag */
414     WRITE_UINT32 (bs, 0, 1);
415     if (nal_hrd_parameters_present_flag
416         || 0 /*vcl_hrd_parameters_present_flag */ ) {
417       /* low_delay_hrd_flag */
418       WRITE_UINT32 (bs, 0, 1);
419     }
420     /* pic_struct_present_flag */
421     WRITE_UINT32 (bs, 0, 1);
422     /* bs_restriction_flag */
423     WRITE_UINT32 (bs, 0, 1);
424   }
425
426   /* rbsp_trailing_bits */
427   bs_write_trailing_bits (bs);
428   return TRUE;
429
430   /* ERRORS */
431 bs_error:
432   {
433     GST_WARNING ("failed to write SPS NAL unit");
434     return FALSE;
435   }
436 }
437
438 /* Write a PPS NAL unit */
439 static gboolean
440 bs_write_pps (GstBitWriter * bs,
441     const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
442 {
443   guint32 num_slice_groups_minus1 = 0;
444   guint32 pic_init_qs_minus26 = 0;
445   guint32 redundant_pic_cnt_present_flag = 0;
446
447   /* pic_parameter_set_id */
448   WRITE_UE (bs, pic_param->pic_parameter_set_id);
449   /* seq_parameter_set_id */
450   WRITE_UE (bs, pic_param->seq_parameter_set_id);
451   /* entropy_coding_mode_flag */
452   WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
453   /* pic_order_present_flag */
454   WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1);
455   /* slice_groups-1 */
456   WRITE_UE (bs, num_slice_groups_minus1);
457
458   if (num_slice_groups_minus1 > 0) {
459      /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)");
460   }
461   WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1);
462   WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1);
463   WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
464   WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);
465   /* pic_init_qp_minus26 */
466   WRITE_SE (bs, pic_param->pic_init_qp - 26);
467   /* pic_init_qs_minus26 */
468   WRITE_SE (bs, pic_init_qs_minus26);
469   /* chroma_qp_index_offset */
470   WRITE_SE (bs, pic_param->chroma_qp_index_offset);
471
472   WRITE_UINT32 (bs,
473       pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
474   WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
475   WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1);
476
477   /* more_rbsp_data */
478   if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
479     WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
480     WRITE_UINT32 (bs,
481         pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
482     if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
483       g_assert (0 && "unsupported scaling lists");
484       /* FIXME */
485       /*
486          for (i = 0; i <
487          (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
488          i++) {
489          gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
490          }
491        */
492     }
493     WRITE_SE (bs, pic_param->second_chroma_qp_index_offset);
494   }
495
496   /* rbsp_trailing_bits */
497   bs_write_trailing_bits (bs);
498   return TRUE;
499
500   /* ERRORS */
501 bs_error:
502   {
503     GST_WARNING ("failed to write PPS NAL unit");
504     return FALSE;
505   }
506 }
507
508 /* ------------------------------------------------------------------------- */
509 /* --- H.264 Encoder                                                     --- */
510 /* ------------------------------------------------------------------------- */
511
512 #define GST_VAAPI_ENCODER_H264_CAST(encoder) \
513     ((GstVaapiEncoderH264 *)(encoder))
514
515 struct _GstVaapiEncoderH264
516 {
517   GstVaapiEncoder parent_instance;
518
519   GstVaapiProfile profile;
520   GstVaapiLevelH264 level;
521   guint8 profile_idc;
522   guint8 max_profile_idc;
523   guint8 hw_max_profile_idc;
524   guint8 level_idc;
525   guint32 idr_period;
526   guint32 init_qp;
527   guint32 min_qp;
528   guint32 num_slices;
529   guint32 num_bframes;
530   guint32 mb_width;
531   guint32 mb_height;
532   gboolean use_cabac;
533   gboolean use_dct8x8;
534
535   /* re-ordering */
536   GQueue reorder_frame_list;
537   guint reorder_state;
538   guint frame_index;
539   guint cur_frame_num;
540   guint cur_present_index;
541   GstClockTime cts_offset;
542
543   /* reference list */
544   GQueue ref_list;
545   guint max_ref_frames;
546   /* max reflist count */
547   guint max_reflist0_count;
548   guint max_reflist1_count;
549
550   /* frame, poc */
551   guint32 max_frame_num;
552   guint32 log2_max_frame_num;
553   guint32 max_pic_order_cnt;
554   guint32 log2_max_pic_order_cnt;
555   guint32 idr_num;
556
557   GstBuffer *sps_data;
558   GstBuffer *pps_data;
559 };
560
561 static inline void
562 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
563     const guint8 * nal, guint32 size)
564 {
565   guint8 nal_type;
566   gsize ret;
567
568   g_assert (size);
569
570   if (encoder->sps_data && encoder->pps_data)
571     return;
572
573   nal_type = nal[0] & 0x1F;
574   switch (nal_type) {
575     case GST_VAAPI_ENCODER_H264_NAL_SPS:
576       encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
577       ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
578       g_assert (ret == size);
579       break;
580     case GST_VAAPI_ENCODER_H264_NAL_PPS:
581       encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
582       ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
583       g_assert (ret == size);
584       break;
585     default:
586       break;
587   }
588 }
589
590 /* Determines the largest supported profile by the underlying hardware */
591 static gboolean
592 ensure_hw_profile_limits (GstVaapiEncoderH264 * encoder)
593 {
594   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
595   GArray *profiles;
596   guint i, profile_idc, max_profile_idc;
597
598   if (encoder->hw_max_profile_idc)
599     return TRUE;
600
601   profiles = gst_vaapi_display_get_encode_profiles (display);
602   if (!profiles)
603     return FALSE;
604
605   max_profile_idc = 0;
606   for (i = 0; i < profiles->len; i++) {
607     const GstVaapiProfile profile =
608         g_array_index (profiles, GstVaapiProfile, i);
609     profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
610     if (!profile_idc)
611       continue;
612     if (max_profile_idc < profile_idc)
613       max_profile_idc = profile_idc;
614   }
615   g_array_unref (profiles);
616
617   encoder->hw_max_profile_idc = max_profile_idc;
618   return TRUE;
619 }
620
621 /* Derives the profile supported by the underlying hardware */
622 static gboolean
623 ensure_hw_profile (GstVaapiEncoderH264 * encoder)
624 {
625   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
626   GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
627   GstVaapiProfile profile, profiles[4];
628   guint i, num_profiles = 0;
629
630   profiles[num_profiles++] = encoder->profile;
631   switch (encoder->profile) {
632     case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
633       profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
634       profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
635       // fall-through
636     case GST_VAAPI_PROFILE_H264_MAIN:
637       profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
638       break;
639     default:
640       break;
641   }
642
643   profile = GST_VAAPI_PROFILE_UNKNOWN;
644   for (i = 0; i < num_profiles; i++) {
645     if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
646       profile = profiles[i];
647       break;
648     }
649   }
650   if (profile == GST_VAAPI_PROFILE_UNKNOWN)
651     goto error_unsupported_profile;
652
653   GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
654   return TRUE;
655
656   /* ERRORS */
657 error_unsupported_profile:
658   {
659     GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
660     return FALSE;
661   }
662 }
663
664 /* Check target decoder constraints */
665 static gboolean
666 ensure_profile_limits (GstVaapiEncoderH264 * encoder)
667 {
668   GstVaapiProfile profile;
669
670   if (!encoder->max_profile_idc
671       || encoder->profile_idc <= encoder->max_profile_idc)
672     return TRUE;
673
674   GST_WARNING ("lowering coding tools to meet target decoder constraints");
675
676   /* Try Main profile coding tools */
677   if (encoder->max_profile_idc < 100) {
678     encoder->use_dct8x8 = FALSE;
679     profile = GST_VAAPI_PROFILE_H264_MAIN;
680   }
681
682   /* Try Constrained Baseline profile coding tools */
683   if (encoder->max_profile_idc < 77) {
684     encoder->num_bframes = 0;
685     encoder->use_cabac = FALSE;
686     profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
687   }
688
689   encoder->profile = profile;
690   encoder->profile_idc = encoder->max_profile_idc;
691   return TRUE;
692 }
693
694 /* Derives the minimum profile from the active coding tools */
695 static gboolean
696 ensure_profile (GstVaapiEncoderH264 * encoder)
697 {
698   GstVaapiProfile profile;
699
700   /* Always start from "constrained-baseline" profile for maximum
701      compatibility */
702   profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
703
704   /* Main profile coding tools */
705   if (encoder->num_bframes > 0 || encoder->use_cabac)
706     profile = GST_VAAPI_PROFILE_H264_MAIN;
707
708   /* High profile coding tools */
709   if (encoder->use_dct8x8)
710     profile = GST_VAAPI_PROFILE_H264_HIGH;
711
712   encoder->profile = profile;
713   encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
714   return TRUE;
715 }
716
717 /* Derives the level from the currently set limits */
718 static gboolean
719 ensure_level (GstVaapiEncoderH264 * encoder)
720 {
721   const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
722   const GstVaapiH264LevelLimits *limits_table;
723   guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
724
725   PicSizeMbs = encoder->mb_width * encoder->mb_height;
726   MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
727   MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
728       GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
729
730   limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
731   for (i = 0; i < num_limits; i++) {
732     const GstVaapiH264LevelLimits *const limits = &limits_table[i];
733     if (PicSizeMbs <= limits->MaxFS &&
734         MaxDpbMbs <= limits->MaxDpbMbs &&
735         MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR))
736       break;
737   }
738   if (i == num_limits)
739     goto error_unsupported_level;
740
741   encoder->level = limits_table[i].level;
742   encoder->level_idc = limits_table[i].level_idc;
743   return TRUE;
744
745   /* ERRORS */
746 error_unsupported_level:
747   {
748     GST_ERROR ("failed to find a suitable level matching codec config");
749     return FALSE;
750   }
751 }
752
753 /* Enable "high-compression" tuning options */
754 static gboolean
755 ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder)
756 {
757   guint8 profile_idc;
758
759   if (!ensure_hw_profile_limits (encoder))
760     return FALSE;
761
762   profile_idc = encoder->hw_max_profile_idc;
763   if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
764     profile_idc = encoder->max_profile_idc;
765
766   /* Tuning options to enable Main profile */
767   if (profile_idc >= 77) {
768     encoder->use_cabac = TRUE;
769     if (!encoder->num_bframes)
770       encoder->num_bframes = 1;
771   }
772
773   /* Tuning options to enable High profile */
774   if (profile_idc >= 100) {
775     encoder->use_dct8x8 = TRUE;
776   }
777   return TRUE;
778 }
779
780 /* Ensure tuning options */
781 static gboolean
782 ensure_tuning (GstVaapiEncoderH264 * encoder)
783 {
784   gboolean success;
785
786   switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
787     case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
788       success = ensure_tuning_high_compression (encoder);
789       break;
790     default:
791       success = TRUE;
792       break;
793   }
794   return success;
795 }
796
797 /* Handle new GOP starts */
798 static void
799 reset_gop_start (GstVaapiEncoderH264 * encoder)
800 {
801   ++encoder->idr_num;
802   encoder->frame_index = 1;
803   encoder->cur_frame_num = 0;
804   encoder->cur_present_index = 0;
805 }
806
807 /* Marks the supplied picture as a B-frame */
808 static void
809 set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
810 {
811   g_assert (pic && encoder);
812   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
813   pic->type = GST_VAAPI_PICTURE_TYPE_B;
814   pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
815 }
816
817 /* Marks the supplied picture as a P-frame */
818 static void
819 set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
820 {
821   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
822   pic->type = GST_VAAPI_PICTURE_TYPE_P;
823   pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
824 }
825
826 /* Marks the supplied picture as an I-frame */
827 static void
828 set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
829 {
830   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
831   pic->type = GST_VAAPI_PICTURE_TYPE_I;
832   pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
833
834   g_assert (pic->frame);
835   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
836 }
837
838 /* Marks the supplied picture as an IDR frame */
839 static void
840 set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
841 {
842   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
843   pic->type = GST_VAAPI_PICTURE_TYPE_I;
844   pic->frame_num = 0;
845   pic->poc = 0;
846   GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
847
848   g_assert (pic->frame);
849   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
850 }
851
852 /* Marks the supplied picture a a key-frame */
853 static void
854 set_key_frame (GstVaapiEncPicture * picture,
855     GstVaapiEncoderH264 * encoder, gboolean is_idr)
856 {
857   if (is_idr) {
858     reset_gop_start (encoder);
859     set_idr_frame (picture, encoder);
860   } else
861     set_i_frame (picture, encoder);
862 }
863
864 /* Fills in VA HRD parameters */
865 static void
866 fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd)
867 {
868   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
869
870   if (base_encoder->bitrate > 0) {
871     hrd->buffer_size = base_encoder->bitrate * 1000 * 8;
872     hrd->initial_buffer_fullness = hrd->buffer_size / 2;
873   } else {
874     hrd->buffer_size = 0;
875     hrd->initial_buffer_fullness = 0;
876   }
877 }
878
879 /* Adds the supplied sequence header (SPS) to the list of packed
880    headers to pass down as-is to the encoder */
881 static gboolean
882 add_packed_sequence_header (GstVaapiEncoderH264 * encoder,
883     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
884 {
885   GstVaapiEncPackedHeader *packed_seq;
886   GstBitWriter bs;
887   VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
888   const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
889   guint32 data_bit_size;
890   guint8 *data;
891
892   gst_bit_writer_init (&bs, 128 * 8);
893   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
894   bs_write_nal_header (&bs,
895       GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
896   bs_write_sps (&bs, seq_param, encoder->profile);
897   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
898   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
899   data = GST_BIT_WRITER_DATA (&bs);
900
901   packed_seq_param.type = VAEncPackedHeaderSequence;
902   packed_seq_param.bit_length = data_bit_size;
903   packed_seq_param.has_emulation_bytes = 0;
904
905   packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
906       &packed_seq_param, sizeof (packed_seq_param),
907       data, (data_bit_size + 7) / 8);
908   g_assert (packed_seq);
909
910   gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
911   gst_vaapi_codec_object_replace (&packed_seq, NULL);
912
913   /* store sps data */
914   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
915   gst_bit_writer_clear (&bs, TRUE);
916   return TRUE;
917
918   /* ERRORS */
919 bs_error:
920   {
921     GST_WARNING ("failed to write SPS NAL unit");
922     gst_bit_writer_clear (&bs, TRUE);
923     return FALSE;
924   }
925 }
926
927 /* Adds the supplied picture header (PPS) to the list of packed
928    headers to pass down as-is to the encoder */
929 static gboolean
930 add_packed_picture_header (GstVaapiEncoderH264 * encoder,
931     GstVaapiEncPicture * picture)
932 {
933   GstVaapiEncPackedHeader *packed_pic;
934   GstBitWriter bs;
935   VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
936   const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
937   guint32 data_bit_size;
938   guint8 *data;
939
940   gst_bit_writer_init (&bs, 128 * 8);
941   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
942   bs_write_nal_header (&bs,
943       GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
944   bs_write_pps (&bs, pic_param, encoder->profile);
945   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
946   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
947   data = GST_BIT_WRITER_DATA (&bs);
948
949   packed_pic_param.type = VAEncPackedHeaderPicture;
950   packed_pic_param.bit_length = data_bit_size;
951   packed_pic_param.has_emulation_bytes = 0;
952
953   packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
954       &packed_pic_param, sizeof (packed_pic_param),
955       data, (data_bit_size + 7) / 8);
956   g_assert (packed_pic);
957
958   gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
959   gst_vaapi_codec_object_replace (&packed_pic, NULL);
960
961   /* store pps data */
962   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
963   gst_bit_writer_clear (&bs, TRUE);
964   return TRUE;
965
966   /* ERRORS */
967 bs_error:
968   {
969     GST_WARNING ("failed to write PPS NAL unit");
970     gst_bit_writer_clear (&bs, TRUE);
971     return FALSE;
972   }
973 }
974
975 /* Reference picture management */
976 static void
977 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
978 {
979   if (!ref)
980     return;
981   if (ref->pic)
982     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
983   g_slice_free (GstVaapiEncoderH264Ref, ref);
984 }
985
986 static inline GstVaapiEncoderH264Ref *
987 reference_pic_create (GstVaapiEncoderH264 * encoder,
988     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
989 {
990   GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
991
992   ref->pic = surface;
993   ref->frame_num = picture->frame_num;
994   ref->poc = picture->poc;
995   return ref;
996 }
997
998 static gboolean
999 reference_list_update (GstVaapiEncoderH264 * encoder,
1000     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1001 {
1002   GstVaapiEncoderH264Ref *ref;
1003
1004   if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
1005     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
1006     return TRUE;
1007   }
1008   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
1009     while (!g_queue_is_empty (&encoder->ref_list))
1010       reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
1011   } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_frames) {
1012     reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
1013   }
1014   ref = reference_pic_create (encoder, picture, surface);
1015   g_queue_push_tail (&encoder->ref_list, ref);
1016   g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_frames);
1017   return TRUE;
1018 }
1019
1020 static gboolean
1021 reference_list_init (GstVaapiEncoderH264 * encoder,
1022     GstVaapiEncPicture * picture,
1023     GstVaapiEncoderH264Ref ** reflist_0,
1024     guint * reflist_0_count,
1025     GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
1026 {
1027   GstVaapiEncoderH264Ref *tmp;
1028   GList *iter, *list_0_start = NULL, *list_1_start = NULL;
1029   guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1030   guint count;
1031
1032   *reflist_0_count = 0;
1033   *reflist_1_count = 0;
1034   if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
1035     return TRUE;
1036
1037   iter = g_queue_peek_tail_link (&encoder->ref_list);
1038   for (; iter; iter = g_list_previous (iter)) {
1039     tmp = (GstVaapiEncoderH264Ref *) iter->data;
1040     g_assert (tmp && tmp->poc != picture->poc);
1041     if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
1042       list_0_start = iter;
1043       list_1_start = g_list_next (iter);
1044       break;
1045     }
1046   }
1047
1048   /* order reflist_0 */
1049   g_assert (list_0_start);
1050   iter = list_0_start;
1051   count = 0;
1052   for (; iter; iter = g_list_previous (iter)) {
1053     reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
1054     ++count;
1055   }
1056   *reflist_0_count = count;
1057
1058   if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1059     return TRUE;
1060
1061   /* order reflist_1 */
1062   count = 0;
1063   iter = list_1_start;
1064   for (; iter; iter = g_list_next (iter)) {
1065     reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
1066     ++count;
1067   }
1068   *reflist_1_count = count;
1069   return TRUE;
1070 }
1071
1072 /* Fills in VA sequence parameter buffer */
1073 static gboolean
1074 fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence)
1075 {
1076   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1077   VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1078
1079   memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
1080   seq_param->seq_parameter_set_id = 0;
1081   seq_param->level_idc = encoder->level_idc;
1082   seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
1083   seq_param->ip_period = 0;     // ?
1084   if (base_encoder->bitrate > 0)
1085     seq_param->bits_per_second = base_encoder->bitrate * 1000;
1086   else
1087     seq_param->bits_per_second = 0;
1088
1089   seq_param->max_num_ref_frames = encoder->max_ref_frames;
1090   seq_param->picture_width_in_mbs = encoder->mb_width;
1091   seq_param->picture_height_in_mbs = encoder->mb_height;
1092
1093   /*sequence field values */
1094   seq_param->seq_fields.value = 0;
1095   seq_param->seq_fields.bits.chroma_format_idc = 1;
1096   seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
1097   seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
1098   seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
1099   /* direct_8x8_inference_flag default false */
1100   seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
1101   g_assert (encoder->log2_max_frame_num >= 4);
1102   seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
1103       encoder->log2_max_frame_num - 4;
1104   /* picture order count */
1105   seq_param->seq_fields.bits.pic_order_cnt_type = 0;
1106   g_assert (encoder->log2_max_pic_order_cnt >= 4);
1107   seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
1108       encoder->log2_max_pic_order_cnt - 4;
1109
1110   seq_param->bit_depth_luma_minus8 = 0;
1111   seq_param->bit_depth_chroma_minus8 = 0;
1112
1113   /* not used if pic_order_cnt_type == 0 */
1114   if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
1115     seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
1116     seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
1117     seq_param->offset_for_non_ref_pic = 0;
1118     seq_param->offset_for_top_to_bottom_field = 0;
1119     memset (seq_param->offset_for_ref_frame, 0,
1120         sizeof (seq_param->offset_for_ref_frame));
1121   }
1122
1123   /* frame_cropping_flag */
1124   if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
1125       (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
1126     static const guint SubWidthC[] = { 1, 2, 2, 1 };
1127     static const guint SubHeightC[] = { 1, 2, 1, 1 };
1128     const guint CropUnitX =
1129         SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
1130     const guint CropUnitY =
1131         SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
1132         (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
1133
1134     seq_param->frame_cropping_flag = 1;
1135     seq_param->frame_crop_left_offset = 0;
1136     seq_param->frame_crop_right_offset =
1137         (16 * encoder->mb_width -
1138         GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX;
1139     seq_param->frame_crop_top_offset = 0;
1140     seq_param->frame_crop_bottom_offset =
1141         (16 * encoder->mb_height -
1142         GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY;
1143   }
1144
1145   /* VUI parameters are always set, at least for timing_info (framerate) */
1146   seq_param->vui_parameters_present_flag = TRUE;
1147   if (seq_param->vui_parameters_present_flag) {
1148     seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
1149     seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1150     seq_param->vui_fields.bits.timing_info_present_flag = TRUE;
1151     if (seq_param->vui_fields.bits.timing_info_present_flag) {
1152       seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1153       seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
1154     }
1155   }
1156   return TRUE;
1157 }
1158
1159 /* Fills in VA picture parameter buffer */
1160 static gboolean
1161 fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1162     GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1163 {
1164   VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1165   GstVaapiEncoderH264Ref *ref_pic;
1166   GList *reflist;
1167   guint i;
1168
1169   memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
1170
1171   /* reference list,  */
1172   pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1173   pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
1174   i = 0;
1175   if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1176     for (reflist = g_queue_peek_head_link (&encoder->ref_list);
1177         reflist; reflist = g_list_next (reflist)) {
1178       ref_pic = reflist->data;
1179       g_assert (ref_pic && ref_pic->pic &&
1180           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1181
1182       pic_param->ReferenceFrames[i].picture_id =
1183           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1184       ++i;
1185     }
1186     g_assert (i <= 16 && i <= encoder->max_ref_frames);
1187   }
1188   for (; i < 16; ++i) {
1189     pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
1190   }
1191   pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1192
1193   pic_param->pic_parameter_set_id = 0;
1194   pic_param->seq_parameter_set_id = 0;
1195   pic_param->last_picture = 0;  /* means last encoding picture */
1196   pic_param->frame_num = picture->frame_num;
1197   pic_param->pic_init_qp = encoder->init_qp;
1198   pic_param->num_ref_idx_l0_active_minus1 =
1199       (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
1200   pic_param->num_ref_idx_l1_active_minus1 =
1201       (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
1202   pic_param->chroma_qp_index_offset = 0;
1203   pic_param->second_chroma_qp_index_offset = 0;
1204
1205   /* set picture fields */
1206   pic_param->pic_fields.value = 0;
1207   pic_param->pic_fields.bits.idr_pic_flag =
1208       GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1209   pic_param->pic_fields.bits.reference_pic_flag =
1210       (picture->type != GST_VAAPI_PICTURE_TYPE_B);
1211   pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
1212   pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
1213   pic_param->pic_fields.bits.weighted_bipred_idc = 0;
1214   pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
1215   pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
1216   /* enable debloking */
1217   pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
1218   pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
1219   /* bottom_field_pic_order_in_frame_present_flag */
1220   pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
1221   pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
1222
1223   return TRUE;
1224 }
1225
1226 /* Adds slice headers to picture */
1227 static gboolean
1228 add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1229     GstVaapiEncoderH264Ref ** reflist_0, guint reflist_0_count,
1230     GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
1231 {
1232   VAEncSliceParameterBufferH264 *slice_param;
1233   GstVaapiEncSlice *slice;
1234   guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
1235   guint mb_size;
1236   guint last_mb_index;
1237   guint i_slice, i_ref;
1238
1239   g_assert (picture);
1240
1241   mb_size = encoder->mb_width * encoder->mb_height;
1242
1243   g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1244   slice_of_mbs = mb_size / encoder->num_slices;
1245   slice_mod_mbs = mb_size % encoder->num_slices;
1246   last_mb_index = 0;
1247   for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1248     cur_slice_mbs = slice_of_mbs;
1249     if (slice_mod_mbs) {
1250       ++cur_slice_mbs;
1251       --slice_mod_mbs;
1252     }
1253     slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1254     g_assert (slice && slice->param_id != VA_INVALID_ID);
1255     slice_param = slice->param;
1256
1257     memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1258     slice_param->macroblock_address = last_mb_index;
1259     slice_param->num_macroblocks = cur_slice_mbs;
1260     slice_param->macroblock_info = VA_INVALID_ID;
1261     slice_param->slice_type = h264_get_slice_type (picture->type);
1262     g_assert (slice_param->slice_type != -1);
1263     slice_param->pic_parameter_set_id = 0;
1264     slice_param->idr_pic_id = encoder->idr_num;
1265     slice_param->pic_order_cnt_lsb = picture->poc;
1266
1267     /* not used if pic_order_cnt_type = 0 */
1268     slice_param->delta_pic_order_cnt_bottom = 0;
1269     memset (slice_param->delta_pic_order_cnt, 0,
1270         sizeof (slice_param->delta_pic_order_cnt));
1271
1272     /* only works for B frames */
1273     slice_param->direct_spatial_mv_pred_flag = FALSE;
1274     /* default equal to picture parameters */
1275     slice_param->num_ref_idx_active_override_flag = FALSE;
1276     if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1277       slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1278     else
1279       slice_param->num_ref_idx_l0_active_minus1 = 0;
1280     if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1281       slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1282     else
1283       slice_param->num_ref_idx_l1_active_minus1 = 0;
1284     g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1285     g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1286
1287     i_ref = 0;
1288     if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1289       for (; i_ref < reflist_0_count; ++i_ref) {
1290         slice_param->RefPicList0[i_ref].picture_id =
1291             GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1292       }
1293       g_assert (i_ref == 1);
1294     }
1295     for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1296       slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1297     }
1298
1299     i_ref = 0;
1300     if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1301       for (; i_ref < reflist_1_count; ++i_ref) {
1302         slice_param->RefPicList1[i_ref].picture_id =
1303             GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1304       }
1305       g_assert (i_ref == 1);
1306     }
1307     for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1308       slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1309     }
1310
1311     /* not used if  pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1312     slice_param->luma_log2_weight_denom = 0;
1313     slice_param->chroma_log2_weight_denom = 0;
1314     slice_param->luma_weight_l0_flag = FALSE;
1315     memset (slice_param->luma_weight_l0, 0,
1316         sizeof (slice_param->luma_weight_l0));
1317     memset (slice_param->luma_offset_l0, 0,
1318         sizeof (slice_param->luma_offset_l0));
1319     slice_param->chroma_weight_l0_flag = FALSE;
1320     memset (slice_param->chroma_weight_l0, 0,
1321         sizeof (slice_param->chroma_weight_l0));
1322     memset (slice_param->chroma_offset_l0, 0,
1323         sizeof (slice_param->chroma_offset_l0));
1324     slice_param->luma_weight_l1_flag = FALSE;
1325     memset (slice_param->luma_weight_l1, 0,
1326         sizeof (slice_param->luma_weight_l1));
1327     memset (slice_param->luma_offset_l1, 0,
1328         sizeof (slice_param->luma_offset_l1));
1329     slice_param->chroma_weight_l1_flag = FALSE;
1330     memset (slice_param->chroma_weight_l1, 0,
1331         sizeof (slice_param->chroma_weight_l1));
1332     memset (slice_param->chroma_offset_l1, 0,
1333         sizeof (slice_param->chroma_offset_l1));
1334
1335     slice_param->cabac_init_idc = 0;
1336     slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1337     if (slice_param->slice_qp_delta > 4)
1338       slice_param->slice_qp_delta = 4;
1339     slice_param->disable_deblocking_filter_idc = 0;
1340     slice_param->slice_alpha_c0_offset_div2 = 2;
1341     slice_param->slice_beta_offset_div2 = 2;
1342
1343     /* set calculation for next slice */
1344     last_mb_index += cur_slice_mbs;
1345
1346     gst_vaapi_enc_picture_add_slice (picture, slice);
1347     gst_vaapi_codec_object_replace (&slice, NULL);
1348   }
1349   g_assert (last_mb_index == mb_size);
1350   return TRUE;
1351 }
1352
1353 /* Generates and submits SPS header accordingly into the bitstream */
1354 static gboolean
1355 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1356 {
1357   GstVaapiEncSequence *sequence;
1358
1359   g_assert (picture);
1360   sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1361   g_assert (sequence);
1362   if (!sequence)
1363     goto error;
1364
1365   if (!fill_sequence (encoder, sequence))
1366     goto error;
1367
1368   if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1369       !add_packed_sequence_header (encoder, picture, sequence))
1370     goto error;
1371   gst_vaapi_enc_picture_set_sequence (picture, sequence);
1372   gst_vaapi_codec_object_replace (&sequence, NULL);
1373   return TRUE;
1374
1375 error:
1376   gst_vaapi_codec_object_replace (&sequence, NULL);
1377   return FALSE;
1378 }
1379
1380 /* Generates additional control parameters */
1381 static gboolean
1382 ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1383 {
1384   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1385   GstVaapiEncMiscParam *misc = NULL;
1386   VAEncMiscParameterRateControl *rate_control;
1387
1388   /* HRD params */
1389   misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1390   g_assert (misc);
1391   if (!misc)
1392     return FALSE;
1393   fill_hrd_params (encoder, misc->data);
1394   gst_vaapi_enc_picture_add_misc_param (picture, misc);
1395   gst_vaapi_codec_object_replace (&misc, NULL);
1396
1397   /* RateControl params */
1398   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1399       GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1400     misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1401     g_assert (misc);
1402     if (!misc)
1403       return FALSE;
1404     rate_control = misc->data;
1405     memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1406     if (base_encoder->bitrate)
1407       rate_control->bits_per_second = base_encoder->bitrate * 1000;
1408     else
1409       rate_control->bits_per_second = 0;
1410     rate_control->target_percentage = 70;
1411     rate_control->window_size = 500;
1412     rate_control->initial_qp = encoder->init_qp;
1413     rate_control->min_qp = encoder->min_qp;
1414     rate_control->basic_unit_size = 0;
1415     gst_vaapi_enc_picture_add_misc_param (picture, misc);
1416     gst_vaapi_codec_object_replace (&misc, NULL);
1417   }
1418   return TRUE;
1419 }
1420
1421 /* Generates and submits PPS header accordingly into the bitstream */
1422 static gboolean
1423 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1424     GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1425 {
1426   GstVaapiCodedBuffer *const codedbuf =
1427       GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1428
1429   if (!fill_picture (encoder, picture, codedbuf, surface))
1430     return FALSE;
1431
1432   if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1433       !add_packed_picture_header (encoder, picture)) {
1434     GST_ERROR ("set picture packed header failed");
1435     return FALSE;
1436   }
1437   return TRUE;
1438 }
1439
1440 /* Generates slice headers */
1441 static gboolean
1442 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1443 {
1444   GstVaapiEncoderH264Ref *reflist_0[16];
1445   GstVaapiEncoderH264Ref *reflist_1[16];
1446   guint reflist_0_count = 0, reflist_1_count = 0;
1447
1448   g_assert (picture);
1449
1450   if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1451       !reference_list_init (encoder, picture,
1452           reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1453     GST_ERROR ("reference list reorder failed");
1454     return FALSE;
1455   }
1456
1457   g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_frames);
1458   if (reflist_0_count > encoder->max_reflist0_count)
1459     reflist_0_count = encoder->max_reflist0_count;
1460   if (reflist_1_count > encoder->max_reflist1_count)
1461     reflist_1_count = encoder->max_reflist1_count;
1462
1463   if (!add_slice_headers (encoder, picture,
1464           reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1465     return FALSE;
1466
1467   return TRUE;
1468 }
1469
1470 /* Estimates a good enough bitrate if none was supplied */
1471 static void
1472 ensure_bitrate (GstVaapiEncoderH264 * encoder)
1473 {
1474   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1475
1476   /* Default compression: 48 bits per macroblock in "high-compression" mode */
1477   switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1478     case GST_VAAPI_RATECONTROL_CBR:
1479     case GST_VAAPI_RATECONTROL_VBR:
1480     case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
1481       if (!base_encoder->bitrate) {
1482         /* According to the literature and testing, CABAC entropy coding
1483            mode could provide for +10% to +18% improvement in general,
1484            thus estimating +15% here ; and using adaptive 8x8 transforms
1485            in I-frames could bring up to +10% improvement. */
1486         guint bits_per_mb = 48;
1487         if (!encoder->use_cabac)
1488           bits_per_mb += (bits_per_mb * 15) / 100;
1489         if (!encoder->use_dct8x8)
1490           bits_per_mb += (bits_per_mb * 10) / 100;
1491
1492         base_encoder->bitrate =
1493             encoder->mb_width * encoder->mb_height * bits_per_mb *
1494             GST_VAAPI_ENCODER_FPS_N (encoder) /
1495             GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
1496         GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
1497       }
1498       break;
1499     default:
1500       base_encoder->bitrate = 0;
1501       break;
1502   }
1503 }
1504
1505 /* Constructs profile and level information based on user-defined limits */
1506 static GstVaapiEncoderStatus
1507 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
1508 {
1509   ensure_tuning (encoder);
1510
1511   if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
1512     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1513
1514   /* Check HW constraints */
1515   if (!ensure_hw_profile_limits (encoder))
1516     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1517   if (encoder->profile_idc > encoder->hw_max_profile_idc)
1518     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1519
1520   /* Ensure bitrate if not set already and derive the right level to use */
1521   ensure_bitrate (encoder);
1522   if (!ensure_level (encoder))
1523     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1524   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1525 }
1526
1527 static void
1528 reset_properties (GstVaapiEncoderH264 * encoder)
1529 {
1530   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1531   guint mb_size;
1532
1533   if (encoder->idr_period < base_encoder->keyframe_period)
1534     encoder->idr_period = base_encoder->keyframe_period;
1535   if (encoder->idr_period > MAX_IDR_PERIOD)
1536     encoder->idr_period = MAX_IDR_PERIOD;
1537
1538   if (encoder->min_qp > encoder->init_qp ||
1539       (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
1540           encoder->min_qp < encoder->init_qp))
1541     encoder->min_qp = encoder->init_qp;
1542
1543   mb_size = encoder->mb_width * encoder->mb_height;
1544   if (encoder->num_slices > (mb_size + 1) / 2)
1545     encoder->num_slices = (mb_size + 1) / 2;
1546   g_assert (encoder->num_slices);
1547
1548   if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
1549     encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
1550
1551   if (encoder->num_bframes)
1552     encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1553         GST_VAAPI_ENCODER_FPS_N (encoder);
1554   else
1555     encoder->cts_offset = 0;
1556
1557   /* init max_frame_num, max_poc */
1558   encoder->log2_max_frame_num =
1559       h264_get_log2_max_frame_num (encoder->idr_period);
1560   g_assert (encoder->log2_max_frame_num >= 4);
1561   encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1562   encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1563   encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1564
1565   encoder->frame_index = 0;
1566   encoder->idr_num = 0;
1567   encoder->max_reflist0_count = 1;
1568   encoder->max_reflist1_count = encoder->num_bframes > 0;
1569   encoder->max_ref_frames =
1570       encoder->max_reflist0_count + encoder->max_reflist1_count;
1571 }
1572
1573 static GstVaapiEncoderStatus
1574 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
1575     GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1576 {
1577   GstVaapiEncoderH264 *const encoder =
1578       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1579   GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1580   GstVaapiSurfaceProxy *reconstruct = NULL;
1581
1582   reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
1583
1584   g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1585
1586   if (!ensure_sequence (encoder, picture))
1587     goto error;
1588   if (!ensure_misc_params (encoder, picture))
1589     goto error;
1590   if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1591     goto error;
1592   if (!ensure_slices (encoder, picture))
1593     goto error;
1594   if (!gst_vaapi_enc_picture_encode (picture))
1595     goto error;
1596
1597   if (!reference_list_update (encoder, picture, reconstruct))
1598     goto error;
1599
1600   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1601 error:
1602   if (reconstruct)
1603     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1604         reconstruct);
1605   return ret;
1606 }
1607
1608 static GstVaapiEncoderStatus
1609 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
1610 {
1611   GstVaapiEncoderH264 *const encoder =
1612       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1613   GstVaapiEncPicture *pic;
1614
1615   encoder->frame_index = 0;
1616   encoder->cur_frame_num = 0;
1617   encoder->cur_present_index = 0;
1618   while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1619     pic = g_queue_pop_head (&encoder->reorder_frame_list);
1620     gst_vaapi_enc_picture_unref (pic);
1621   }
1622   g_queue_clear (&encoder->reorder_frame_list);
1623
1624   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1625 }
1626
1627 /* Generate "codec-data" buffer */
1628 static GstVaapiEncoderStatus
1629 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
1630     GstBuffer ** out_buffer_ptr)
1631 {
1632   GstVaapiEncoderH264 *const encoder =
1633       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1634   const guint32 configuration_version = 0x01;
1635   const guint32 nal_length_size = 4;
1636   guint8 profile_idc, profile_comp, level_idc;
1637   GstMapInfo sps_info, pps_info;
1638   GstBitWriter bs;
1639   GstBuffer *buffer;
1640
1641   if (!encoder->sps_data || !encoder->pps_data)
1642     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1643   if (gst_buffer_get_size (encoder->sps_data) < 4)
1644     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1645
1646   if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1647     goto error_map_sps_buffer;
1648
1649   if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
1650     goto error_map_pps_buffer;
1651
1652   /* skip sps_data[0], which is the nal_unit_type */
1653   profile_idc = sps_info.data[1];
1654   profile_comp = sps_info.data[2];
1655   level_idc = sps_info.data[3];
1656
1657   /* Header */
1658   gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8);
1659   WRITE_UINT32 (&bs, configuration_version, 8);
1660   WRITE_UINT32 (&bs, profile_idc, 8);
1661   WRITE_UINT32 (&bs, profile_comp, 8);
1662   WRITE_UINT32 (&bs, level_idc, 8);
1663   WRITE_UINT32 (&bs, 0x3f, 6);  /* 111111 */
1664   WRITE_UINT32 (&bs, nal_length_size - 1, 2);
1665   WRITE_UINT32 (&bs, 0x07, 3);  /* 111 */
1666
1667   /* Write SPS */
1668   WRITE_UINT32 (&bs, 1, 5);     /* SPS count = 1 */
1669   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1670   WRITE_UINT32 (&bs, sps_info.size, 16);
1671   gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size);
1672
1673   /* Write PPS */
1674   WRITE_UINT32 (&bs, 1, 8);     /* PPS count = 1 */
1675   WRITE_UINT32 (&bs, pps_info.size, 16);
1676   gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size);
1677
1678   gst_buffer_unmap (encoder->pps_data, &pps_info);
1679   gst_buffer_unmap (encoder->sps_data, &sps_info);
1680
1681   buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs),
1682       GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
1683   if (!buffer)
1684     goto error_alloc_buffer;
1685   *out_buffer_ptr = buffer;
1686
1687   gst_bit_writer_clear (&bs, FALSE);
1688   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1689
1690   /* ERRORS */
1691 bs_error:
1692   {
1693     GST_ERROR ("failed to write codec-data");
1694     gst_buffer_unmap (encoder->sps_data, &sps_info);
1695     gst_buffer_unmap (encoder->pps_data, &pps_info);
1696     gst_bit_writer_clear (&bs, TRUE);
1697     return FALSE;
1698   }
1699 error_map_sps_buffer:
1700   {
1701     GST_ERROR ("failed to map SPS packed header");
1702     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1703   }
1704 error_map_pps_buffer:
1705   {
1706     GST_ERROR ("failed to map PPS packed header");
1707     gst_buffer_unmap (encoder->sps_data, &sps_info);
1708     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1709   }
1710 error_alloc_buffer:
1711   {
1712     GST_ERROR ("failed to allocate codec-data buffer");
1713     gst_bit_writer_clear (&bs, TRUE);
1714     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1715   }
1716 }
1717
1718 static GstVaapiEncoderStatus
1719 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
1720     GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1721 {
1722   GstVaapiEncoderH264 *const encoder =
1723       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1724   GstVaapiEncPicture *picture;
1725   gboolean is_idr = FALSE;
1726
1727   *output = NULL;
1728
1729   if (!frame) {
1730     if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1731       return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1732
1733     /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1734        dump B frames from queue, sometime, there may also have P frame or I frame */
1735     g_assert (encoder->num_bframes > 0);
1736     g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1737         GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1738     picture = g_queue_pop_head (&encoder->reorder_frame_list);
1739     g_assert (picture);
1740     if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1741       encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1742     }
1743     goto end;
1744   }
1745
1746   /* new frame coming */
1747   picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1748   if (!picture) {
1749     GST_WARNING ("create H264 picture failed, frame timestamp:%"
1750         GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1751     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1752   }
1753   ++encoder->cur_present_index;
1754   picture->poc = ((encoder->cur_present_index * 2) %
1755       encoder->max_pic_order_cnt);
1756
1757   is_idr = (encoder->frame_index == 0 ||
1758       encoder->frame_index >= encoder->idr_period);
1759
1760   /* check key frames */
1761   if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1762       (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) ==
1763       0) {
1764     ++encoder->cur_frame_num;
1765     ++encoder->frame_index;
1766
1767     /* b frame enabled,  check queue of reorder_frame_list */
1768     if (encoder->num_bframes
1769         && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1770       GstVaapiEncPicture *p_pic;
1771
1772       p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1773       set_p_frame (p_pic, encoder);
1774       g_queue_foreach (&encoder->reorder_frame_list,
1775           (GFunc) set_b_frame, encoder);
1776       ++encoder->cur_frame_num;
1777       set_key_frame (picture, encoder, is_idr);
1778       g_queue_push_tail (&encoder->reorder_frame_list, picture);
1779       picture = p_pic;
1780       encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1781     } else {                    /* no b frames in queue */
1782       set_key_frame (picture, encoder, is_idr);
1783       g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1784       if (encoder->num_bframes)
1785         encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1786     }
1787     goto end;
1788   }
1789
1790   /* new p/b frames coming */
1791   ++encoder->frame_index;
1792   if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1793       g_queue_get_length (&encoder->reorder_frame_list) <
1794       encoder->num_bframes) {
1795     g_queue_push_tail (&encoder->reorder_frame_list, picture);
1796     return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1797   }
1798
1799   ++encoder->cur_frame_num;
1800   set_p_frame (picture, encoder);
1801
1802   if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1803     g_queue_foreach (&encoder->reorder_frame_list, (GFunc) set_b_frame,
1804         encoder);
1805     encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1806     g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1807   }
1808
1809 end:
1810   g_assert (picture);
1811   frame = picture->frame;
1812   if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1813     frame->pts += encoder->cts_offset;
1814   *output = picture;
1815
1816   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1817 }
1818
1819 static GstVaapiEncoderStatus
1820 set_context_info (GstVaapiEncoder * base_encoder)
1821 {
1822   GstVaapiEncoderH264 *const encoder =
1823       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1824   GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1825   const guint DEFAULT_SURFACES_COUNT = 3;
1826
1827   /* Maximum sizes for common headers (in bits) */
1828   enum
1829   {
1830     MAX_SPS_HDR_SIZE = 16473,
1831     MAX_VUI_PARAMS_SIZE = 210,
1832     MAX_HRD_PARAMS_SIZE = 4103,
1833     MAX_PPS_HDR_SIZE = 101,
1834     MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1835   };
1836
1837   if (!ensure_hw_profile (encoder))
1838     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1839
1840   base_encoder->num_ref_frames =
1841       (encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1842
1843   /* Only YUV 4:2:0 formats are supported for now. This means that we
1844      have a limit of 3200 bits per macroblock. */
1845   /* XXX: check profile and compute RawMbBits */
1846   base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
1847       GST_ROUND_UP_16 (vip->height) / 256) * 400;
1848
1849   /* Account for SPS header */
1850   /* XXX: exclude scaling lists, MVC/SVC extensions */
1851   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1852       MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1853
1854   /* Account for PPS header */
1855   /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1856   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1857
1858   /* Account for slice header */
1859   base_encoder->codedbuf_size += encoder->num_slices * (4 +
1860       GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1861
1862   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1863 }
1864
1865 static GstVaapiEncoderStatus
1866 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
1867 {
1868   GstVaapiEncoderH264 *const encoder =
1869       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1870   GstVaapiEncoderStatus status;
1871
1872   encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1873   encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1874
1875   status = ensure_profile_and_level (encoder);
1876   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
1877     return status;
1878
1879   reset_properties (encoder);
1880   return set_context_info (base_encoder);
1881 }
1882
1883 static gboolean
1884 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
1885 {
1886   GstVaapiEncoderH264 *const encoder =
1887       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1888
1889   /* re-ordering */
1890   g_queue_init (&encoder->reorder_frame_list);
1891   encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1892
1893   /* reference frames */
1894   g_queue_init (&encoder->ref_list);
1895   encoder->max_ref_frames = 0;
1896   encoder->max_reflist0_count = 1;
1897   encoder->max_reflist1_count = 1;
1898
1899   return TRUE;
1900 }
1901
1902 static void
1903 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
1904 {
1905   /*free private buffers */
1906   GstVaapiEncoderH264 *const encoder =
1907       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1908   GstVaapiEncPicture *pic;
1909   GstVaapiEncoderH264Ref *ref;
1910
1911   gst_buffer_replace (&encoder->sps_data, NULL);
1912   gst_buffer_replace (&encoder->pps_data, NULL);
1913
1914   while (!g_queue_is_empty (&encoder->ref_list)) {
1915     ref = g_queue_pop_head (&encoder->ref_list);
1916     reference_pic_free (encoder, ref);
1917   }
1918   g_queue_clear (&encoder->ref_list);
1919
1920   while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1921     pic = g_queue_pop_head (&encoder->reorder_frame_list);
1922     gst_vaapi_enc_picture_unref (pic);
1923   }
1924   g_queue_clear (&encoder->reorder_frame_list);
1925
1926 }
1927
1928 static GstVaapiEncoderStatus
1929 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
1930     gint prop_id, const GValue * value)
1931 {
1932   GstVaapiEncoderH264 *const encoder =
1933       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
1934
1935   switch (prop_id) {
1936     case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
1937       encoder->num_bframes = g_value_get_uint (value);
1938       break;
1939     case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
1940       encoder->init_qp = g_value_get_uint (value);
1941       break;
1942     case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
1943       encoder->min_qp = g_value_get_uint (value);
1944       break;
1945     case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
1946       encoder->num_slices = g_value_get_uint (value);
1947       break;
1948     case GST_VAAPI_ENCODER_H264_PROP_CABAC:
1949       encoder->use_cabac = g_value_get_boolean (value);
1950       break;
1951     case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
1952       encoder->use_dct8x8 = g_value_get_boolean (value);
1953       break;
1954     default:
1955       return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
1956   }
1957   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1958 }
1959
1960 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
1961
1962 static inline const GstVaapiEncoderClass *
1963 gst_vaapi_encoder_h264_class (void)
1964 {
1965   static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1966     GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1967     .set_property = gst_vaapi_encoder_h264_set_property,
1968     .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1969   };
1970   return &GstVaapiEncoderH264Class;
1971 }
1972
1973 /**
1974  * gst_vaapi_encoder_h264_new:
1975  * @display: a #GstVaapiDisplay
1976  *
1977  * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
1978  * only supported output stream format is "byte-stream" format.
1979  *
1980  * Return value: the newly allocated #GstVaapiEncoder object
1981  */
1982 GstVaapiEncoder *
1983 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1984 {
1985   return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1986 }
1987
1988 /**
1989  * gst_vaapi_encoder_h264_get_default_properties:
1990  *
1991  * Determines the set of common and H.264 specific encoder properties.
1992  * The caller owns an extra reference to the resulting array of
1993  * #GstVaapiEncoderPropInfo elements, so it shall be released with
1994  * g_ptr_array_unref() after usage.
1995  *
1996  * Return value: the set of encoder properties for #GstVaapiEncoderH264,
1997  *   or %NULL if an error occurred.
1998  */
1999 GPtrArray *
2000 gst_vaapi_encoder_h264_get_default_properties (void)
2001 {
2002   const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
2003   GPtrArray *props;
2004
2005   props = gst_vaapi_encoder_properties_get_default (klass);
2006   if (!props)
2007     return NULL;
2008
2009   /**
2010    * GstVaapiEncoderH264:max-bframes:
2011    *
2012    * The number of B-frames between I and P.
2013    */
2014   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2015       GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
2016       g_param_spec_uint ("max-bframes",
2017           "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
2018           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2019
2020   /**
2021    * GstVaapiEncoderH264:init-qp:
2022    *
2023    * The initial quantizer value.
2024    */
2025   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2026       GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
2027       g_param_spec_uint ("init-qp",
2028           "Initial QP", "Initial quantizer value", 1, 51, 26,
2029           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2030
2031   /**
2032    * GstVaapiEncoderH264:min-qp:
2033    *
2034    * The minimum quantizer value.
2035    */
2036   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2037       GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
2038       g_param_spec_uint ("min-qp",
2039           "Minimum QP", "Minimum quantizer value", 1, 51, 1,
2040           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2041
2042   /**
2043    * GstVaapiEncoderH264:num-slices:
2044    *
2045    * The number of slices per frame.
2046    */
2047   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2048       GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
2049       g_param_spec_uint ("num-slices",
2050           "Number of Slices",
2051           "Number of slices per frame",
2052           1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2053
2054   /**
2055    * GstVaapiEncoderH264:cabac:
2056    *
2057    * Enable CABAC entropy coding mode for improved compression ratio,
2058    * at the expense that the minimum target profile is Main. Default
2059    * is CAVLC entropy coding mode.
2060    */
2061   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2062       GST_VAAPI_ENCODER_H264_PROP_CABAC,
2063       g_param_spec_boolean ("cabac",
2064           "Enable CABAC",
2065           "Enable CABAC entropy coding mode",
2066           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2067
2068   /**
2069    * GstVaapiEncoderH264:dct8x8:
2070    *
2071    * Enable adaptive use of 8x8 transforms in I-frames. This improves
2072    * the compression ratio by the minimum target profile is High.
2073    * Default is to use 4x4 DCT only.
2074    */
2075   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2076       GST_VAAPI_ENCODER_H264_PROP_DCT8X8,
2077       g_param_spec_boolean ("dct8x8",
2078           "Enable 8x8 DCT",
2079           "Enable adaptive use of 8x8 transforms in I-frames",
2080           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2081
2082   return props;
2083 }
2084
2085 /**
2086  * gst_vaapi_encoder_h264_set_max_profile:
2087  * @encoder: a #GstVaapiEncoderH264
2088  * @profile: an H.264 #GstVaapiProfile
2089  *
2090  * Notifies the @encoder to use coding tools from the supplied
2091  * @profile at most.
2092  *
2093  * This means that if the minimal profile derived to
2094  * support the specified coding tools is greater than this @profile,
2095  * then an error is returned when the @encoder is configured.
2096  *
2097  * Return value: %TRUE on success
2098  */
2099 gboolean
2100 gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
2101     GstVaapiProfile profile)
2102 {
2103   guint8 profile_idc;
2104
2105   g_return_val_if_fail (encoder != NULL, FALSE);
2106   g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
2107
2108   if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
2109     return FALSE;
2110
2111   profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
2112   if (!profile_idc)
2113     return FALSE;
2114
2115   encoder->max_profile_idc = profile_idc;
2116   return TRUE;
2117 }
2118
2119 /**
2120  * gst_vaapi_encoder_h264_get_profile_and_level:
2121  * @encoder: a #GstVaapiEncoderH264
2122  * @out_profile_ptr: return location for the #GstVaapiProfile
2123  * @out_level_ptr: return location for the #GstVaapiLevelH264
2124  *
2125  * Queries the H.264 @encoder for the active profile and level. That
2126  * information is only constructed and valid after the encoder is
2127  * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
2128  * function is called.
2129  *
2130  * Return value: %TRUE on success
2131  */
2132 gboolean
2133 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
2134     GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
2135 {
2136   g_return_val_if_fail (encoder != NULL, FALSE);
2137
2138   if (!encoder->profile || !encoder->level)
2139     return FALSE;
2140
2141   if (out_profile_ptr)
2142     *out_profile_ptr = encoder->profile;
2143   if (out_level_ptr)
2144     *out_level_ptr = encoder->level;
2145   return TRUE;
2146 }