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