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