f986d5e50fdf9a1a81dc95d126d27cbd6ec86ef9
[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-2014 Intel Corporation
5  *    Author: Wind Yuan <feng.yuan@intel.com>
6  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public License
10  *  as published by the Free Software Foundation; either version 2.1
11  *  of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free
20  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301 USA
22  */
23
24 #include "sysdeps.h"
25 #include <va/va.h>
26 #include <va/va_enc_h264.h>
27 #include <gst/base/gstbitwriter.h>
28 #include <gst/codecparsers/gsth264parser.h>
29 #include "gstvaapicompat.h"
30 #include "gstvaapiencoder_priv.h"
31 #include "gstvaapiencoder_h264.h"
32 #include "gstvaapiutils_h264.h"
33 #include "gstvaapiutils_h264_priv.h"
34 #include "gstvaapicodedbufferproxy_priv.h"
35 #include "gstvaapisurface.h"
36
37 #define DEBUG 1
38 #include "gstvaapidebug.h"
39
40 /* Define the maximum number of views supported */
41 #define MAX_NUM_VIEWS 2
42
43 /* Define the maximum IDR period */
44 #define MAX_IDR_PERIOD 512
45
46 /* Default CPB length (in milliseconds) */
47 #define DEFAULT_CPB_LENGTH 1500
48
49 /* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */
50 #define SX_CPB_SIZE 4
51
52 /* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */
53 #define SX_BITRATE 6
54
55 /* Define default rate control mode ("constant-qp") */
56 #define DEFAULT_RATECONTROL GST_VAAPI_RATECONTROL_CQP
57
58 /* Supported set of VA rate controls, within this implementation */
59 #define SUPPORTED_RATECONTROLS                          \
60   (GST_VAAPI_RATECONTROL_MASK (CQP)  |                  \
61    GST_VAAPI_RATECONTROL_MASK (CBR)  |                  \
62    GST_VAAPI_RATECONTROL_MASK (VBR)  |                  \
63    GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED))
64
65 /* Supported set of tuning options, within this implementation */
66 #define SUPPORTED_TUNE_OPTIONS                          \
67   (GST_VAAPI_ENCODER_TUNE_MASK (NONE) |                 \
68    GST_VAAPI_ENCODER_TUNE_MASK (HIGH_COMPRESSION))
69
70 /* Supported set of VA packed headers, within this implementation */
71 #define SUPPORTED_PACKED_HEADERS                \
72   (VA_ENC_PACKED_HEADER_SEQUENCE |              \
73    VA_ENC_PACKED_HEADER_PICTURE  |              \
74    VA_ENC_PACKED_HEADER_SLICE    |              \
75    VA_ENC_PACKED_HEADER_RAW_DATA)
76
77 #define GST_H264_NAL_REF_IDC_NONE        0
78 #define GST_H264_NAL_REF_IDC_LOW         1
79 #define GST_H264_NAL_REF_IDC_MEDIUM      2
80 #define GST_H264_NAL_REF_IDC_HIGH        3
81
82 typedef struct
83 {
84   GstVaapiSurfaceProxy *pic;
85   guint poc;
86   guint frame_num;
87 } GstVaapiEncoderH264Ref;
88
89 typedef enum
90 {
91   GST_VAAPI_ENC_H264_REORD_NONE = 0,
92   GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
93   GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
94 } GstVaapiEncH264ReorderState;
95
96 typedef struct _GstVaapiH264ViewRefPool
97 {
98   GQueue ref_list;
99   guint max_ref_frames;
100   guint max_reflist0_count;
101   guint max_reflist1_count;
102 } GstVaapiH264ViewRefPool;
103
104 typedef struct _GstVaapiH264ViewReorderPool
105 {
106   GQueue reorder_frame_list;
107   guint reorder_state;
108   guint frame_index;
109   guint cur_frame_num;
110   guint cur_present_index;
111 } GstVaapiH264ViewReorderPool;
112
113 static inline gboolean
114 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
115 {
116   return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
117 }
118
119 /* Get slice_type value for H.264 specification */
120 static guint8
121 h264_get_slice_type (GstVaapiPictureType type)
122 {
123   switch (type) {
124     case GST_VAAPI_PICTURE_TYPE_I:
125       return GST_H264_I_SLICE;
126     case GST_VAAPI_PICTURE_TYPE_P:
127       return GST_H264_P_SLICE;
128     case GST_VAAPI_PICTURE_TYPE_B:
129       return GST_H264_B_SLICE;
130     default:
131       break;
132   }
133   return -1;
134 }
135
136 /* Get log2_max_frame_num value for H.264 specification */
137 static guint
138 h264_get_log2_max_frame_num (guint num)
139 {
140   guint ret = 0;
141
142   while (num) {
143     ++ret;
144     num >>= 1;
145   }
146   if (ret <= 4)
147     ret = 4;
148   else if (ret > 10)
149     ret = 10;
150   /* must be greater than 4 */
151   return ret;
152 }
153
154 /* Determines the cpbBrNalFactor based on the supplied profile */
155 static guint
156 h264_get_cpb_nal_factor (GstVaapiProfile profile)
157 {
158   guint f;
159
160   /* Table A-2 */
161   switch (profile) {
162     case GST_VAAPI_PROFILE_H264_HIGH:
163       f = 1500;
164       break;
165     case GST_VAAPI_PROFILE_H264_HIGH10:
166       f = 3600;
167       break;
168     case GST_VAAPI_PROFILE_H264_HIGH_422:
169     case GST_VAAPI_PROFILE_H264_HIGH_444:
170       f = 4800;
171       break;
172     case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH:
173     case GST_VAAPI_PROFILE_H264_STEREO_HIGH:
174       f = 1500;                 /* H.10.2.1 (r) */
175       break;
176     default:
177       f = 1200;
178       break;
179   }
180   return f;
181 }
182
183 /* ------------------------------------------------------------------------- */
184 /* --- H.264 Bitstream Writer                                            --- */
185 /* ------------------------------------------------------------------------- */
186
187 #define WRITE_UINT32(bs, val, nbits) do {                       \
188     if (!gst_bit_writer_put_bits_uint32 (bs, val, nbits)) {     \
189       GST_WARNING ("failed to write uint32, nbits: %d", nbits); \
190       goto bs_error;                                            \
191     }                                                           \
192   } while (0)
193
194 #define WRITE_UE(bs, val) do {                  \
195     if (!bs_write_ue (bs, val)) {               \
196       GST_WARNING ("failed to write ue(v)");    \
197       goto bs_error;                            \
198     }                                           \
199   } while (0)
200
201 #define WRITE_SE(bs, val) do {                  \
202     if (!bs_write_se (bs, val)) {               \
203       GST_WARNING ("failed to write se(v)");    \
204       goto bs_error;                            \
205     }                                           \
206   } while (0)
207
208 /* Write an unsigned integer Exp-Golomb-coded syntax element. i.e. ue(v) */
209 static gboolean
210 bs_write_ue (GstBitWriter * bs, guint32 value)
211 {
212   guint32 size_in_bits = 0;
213   guint32 tmp_value = ++value;
214
215   while (tmp_value) {
216     ++size_in_bits;
217     tmp_value >>= 1;
218   }
219   if (size_in_bits > 1
220       && !gst_bit_writer_put_bits_uint32 (bs, 0, size_in_bits - 1))
221     return FALSE;
222   if (!gst_bit_writer_put_bits_uint32 (bs, value, size_in_bits))
223     return FALSE;
224   return TRUE;
225 }
226
227 /* Write a signed integer Exp-Golomb-coded syntax element. i.e. se(v) */
228 static gboolean
229 bs_write_se (GstBitWriter * bs, gint32 value)
230 {
231   guint32 new_val;
232
233   if (value <= 0)
234     new_val = -(value << 1);
235   else
236     new_val = (value << 1) - 1;
237
238   if (!bs_write_ue (bs, new_val))
239     return FALSE;
240   return TRUE;
241 }
242
243 /* Write the NAL unit header */
244 static gboolean
245 bs_write_nal_header (GstBitWriter * bs, guint32 nal_ref_idc,
246     guint32 nal_unit_type)
247 {
248   WRITE_UINT32 (bs, 0, 1);
249   WRITE_UINT32 (bs, nal_ref_idc, 2);
250   WRITE_UINT32 (bs, nal_unit_type, 5);
251   return TRUE;
252
253   /* ERRORS */
254 bs_error:
255   {
256     GST_WARNING ("failed to write NAL unit header");
257     return FALSE;
258   }
259 }
260
261 /* Write the MVC NAL unit header extension */
262 static gboolean
263 bs_write_nal_header_mvc_extension (GstBitWriter * bs,
264     GstVaapiEncPicture * picture, guint32 view_id)
265 {
266   guint32 svc_extension_flag = 0;
267   guint32 non_idr_flag = 1;
268   guint32 priority_id = 0;
269   guint32 temporal_id = 0;
270   guint32 anchor_pic_flag = 0;
271   guint32 inter_view_flag = 0;
272
273   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
274     non_idr_flag = 0;
275
276   if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
277     anchor_pic_flag = 1;
278   /* svc_extension_flag == 0 for mvc stream */
279   WRITE_UINT32 (bs, svc_extension_flag, 1);
280
281   WRITE_UINT32 (bs, non_idr_flag, 1);
282   WRITE_UINT32 (bs, priority_id, 6);
283   WRITE_UINT32 (bs, view_id, 10);
284   WRITE_UINT32 (bs, temporal_id, 3);
285   WRITE_UINT32 (bs, anchor_pic_flag, 1);
286   WRITE_UINT32 (bs, inter_view_flag, 1);
287   WRITE_UINT32 (bs, 1, 1);
288
289   return TRUE;
290
291   /* ERRORS */
292 bs_error:
293   {
294     GST_WARNING ("failed to write NAL unit header");
295     return FALSE;
296   }
297 }
298
299 /* Write the NAL unit trailing bits */
300 static gboolean
301 bs_write_trailing_bits (GstBitWriter * bs)
302 {
303   if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
304     goto bs_error;
305   gst_bit_writer_align_bytes_unchecked (bs, 0);
306   return TRUE;
307
308   /* ERRORS */
309 bs_error:
310   {
311     GST_WARNING ("failed to write NAL unit trailing bits");
312     return FALSE;
313   }
314 }
315
316 /* Write an SPS NAL unit */
317 static gboolean
318 bs_write_sps_data (GstBitWriter * bs,
319     const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
320     const VAEncMiscParameterHRD * hrd_params)
321 {
322   guint8 profile_idc;
323   guint32 constraint_set0_flag, constraint_set1_flag;
324   guint32 constraint_set2_flag, constraint_set3_flag;
325   guint32 gaps_in_frame_num_value_allowed_flag = 0;     // ??
326   gboolean nal_hrd_parameters_present_flag;
327
328   guint32 b_qpprime_y_zero_transform_bypass = 0;
329   guint32 residual_color_transform_flag = 0;
330   guint32 pic_height_in_map_units =
331       (seq_param->seq_fields.bits.frame_mbs_only_flag ?
332       seq_param->picture_height_in_mbs : seq_param->picture_height_in_mbs / 2);
333   guint32 mb_adaptive_frame_field =
334       !seq_param->seq_fields.bits.frame_mbs_only_flag;
335   guint32 i = 0;
336
337   profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
338   constraint_set0_flag =        /* A.2.1 (baseline profile constraints) */
339       profile == GST_VAAPI_PROFILE_H264_BASELINE ||
340       profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
341   constraint_set1_flag =        /* A.2.2 (main profile constraints) */
342       profile == GST_VAAPI_PROFILE_H264_MAIN ||
343       profile == GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
344   constraint_set2_flag = 0;
345   constraint_set3_flag = 0;
346
347   /* profile_idc */
348   WRITE_UINT32 (bs, profile_idc, 8);
349   /* constraint_set0_flag */
350   WRITE_UINT32 (bs, constraint_set0_flag, 1);
351   /* constraint_set1_flag */
352   WRITE_UINT32 (bs, constraint_set1_flag, 1);
353   /* constraint_set2_flag */
354   WRITE_UINT32 (bs, constraint_set2_flag, 1);
355   /* constraint_set3_flag */
356   WRITE_UINT32 (bs, constraint_set3_flag, 1);
357   /* reserved_zero_4bits */
358   WRITE_UINT32 (bs, 0, 4);
359   /* level_idc */
360   WRITE_UINT32 (bs, seq_param->level_idc, 8);
361   /* seq_parameter_set_id */
362   WRITE_UE (bs, seq_param->seq_parameter_set_id);
363
364   if (profile == GST_VAAPI_PROFILE_H264_HIGH ||
365       profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
366       profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH) {
367     /* for high profile */
368     /* chroma_format_idc  = 1, 4:2:0 */
369     WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
370     if (3 == seq_param->seq_fields.bits.chroma_format_idc) {
371       WRITE_UINT32 (bs, residual_color_transform_flag, 1);
372     }
373     /* bit_depth_luma_minus8 */
374     WRITE_UE (bs, seq_param->bit_depth_luma_minus8);
375     /* bit_depth_chroma_minus8 */
376     WRITE_UE (bs, seq_param->bit_depth_chroma_minus8);
377     /* b_qpprime_y_zero_transform_bypass */
378     WRITE_UINT32 (bs, b_qpprime_y_zero_transform_bypass, 1);
379
380     /* seq_scaling_matrix_present_flag  */
381     g_assert (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
382     WRITE_UINT32 (bs,
383         seq_param->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
384
385 #if 0
386     if (seq_param->seq_fields.bits.seq_scaling_matrix_present_flag) {
387       for (i = 0;
388           i < (seq_param->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
389           i++) {
390         gst_bit_writer_put_bits_uint8 (bs,
391             seq_param->seq_fields.bits.seq_scaling_list_present_flag, 1);
392         if (seq_param->seq_fields.bits.seq_scaling_list_present_flag) {
393           g_assert (0);
394           /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
395         }
396       }
397     }
398 #endif
399   }
400
401   /* log2_max_frame_num_minus4 */
402   WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4);
403   /* pic_order_cnt_type */
404   WRITE_UE (bs, seq_param->seq_fields.bits.pic_order_cnt_type);
405
406   if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
407     /* log2_max_pic_order_cnt_lsb_minus4 */
408     WRITE_UE (bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
409   } else if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
410     g_assert (0 && "only POC type 0 is supported");
411     WRITE_UINT32 (bs,
412         seq_param->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
413     WRITE_SE (bs, seq_param->offset_for_non_ref_pic);
414     WRITE_SE (bs, seq_param->offset_for_top_to_bottom_field);
415     WRITE_UE (bs, seq_param->num_ref_frames_in_pic_order_cnt_cycle);
416     for (i = 0; i < seq_param->num_ref_frames_in_pic_order_cnt_cycle; i++) {
417       WRITE_SE (bs, seq_param->offset_for_ref_frame[i]);
418     }
419   }
420
421   /* num_ref_frames */
422   WRITE_UE (bs, seq_param->max_num_ref_frames);
423   /* gaps_in_frame_num_value_allowed_flag */
424   WRITE_UINT32 (bs, gaps_in_frame_num_value_allowed_flag, 1);
425
426   /* pic_width_in_mbs_minus1 */
427   WRITE_UE (bs, seq_param->picture_width_in_mbs - 1);
428   /* pic_height_in_map_units_minus1 */
429   WRITE_UE (bs, pic_height_in_map_units - 1);
430   /* frame_mbs_only_flag */
431   WRITE_UINT32 (bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);
432
433   if (!seq_param->seq_fields.bits.frame_mbs_only_flag) {        //ONLY mbs
434     g_assert (0 && "only progressive frames encoding is supported");
435     WRITE_UINT32 (bs, mb_adaptive_frame_field, 1);
436   }
437
438   /* direct_8x8_inference_flag */
439   WRITE_UINT32 (bs, 0, 1);
440   /* frame_cropping_flag */
441   WRITE_UINT32 (bs, seq_param->frame_cropping_flag, 1);
442
443   if (seq_param->frame_cropping_flag) {
444     /* frame_crop_left_offset */
445     WRITE_UE (bs, seq_param->frame_crop_left_offset);
446     /* frame_crop_right_offset */
447     WRITE_UE (bs, seq_param->frame_crop_right_offset);
448     /* frame_crop_top_offset */
449     WRITE_UE (bs, seq_param->frame_crop_top_offset);
450     /* frame_crop_bottom_offset */
451     WRITE_UE (bs, seq_param->frame_crop_bottom_offset);
452   }
453
454   /* vui_parameters_present_flag */
455   WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
456   if (seq_param->vui_parameters_present_flag) {
457     /* aspect_ratio_info_present_flag */
458     WRITE_UINT32 (bs,
459         seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
460     if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
461       WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
462       if (seq_param->aspect_ratio_idc == 0xFF) {
463         WRITE_UINT32 (bs, seq_param->sar_width, 16);
464         WRITE_UINT32 (bs, seq_param->sar_height, 16);
465       }
466     }
467
468     /* overscan_info_present_flag */
469     WRITE_UINT32 (bs, 0, 1);
470     /* video_signal_type_present_flag */
471     WRITE_UINT32 (bs, 0, 1);
472     /* chroma_loc_info_present_flag */
473     WRITE_UINT32 (bs, 0, 1);
474
475     /* timing_info_present_flag */
476     WRITE_UINT32 (bs, seq_param->vui_fields.bits.timing_info_present_flag, 1);
477     if (seq_param->vui_fields.bits.timing_info_present_flag) {
478       WRITE_UINT32 (bs, seq_param->num_units_in_tick, 32);
479       WRITE_UINT32 (bs, seq_param->time_scale, 32);
480       WRITE_UINT32 (bs, 1, 1);  /* fixed_frame_rate_flag */
481     }
482
483     /* nal_hrd_parameters_present_flag */
484     nal_hrd_parameters_present_flag = seq_param->bits_per_second > 0;
485     nal_hrd_parameters_present_flag = FALSE;    /* XXX: disabled for now */
486     WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
487     if (nal_hrd_parameters_present_flag) {
488       /* hrd_parameters */
489       /* cpb_cnt_minus1 */
490       WRITE_UE (bs, 0);
491       WRITE_UINT32 (bs, SX_BITRATE - 6, 4);     /* bit_rate_scale */
492       WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4);    /* cpb_size_scale */
493
494       for (i = 0; i < 1; ++i) {
495         /* bit_rate_value_minus1[0] */
496         WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
497         /* cpb_size_value_minus1[0] */
498         WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
499         /* cbr_flag[0] */
500         WRITE_UINT32 (bs, 1, 1);
501       }
502       /* initial_cpb_removal_delay_length_minus1 */
503       WRITE_UINT32 (bs, 23, 5);
504       /* cpb_removal_delay_length_minus1 */
505       WRITE_UINT32 (bs, 23, 5);
506       /* dpb_output_delay_length_minus1 */
507       WRITE_UINT32 (bs, 23, 5);
508       /* time_offset_length  */
509       WRITE_UINT32 (bs, 23, 5);
510     }
511
512     /* vcl_hrd_parameters_present_flag */
513     WRITE_UINT32 (bs, 0, 1);
514
515     if (nal_hrd_parameters_present_flag
516         || 0 /*vcl_hrd_parameters_present_flag */ ) {
517       /* low_delay_hrd_flag */
518       WRITE_UINT32 (bs, 0, 1);
519     }
520     /* pic_struct_present_flag */
521     WRITE_UINT32 (bs, 0, 1);
522     /* bs_restriction_flag */
523     WRITE_UINT32 (bs, 0, 1);
524   }
525   return TRUE;
526
527   /* ERRORS */
528 bs_error:
529   {
530     GST_WARNING ("failed to write SPS NAL unit");
531     return FALSE;
532   }
533 }
534
535 static gboolean
536 bs_write_sps (GstBitWriter * bs,
537     const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
538     const VAEncMiscParameterHRD * hrd_params)
539 {
540   if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
541     return FALSE;
542
543   /* rbsp_trailing_bits */
544   bs_write_trailing_bits (bs);
545
546   return FALSE;
547 }
548
549 static gboolean
550 bs_write_subset_sps (GstBitWriter * bs,
551     const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
552     guint num_views, const VAEncMiscParameterHRD * hrd_params)
553 {
554   guint32 i, j, k;
555
556   if (!bs_write_sps_data (bs, seq_param, profile, hrd_params))
557     return FALSE;
558
559   if (profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH ||
560       profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH) {
561     guint32 num_views_minus1, num_level_values_signalled_minus1;
562
563     num_views_minus1 = num_views - 1;
564     g_assert (num_views_minus1 < 1024);
565
566     /* bit equal to one */
567     WRITE_UINT32 (bs, 1, 1);
568
569     WRITE_UE (bs, num_views_minus1);
570
571     for (i = 0; i <= num_views_minus1; i++)
572       WRITE_UE (bs, i);
573
574     for (i = 1; i <= num_views_minus1; i++) {
575       guint32 num_anchor_refs_l0 = 15;
576       WRITE_UE (bs, num_anchor_refs_l0);
577       for (j = 0; j < num_anchor_refs_l0; j++)
578         WRITE_UE (bs, 0);
579
580       guint32 num_anchor_refs_l1 = 15;
581       WRITE_UE (bs, num_anchor_refs_l1);
582       for (j = 0; j < num_anchor_refs_l1; j++)
583         WRITE_UE (bs, 0);
584     }
585
586     for (i = 1; i <= num_views_minus1; i++) {
587       guint num_non_anchor_refs_l0 = 15;
588       WRITE_UE (bs, num_non_anchor_refs_l0);
589       for (j = 0; j < num_non_anchor_refs_l0; j++)
590         WRITE_UE (bs, 0);
591
592       guint num_non_anchor_refs_l1 = 15;
593       WRITE_UE (bs, num_non_anchor_refs_l1);
594       for (j = 0; j < num_non_anchor_refs_l1; j++)
595         WRITE_UE (bs, 0);
596     }
597
598     /* num level values signalled minus1 */
599     num_level_values_signalled_minus1 = 0;
600     g_assert (num_level_values_signalled_minus1 < 64);
601     WRITE_UE (bs, num_level_values_signalled_minus1);
602
603     for (i = 0; i <= num_level_values_signalled_minus1; i++) {
604       guint16 num_applicable_ops_minus1 = 0;
605       g_assert (num_applicable_ops_minus1 < 1024);
606
607       WRITE_UINT32 (bs, seq_param->level_idc, 8);
608       WRITE_UE (bs, num_applicable_ops_minus1);
609
610       for (j = 0; j <= num_applicable_ops_minus1; j++) {
611         guint8 temporal_id = 0;
612         guint16 num_target_views_minus1 = 1;
613
614         WRITE_UINT32 (bs, temporal_id, 3);
615         WRITE_UE (bs, num_target_views_minus1);
616
617         for (k = 0; k <= num_target_views_minus1; k++)
618           WRITE_UE (bs, k);
619
620         WRITE_UE (bs, num_views_minus1);
621       }
622     }
623
624     /* mvc_vui_parameters_present_flag */
625     WRITE_UINT32 (bs, 0, 1);
626   }
627
628   /* additional_extension2_flag */
629   WRITE_UINT32 (bs, 0, 1);
630
631   /* rbsp_trailing_bits */
632   bs_write_trailing_bits (bs);
633   return TRUE;
634
635   /* ERRORS */
636 bs_error:
637   {
638     GST_WARNING ("failed to write subset SPS NAL unit");
639     return FALSE;
640   }
641   return FALSE;
642 }
643
644 /* Write a PPS NAL unit */
645 static gboolean
646 bs_write_pps (GstBitWriter * bs,
647     const VAEncPictureParameterBufferH264 * pic_param, GstVaapiProfile profile)
648 {
649   guint32 num_slice_groups_minus1 = 0;
650   guint32 pic_init_qs_minus26 = 0;
651   guint32 redundant_pic_cnt_present_flag = 0;
652
653   /* pic_parameter_set_id */
654   WRITE_UE (bs, pic_param->pic_parameter_set_id);
655   /* seq_parameter_set_id */
656   WRITE_UE (bs, pic_param->seq_parameter_set_id);
657   /* entropy_coding_mode_flag */
658   WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);
659   /* pic_order_present_flag */
660   WRITE_UINT32 (bs, pic_param->pic_fields.bits.pic_order_present_flag, 1);
661   /* slice_groups-1 */
662   WRITE_UE (bs, num_slice_groups_minus1);
663
664   if (num_slice_groups_minus1 > 0) {
665      /*FIXME*/ g_assert (0 && "unsupported arbitrary slice ordering (ASO)");
666   }
667   WRITE_UE (bs, pic_param->num_ref_idx_l0_active_minus1);
668   WRITE_UE (bs, pic_param->num_ref_idx_l1_active_minus1);
669   WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
670   WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);
671   /* pic_init_qp_minus26 */
672   WRITE_SE (bs, pic_param->pic_init_qp - 26);
673   /* pic_init_qs_minus26 */
674   WRITE_SE (bs, pic_init_qs_minus26);
675   /* chroma_qp_index_offset */
676   WRITE_SE (bs, pic_param->chroma_qp_index_offset);
677
678   WRITE_UINT32 (bs,
679       pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1);
680   WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
681   WRITE_UINT32 (bs, redundant_pic_cnt_present_flag, 1);
682
683   /* more_rbsp_data */
684   if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
685     WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);
686     WRITE_UINT32 (bs,
687         pic_param->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
688     if (pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
689       g_assert (0 && "unsupported scaling lists");
690       /* FIXME */
691       /*
692          for (i = 0; i <
693          (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic_param->pic_fields.bits.transform_8x8_mode_flag));
694          i++) {
695          gst_bit_writer_put_bits_uint8(bs, pic_param->pic_fields.bits.pic_scaling_list_present_flag, 1);
696          }
697        */
698     }
699     WRITE_SE (bs, pic_param->second_chroma_qp_index_offset);
700   }
701
702   /* rbsp_trailing_bits */
703   bs_write_trailing_bits (bs);
704   return TRUE;
705
706   /* ERRORS */
707 bs_error:
708   {
709     GST_WARNING ("failed to write PPS NAL unit");
710     return FALSE;
711   }
712 }
713
714 /* ------------------------------------------------------------------------- */
715 /* --- H.264 Encoder                                                     --- */
716 /* ------------------------------------------------------------------------- */
717
718 #define GST_VAAPI_ENCODER_H264_CAST(encoder) \
719     ((GstVaapiEncoderH264 *)(encoder))
720
721 struct _GstVaapiEncoderH264
722 {
723   GstVaapiEncoder parent_instance;
724
725   GstVaapiProfile profile;
726   GstVaapiLevelH264 level;
727   guint8 profile_idc;
728   guint8 max_profile_idc;
729   guint8 hw_max_profile_idc;
730   guint8 level_idc;
731   guint32 idr_period;
732   guint32 init_qp;
733   guint32 min_qp;
734   guint32 num_slices;
735   guint32 num_bframes;
736   guint32 mb_width;
737   guint32 mb_height;
738   gboolean use_cabac;
739   gboolean use_dct8x8;
740   GstClockTime cts_offset;
741
742   /* frame, poc */
743   guint32 max_frame_num;
744   guint32 log2_max_frame_num;
745   guint32 max_pic_order_cnt;
746   guint32 log2_max_pic_order_cnt;
747   guint32 idr_num;
748   guint8 pic_order_cnt_type;
749   guint8 delta_pic_order_always_zero_flag;
750
751   GstBuffer *sps_data;
752   GstBuffer *subset_sps_data;
753   GstBuffer *pps_data;
754
755   guint bitrate_bits;           // bitrate (bits)
756   guint cpb_length;             // length of CPB buffer (ms)
757   guint cpb_length_bits;        // length of CPB buffer (bits)
758
759   /* MVC */
760   gboolean is_mvc;
761   guint32 view_idx;
762   guint32 num_views;
763   GstVaapiH264ViewRefPool ref_pools[MAX_NUM_VIEWS];
764   GstVaapiH264ViewReorderPool reorder_pools[MAX_NUM_VIEWS];
765 };
766
767 /* Write a Slice NAL unit */
768 static gboolean
769 bs_write_slice (GstBitWriter * bs,
770     const VAEncSliceParameterBufferH264 * slice_param,
771     GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
772 {
773   const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
774   guint32 field_pic_flag = 0;
775   guint32 ref_pic_list_modification_flag_l0 = 0;
776   guint32 ref_pic_list_modification_flag_l1 = 0;
777   guint32 no_output_of_prior_pics_flag = 0;
778   guint32 long_term_reference_flag = 0;
779   guint32 adaptive_ref_pic_marking_mode_flag = 0;
780
781   /* first_mb_in_slice */
782   WRITE_UE (bs, slice_param->macroblock_address);
783   /* slice_type */
784   WRITE_UE (bs, slice_param->slice_type);
785   /* pic_parameter_set_id */
786   WRITE_UE (bs, slice_param->pic_parameter_set_id);
787   /* frame_num */
788   WRITE_UINT32 (bs, picture->frame_num, encoder->log2_max_frame_num);
789
790   /* XXX: only frames (i.e. non-interlaced) are supported for now */
791   /* frame_mbs_only_flag == 0 */
792
793   /* idr_pic_id */
794   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
795     WRITE_UE (bs, slice_param->idr_pic_id);
796
797   /* XXX: only POC type 0 is supported */
798   if (!encoder->pic_order_cnt_type) {
799     WRITE_UINT32 (bs, slice_param->pic_order_cnt_lsb,
800         encoder->log2_max_pic_order_cnt);
801     /* bottom_field_pic_order_in_frame_present_flag is FALSE */
802     if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
803       WRITE_SE (bs, slice_param->delta_pic_order_cnt_bottom);
804   } else if (encoder->pic_order_cnt_type == 1 &&
805       !encoder->delta_pic_order_always_zero_flag) {
806     WRITE_SE (bs, slice_param->delta_pic_order_cnt[0]);
807     if (pic_param->pic_fields.bits.pic_order_present_flag && !field_pic_flag)
808       WRITE_SE (bs, slice_param->delta_pic_order_cnt[1]);
809   }
810   /* redundant_pic_cnt_present_flag is FALSE, no redundant coded pictures */
811
812   /* only works for B-frames */
813   if (slice_param->slice_type == 1)
814     WRITE_UINT32 (bs, slice_param->direct_spatial_mv_pred_flag, 1);
815
816   /* not supporting SP slices */
817   if (slice_param->slice_type == 0 || slice_param->slice_type == 1) {
818     WRITE_UINT32 (bs, slice_param->num_ref_idx_active_override_flag, 1);
819     if (slice_param->num_ref_idx_active_override_flag) {
820       WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1);
821       if (slice_param->slice_type == 1)
822         WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1);
823     }
824   }
825   /* XXX: not supporting custom reference picture list modifications */
826   if ((slice_param->slice_type != 2) && (slice_param->slice_type != 4))
827     WRITE_UINT32 (bs, ref_pic_list_modification_flag_l0, 1);
828   if (slice_param->slice_type == 1)
829     WRITE_UINT32 (bs, ref_pic_list_modification_flag_l1, 1);
830
831   /* we have: weighted_pred_flag == FALSE and */
832   /*        : weighted_bipred_idc == FALSE */
833   if ((pic_param->pic_fields.bits.weighted_pred_flag &&
834           (slice_param->slice_type == 0)) ||
835       ((pic_param->pic_fields.bits.weighted_bipred_idc == 1) &&
836           (slice_param->slice_type == 1))) {
837     /* XXXX: add pred_weight_table() */
838   }
839
840   /* dec_ref_pic_marking() */
841   if (slice_param->slice_type == 0 || slice_param->slice_type == 2) {
842     if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
843       /* no_output_of_prior_pics_flag = 0 */
844       WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1);
845       /* long_term_reference_flag = 0 */
846       WRITE_UINT32 (bs, long_term_reference_flag, 1);
847     } else {
848       /* only sliding_window reference picture marking mode is supported */
849       /* adpative_ref_pic_marking_mode_flag = 0 */
850       WRITE_UINT32 (bs, adaptive_ref_pic_marking_mode_flag, 1);
851     }
852   }
853
854   /* cabac_init_idc */
855   if (pic_param->pic_fields.bits.entropy_coding_mode_flag &&
856       slice_param->slice_type != 2)
857     WRITE_UE (bs, slice_param->cabac_init_idc);
858   /*slice_qp_delta */
859   WRITE_SE (bs, slice_param->slice_qp_delta);
860
861   /* XXX: only supporting I, P and B type slices */
862   /* no sp_for_switch_flag and no slice_qs_delta */
863
864   if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag) {
865     /* disable_deblocking_filter_idc */
866     WRITE_UE (bs, slice_param->disable_deblocking_filter_idc);
867     if (slice_param->disable_deblocking_filter_idc != 1) {
868       WRITE_SE (bs, slice_param->slice_alpha_c0_offset_div2);
869       WRITE_SE (bs, slice_param->slice_beta_offset_div2);
870     }
871   }
872
873   /* XXX: unsupported arbitrary slice ordering (ASO) */
874   /* num_slic_groups_minus1 should be zero */
875   return TRUE;
876
877   /* ERRORS */
878 bs_error:
879   {
880     GST_WARNING ("failed to write Slice NAL unit");
881     return FALSE;
882   }
883 }
884
885 static inline void
886 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
887     const guint8 * nal, guint32 size)
888 {
889   guint8 nal_type;
890   gsize ret;
891   gboolean has_subset_sps;
892
893   g_assert (size);
894
895   has_subset_sps = !encoder->is_mvc || (encoder->subset_sps_data != NULL);
896   if (encoder->sps_data && encoder->pps_data && has_subset_sps)
897     return;
898
899   nal_type = nal[0] & 0x1F;
900   switch (nal_type) {
901     case GST_H264_NAL_SPS:
902       encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
903       ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
904       g_assert (ret == size);
905       break;
906     case GST_H264_NAL_SUBSET_SPS:
907       encoder->subset_sps_data = gst_buffer_new_allocate (NULL, size, NULL);
908       ret = gst_buffer_fill (encoder->subset_sps_data, 0, nal, size);
909       g_assert (ret == size);
910       break;
911     case GST_H264_NAL_PPS:
912       encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
913       ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
914       g_assert (ret == size);
915       break;
916     default:
917       break;
918   }
919 }
920
921 /* Determines the largest supported profile by the underlying hardware */
922 static gboolean
923 ensure_hw_profile_limits (GstVaapiEncoderH264 * encoder)
924 {
925   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
926   GArray *profiles;
927   guint i, profile_idc, max_profile_idc;
928
929   if (encoder->hw_max_profile_idc)
930     return TRUE;
931
932   profiles = gst_vaapi_display_get_encode_profiles (display);
933   if (!profiles)
934     return FALSE;
935
936   max_profile_idc = 0;
937   for (i = 0; i < profiles->len; i++) {
938     const GstVaapiProfile profile =
939         g_array_index (profiles, GstVaapiProfile, i);
940     profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
941     if (!profile_idc)
942       continue;
943     if (max_profile_idc < profile_idc)
944       max_profile_idc = profile_idc;
945   }
946   g_array_unref (profiles);
947
948   encoder->hw_max_profile_idc = max_profile_idc;
949   return TRUE;
950 }
951
952 /* Derives the profile supported by the underlying hardware */
953 static gboolean
954 ensure_hw_profile (GstVaapiEncoderH264 * encoder)
955 {
956   GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
957   GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
958   GstVaapiProfile profile, profiles[4];
959   guint i, num_profiles = 0;
960
961   profiles[num_profiles++] = encoder->profile;
962   switch (encoder->profile) {
963     case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
964       profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
965       profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
966       // fall-through
967     case GST_VAAPI_PROFILE_H264_MAIN:
968       profiles[num_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
969       break;
970     default:
971       break;
972   }
973
974   profile = GST_VAAPI_PROFILE_UNKNOWN;
975   for (i = 0; i < num_profiles; i++) {
976     if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
977       profile = profiles[i];
978       break;
979     }
980   }
981   if (profile == GST_VAAPI_PROFILE_UNKNOWN)
982     goto error_unsupported_profile;
983
984   GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
985   return TRUE;
986
987   /* ERRORS */
988 error_unsupported_profile:
989   {
990     GST_ERROR ("unsupported HW profile (0x%08x)", encoder->profile);
991     return FALSE;
992   }
993 }
994
995 /* Check target decoder constraints */
996 static gboolean
997 ensure_profile_limits (GstVaapiEncoderH264 * encoder)
998 {
999   GstVaapiProfile profile;
1000
1001   if (!encoder->max_profile_idc
1002       || encoder->profile_idc <= encoder->max_profile_idc)
1003     return TRUE;
1004
1005   GST_WARNING ("lowering coding tools to meet target decoder constraints");
1006
1007   /* Try Main profile coding tools */
1008   if (encoder->max_profile_idc < 100) {
1009     encoder->use_dct8x8 = FALSE;
1010     profile = GST_VAAPI_PROFILE_H264_MAIN;
1011   }
1012
1013   /* Try Constrained Baseline profile coding tools */
1014   if (encoder->max_profile_idc < 77) {
1015     encoder->num_bframes = 0;
1016     encoder->use_cabac = FALSE;
1017     profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
1018   }
1019
1020   encoder->profile = profile;
1021   encoder->profile_idc = encoder->max_profile_idc;
1022   return TRUE;
1023 }
1024
1025 /* Derives the minimum profile from the active coding tools */
1026 static gboolean
1027 ensure_profile (GstVaapiEncoderH264 * encoder)
1028 {
1029   GstVaapiProfile profile;
1030
1031   /* Always start from "constrained-baseline" profile for maximum
1032      compatibility */
1033   profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
1034
1035   /* Main profile coding tools */
1036   if (encoder->num_bframes > 0 || encoder->use_cabac)
1037     profile = GST_VAAPI_PROFILE_H264_MAIN;
1038
1039   /* High profile coding tools */
1040   if (encoder->use_dct8x8)
1041     profile = GST_VAAPI_PROFILE_H264_HIGH;
1042
1043   /* MVC profiles coding tools */
1044   if (encoder->num_views == 2)
1045     profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH;
1046   else if (encoder->num_views > 2)
1047     profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH;
1048
1049   encoder->profile = profile;
1050   encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
1051   return TRUE;
1052 }
1053
1054 /* Derives the level from the currently set limits */
1055 static gboolean
1056 ensure_level (GstVaapiEncoderH264 * encoder)
1057 {
1058   const guint cpb_factor = h264_get_cpb_nal_factor (encoder->profile);
1059   const GstVaapiH264LevelLimits *limits_table;
1060   guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
1061
1062   PicSizeMbs = encoder->mb_width * encoder->mb_height;
1063   MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
1064   MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
1065       GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
1066
1067   limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
1068   for (i = 0; i < num_limits; i++) {
1069     const GstVaapiH264LevelLimits *const limits = &limits_table[i];
1070     if (PicSizeMbs <= limits->MaxFS &&
1071         MaxDpbMbs <= limits->MaxDpbMbs &&
1072         MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits
1073             || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) &&
1074         (!encoder->cpb_length_bits ||
1075             encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor)))
1076       break;
1077   }
1078   if (i == num_limits)
1079     goto error_unsupported_level;
1080
1081   encoder->level = limits_table[i].level;
1082   encoder->level_idc = limits_table[i].level_idc;
1083   return TRUE;
1084
1085   /* ERRORS */
1086 error_unsupported_level:
1087   {
1088     GST_ERROR ("failed to find a suitable level matching codec config");
1089     return FALSE;
1090   }
1091 }
1092
1093 /* Enable "high-compression" tuning options */
1094 static gboolean
1095 ensure_tuning_high_compression (GstVaapiEncoderH264 * encoder)
1096 {
1097   guint8 profile_idc;
1098
1099   if (!ensure_hw_profile_limits (encoder))
1100     return FALSE;
1101
1102   profile_idc = encoder->hw_max_profile_idc;
1103   if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
1104     profile_idc = encoder->max_profile_idc;
1105
1106   /* Tuning options to enable Main profile */
1107   if (profile_idc >= 77 && profile_idc != 88) {
1108     encoder->use_cabac = TRUE;
1109     if (!encoder->num_bframes)
1110       encoder->num_bframes = 1;
1111   }
1112
1113   /* Tuning options to enable High profile */
1114   if (profile_idc >= 100) {
1115     encoder->use_dct8x8 = TRUE;
1116   }
1117   return TRUE;
1118 }
1119
1120 /* Ensure tuning options */
1121 static gboolean
1122 ensure_tuning (GstVaapiEncoderH264 * encoder)
1123 {
1124   gboolean success;
1125
1126   switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
1127     case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
1128       success = ensure_tuning_high_compression (encoder);
1129       break;
1130     default:
1131       success = TRUE;
1132       break;
1133   }
1134   return success;
1135 }
1136
1137 /* Handle new GOP starts */
1138 static void
1139 reset_gop_start (GstVaapiEncoderH264 * encoder)
1140 {
1141   GstVaapiH264ViewReorderPool *const reorder_pool =
1142       &encoder->reorder_pools[encoder->view_idx];
1143
1144   reorder_pool->frame_index = 1;
1145   reorder_pool->cur_frame_num = 0;
1146   reorder_pool->cur_present_index = 0;
1147   ++encoder->idr_num;
1148 }
1149
1150 /* Marks the supplied picture as a B-frame */
1151 static void
1152 set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1153 {
1154   GstVaapiH264ViewReorderPool *const reorder_pool =
1155       &encoder->reorder_pools[encoder->view_idx];
1156
1157   g_assert (pic && encoder);
1158   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1159   pic->type = GST_VAAPI_PICTURE_TYPE_B;
1160   pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
1161 }
1162
1163 /* Marks the supplied picture as a P-frame */
1164 static void
1165 set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1166 {
1167   GstVaapiH264ViewReorderPool *const reorder_pool =
1168       &encoder->reorder_pools[encoder->view_idx];
1169
1170   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1171   pic->type = GST_VAAPI_PICTURE_TYPE_P;
1172   pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
1173 }
1174
1175 /* Marks the supplied picture as an I-frame */
1176 static void
1177 set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1178 {
1179   GstVaapiH264ViewReorderPool *const reorder_pool =
1180       &encoder->reorder_pools[encoder->view_idx];
1181
1182   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1183   pic->type = GST_VAAPI_PICTURE_TYPE_I;
1184   pic->frame_num = (reorder_pool->cur_frame_num % encoder->max_frame_num);
1185
1186   g_assert (pic->frame);
1187   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1188 }
1189
1190 /* Marks the supplied picture as an IDR frame */
1191 static void
1192 set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
1193 {
1194   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1195   pic->type = GST_VAAPI_PICTURE_TYPE_I;
1196   pic->frame_num = 0;
1197   pic->poc = 0;
1198   GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
1199
1200   g_assert (pic->frame);
1201   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1202 }
1203
1204 /* Marks the supplied picture a a key-frame */
1205 static void
1206 set_key_frame (GstVaapiEncPicture * picture,
1207     GstVaapiEncoderH264 * encoder, gboolean is_idr)
1208 {
1209   if (is_idr) {
1210     reset_gop_start (encoder);
1211     set_idr_frame (picture, encoder);
1212   } else
1213     set_i_frame (picture, encoder);
1214 }
1215
1216 /* Fills in VA HRD parameters */
1217 static void
1218 fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd)
1219 {
1220   if (encoder->bitrate_bits > 0) {
1221     hrd->buffer_size = encoder->cpb_length_bits;
1222     hrd->initial_buffer_fullness = hrd->buffer_size / 2;
1223   } else {
1224     hrd->buffer_size = 0;
1225     hrd->initial_buffer_fullness = 0;
1226   }
1227 }
1228
1229 /* Adds the supplied sequence header (SPS) to the list of packed
1230    headers to pass down as-is to the encoder */
1231 static gboolean
1232 add_packed_sequence_header (GstVaapiEncoderH264 * encoder,
1233     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1234 {
1235   GstVaapiEncPackedHeader *packed_seq;
1236   GstBitWriter bs;
1237   VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
1238   const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1239   GstVaapiProfile profile = encoder->profile;
1240
1241   VAEncMiscParameterHRD hrd_params;
1242   guint32 data_bit_size;
1243   guint8 *data;
1244
1245   fill_hrd_params (encoder, &hrd_params);
1246
1247   gst_bit_writer_init (&bs, 128 * 8);
1248   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1249   bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SPS);
1250
1251   /* Set High profile for encoding the MVC base view. Otherwise, some
1252      traditional decoder cannot recognize MVC profile streams with
1253      only the base view in there */
1254   if (profile == GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH ||
1255       profile == GST_VAAPI_PROFILE_H264_STEREO_HIGH)
1256     profile = GST_VAAPI_PROFILE_H264_HIGH;
1257
1258   bs_write_sps (&bs, seq_param, profile, &hrd_params);
1259
1260   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1261   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1262   data = GST_BIT_WRITER_DATA (&bs);
1263
1264   packed_seq_param.type = VAEncPackedHeaderSequence;
1265   packed_seq_param.bit_length = data_bit_size;
1266   packed_seq_param.has_emulation_bytes = 0;
1267
1268   packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1269       &packed_seq_param, sizeof (packed_seq_param),
1270       data, (data_bit_size + 7) / 8);
1271   g_assert (packed_seq);
1272
1273   gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
1274   gst_vaapi_codec_object_replace (&packed_seq, NULL);
1275
1276   /* store sps data */
1277   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1278   gst_bit_writer_clear (&bs, TRUE);
1279   return TRUE;
1280
1281   /* ERRORS */
1282 bs_error:
1283   {
1284     GST_WARNING ("failed to write SPS NAL unit");
1285     gst_bit_writer_clear (&bs, TRUE);
1286     return FALSE;
1287   }
1288 }
1289
1290 static gboolean
1291 add_packed_sequence_header_mvc (GstVaapiEncoderH264 * encoder,
1292     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1293 {
1294   GstVaapiEncPackedHeader *packed_seq;
1295   GstBitWriter bs;
1296   VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
1297   const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1298   VAEncMiscParameterHRD hrd_params;
1299   guint32 data_bit_size;
1300   guint8 *data;
1301
1302   fill_hrd_params (encoder, &hrd_params);
1303
1304   /* non-base layer, pack one subset sps */
1305   gst_bit_writer_init (&bs, 128 * 8);
1306   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1307   bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_SUBSET_SPS);
1308
1309   bs_write_subset_sps (&bs, seq_param, encoder->profile, encoder->num_views,
1310       &hrd_params);
1311
1312   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1313   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1314   data = GST_BIT_WRITER_DATA (&bs);
1315
1316   packed_header_param_buffer.type = VAEncPackedHeaderSequence;
1317   packed_header_param_buffer.bit_length = data_bit_size;
1318   packed_header_param_buffer.has_emulation_bytes = 0;
1319
1320   packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1321       &packed_header_param_buffer, sizeof (packed_header_param_buffer),
1322       data, (data_bit_size + 7) / 8);
1323   g_assert (packed_seq);
1324
1325   gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
1326   gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL);
1327
1328   /* store subset sps data */
1329   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1330   gst_bit_writer_clear (&bs, TRUE);
1331   return TRUE;
1332
1333   /* ERRORS */
1334 bs_error:
1335   {
1336     GST_WARNING ("failed to write SPS NAL unit");
1337     gst_bit_writer_clear (&bs, TRUE);
1338     return FALSE;
1339   }
1340 }
1341
1342 /* Adds the supplied picture header (PPS) to the list of packed
1343    headers to pass down as-is to the encoder */
1344 static gboolean
1345 add_packed_picture_header (GstVaapiEncoderH264 * encoder,
1346     GstVaapiEncPicture * picture)
1347 {
1348   GstVaapiEncPackedHeader *packed_pic;
1349   GstBitWriter bs;
1350   VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
1351   const VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1352   guint32 data_bit_size;
1353   guint8 *data;
1354
1355   gst_bit_writer_init (&bs, 128 * 8);
1356   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1357   bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_HIGH, GST_H264_NAL_PPS);
1358   bs_write_pps (&bs, pic_param, encoder->profile);
1359   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1360   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1361   data = GST_BIT_WRITER_DATA (&bs);
1362
1363   packed_pic_param.type = VAEncPackedHeaderPicture;
1364   packed_pic_param.bit_length = data_bit_size;
1365   packed_pic_param.has_emulation_bytes = 0;
1366
1367   packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1368       &packed_pic_param, sizeof (packed_pic_param),
1369       data, (data_bit_size + 7) / 8);
1370   g_assert (packed_pic);
1371
1372   gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
1373   gst_vaapi_codec_object_replace (&packed_pic, NULL);
1374
1375   /* store pps data */
1376   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1377   gst_bit_writer_clear (&bs, TRUE);
1378   return TRUE;
1379
1380   /* ERRORS */
1381 bs_error:
1382   {
1383     GST_WARNING ("failed to write PPS NAL unit");
1384     gst_bit_writer_clear (&bs, TRUE);
1385     return FALSE;
1386   }
1387 }
1388
1389 static gboolean
1390 get_nal_hdr_attributes (GstVaapiEncPicture * picture,
1391     guint8 * nal_ref_idc, guint8 * nal_unit_type)
1392 {
1393   switch (picture->type) {
1394     case GST_VAAPI_PICTURE_TYPE_I:
1395       *nal_ref_idc = GST_H264_NAL_REF_IDC_HIGH;
1396       if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
1397         *nal_unit_type = GST_H264_NAL_SLICE_IDR;
1398       else
1399         *nal_unit_type = GST_H264_NAL_SLICE;
1400       break;
1401     case GST_VAAPI_PICTURE_TYPE_P:
1402       *nal_ref_idc = GST_H264_NAL_REF_IDC_MEDIUM;
1403       *nal_unit_type = GST_H264_NAL_SLICE;
1404       break;
1405     case GST_VAAPI_PICTURE_TYPE_B:
1406       *nal_ref_idc = GST_H264_NAL_REF_IDC_NONE;
1407       *nal_unit_type = GST_H264_NAL_SLICE;
1408       break;
1409     default:
1410       return FALSE;
1411   }
1412   return TRUE;
1413 }
1414
1415 /* Adds the supplied prefix nal header to the list of packed
1416    headers to pass down as-is to the encoder */
1417 static gboolean
1418 add_packed_prefix_nal_header (GstVaapiEncoderH264 * encoder,
1419     GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
1420 {
1421   GstVaapiEncPackedHeader *packed_prefix_nal;
1422   GstBitWriter bs;
1423   VAEncPackedHeaderParameterBuffer packed_prefix_nal_param = { 0 };
1424   guint32 data_bit_size;
1425   guint8 *data;
1426   guint8 nal_ref_idc, nal_unit_type;
1427
1428   gst_bit_writer_init (&bs, 128 * 8);
1429   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1430
1431   if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
1432     goto bs_error;
1433   nal_unit_type = GST_H264_NAL_PREFIX_UNIT;
1434
1435   bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
1436   bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx);
1437   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1438   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1439   data = GST_BIT_WRITER_DATA (&bs);
1440
1441   packed_prefix_nal_param.type = VAEncPackedHeaderRawData;
1442   packed_prefix_nal_param.bit_length = data_bit_size;
1443   packed_prefix_nal_param.has_emulation_bytes = 0;
1444
1445   packed_prefix_nal =
1446       gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1447       &packed_prefix_nal_param, sizeof (packed_prefix_nal_param), data,
1448       (data_bit_size + 7) / 8);
1449   g_assert (packed_prefix_nal);
1450
1451   gst_vaapi_enc_slice_add_packed_header (slice, packed_prefix_nal);
1452   gst_vaapi_codec_object_replace (&packed_prefix_nal, NULL);
1453
1454   gst_bit_writer_clear (&bs, TRUE);
1455
1456   return TRUE;
1457
1458   /* ERRORS */
1459 bs_error:
1460   {
1461     GST_WARNING ("failed to write Prefix NAL unit header");
1462     gst_bit_writer_clear (&bs, TRUE);
1463     return FALSE;
1464   }
1465 }
1466
1467 /* Adds the supplied slice header to the list of packed
1468    headers to pass down as-is to the encoder */
1469 static gboolean
1470 add_packed_slice_header (GstVaapiEncoderH264 * encoder,
1471     GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
1472 {
1473   GstVaapiEncPackedHeader *packed_slice;
1474   GstBitWriter bs;
1475   VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 };
1476   const VAEncSliceParameterBufferH264 *const slice_param = slice->param;
1477   guint32 data_bit_size;
1478   guint8 *data;
1479   guint8 nal_ref_idc, nal_unit_type;
1480
1481   gst_bit_writer_init (&bs, 128 * 8);
1482   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
1483
1484   if (!get_nal_hdr_attributes (picture, &nal_ref_idc, &nal_unit_type))
1485     goto bs_error;
1486   /* pack nal_unit_header_mvc_extension() for the non base view */
1487   if (encoder->is_mvc && encoder->view_idx) {
1488     bs_write_nal_header (&bs, nal_ref_idc, GST_H264_NAL_SLICE_EXT);
1489     bs_write_nal_header_mvc_extension (&bs, picture, encoder->view_idx);
1490   } else
1491     bs_write_nal_header (&bs, nal_ref_idc, nal_unit_type);
1492
1493   bs_write_slice (&bs, slice_param, encoder, picture);
1494   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1495   data = GST_BIT_WRITER_DATA (&bs);
1496
1497   packed_slice_param.type = VAEncPackedHeaderSlice;
1498   packed_slice_param.bit_length = data_bit_size;
1499   packed_slice_param.has_emulation_bytes = 0;
1500
1501   packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1502       &packed_slice_param, sizeof (packed_slice_param),
1503       data, (data_bit_size + 7) / 8);
1504   g_assert (packed_slice);
1505
1506   gst_vaapi_enc_slice_add_packed_header (slice, packed_slice);
1507   gst_vaapi_codec_object_replace (&packed_slice, NULL);
1508
1509   gst_bit_writer_clear (&bs, TRUE);
1510   return TRUE;
1511
1512   /* ERRORS */
1513 bs_error:
1514   {
1515     GST_WARNING ("failed to write Slice NAL unit header");
1516     gst_bit_writer_clear (&bs, TRUE);
1517     return FALSE;
1518   }
1519 }
1520
1521 /* Reference picture management */
1522 static void
1523 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
1524 {
1525   if (!ref)
1526     return;
1527   if (ref->pic)
1528     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
1529   g_slice_free (GstVaapiEncoderH264Ref, ref);
1530 }
1531
1532 static inline GstVaapiEncoderH264Ref *
1533 reference_pic_create (GstVaapiEncoderH264 * encoder,
1534     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1535 {
1536   GstVaapiEncoderH264Ref *const ref = g_slice_new0 (GstVaapiEncoderH264Ref);
1537
1538   ref->pic = surface;
1539   ref->frame_num = picture->frame_num;
1540   ref->poc = picture->poc;
1541   return ref;
1542 }
1543
1544 static gboolean
1545 reference_list_update (GstVaapiEncoderH264 * encoder,
1546     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1547 {
1548   GstVaapiEncoderH264Ref *ref;
1549   GstVaapiH264ViewRefPool *const ref_pool =
1550       &encoder->ref_pools[encoder->view_idx];
1551
1552   if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
1553     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
1554     return TRUE;
1555   }
1556   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
1557     while (!g_queue_is_empty (&ref_pool->ref_list))
1558       reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1559   } else if (g_queue_get_length (&ref_pool->ref_list) >=
1560       ref_pool->max_ref_frames) {
1561     reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1562   }
1563   ref = reference_pic_create (encoder, picture, surface);
1564   g_queue_push_tail (&ref_pool->ref_list, ref);
1565   g_assert (g_queue_get_length (&ref_pool->ref_list) <=
1566       ref_pool->max_ref_frames);
1567   return TRUE;
1568 }
1569
1570 static gboolean
1571 reference_list_init (GstVaapiEncoderH264 * encoder,
1572     GstVaapiEncPicture * picture,
1573     GstVaapiEncoderH264Ref ** reflist_0,
1574     guint * reflist_0_count,
1575     GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
1576 {
1577   GstVaapiEncoderH264Ref *tmp;
1578   GstVaapiH264ViewRefPool *const ref_pool =
1579       &encoder->ref_pools[encoder->view_idx];
1580   GList *iter, *list_0_start = NULL, *list_1_start = NULL;
1581   guint count;
1582
1583   *reflist_0_count = 0;
1584   *reflist_1_count = 0;
1585   if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
1586     return TRUE;
1587
1588   iter = g_queue_peek_tail_link (&ref_pool->ref_list);
1589   for (; iter; iter = g_list_previous (iter)) {
1590     tmp = (GstVaapiEncoderH264Ref *) iter->data;
1591     g_assert (tmp && tmp->poc != picture->poc);
1592     if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) {
1593       list_0_start = iter;
1594       list_1_start = g_list_next (iter);
1595       break;
1596     }
1597   }
1598
1599   /* order reflist_0 */
1600   g_assert (list_0_start);
1601   iter = list_0_start;
1602   count = 0;
1603   for (; iter; iter = g_list_previous (iter)) {
1604     reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
1605     ++count;
1606   }
1607   *reflist_0_count = count;
1608
1609   if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1610     return TRUE;
1611
1612   /* order reflist_1 */
1613   count = 0;
1614   iter = list_1_start;
1615   for (; iter; iter = g_list_next (iter)) {
1616     reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
1617     ++count;
1618   }
1619   *reflist_1_count = count;
1620   return TRUE;
1621 }
1622
1623 /* Fills in VA sequence parameter buffer */
1624 static gboolean
1625 fill_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncSequence * sequence)
1626 {
1627   VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
1628   GstVaapiH264ViewRefPool *const ref_pool =
1629       &encoder->ref_pools[encoder->view_idx];
1630
1631   memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferH264));
1632   seq_param->seq_parameter_set_id = encoder->view_idx;
1633   seq_param->level_idc = encoder->level_idc;
1634   seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
1635   seq_param->ip_period = 1 + encoder->num_bframes;
1636   seq_param->bits_per_second = encoder->bitrate_bits;
1637
1638   seq_param->max_num_ref_frames = ref_pool->max_ref_frames;
1639   seq_param->picture_width_in_mbs = encoder->mb_width;
1640   seq_param->picture_height_in_mbs = encoder->mb_height;
1641
1642   /*sequence field values */
1643   seq_param->seq_fields.value = 0;
1644   seq_param->seq_fields.bits.chroma_format_idc = 1;
1645   seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
1646   seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
1647   seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
1648   /* direct_8x8_inference_flag default false */
1649   seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
1650   g_assert (encoder->log2_max_frame_num >= 4);
1651   seq_param->seq_fields.bits.log2_max_frame_num_minus4 =
1652       encoder->log2_max_frame_num - 4;
1653   /* picture order count */
1654   encoder->pic_order_cnt_type = seq_param->seq_fields.bits.pic_order_cnt_type =
1655       0;
1656   g_assert (encoder->log2_max_pic_order_cnt >= 4);
1657   seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
1658       encoder->log2_max_pic_order_cnt - 4;
1659
1660   seq_param->bit_depth_luma_minus8 = 0;
1661   seq_param->bit_depth_chroma_minus8 = 0;
1662
1663   /* not used if pic_order_cnt_type == 0 */
1664   if (seq_param->seq_fields.bits.pic_order_cnt_type == 1) {
1665     encoder->delta_pic_order_always_zero_flag =
1666         seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
1667     seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0;
1668     seq_param->offset_for_non_ref_pic = 0;
1669     seq_param->offset_for_top_to_bottom_field = 0;
1670     memset (seq_param->offset_for_ref_frame, 0,
1671         sizeof (seq_param->offset_for_ref_frame));
1672   }
1673
1674   /* frame_cropping_flag */
1675   if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 15) ||
1676       (GST_VAAPI_ENCODER_HEIGHT (encoder) & 15)) {
1677     static const guint SubWidthC[] = { 1, 2, 2, 1 };
1678     static const guint SubHeightC[] = { 1, 2, 1, 1 };
1679     const guint CropUnitX =
1680         SubWidthC[seq_param->seq_fields.bits.chroma_format_idc];
1681     const guint CropUnitY =
1682         SubHeightC[seq_param->seq_fields.bits.chroma_format_idc] *
1683         (2 - seq_param->seq_fields.bits.frame_mbs_only_flag);
1684
1685     seq_param->frame_cropping_flag = 1;
1686     seq_param->frame_crop_left_offset = 0;
1687     seq_param->frame_crop_right_offset =
1688         (16 * encoder->mb_width -
1689         GST_VAAPI_ENCODER_WIDTH (encoder)) / CropUnitX;
1690     seq_param->frame_crop_top_offset = 0;
1691     seq_param->frame_crop_bottom_offset =
1692         (16 * encoder->mb_height -
1693         GST_VAAPI_ENCODER_HEIGHT (encoder)) / CropUnitY;
1694   }
1695
1696   /* VUI parameters are always set, at least for timing_info (framerate) */
1697   seq_param->vui_parameters_present_flag = TRUE;
1698   if (seq_param->vui_parameters_present_flag) {
1699     seq_param->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
1700     seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1701     /* if vui_parameters_present_flag is TRUE and sps data belongs to
1702      * subset sps, timing_info_preset_flag should be zero (H.7.4.2.1.1) */
1703     seq_param->vui_fields.bits.timing_info_present_flag = !encoder->view_idx;
1704     if (seq_param->vui_fields.bits.timing_info_present_flag) {
1705       seq_param->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1706       seq_param->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
1707     }
1708   }
1709   return TRUE;
1710 }
1711
1712 /* Fills in VA picture parameter buffer */
1713 static gboolean
1714 fill_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1715     GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1716 {
1717   VAEncPictureParameterBufferH264 *const pic_param = picture->param;
1718   GstVaapiH264ViewRefPool *const ref_pool =
1719       &encoder->ref_pools[encoder->view_idx];
1720   GstVaapiEncoderH264Ref *ref_pic;
1721   GList *reflist;
1722   guint i;
1723
1724   memset (pic_param, 0, sizeof (VAEncPictureParameterBufferH264));
1725
1726   /* reference list,  */
1727   pic_param->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1728   pic_param->CurrPic.TopFieldOrderCnt = picture->poc;
1729   i = 0;
1730   if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1731     for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
1732         reflist; reflist = g_list_next (reflist)) {
1733       ref_pic = reflist->data;
1734       g_assert (ref_pic && ref_pic->pic &&
1735           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1736
1737       pic_param->ReferenceFrames[i].picture_id =
1738           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1739       ++i;
1740     }
1741     g_assert (i <= 16 && i <= ref_pool->max_ref_frames);
1742   }
1743   for (; i < 16; ++i) {
1744     pic_param->ReferenceFrames[i].picture_id = VA_INVALID_ID;
1745   }
1746   pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1747
1748   pic_param->pic_parameter_set_id = encoder->view_idx;
1749   pic_param->seq_parameter_set_id = encoder->view_idx;
1750   pic_param->last_picture = 0;  /* means last encoding picture */
1751   pic_param->frame_num = picture->frame_num;
1752   pic_param->pic_init_qp = encoder->init_qp;
1753   pic_param->num_ref_idx_l0_active_minus1 =
1754       (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0);
1755   pic_param->num_ref_idx_l1_active_minus1 =
1756       (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0);
1757   pic_param->chroma_qp_index_offset = 0;
1758   pic_param->second_chroma_qp_index_offset = 0;
1759
1760   /* set picture fields */
1761   pic_param->pic_fields.value = 0;
1762   pic_param->pic_fields.bits.idr_pic_flag =
1763       GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1764   pic_param->pic_fields.bits.reference_pic_flag =
1765       (picture->type != GST_VAAPI_PICTURE_TYPE_B);
1766   pic_param->pic_fields.bits.entropy_coding_mode_flag = encoder->use_cabac;
1767   pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
1768   pic_param->pic_fields.bits.weighted_bipred_idc = 0;
1769   pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
1770   pic_param->pic_fields.bits.transform_8x8_mode_flag = encoder->use_dct8x8;
1771   /* enable debloking */
1772   pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
1773   pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
1774   /* bottom_field_pic_order_in_frame_present_flag */
1775   pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
1776   pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
1777
1778   return TRUE;
1779 }
1780
1781 /* Adds slice headers to picture */
1782 static gboolean
1783 add_slice_headers (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1784     GstVaapiEncoderH264Ref ** reflist_0, guint reflist_0_count,
1785     GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
1786 {
1787   VAEncSliceParameterBufferH264 *slice_param;
1788   GstVaapiEncSlice *slice;
1789   guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
1790   guint mb_size;
1791   guint last_mb_index;
1792   guint i_slice, i_ref;
1793
1794   g_assert (picture);
1795
1796   mb_size = encoder->mb_width * encoder->mb_height;
1797
1798   g_assert (encoder->num_slices && encoder->num_slices < mb_size);
1799   slice_of_mbs = mb_size / encoder->num_slices;
1800   slice_mod_mbs = mb_size % encoder->num_slices;
1801   last_mb_index = 0;
1802   for (i_slice = 0; i_slice < encoder->num_slices; ++i_slice) {
1803     cur_slice_mbs = slice_of_mbs;
1804     if (slice_mod_mbs) {
1805       ++cur_slice_mbs;
1806       --slice_mod_mbs;
1807     }
1808     slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1809     g_assert (slice && slice->param_id != VA_INVALID_ID);
1810     slice_param = slice->param;
1811
1812     memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1813     slice_param->macroblock_address = last_mb_index;
1814     slice_param->num_macroblocks = cur_slice_mbs;
1815     slice_param->macroblock_info = VA_INVALID_ID;
1816     slice_param->slice_type = h264_get_slice_type (picture->type);
1817     g_assert (slice_param->slice_type != -1);
1818     slice_param->pic_parameter_set_id = encoder->view_idx;
1819     slice_param->idr_pic_id = encoder->idr_num;
1820     slice_param->pic_order_cnt_lsb = picture->poc;
1821
1822     /* not used if pic_order_cnt_type = 0 */
1823     slice_param->delta_pic_order_cnt_bottom = 0;
1824     memset (slice_param->delta_pic_order_cnt, 0,
1825         sizeof (slice_param->delta_pic_order_cnt));
1826
1827     /* only works for B frames */
1828     slice_param->direct_spatial_mv_pred_flag = FALSE;
1829     /* default equal to picture parameters */
1830     slice_param->num_ref_idx_active_override_flag = FALSE;
1831     if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1832       slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1833     else
1834       slice_param->num_ref_idx_l0_active_minus1 = 0;
1835     if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1836       slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1837     else
1838       slice_param->num_ref_idx_l1_active_minus1 = 0;
1839     g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1840     g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1841
1842     i_ref = 0;
1843     if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1844       for (; i_ref < reflist_0_count; ++i_ref) {
1845         slice_param->RefPicList0[i_ref].picture_id =
1846             GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1847       }
1848       g_assert (i_ref == 1);
1849     }
1850     for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList0); ++i_ref) {
1851       slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1852     }
1853
1854     i_ref = 0;
1855     if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1856       for (; i_ref < reflist_1_count; ++i_ref) {
1857         slice_param->RefPicList1[i_ref].picture_id =
1858             GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1859       }
1860       g_assert (i_ref == 1);
1861     }
1862     for (; i_ref < G_N_ELEMENTS (slice_param->RefPicList1); ++i_ref) {
1863       slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1864     }
1865
1866     /* not used if  pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1867     slice_param->luma_log2_weight_denom = 0;
1868     slice_param->chroma_log2_weight_denom = 0;
1869     slice_param->luma_weight_l0_flag = FALSE;
1870     memset (slice_param->luma_weight_l0, 0,
1871         sizeof (slice_param->luma_weight_l0));
1872     memset (slice_param->luma_offset_l0, 0,
1873         sizeof (slice_param->luma_offset_l0));
1874     slice_param->chroma_weight_l0_flag = FALSE;
1875     memset (slice_param->chroma_weight_l0, 0,
1876         sizeof (slice_param->chroma_weight_l0));
1877     memset (slice_param->chroma_offset_l0, 0,
1878         sizeof (slice_param->chroma_offset_l0));
1879     slice_param->luma_weight_l1_flag = FALSE;
1880     memset (slice_param->luma_weight_l1, 0,
1881         sizeof (slice_param->luma_weight_l1));
1882     memset (slice_param->luma_offset_l1, 0,
1883         sizeof (slice_param->luma_offset_l1));
1884     slice_param->chroma_weight_l1_flag = FALSE;
1885     memset (slice_param->chroma_weight_l1, 0,
1886         sizeof (slice_param->chroma_weight_l1));
1887     memset (slice_param->chroma_offset_l1, 0,
1888         sizeof (slice_param->chroma_offset_l1));
1889
1890     slice_param->cabac_init_idc = 0;
1891     slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1892     if (slice_param->slice_qp_delta > 4)
1893       slice_param->slice_qp_delta = 4;
1894     slice_param->disable_deblocking_filter_idc = 0;
1895     slice_param->slice_alpha_c0_offset_div2 = 2;
1896     slice_param->slice_beta_offset_div2 = 2;
1897
1898     /* set calculation for next slice */
1899     last_mb_index += cur_slice_mbs;
1900
1901     /* add packed Prefix NAL unit before each Coded slice NAL in base view */
1902     if (encoder->is_mvc && !encoder->view_idx &&
1903         (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1904             VA_ENC_PACKED_HEADER_RAW_DATA)
1905         && !add_packed_prefix_nal_header (encoder, picture, slice))
1906       goto error_create_packed_prefix_nal_hdr;
1907     if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1908             VA_ENC_PACKED_HEADER_SLICE)
1909         && !add_packed_slice_header (encoder, picture, slice))
1910       goto error_create_packed_slice_hdr;
1911
1912     gst_vaapi_enc_picture_add_slice (picture, slice);
1913     gst_vaapi_codec_object_replace (&slice, NULL);
1914   }
1915   g_assert (last_mb_index == mb_size);
1916   return TRUE;
1917
1918 error_create_packed_slice_hdr:
1919   {
1920     GST_ERROR ("failed to create packed slice header buffer");
1921     gst_vaapi_codec_object_replace (&slice, NULL);
1922     return FALSE;
1923   }
1924 error_create_packed_prefix_nal_hdr:
1925   {
1926     GST_ERROR ("failed to create packed prefix nal header buffer");
1927     gst_vaapi_codec_object_replace (&slice, NULL);
1928     return FALSE;
1929   }
1930 }
1931
1932 /* Generates and submits SPS header accordingly into the bitstream */
1933 static gboolean
1934 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1935 {
1936   GstVaapiEncSequence *sequence = NULL;
1937
1938   // Submit an SPS header before every new I-frame
1939   if (picture->type != GST_VAAPI_PICTURE_TYPE_I)
1940     return TRUE;
1941
1942   sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1943   if (!sequence || !fill_sequence (encoder, sequence))
1944     goto error_create_seq_param;
1945
1946   /* add subset sps for non-base view and sps for base view */
1947   if (encoder->is_mvc && encoder->view_idx) {
1948     if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS)
1949         && !add_packed_sequence_header_mvc (encoder, picture, sequence))
1950       goto error_create_packed_seq_hdr;
1951   } else {
1952     if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_SPS)
1953         && !add_packed_sequence_header (encoder, picture, sequence))
1954       goto error_create_packed_seq_hdr;
1955   }
1956
1957   if (sequence) {
1958     gst_vaapi_enc_picture_set_sequence (picture, sequence);
1959     gst_vaapi_codec_object_replace (&sequence, NULL);
1960   }
1961   return TRUE;
1962
1963   /* ERRORS */
1964 error_create_seq_param:
1965   {
1966     GST_ERROR ("failed to create sequence parameter buffer (SPS)");
1967     gst_vaapi_codec_object_replace (&sequence, NULL);
1968     return FALSE;
1969   }
1970 error_create_packed_seq_hdr:
1971   {
1972     GST_ERROR ("failed to create packed sequence header buffer");
1973     gst_vaapi_codec_object_replace (&sequence, NULL);
1974     return FALSE;
1975   }
1976 }
1977
1978 /* Generates additional control parameters */
1979 static gboolean
1980 ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1981 {
1982   GstVaapiEncMiscParam *misc = NULL;
1983   VAEncMiscParameterRateControl *rate_control;
1984
1985   /* HRD params */
1986   misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1987   g_assert (misc);
1988   if (!misc)
1989     return FALSE;
1990   fill_hrd_params (encoder, misc->data);
1991   gst_vaapi_enc_picture_add_misc_param (picture, misc);
1992   gst_vaapi_codec_object_replace (&misc, NULL);
1993
1994   /* RateControl params */
1995   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1996       GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1997     misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1998     g_assert (misc);
1999     if (!misc)
2000       return FALSE;
2001     rate_control = misc->data;
2002     memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
2003     rate_control->bits_per_second = encoder->bitrate_bits;
2004     rate_control->target_percentage = 70;
2005     rate_control->window_size = encoder->cpb_length;
2006     rate_control->initial_qp = encoder->init_qp;
2007     rate_control->min_qp = encoder->min_qp;
2008     rate_control->basic_unit_size = 0;
2009     gst_vaapi_enc_picture_add_misc_param (picture, misc);
2010     gst_vaapi_codec_object_replace (&misc, NULL);
2011   }
2012   return TRUE;
2013 }
2014
2015 /* Generates and submits PPS header accordingly into the bitstream */
2016 static gboolean
2017 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
2018     GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
2019 {
2020   GstVaapiCodedBuffer *const codedbuf =
2021       GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
2022   gboolean res = FALSE;
2023
2024   res = fill_picture (encoder, picture, codedbuf, surface);
2025
2026   if (!res)
2027     return FALSE;
2028
2029   if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
2030       (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) & VAEncPackedHeaderH264_PPS)
2031       && !add_packed_picture_header (encoder, picture)) {
2032     GST_ERROR ("set picture packed header failed");
2033     return FALSE;
2034   }
2035   return TRUE;
2036 }
2037
2038 /* Generates slice headers */
2039 static gboolean
2040 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
2041 {
2042   GstVaapiEncoderH264Ref *reflist_0[16];
2043   GstVaapiEncoderH264Ref *reflist_1[16];
2044   GstVaapiH264ViewRefPool *const ref_pool =
2045       &encoder->ref_pools[encoder->view_idx];
2046   guint reflist_0_count = 0, reflist_1_count = 0;
2047
2048   g_assert (picture);
2049
2050   if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
2051       !reference_list_init (encoder, picture,
2052           reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
2053     GST_ERROR ("reference list reorder failed");
2054     return FALSE;
2055   }
2056
2057   g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
2058   if (reflist_0_count > ref_pool->max_reflist0_count)
2059     reflist_0_count = ref_pool->max_reflist0_count;
2060   if (reflist_1_count > ref_pool->max_reflist1_count)
2061     reflist_1_count = ref_pool->max_reflist1_count;
2062
2063   if (!add_slice_headers (encoder, picture,
2064           reflist_0, reflist_0_count, reflist_1, reflist_1_count))
2065     return FALSE;
2066
2067   return TRUE;
2068 }
2069
2070 /* Normalizes bitrate (and CPB size) for HRD conformance */
2071 static void
2072 ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder)
2073 {
2074   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2075   guint bitrate, cpb_size;
2076
2077   if (!base_encoder->bitrate) {
2078     encoder->bitrate_bits = 0;
2079     return;
2080   }
2081
2082   /* Round down bitrate. This is a hard limit mandated by the user */
2083   g_assert (SX_BITRATE >= 6);
2084   bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
2085   GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
2086   encoder->bitrate_bits = bitrate;
2087
2088   /* Round up CPB size. This is an HRD compliance detail */
2089   g_assert (SX_CPB_SIZE >= 4);
2090   cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) &
2091       ~((1U << SX_CPB_SIZE) - 1);
2092   GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
2093   encoder->cpb_length_bits = cpb_size;
2094 }
2095
2096 /* Estimates a good enough bitrate if none was supplied */
2097 static void
2098 ensure_bitrate (GstVaapiEncoderH264 * encoder)
2099 {
2100   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2101
2102   /* Default compression: 48 bits per macroblock in "high-compression" mode */
2103   switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
2104     case GST_VAAPI_RATECONTROL_CBR:
2105     case GST_VAAPI_RATECONTROL_VBR:
2106     case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
2107       if (!base_encoder->bitrate) {
2108         /* According to the literature and testing, CABAC entropy coding
2109            mode could provide for +10% to +18% improvement in general,
2110            thus estimating +15% here ; and using adaptive 8x8 transforms
2111            in I-frames could bring up to +10% improvement. */
2112         guint bits_per_mb = 48;
2113         if (!encoder->use_cabac)
2114           bits_per_mb += (bits_per_mb * 15) / 100;
2115         if (!encoder->use_dct8x8)
2116           bits_per_mb += (bits_per_mb * 10) / 100;
2117
2118         base_encoder->bitrate =
2119             encoder->mb_width * encoder->mb_height * bits_per_mb *
2120             GST_VAAPI_ENCODER_FPS_N (encoder) /
2121             GST_VAAPI_ENCODER_FPS_D (encoder) / 1000;
2122         GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
2123       }
2124       break;
2125     default:
2126       base_encoder->bitrate = 0;
2127       break;
2128   }
2129   ensure_bitrate_hrd (encoder);
2130 }
2131
2132 /* Constructs profile and level information based on user-defined limits */
2133 static GstVaapiEncoderStatus
2134 ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
2135 {
2136   ensure_tuning (encoder);
2137
2138   if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
2139     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2140
2141   /* Check HW constraints */
2142   if (!ensure_hw_profile_limits (encoder))
2143     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2144   if (encoder->profile_idc > encoder->hw_max_profile_idc)
2145     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2146
2147   /* Ensure bitrate if not set already and derive the right level to use */
2148   ensure_bitrate (encoder);
2149   if (!ensure_level (encoder))
2150     return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
2151   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2152 }
2153
2154 static void
2155 reset_properties (GstVaapiEncoderH264 * encoder)
2156 {
2157   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
2158   guint mb_size, i;
2159
2160   if (encoder->idr_period < base_encoder->keyframe_period)
2161     encoder->idr_period = base_encoder->keyframe_period;
2162   if (encoder->idr_period > MAX_IDR_PERIOD)
2163     encoder->idr_period = MAX_IDR_PERIOD;
2164
2165   if (encoder->min_qp > encoder->init_qp ||
2166       (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
2167           encoder->min_qp < encoder->init_qp))
2168     encoder->min_qp = encoder->init_qp;
2169
2170   mb_size = encoder->mb_width * encoder->mb_height;
2171   if (encoder->num_slices > (mb_size + 1) / 2)
2172     encoder->num_slices = (mb_size + 1) / 2;
2173   g_assert (encoder->num_slices);
2174
2175   if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
2176     encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
2177
2178   if (encoder->num_bframes)
2179     encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
2180         GST_VAAPI_ENCODER_FPS_N (encoder);
2181   else
2182     encoder->cts_offset = 0;
2183
2184   /* init max_frame_num, max_poc */
2185   encoder->log2_max_frame_num =
2186       h264_get_log2_max_frame_num (encoder->idr_period);
2187   g_assert (encoder->log2_max_frame_num >= 4);
2188   encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
2189   encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
2190   encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
2191   encoder->idr_num = 0;
2192
2193   encoder->is_mvc = encoder->num_views > 1;
2194   for (i = 0; i < encoder->num_views; i++) {
2195     GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
2196     ref_pool->max_reflist0_count = 1;
2197     ref_pool->max_reflist1_count = encoder->num_bframes > 0;
2198     ref_pool->max_ref_frames = ref_pool->max_reflist0_count
2199         + ref_pool->max_reflist1_count;
2200
2201     GstVaapiH264ViewReorderPool *const reorder_pool =
2202         &encoder->reorder_pools[i];
2203     reorder_pool->frame_index = 0;
2204   }
2205 }
2206
2207 static GstVaapiEncoderStatus
2208 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base_encoder,
2209     GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
2210 {
2211   GstVaapiEncoderH264 *const encoder =
2212       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2213   GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2214   GstVaapiSurfaceProxy *reconstruct = NULL;
2215
2216   reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
2217
2218   g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
2219
2220   if (!ensure_sequence (encoder, picture))
2221     goto error;
2222   if (!ensure_misc_params (encoder, picture))
2223     goto error;
2224   if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
2225     goto error;
2226   if (!ensure_slices (encoder, picture))
2227     goto error;
2228   if (!gst_vaapi_enc_picture_encode (picture))
2229     goto error;
2230
2231   if (!reference_list_update (encoder, picture, reconstruct))
2232     goto error;
2233
2234   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2235 error:
2236   if (reconstruct)
2237     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
2238         reconstruct);
2239   return ret;
2240 }
2241
2242 static GstVaapiEncoderStatus
2243 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base_encoder)
2244 {
2245   GstVaapiEncoderH264 *const encoder =
2246       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2247   GstVaapiH264ViewReorderPool *reorder_pool;
2248   GstVaapiEncPicture *pic;
2249   guint i;
2250
2251   for (i = 0; i < encoder->num_views; i++) {
2252     reorder_pool = &encoder->reorder_pools[i];
2253     reorder_pool->frame_index = 0;
2254     reorder_pool->cur_frame_num = 0;
2255     reorder_pool->cur_present_index = 0;
2256
2257     while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2258       pic = (GstVaapiEncPicture *)
2259           g_queue_pop_head (&reorder_pool->reorder_frame_list);
2260       gst_vaapi_enc_picture_unref (pic);
2261     }
2262     g_queue_clear (&reorder_pool->reorder_frame_list);
2263   }
2264
2265   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2266 }
2267
2268 /* Generate "codec-data" buffer */
2269 static GstVaapiEncoderStatus
2270 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base_encoder,
2271     GstBuffer ** out_buffer_ptr)
2272 {
2273   GstVaapiEncoderH264 *const encoder =
2274       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2275   const guint32 configuration_version = 0x01;
2276   const guint32 nal_length_size = 4;
2277   guint8 profile_idc, profile_comp, level_idc;
2278   GstMapInfo sps_info, pps_info;
2279   GstBitWriter bs;
2280   GstBuffer *buffer;
2281
2282   if (!encoder->sps_data || !encoder->pps_data)
2283     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
2284   if (gst_buffer_get_size (encoder->sps_data) < 4)
2285     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
2286
2287   if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
2288     goto error_map_sps_buffer;
2289
2290   if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
2291     goto error_map_pps_buffer;
2292
2293   /* skip sps_data[0], which is the nal_unit_type */
2294   profile_idc = sps_info.data[1];
2295   profile_comp = sps_info.data[2];
2296   level_idc = sps_info.data[3];
2297
2298   /* Header */
2299   gst_bit_writer_init (&bs, (sps_info.size + pps_info.size + 64) * 8);
2300   WRITE_UINT32 (&bs, configuration_version, 8);
2301   WRITE_UINT32 (&bs, profile_idc, 8);
2302   WRITE_UINT32 (&bs, profile_comp, 8);
2303   WRITE_UINT32 (&bs, level_idc, 8);
2304   WRITE_UINT32 (&bs, 0x3f, 6);  /* 111111 */
2305   WRITE_UINT32 (&bs, nal_length_size - 1, 2);
2306   WRITE_UINT32 (&bs, 0x07, 3);  /* 111 */
2307
2308   /* Write SPS */
2309   WRITE_UINT32 (&bs, 1, 5);     /* SPS count = 1 */
2310   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
2311   WRITE_UINT32 (&bs, sps_info.size, 16);
2312   gst_bit_writer_put_bytes (&bs, sps_info.data, sps_info.size);
2313
2314   /* Write PPS */
2315   WRITE_UINT32 (&bs, 1, 8);     /* PPS count = 1 */
2316   WRITE_UINT32 (&bs, pps_info.size, 16);
2317   gst_bit_writer_put_bytes (&bs, pps_info.data, pps_info.size);
2318
2319   gst_buffer_unmap (encoder->pps_data, &pps_info);
2320   gst_buffer_unmap (encoder->sps_data, &sps_info);
2321
2322   buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs),
2323       GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
2324   if (!buffer)
2325     goto error_alloc_buffer;
2326   *out_buffer_ptr = buffer;
2327
2328   gst_bit_writer_clear (&bs, FALSE);
2329   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2330
2331   /* ERRORS */
2332 bs_error:
2333   {
2334     GST_ERROR ("failed to write codec-data");
2335     gst_buffer_unmap (encoder->sps_data, &sps_info);
2336     gst_buffer_unmap (encoder->pps_data, &pps_info);
2337     gst_bit_writer_clear (&bs, TRUE);
2338     return FALSE;
2339   }
2340 error_map_sps_buffer:
2341   {
2342     GST_ERROR ("failed to map SPS packed header");
2343     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2344   }
2345 error_map_pps_buffer:
2346   {
2347     GST_ERROR ("failed to map PPS packed header");
2348     gst_buffer_unmap (encoder->sps_data, &sps_info);
2349     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2350   }
2351 error_alloc_buffer:
2352   {
2353     GST_ERROR ("failed to allocate codec-data buffer");
2354     gst_bit_writer_clear (&bs, TRUE);
2355     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2356   }
2357 }
2358
2359 static GstVaapiEncoderStatus
2360 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base_encoder,
2361     GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
2362 {
2363   GstVaapiEncoderH264 *const encoder =
2364       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2365   GstVaapiH264ViewReorderPool *reorder_pool = NULL;
2366   GstVaapiEncPicture *picture;
2367   gboolean is_idr = FALSE;
2368
2369   *output = NULL;
2370
2371   /* encoding views alternatively for MVC */
2372   if (encoder->is_mvc) {
2373     if (frame)
2374       encoder->view_idx = frame->system_frame_number % MAX_NUM_VIEWS;
2375     else
2376       encoder->view_idx = (encoder->view_idx + 1) % MAX_NUM_VIEWS;
2377   }
2378   reorder_pool = &encoder->reorder_pools[encoder->view_idx];
2379
2380   if (!frame) {
2381     if (reorder_pool->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
2382       return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
2383
2384     /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
2385        dump B frames from queue, sometime, there may also have P frame or I frame */
2386     g_assert (encoder->num_bframes > 0);
2387     g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list),
2388         GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
2389     picture = g_queue_pop_head (&reorder_pool->reorder_frame_list);
2390     g_assert (picture);
2391     if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2392       reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
2393     }
2394     goto end;
2395   }
2396
2397   /* new frame coming */
2398   picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
2399   if (!picture) {
2400     GST_WARNING ("create H264 picture failed, frame timestamp:%"
2401         GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
2402     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2403   }
2404   ++reorder_pool->cur_present_index;
2405   picture->poc = ((reorder_pool->cur_present_index * 2) %
2406       encoder->max_pic_order_cnt);
2407
2408   is_idr = (reorder_pool->frame_index == 0 ||
2409       reorder_pool->frame_index >= encoder->idr_period);
2410
2411   /* check key frames */
2412   if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
2413       (reorder_pool->frame_index %
2414           GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) {
2415     ++reorder_pool->cur_frame_num;
2416     ++reorder_pool->frame_index;
2417
2418     /* b frame enabled,  check queue of reorder_frame_list */
2419     if (encoder->num_bframes
2420         && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2421       GstVaapiEncPicture *p_pic;
2422
2423       p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
2424       set_p_frame (p_pic, encoder);
2425       g_queue_foreach (&reorder_pool->reorder_frame_list,
2426           (GFunc) set_b_frame, encoder);
2427       ++reorder_pool->cur_frame_num;
2428       set_key_frame (picture, encoder, is_idr);
2429       g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
2430       picture = p_pic;
2431       reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
2432     } else {                    /* no b frames in queue */
2433       set_key_frame (picture, encoder, is_idr);
2434       g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list));
2435       if (encoder->num_bframes)
2436         reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
2437     }
2438     goto end;
2439   }
2440
2441   /* new p/b frames coming */
2442   ++reorder_pool->frame_index;
2443   if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
2444       g_queue_get_length (&reorder_pool->reorder_frame_list) <
2445       encoder->num_bframes) {
2446     g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
2447     return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
2448   }
2449
2450   ++reorder_pool->cur_frame_num;
2451   set_p_frame (picture, encoder);
2452
2453   if (reorder_pool->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
2454     g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame,
2455         encoder);
2456     reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
2457     g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list));
2458   }
2459
2460 end:
2461   g_assert (picture);
2462   frame = picture->frame;
2463   if (GST_CLOCK_TIME_IS_VALID (frame->pts))
2464     frame->pts += encoder->cts_offset;
2465   *output = picture;
2466
2467   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2468 }
2469
2470 static GstVaapiEncoderStatus
2471 set_context_info (GstVaapiEncoder * base_encoder)
2472 {
2473   GstVaapiEncoderH264 *const encoder =
2474       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2475   GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
2476   const guint DEFAULT_SURFACES_COUNT = 3;
2477
2478   /* Maximum sizes for common headers (in bits) */
2479   enum
2480   {
2481     MAX_SPS_HDR_SIZE = 16473,
2482     MAX_VUI_PARAMS_SIZE = 210,
2483     MAX_HRD_PARAMS_SIZE = 4103,
2484     MAX_PPS_HDR_SIZE = 101,
2485     MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
2486   };
2487
2488   if (!ensure_hw_profile (encoder))
2489     return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2490
2491   base_encoder->num_ref_frames =
2492       ((encoder->num_bframes ? 2 : 1) + DEFAULT_SURFACES_COUNT)
2493       * encoder->num_views;
2494
2495   /* Only YUV 4:2:0 formats are supported for now. This means that we
2496      have a limit of 3200 bits per macroblock. */
2497   /* XXX: check profile and compute RawMbBits */
2498   base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
2499       GST_ROUND_UP_16 (vip->height) / 256) * 400;
2500
2501   /* Account for SPS header */
2502   /* XXX: exclude scaling lists, MVC/SVC extensions */
2503   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
2504       MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
2505
2506   /* Account for PPS header */
2507   /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
2508   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
2509
2510   /* Account for slice header */
2511   base_encoder->codedbuf_size += encoder->num_slices * (4 +
2512       GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
2513
2514   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2515 }
2516
2517 static GstVaapiEncoderStatus
2518 gst_vaapi_encoder_h264_reconfigure (GstVaapiEncoder * base_encoder)
2519 {
2520   GstVaapiEncoderH264 *const encoder =
2521       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2522   GstVaapiEncoderStatus status;
2523
2524   encoder->mb_width = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
2525   encoder->mb_height = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
2526
2527   status = ensure_profile_and_level (encoder);
2528   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
2529     return status;
2530
2531   reset_properties (encoder);
2532   return set_context_info (base_encoder);
2533 }
2534
2535 static gboolean
2536 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base_encoder)
2537 {
2538   GstVaapiEncoderH264 *const encoder =
2539       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2540   guint32 i;
2541
2542   /* Multi-view coding information */
2543   encoder->is_mvc = FALSE;
2544   encoder->num_views = 1;
2545   encoder->view_idx = 0;
2546
2547   /* re-ordering  list initialize */
2548   for (i = 0; i < MAX_NUM_VIEWS; i++) {
2549     GstVaapiH264ViewReorderPool *const reorder_pool =
2550         &encoder->reorder_pools[i];
2551     g_queue_init (&reorder_pool->reorder_frame_list);
2552     reorder_pool->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
2553     reorder_pool->frame_index = 0;
2554     reorder_pool->cur_frame_num = 0;
2555     reorder_pool->cur_present_index = 0;
2556   }
2557
2558   /* reference list info initialize */
2559   for (i = 0; i < MAX_NUM_VIEWS; i++) {
2560     GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
2561     g_queue_init (&ref_pool->ref_list);
2562     ref_pool->max_ref_frames = 0;
2563     ref_pool->max_reflist0_count = 1;
2564     ref_pool->max_reflist1_count = 1;
2565   }
2566
2567   return TRUE;
2568 }
2569
2570 static void
2571 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base_encoder)
2572 {
2573   /*free private buffers */
2574   GstVaapiEncoderH264 *const encoder =
2575       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2576   GstVaapiEncPicture *pic;
2577   GstVaapiEncoderH264Ref *ref;
2578   guint32 i;
2579
2580   gst_buffer_replace (&encoder->sps_data, NULL);
2581   gst_buffer_replace (&encoder->subset_sps_data, NULL);
2582   gst_buffer_replace (&encoder->pps_data, NULL);
2583
2584   /* reference list info de-init */
2585   for (i = 0; i < MAX_NUM_VIEWS; i++) {
2586     GstVaapiH264ViewRefPool *const ref_pool = &encoder->ref_pools[i];
2587     while (!g_queue_is_empty (&ref_pool->ref_list)) {
2588       ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&ref_pool->ref_list);
2589       reference_pic_free (encoder, ref);
2590     }
2591     g_queue_clear (&ref_pool->ref_list);
2592   }
2593
2594   /* re-ordering  list initialize */
2595   for (i = 0; i < MAX_NUM_VIEWS; i++) {
2596     GstVaapiH264ViewReorderPool *const reorder_pool =
2597         &encoder->reorder_pools[i];
2598     while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2599       pic = (GstVaapiEncPicture *)
2600           g_queue_pop_head (&reorder_pool->reorder_frame_list);
2601       gst_vaapi_enc_picture_unref (pic);
2602     }
2603     g_queue_clear (&reorder_pool->reorder_frame_list);
2604   }
2605 }
2606
2607 static GstVaapiEncoderStatus
2608 gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
2609     gint prop_id, const GValue * value)
2610 {
2611   GstVaapiEncoderH264 *const encoder =
2612       GST_VAAPI_ENCODER_H264_CAST (base_encoder);
2613
2614   switch (prop_id) {
2615     case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
2616       encoder->num_bframes = g_value_get_uint (value);
2617       break;
2618     case GST_VAAPI_ENCODER_H264_PROP_INIT_QP:
2619       encoder->init_qp = g_value_get_uint (value);
2620       break;
2621     case GST_VAAPI_ENCODER_H264_PROP_MIN_QP:
2622       encoder->min_qp = g_value_get_uint (value);
2623       break;
2624     case GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES:
2625       encoder->num_slices = g_value_get_uint (value);
2626       break;
2627     case GST_VAAPI_ENCODER_H264_PROP_CABAC:
2628       encoder->use_cabac = g_value_get_boolean (value);
2629       break;
2630     case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
2631       encoder->use_dct8x8 = g_value_get_boolean (value);
2632       break;
2633     case GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH:
2634       encoder->cpb_length = g_value_get_uint (value);
2635       break;
2636     case GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS:
2637       encoder->num_views = g_value_get_uint (value);
2638       break;
2639     default:
2640       return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
2641   }
2642   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2643 }
2644
2645 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H264);
2646
2647 static inline const GstVaapiEncoderClass *
2648 gst_vaapi_encoder_h264_class (void)
2649 {
2650   static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
2651     GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
2652     .set_property = gst_vaapi_encoder_h264_set_property,
2653     .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
2654   };
2655   return &GstVaapiEncoderH264Class;
2656 }
2657
2658 /**
2659  * gst_vaapi_encoder_h264_new:
2660  * @display: a #GstVaapiDisplay
2661  *
2662  * Creates a new #GstVaapiEncoder for H.264 encoding. Note that the
2663  * only supported output stream format is "byte-stream" format.
2664  *
2665  * Return value: the newly allocated #GstVaapiEncoder object
2666  */
2667 GstVaapiEncoder *
2668 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
2669 {
2670   return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
2671 }
2672
2673 /**
2674  * gst_vaapi_encoder_h264_get_default_properties:
2675  *
2676  * Determines the set of common and H.264 specific encoder properties.
2677  * The caller owns an extra reference to the resulting array of
2678  * #GstVaapiEncoderPropInfo elements, so it shall be released with
2679  * g_ptr_array_unref() after usage.
2680  *
2681  * Return value: the set of encoder properties for #GstVaapiEncoderH264,
2682  *   or %NULL if an error occurred.
2683  */
2684 GPtrArray *
2685 gst_vaapi_encoder_h264_get_default_properties (void)
2686 {
2687   const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h264_class ();
2688   GPtrArray *props;
2689
2690   props = gst_vaapi_encoder_properties_get_default (klass);
2691   if (!props)
2692     return NULL;
2693
2694   /**
2695    * GstVaapiEncoderH264:max-bframes:
2696    *
2697    * The number of B-frames between I and P.
2698    */
2699   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2700       GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES,
2701       g_param_spec_uint ("max-bframes",
2702           "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
2703           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2704
2705   /**
2706    * GstVaapiEncoderH264:init-qp:
2707    *
2708    * The initial quantizer value.
2709    */
2710   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2711       GST_VAAPI_ENCODER_H264_PROP_INIT_QP,
2712       g_param_spec_uint ("init-qp",
2713           "Initial QP", "Initial quantizer value", 1, 51, 26,
2714           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2715
2716   /**
2717    * GstVaapiEncoderH264:min-qp:
2718    *
2719    * The minimum quantizer value.
2720    */
2721   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2722       GST_VAAPI_ENCODER_H264_PROP_MIN_QP,
2723       g_param_spec_uint ("min-qp",
2724           "Minimum QP", "Minimum quantizer value", 1, 51, 1,
2725           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2726
2727   /**
2728    * GstVaapiEncoderH264:num-slices:
2729    *
2730    * The number of slices per frame.
2731    */
2732   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2733       GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES,
2734       g_param_spec_uint ("num-slices",
2735           "Number of Slices",
2736           "Number of slices per frame",
2737           1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2738
2739   /**
2740    * GstVaapiEncoderH264:cabac:
2741    *
2742    * Enable CABAC entropy coding mode for improved compression ratio,
2743    * at the expense that the minimum target profile is Main. Default
2744    * is CAVLC entropy coding mode.
2745    */
2746   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2747       GST_VAAPI_ENCODER_H264_PROP_CABAC,
2748       g_param_spec_boolean ("cabac",
2749           "Enable CABAC",
2750           "Enable CABAC entropy coding mode",
2751           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2752
2753   /**
2754    * GstVaapiEncoderH264:dct8x8:
2755    *
2756    * Enable adaptive use of 8x8 transforms in I-frames. This improves
2757    * the compression ratio by the minimum target profile is High.
2758    * Default is to use 4x4 DCT only.
2759    */
2760   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2761       GST_VAAPI_ENCODER_H264_PROP_DCT8X8,
2762       g_param_spec_boolean ("dct8x8",
2763           "Enable 8x8 DCT",
2764           "Enable adaptive use of 8x8 transforms in I-frames",
2765           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2766
2767   /**
2768    * GstVaapiEncoderH264:cpb-length:
2769    *
2770    * The size of the CPB buffer in milliseconds.
2771    */
2772   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2773       GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH,
2774       g_param_spec_uint ("cpb-length",
2775           "CPB Length", "Length of the CPB buffer in milliseconds",
2776           1, 10000, DEFAULT_CPB_LENGTH,
2777           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2778
2779   /**
2780    * GstVaapiEncoderH264:num-views:
2781    *
2782    * The number of views for MVC encoding .
2783    */
2784   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2785       GST_VAAPI_ENCODER_H264_PROP_NUM_VIEWS,
2786       g_param_spec_uint ("num-views",
2787           "Number of Views",
2788           "Number of Views for MVC encoding",
2789           1, MAX_NUM_VIEWS, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2790
2791   return props;
2792 }
2793
2794 /**
2795  * gst_vaapi_encoder_h264_set_max_profile:
2796  * @encoder: a #GstVaapiEncoderH264
2797  * @profile: an H.264 #GstVaapiProfile
2798  *
2799  * Notifies the @encoder to use coding tools from the supplied
2800  * @profile at most.
2801  *
2802  * This means that if the minimal profile derived to
2803  * support the specified coding tools is greater than this @profile,
2804  * then an error is returned when the @encoder is configured.
2805  *
2806  * Return value: %TRUE on success
2807  */
2808 gboolean
2809 gst_vaapi_encoder_h264_set_max_profile (GstVaapiEncoderH264 * encoder,
2810     GstVaapiProfile profile)
2811 {
2812   guint8 profile_idc;
2813
2814   g_return_val_if_fail (encoder != NULL, FALSE);
2815   g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
2816
2817   if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H264)
2818     return FALSE;
2819
2820   profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
2821   if (!profile_idc)
2822     return FALSE;
2823
2824   encoder->max_profile_idc = profile_idc;
2825   return TRUE;
2826 }
2827
2828 /**
2829  * gst_vaapi_encoder_h264_get_profile_and_level:
2830  * @encoder: a #GstVaapiEncoderH264
2831  * @out_profile_ptr: return location for the #GstVaapiProfile
2832  * @out_level_ptr: return location for the #GstVaapiLevelH264
2833  *
2834  * Queries the H.264 @encoder for the active profile and level. That
2835  * information is only constructed and valid after the encoder is
2836  * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
2837  * function is called.
2838  *
2839  * Return value: %TRUE on success
2840  */
2841 gboolean
2842 gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
2843     GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
2844 {
2845   g_return_val_if_fail (encoder != NULL, FALSE);
2846
2847   if (!encoder->profile || !encoder->level)
2848     return FALSE;
2849
2850   if (out_profile_ptr)
2851     *out_profile_ptr = encoder->profile;
2852   if (out_level_ptr)
2853     *out_level_ptr = encoder->level;
2854   return TRUE;
2855 }