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