483453d3d40c5d908a744beb21ec76666f372cf7
[profile/ivi/gstreamer-vaapi.git] / gst / vaapiencode / gstvaapih264encoder.c
1
2 #include "gstvaapih264encoder.h"
3
4 #include <string.h>
5 #include <stdlib.h>
6 #include <va/va.h>
7 #include "va/va_x11.h"
8 #include <X11/Xlib.h>
9 #include <glib.h>
10
11 #include "gst/gstclock.h"
12 #include "gst/gstvalue.h"
13
14 #include "gst/vaapi/gstvaapiobject.h"
15 #include "gst/vaapi/gstvaapiobject_priv.h"
16 #include "gst/vaapi/gstvaapicontext.h"
17 #include "gst/vaapi/gstvaapisurface.h"
18 #include "gst/vaapi/gstvaapivideobuffer.h"
19 #include "gst/vaapi/gstvaapidisplay_priv.h"
20
21 /* enable old lib va*/
22 //#define _SIMPLE_LIB_VA_
23
24 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
25 #define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
26
27 #define SHARE_CODED_BUF         0
28
29 #define DEFAULT_SURFACE_NUMBER  3
30 #define DEFAULT_CODEDBUF_NUM    5
31 #define DEFAULT_SID_INPUT       0 // suface_ids[0]
32
33 #define REF_RECON_SURFACE_NUM   2
34
35 #define ENTROPY_MODE_CAVLC      0
36 #define ENTROPY_MODE_CABAC      1
37
38 #define BR_CBR          0
39 #define BR_VBR          1
40 #define BR_CQP          2
41
42 #define NAL_REF_IDC_NONE        0
43 #define NAL_REF_IDC_LOW         1
44 #define NAL_REF_IDC_MEDIUM      2
45 #define NAL_REF_IDC_HIGH        3
46
47
48 typedef enum {
49   NAL_UNKNOWN     = 0,
50   NAL_NON_IDR     = 1,
51   NAL_IDR         = 5,    /* ref_idc != 0 */
52   NAL_SEI         = 6,    /* ref_idc == 0 */
53   NAL_SPS         = 7,
54   NAL_PPS         = 8,
55   NAL_AUD         = 9,
56   NAL_FILLER      = 12,
57 }H264_NAL_TYPE;
58
59
60 typedef enum {
61   SLICE_TYPE_P  = 0,
62   SLICE_TYPE_B  = 1,
63   SLICE_TYPE_I  = 2
64 } H264_SLICE_TYPE;
65
66 struct _GstH264EncoderPrivate {
67   GstH264Encoder   *public;
68   guint32           format;   /*NV12, I420,*/
69   gboolean          es_flag;  /*elementary flag*/
70
71   /* private data*/
72   GQueue           *video_buffer_caches; /*not used for baseline*/
73
74   GstVaapiSurface  *ref_surface1;  /* reference buffer*/
75   GstVaapiSurface  *ref_surface2;  /* for B frames */
76   GstVaapiSurface  *recon_surface; /* reconstruct buffer*/
77
78   VABufferID        seq_parameter;
79   VABufferID        pic_parameter;
80   VABufferID        slice_parameter;
81   VABufferID        packed_sps_par_buf;
82   VABufferID        packed_sps_data_buf;
83   VABufferID        packed_pps_par_buf;
84   VABufferID        packed_pps_data_buf;
85 #ifdef _SIMPLE_LIB_VA_
86   VAEncSliceParameterBuffer     *slice_param_buffers;
87 #else
88   VAEncSliceParameterBufferH264 *slice_param_buffers;
89 #endif
90   guint32           default_slice_height;
91   guint32           slice_mod_mb_num;
92   guint32           default_cts_offset;
93
94   GstBuffer        *sps_data;
95   GstBuffer        *pps_data;
96
97   GQueue           *queued_buffers;  /* GstVaapiVideoBuffers with surface*/
98
99   guint32           gop_count;
100   guint32           cur_display_num;
101   guint32           cur_decode_num;
102   H264_SLICE_TYPE   cur_slice_type;
103   guint64           last_decode_time;
104 };
105
106 G_DEFINE_TYPE(GstH264Encoder, gst_h264_encoder, GST_TYPE_VAAPI_BASE_ENCODER);
107
108
109 // 4096-1
110 #define H264_BITSTREAM_ALLOC_ALIGN_MASK 0x0FFF
111
112 #define BIT_STREAM_BUFFER(stream)    ((stream)->buffer)
113 #define BIT_STREAM_BIT_SIZE(stream)  ((stream)->bit_size)
114
115 struct _H264Bitstream {
116   guint8   *buffer;
117   guint32   bit_size;
118   guint32   max_bit_capability;
119 };
120
121 typedef struct _H264Bitstream H264Bitstream;
122
123 static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
124
125 static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
126                                     GstVaapiContext *context, GList **coded_pics);
127
128 /*other functions*/
129 static EncoderStatus gst_h264_encoder_get_avcC_codec_data(
130                                     GstVaapiEncoder* encoder, GstBuffer **buffer);
131 static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
132
133 static gboolean      gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
134 static void          gst_h264_encoder_finalize(GObject *object);
135 static void          gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
136
137 static gboolean      gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder,
138                                     GstVaapiDisplay *display, GstVaapiContext *context);
139 static gboolean      gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder,
140                                     GstVaapiDisplay *display, GstVaapiContext *context);
141 static EncoderStatus gst_h264_encoder_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
142                                     GstVaapiVideoBuffer *display_buf,  gboolean need_flush,
143                                     GstVaapiVideoBuffer **out_buf);
144 static void          gst_h264_encoder_frame_failed(GstVaapiBaseEncoder *encoder,
145                                     GstVaapiVideoBuffer* buffer);
146 static EncoderStatus gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
147                                     GstVaapiContext *context, GstVaapiSurface *surface,
148                                     guint frame_index, VABufferID coded_buf, gboolean *is_key);
149 static void          gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
150 //static EncoderStatus h264_encoder_read_sps_pps(
151 //                                    GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size);
152 static GstBuffer    *gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
153                                     guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
154
155 /* h264 bitstream functions */
156 static void     h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
157 static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
158 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value);
159 static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value);
160 static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value);
161 static gboolean h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
162
163 static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size);
164 static void     h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
165 static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size);
166 static gboolean h264_bitstream_write_sps(H264Bitstream *bitstream, VAEncSequenceParameterBufferH264 *seq);
167 static gboolean h264_bitstream_write_pps(H264Bitstream *bitstream, VAEncPictureParameterBufferH264 *pic);
168 static gboolean h264_bitstream_write_nal_header(H264Bitstream *bitstream,
169                                     guint nal_ref_idc, guint nal_unit_type);
170
171 static const guint8 *h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size);
172 static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
173                                     guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
174
175 static void
176 gst_h264_encoder_class_init(GstH264EncoderClass *klass)
177 {
178   GObjectClass * const object_class = G_OBJECT_CLASS(klass);
179   GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
180   GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
181
182   g_type_class_add_private(klass, sizeof(GstH264EncoderPrivate));
183
184   GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
185       "gst_va_h264_encoder element");
186
187   object_class->finalize = gst_h264_encoder_finalize;
188
189   base_class->validate_attributes = gst_h264_validate_parameters;
190   base_class->pre_alloc_resource  = gst_h264_encoder_alloc_slices;
191   base_class->release_resource    = gst_h264_encoder_release_resource;
192   base_class->prepare_next_input_buffer = gst_h264_encoder_prepare_next_buffer;
193   base_class->render_frame = gst_h264_encoder_rendering;
194   base_class->notify_frame = gst_h264_notify_frame;
195   base_class->copy_coded_frame = gst_h264_encoder_copy_coded_buffer;
196   base_class->encode_frame_failed = gst_h264_encoder_frame_failed;
197
198   encoder_class->flush = gst_h264_encoder_flush;
199
200   encoder_class->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
201   /* encoder_class->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
202
203   /*
204   object_class->set_property = gst_h264_encoder_set_property;
205   object_class->get_property = gst_h264_encoder_get_property;
206   */
207 }
208
209 static VAProfile
210 h264_get_va_profile(guint32 profile)
211 {
212   switch (profile) {
213     case H264_PROFILE_BASELINE:
214       return VAProfileH264Baseline;
215
216     case H264_PROFILE_MAIN:
217       return VAProfileH264Main;
218
219     case H264_PROFILE_HIGH:
220       return VAProfileH264High;
221
222     default:
223       break;
224   }
225   return (-1);
226 }
227
228 static void
229 gst_h264_encoder_init(GstH264Encoder *encoder)
230 {
231   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
232   ENCODER_ASSERT(h264_prv);
233   h264_prv->public = encoder;
234
235   /* init public attributes */
236   gst_h264_encoder_init_public_values(encoder);
237   gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
238
239   /* init private values*/
240   h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
241   h264_prv->es_flag = TRUE;
242   //h264_prv->es_flag = FALSE;
243
244   h264_prv->ref_surface1 = NULL;
245   h264_prv->ref_surface2 = NULL;
246   h264_prv->recon_surface = NULL;
247
248   h264_prv->seq_parameter = VA_INVALID_ID;
249   h264_prv->pic_parameter = VA_INVALID_ID;
250   h264_prv->slice_parameter = VA_INVALID_ID;
251   h264_prv->packed_sps_par_buf = VA_INVALID_ID;
252   h264_prv->packed_sps_data_buf = VA_INVALID_ID;
253   h264_prv->packed_pps_par_buf = VA_INVALID_ID;
254   h264_prv->packed_pps_data_buf = VA_INVALID_ID;
255   h264_prv->slice_param_buffers = NULL;
256   h264_prv->default_slice_height = 0;
257   h264_prv->slice_mod_mb_num = 0;
258
259   h264_prv->sps_data = NULL;
260   h264_prv->pps_data = NULL;
261
262   h264_prv->queued_buffers = g_queue_new();
263   h264_prv->gop_count = 0;
264   h264_prv->cur_display_num = 0;
265   h264_prv->cur_decode_num = 0;
266   h264_prv->cur_slice_type = SLICE_TYPE_I;
267   h264_prv->last_decode_time = 0LL;
268   h264_prv->default_cts_offset = 0;
269 }
270
271 static void
272 gst_h264_encoder_finalize(GObject *object)
273 {
274   /*free private buffers*/
275   GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
276   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(object);
277
278   if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
279     gst_vaapi_encoder_uninitialize(encoder);
280   }
281
282   if (h264_prv->sps_data) {
283     gst_buffer_unref(h264_prv->sps_data);
284     h264_prv->sps_data = NULL;
285   }
286   if (h264_prv->pps_data) {
287     gst_buffer_unref(h264_prv->pps_data);
288     h264_prv->pps_data = NULL;
289   }
290   if (h264_prv->slice_param_buffers) {
291     g_free(h264_prv->slice_param_buffers);
292     h264_prv->slice_param_buffers = NULL;
293   }
294
295   if (h264_prv->queued_buffers) {
296     ENCODER_ASSERT(g_queue_is_empty(h264_prv->queued_buffers));
297     g_queue_free(h264_prv->queued_buffers);
298     h264_prv->queued_buffers = NULL;
299   }
300
301   G_OBJECT_CLASS(gst_h264_encoder_parent_class)->finalize(object);
302 }
303
304
305 GstH264Encoder *
306 gst_h264_encoder_new(void)
307 {
308   return GST_H264_ENCODER(g_object_new(GST_TYPE_H264_ENCODER, NULL));
309 }
310
311 static void
312 gst_h264_encoder_init_public_values(GstH264Encoder* encoder)
313 {
314   encoder->profile = 0;
315   encoder->level = 0;
316   encoder->bitrate = 0;
317   encoder->intra_period = 0;
318   encoder->init_qp = -1;
319   encoder->min_qp = -1;
320   encoder->slice_num = 0;
321   encoder->b_frame_num = 0;
322 }
323
324 void
325 gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es)
326 {
327   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
328   h264_prv->es_flag = es;
329 }
330
331
332 gboolean
333 gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
334 {
335   GstH264Encoder *encoder = GST_H264_ENCODER(base_encoder);
336   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
337   if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
338     return FALSE;
339   }
340   if (!encoder->profile) {
341     encoder->profile = H264_DEFAULT_PROFILE;
342   }
343   gst_vaapi_base_encoder_set_va_profile(base_encoder, h264_get_va_profile(encoder->profile));
344   if (!encoder->level) {
345     if (encoder->profile <= H264_PROFILE_BASELINE)
346       encoder->level = H264_LEVEL_30;
347     else
348       encoder->level = H264_LEVEL_41;
349   }
350   if (!encoder->intra_period) {
351     encoder->intra_period = H264_DEFAULT_INTRA_PERIOD;
352   }
353   if (-1 == encoder->init_qp) {
354     encoder->init_qp = H264_DEFAULT_INIT_QP;
355   }
356   if (-1 == encoder->min_qp) {
357     encoder->min_qp = H264_DEFAULT_MIN_QP;
358   }
359
360   if (encoder->min_qp > encoder->init_qp) {
361     encoder->min_qp = encoder->init_qp;
362   }
363
364   /* default compress ratio 1: (4*8*1.5) */
365   if (!encoder->bitrate) {
366     encoder->bitrate = 0; //ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
367   }
368
369   if (!encoder->slice_num) {
370     encoder->slice_num = H264_DEFAULT_SLICE_NUM;
371   }
372
373   /* need  calculate slice-num and each slice-height
374         suppose:  ((encoder->height+15)/16) = 13, slice_num = 8
375         then: slice_1_height = 2
376                  slice_2_height = 2
377                  slice_3_height = 2
378                  slice_4_height = 2
379                  slice_5_height = 2
380                  slice_6_height = 1
381                  slice_7_height = 1
382                  slice_8_height = 1
383    */
384   h264_prv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
385   if (0 == h264_prv->default_slice_height) { /* special value */
386     h264_prv->default_slice_height = 1;
387     h264_prv->slice_mod_mb_num = 0;
388     encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
389   } else {
390     h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
391   }
392
393   if (encoder->b_frame_num) {
394     h264_prv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
395   } else {
396     h264_prv->default_cts_offset = 0;
397   }
398   return TRUE;
399 }
400
401
402 static gboolean
403 h264_encoder_release_parameters(GstH264Encoder *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
404 {
405   VAStatus va_status = VA_STATUS_SUCCESS;
406   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
407
408   gboolean is_locked = FALSE;
409
410   ENCODER_ASSERT(display);
411   ENCODER_ASSERT(context);
412   VAAPI_UNUSED_ARG(va_status);
413   VADisplay va_dpy = gst_vaapi_display_get_display(display);
414
415   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
416   if (VA_INVALID_ID != h264_prv->seq_parameter) {
417     va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
418     h264_prv->seq_parameter = VA_INVALID_ID;
419   }
420   if (VA_INVALID_ID != h264_prv->pic_parameter) {
421     va_status = vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
422     h264_prv->pic_parameter = VA_INVALID_ID;
423   }
424   if (VA_INVALID_ID != h264_prv->slice_parameter) {
425     va_status = vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
426     h264_prv->slice_parameter = VA_INVALID_ID;
427   }
428
429   if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
430     va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_par_buf);
431     h264_prv->packed_sps_par_buf = VA_INVALID_ID;
432   }
433   if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
434     va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_data_buf);
435     h264_prv->packed_sps_data_buf = VA_INVALID_ID;
436   }
437   if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
438     va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_par_buf);
439     h264_prv->packed_pps_par_buf = VA_INVALID_ID;
440   }
441   if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
442     va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_data_buf);
443     h264_prv->packed_pps_data_buf = VA_INVALID_ID;
444   }
445
446   ENCODER_RELEASE_DISPLAY_LOCK(display);
447
448   if (h264_prv->slice_param_buffers) {
449     g_free(h264_prv->slice_param_buffers);
450     h264_prv->slice_param_buffers = NULL;
451   }
452
453   if (h264_prv->sps_data) {
454     gst_buffer_unref(h264_prv->sps_data);
455     h264_prv->sps_data = NULL;
456   }
457   if (h264_prv->pps_data) {
458     gst_buffer_unref(h264_prv->pps_data);
459     h264_prv->pps_data = NULL;
460   }
461
462   return TRUE;
463 }
464
465 static void
466 h264_release_queued_buffers(GstH264EncoderPrivate *h264_prv)
467 {
468     while (!g_queue_is_empty(h264_prv->queued_buffers)) {
469     GstBuffer* tmp = g_queue_pop_head(h264_prv->queued_buffers);
470     if (tmp)
471       gst_buffer_unref(tmp);
472   }
473 }
474
475
476 static gboolean
477 gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
478 {
479   GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
480   gboolean ret = TRUE;
481   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
482
483   /* release buffers first */
484   h264_encoder_release_parameters(h264_encoder, display, context);
485   h264_release_queued_buffers(h264_prv);
486   h264_prv->cur_display_num = 0;
487   h264_prv->cur_decode_num = 0;
488   h264_prv->cur_slice_type = SLICE_TYPE_I;
489   h264_prv->gop_count = 0;
490   h264_prv->last_decode_time = 0LL;
491   h264_prv->default_cts_offset = 0;
492
493   /*remove ref_surface1*/
494   if (h264_prv->ref_surface1) {
495     if (context) {
496       gst_vaapi_context_put_surface(context, h264_prv->ref_surface1);
497     } else {
498       g_object_unref(h264_prv->ref_surface1);
499     }
500     h264_prv->ref_surface1 = NULL;
501   }
502
503   if (h264_prv->ref_surface2) {
504     if (context) {
505       gst_vaapi_context_put_surface(context, h264_prv->ref_surface2);
506     } else {
507       g_object_unref(h264_prv->ref_surface2);
508     }
509     h264_prv->ref_surface2 = NULL;
510   }
511
512   /*remove recon_surface*/
513   if (h264_prv->recon_surface) {
514     if (context) {
515       gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
516     } else {
517       g_object_unref(h264_prv->recon_surface);
518     }
519     h264_prv->recon_surface = NULL;
520   }
521
522   return ret;
523 }
524
525 static gboolean
526 gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display, GstVaapiContext *context)
527 {
528   gboolean ret = TRUE;
529   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
530   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
531
532   h264_prv->slice_param_buffers =
533 #ifdef _SIMPLE_LIB_VA_
534   (VAEncSliceParameterBuffer*)
535 #else
536   (VAEncSliceParameterBufferH264*)
537 #endif
538           g_malloc0_n(h264_encoder->slice_num,
539               sizeof(h264_prv->slice_param_buffers[0]));
540
541   return ret;
542 }
543
544 static void
545 gst_h264_encoder_frame_failed(GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer)
546 {
547   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
548   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
549
550   h264_release_queued_buffers(h264_prv);
551   h264_prv->cur_display_num = 0;
552   h264_prv->cur_decode_num = 0;
553   h264_prv->cur_slice_type = SLICE_TYPE_I;
554   h264_prv->gop_count = 0;
555   h264_prv->last_decode_time = 0LL;
556 }
557
558 static EncoderStatus
559 gst_h264_encoder_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
560                               GstVaapiVideoBuffer *display_buf, gboolean need_flush,
561                               GstVaapiVideoBuffer **out_buf)
562 {
563   EncoderStatus ret = ENCODER_NO_ERROR;
564   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
565   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
566   GstVaapiVideoBuffer  *return_buf = NULL;
567   //guint64 pts = 0;
568
569   if (NULL == display_buf && g_queue_is_empty(h264_prv->queued_buffers)) {
570     ret = ENCODER_BUFFER_EMPTY;
571     if (h264_prv->gop_count >= h264_encoder->intra_period || need_flush)
572       h264_prv->gop_count = 0;
573     goto end;
574   }
575
576   if (display_buf) {
577     ++h264_prv->gop_count;
578     gst_buffer_ref(GST_BUFFER_CAST(display_buf));
579     h264_prv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
580   }
581
582   /* first frame */
583   if (h264_prv->gop_count == 1) {
584     ENCODER_ASSERT(display_buf);
585     h264_prv->cur_display_num = 0;
586     h264_prv->cur_decode_num = 0;
587     h264_prv->cur_slice_type = SLICE_TYPE_I;
588     return_buf = display_buf;
589     goto end;
590   }
591
592   if (display_buf) {
593     if (h264_encoder->b_frame_num &&
594         h264_prv->gop_count < h264_encoder->intra_period &&
595         g_queue_get_length(h264_prv->queued_buffers) < h264_encoder->b_frame_num
596         )
597     {
598       g_queue_push_tail(h264_prv->queued_buffers, display_buf);
599       ret = ENCODER_BUFFER_WAITING;
600       goto end;
601     }
602     h264_prv->cur_slice_type = SLICE_TYPE_P;
603     h264_prv->cur_display_num = h264_prv->gop_count-1;
604     ++h264_prv->cur_decode_num;
605     return_buf = display_buf;
606   } else {
607     if (need_flush) {
608       return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(h264_prv->queued_buffers);
609       h264_prv->cur_slice_type = SLICE_TYPE_P;
610       h264_prv->cur_display_num = h264_prv->gop_count - 1;
611       ++h264_prv->cur_decode_num;
612     } else {
613       return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(h264_prv->queued_buffers);
614       h264_prv->cur_slice_type = SLICE_TYPE_B;
615       h264_prv->cur_display_num = h264_prv->gop_count - 2 - g_queue_get_length(h264_prv->queued_buffers);
616     }
617   }
618
619 end:
620   *out_buf = return_buf;
621   /* calculate cts/pts/dts */
622 #if 0
623   if (return_buf) {
624     pts = GST_BUFFER_TIMESTAMP(return_buf);
625     tmp_next_buf = (GstVaapiVideoBuffer*)g_queue_peek_head(h264_prv->queued_buffers);
626     if (tmp_next_buf) {
627       GST_BUFFER_TIMESTAMP(return_buf) = GST_BUFFER_TIMESTAMP(tmp_next_buf);
628     } else if (SLICE_TYPE_B == h264_prv->cur_slice_type) {
629       GST_BUFFER_TIMESTAMP(return_buf) = h264_prv->last_decode_time;
630     }
631
632     pts += h264_prv->default_cts_offset;
633     if ((gint64)(pts - GST_BUFFER_TIMESTAMP(return_buf)) < 0) {
634       pts = GST_BUFFER_TIMESTAMP(return_buf);
635     }
636
637     GST_BUFFER_OFFSET_END(return_buf) = pts;
638     GST_BUFFER_TIMESTAMP(return_buf) = pts;
639   }
640 #endif
641
642   return ret;
643 }
644
645
646 #ifdef _SIMPLE_LIB_VA_
647 static EncoderStatus
648 gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
649                              GstVaapiContext *context, GstVaapiSurface *surface,
650                              guint frame_index, VABufferID coded_buf, gboolean *is_key)
651 {
652   EncoderStatus ret = ENCODER_NO_ERROR;
653   VAStatus va_status = VA_STATUS_SUCCESS;
654   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
655   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
656   VAEncPictureParameterBufferH264 pic_h264;
657   VAEncSliceParameterBuffer *slice_h264 = NULL;
658
659   gboolean is_locked = FALSE;
660
661   ENCODER_ASSERT(display && context);
662   VADisplay va_dpy = gst_vaapi_display_get_display(display);
663   VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
664
665   *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
666
667   /* lock display */
668   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
669   /*handle first surface_index*/
670   /*only need first frame*/
671   if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
672     VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
673     seq_h264.level_idc = h264_encoder->level; /* 3.0 */
674     seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
675     seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
676     seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
677
678     seq_h264.bits_per_second = h264_encoder->bitrate;
679     seq_h264.frame_rate = ENCODER_FPS(h264_encoder);
680     seq_h264.initial_qp = h264_encoder->init_qp; /*qp_value; 15, 24, 26?*/
681     seq_h264.min_qp = h264_encoder->min_qp;     /*1, 6, 10*/
682     seq_h264.basic_unit_size = 0;
683     seq_h264.intra_period = h264_encoder->intra_period;
684     seq_h264.intra_idr_period = h264_encoder->intra_period;
685
686     va_status = vaCreateBuffer(va_dpy, context_id,
687                                VAEncSequenceParameterBufferType,
688                                sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
689     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
690                          ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.");
691     va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
692     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
693                          ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.");
694   }
695
696   /* set pic_parameters*/
697   if (!h264_prv->ref_surface1) {
698     h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
699     ENCODER_CHECK_STATUS(h264_prv->ref_surface1, ENCODER_SURFACE_ERR,
700                          "reference surface, h264_pop_free_surface failed.");
701   }
702   if (!h264_prv->recon_surface) {
703     h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
704     ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR,
705                          "reconstructed surface, h264_pop_free_surface failed.");
706   }
707
708   pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
709   pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
710   pic_h264.coded_buf = coded_buf;
711   pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
712   pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
713   pic_h264.last_picture = 0; // last pic or not
714
715   if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
716     vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
717     h264_prv->pic_parameter = VA_INVALID_ID;
718   }
719   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
720                                sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
721
722   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
723                        ENCODER_PICTURE_ERR, "creating pic-param buffer failed.");
724
725   va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
726   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
727                        ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.");
728
729   /* set slice parameters, support multiple slices */
730   int i = 0;
731   guint32 last_row_num = 0;
732   guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
733
734   memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
735   for (i = 0; i < h264_encoder->slice_num; ++i) {
736     slice_h264 = &h264_prv->slice_param_buffers[i];
737     slice_h264->start_row_number = last_row_num;               /* unit MB*/
738     slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
739     if (slice_mod_num) {
740       ++slice_h264->slice_height;
741       --slice_mod_num;
742     }
743     last_row_num += slice_h264->slice_height;
744     slice_h264->slice_flags.bits.is_intra = *is_key;
745     slice_h264->slice_flags.bits.disable_deblocking_filter_idc = 0;
746
747   }
748   ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
749
750   if (VA_INVALID_ID != h264_prv->slice_parameter) {
751     vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
752     h264_prv->slice_parameter = VA_INVALID_ID;
753   }
754   va_status = vaCreateBuffer(va_dpy,
755                              context_id,
756                              VAEncSliceParameterBufferType,
757                              sizeof(h264_prv->slice_param_buffers[0]),
758                              h264_encoder->slice_num,
759                              h264_prv->slice_param_buffers,
760                              &h264_prv->slice_parameter);
761   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
762                        ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.");
763
764   va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
765   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
766                        ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.");
767
768   /*after finished, set ref_surface1_index, recon_surface_index */
769   GstVaapiSurface *swap = h264_prv->ref_surface1;
770   h264_prv->ref_surface1 = h264_prv->recon_surface;
771   h264_prv->recon_surface = swap;
772
773   end:
774   ENCODER_RELEASE_DISPLAY_LOCK(display);
775   return ret;
776 }
777
778 #else  /* extended libva, new parameter structures*/
779
780 static void h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
781 {
782   GstVaapiSurface *tmp;
783
784   g_return_if_fail(s1 && s2);
785   tmp = *s1;
786   *s1 = *s2;
787   *s2 = tmp;
788 }
789
790 static gboolean
791 h264_recreate_seq_param(GstH264Encoder *h264_encoder,
792                         VADisplay va_dpy, VAContextID context_id)
793 {
794   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
795   VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
796   guint width_in_mbs, height_in_mbs;
797   gboolean ret = TRUE;
798   VAStatus va_status = VA_STATUS_SUCCESS;
799
800   /* only once */
801   if (VA_INVALID_ID != h264_prv->seq_parameter)
802     return TRUE;
803
804   width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
805   height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
806
807   seq_h264.seq_parameter_set_id = 0;
808   seq_h264.profile_idc = h264_encoder->profile;
809   seq_h264.level_idc = h264_encoder->level; /* 3.0 */
810   seq_h264.intra_period = h264_encoder->intra_period;
811   seq_h264.ip_period = 0;           // ?
812   seq_h264.max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1);  // ?, why 4
813   seq_h264.picture_width_in_mbs = width_in_mbs;
814   seq_h264.picture_height_in_mbs = height_in_mbs;
815   seq_h264.frame_mbs_only_flag = 1;
816   seq_h264.target_usage = 1;        // ?
817
818   if (h264_encoder->init_qp == -1)
819       seq_h264.rate_control_method = BR_CBR;
820   else if (h264_encoder->init_qp == -2)
821       seq_h264.rate_control_method = BR_VBR;
822   else {
823       ENCODER_ASSERT(h264_encoder->init_qp >= 0 && h264_encoder->init_qp <= 51);
824       seq_h264.rate_control_method = BR_CQP;
825   }
826
827   if (h264_encoder->bitrate> 0)
828       seq_h264.bits_per_second = h264_encoder->bitrate; /* use kbps as input */
829   else
830       seq_h264.bits_per_second = 0;
831
832   if (seq_h264.rate_control_method == BR_VBR) {
833     seq_h264.max_bits_per_second = seq_h264.bits_per_second*1.5;
834     seq_h264.min_bits_per_second = seq_h264.bits_per_second*0.3;
835   }
836   seq_h264.initial_hrd_buffer_fullness = 0;   // ??
837   seq_h264.hrd_buffer_size = 0;
838   seq_h264.num_units_in_tick = 100;
839   seq_h264.time_scale = ENCODER_FPS(h264_encoder)*2*seq_h264.num_units_in_tick;
840
841   if (height_in_mbs*16 - ENCODER_HEIGHT(h264_encoder)) {
842     seq_h264.frame_cropping_flag = 1;
843     seq_h264.frame_crop_left_offset = 0;
844     seq_h264.frame_crop_right_offset = 0;
845     seq_h264.frame_crop_top_offset = 0;
846     seq_h264.frame_crop_bottom_offset =
847            (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_h264.frame_mbs_only_flag + 1));
848   }
849   seq_h264.pic_order_cnt_type = 0;   // pic order cnt
850   seq_h264.direct_8x8_inference_flag = 0;
851   seq_h264.log2_max_frame_num_minus4 = 4; // log2(seq_h264.intra_period)-3 : 0
852   seq_h264.log2_max_pic_order_cnt_lsb_minus4 = seq_h264.log2_max_frame_num_minus4+2;
853   seq_h264.vui_flag = 0; // 0? or 1?
854
855   va_status = vaCreateBuffer(va_dpy, context_id,
856                              VAEncSequenceParameterBufferType,
857                              sizeof(seq_h264), 1,
858                              &seq_h264, &h264_prv->seq_parameter);
859   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
860                      FALSE, "alloc seq-buffer failed.");
861
862   /*pack sps header buffer/data */
863   if (NULL == h264_prv->sps_data) {
864     VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
865     guint32 length_in_bits, offset_in_bytes;
866     guint8 *packed_seq_buffer = NULL;
867     H264Bitstream bitstream;
868     h264_bitstream_init(&bitstream, 128*8);
869     h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
870     h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
871     h264_bitstream_write_sps(&bitstream, &seq_h264);
872     ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
873     length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
874     packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
875     //h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
876     //GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4;
877     //memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, (length_in_bits+7)/8-4);
878
879     offset_in_bytes = 0;
880     packed_header_param_buffer.type = VAEncPackedHeaderSPS;
881     packed_header_param_buffer.insert_emulation_bytes = 1;
882     packed_header_param_buffer.skip_emulation_check_count = 5;
883     packed_header_param_buffer.num_headers = 1;
884     packed_header_param_buffer.length_in_bits = &length_in_bits;
885     packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
886     va_status = vaCreateBuffer(va_dpy,
887                                context_id,
888                                VAEncPackedHeaderParameterBufferType,
889                                sizeof(packed_header_param_buffer), 1,
890                                &packed_header_param_buffer,
891                                &h264_prv->packed_sps_par_buf);
892     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
893                          FALSE,
894                          "EncPackedSeqHeaderParameterBuffer failed");
895     va_status = vaCreateBuffer(va_dpy,
896                                context_id,
897                                VAEncPackedHeaderDataBufferType,
898                                (length_in_bits + 7) / 8, 1,
899                                packed_seq_buffer,
900                                &h264_prv->packed_sps_data_buf);
901     h264_bitstream_destroy(&bitstream, TRUE);
902     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
903                          FALSE,
904                          "EncPackedSeqHeaderDataBuffer failed");
905   }
906 end:
907
908   return ret;
909 }
910
911 static gboolean
912 h264_recreate_pic_param(GstH264Encoder *h264_encoder,
913                         VADisplay va_dpy, VAContextID context_id,
914                         VABufferID coded_buf)
915 {
916   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
917   VAEncPictureParameterBufferH264 pic_h264;
918   gboolean ret = TRUE;
919   VAStatus va_status = VA_STATUS_SUCCESS;
920
921   VAAPI_UNUSED_ARG(va_status);
922   memset(&pic_h264, 0, sizeof(pic_h264));
923   pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
924   pic_h264.CurrPic.TopFieldOrderCnt = h264_prv->cur_display_num * 2;   // ??? /**/
925   pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
926   pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
927   pic_h264.ReferenceFrames[2].picture_id = VA_INVALID_ID;
928   pic_h264.CodedBuf = coded_buf;
929
930   pic_h264.seq_parameter_set_id = 0;
931   pic_h264.pic_parameter_set_id = 0;
932   pic_h264.last_picture = 0;
933   pic_h264.frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ?
934                        (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num);
935   pic_h264.coding_type = 0;
936   pic_h264.pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26);
937   pic_h264.num_ref_idx_l0_active_minus1 = 0;
938   pic_h264.num_ref_idx_l1_active_minus1 = 0;
939   pic_h264.pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I);
940   pic_h264.pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B);
941   pic_h264.pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC;
942   pic_h264.pic_fields.bits.weighted_pred_flag = 0;
943   pic_h264.pic_fields.bits.weighted_bipred_idc = 0;
944   pic_h264.pic_fields.bits.transform_8x8_mode_flag = 1;
945   pic_h264.pic_fields.bits.deblocking_filter_control_present_flag = 1;
946
947   char *frame_type = "I";
948   if (h264_prv->cur_slice_type == SLICE_TYPE_P)
949     frame_type = "P";
950   if (h264_prv->cur_slice_type == SLICE_TYPE_B)
951     frame_type = "B";
952   ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
953          frame_type, pic_h264.frame_num, pic_h264.CurrPic.TopFieldOrderCnt);
954
955   if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
956     vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
957     h264_prv->pic_parameter = VA_INVALID_ID;
958   }
959   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
960                                sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
961
962   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
963                        FALSE, "creating pic-param buffer failed.");
964
965   //if (NULL == h264_prv->pps_data) {
966   if (VA_INVALID_ID == h264_prv->packed_pps_data_buf) {
967     VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
968     guint32 length_in_bits, offset_in_bytes;
969     guint8 *packed_pic_buffer = NULL;
970     H264Bitstream bitstream;
971     h264_bitstream_init(&bitstream, 128*8);
972     h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
973     h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_PPS);
974     h264_bitstream_write_pps(&bitstream, &pic_h264);
975     ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
976     length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
977     packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
978     //h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
979     //GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4;
980     //memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, (length_in_bits+7)/8-4);
981
982     offset_in_bytes = 0;
983     packed_header_param_buffer.type = VAEncPackedHeaderPPS;
984     packed_header_param_buffer.insert_emulation_bytes = 1;
985     packed_header_param_buffer.skip_emulation_check_count = 5;
986     packed_header_param_buffer.num_headers = 1;
987     packed_header_param_buffer.length_in_bits = &length_in_bits;
988     packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
989
990     va_status = vaCreateBuffer(va_dpy,
991                                context_id,
992                                VAEncPackedHeaderParameterBufferType,
993                                sizeof(packed_header_param_buffer), 1,
994                                &packed_header_param_buffer,
995                                &h264_prv->packed_pps_par_buf);
996     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
997                          FALSE,
998                          "EncPackedPicHeaderParameterBuffer failed");
999
1000     va_status = vaCreateBuffer(va_dpy,
1001                                context_id,
1002                                VAEncPackedHeaderDataBufferType,
1003                                (length_in_bits + 7) / 8, 1,
1004                                packed_pic_buffer,
1005                                &h264_prv->packed_pps_data_buf);
1006     h264_bitstream_destroy(&bitstream, TRUE);
1007     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1008                          FALSE,
1009                          "EncPackedPicHeaderDataBuffer failed");
1010   }
1011
1012 end:
1013   return ret;
1014 }
1015
1016
1017 static gboolean
1018 h264_recreate_slice_param(GstH264Encoder *h264_encoder,
1019                         VADisplay va_dpy, VAContextID context_id)
1020 {
1021   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1022   VAEncSliceParameterBufferH264 *slice_h264 = NULL;
1023   guint width_in_mbs;
1024   gboolean ret = TRUE;
1025   VAStatus va_status = VA_STATUS_SUCCESS;
1026
1027   width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
1028
1029   int i = 0;
1030   guint32 last_row_num = 0;
1031   guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
1032
1033   memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
1034   for (i = 0; i < h264_encoder->slice_num; ++i) {
1035     slice_h264 = &h264_prv->slice_param_buffers[i];
1036
1037     slice_h264->starting_macroblock_address = last_row_num*width_in_mbs;
1038     slice_h264->number_of_mbs = width_in_mbs*h264_prv->default_slice_height;
1039     last_row_num += h264_prv->default_slice_height;
1040     if (slice_mod_num) {
1041       slice_h264->number_of_mbs += width_in_mbs;
1042       ++last_row_num;
1043       --slice_mod_num;
1044     }
1045     slice_h264->pic_parameter_set_id = 0;
1046     slice_h264->slice_type = h264_prv->cur_slice_type;
1047     slice_h264->direct_spatial_mv_pred_flag = 0;
1048     slice_h264->num_ref_idx_l0_active_minus1 = 0;
1049     slice_h264->num_ref_idx_l1_active_minus1 = 0;
1050     slice_h264->cabac_init_idc = 0;
1051     slice_h264->slice_qp_delta = 0;
1052     slice_h264->disable_deblocking_filter_idc = 0;
1053     slice_h264->slice_alpha_c0_offset_div2 = 2;
1054     slice_h264->slice_beta_offset_div2 = 2;
1055     slice_h264->idr_pic_id = 0;
1056
1057     slice_h264->ref_pic_list_modification_flag_l0 = 0;
1058     slice_h264->ref_pic_list_modification_flag_l1 = 0;
1059
1060   }
1061   ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
1062
1063   if (VA_INVALID_ID != h264_prv->slice_parameter) {
1064     vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
1065     h264_prv->slice_parameter = VA_INVALID_ID;
1066   }
1067   va_status = vaCreateBuffer(va_dpy,
1068                              context_id,
1069                              VAEncSliceParameterBufferType,
1070                              sizeof(h264_prv->slice_param_buffers[0]),
1071                              h264_encoder->slice_num,
1072                              h264_prv->slice_param_buffers,
1073                              &h264_prv->slice_parameter);
1074   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
1075                        FALSE, "creating slice-parameters buffer failed.");
1076
1077 end:
1078   return ret;
1079 }
1080
1081 static EncoderStatus
1082 gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
1083                              GstVaapiContext *context, GstVaapiSurface *surface,
1084                              guint frame_index, VABufferID coded_buf, gboolean *is_key)
1085 {
1086   EncoderStatus ret = ENCODER_NO_ERROR;
1087   VAStatus va_status = VA_STATUS_SUCCESS;
1088   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1089   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1090   VABufferID va_buffers[64];
1091   guint32    va_buffers_count = 0;
1092   gboolean is_params_ok = TRUE;
1093
1094   gboolean is_locked = FALSE;
1095
1096   ENCODER_ASSERT(display && context);
1097   VADisplay va_dpy = gst_vaapi_display_get_display(display);
1098   VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
1099
1100   *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
1101
1102   if (!h264_prv->ref_surface1) {
1103     h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
1104     ENCODER_CHECK_STATUS(h264_prv->ref_surface1,
1105                          ENCODER_SURFACE_ERR,
1106                          "reference surface, h264_pop_free_surface failed.");
1107   }
1108   if (!h264_prv->ref_surface2) {
1109     h264_prv->ref_surface2 = gst_vaapi_context_get_surface(context);
1110     ENCODER_CHECK_STATUS(h264_prv->ref_surface2,
1111                          ENCODER_SURFACE_ERR,
1112                          "reference surface, h264_pop_free_surface failed.");
1113   }
1114   if (!h264_prv->recon_surface) {
1115     h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
1116     ENCODER_CHECK_STATUS(h264_prv->recon_surface,
1117                          ENCODER_SURFACE_ERR,
1118                          "reconstructed surface, h264_pop_free_surface failed.");
1119   }
1120
1121   if (SLICE_TYPE_P == h264_prv->cur_slice_type) {
1122     h264_swap_surface(&h264_prv->ref_surface1, &h264_prv->ref_surface2);
1123   }
1124
1125   /* set sequence parameters, need set every time */
1126   is_params_ok = h264_recreate_seq_param(h264_encoder, va_dpy, context_id);
1127   ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1128                        "h264_recreate_seq_param failed");
1129   /* set pic_parameters*/
1130   is_params_ok = h264_recreate_pic_param(h264_encoder, va_dpy, context_id, coded_buf);
1131   ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1132                        "h264_recreate_pic_param failed");
1133   /* set slice parameters, support multiple slices */
1134   is_params_ok = h264_recreate_slice_param(h264_encoder, va_dpy, context_id);
1135   ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1136                        "h264_recreate_slice_param failed");
1137
1138   /* lock display */
1139   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
1140
1141   /*render all buffers*/
1142   if (VA_INVALID_ID != h264_prv->seq_parameter) {
1143     va_buffers[va_buffers_count++] = h264_prv->seq_parameter;
1144   }
1145   if (VA_INVALID_ID != h264_prv->pic_parameter) {
1146     va_buffers[va_buffers_count++] = h264_prv->pic_parameter;
1147   }
1148   if (VA_INVALID_ID != h264_prv->slice_parameter) {
1149     va_buffers[va_buffers_count++] = h264_prv->slice_parameter;
1150   }
1151   if (SLICE_TYPE_I == h264_prv->cur_slice_type) {
1152     if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
1153       va_buffers[va_buffers_count++] = h264_prv->packed_sps_par_buf;
1154     }
1155     if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
1156       va_buffers[va_buffers_count++] = h264_prv->packed_sps_data_buf;
1157     }
1158     if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
1159       va_buffers[va_buffers_count++] = h264_prv->packed_pps_par_buf;
1160     }
1161     if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
1162       va_buffers[va_buffers_count++] = h264_prv->packed_pps_data_buf;
1163     }
1164   }
1165
1166   va_status = vaRenderPicture(va_dpy, context_id, va_buffers, va_buffers_count);
1167   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR,
1168                        "vaRenderH264Picture failed.");
1169
1170   /*after finished,  swap  recon and surface2*/
1171   if (SLICE_TYPE_P == h264_prv->cur_slice_type ||
1172       SLICE_TYPE_I == h264_prv->cur_slice_type) {
1173     h264_swap_surface(&h264_prv->recon_surface, &h264_prv->ref_surface2);
1174   }
1175
1176   end:
1177   ENCODER_RELEASE_DISPLAY_LOCK(display);
1178   return ret;
1179 }
1180
1181 #endif
1182
1183 static GstBuffer *
1184 gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
1185                                         guint8 *frame,
1186                                         guint32 frame_size,
1187                                         VABufferID *coded_buf)
1188 {
1189   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
1190   GstBuffer *ret_buffer;
1191   guint32   nal_size;
1192   const guint8   *nal_start;
1193   guint8  *frame_end;
1194
1195   ret_buffer = gst_buffer_new();
1196   ENCODER_ASSERT(ret_buffer);
1197   H264Bitstream bitstream;
1198   h264_bitstream_init(&bitstream, (frame_size+32)*8);
1199   h264_bitstream_align(&bitstream, 0);
1200   ENCODER_ASSERT(bitstream.bit_size == 0);
1201
1202   if (!h264_prv->es_flag) { /*nal format*/
1203     h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
1204     ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
1205   } else { /* elementary format */
1206     frame_end = frame + frame_size;
1207     nal_start = frame;
1208     nal_size = 0;
1209     while((nal_start = h264_next_nal(nal_start, frame_end-nal_start, &nal_size)) != NULL) {
1210       ENCODER_ASSERT(nal_size);
1211       if (!nal_size) {
1212         nal_start += nal_size;
1213         continue;
1214       }
1215       h264_bitstream_write_uint(&bitstream, nal_size, 32);
1216       h264_bitstream_write_byte_array(&bitstream, nal_start, nal_size);
1217       nal_start += nal_size;
1218     }
1219   }
1220   h264_bitstream_align(&bitstream, 0);
1221
1222   GST_BUFFER_MALLOCDATA(ret_buffer) =
1223         GST_BUFFER_DATA(ret_buffer) = BIT_STREAM_BUFFER(&bitstream);
1224   GST_BUFFER_SIZE(ret_buffer) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1225   h264_bitstream_destroy(&bitstream, FALSE);
1226
1227   return ret_buffer;
1228 }
1229
1230 static EncoderStatus
1231 h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size)
1232 {
1233   const guint8 *end = buf + size;
1234   const guint8 *nal_start = buf;
1235   guint32 nal_size = 0;
1236   guint8 nal_type;
1237   GstBuffer *sps = NULL, *pps = NULL;
1238
1239   while((!sps || !pps) && (nal_start = h264_next_nal(nal_start, end-nal_start, &nal_size)) != NULL) {
1240     if (!nal_size) {
1241       nal_start += nal_size;
1242       continue;
1243     }
1244
1245     nal_type = (*nal_start)&0x1F;
1246     switch (nal_type) {
1247       case NAL_SPS: {
1248         sps = gst_buffer_new_and_alloc(nal_size);
1249         memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
1250         gst_buffer_replace(&h264_prv->sps_data, sps);
1251         gst_buffer_unref(sps); /*don't set to NULL*/
1252         break;
1253       }
1254
1255       case NAL_PPS: {
1256         pps = gst_buffer_new_and_alloc(nal_size);
1257         memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
1258         gst_buffer_replace(&h264_prv->pps_data, pps);
1259         gst_buffer_unref(pps);
1260         break;
1261       }
1262
1263       default:
1264         break;
1265     }
1266     nal_start += nal_size;
1267
1268   }
1269   if (!sps || !pps) {
1270     return ENCODER_DATA_NOT_READY;
1271   }
1272   return ENCODER_NO_ERROR;
1273 }
1274
1275 static void
1276 gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
1277 {
1278   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
1279   if (!h264_prv->sps_data || !h264_prv->pps_data) {
1280     h264_encoder_read_sps_pps(h264_prv, buf, size);
1281   }
1282   if (h264_prv->sps_data && h264_prv->pps_data) {
1283     gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
1284   }
1285 }
1286
1287
1288 static gboolean
1289 h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
1290                                 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc)
1291 {
1292   ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
1293   ENCODER_ASSERT(sps_size >= 4);
1294   if (sps_size < 4) {
1295     return FALSE;
1296   }
1297   /*skip sps_data[0], nal_type*/
1298   *profile_idc = sps_data[1];
1299   *profile_comp = sps_data[2];
1300   *level_idc = sps_data[3];
1301   return TRUE;
1302 }
1303
1304
1305 static EncoderStatus
1306 gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
1307                        GstVaapiContext *context, GList **coded_pics)
1308 {
1309   GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
1310   EncoderStatus ret = ENCODER_NO_ERROR;
1311   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1312
1313   //h264_prv->frame_count = 0;
1314   h264_prv->cur_display_num = 0;
1315   h264_prv->cur_decode_num = 0;
1316   h264_prv->cur_slice_type = SLICE_TYPE_I;
1317   h264_prv->gop_count = g_queue_get_length(h264_prv->queued_buffers);
1318   //gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
1319
1320   //end:
1321   return ret;
1322 }
1323
1324 /*test*/
1325 static int draw_picture(int width, int height,
1326                          unsigned char *Y_start,
1327                          unsigned char *U_start,
1328                          unsigned char *V_start,
1329                          int UV_interleave, int box_width, int row_shift);
1330
1331 int main_test(int argc, char* argv[])
1332 {
1333   EncoderStatus ret = ENCODER_NO_ERROR;
1334   GstVaapiEncoder *encoder = NULL;
1335
1336   GList *coded_pics = NULL;
1337   GstBuffer **raw_buffer = NULL;
1338   const guint32 raw_buffer_num = 20;
1339
1340   GstBuffer *tmp_buffer;
1341
1342   guint32 i = 0, k = 0;
1343
1344   gst_init (&argc, &argv);
1345
1346   g_type_init();
1347   if (!g_thread_supported ())
1348     g_thread_init (NULL);
1349
1350   GstH264Encoder *h264_encoder = gst_h264_encoder_new();
1351   encoder = GST_VAAPI_ENCODER(h264_encoder);
1352   ENCODER_ASSERT(encoder);
1353
1354   h264_encoder->profile = 64;
1355   h264_encoder->level = 30;
1356   encoder->width = 1280;
1357   encoder->height = 720;
1358   encoder->frame_rate = 10;
1359   h264_encoder->bitrate = 512*1000;
1360   h264_encoder->intra_period = 30;
1361   ret = gst_vaapi_encoder_initialize(encoder);
1362   ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
1363   ret = gst_vaapi_encoder_open(encoder, NULL);
1364   ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
1365
1366   guint32 buffer_size = encoder->width * encoder->width *3 /2;
1367   guint32 y_width = encoder->width, y_size = encoder->width * encoder->height;
1368   guint32 u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
1369   guint32 v_width = encoder->width/2;
1370   guint8 *y_src, *u_src, *v_src;
1371
1372   /*set buffers*/
1373   int box_width=8;
1374   int row_shift=0;
1375
1376   VAAPI_UNUSED_ARG(v_width);
1377   VAAPI_UNUSED_ARG(u_width);
1378   VAAPI_UNUSED_ARG(y_width);
1379   raw_buffer = (GstBuffer**)g_malloc0(raw_buffer_num*sizeof(GstBuffer*));
1380   for (i = 0; i < raw_buffer_num; i++) {
1381     raw_buffer[i] = gst_buffer_new_and_alloc(buffer_size);
1382     y_src = GST_BUFFER_DATA(raw_buffer[i]);
1383     u_src = y_src + y_size;
1384     v_src = u_src + u_size;
1385
1386     draw_picture(encoder->width, encoder->height, y_src, u_src, v_src, 0, box_width, row_shift);
1387     row_shift++;
1388     if (row_shift==(2*box_width)) row_shift= 0;
1389   }
1390
1391   FILE *fp = fopen("tmp.h264", "wb");
1392   ENCODER_ASSERT(fp);
1393
1394   k = 0;
1395
1396   for (i = 0; i < 50; i++) {
1397     coded_pics = NULL;
1398     ret = gst_vaapi_encoder_encode(encoder, raw_buffer[k], &coded_pics);
1399     ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
1400     ++k;
1401     if (k >= raw_buffer_num) k = 0;
1402
1403     while (coded_pics) {
1404       tmp_buffer = coded_pics->data;
1405       coded_pics = g_list_remove(coded_pics, tmp_buffer);
1406       fwrite(GST_BUFFER_DATA(tmp_buffer), GST_BUFFER_SIZE(tmp_buffer), 1, fp);
1407       printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8));
1408       gst_buffer_unref(tmp_buffer);
1409     }
1410   }
1411   fclose(fp);
1412
1413   ret = gst_vaapi_encoder_close(encoder);
1414   ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
1415
1416   for (i = 0; i < raw_buffer_num; i++) {
1417     gst_buffer_unref(raw_buffer[i]);
1418   }
1419   g_free(raw_buffer);
1420   gst_vaapi_encoder_unref(encoder);
1421
1422   return 0;
1423 }
1424
1425 EncoderStatus
1426 gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
1427 {
1428   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1429   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1430   GstBuffer *avc_codec;
1431   const guint32 configuration_version = 0x01;
1432   const guint32 length_size_minus_one = 0x03;
1433   guint32 profile, profile_comp, level_idc;
1434
1435   ENCODER_ASSERT(buffer);
1436   if (!h264_prv->sps_data || !h264_prv->pps_data) {
1437     return ENCODER_DATA_NOT_READY;
1438   }
1439
1440   if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(h264_prv->sps_data),
1441                                    GST_BUFFER_SIZE(h264_prv->sps_data),
1442                                    &profile, &profile_comp, &level_idc))
1443   {
1444     ENCODER_ASSERT(0);
1445     return ENCODER_DATA_ERR;
1446   }
1447
1448   H264Bitstream bitstream;
1449   h264_bitstream_init(&bitstream,
1450                      (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 32)*8);
1451
1452   /*codec_data*/
1453   h264_bitstream_write_uint(&bitstream, configuration_version, 8);
1454   h264_bitstream_write_uint(&bitstream, profile, 8);
1455   h264_bitstream_write_uint(&bitstream, profile_comp, 8);
1456   h264_bitstream_write_uint(&bitstream, level_idc, 8);
1457   h264_bitstream_write_uint(&bitstream, h264_bit_mask[6], 6); /*111111*/
1458   h264_bitstream_write_uint(&bitstream, length_size_minus_one, 2);
1459   h264_bitstream_write_uint(&bitstream, h264_bit_mask[3], 3); /*111*/
1460
1461   /*write sps*/
1462   h264_bitstream_write_uint(&bitstream, 1, 5);   /* sps count = 1*/
1463   ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
1464   h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->sps_data), 16);
1465   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
1466                                               GST_BUFFER_SIZE(h264_prv->sps_data));
1467
1468   /*write pps*/
1469   h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
1470   h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->pps_data), 16);
1471   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
1472                                               GST_BUFFER_SIZE(h264_prv->pps_data));
1473
1474   avc_codec = gst_buffer_new();
1475   GST_BUFFER_MALLOCDATA(avc_codec) =
1476          GST_BUFFER_DATA(avc_codec) =
1477          BIT_STREAM_BUFFER(&bitstream);
1478   GST_BUFFER_SIZE(avc_codec) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1479   h264_bitstream_destroy(&bitstream, FALSE);
1480   *buffer = avc_codec;
1481
1482   return ENCODER_NO_ERROR;
1483 }
1484
1485 EncoderStatus
1486 gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
1487 {
1488   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1489   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1490   GstBuffer *nal_sps_pps;
1491
1492   ENCODER_ASSERT(buffer);
1493   if (!h264_prv->sps_data || !h264_prv->pps_data) {
1494     return ENCODER_DATA_NOT_READY;
1495   }
1496
1497   H264Bitstream bitstream;
1498   h264_bitstream_init(&bitstream,
1499                      (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 8)*8);
1500
1501   /*0x000001 start code*/
1502   h264_bitstream_write_uint(&bitstream, 0x000001, 24);
1503   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
1504                                               GST_BUFFER_SIZE(h264_prv->sps_data));
1505   h264_bitstream_write_uint(&bitstream, 0x000001, 24);
1506   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
1507                                               GST_BUFFER_SIZE(h264_prv->pps_data));
1508
1509   nal_sps_pps = gst_buffer_new();
1510   GST_BUFFER_MALLOCDATA(nal_sps_pps) =
1511          GST_BUFFER_DATA(nal_sps_pps) =
1512          BIT_STREAM_BUFFER(&bitstream);
1513   GST_BUFFER_SIZE(nal_sps_pps) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1514   h264_bitstream_destroy(&bitstream, FALSE);
1515   *buffer = nal_sps_pps;
1516   return ENCODER_NO_ERROR;
1517 }
1518
1519 static void
1520 h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
1521 {
1522   bitstream->bit_size = 0;
1523   bitstream->buffer = NULL;
1524   bitstream->max_bit_capability = 0;
1525   if (bit_capability) {
1526     h264_bitstream_auto_grow(bitstream, bit_capability);
1527   }
1528 }
1529
1530 static gboolean
1531 h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size)
1532 {
1533   gboolean ret = TRUE;
1534   guint32 byte_pos, bit_offset;
1535   guint8  *cur_byte;
1536   guint32 fill_bits;
1537
1538   if(!bit_size) {
1539     return TRUE;
1540   }
1541
1542   VAAPI_UNUSED_ARG(ret);
1543   ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, bit_size),
1544                        FALSE,
1545                        "h264_bitstream_auto_grow failed.");
1546   byte_pos = (bitstream->bit_size>>3);
1547   bit_offset = (bitstream->bit_size&0x07);
1548   cur_byte = bitstream->buffer + byte_pos;
1549   ENCODER_ASSERT(bit_offset < 8 && bitstream->bit_size <= bitstream->max_bit_capability);
1550
1551   while (bit_size) {
1552     fill_bits = ((8-bit_offset) < bit_size ? (8-bit_offset) : bit_size);
1553     bit_size -= fill_bits;
1554     bitstream->bit_size += fill_bits;
1555
1556     *cur_byte |= ((value>>bit_size) & h264_bit_mask[fill_bits])<<(8-bit_offset-fill_bits);
1557     ++cur_byte;
1558     bit_offset = 0;
1559   }
1560   ENCODER_ASSERT(cur_byte <= bitstream->buffer + bitstream->max_bit_capability/8);
1561
1562   end:
1563   return ret;
1564 }
1565
1566 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value)
1567 {
1568   guint32 bit_offset, bit_left;
1569
1570   bit_offset = (bitstream->bit_size&0x07);
1571   if (!bit_offset) {
1572     return TRUE;
1573   }
1574   bit_left = 8 - bit_offset;
1575   if (value) value = h264_bit_mask[bit_left];
1576   return h264_bitstream_write_uint(bitstream, value, bit_left);
1577 }
1578
1579
1580 static gboolean
1581 h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size)
1582 {
1583   gboolean ret = TRUE;
1584   if (!byte_size) {
1585     return 0;
1586   }
1587
1588   VAAPI_UNUSED_ARG(ret);
1589   ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, byte_size<<3),
1590                        FALSE,
1591                        "h264_bitstream_auto_grow failed.");
1592   if (0 == (bitstream->bit_size&0x07)) {
1593     memcpy(&bitstream->buffer[bitstream->bit_size>>3], buf, byte_size);
1594     bitstream->bit_size += (byte_size<<3);
1595   } else {
1596     ENCODER_ASSERT(0);
1597     while(byte_size) {
1598       h264_bitstream_write_uint(bitstream, *buf, 8);
1599       --byte_size;
1600       ++buf;
1601     }
1602   }
1603
1604 end:
1605   return ret;
1606 }
1607
1608 static gboolean
1609 h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value)
1610 {
1611   gboolean ret = TRUE;
1612   guint32  size_in_bits = 0;
1613   guint32  tmp_value = ++value;
1614   while (tmp_value) {
1615     ++size_in_bits;
1616     tmp_value >>= 1;
1617   }
1618   ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1),
1619                        FALSE,
1620                        "h264_bitstream_write_ue failed.");
1621   ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits),
1622                        FALSE,
1623                        "h264_bitstream_write_ue failed.");
1624
1625 end:
1626   return ret;
1627 }
1628
1629 static gboolean
1630 h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value)
1631 {
1632   gboolean ret = TRUE;
1633   guint32 new_val;
1634
1635   if (value <= 0) {
1636     new_val = -(value<<1);
1637   } else {
1638     new_val = (value<<1) - 1;
1639   }
1640
1641   ENCODER_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val),
1642                        FALSE,
1643                        "h264_bitstream_write_se failed.");
1644
1645 end:
1646   return ret;
1647 }
1648
1649 static gboolean
1650 h264_bitstream_write_trailing_bits(H264Bitstream *bitstream)
1651 {
1652     h264_bitstream_write_uint(bitstream, 1, 1);
1653     h264_bitstream_align(bitstream, 0);
1654     return TRUE;
1655 }
1656
1657 static void
1658 h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag)
1659 {
1660   if (bitstream->buffer && free_flag) {
1661     free (bitstream->buffer);
1662   }
1663   bitstream->buffer = NULL;
1664   bitstream->bit_size = 0;
1665   bitstream->max_bit_capability = 0;
1666 }
1667
1668 static gboolean
1669 h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size)
1670 {
1671   guint32 new_bit_size = extra_bit_size + bitstream->bit_size;
1672   guint32 clear_pos;
1673
1674   ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
1675   if (new_bit_size <= bitstream->max_bit_capability) {
1676     return TRUE;
1677   }
1678
1679   new_bit_size = ((new_bit_size + H264_BITSTREAM_ALLOC_ALIGN_MASK)
1680                 &(~H264_BITSTREAM_ALLOC_ALIGN_MASK));
1681   ENCODER_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
1682   clear_pos = ((bitstream->bit_size+7)>>3);
1683   bitstream->buffer = realloc(bitstream->buffer, new_bit_size>>3);
1684   memset(bitstream->buffer+clear_pos, 0, (new_bit_size>>3)-clear_pos);
1685   bitstream->max_bit_capability = new_bit_size;
1686   return TRUE;
1687 }
1688
1689 static gboolean
1690 h264_bitstream_write_nal_header(H264Bitstream *bitstream,
1691                                  guint nal_ref_idc, guint nal_unit_type)
1692 {
1693   h264_bitstream_write_uint(bitstream, 0, 1);
1694   h264_bitstream_write_uint(bitstream, nal_ref_idc, 2);
1695   h264_bitstream_write_uint(bitstream, nal_unit_type, 5);
1696   return TRUE;
1697 }
1698
1699 static gboolean
1700 h264_bitstream_write_sps(H264Bitstream *bitstream,
1701                      VAEncSequenceParameterBufferH264 *seq)
1702 {
1703   guint32 constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag;
1704   guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
1705
1706   guint32 b_qpprime_y_zero_transform_bypass = (seq->rate_control_method == BR_CQP);
1707   guint32 residual_color_transform_flag = 0;
1708   guint32 pic_height_in_map_units = (seq->frame_mbs_only_flag ?
1709                                     seq->picture_height_in_mbs :
1710                                     seq->picture_height_in_mbs/2);
1711   guint32 mb_adaptive_frame_field = !seq->frame_mbs_only_flag;
1712   guint32 i = 0;
1713
1714   constraint_set0_flag = seq->profile_idc == H264_PROFILE_BASELINE;
1715   constraint_set1_flag = seq->profile_idc <= H264_PROFILE_MAIN;
1716   constraint_set2_flag = 0;
1717   constraint_set3_flag = 0;
1718
1719   h264_bitstream_write_uint(bitstream, seq->profile_idc, 8);         /* profile_idc */
1720   h264_bitstream_write_uint(bitstream, constraint_set0_flag, 1);     /* constraint_set0_flag */
1721   h264_bitstream_write_uint(bitstream, constraint_set1_flag, 1);     /* constraint_set1_flag */
1722   h264_bitstream_write_uint(bitstream, constraint_set2_flag, 1);     /* constraint_set2_flag */
1723   h264_bitstream_write_uint(bitstream, constraint_set3_flag, 1);     /* constraint_set3_flag */
1724   h264_bitstream_write_uint(bitstream, 0, 4);                        /* reserved_zero_4bits */
1725   h264_bitstream_write_uint(bitstream, seq->level_idc, 8);   /* level_idc */
1726   h264_bitstream_write_ue(bitstream, seq->seq_parameter_set_id);     /* seq_parameter_set_id */
1727
1728   if (seq->profile_idc >= H264_PROFILE_HIGH) {
1729     /* for high profile */
1730     ENCODER_ASSERT(0);
1731     h264_bitstream_write_ue(bitstream, seq->seq_fields.bits.chroma_format_idc); /* chroma_format_idc  = 1, 4:2:0*/
1732     if (3 == seq->seq_fields.bits.chroma_format_idc) {
1733       h264_bitstream_write_uint(bitstream, residual_color_transform_flag, 1);
1734     }
1735     h264_bitstream_write_ue(bitstream, seq->bit_depth_luma_minus8); /* bit_depth_luma_minus8 */
1736     h264_bitstream_write_ue(bitstream, seq->bit_depth_chroma_minus8); /* bit_depth_chroma_minus8 */
1737     h264_bitstream_write_uint(bitstream, b_qpprime_y_zero_transform_bypass, 1); /* b_qpprime_y_zero_transform_bypass */
1738     ENCODER_ASSERT(seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
1739     h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1); /*seq_scaling_matrix_present_flag  */
1740
1741     if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) {
1742       for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); i++) {
1743         h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_list_present_flag, 1);
1744         if (seq->seq_fields.bits.seq_scaling_list_present_flag) {
1745           ENCODER_ASSERT(0);
1746           /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1*/
1747         }
1748       }
1749     }
1750   }
1751
1752   h264_bitstream_write_ue(bitstream, seq->log2_max_frame_num_minus4);    /* log2_max_frame_num_minus4 */
1753   h264_bitstream_write_ue(bitstream, seq->pic_order_cnt_type);           /* pic_order_cnt_type */
1754
1755   if (seq->pic_order_cnt_type == 0)
1756     h264_bitstream_write_ue(bitstream, seq->log2_max_pic_order_cnt_lsb_minus4);/* log2_max_pic_order_cnt_lsb_minus4 */
1757   else if (seq->pic_order_cnt_type == 1) {
1758     ENCODER_ASSERT(0);
1759     h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
1760     h264_bitstream_write_se(bitstream, seq->offset_for_non_ref_pic);
1761     h264_bitstream_write_se(bitstream, seq->offset_for_top_to_bottom_field);
1762     h264_bitstream_write_ue(bitstream, seq->num_ref_frames_in_pic_order_cnt_cycle);
1763     for ( i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) {
1764       h264_bitstream_write_se(bitstream, seq->offset_for_ref_frame[i]);
1765     }
1766   }
1767
1768   h264_bitstream_write_ue(bitstream, seq->max_num_ref_frames);                   /* num_ref_frames */
1769   h264_bitstream_write_uint(bitstream, gaps_in_frame_num_value_allowed_flag, 1); /* gaps_in_frame_num_value_allowed_flag */
1770
1771   h264_bitstream_write_ue(bitstream, seq->picture_width_in_mbs - 1);  /* pic_width_in_mbs_minus1 */
1772   h264_bitstream_write_ue(bitstream, pic_height_in_map_units - 1);    /* pic_height_in_map_units_minus1 */
1773   h264_bitstream_write_uint(bitstream, seq->frame_mbs_only_flag, 1);  /* frame_mbs_only_flag */
1774
1775   if (!seq->frame_mbs_only_flag) { //ONLY mbs
1776       ENCODER_ASSERT(0);
1777       h264_bitstream_write_uint(bitstream, mb_adaptive_frame_field, 1);
1778   }
1779
1780   h264_bitstream_write_uint(bitstream, 0, 1);                           /* direct_8x8_inference_flag */
1781   h264_bitstream_write_uint(bitstream, seq->frame_cropping_flag, 1);    /* frame_cropping_flag */
1782
1783   if (seq->frame_cropping_flag) {
1784       h264_bitstream_write_ue(bitstream, seq->frame_crop_left_offset);  /* frame_crop_left_offset */
1785       h264_bitstream_write_ue(bitstream, seq->frame_crop_right_offset); /* frame_crop_right_offset */
1786       h264_bitstream_write_ue(bitstream, seq->frame_crop_top_offset);   /* frame_crop_top_offset */
1787       h264_bitstream_write_ue(bitstream, seq->frame_crop_bottom_offset); /* frame_crop_bottom_offset */
1788   }
1789   ENCODER_ASSERT(seq->vui_flag == 0);
1790   h264_bitstream_write_uint(bitstream, seq->vui_flag, 1);               /* vui_parameters_present_flag */
1791   if (seq->vui_flag) {
1792     /*FIXME, to write vui parameters*/
1793   }
1794   h264_bitstream_write_trailing_bits(bitstream);                        /* rbsp_trailing_bits */
1795   return TRUE;
1796 }
1797
1798
1799 static gboolean
1800 h264_bitstream_write_pps(H264Bitstream *bitstream,
1801                         VAEncPictureParameterBufferH264 *pic)
1802 {
1803   guint32 num_slice_groups_minus1 = 0;
1804   guint32 pic_init_qs_minus26 = 0;
1805   guint32 redundant_pic_cnt_present_flag = 0;
1806
1807   h264_bitstream_write_ue(bitstream, pic->pic_parameter_set_id); /* pic_parameter_set_id */
1808   h264_bitstream_write_ue(bitstream, pic->seq_parameter_set_id); /* seq_parameter_set_id */
1809   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.entropy_coding_mode_flag, 1); /* entropy_coding_mode_flag */
1810   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_order_present_flag, 1); /* pic_order_present_flag */
1811   h264_bitstream_write_ue(bitstream, num_slice_groups_minus1); /*slice_groups-1*/
1812
1813   if (num_slice_groups_minus1 > 0) {
1814     /*FIXME*/
1815     ENCODER_ASSERT(0);
1816   }
1817   h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l0_active_minus1);
1818   h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l1_active_minus1);
1819   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.weighted_pred_flag, 1);
1820   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.weighted_bipred_idc, 2);
1821   h264_bitstream_write_se(bitstream, pic->pic_init_qp-26);  /* pic_init_qp_minus26 */
1822   h264_bitstream_write_se(bitstream, pic_init_qs_minus26);  /* pic_init_qs_minus26 */
1823   h264_bitstream_write_se(bitstream, pic->chroma_qp_index_offset); /*chroma_qp_index_offset*/
1824
1825   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.deblocking_filter_control_present_flag, 1);
1826   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.constrained_intra_pred_flag, 1);
1827   h264_bitstream_write_uint(bitstream, redundant_pic_cnt_present_flag, 1);
1828
1829   /*more_rbsp_data*/
1830   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.transform_8x8_mode_flag, 1);
1831   h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
1832   if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) {
1833     ENCODER_ASSERT(0);
1834     /* FIXME */
1835     /*
1836     for (i = 0; i <
1837       (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag));
1838       i++) {
1839       h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_list_present_flag, 1);
1840     }
1841     */
1842   }
1843
1844   h264_bitstream_write_se(bitstream, pic->second_chroma_qp_index_offset);
1845   h264_bitstream_write_trailing_bits(bitstream);
1846   return TRUE;
1847 }
1848
1849
1850 static const guint8 *
1851 h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
1852 {
1853     const guint8 *cur = buffer;
1854     const guint8 *end = buffer + len;
1855     const guint8 *nal_start = NULL;
1856     guint32 flag = 0xFFFFFFFF;
1857     guint32 nal_start_len = 0;
1858
1859     ENCODER_ASSERT(len >= 0 && buffer && nal_size);
1860     if (len < 3) {
1861         *nal_size = len;
1862         nal_start = (len ? buffer : NULL);
1863         return nal_start;
1864     }
1865
1866     /*locate head postion*/
1867     if (!buffer[0] && !buffer[1]) {
1868         if (buffer[2] == 1) { // 0x000001
1869             nal_start_len = 3;
1870         } else if (!buffer[2] && len >=4 && buffer[3] == 1) { //0x00000001
1871             nal_start_len = 4;
1872         }
1873     }
1874     nal_start = buffer + nal_start_len;
1875     cur = nal_start;
1876
1877     /*find next nal start position*/
1878     while (cur < end) {
1879         flag = ((flag<<8) | ((*cur++)&0xFF));
1880         if (flag == 0x00000001) {
1881             *nal_size = cur - 4 - nal_start;
1882             break;
1883         } else if ((flag&0x00FFFFFF) == 0x00000001) {
1884             *nal_size = cur - 3 - nal_start;
1885             break;
1886         }
1887     }
1888     if (cur >= end) {
1889       *nal_size = end - nal_start;
1890       if (nal_start >= end) {
1891         nal_start = NULL;
1892       }
1893     }
1894     return nal_start;
1895 }
1896
1897 static int draw_picture(int width, int height,
1898                          unsigned char *Y_start,
1899                          unsigned char *U_start,
1900                          unsigned char *V_start,
1901                          int UV_interleave, int box_width, int row_shift)
1902 {
1903     int row;
1904     int field = 0;
1905     int Y_pitch = width;
1906     int U_pitch = width/2;
1907     int V_pitch = width/2;
1908
1909     /* copy Y plane */
1910     for (row=0;row<height;row++) {
1911         unsigned char *Y_row = Y_start + row * Y_pitch;
1912         int jj, xpos, ypos;
1913
1914         ypos = (row / box_width) & 0x1;
1915
1916         /* fill garbage data into the other field */
1917         if (((field == 1) && (row &1))
1918             || ((field == 2) && ((row &1)==0))) {
1919             memset(Y_row, 0xff, width);
1920             continue;
1921         }
1922
1923         for (jj=0; jj<width; jj++) {
1924             xpos = ((row_shift + jj) / box_width) & 0x1;
1925
1926             if ((xpos == 0) && (ypos == 0))
1927                 Y_row[jj] = 0xeb;
1928             if ((xpos == 1) && (ypos == 1))
1929                 Y_row[jj] = 0xeb;
1930
1931             if ((xpos == 1) && (ypos == 0))
1932                 Y_row[jj] = 0x10;
1933             if ((xpos == 0) && (ypos == 1))
1934                 Y_row[jj] = 0x10;
1935         }
1936     }
1937
1938     /* copy UV data */
1939     for( row =0; row < height/2; row++) {
1940         unsigned short value = 0x80;
1941
1942         /* fill garbage data into the other field */
1943         if (((field == 1) && (row &1))
1944             || ((field == 2) && ((row &1)==0))) {
1945             value = 0xff;
1946         }
1947
1948         if (UV_interleave) {
1949             unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch);
1950
1951             memset(UV_row, value, width);
1952         } else {
1953             unsigned char *U_row = U_start + row * U_pitch;
1954             unsigned char *V_row = V_start + row * V_pitch;
1955
1956             memset (U_row,value,width/2);
1957             memset (V_row,value,width/2);
1958         }
1959     }
1960     return 0;
1961 }
1962
1963
1964