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