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