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