add h264encoder
[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 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
22 #define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
23
24 #define SHARE_CODED_BUF         0
25
26 #define DEFAULT_SURFACE_NUMBER  3
27 #define DEFAULT_CODEDBUF_NUM    5
28 #define DEFAULT_SID_INPUT       0 // suface_ids[0]
29
30 #define REF_RECON_SURFACE_NUM   2
31
32 typedef enum {
33   NAL_UNKNOWN     = 0,
34   NAL_NON_IDR     = 1,
35   NAL_IDR         = 5,    /* ref_idc != 0 */
36   NAL_SEI         = 6,    /* ref_idc == 0 */
37   NAL_SPS         = 7,
38   NAL_PPS         = 8,
39   NAL_AUD         = 9,
40   NAL_FILLER      = 12,
41 }H264_NAL_TYPE;
42
43 struct _GstH264EncodeBuffer {
44   GstBuffer           buffer;
45   VABufferID         *coded_id;
46   GstH264EncoderPrivate *encoder;
47 };
48
49 struct _GstH264EncoderPrivate {
50   GstH264Encoder   *public;
51   guint32           format;   /*NV12, I420,*/
52   gboolean          es_flag;  /*elementary flag*/
53
54   /* private data*/
55   GQueue           *video_buffer_caches; /*not used for baseline*/
56
57   GstVaapiSurface  *ref_surface;  /* reference buffer*/
58   GstVaapiSurface  *recon_surface; /* reconstruct buffer*/
59
60   VABufferID        seq_parameter;
61   VABufferID        pic_parameter;
62   VABufferID        slice_parameter;
63   VAEncSliceParameterBuffer *slice_param_buffers;
64   guint32           default_slice_height;
65   guint32           slice_mod_mb_num;
66
67   GstBuffer        *sps_data;
68   GstBuffer        *pps_data;
69
70 };
71
72 G_DEFINE_TYPE(GstH264Encoder, gst_h264_encoder, GST_TYPE_VAAPI_BASE_ENCODER);
73
74
75 // 4096-1
76 #define H264_BITSTREAM_ALLOC_ALIGN_MASK 0x0FFF
77
78 #define BIT_STREAM_BUFFER(stream)    ((stream)->buffer)
79 #define BIT_STREAM_BIT_SIZE(stream)  ((stream)->bit_size)
80
81 struct _H264Bitstream {
82   guint8   *buffer;
83   guint32   bit_size;
84   guint32   max_bit_capability;
85 };
86
87 typedef struct _H264Bitstream H264Bitstream;
88
89 static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
90
91 static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
92                                     GstVaapiContext *context, GList **coded_pics);
93
94 /*other functions*/
95 static EncoderStatus gst_h264_encoder_get_avcC_codec_data(
96                                     GstVaapiEncoder* encoder, GstBuffer **buffer);
97 static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
98
99 static gboolean      gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
100 static void          gst_h264_encoder_finalize(GObject *object);
101 static void          gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
102
103 static gboolean      gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder,
104                                     GstVaapiDisplay *display, GstVaapiContext *context);
105 static gboolean      gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder,
106                                     GstVaapiDisplay *display, GstVaapiContext *context);
107
108 static EncoderStatus gst_h264_prepare_encoding(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
109                                     GstVaapiContext *context, GstVaapiSurface *surface,
110                                     guint frame_index, VABufferID coded_buf, gboolean *is_key);
111 static void          gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
112 //static EncoderStatus h264_encoder_read_sps_pps(
113 //                                    GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size);
114 static GstBuffer    *gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
115                                     guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
116
117 /* h264 bitstream functions */
118 static void     h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
119 static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
120 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value);
121 static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value);
122 static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, guint32 value);
123 static gboolean h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
124
125 static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size);
126 static void     h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
127 static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size);
128 static gboolean h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv);
129 static gboolean h264_bitstream_write_pps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv);
130 static const guint8 *h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size);
131 static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
132                                 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
133
134 static void
135 gst_h264_encoder_class_init(GstH264EncoderClass *klass)
136 {
137   GObjectClass * const object_class = G_OBJECT_CLASS(klass);
138   GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
139   GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
140
141   g_type_class_add_private(klass, sizeof(GstH264EncoderPrivate));
142
143   GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
144       "gst_va_h264_encoder element");
145
146   object_class->finalize = gst_h264_encoder_finalize;
147
148   base_class->validate_attributes = gst_h264_validate_parameters;
149   base_class->pre_alloc_resource  = gst_h264_encoder_alloc_slices;
150   base_class->release_resource    = gst_h264_encoder_release_resource;
151   base_class->prepare_frame = gst_h264_prepare_encoding;
152   base_class->notify_frame = gst_h264_notify_frame;
153   base_class->copy_coded_frame = gst_h264_encoder_copy_coded_buffer;
154
155   encoder_class->flush = gst_h264_encoder_flush;
156
157   encoder_class->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
158   /* encoder_class->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
159
160   /*
161   object_class->set_property = gst_h264_encoder_set_property;
162   object_class->get_property = gst_h264_encoder_get_property;
163   */
164 }
165
166
167 static void
168 gst_h264_encode_buffer_class_init (gpointer g_class, gpointer class_data)
169 {
170   GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class);
171
172   h264_encode_buffer_parent_class = g_type_class_peek_parent(g_class);
173   ENCODER_ASSERT(h264_encode_buffer_parent_class);
174
175   mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
176       gst_h264_encode_buffer_finalize;
177 }
178
179
180 static GType
181 gst_h264_encode_buffer_get_type (void)
182 {
183   static GType s_h264_encode_buffer_type = 0;
184   if (G_UNLIKELY (s_h264_encode_buffer_type == 0)) {
185     static const GTypeInfo s_h264_encode_buffer_info = {
186       sizeof(GstBufferClass),
187       NULL,
188       NULL,
189       gst_h264_encode_buffer_class_init,
190       NULL,
191       NULL,
192       sizeof(GstH264EncodeBuffer),
193       0,
194       NULL,
195       NULL
196     };
197     s_h264_encode_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
198         "GstH264EncodeBuffer", &s_h264_encode_buffer_info, 0);
199   }
200   return s_h264_encode_buffer_type;
201 }
202
203 static void
204 gst_h264_encode_buffer_finalize (GstH264EncodeBuffer *h264_buffer)
205 {
206   GstH264EncoderPrivate *h264_prv = NULL;
207   VABufferID* coded_id = NULL;
208   GstVaapiDisplay *display = NULL;
209
210   gboolean is_locked = FALSE;
211
212   h264_prv = h264_buffer->encoder;
213   coded_id = h264_buffer->coded_id;
214   display = ENCODER_DISPLAY(h264_prv->public);
215
216   ENCODER_ASSERT(display);
217   VADisplay va_dpy = gst_vaapi_display_get_display(display);
218
219   ENCODER_ASSERT(h264_prv);
220   ENCODER_ASSERT(coded_id && VA_INVALID_ID!= *coded_id);
221
222   /*if (--(*h264_buffer->ref_coded_id) == 0) */
223   {
224     /*g_free(h264_buffer->ref_coded_id);*/
225     ENCODER_ACQUIRE_DISPLAY_LOCK(display);
226     vaUnmapBuffer(va_dpy, *coded_id);
227     ENCODER_RELEASE_DISPLAY_LOCK(display);
228     push_available_coded_buffer(h264_prv, coded_id);
229   }
230
231   if (GST_MINI_OBJECT_CLASS(h264_encode_buffer_parent_class)->finalize) {
232     GST_MINI_OBJECT_CLASS(h264_encode_buffer_parent_class)->finalize(GST_MINI_OBJECT(h264_buffer));
233   }
234 }
235
236 static GstH264EncodeBuffer *
237 gst_h264_encode_buffer_new(GstH264EncoderPrivate *h264_prv,
238                            VABufferID *coded_id)
239 {
240   GstH264EncodeBuffer *buf = (GstH264EncodeBuffer*)gst_mini_object_new(GST_TYPE_H264_ENCODE_BUFFER);
241   buf->coded_id = coded_id;
242   buf->encoder = h264_prv;
243   return buf;
244 }
245
246
247 static GstVaapiSurface *
248 h264_get_video_surface(GstH264EncoderPrivate *h264_prv, GstVaapiVideoBuffer *video_buffer)
249 {
250   //ref_surface
251   GstVaapiSurface *ret = gst_vaapi_video_buffer_get_surface(video_buffer);
252
253   ENCODER_CHECK_STATUS(ret, NULL, "video buffer doesn't have a surface");
254 #if 0
255   g_queue_push_tail(h264_prv->video_buffer_caches,video_buffer);
256   gst_buffer_ref(GST_BUFFER(video_buffer));
257 #endif
258   return ret;
259
260   end:
261   return NULL;
262 }
263
264 static void
265 h264_release_video_surface(GstH264EncoderPrivate *h264_prv, VASurfaceID surface)
266 {
267 #if 0
268   ENCODER_ASSERT(h264_prv->video_buffer_caches);
269   g_queue_find_custom(h264_prv->video_buffer_caches,xx, compare_func);
270   for (h264_prv->video_buffer_caches) {
271   }
272 #endif
273 }
274
275 static VAProfile
276 h264_get_va_profile(guint32 profile)
277 {
278   switch (profile) {
279     case H264_PROFILE_BASELINE:
280       return VAProfileH264Baseline;
281
282     case H264_PROFILE_MAIN:
283       return VAProfileH264Main;
284
285     case H264_PROFILE_HIGH:
286       return VAProfileH264High;
287
288     default:
289       break;
290   }
291   return (-1);
292 }
293
294 GstH264Encoder *
295 gst_h264_encoder_new(void)
296 {
297   return GST_H264_ENCODER(g_object_new(GST_TYPE_H264_ENCODER, NULL));
298 }
299
300
301 static void
302 gst_h264_encoder_init(GstH264Encoder *encoder)
303 {
304   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
305   GstVaapiEncoderPrivate *encoder_prv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
306   ENCODER_ASSERT(h264_prv);
307   h264_prv->public = encoder;
308
309   /* init public attributes */
310   gst_h264_encoder_init_public_values(encoder);
311   gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
312
313   /* init private values*/
314   h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
315   h264_prv->es_flag = TRUE;
316
317   h264_prv->ref_surface = NULL;
318   h264_prv->recon_surface = NULL;
319
320   h264_prv->seq_parameter = VA_INVALID_ID;
321   h264_prv->pic_parameter = VA_INVALID_ID;
322   h264_prv->slice_parameter = VA_INVALID_ID;
323   h264_prv->slice_param_buffers = NULL;
324   h264_prv->default_slice_height = 0;
325   h264_prv->slice_mod_mb_num = 0;
326
327   h264_prv->sps_data = NULL;
328   h264_prv->pps_data = NULL;
329 }
330
331 static void
332 gst_h264_encoder_finalize(GObject *object)
333 {
334   /*free private buffers*/
335   GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
336   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(object);
337
338   if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
339     gst_vaapi_encoder_uninitialize(encoder);
340   }
341
342   if (h264_prv->sps_data) {
343     gst_buffer_unref(h264_prv->sps_data);
344     h264_prv->sps_data = NULL;
345   }
346   if (h264_prv->pps_data) {
347     gst_buffer_unref(h264_prv->pps_data);
348     h264_prv->pps_data = NULL;
349   }
350   if (h264_prv->slice_param_buffers) {
351     g_free(h264_prv->slice_param_buffers);
352     h264_prv->slice_param_buffers = NULL;
353   }
354
355   G_OBJECT_CLASS(gst_h264_encoder_parent_class)->finalize(object);
356 }
357
358
359 static void
360 gst_h264_encoder_init_public_values(GstH264Encoder* encoder)
361 {
362   encoder->profile = 0;
363   encoder->level = 0;
364   encoder->bitrate = 0;
365   encoder->intra_period = 0;
366   encoder->init_qp = -1;
367   encoder->min_qp = -1;
368   encoder->slice_num = 0;
369 }
370
371 void
372 gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es)
373 {
374   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
375   h264_prv->es_flag = es;
376 }
377
378
379 gboolean
380 gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
381 {
382   GstH264Encoder *encoder = GST_H264_ENCODER(base_encoder);
383   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
384   if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
385     return FALSE;
386   }
387   if (!encoder->profile) {
388     encoder->profile = H264_DEFAULT_PROFILE;
389   }
390   gst_vaapi_base_encoder_set_va_profile(base_encoder, h264_get_va_profile(encoder->profile));
391   if (!encoder->level) {
392     encoder->level = H264_DEFAULT_LEVEL;
393   }
394   if (!encoder->intra_period) {
395     encoder->intra_period = H264_DEFAULT_INTRA_PERIOD;
396   }
397   if (-1 == encoder->init_qp) {
398     encoder->init_qp = H264_DEFAULT_INIT_QP;
399   }
400   if (-1 == encoder->min_qp) {
401     encoder->min_qp = H264_DEFAULT_MIN_QP;
402   }
403
404   if (encoder->min_qp > encoder->init_qp) {
405     encoder->min_qp = encoder->init_qp;
406   }
407
408   /* default compress ratio 1: (4*8*1.5) */
409   if (!encoder->bitrate) {
410     encoder->bitrate = ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
411   }
412
413   if (!encoder->slice_num) {
414     encoder->slice_num = H264_DEFAULT_SLICE_NUM;
415   }
416
417   /* need  calculate slice-num and each slice-height
418         suppose:  ((encoder->height+15)/16) = 13, slice_num = 8
419         then: slice_1_height = 2
420                  slice_2_height = 2
421                  slice_3_height = 2
422                  slice_4_height = 2
423                  slice_5_height = 2
424                  slice_6_height = 1
425                  slice_7_height = 1
426                  slice_8_height = 1
427    */
428   h264_prv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
429   if (0 == h264_prv->default_slice_height) { /* special value */
430     h264_prv->default_slice_height = 1;
431     h264_prv->slice_mod_mb_num = 0;
432     encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
433   } else {
434     h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
435   }
436   return TRUE;
437 }
438
439
440 static gboolean
441 h264_encoder_release_parameters(GstH264Encoder *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
442 {
443   VAStatus va_status = VA_STATUS_SUCCESS;
444   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
445   guint32 i;
446
447   gboolean is_locked = FALSE;
448
449   ENCODER_ASSERT(display);
450   ENCODER_ASSERT(context);
451   VADisplay va_dpy = gst_vaapi_display_get_display(display);
452
453   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
454   if (VA_INVALID_ID != h264_prv->seq_parameter) {
455     va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
456     h264_prv->seq_parameter = VA_INVALID_ID;
457   }
458   if (VA_INVALID_ID != h264_prv->pic_parameter) {
459     va_status = vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
460     h264_prv->pic_parameter = VA_INVALID_ID;
461   }
462   if (VA_INVALID_ID != h264_prv->slice_parameter) {
463     va_status = vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
464     h264_prv->slice_parameter = VA_INVALID_ID;
465   }
466
467   ENCODER_RELEASE_DISPLAY_LOCK(display);
468
469   if (h264_prv->slice_param_buffers) {
470     g_free(h264_prv->slice_param_buffers);
471     h264_prv->slice_param_buffers = NULL;
472   }
473
474   return TRUE;
475 }
476
477
478 static gboolean
479 gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
480 {
481   GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
482   gboolean ret = TRUE;
483   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
484
485   /* release buffers first */
486   h264_encoder_release_parameters(h264_encoder, display, context);
487
488   /*remove ref_surface*/
489   if (h264_prv->ref_surface) {
490     if (context) {
491       gst_vaapi_context_put_surface(context, h264_prv->ref_surface);
492     } else {
493       g_object_unref(h264_prv->ref_surface);
494     }
495     h264_prv->ref_surface = NULL;
496   }
497
498   /*remove recon_surface*/
499   if (h264_prv->recon_surface) {
500     if (context) {
501       gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
502     } else {
503       g_object_unref(h264_prv->recon_surface);
504     }
505     h264_prv->recon_surface = NULL;
506   }
507
508   if (h264_prv->sps_data) {
509     gst_buffer_unref(h264_prv->sps_data);
510     h264_prv->sps_data = NULL;
511   }
512   if (h264_prv->pps_data) {
513     gst_buffer_unref(h264_prv->pps_data);
514     h264_prv->pps_data = NULL;
515   }
516   return ret;
517 }
518
519 static gboolean
520 gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display, GstVaapiContext *context)
521 {
522   gboolean ret = TRUE;
523   VAStatus va_status = VA_STATUS_SUCCESS;
524   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
525   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
526
527   h264_prv->slice_param_buffers = (VAEncSliceParameterBuffer*)g_malloc0_n(h264_encoder->slice_num,
528                                                      sizeof(h264_prv->slice_param_buffers[0]));
529   return ret;
530 }
531
532
533
534 static EncoderStatus
535 gst_h264_prepare_encoding(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
536                              GstVaapiContext *context, GstVaapiSurface *surface,
537                              guint frame_index, VABufferID coded_buf, gboolean *is_key)
538 {
539   EncoderStatus ret = ENCODER_NO_ERROR;
540   VAStatus va_status = VA_STATUS_SUCCESS;
541   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
542   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
543 #ifdef _MRST_
544   VAEncPictureParameterBufferH264 pic_h264;
545 #else
546   VAEncPictureParameterBufferH264Baseline pic_h264;
547 #endif
548   VAEncSliceParameterBuffer *slice_h264 = NULL;
549
550   gboolean is_locked = FALSE;
551
552   ENCODER_ASSERT(display && context);
553   VADisplay va_dpy = gst_vaapi_display_get_display(display);
554   VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
555
556   *is_key = ((frame_index % h264_encoder->intra_period) == 0);
557
558   /* lock display */
559   ENCODER_ACQUIRE_DISPLAY_LOCK(display);
560   /*handle first surface_index*/
561   /*only need first frame*/
562   if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
563   #ifdef _MRST_
564     VAEncSequenceParameterBufferH264 seq_h264 = {0};
565   #else
566     VAEncSequenceParameterBufferH264Baseline seq_h264 = {0};
567   #endif
568
569     seq_h264.level_idc = h264_encoder->level; /* 3.0 */
570     seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
571     seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
572     seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
573
574     seq_h264.bits_per_second = h264_encoder->bitrate;
575     seq_h264.frame_rate = ENCODER_FPS(h264_encoder);
576     seq_h264.initial_qp = h264_encoder->init_qp; /*qp_value; 15, 24, 26?*/
577     seq_h264.min_qp = h264_encoder->min_qp;     /*1, 6, 10*/
578     seq_h264.basic_unit_size = 0;
579     seq_h264.intra_period = h264_encoder->intra_period;
580     seq_h264.intra_idr_period = h264_encoder->intra_period;
581
582     va_status = vaCreateBuffer(va_dpy, context_id,
583                                VAEncSequenceParameterBufferType,
584                                sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
585     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.\n");
586     va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
587     ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.\n");
588   }
589
590   /* set pic_parameters*/
591   if (!h264_prv->ref_surface) {
592     h264_prv->ref_surface = gst_vaapi_context_get_surface(context);
593     ENCODER_CHECK_STATUS(h264_prv->ref_surface, ENCODER_SURFACE_ERR, "reference surface, h264_pop_free_surface failed.\n");
594   }
595   if (!h264_prv->recon_surface) {
596     h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
597     ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR, "reconstructed surface, h264_pop_free_surface failed.\n");
598   }
599
600   pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface);
601   pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
602   pic_h264.coded_buf = coded_buf;
603   pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
604   pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
605   pic_h264.last_picture = 0; // last pic or not
606
607   if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
608     vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
609     h264_prv->pic_parameter = VA_INVALID_ID;
610   }
611   va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
612                                sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
613
614   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "creating pic-param buffer failed.\n");
615
616   va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
617   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.\n");
618
619   /* set slice parameters, support multiple slices */
620   int i = 0;
621   guint32 last_row_num = 0;
622   guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
623
624   memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
625   for (i = 0; i < h264_encoder->slice_num; ++i) {
626     slice_h264 = &h264_prv->slice_param_buffers[i];
627     slice_h264->start_row_number = last_row_num;               /* unit MB*/
628     slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
629     if (slice_mod_num) {
630       ++slice_h264->slice_height;
631       --slice_mod_num;
632     }
633     last_row_num += slice_h264->slice_height;
634     slice_h264->slice_flags.bits.is_intra = *is_key;
635     slice_h264->slice_flags.bits.disable_deblocking_filter_idc = 0;
636
637   }
638   ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
639
640   if (VA_INVALID_ID != h264_prv->slice_parameter) {
641     vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
642     h264_prv->slice_parameter = VA_INVALID_ID;
643   }
644   va_status = vaCreateBuffer(va_dpy,
645                              context_id,
646                              VAEncSliceParameterBufferType,
647                              sizeof(h264_prv->slice_param_buffers[0]),
648                              h264_encoder->slice_num,
649                              h264_prv->slice_param_buffers,
650                              &h264_prv->slice_parameter);
651   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.\n");
652
653   va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
654   ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.\n");
655
656   /*after finished, set ref_surface_index, recon_surface_index */
657   GstVaapiSurface *swap = h264_prv->ref_surface;
658   h264_prv->ref_surface = h264_prv->recon_surface;
659   h264_prv->recon_surface = swap;
660
661   end:
662   ENCODER_RELEASE_DISPLAY_LOCK(display);
663   return ret;
664 }
665
666
667 static GstBuffer *
668 gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
669                                         guint8 *frame,
670                                         guint32 frame_size,
671                                         VABufferID *coded_buf)
672 {
673   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
674   GstBuffer *ret_buffer;
675   guint32   nal_size;
676   const guint8   *nal_start;
677   guint8  *frame_end;
678
679   ret_buffer = gst_buffer_new();
680   ENCODER_ASSERT(ret_buffer);
681   H264Bitstream bitstream;
682   h264_bitstream_init(&bitstream, (frame_size+32)*8);
683   h264_bitstream_align(&bitstream, 0);
684   ENCODER_ASSERT(bitstream.bit_size == 0);
685
686   if (!h264_prv->es_flag) { /*nal format*/
687     h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
688     ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
689   } else { /* elementary format */
690     frame_end = frame + frame_size;
691     nal_start = frame;
692     nal_size = 0;
693     while((nal_start = h264_next_nal(nal_start, frame_end-nal_start, &nal_size)) != NULL) {
694       ENCODER_ASSERT(nal_size);
695       if (!nal_size) {
696         nal_start += nal_size;
697         continue;
698       }
699       h264_bitstream_write_uint(&bitstream, nal_size, 32);
700       h264_bitstream_write_byte_array(&bitstream, nal_start, nal_size);
701       nal_start += nal_size;
702     }
703   }
704   h264_bitstream_align(&bitstream, 0);
705
706   GST_BUFFER_MALLOCDATA(ret_buffer) =
707         GST_BUFFER_DATA(ret_buffer) = BIT_STREAM_BUFFER(&bitstream);
708   GST_BUFFER_SIZE(ret_buffer) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
709   h264_bitstream_destroy(&bitstream, FALSE);
710
711   return ret_buffer;
712 }
713
714 static EncoderStatus
715 h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size)
716 {
717   const guint8 *end = buf + size;
718   const guint8 *nal_start = buf;
719   guint32 nal_size = 0;
720   guint8 nal_type;
721   GstBuffer *sps = NULL, *pps = NULL;
722
723   while((!sps || !pps) && (nal_start = h264_next_nal(nal_start, end-nal_start, &nal_size)) != NULL) {
724     if (!nal_size) {
725       nal_start += nal_size;
726       continue;
727     }
728
729     nal_type = (*nal_start)&0x1F;
730     switch (nal_type) {
731       case NAL_SPS: {
732         sps = gst_buffer_new_and_alloc(nal_size);
733         memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
734         gst_buffer_replace(&h264_prv->sps_data, sps);
735         gst_buffer_unref(sps); /*don't set to NULL*/
736         break;
737       }
738
739       case NAL_PPS: {
740         pps = gst_buffer_new_and_alloc(nal_size);
741         memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
742         gst_buffer_replace(&h264_prv->pps_data, pps);
743         gst_buffer_unref(pps);
744         break;
745       }
746
747       default:
748         break;
749     }
750     nal_start += nal_size;
751
752   }
753   if (!sps || !pps) {
754     return ENCODER_DATA_NOT_READY;
755   }
756   return ENCODER_NO_ERROR;
757 }
758
759 static void
760 gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
761 {
762   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
763   if (!h264_prv->sps_data || !h264_prv->pps_data) {
764     h264_encoder_read_sps_pps(h264_prv, buf, size);
765   }
766   if (h264_prv->sps_data && h264_prv->pps_data) {
767     gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
768   }
769 }
770
771
772 static gboolean
773 h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
774                                 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc)
775 {
776   ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
777   ENCODER_ASSERT(sps_size >= 4);
778   if (sps_size < 4) {
779     return FALSE;
780   }
781   /*skip sps_data[0], nal_type*/
782   *profile_idc = sps_data[1];
783   *profile_comp = sps_data[2];
784   *level_idc = sps_data[3];
785   return TRUE;
786 }
787
788
789 static EncoderStatus
790 gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
791                        GstVaapiContext *context, GList **coded_pics)
792 {
793   GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
794   EncoderStatus ret = ENCODER_NO_ERROR;
795   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
796
797   //h264_prv->frame_count = 0;
798   //gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
799
800   //end:
801   return ret;
802 }
803
804 /*test*/
805 static int draw_picture(int width, int height,
806                          unsigned char *Y_start,
807                          unsigned char *U_start,
808                          unsigned char *V_start,
809                          int UV_interleave, int box_width, int row_shift);
810
811 int main_test(int argc, char* argv[])
812 {
813   EncoderStatus ret = ENCODER_NO_ERROR;
814   GstVaapiEncoder *encoder = NULL;
815
816   GList *coded_pics = NULL;
817   GstBuffer **raw_buffer = NULL;
818   const guint32 raw_buffer_num = 20;
819
820   GstBuffer *tmp_buffer;
821
822   guint32 i = 0, k = 0;
823
824   gst_init (&argc, &argv);
825
826   g_type_init();
827   if (!g_thread_supported ())
828     g_thread_init (NULL);
829
830   GstH264Encoder *h264_encoder = gst_h264_encoder_new();
831   encoder = GST_VAAPI_ENCODER(h264_encoder);
832   ENCODER_ASSERT(encoder);
833
834   h264_encoder->profile = 64;
835   h264_encoder->level = 30;
836   encoder->width = 1280;
837   encoder->height = 720;
838   encoder->frame_rate = 10;
839   h264_encoder->bitrate = 512*1000;
840   h264_encoder->intra_period = 30;
841   ret = gst_vaapi_encoder_initialize(encoder);
842   ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
843   ret = gst_vaapi_encoder_open(encoder, NULL);
844   ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
845
846   guint32 buffer_size = encoder->width * encoder->width *3 /2;
847   guint32 y_width = encoder->width, y_size = encoder->width * encoder->height;
848   guint32 u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
849   guint32 v_width = encoder->width/2;
850   guint8 *y_src, *u_src, *v_src;
851
852   /*set buffers*/
853   int box_width=8;
854   int row_shift=0;
855   raw_buffer = (GstBuffer**)g_malloc0(raw_buffer_num*sizeof(GstBuffer*));
856   for (i = 0; i < raw_buffer_num; i++) {
857     raw_buffer[i] = gst_buffer_new_and_alloc(buffer_size);
858     y_src = GST_BUFFER_DATA(raw_buffer[i]);
859     u_src = y_src + y_size;
860     v_src = u_src + u_size;
861
862     draw_picture(encoder->width, encoder->height, y_src, u_src, v_src, 0, box_width, row_shift);
863     row_shift++;
864     if (row_shift==(2*box_width)) row_shift= 0;
865   }
866
867   FILE *fp = fopen("tmp.h264", "wb");
868   ENCODER_ASSERT(fp);
869
870   k = 0;
871
872   for (i = 0; i < 50; i++) {
873     coded_pics = NULL;
874     ret = gst_vaapi_encoder_encode(encoder, raw_buffer[k], &coded_pics);
875     ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
876     ++k;
877     if (k >= raw_buffer_num) k = 0;
878
879     while (coded_pics) {
880       tmp_buffer = coded_pics->data;
881       coded_pics = g_list_remove(coded_pics, tmp_buffer);
882       fwrite(GST_BUFFER_DATA(tmp_buffer), GST_BUFFER_SIZE(tmp_buffer), 1, fp);
883       printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8));
884       gst_buffer_unref(tmp_buffer);
885     }
886   }
887   fclose(fp);
888
889   ret = gst_vaapi_encoder_close(encoder);
890   ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
891
892   for (i = 0; i < raw_buffer_num; i++) {
893     gst_buffer_unref(raw_buffer[i]);
894   }
895   g_free(raw_buffer);
896   gst_vaapi_encoder_unref(encoder);
897
898   return 0;
899 }
900
901 EncoderStatus
902 gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
903 {
904   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
905   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
906   GstBuffer *avc_codec;
907   const guint32 configuration_version = 0x01;
908   const guint32 length_size_minus_one = 0x03;
909   guint32 profile, profile_comp, level_idc;
910
911   ENCODER_ASSERT(buffer);
912   if (!h264_prv->sps_data || !h264_prv->pps_data) {
913     return ENCODER_DATA_NOT_READY;
914   }
915
916   if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(h264_prv->sps_data),
917                                    GST_BUFFER_SIZE(h264_prv->sps_data),
918                                    &profile, &profile_comp, &level_idc))
919   {
920     ENCODER_ASSERT(0);
921     return ENCODER_DATA_ERR;
922   }
923
924   H264Bitstream bitstream;
925   h264_bitstream_init(&bitstream,
926                      (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 32)*8);
927
928   /*codec_data*/
929   h264_bitstream_write_uint(&bitstream, configuration_version, 8);
930   h264_bitstream_write_uint(&bitstream, profile, 8);
931   h264_bitstream_write_uint(&bitstream, profile_comp, 8);
932   h264_bitstream_write_uint(&bitstream, level_idc, 8);
933   h264_bitstream_write_uint(&bitstream, h264_bit_mask[6], 6); /*111111*/
934   h264_bitstream_write_uint(&bitstream, length_size_minus_one, 2);
935   h264_bitstream_write_uint(&bitstream, h264_bit_mask[3], 3); /*111*/
936
937   /*write sps*/
938   h264_bitstream_write_uint(&bitstream, 1, 5);   /* sps count = 1*/
939   ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
940   h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->sps_data), 16);
941   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
942                                               GST_BUFFER_SIZE(h264_prv->sps_data));
943
944   /*write pps*/
945   h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
946   h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->pps_data), 16);
947   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
948                                               GST_BUFFER_SIZE(h264_prv->pps_data));
949
950   avc_codec = gst_buffer_new();
951   GST_BUFFER_MALLOCDATA(avc_codec) =
952          GST_BUFFER_DATA(avc_codec) =
953          BIT_STREAM_BUFFER(&bitstream);
954   GST_BUFFER_SIZE(avc_codec) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
955   h264_bitstream_destroy(&bitstream, FALSE);
956   *buffer = avc_codec;
957
958   return ENCODER_NO_ERROR;
959 }
960
961 EncoderStatus
962 gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
963 {
964   GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
965   GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
966   GstBuffer *nal_sps_pps;
967
968   ENCODER_ASSERT(buffer);
969   if (!h264_prv->sps_data || !h264_prv->pps_data) {
970     return ENCODER_DATA_NOT_READY;
971   }
972
973   H264Bitstream bitstream;
974   h264_bitstream_init(&bitstream,
975                      (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 8)*8);
976
977   /*0x000001 start code*/
978   h264_bitstream_write_uint(&bitstream, 0x000001, 24);
979   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
980                                               GST_BUFFER_SIZE(h264_prv->sps_data));
981   h264_bitstream_write_uint(&bitstream, 0x000001, 24);
982   h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
983                                               GST_BUFFER_SIZE(h264_prv->pps_data));
984
985   nal_sps_pps = gst_buffer_new();
986   GST_BUFFER_MALLOCDATA(nal_sps_pps) =
987          GST_BUFFER_DATA(nal_sps_pps) =
988          BIT_STREAM_BUFFER(&bitstream);
989   GST_BUFFER_SIZE(nal_sps_pps) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
990   h264_bitstream_destroy(&bitstream, FALSE);
991   *buffer = nal_sps_pps;
992   return ENCODER_NO_ERROR;
993 }
994
995 static void
996 h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
997 {
998   bitstream->bit_size = 0;
999   bitstream->buffer = NULL;
1000   bitstream->max_bit_capability = 0;
1001   if (bit_capability) {
1002     h264_bitstream_auto_grow(bitstream, bit_capability);
1003   }
1004 }
1005
1006 static gboolean
1007 h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size)
1008 {
1009   gboolean ret = TRUE;
1010   guint32 byte_pos, bit_offset;
1011   guint8  *cur_byte;
1012   guint32 fill_bits;
1013
1014   if(!bit_size) {
1015     return TRUE;
1016   }
1017
1018   ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, bit_size), FALSE, "h264_bitstream_auto_grow failed.\n");
1019   byte_pos = (bitstream->bit_size>>3);
1020   bit_offset = (bitstream->bit_size&0x07);
1021   cur_byte = bitstream->buffer + byte_pos;
1022   ENCODER_ASSERT(bit_offset < 8 && bitstream->bit_size <= bitstream->max_bit_capability);
1023
1024   while (bit_size) {
1025     fill_bits = ((8-bit_offset) < bit_size ? (8-bit_offset) : bit_size);
1026     bit_size -= fill_bits;
1027     bitstream->bit_size += fill_bits;
1028
1029     *cur_byte |= ((value>>bit_size) & h264_bit_mask[fill_bits])<<(8-bit_offset-fill_bits);
1030     ++cur_byte;
1031     bit_offset = 0;
1032   }
1033   ENCODER_ASSERT(cur_byte <= bitstream->buffer + bitstream->max_bit_capability/8);
1034   return TRUE;
1035
1036   end:
1037   return FALSE;
1038 }
1039
1040 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value)
1041 {
1042   guint32 bit_offset, bit_left;
1043
1044   bit_offset = (bitstream->bit_size&0x07);
1045   if (!bit_offset) {
1046     return TRUE;
1047   }
1048   bit_left = 8 - bit_offset;
1049   if (value) value = h264_bit_mask[bit_left];
1050   return h264_bitstream_write_uint(bitstream, value, bit_left);
1051 }
1052
1053
1054 static gboolean
1055 h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size)
1056 {
1057   gboolean ret = TRUE;
1058   if (!byte_size) {
1059     return 0;
1060   }
1061   ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, byte_size<<3), FALSE, "h264_bitstream_auto_grow failed.\n");
1062   if (0 == (bitstream->bit_size&0x07)) {
1063     memcpy(&bitstream->buffer[bitstream->bit_size>>3], buf, byte_size);
1064     bitstream->bit_size += (byte_size<<3);
1065   } else {
1066     ENCODER_ASSERT(0);
1067     while(byte_size) {
1068       h264_bitstream_write_uint(bitstream, *buf, 8);
1069       --byte_size;
1070       ++buf;
1071     }
1072   }
1073   return TRUE;
1074
1075 end:
1076   return FALSE;
1077 }
1078
1079 static gboolean
1080 h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value)
1081 {
1082   gboolean ret = TRUE;
1083   guint32  size_in_bits = 0;
1084   guint32  tmp_value = ++value;
1085   while (tmp_value) {
1086     ++size_in_bits;
1087     tmp_value >>= 1;
1088   }
1089   ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1), FALSE, "h264_bitstream_write_ue failed.\n");
1090   ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits), FALSE, "h264_bitstream_write_ue failed.\n");
1091   return TRUE;
1092
1093 end:
1094   return FALSE;
1095 }
1096
1097 static gboolean
1098 h264_bitstream_write_se(H264Bitstream *bitstream, guint32 value)
1099 {
1100   gboolean ret = TRUE;
1101   guint32 new_val;
1102
1103   if (value <= 0) {
1104     new_val = -(value<<1);
1105   } else {
1106     new_val = (value<<1) - 1;
1107   }
1108
1109   ENCODER_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val), FALSE, "h264_bitstream_write_se failed.\n");
1110   return TRUE;
1111
1112   end:
1113   return FALSE;
1114 }
1115
1116 static gboolean
1117 h264_bitstream_write_trailing_bits(H264Bitstream *bitstream)
1118 {
1119     h264_bitstream_write_uint(bitstream, 1, 1);
1120     h264_bitstream_align(bitstream, 0);
1121     return TRUE;
1122 }
1123
1124 static void
1125 h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag)
1126 {
1127   if (bitstream->buffer && free_flag) {
1128     free (bitstream->buffer);
1129   }
1130   bitstream->buffer = NULL;
1131   bitstream->bit_size = 0;
1132   bitstream->max_bit_capability = 0;
1133 }
1134
1135 static gboolean
1136 h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size)
1137 {
1138   guint32 new_bit_size = extra_bit_size + bitstream->bit_size;
1139   guint32 clear_pos;
1140
1141   ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
1142   if (new_bit_size <= bitstream->max_bit_capability) {
1143     return TRUE;
1144   }
1145
1146   new_bit_size = ((new_bit_size + H264_BITSTREAM_ALLOC_ALIGN_MASK)
1147                 &(~H264_BITSTREAM_ALLOC_ALIGN_MASK));
1148   ENCODER_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
1149   clear_pos = ((bitstream->bit_size+7)>>3);
1150   bitstream->buffer = realloc(bitstream->buffer, new_bit_size>>3);
1151   memset(bitstream->buffer+clear_pos, 0, (new_bit_size>>3)-clear_pos);
1152   bitstream->max_bit_capability = new_bit_size;
1153   return TRUE;
1154 }
1155
1156 static gboolean
1157 h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv)
1158 {
1159   guint32 constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag;
1160   guint32 seq_parameter_set_id = 0;
1161
1162   /*need to set the values*/
1163   guint32 log2_max_frame_num_minus4 = 0;  // 1? 3?
1164   guint32 pic_order_cnt_type = 0; // Must be 0
1165   guint32 log2_max_pic_order_cnt_lsb_minus4 = 0;  // 2 ? 4?
1166   guint32 num_ref_frames = 1;  // only P frames
1167   guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
1168   guint32 mb_width = (ENCODER_WIDTH(h264_prv->public)+15)/16; // mb_width
1169   guint32 mb_height = (ENCODER_HEIGHT(h264_prv->public)+15)/16; // mb_height
1170   guint32 frame_mbs_only_flag = 1; // only mbs
1171   guint32 frame_cropping_flag = 0;
1172   guint32 frame_crop_bottom_offset = 0;
1173   guint32 vui_present_flag = 0; // no vui flags
1174
1175
1176   constraint_set0_flag = h264_prv->public->profile == H264_PROFILE_BASELINE;
1177   constraint_set1_flag = h264_prv->public->profile <= H264_PROFILE_MAIN;
1178   constraint_set2_flag = 0;
1179   constraint_set3_flag = 0;
1180
1181   if (mb_height * 16 - ENCODER_HEIGHT(h264_prv->public)) {
1182     frame_cropping_flag = 1;
1183     frame_crop_bottom_offset =
1184         (mb_height * 16 - ENCODER_HEIGHT(h264_prv->public)) / (2 * (!frame_mbs_only_flag + 1));
1185   }
1186
1187   h264_bitstream_write_uint(bitstream, h264_prv->public->profile, 8); /* profile_idc */
1188   h264_bitstream_write_uint(bitstream, constraint_set0_flag, 1);     /* constraint_set0_flag */
1189   h264_bitstream_write_uint(bitstream, constraint_set1_flag, 1);     /* constraint_set1_flag */
1190   h264_bitstream_write_uint(bitstream, constraint_set2_flag, 1);     /* constraint_set2_flag */
1191   h264_bitstream_write_uint(bitstream, constraint_set3_flag, 1);     /* constraint_set3_flag */
1192   h264_bitstream_write_uint(bitstream, 0, 4);                        /* reserved_zero_4bits */
1193   h264_bitstream_write_uint(bitstream, h264_prv->public->level, 8);   /* level_idc */
1194   h264_bitstream_write_ue(bitstream, seq_parameter_set_id);          /* seq_parameter_set_id */
1195
1196   if (h264_prv->public->profile >= H264_PROFILE_HIGH) {
1197       /* FIXME: fix for high profile */
1198       ENCODER_ASSERT(0);
1199   }
1200
1201   h264_bitstream_write_ue(bitstream, log2_max_frame_num_minus4);    /* log2_max_frame_num_minus4 */
1202   h264_bitstream_write_ue(bitstream, pic_order_cnt_type);           /* pic_order_cnt_type */
1203
1204   if (pic_order_cnt_type == 0)
1205       h264_bitstream_write_ue(bitstream, log2_max_pic_order_cnt_lsb_minus4);/* log2_max_pic_order_cnt_lsb_minus4 */
1206   else {
1207       ENCODER_ASSERT(0);
1208   }
1209
1210   h264_bitstream_write_ue(bitstream, num_ref_frames);                            /* num_ref_frames */
1211   h264_bitstream_write_uint(bitstream, gaps_in_frame_num_value_allowed_flag, 1); /* gaps_in_frame_num_value_allowed_flag */
1212
1213   h264_bitstream_write_ue(bitstream, mb_width - 1);              /* pic_width_in_mbs_minus1 */
1214   h264_bitstream_write_ue(bitstream, mb_height - 1);             /* pic_height_in_map_units_minus1 */
1215   h264_bitstream_write_uint(bitstream, frame_mbs_only_flag, 1);  /* frame_mbs_only_flag */
1216
1217   if (!frame_mbs_only_flag) { //ONLY mbs
1218       ENCODER_ASSERT(0);
1219   }
1220
1221   h264_bitstream_write_uint(bitstream, 0, 1);                         /* direct_8x8_inference_flag */
1222   h264_bitstream_write_uint(bitstream, frame_cropping_flag, 1);       /* frame_cropping_flag */
1223
1224   if (frame_cropping_flag) {
1225       h264_bitstream_write_ue(bitstream, 0);                        /* frame_crop_left_offset */
1226       h264_bitstream_write_ue(bitstream, 0);                        /* frame_crop_right_offset */
1227       h264_bitstream_write_ue(bitstream, 0);                        /* frame_crop_top_offset */
1228       h264_bitstream_write_ue(bitstream, frame_crop_bottom_offset); /* frame_crop_bottom_offset */
1229   }
1230
1231   h264_bitstream_write_uint(bitstream, vui_present_flag, 1);                         /* vui_parameters_present_flag */
1232   h264_bitstream_write_trailing_bits(bitstream);                             /* rbsp_trailing_bits */
1233   return TRUE;
1234
1235   //end:
1236   //return FALSE;
1237
1238 }
1239
1240 static const guint8 *
1241 h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
1242 {
1243     const guint8 *cur = buffer;
1244     const guint8 *end = buffer + len;
1245     const guint8 *nal_start = NULL;
1246     guint32 flag = 0xFFFFFFFF;
1247     guint32 nal_start_len = 0;
1248
1249     ENCODER_ASSERT(len >= 0 && buffer && nal_size);
1250     if (len < 3) {
1251         *nal_size = len;
1252         nal_start = (len ? buffer : NULL);
1253         return nal_start;
1254     }
1255
1256     /*locate head postion*/
1257     if (!buffer[0] && !buffer[1]) {
1258         if (buffer[2] == 1) { // 0x000001
1259             nal_start_len = 3;
1260         } else if (!buffer[2] && len >=4 && buffer[3] == 1) { //0x00000001
1261             nal_start_len = 4;
1262         }
1263     }
1264     nal_start = buffer + nal_start_len;
1265     cur = nal_start;
1266
1267     /*find next nal start position*/
1268     while (cur < end) {
1269         flag = ((flag<<8) | ((*cur++)&0xFF));
1270         if (flag == 0x00000001) {
1271             *nal_size = cur - 4 - nal_start;
1272             break;
1273         } else if ((flag&0x00FFFFFF) == 0x00000001) {
1274             *nal_size = cur - 3 - nal_start;
1275             break;
1276         }
1277     }
1278     if (cur >= end) {
1279       *nal_size = end - nal_start;
1280       if (nal_start >= end) {
1281         nal_start = NULL;
1282       }
1283     }
1284     return nal_start;
1285 }
1286
1287
1288 static gboolean
1289 h264_bitstream_write_pps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv)
1290 {
1291   ENCODER_ASSERT(0);
1292   return TRUE;
1293 }
1294
1295 static int draw_picture(int width, int height,
1296                          unsigned char *Y_start,
1297                          unsigned char *U_start,
1298                          unsigned char *V_start,
1299                          int UV_interleave, int box_width, int row_shift)
1300 {
1301     int row;
1302     int field = 0;
1303     int Y_pitch = width;
1304     int U_pitch = width/2;
1305     int V_pitch = width/2;
1306
1307     /* copy Y plane */
1308     for (row=0;row<height;row++) {
1309         unsigned char *Y_row = Y_start + row * Y_pitch;
1310         int jj, xpos, ypos;
1311
1312         ypos = (row / box_width) & 0x1;
1313
1314         /* fill garbage data into the other field */
1315         if (((field == 1) && (row &1))
1316             || ((field == 2) && ((row &1)==0))) {
1317             memset(Y_row, 0xff, width);
1318             continue;
1319         }
1320
1321         for (jj=0; jj<width; jj++) {
1322             xpos = ((row_shift + jj) / box_width) & 0x1;
1323
1324             if ((xpos == 0) && (ypos == 0))
1325                 Y_row[jj] = 0xeb;
1326             if ((xpos == 1) && (ypos == 1))
1327                 Y_row[jj] = 0xeb;
1328
1329             if ((xpos == 1) && (ypos == 0))
1330                 Y_row[jj] = 0x10;
1331             if ((xpos == 0) && (ypos == 1))
1332                 Y_row[jj] = 0x10;
1333         }
1334     }
1335
1336     /* copy UV data */
1337     for( row =0; row < height/2; row++) {
1338         unsigned short value = 0x80;
1339
1340         /* fill garbage data into the other field */
1341         if (((field == 1) && (row &1))
1342             || ((field == 2) && ((row &1)==0))) {
1343             value = 0xff;
1344         }
1345
1346         if (UV_interleave) {
1347             unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch);
1348
1349             memset(UV_row, value, width);
1350         } else {
1351             unsigned char *U_row = U_start + row * U_pitch;
1352             unsigned char *V_row = V_start + row * V_pitch;
1353
1354             memset (U_row,value,width/2);
1355             memset (V_row,value,width/2);
1356         }
1357     }
1358     return 0;
1359 }
1360
1361
1362