encoder: fix indentation.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapiencoder_h264.c
1 /*
2  *  gstvaapiencoder_h264.c - H.264 encoder
3  *
4  *  Copyright (C) 2012 -2013 Intel Corporation
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public License
8  *  as published by the Free Software Foundation; either version 2.1
9  *  of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free
18  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301 USA
20  */
21
22 #include "sysdeps.h"
23 #include "gstvaapicompat.h"
24 #include "gstvaapiencoder_h264.h"
25 #include "gstvaapiencoder_h264_priv.h"
26 #include "gstvaapiencoder_priv.h"
27 #include "gstvaapicodedbufferproxy_priv.h"
28
29 #include <va/va.h>
30 #include <va/va_enc_h264.h>
31
32 #include "gstvaapicontext.h"
33 #include "gstvaapisurface.h"
34 #include "gstvaapidisplay_priv.h"
35
36 #define DEBUG 1
37 #include "gstvaapidebug.h"
38
39 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE        0
40 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW         1
41 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM      2
42 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH        3
43
44 typedef enum
45 {
46   GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CAVLC = 0,
47   GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC = 1
48 } GstVaapiEncoderH264EntropyMode;
49
50 typedef enum
51 {
52   GST_VAAPI_ENCODER_H264_NAL_UNKNOWN = 0,
53   GST_VAAPI_ENCODER_H264_NAL_NON_IDR = 1,
54   GST_VAAPI_ENCODER_H264_NAL_IDR = 5,   /* ref_idc != 0 */
55   GST_VAAPI_ENCODER_H264_NAL_SEI = 6,   /* ref_idc == 0 */
56   GST_VAAPI_ENCODER_H264_NAL_SPS = 7,
57   GST_VAAPI_ENCODER_H264_NAL_PPS = 8
58 } GstVaapiEncoderH264NalType;
59
60 typedef enum
61 {
62   SLICE_TYPE_P = 0,
63   SLICE_TYPE_B = 1,
64   SLICE_TYPE_I = 2
65 } H264_SLICE_TYPE;
66
67 typedef struct
68 {
69   GstVaapiSurfaceProxy *pic;
70   guint poc;
71   guint frame_num;
72 } GstVaapiEncoderH264Ref;
73
74 #define GST_VAAPI_H264_CAPS                                \
75         "video/x-h264, "                                   \
76         "framerate = (fraction) [0/1, MAX], "              \
77         "width = (int) [ 1, MAX ], "                       \
78         "height = (int) [ 1, MAX ], "                      \
79         "stream-format = (string) { avc, byte-stream }, "  \
80         "alignment = (string) { au } "
81
82 typedef enum
83 {
84   GST_VAAPI_ENC_H264_REORD_NONE = 0,
85   GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES = 1,
86   GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES = 2
87 } GstVaapiEncH264ReorderState;
88
89 static inline gboolean
90 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
91 {
92   return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
93 }
94
95 static inline guint8
96 _get_va_slice_type (GstVaapiPictureType type)
97 {
98   switch (type) {
99     case GST_VAAPI_PICTURE_TYPE_I:
100       return 2;
101     case GST_VAAPI_PICTURE_TYPE_P:
102       return 0;
103     case GST_VAAPI_PICTURE_TYPE_B:
104       return 1;
105     default:
106       return -1;
107   }
108   return -1;
109 }
110
111 static inline gboolean
112 _read_sps_attributes (const guint8 * sps_data,
113     guint32 sps_size,
114     guint32 * profile_idc, guint32 * profile_comp, guint32 * level_idc)
115 {
116   g_assert (profile_idc && profile_comp && level_idc);
117   g_assert (sps_size >= 4);
118   if (sps_size < 4) {
119     return FALSE;
120   }
121   /* skip sps_data[0], nal_type */
122   *profile_idc = sps_data[1];
123   *profile_comp = sps_data[2];
124   *level_idc = sps_data[3];
125   return TRUE;
126 }
127
128 static inline guint
129 _get_log2_max_frame_num (guint num)
130 {
131   guint ret = 0;
132
133   while (num) {
134     ++ret;
135     num >>= 1;
136   }
137   if (ret <= 4)
138     ret = 4;
139   else if (ret > 10)
140     ret = 10;
141   /* must greater than 4 */
142   return ret;
143 }
144
145 static inline guint
146 _profile_to_value (GstVaapiProfile profile)
147 {
148   switch (profile) {
149     case GST_VAAPI_PROFILE_H264_BASELINE:
150       return 66;
151     case GST_VAAPI_PROFILE_H264_MAIN:
152       return 77;
153     case GST_VAAPI_PROFILE_H264_HIGH:
154       return 100;
155     default:
156       break;
157   }
158   return 0;
159 }
160
161 static inline void
162 _check_sps_pps_status (GstVaapiEncoderH264 * encoder,
163     const guint8 * nal, guint32 size)
164 {
165   guint8 nal_type;
166   gsize ret;
167
168   g_assert (size);
169
170   if (encoder->sps_data && encoder->pps_data)
171     return;
172
173   nal_type = nal[0] & 0x1F;
174   switch (nal_type) {
175     case GST_VAAPI_ENCODER_H264_NAL_SPS:
176       encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
177       ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
178       g_assert (ret == size);
179       break;
180     case GST_VAAPI_ENCODER_H264_NAL_PPS:
181       encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
182       ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
183       g_assert (ret == size);
184       break;
185     default:
186       break;
187   }
188 }
189
190 static void
191 _set_level (GstVaapiEncoderH264 * encoder)
192 {
193   guint pic_mb_size;
194   guint MaxDpbMbs, MaxMBPS;
195   guint dbp_level, mbps_level, profile_level;
196
197   if (encoder->level) {
198     if (encoder->level < GST_VAAPI_ENCODER_H264_LEVEL_10)
199       encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_10;
200     else if (encoder->level > GST_VAAPI_ENCODER_H264_LEVEL_51)
201       encoder->level = GST_VAAPI_ENCODER_H264_LEVEL_51;
202     return;
203   }
204
205   /* calculate level */
206   pic_mb_size = ((GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16) *
207       ((GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16);
208   MaxDpbMbs = pic_mb_size * ((encoder->b_frame_num) ? 2 : 1);
209   MaxMBPS = pic_mb_size * GST_VAAPI_ENCODER_FPS_N (encoder) /
210       GST_VAAPI_ENCODER_FPS_D (encoder);
211
212   /* calculate from MaxDbpMbs */
213   if (MaxDpbMbs > 110400)
214     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_51;
215   else if (MaxDpbMbs > 34816)
216     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_50;
217   else if (MaxDpbMbs > 32768)
218     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_42;
219   else if (MaxDpbMbs > 20480)   /* 41 or 40 */
220     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
221   else if (MaxDpbMbs > 18000)
222     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_32;
223   else if (MaxDpbMbs > 8100)
224     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_31;
225   else if (MaxDpbMbs > 4752)    /* 30 or 22 */
226     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
227   else if (MaxDpbMbs > 2376)
228     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_21;
229   else if (MaxDpbMbs > 900)     /* 20, 13, 12 */
230     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
231   else if (MaxDpbMbs > 396)
232     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_11;
233   else
234     dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_10;
235
236   /* calculate from Max Mb processing rate */
237   if (MaxMBPS > 589824)
238     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_51;
239   else if (MaxMBPS > 522240)
240     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_50;
241   else if (MaxMBPS > 245760)
242     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_42;
243   else if (MaxMBPS > 216000)    /* 40 or 41 */
244     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
245   else if (MaxMBPS > 108000)
246     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_32;
247   else if (MaxMBPS > 40500)
248     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_31;
249   else if (MaxMBPS > 20250)
250     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
251   else if (MaxMBPS > 19800)
252     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_22;
253   else if (MaxMBPS > 11800)
254     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_21;
255   else if (MaxMBPS > 6000)      /*13 or 20 */
256     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
257   else if (MaxMBPS > 3000)
258     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_12;
259   else if (MaxMBPS > 1485)
260     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_11;
261   else
262     mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_10;
263
264   if (encoder->profile == GST_VAAPI_PROFILE_H264_HIGH)
265     profile_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
266   else if (encoder->profile == GST_VAAPI_PROFILE_H264_MAIN)
267     profile_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
268   else
269     profile_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
270
271   encoder->level = (dbp_level > mbps_level ? dbp_level : mbps_level);
272   if (encoder->level < profile_level)
273     encoder->level = profile_level;
274 }
275
276 static inline void
277 _reset_gop_start (GstVaapiEncoderH264 * encoder)
278 {
279   ++encoder->idr_num;
280   encoder->frame_index = 1;
281   encoder->cur_frame_num = 0;
282   encoder->cur_present_index = 0;
283 }
284
285 static void
286 _set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
287 {
288   g_assert (pic && encoder);
289   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
290   pic->type = GST_VAAPI_PICTURE_TYPE_B;
291   pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
292 }
293
294 static inline void
295 _set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
296 {
297   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
298   pic->type = GST_VAAPI_PICTURE_TYPE_P;
299   pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
300 }
301
302 static inline void
303 _set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
304 {
305   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
306   pic->type = GST_VAAPI_PICTURE_TYPE_I;
307   pic->frame_num = (encoder->cur_frame_num % encoder->max_frame_num);
308   g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
309   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
310 }
311
312 static inline void
313 _set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH264 * encoder)
314 {
315   g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
316   pic->type = GST_VAAPI_PICTURE_TYPE_I;
317   pic->frame_num = 0;
318   pic->poc = 0;
319   GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
320
321   g_assert (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
322   GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (GST_VAAPI_ENC_PICTURE_GET_FRAME (pic));
323 }
324
325 static inline void
326 _set_key_frame (GstVaapiEncPicture * picture,
327     GstVaapiEncoderH264 * encoder, gboolean is_idr)
328 {
329   if (is_idr) {
330     _reset_gop_start (encoder);
331     _set_idr_frame (picture, encoder);
332   } else
333     _set_i_frame (picture, encoder);
334 }
335
336 gboolean
337 gst_bit_writer_put_ue (GstBitWriter * bitwriter, guint32 value)
338 {
339   guint32 size_in_bits = 0;
340   guint32 tmp_value = ++value;
341
342   while (tmp_value) {
343     ++size_in_bits;
344     tmp_value >>= 1;
345   }
346   if (size_in_bits > 1
347       && !gst_bit_writer_put_bits_uint32 (bitwriter, 0, size_in_bits - 1))
348     return FALSE;
349   if (!gst_bit_writer_put_bits_uint32 (bitwriter, value, size_in_bits))
350     return FALSE;
351   return TRUE;
352 }
353
354 gboolean
355 gst_bit_writer_put_se (GstBitWriter * bitwriter, gint32 value)
356 {
357   guint32 new_val;
358
359   if (value <= 0)
360     new_val = -(value << 1);
361   else
362     new_val = (value << 1) - 1;
363
364   if (!gst_bit_writer_put_ue (bitwriter, new_val))
365     return FALSE;
366   return TRUE;
367 }
368
369
370 static gboolean
371 gst_bit_writer_write_nal_header (GstBitWriter * bitwriter,
372     guint32 nal_ref_idc, guint32 nal_unit_type)
373 {
374   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
375   gst_bit_writer_put_bits_uint32 (bitwriter, nal_ref_idc, 2);
376   gst_bit_writer_put_bits_uint32 (bitwriter, nal_unit_type, 5);
377   return TRUE;
378 }
379
380 static gboolean
381 gst_bit_writer_write_trailing_bits (GstBitWriter * bitwriter)
382 {
383   gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
384   gst_bit_writer_align_bytes_unchecked (bitwriter, 0);
385   return TRUE;
386 }
387
388 static gboolean
389 gst_bit_writer_write_sps (GstBitWriter * bitwriter,
390     VAEncSequenceParameterBufferH264 * seq, GstVaapiProfile profile)
391 {
392   guint32 constraint_set0_flag, constraint_set1_flag;
393   guint32 constraint_set2_flag, constraint_set3_flag;
394   guint32 gaps_in_frame_num_value_allowed_flag = 0;     // ??
395   gboolean nal_hrd_parameters_present_flag;
396
397   guint32 b_qpprime_y_zero_transform_bypass = 0;
398   guint32 residual_color_transform_flag = 0;
399   guint32 pic_height_in_map_units =
400       (seq->seq_fields.bits.frame_mbs_only_flag ?
401       seq->picture_height_in_mbs : seq->picture_height_in_mbs / 2);
402   guint32 mb_adaptive_frame_field = !seq->seq_fields.bits.frame_mbs_only_flag;
403   guint32 i = 0;
404
405   constraint_set0_flag = profile == GST_VAAPI_PROFILE_H264_BASELINE;
406   constraint_set1_flag = profile <= GST_VAAPI_PROFILE_H264_MAIN;
407   constraint_set2_flag = 0;
408   constraint_set3_flag = 0;
409
410   /* profile_idc */
411   gst_bit_writer_put_bits_uint32 (bitwriter, _profile_to_value (profile), 8);
412   /* constraint_set0_flag */
413   gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set0_flag, 1);
414   /* constraint_set1_flag */
415   gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set1_flag, 1);
416   /* constraint_set2_flag */
417   gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set2_flag, 1);
418   /* constraint_set3_flag */
419   gst_bit_writer_put_bits_uint32 (bitwriter, constraint_set3_flag, 1);
420   /* reserved_zero_4bits */
421   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 4);
422   /* level_idc */
423   gst_bit_writer_put_bits_uint32 (bitwriter, seq->level_idc, 8);
424   /* seq_parameter_set_id */
425   gst_bit_writer_put_ue (bitwriter, seq->seq_parameter_set_id);
426
427   if (profile == GST_VAAPI_PROFILE_H264_HIGH) {
428     /* for high profile */
429     /* chroma_format_idc  = 1, 4:2:0 */
430     gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.chroma_format_idc);
431     if (3 == seq->seq_fields.bits.chroma_format_idc) {
432       gst_bit_writer_put_bits_uint32 (bitwriter, residual_color_transform_flag,
433           1);
434     }
435     /* bit_depth_luma_minus8 */
436     gst_bit_writer_put_ue (bitwriter, seq->bit_depth_luma_minus8);
437     /* bit_depth_chroma_minus8 */
438     gst_bit_writer_put_ue (bitwriter, seq->bit_depth_chroma_minus8);
439     /* b_qpprime_y_zero_transform_bypass */
440     gst_bit_writer_put_bits_uint32 (bitwriter,
441         b_qpprime_y_zero_transform_bypass, 1);
442     g_assert (seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
443     /*seq_scaling_matrix_present_flag  */
444     gst_bit_writer_put_bits_uint32 (bitwriter,
445         seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1);
446
447 #if 0
448     if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) {
449       for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12);
450           i++) {
451         gst_bit_writer_put_bits_uint8 (bitwriter,
452             seq->seq_fields.bits.seq_scaling_list_present_flag, 1);
453         if (seq->seq_fields.bits.seq_scaling_list_present_flag) {
454           g_assert (0);
455           /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1 */
456         }
457       }
458     }
459 #endif
460   }
461
462   /* log2_max_frame_num_minus4 */
463   gst_bit_writer_put_ue (bitwriter,
464       seq->seq_fields.bits.log2_max_frame_num_minus4);
465   /* pic_order_cnt_type */
466   gst_bit_writer_put_ue (bitwriter, seq->seq_fields.bits.pic_order_cnt_type);
467
468   if (seq->seq_fields.bits.pic_order_cnt_type == 0) {
469     /* log2_max_pic_order_cnt_lsb_minus4 */
470     gst_bit_writer_put_ue (bitwriter,
471         seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
472   } else if (seq->seq_fields.bits.pic_order_cnt_type == 1) {
473     g_assert (0);
474     gst_bit_writer_put_bits_uint32 (bitwriter,
475         seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
476     gst_bit_writer_put_se (bitwriter, seq->offset_for_non_ref_pic);
477     gst_bit_writer_put_se (bitwriter, seq->offset_for_top_to_bottom_field);
478     gst_bit_writer_put_ue (bitwriter,
479         seq->num_ref_frames_in_pic_order_cnt_cycle);
480     for (i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) {
481       gst_bit_writer_put_se (bitwriter, seq->offset_for_ref_frame[i]);
482     }
483   }
484
485   /* num_ref_frames */
486   gst_bit_writer_put_ue (bitwriter, seq->max_num_ref_frames);
487   /* gaps_in_frame_num_value_allowed_flag */
488   gst_bit_writer_put_bits_uint32 (bitwriter,
489       gaps_in_frame_num_value_allowed_flag, 1);
490
491   /* pic_width_in_mbs_minus1 */
492   gst_bit_writer_put_ue (bitwriter, seq->picture_width_in_mbs - 1);
493   /* pic_height_in_map_units_minus1 */
494   gst_bit_writer_put_ue (bitwriter, pic_height_in_map_units - 1);
495   /* frame_mbs_only_flag */
496   gst_bit_writer_put_bits_uint32 (bitwriter,
497       seq->seq_fields.bits.frame_mbs_only_flag, 1);
498
499   if (!seq->seq_fields.bits.frame_mbs_only_flag) {      //ONLY mbs
500     g_assert (0);
501     gst_bit_writer_put_bits_uint32 (bitwriter, mb_adaptive_frame_field, 1);
502   }
503
504   /* direct_8x8_inference_flag */
505   gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
506   /* frame_cropping_flag */
507   gst_bit_writer_put_bits_uint32 (bitwriter, seq->frame_cropping_flag, 1);
508
509   if (seq->frame_cropping_flag) {
510     /* frame_crop_left_offset */
511     gst_bit_writer_put_ue (bitwriter, seq->frame_crop_left_offset);
512     /* frame_crop_right_offset */
513     gst_bit_writer_put_ue (bitwriter, seq->frame_crop_right_offset);
514     /* frame_crop_top_offset */
515     gst_bit_writer_put_ue (bitwriter, seq->frame_crop_top_offset);
516     /* frame_crop_bottom_offset */
517     gst_bit_writer_put_ue (bitwriter, seq->frame_crop_bottom_offset);
518   }
519
520   /* vui_parameters_present_flag */
521   gst_bit_writer_put_bits_uint32 (bitwriter, seq->vui_parameters_present_flag,
522       1);
523   if (seq->vui_parameters_present_flag) {
524     /* aspect_ratio_info_present_flag */
525     gst_bit_writer_put_bits_uint32 (bitwriter,
526         seq->vui_fields.bits.aspect_ratio_info_present_flag, 1);
527     if (seq->vui_fields.bits.aspect_ratio_info_present_flag) {
528       gst_bit_writer_put_bits_uint32 (bitwriter, seq->aspect_ratio_idc, 8);
529       if (seq->aspect_ratio_idc == 0xFF) {
530         gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_width, 16);
531         gst_bit_writer_put_bits_uint32 (bitwriter, seq->sar_height, 16);
532       }
533     }
534
535     /* overscan_info_present_flag */
536     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
537     /* video_signal_type_present_flag */
538     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
539     /* chroma_loc_info_present_flag */
540     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
541
542     /* timing_info_present_flag */
543     gst_bit_writer_put_bits_uint32 (bitwriter,
544         seq->vui_fields.bits.timing_info_present_flag, 1);
545     if (seq->vui_fields.bits.timing_info_present_flag) {
546       gst_bit_writer_put_bits_uint32 (bitwriter, seq->num_units_in_tick, 32);
547       gst_bit_writer_put_bits_uint32 (bitwriter, seq->time_scale, 32);
548       gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1); /* fixed_frame_rate_flag */
549     }
550
551     nal_hrd_parameters_present_flag = (seq->bits_per_second > 0 ? TRUE : FALSE);
552     /* nal_hrd_parameters_present_flag */
553     gst_bit_writer_put_bits_uint32 (bitwriter, nal_hrd_parameters_present_flag,
554         1);
555     if (nal_hrd_parameters_present_flag) {
556       /* hrd_parameters */
557       /* cpb_cnt_minus1 */
558       gst_bit_writer_put_ue (bitwriter, 0);
559       gst_bit_writer_put_bits_uint32 (bitwriter, 4, 4); /* bit_rate_scale */
560       gst_bit_writer_put_bits_uint32 (bitwriter, 6, 4); /* cpb_size_scale */
561
562       for (i = 0; i < 1; ++i) {
563         /* bit_rate_value_minus1[0] */
564         gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 - 1);
565         /* cpb_size_value_minus1[0] */
566         gst_bit_writer_put_ue (bitwriter, seq->bits_per_second / 1024 * 8 - 1);
567         /* cbr_flag[0] */
568         gst_bit_writer_put_bits_uint32 (bitwriter, 1, 1);
569       }
570       /* initial_cpb_removal_delay_length_minus1 */
571       gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
572       /* cpb_removal_delay_length_minus1 */
573       gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
574       /* dpb_output_delay_length_minus1 */
575       gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
576       /* time_offset_length  */
577       gst_bit_writer_put_bits_uint32 (bitwriter, 23, 5);
578     }
579     /* vcl_hrd_parameters_present_flag */
580     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
581     if (nal_hrd_parameters_present_flag
582         || 0 /*vcl_hrd_parameters_present_flag */ ) {
583       /* low_delay_hrd_flag */
584       gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
585     }
586     /* pic_struct_present_flag */
587     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
588     /* bitwriter_restriction_flag */
589     gst_bit_writer_put_bits_uint32 (bitwriter, 0, 1);
590   }
591
592   /* rbsp_trailing_bits */
593   gst_bit_writer_write_trailing_bits (bitwriter);
594   return TRUE;
595 }
596
597 static gboolean
598 gst_bit_writer_write_pps (GstBitWriter * bitwriter,
599     VAEncPictureParameterBufferH264 * pic)
600 {
601   guint32 num_slice_groups_minus1 = 0;
602   guint32 pic_init_qs_minus26 = 0;
603   guint32 redundant_pic_cnt_present_flag = 0;
604
605   /* pic_parameter_set_id */
606   gst_bit_writer_put_ue (bitwriter, pic->pic_parameter_set_id);
607   /* seq_parameter_set_id */
608   gst_bit_writer_put_ue (bitwriter, pic->seq_parameter_set_id);
609   /* entropy_coding_mode_flag */
610   gst_bit_writer_put_bits_uint32 (bitwriter,
611       pic->pic_fields.bits.entropy_coding_mode_flag, 1);
612   /* pic_order_present_flag */
613   gst_bit_writer_put_bits_uint32 (bitwriter,
614       pic->pic_fields.bits.pic_order_present_flag, 1);
615   /*slice_groups-1 */
616   gst_bit_writer_put_ue (bitwriter, num_slice_groups_minus1);
617
618   if (num_slice_groups_minus1 > 0) {
619      /*FIXME*/ g_assert (0);
620   }
621   gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l0_active_minus1);
622   gst_bit_writer_put_ue (bitwriter, pic->num_ref_idx_l1_active_minus1);
623   gst_bit_writer_put_bits_uint32 (bitwriter,
624       pic->pic_fields.bits.weighted_pred_flag, 1);
625   gst_bit_writer_put_bits_uint32 (bitwriter,
626       pic->pic_fields.bits.weighted_bipred_idc, 2);
627   /* pic_init_qp_minus26 */
628   gst_bit_writer_put_se (bitwriter, pic->pic_init_qp - 26);
629   /* pic_init_qs_minus26 */
630   gst_bit_writer_put_se (bitwriter, pic_init_qs_minus26);
631   /*chroma_qp_index_offset */
632   gst_bit_writer_put_se (bitwriter, pic->chroma_qp_index_offset);
633
634   gst_bit_writer_put_bits_uint32 (bitwriter,
635       pic->pic_fields.bits.deblocking_filter_control_present_flag, 1);
636   gst_bit_writer_put_bits_uint32 (bitwriter,
637       pic->pic_fields.bits.constrained_intra_pred_flag, 1);
638   gst_bit_writer_put_bits_uint32 (bitwriter, redundant_pic_cnt_present_flag, 1);
639
640   /*more_rbsp_data */
641   gst_bit_writer_put_bits_uint32 (bitwriter,
642       pic->pic_fields.bits.transform_8x8_mode_flag, 1);
643   gst_bit_writer_put_bits_uint32 (bitwriter,
644       pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
645   if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) {
646     g_assert (0);
647     /* FIXME */
648     /*
649        for (i = 0; i <
650        (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag));
651        i++) {
652        gst_bit_writer_put_bits_uint8(bitwriter, pic->pic_fields.bits.pic_scaling_list_present_flag, 1);
653        }
654      */
655   }
656
657   gst_bit_writer_put_se (bitwriter, pic->second_chroma_qp_index_offset);
658   gst_bit_writer_write_trailing_bits (bitwriter);
659
660   return TRUE;
661 }
662
663 static gboolean
664 add_sequence_packed_header (GstVaapiEncoderH264 * encoder,
665     GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
666 {
667   GstVaapiEncPackedHeader *packed_seq;
668   GstBitWriter writer;
669   VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
670   VAEncSequenceParameterBufferH264 *seq_param = sequence->param;
671   guint32 data_bit_size;
672   guint8 *data;
673
674   gst_bit_writer_init (&writer, 128 * 8);
675   gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32);     /* start code */
676   gst_bit_writer_write_nal_header (&writer,
677       GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
678   gst_bit_writer_write_sps (&writer, seq_param, encoder->profile);
679   g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
680   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
681   data = GST_BIT_WRITER_DATA (&writer);
682
683   packed_header_param_buffer.type = VAEncPackedHeaderSequence;
684   packed_header_param_buffer.bit_length = data_bit_size;
685   packed_header_param_buffer.has_emulation_bytes = 0;
686
687   packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
688       &packed_header_param_buffer, sizeof (packed_header_param_buffer),
689       data, (data_bit_size + 7) / 8);
690   g_assert (packed_seq);
691
692   gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
693   gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_seq, NULL);
694
695   /* store sps data */
696   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
697
698   gst_bit_writer_clear (&writer, TRUE);
699
700   return TRUE;
701 }
702
703 static gboolean
704 add_picture_packed_header (GstVaapiEncoderH264 * encoder,
705     GstVaapiEncPicture * picture)
706 {
707   GstVaapiEncPackedHeader *packed_pic;
708   GstBitWriter writer;
709   VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
710   VAEncPictureParameterBufferH264 *pic_param = picture->param;
711   guint32 data_bit_size;
712   guint8 *data;
713
714   gst_bit_writer_init (&writer, 128 * 8);
715   gst_bit_writer_put_bits_uint32 (&writer, 0x00000001, 32);     /* start code */
716   gst_bit_writer_write_nal_header (&writer,
717       GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_PPS);
718   gst_bit_writer_write_pps (&writer, pic_param);
719   g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
720   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer);
721   data = GST_BIT_WRITER_DATA (&writer);
722
723   packed_header_param_buffer.type = VAEncPackedHeaderPicture;
724   packed_header_param_buffer.bit_length = data_bit_size;
725   packed_header_param_buffer.has_emulation_bytes = 0;
726
727   packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
728       &packed_header_param_buffer, sizeof (packed_header_param_buffer),
729       data, (data_bit_size + 7) / 8);
730   g_assert (packed_pic);
731
732   gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
733   gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & packed_pic, NULL);
734
735   /* store pps data */
736   _check_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
737   gst_bit_writer_clear (&writer, TRUE);
738
739   return TRUE;
740 }
741
742 /*  reference picture management */
743 static void
744 reference_pic_free (GstVaapiEncoderH264 * encoder, GstVaapiEncoderH264Ref * ref)
745 {
746   if (!ref)
747     return;
748   if (ref->pic)
749     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
750   g_slice_free (GstVaapiEncoderH264Ref, ref);
751 }
752
753 static inline GstVaapiEncoderH264Ref *
754 reference_pic_create (GstVaapiEncoderH264 * encoder,
755     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
756 {
757   GstVaapiEncoderH264Ref *ref = g_slice_new0 (GstVaapiEncoderH264Ref);
758
759   ref->pic = surface;
760   ref->frame_num = picture->frame_num;
761   ref->poc = picture->poc;
762   return ref;
763 }
764
765 static gboolean
766 reference_list_update (GstVaapiEncoderH264 * encoder,
767     GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
768 {
769   GstVaapiEncoderH264Ref *ref;
770
771   if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
772     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
773     return TRUE;
774   }
775   if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
776     while (!g_queue_is_empty (&encoder->ref_list))
777       reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
778   } else if (g_queue_get_length (&encoder->ref_list) >= encoder->max_ref_num) {
779     reference_pic_free (encoder, g_queue_pop_head (&encoder->ref_list));
780   }
781   ref = reference_pic_create (encoder, picture, surface);
782   g_queue_push_tail (&encoder->ref_list, ref);
783   g_assert (g_queue_get_length (&encoder->ref_list) <= encoder->max_ref_num);
784   return TRUE;
785 }
786
787 static gboolean
788 reference_list_init (GstVaapiEncoderH264 * encoder,
789     GstVaapiEncPicture * picture,
790     GstVaapiEncoderH264Ref ** reflist_0,
791     guint * reflist_0_count,
792     GstVaapiEncoderH264Ref ** reflist_1, guint * reflist_1_count)
793 {
794   GstVaapiEncoderH264Ref *tmp;
795   GList *iter, *list_0_start = NULL, *list_1_start = NULL;
796   guint max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
797   guint count;
798
799   *reflist_0_count = 0;
800   *reflist_1_count = 0;
801   if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
802     return TRUE;
803
804   iter = g_queue_peek_tail_link (&encoder->ref_list);
805   for (; iter; iter = g_list_previous (iter)) {
806     tmp = (GstVaapiEncoderH264Ref *) iter->data;
807     g_assert (tmp && tmp->poc != picture->poc);
808     if (_poc_greater_than (picture->poc, tmp->poc, max_pic_order_cnt)) {
809       list_0_start = iter;
810       list_1_start = g_list_next (iter);
811       break;
812     }
813   }
814
815   /* order reflist_0 */
816   g_assert (list_0_start);
817   iter = list_0_start;
818   count = 0;
819   for (; iter; iter = g_list_previous (iter)) {
820     reflist_0[count] = (GstVaapiEncoderH264Ref *) iter->data;
821     ++count;
822   }
823   *reflist_0_count = count;
824
825   if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
826     return TRUE;
827
828   /* order reflist_1 */
829   count = 0;
830   iter = list_1_start;
831   for (; iter; iter = g_list_next (iter)) {
832     reflist_1[count] = (GstVaapiEncoderH264Ref *) iter->data;
833     ++count;
834   }
835   *reflist_1_count = count;
836   return TRUE;
837 }
838
839 /* fill the  H264 VA encoding parameters */
840 static gboolean
841 fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
842     GstVaapiEncSequence * sequence)
843 {
844   VAEncSequenceParameterBufferH264 *seq = sequence->param;
845   guint width_in_mbs, height_in_mbs;
846
847   width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
848   height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
849
850   memset (seq, 0, sizeof (VAEncSequenceParameterBufferH264));
851   seq->seq_parameter_set_id = 0;
852   seq->level_idc = encoder->level;
853   seq->intra_period = encoder->intra_period;
854   seq->ip_period = 0;           // ?
855   if (encoder->bitrate > 0)
856     seq->bits_per_second = encoder->bitrate * 1024;
857   else
858     seq->bits_per_second = 0;
859
860   seq->max_num_ref_frames = encoder->max_ref_num;
861   seq->picture_width_in_mbs = width_in_mbs;
862   seq->picture_height_in_mbs = height_in_mbs;
863
864   /*sequence field values */
865   seq->seq_fields.value = 0;
866   seq->seq_fields.bits.chroma_format_idc = 1;
867   seq->seq_fields.bits.frame_mbs_only_flag = 1;
868   seq->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE;
869   seq->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
870   /* direct_8x8_inference_flag default false */
871   seq->seq_fields.bits.direct_8x8_inference_flag = FALSE;
872   g_assert (encoder->log2_max_frame_num >= 4);
873   seq->seq_fields.bits.log2_max_frame_num_minus4 =
874       encoder->log2_max_frame_num - 4;
875   /* picture order count */
876   seq->seq_fields.bits.pic_order_cnt_type = 0;
877   g_assert (encoder->log2_max_pic_order_cnt >= 4);
878   seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
879       encoder->log2_max_pic_order_cnt - 4;
880
881   seq->bit_depth_luma_minus8 = 0;
882   seq->bit_depth_chroma_minus8 = 0;
883
884   /* not used if pic_order_cnt_type == 0 */
885   if (seq->seq_fields.bits.pic_order_cnt_type == 1) {
886     seq->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
887     seq->num_ref_frames_in_pic_order_cnt_cycle = 0;
888     seq->offset_for_non_ref_pic = 0;
889     seq->offset_for_top_to_bottom_field = 0;
890     memset (seq->offset_for_ref_frame, 0, sizeof (seq->offset_for_ref_frame));
891   }
892
893   if (height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) {
894     seq->frame_cropping_flag = 1;
895     seq->frame_crop_left_offset = 0;
896     seq->frame_crop_right_offset = 0;
897     seq->frame_crop_top_offset = 0;
898     seq->frame_crop_bottom_offset =
899         ((height_in_mbs * 16 - GST_VAAPI_ENCODER_HEIGHT (encoder)) /
900         (2 * (!seq->seq_fields.bits.frame_mbs_only_flag + 1)));
901   }
902
903   /*vui not set */
904   seq->vui_parameters_present_flag = (encoder->bitrate > 0 ? TRUE : FALSE);
905   if (seq->vui_parameters_present_flag) {
906     seq->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
907     seq->vui_fields.bits.bitstream_restriction_flag = FALSE;
908     seq->vui_fields.bits.timing_info_present_flag =
909         (encoder->bitrate > 0 ? TRUE : FALSE);
910     if (seq->vui_fields.bits.timing_info_present_flag) {
911       seq->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
912       seq->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
913     }
914   }
915
916   return TRUE;
917 }
918
919 static gboolean
920 fill_va_picture_param (GstVaapiEncoderH264 * encoder,
921     GstVaapiEncPicture * picture,
922     GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
923 {
924   VAEncPictureParameterBufferH264 *pic = picture->param;
925   GstVaapiEncoderH264Ref *ref_pic;
926   GList *reflist;
927   guint i;
928
929   memset (pic, 0, sizeof (VAEncPictureParameterBufferH264));
930
931   /* reference list,  */
932   pic->CurrPic.picture_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
933   pic->CurrPic.TopFieldOrderCnt = picture->poc;
934   i = 0;
935   if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
936     for (reflist = g_queue_peek_head_link (&encoder->ref_list);
937         reflist; reflist = g_list_next (reflist)) {
938       ref_pic = reflist->data;
939       g_assert (ref_pic && ref_pic->pic &&
940           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
941
942       pic->ReferenceFrames[i].picture_id =
943           GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
944       ++i;
945     }
946     g_assert (i <= 16 && i <= encoder->max_ref_num);
947   }
948   for (; i < 16; ++i) {
949     pic->ReferenceFrames[i].picture_id = VA_INVALID_ID;
950   }
951   pic->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
952
953   pic->pic_parameter_set_id = 0;
954   pic->seq_parameter_set_id = 0;
955   pic->last_picture = 0;        /* means last encoding picture */
956   pic->frame_num = picture->frame_num;
957   pic->pic_init_qp = encoder->init_qp;
958   pic->num_ref_idx_l0_active_minus1 =
959       (encoder->max_reflist0_count ? (encoder->max_reflist0_count - 1) : 0);
960   pic->num_ref_idx_l1_active_minus1 =
961       (encoder->max_reflist1_count ? (encoder->max_reflist1_count - 1) : 0);
962   pic->chroma_qp_index_offset = 0;
963   pic->second_chroma_qp_index_offset = 0;
964
965   /* set picture fields */
966   pic->pic_fields.value = 0;
967   pic->pic_fields.bits.idr_pic_flag = GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
968   pic->pic_fields.bits.reference_pic_flag =
969       (picture->type != GST_VAAPI_PICTURE_TYPE_B);
970   pic->pic_fields.bits.entropy_coding_mode_flag =
971       GST_VAAPI_ENCODER_H264_ENTROPY_MODE_CABAC;
972   pic->pic_fields.bits.weighted_pred_flag = FALSE;
973   pic->pic_fields.bits.weighted_bipred_idc = 0;
974   pic->pic_fields.bits.constrained_intra_pred_flag = 0;
975   pic->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH);     /* enable 8x8 */
976   /* enable debloking */
977   pic->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
978   pic->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
979   /* bottom_field_pic_order_in_frame_present_flag */
980   pic->pic_fields.bits.pic_order_present_flag = FALSE;
981   pic->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
982
983   return TRUE;
984 }
985
986 static gboolean
987 fill_va_slices_param (GstVaapiEncoderH264 * encoder,
988     GstVaapiEncPicture * picture,
989     GstVaapiEncoderH264Ref ** reflist_0,
990     guint reflist_0_count,
991     GstVaapiEncoderH264Ref ** reflist_1, guint reflist_1_count)
992 {
993   VAEncSliceParameterBufferH264 *slice_param;
994   GstVaapiEncSlice *slice;
995   guint width_in_mbs, height_in_mbs;
996   guint slice_of_mbs, slice_mod_mbs, cur_slice_mbs;
997   guint total_mbs;
998   guint last_mb_index;
999   guint i_slice, i_ref;
1000
1001   g_assert (picture);
1002
1003   width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1004   height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1005   total_mbs = width_in_mbs * height_in_mbs;
1006
1007   g_assert (encoder->slice_num && encoder->slice_num < total_mbs);
1008   slice_of_mbs = total_mbs / encoder->slice_num;
1009   slice_mod_mbs = total_mbs % encoder->slice_num;
1010   last_mb_index = 0;
1011   for (i_slice = 0; i_slice < encoder->slice_num; ++i_slice) {
1012     cur_slice_mbs = slice_of_mbs;
1013     if (slice_mod_mbs) {
1014       ++cur_slice_mbs;
1015       --slice_mod_mbs;
1016     }
1017     slice = GST_VAAPI_ENC_SLICE_NEW (H264, encoder);
1018     g_assert (slice && slice->param_id != VA_INVALID_ID);
1019     slice_param = slice->param;
1020
1021     memset (slice_param, 0, sizeof (VAEncSliceParameterBufferH264));
1022     slice_param->macroblock_address = last_mb_index;
1023     slice_param->num_macroblocks = cur_slice_mbs;
1024     slice_param->macroblock_info = VA_INVALID_ID;
1025     slice_param->slice_type = _get_va_slice_type (picture->type);
1026     g_assert (slice_param->slice_type != -1);
1027     slice_param->pic_parameter_set_id = 0;
1028     slice_param->idr_pic_id = encoder->idr_num;
1029     slice_param->pic_order_cnt_lsb = picture->poc;
1030
1031     /* not used if pic_order_cnt_type = 0 */
1032     slice_param->delta_pic_order_cnt_bottom = 0;
1033     memset (slice_param->delta_pic_order_cnt,
1034         0, sizeof (slice_param->delta_pic_order_cnt));
1035
1036     /*only works for B frames */
1037     slice_param->direct_spatial_mv_pred_flag = FALSE;
1038     /* default equal to picture parameters */
1039     slice_param->num_ref_idx_active_override_flag = FALSE;
1040     if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1041       slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1042     else
1043       slice_param->num_ref_idx_l0_active_minus1 = 0;
1044     if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1045       slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1046     else
1047       slice_param->num_ref_idx_l1_active_minus1 = 0;
1048     g_assert (slice_param->num_ref_idx_l0_active_minus1 == 0);
1049     g_assert (slice_param->num_ref_idx_l1_active_minus1 == 0);
1050
1051     i_ref = 0;
1052     if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1053       for (; i_ref < reflist_0_count; ++i_ref) {
1054         slice_param->RefPicList0[i_ref].picture_id =
1055             GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1056       }
1057       g_assert (i_ref == 1);
1058     }
1059     for (;
1060         i_ref <
1061         sizeof (slice_param->RefPicList0) /
1062         sizeof (slice_param->RefPicList0[0]); ++i_ref) {
1063       slice_param->RefPicList0[i_ref].picture_id = VA_INVALID_SURFACE;
1064     }
1065
1066     i_ref = 0;
1067     if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1068       for (; i_ref < reflist_1_count; ++i_ref) {
1069         slice_param->RefPicList1[i_ref].picture_id =
1070             GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1071       }
1072       g_assert (i_ref == 1);
1073     }
1074     for (;
1075         i_ref <
1076         sizeof (slice_param->RefPicList1) /
1077         sizeof (slice_param->RefPicList1[0]); ++i_ref) {
1078       slice_param->RefPicList1[i_ref].picture_id = VA_INVALID_SURFACE;
1079     }
1080
1081     /* not used if  pic_param.pic_fields.bits.weighted_pred_flag == FALSE */
1082     slice_param->luma_log2_weight_denom = 0;
1083     slice_param->chroma_log2_weight_denom = 0;
1084     slice_param->luma_weight_l0_flag = FALSE;
1085     memset (slice_param->luma_weight_l0, 0,
1086         sizeof (slice_param->luma_weight_l0));
1087     memset (slice_param->luma_offset_l0, 0,
1088         sizeof (slice_param->luma_offset_l0));
1089     slice_param->chroma_weight_l0_flag = FALSE;
1090     memset (slice_param->chroma_weight_l0, 0,
1091         sizeof (slice_param->chroma_weight_l0));
1092     memset (slice_param->chroma_offset_l0, 0,
1093         sizeof (slice_param->chroma_offset_l0));
1094     slice_param->luma_weight_l1_flag = FALSE;
1095     memset (slice_param->luma_weight_l1, 0,
1096         sizeof (slice_param->luma_weight_l1));
1097     memset (slice_param->luma_offset_l1, 0,
1098         sizeof (slice_param->luma_offset_l1));
1099     slice_param->chroma_weight_l1_flag = FALSE;
1100     memset (slice_param->chroma_weight_l1, 0,
1101         sizeof (slice_param->chroma_weight_l1));
1102     memset (slice_param->chroma_offset_l1, 0,
1103         sizeof (slice_param->chroma_offset_l1));
1104
1105     slice_param->cabac_init_idc = 0;
1106     slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1107     if (slice_param->slice_qp_delta > 4)
1108       slice_param->slice_qp_delta = 4;
1109     slice_param->disable_deblocking_filter_idc = 0;
1110     slice_param->slice_alpha_c0_offset_div2 = 2;
1111     slice_param->slice_beta_offset_div2 = 2;
1112
1113     /* set calculation for next slice */
1114     last_mb_index += cur_slice_mbs;
1115
1116     gst_vaapi_enc_picture_add_slice (picture, slice);
1117     gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & slice, NULL);
1118
1119   }
1120   g_assert (last_mb_index == total_mbs);
1121   return TRUE;
1122 }
1123
1124 static gboolean
1125 ensure_sequence (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1126 {
1127   GstVaapiEncSequence *sequence;
1128
1129   g_assert (picture);
1130   sequence = GST_VAAPI_ENC_SEQUENCE_NEW (H264, encoder);
1131   g_assert (sequence);
1132   if (!sequence)
1133     goto error;
1134
1135   if (!fill_va_sequence_param (encoder, sequence))
1136     goto error;
1137
1138   if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1139       !add_sequence_packed_header (encoder, picture, sequence))
1140     goto error;
1141   gst_vaapi_enc_picture_set_sequence (picture, sequence);
1142   gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL);
1143   return TRUE;
1144
1145 error:
1146   gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (&sequence), NULL);
1147   return FALSE;
1148 }
1149
1150 static gboolean
1151 ensure_picture (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture,
1152     GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1153 {
1154   GstVaapiCodedBuffer *const codedbuf =
1155       GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1156
1157   if (!fill_va_picture_param (encoder, picture, codedbuf, surface))
1158     return FALSE;
1159
1160   if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1161       !add_picture_packed_header (encoder, picture)) {
1162     GST_ERROR ("set picture packed header failed");
1163     return FALSE;
1164   }
1165
1166   return TRUE;
1167 }
1168
1169 static gboolean
1170 ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1171 {
1172   GstVaapiEncoderH264Ref *reflist_0[16];
1173   GstVaapiEncoderH264Ref *reflist_1[16];
1174   guint reflist_0_count = 0, reflist_1_count = 0;
1175
1176   g_assert (picture);
1177
1178   if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1179       !reference_list_init (encoder, picture,
1180           reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1181     GST_ERROR ("reference list reorder failed");
1182     return FALSE;
1183   }
1184
1185   g_assert (reflist_0_count + reflist_1_count <= encoder->max_ref_num);
1186   if (reflist_0_count > encoder->max_reflist0_count)
1187     reflist_0_count = encoder->max_reflist0_count;
1188   if (reflist_1_count > encoder->max_reflist1_count)
1189     reflist_1_count = encoder->max_reflist1_count;
1190
1191   if (!fill_va_slices_param (encoder, picture,
1192           reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1193     return FALSE;
1194
1195   return TRUE;
1196 }
1197
1198 static gboolean
1199 ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
1200 {
1201   GstVaapiEncMiscParam *misc = NULL;
1202   VAEncMiscParameterHRD *hrd;
1203   VAEncMiscParameterRateControl *rate_control;
1204
1205   /* add hrd */
1206   misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder);
1207   g_assert (misc);
1208   if (!misc)
1209     return FALSE;
1210   gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1211   hrd = misc->impl;
1212   if (encoder->bitrate > 0) {
1213     hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4;
1214     hrd->buffer_size = encoder->bitrate * 1024 * 8;
1215   } else {
1216     hrd->initial_buffer_fullness = 0;
1217     hrd->buffer_size = 0;
1218   }
1219   gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL);
1220
1221   /* add ratecontrol */
1222   if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR ||
1223       GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) {
1224     misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder);
1225     g_assert (misc);
1226     if (!misc)
1227       return FALSE;
1228     gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
1229     rate_control = misc->impl;
1230     memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
1231     if (encoder->bitrate)
1232       rate_control->bits_per_second = encoder->bitrate * 1024;
1233     else
1234       rate_control->bits_per_second = 0;
1235     rate_control->target_percentage = 70;
1236     rate_control->window_size = 500;
1237     rate_control->initial_qp = encoder->init_qp;
1238     rate_control->min_qp = encoder->min_qp;
1239     rate_control->basic_unit_size = 0;
1240     gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) & misc, NULL);
1241   }
1242
1243   return TRUE;
1244 }
1245
1246 gboolean
1247 init_encoder_public_attributes (GstVaapiEncoderH264 * encoder)
1248 {
1249   guint width_mbs, height_mbs, total_mbs;
1250
1251   if (!GST_VAAPI_ENCODER_WIDTH (encoder) ||
1252       !GST_VAAPI_ENCODER_HEIGHT (encoder) ||
1253       !GST_VAAPI_ENCODER_FPS_N (encoder) ||
1254       !GST_VAAPI_ENCODER_FPS_D (encoder)) {
1255     return FALSE;
1256   }
1257   if (!encoder->profile)
1258     encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE;
1259
1260   _set_level (encoder);
1261
1262   if (!encoder->intra_period)
1263     encoder->intra_period = GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD;
1264   else if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD)
1265     encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD;
1266
1267   if (encoder->idr_period < encoder->intra_period)
1268     encoder->idr_period = encoder->intra_period;
1269   if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD)
1270     encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD;
1271
1272   if (-1 == encoder->init_qp)
1273     encoder->init_qp = GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP;
1274
1275   if (-1 == encoder->min_qp) {
1276     if (GST_VAAPI_RATECONTROL_CQP == GST_VAAPI_ENCODER_RATE_CONTROL (encoder))
1277       encoder->min_qp = encoder->init_qp;
1278     else
1279       encoder->min_qp = GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP;
1280   }
1281
1282   if (encoder->min_qp > encoder->init_qp)
1283     encoder->min_qp = encoder->init_qp;
1284
1285   /* default compress ratio 1: (4*8*1.5) */
1286   if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
1287       GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
1288       GST_VAAPI_RATECONTROL_VBR_CONSTRAINED ==
1289       GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1290     if (!encoder->bitrate)
1291       encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
1292           GST_VAAPI_ENCODER_HEIGHT (encoder) *
1293           GST_VAAPI_ENCODER_FPS_N (encoder) /
1294           GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
1295   } else
1296     encoder->bitrate = 0;
1297
1298   if (!encoder->slice_num)
1299     encoder->slice_num = GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM;
1300
1301   width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
1302   height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
1303   total_mbs = width_mbs * height_mbs;
1304
1305   if (encoder->slice_num > (total_mbs + 1) / 2)
1306     encoder->slice_num = (total_mbs + 1) / 2;
1307   g_assert (encoder->slice_num);
1308
1309   if (encoder->b_frame_num > (encoder->intra_period + 1) / 2)
1310     encoder->b_frame_num = (encoder->intra_period + 1) / 2;
1311
1312   if (encoder->b_frame_num > 50)
1313     encoder->b_frame_num = 50;
1314
1315   return TRUE;
1316 }
1317
1318 static gboolean
1319 init_encoder_private_attributes (GstVaapiEncoderH264 * encoder, GstCaps * caps)
1320 {
1321   if (encoder->b_frame_num)
1322     encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
1323         GST_VAAPI_ENCODER_FPS_N (encoder);
1324   else
1325     encoder->cts_offset = 0;
1326
1327   /* init max_frame_num, max_poc */
1328   encoder->log2_max_frame_num = _get_log2_max_frame_num (encoder->idr_period);
1329   g_assert (encoder->log2_max_frame_num >= 4);
1330   encoder->max_frame_num = (1 << encoder->log2_max_frame_num);
1331   encoder->log2_max_pic_order_cnt = encoder->log2_max_frame_num + 1;
1332   encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
1333
1334   encoder->frame_index = 0;
1335   encoder->idr_num = 0;
1336   encoder->max_reflist0_count = 1;
1337   if (encoder->b_frame_num)
1338     encoder->max_reflist1_count = 1;
1339   else
1340     encoder->max_reflist1_count = 0;
1341   encoder->max_ref_num =
1342       encoder->max_reflist0_count + encoder->max_reflist1_count;
1343   return TRUE;
1344 }
1345
1346
1347 static GstVaapiEncoderStatus
1348 gst_vaapi_encoder_h264_encode (GstVaapiEncoder * base,
1349     GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
1350 {
1351   GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base);
1352   GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
1353   GstVaapiSurfaceProxy *reconstruct = NULL;
1354
1355   reconstruct = gst_vaapi_encoder_create_surface (base);
1356
1357   g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
1358
1359   if (!ensure_sequence (encoder, picture))
1360     goto error;
1361   if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
1362     goto error;
1363   if (!ensure_misc (encoder, picture))
1364     goto error;
1365   if (!ensure_slices (encoder, picture))
1366     goto error;
1367   if (!gst_vaapi_enc_picture_encode (picture))
1368     goto error;
1369
1370   if (!reference_list_update (encoder, picture, reconstruct))
1371     goto error;
1372
1373   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1374 error:
1375   if (reconstruct)
1376     gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
1377         reconstruct);
1378   return ret;
1379 }
1380
1381 static GstVaapiEncoderStatus
1382 gst_vaapi_encoder_h264_flush (GstVaapiEncoder * base)
1383 {
1384   GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base);
1385   GstVaapiEncPicture *pic;
1386
1387   encoder->frame_index = 0;
1388   encoder->cur_frame_num = 0;
1389   encoder->cur_present_index = 0;
1390   while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1391     pic =
1392         (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list);
1393     gst_vaapi_enc_picture_unref (pic);
1394   }
1395   g_queue_clear (&encoder->reorder_frame_list);
1396
1397   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1398 }
1399
1400 static GstVaapiEncoderStatus
1401 gst_vaapi_encoder_h264_get_avcC_codec_data (GstVaapiEncoderH264 * encoder,
1402     GstBuffer ** buffer)
1403 {
1404   GstBuffer *avc_codec;
1405   const guint32 configuration_version = 0x01;
1406   const guint32 length_size_minus_one = 0x03;
1407   guint32 profile, profile_comp, level_idc;
1408   GstMapInfo sps_info, pps_info;
1409   GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_SUCCESS;
1410   GstBitWriter writer;
1411
1412   g_assert (buffer);
1413   if (!encoder->sps_data || !encoder->pps_data)
1414     return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1415
1416   if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
1417     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1418
1419   if (FALSE == _read_sps_attributes (sps_info.data, sps_info.size,
1420           &profile, &profile_comp, &level_idc)) {
1421     ret = GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
1422     goto end;
1423   }
1424
1425   if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ)) {
1426     ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1427     goto end;
1428   }
1429
1430   gst_bit_writer_init (&writer, (sps_info.size + pps_info.size + 64) * 8);
1431   /* codec_data */
1432   gst_bit_writer_put_bits_uint32 (&writer, configuration_version, 8);
1433   gst_bit_writer_put_bits_uint32 (&writer, profile, 8);
1434   gst_bit_writer_put_bits_uint32 (&writer, profile_comp, 8);
1435   gst_bit_writer_put_bits_uint32 (&writer, level_idc, 8);
1436   gst_bit_writer_put_bits_uint32 (&writer, 0x3F, 6);    /*111111 */
1437   gst_bit_writer_put_bits_uint32 (&writer, length_size_minus_one, 2);
1438   gst_bit_writer_put_bits_uint32 (&writer, 0x07, 3);    /*111 */
1439
1440   /* write sps */
1441   gst_bit_writer_put_bits_uint32 (&writer, 1, 5);       /* sps count = 1 */
1442   g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0);
1443   gst_bit_writer_put_bits_uint32 (&writer, sps_info.size, 16);
1444   gst_bit_writer_put_bytes (&writer, sps_info.data, sps_info.size);
1445
1446   /* write pps */
1447   gst_bit_writer_put_bits_uint32 (&writer, 1, 8);       /*pps count = 1 */
1448   gst_bit_writer_put_bits_uint32 (&writer, pps_info.size, 16);
1449   gst_bit_writer_put_bytes (&writer, pps_info.data, pps_info.size);
1450
1451   avc_codec = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&writer),
1452       GST_BIT_WRITER_BIT_SIZE (&writer) / 8);
1453   g_assert (avc_codec);
1454   if (!avc_codec) {
1455     ret = GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1456     goto clear_writer;
1457   }
1458   *buffer = avc_codec;
1459
1460   gst_buffer_unmap (encoder->pps_data, &pps_info);
1461   gst_bit_writer_clear (&writer, FALSE);
1462   ret = GST_VAAPI_ENCODER_STATUS_SUCCESS;
1463   goto end;
1464
1465 clear_writer:
1466   gst_bit_writer_clear (&writer, TRUE);
1467
1468 end:
1469   gst_buffer_unmap (encoder->sps_data, &sps_info);
1470
1471   return ret;
1472 }
1473
1474 static GstVaapiEncoderStatus
1475 gst_vaapi_encoder_h264_get_codec_data (GstVaapiEncoder * base,
1476     GstBuffer ** buffer)
1477 {
1478   GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST (base);
1479
1480   *buffer = NULL;
1481
1482   if (!encoder->is_avc)
1483     return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1484
1485   return gst_vaapi_encoder_h264_get_avcC_codec_data (encoder, buffer);
1486 }
1487
1488 static GstVaapiEncoderStatus
1489 gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base,
1490     GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
1491 {
1492   GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base);
1493   GstVaapiEncPicture *picture;
1494   gboolean is_idr = FALSE;
1495
1496   *output = NULL;
1497
1498   if (!frame) {
1499     if (encoder->reorder_state != GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES)
1500       return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1501
1502     /* reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES
1503        dump B frames from queue, sometime, there may also have P frame or I frame */
1504     g_assert (encoder->b_frame_num > 0);
1505     g_return_val_if_fail (!g_queue_is_empty (&encoder->reorder_frame_list),
1506         GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
1507     picture = g_queue_pop_head (&encoder->reorder_frame_list);
1508     g_assert (picture);
1509     if (g_queue_is_empty (&encoder->reorder_frame_list)) {
1510       encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1511     }
1512     goto end;
1513   }
1514
1515   /* new frame coming */
1516   picture = GST_VAAPI_ENC_PICTURE_NEW (H264, encoder, frame);
1517   if (!picture) {
1518     GST_WARNING ("create H264 picture failed, frame timestamp:%"
1519         GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
1520     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
1521   }
1522   ++encoder->cur_present_index;
1523   picture->poc = ((encoder->cur_present_index * 2) %
1524       encoder->max_pic_order_cnt);
1525
1526   is_idr = (encoder->frame_index == 0 ||
1527       encoder->frame_index >= encoder->idr_period);
1528
1529   /* check key frames */
1530   if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
1531       (encoder->frame_index % encoder->intra_period) == 0) {
1532     ++encoder->cur_frame_num;
1533     ++encoder->frame_index;
1534
1535     /* b frame enabled,  check queue of reorder_frame_list */
1536     if (encoder->b_frame_num
1537         && !g_queue_is_empty (&encoder->reorder_frame_list)) {
1538       GstVaapiEncPicture *p_pic;
1539
1540       p_pic = g_queue_pop_tail (&encoder->reorder_frame_list);
1541       _set_p_frame (p_pic, encoder);
1542       g_queue_foreach (&encoder->reorder_frame_list,
1543           (GFunc) _set_b_frame, encoder);
1544       ++encoder->cur_frame_num;
1545       _set_key_frame (picture, encoder, is_idr);
1546       g_queue_push_tail (&encoder->reorder_frame_list, picture);
1547       picture = p_pic;
1548       encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1549     } else {                    /* no b frames in queue */
1550       _set_key_frame (picture, encoder, is_idr);
1551       g_assert (g_queue_is_empty (&encoder->reorder_frame_list));
1552       if (encoder->b_frame_num)
1553         encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES;
1554     }
1555     goto end;
1556   }
1557
1558   /* new p/b frames coming */
1559   ++encoder->frame_index;
1560   if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES &&
1561       g_queue_get_length (&encoder->reorder_frame_list) <
1562       encoder->b_frame_num) {
1563     g_queue_push_tail (&encoder->reorder_frame_list, picture);
1564     return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
1565   }
1566
1567   ++encoder->cur_frame_num;
1568   _set_p_frame (picture, encoder);
1569
1570   if (encoder->reorder_state == GST_VAAPI_ENC_H264_REORD_WAIT_FRAMES) {
1571     g_queue_foreach (&encoder->reorder_frame_list, (GFunc) _set_b_frame,
1572         encoder);
1573     encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_DUMP_FRAMES;
1574     g_assert (!g_queue_is_empty (&encoder->reorder_frame_list));
1575   }
1576
1577 end:
1578   g_assert (picture);
1579   frame = GST_VAAPI_ENC_PICTURE_GET_FRAME (picture);
1580   if (GST_CLOCK_TIME_IS_VALID (frame->pts))
1581     frame->pts += encoder->cts_offset;
1582   *output = picture;
1583
1584   return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1585 }
1586
1587 static void
1588 gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder)
1589 {
1590   GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder);
1591   GstVaapiContextInfo *const cip = &base_encoder->context_info;
1592   const guint DEFAULT_SURFACES_COUNT = 3;
1593
1594   /* Maximum sizes for common headers (in bits) */
1595   enum
1596   {
1597     MAX_SPS_HDR_SIZE = 16473,
1598     MAX_VUI_PARAMS_SIZE = 210,
1599     MAX_HRD_PARAMS_SIZE = 4103,
1600     MAX_PPS_HDR_SIZE = 101,
1601     MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
1602   };
1603
1604   cip->profile = encoder->profile;
1605   cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT;
1606
1607   /* Only YUV 4:2:0 formats are supported for now. This means that we
1608      have a limit of 3200 bits per macroblock. */
1609   /* XXX: check profile and compute RawMbBits */
1610   base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) *
1611       GST_ROUND_UP_16 (cip->height) / 256) * 400;
1612
1613   /* Account for SPS header */
1614   /* XXX: exclude scaling lists, MVC/SVC extensions */
1615   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
1616       MAX_VUI_PARAMS_SIZE + 2 * MAX_HRD_PARAMS_SIZE) / 8;
1617
1618   /* Account for PPS header */
1619   /* XXX: exclude slice groups, scaling lists, MVC/SVC extensions */
1620   base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
1621
1622   /* Account for slice header. At most 200 slices are supported */
1623   base_encoder->codedbuf_size += 200 * (4 +
1624       GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8);
1625 }
1626
1627 static GstCaps *
1628 gst_vaapi_encoder_h264_set_format (GstVaapiEncoder * base,
1629     GstVideoCodecState * in_state, GstCaps * ref_caps)
1630 {
1631   GstVaapiEncoderH264 *encoder;
1632   GstCaps *result = NULL, *tmp;
1633   GstStructure *structure;
1634   const GValue *value;
1635   const gchar *stream_format;
1636
1637   encoder = GST_VAAPI_ENCODER_H264 (base);
1638
1639   tmp = gst_caps_from_string ("video/x-h264");
1640   gst_caps_set_simple (tmp,
1641       "width", G_TYPE_INT, GST_VAAPI_ENCODER_WIDTH (encoder),
1642       "height", G_TYPE_INT, GST_VAAPI_ENCODER_HEIGHT (encoder),
1643       "framerate", GST_TYPE_FRACTION,
1644       GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder),
1645       NULL);
1646   result = gst_caps_intersect (tmp, ref_caps);
1647   gst_caps_unref (tmp);
1648
1649   /* fixed stream-format and choose byte-stream first */
1650   structure = gst_caps_get_structure (result, 0);
1651   value = gst_structure_get_value (structure, "stream-format");
1652   if (value) {
1653     gst_structure_fixate_field_string (structure, "stream-format",
1654         "byte-stream");
1655     stream_format = gst_structure_get_string (structure, "stream-format");
1656   } else {
1657     stream_format = "byte-stream";
1658     gst_structure_set (structure, "stream-format", G_TYPE_STRING, stream_format,
1659         NULL);
1660   }
1661
1662   if (strcmp (stream_format, "byte-stream") == 0)
1663     encoder->is_avc = FALSE;
1664   else                          /* need codec data later */
1665     encoder->is_avc = TRUE;
1666
1667 #if GST_CHECK_VERSION(1,0,0)
1668   result = gst_caps_fixate (result);
1669 #endif
1670
1671   if (!init_encoder_public_attributes (encoder)) {
1672     GST_WARNING ("encoder ensure public attributes failed ");
1673     goto error;
1674   }
1675
1676   if (!init_encoder_private_attributes (encoder, result)) {
1677     GST_WARNING ("prepare encoding failed ");
1678     goto error;
1679   }
1680
1681   return result;
1682
1683 error:
1684   gst_caps_unref (result);
1685   return NULL;
1686 }
1687
1688 static gboolean
1689 gst_vaapi_encoder_h264_init (GstVaapiEncoder * base)
1690 {
1691   GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264 (base);
1692
1693   /* init attributes */
1694   encoder->profile = 0;
1695   encoder->level = 0;
1696   encoder->bitrate = 0;
1697   encoder->idr_period = 0;
1698   encoder->intra_period = 0;
1699   encoder->init_qp = -1;
1700   encoder->min_qp = -1;
1701   encoder->slice_num = 0;
1702   encoder->b_frame_num = 0;
1703   //gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
1704
1705   /* init private values */
1706   encoder->is_avc = FALSE;
1707   /* re-ordering */
1708   g_queue_init (&encoder->reorder_frame_list);
1709   encoder->reorder_state = GST_VAAPI_ENC_H264_REORD_NONE;
1710   encoder->frame_index = 0;
1711   encoder->cur_frame_num = 0;
1712   encoder->cur_present_index = 0;
1713
1714   g_queue_init (&encoder->ref_list);
1715   encoder->max_ref_num = 0;
1716   encoder->max_reflist0_count = 1;
1717   encoder->max_reflist1_count = 1;
1718
1719   encoder->sps_data = NULL;
1720   encoder->pps_data = NULL;
1721
1722   encoder->cts_offset = 0;
1723
1724   encoder->max_frame_num = 0;
1725   encoder->log2_max_frame_num = 0;
1726   encoder->max_pic_order_cnt = 0;
1727   encoder->log2_max_pic_order_cnt = 0;
1728   encoder->idr_num = 0;
1729
1730   return TRUE;
1731 }
1732
1733 static void
1734 gst_vaapi_encoder_h264_finalize (GstVaapiEncoder * base)
1735 {
1736   /*free private buffers */
1737   GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base);
1738   GstVaapiEncPicture *pic;
1739   GstVaapiEncoderH264Ref *ref;
1740
1741   gst_buffer_replace (&encoder->sps_data, NULL);
1742   gst_buffer_replace (&encoder->pps_data, NULL);
1743
1744   while (!g_queue_is_empty (&encoder->ref_list)) {
1745     ref = (GstVaapiEncoderH264Ref *) g_queue_pop_head (&encoder->ref_list);
1746     reference_pic_free (encoder, ref);
1747   }
1748   g_queue_clear (&encoder->ref_list);
1749
1750   while (!g_queue_is_empty (&encoder->reorder_frame_list)) {
1751     pic =
1752         (GstVaapiEncPicture *) g_queue_pop_head (&encoder->reorder_frame_list);
1753     gst_vaapi_enc_picture_unref (pic);
1754   }
1755   g_queue_clear (&encoder->reorder_frame_list);
1756
1757 }
1758
1759 static inline const GstVaapiEncoderClass *
1760 gst_vaapi_encoder_h264_class (void)
1761 {
1762   static const GstVaapiEncoderClass GstVaapiEncoderH264Class = {
1763     GST_VAAPI_ENCODER_CLASS_INIT (H264, h264),
1764     .get_codec_data = gst_vaapi_encoder_h264_get_codec_data
1765   };
1766   return &GstVaapiEncoderH264Class;
1767 }
1768
1769 GstVaapiEncoder *
1770 gst_vaapi_encoder_h264_new (GstVaapiDisplay * display)
1771 {
1772   return gst_vaapi_encoder_new (gst_vaapi_encoder_h264_class (), display);
1773 }
1774
1775 void
1776 gst_vaapi_encoder_h264_set_avc (GstVaapiEncoderH264 * encoder, gboolean is_avc)
1777 {
1778   encoder->is_avc = is_avc;
1779 }
1780
1781 gboolean
1782 gst_vaapi_encoder_h264_is_avc (GstVaapiEncoderH264 * encoder)
1783 {
1784   return encoder->is_avc;
1785 }