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