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