2 #include "gstvaapih264encoder.h"
11 #include "gst/gstclock.h"
12 #include "gst/gstvalue.h"
14 #include "gst/vaapi/gstvaapiobject.h"
15 #include "gst/vaapi/gstvaapiobject_priv.h"
16 #include "gst/vaapi/gstvaapicontext.h"
17 #include "gst/vaapi/gstvaapisurface.h"
18 #include "gst/vaapi/gstvaapivideobuffer.h"
19 #include "gst/vaapi/gstvaapidisplay_priv.h"
21 /* enable old lib va*/
22 //#define _SIMPLE_LIB_VA_
24 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
25 #define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
27 #define SHARE_CODED_BUF 0
29 #define DEFAULT_SURFACE_NUMBER 3
30 #define DEFAULT_CODEDBUF_NUM 5
31 #define DEFAULT_SID_INPUT 0 // suface_ids[0]
33 #define REF_RECON_SURFACE_NUM 2
35 #define ENTROPY_MODE_CAVLC 0
36 #define ENTROPY_MODE_CABAC 1
42 #define NAL_REF_IDC_NONE 0
43 #define NAL_REF_IDC_LOW 1
44 #define NAL_REF_IDC_MEDIUM 2
45 #define NAL_REF_IDC_HIGH 3
51 NAL_IDR = 5, /* ref_idc != 0 */
52 NAL_SEI = 6, /* ref_idc == 0 */
66 struct _GstH264EncodeBuffer {
69 GstH264EncoderPrivate *encoder;
72 struct _GstH264EncoderPrivate {
73 GstH264Encoder *public;
74 guint32 format; /*NV12, I420,*/
75 gboolean es_flag; /*elementary flag*/
78 GQueue *video_buffer_caches; /*not used for baseline*/
80 GstVaapiSurface *ref_surface1; /* reference buffer*/
81 GstVaapiSurface *ref_surface2; /* for B frames */
82 GstVaapiSurface *recon_surface; /* reconstruct buffer*/
84 VABufferID seq_parameter;
85 VABufferID pic_parameter;
86 VABufferID slice_parameter;
87 VABufferID packed_sps_par_buf;
88 VABufferID packed_sps_data_buf;
89 VABufferID packed_pps_par_buf;
90 VABufferID packed_pps_data_buf;
91 #ifdef _SIMPLE_LIB_VA_
92 VAEncSliceParameterBuffer *slice_param_buffers;
94 VAEncSliceParameterBufferH264 *slice_param_buffers;
96 guint32 default_slice_height;
97 guint32 slice_mod_mb_num;
98 guint32 default_cts_offset;
103 GQueue *queued_buffers; /* GstVaapiVideoBuffers with surface*/
106 guint32 cur_display_num;
107 guint32 cur_decode_num;
108 H264_SLICE_TYPE cur_slice_type;
109 guint64 last_decode_time;
112 G_DEFINE_TYPE(GstH264Encoder, gst_h264_encoder, GST_TYPE_VAAPI_BASE_ENCODER);
116 #define H264_BITSTREAM_ALLOC_ALIGN_MASK 0x0FFF
118 #define BIT_STREAM_BUFFER(stream) ((stream)->buffer)
119 #define BIT_STREAM_BIT_SIZE(stream) ((stream)->bit_size)
121 struct _H264Bitstream {
124 guint32 max_bit_capability;
127 typedef struct _H264Bitstream H264Bitstream;
129 static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
131 static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
132 GstVaapiContext *context, GList **coded_pics);
135 static EncoderStatus gst_h264_encoder_get_avcC_codec_data(
136 GstVaapiEncoder* encoder, GstBuffer **buffer);
137 static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
139 static gboolean gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
140 static void gst_h264_encoder_finalize(GObject *object);
141 static void gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
143 static gboolean gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder,
144 GstVaapiDisplay *display, GstVaapiContext *context);
145 static gboolean gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder,
146 GstVaapiDisplay *display, GstVaapiContext *context);
147 static EncoderStatus gst_h264_encoder_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
148 GstVaapiVideoBuffer *display_buf, gboolean need_flush,
149 GstVaapiVideoBuffer **out_buf);
150 static void gst_h264_encoder_frame_failed(GstVaapiBaseEncoder *encoder,
151 GstVaapiVideoBuffer* buffer);
152 static EncoderStatus gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
153 GstVaapiContext *context, GstVaapiSurface *surface,
154 guint frame_index, VABufferID coded_buf, gboolean *is_key);
155 static void gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
156 //static EncoderStatus h264_encoder_read_sps_pps(
157 // GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size);
158 static GstBuffer *gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
159 guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
161 /* h264 bitstream functions */
162 static void h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
163 static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
164 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value);
165 static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value);
166 static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value);
167 static gboolean h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
169 static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size);
170 static void h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
171 static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size);
172 static gboolean h264_bitstream_write_sps(H264Bitstream *bitstream, VAEncSequenceParameterBufferH264 *seq);
173 static gboolean h264_bitstream_write_pps(H264Bitstream *bitstream, VAEncPictureParameterBufferH264 *pic);
174 static gboolean h264_bitstream_write_nal_header(H264Bitstream *bitstream,
175 guint nal_ref_idc, guint nal_unit_type);
177 static const guint8 *h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size);
178 static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
179 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
182 gst_h264_encoder_class_init(GstH264EncoderClass *klass)
184 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
185 GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
186 GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
188 g_type_class_add_private(klass, sizeof(GstH264EncoderPrivate));
190 GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
191 "gst_va_h264_encoder element");
193 object_class->finalize = gst_h264_encoder_finalize;
195 base_class->validate_attributes = gst_h264_validate_parameters;
196 base_class->pre_alloc_resource = gst_h264_encoder_alloc_slices;
197 base_class->release_resource = gst_h264_encoder_release_resource;
198 base_class->prepare_next_input_buffer = gst_h264_encoder_prepare_next_buffer;
199 base_class->render_frame = gst_h264_encoder_rendering;
200 base_class->notify_frame = gst_h264_notify_frame;
201 base_class->copy_coded_frame = gst_h264_encoder_copy_coded_buffer;
202 base_class->encode_frame_failed = gst_h264_encoder_frame_failed;
204 encoder_class->flush = gst_h264_encoder_flush;
206 encoder_class->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
207 /* encoder_class->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
210 object_class->set_property = gst_h264_encoder_set_property;
211 object_class->get_property = gst_h264_encoder_get_property;
217 gst_h264_encode_buffer_class_init (gpointer g_class, gpointer class_data)
219 GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class);
221 h264_encode_buffer_parent_class = g_type_class_peek_parent(g_class);
222 ENCODER_ASSERT(h264_encode_buffer_parent_class);
224 mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
225 gst_h264_encode_buffer_finalize;
230 gst_h264_encode_buffer_get_type (void)
232 static GType s_h264_encode_buffer_type = 0;
233 if (G_UNLIKELY (s_h264_encode_buffer_type == 0)) {
234 static const GTypeInfo s_h264_encode_buffer_info = {
235 sizeof(GstBufferClass),
238 gst_h264_encode_buffer_class_init,
241 sizeof(GstH264EncodeBuffer),
246 s_h264_encode_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
247 "GstH264EncodeBuffer", &s_h264_encode_buffer_info, 0);
249 return s_h264_encode_buffer_type;
253 gst_h264_encode_buffer_finalize (GstH264EncodeBuffer *h264_buffer)
255 GstH264EncoderPrivate *h264_prv = NULL;
256 VABufferID* coded_id = NULL;
257 GstVaapiDisplay *display = NULL;
259 gboolean is_locked = FALSE;
261 h264_prv = h264_buffer->encoder;
262 coded_id = h264_buffer->coded_id;
263 display = ENCODER_DISPLAY(h264_prv->public);
265 ENCODER_ASSERT(display);
266 VADisplay va_dpy = gst_vaapi_display_get_display(display);
268 ENCODER_ASSERT(h264_prv);
269 ENCODER_ASSERT(coded_id && VA_INVALID_ID!= *coded_id);
271 /*if (--(*h264_buffer->ref_coded_id) == 0) */
273 /*g_free(h264_buffer->ref_coded_id);*/
274 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
275 vaUnmapBuffer(va_dpy, *coded_id);
276 ENCODER_RELEASE_DISPLAY_LOCK(display);
277 push_available_coded_buffer(h264_prv, coded_id);
280 if (GST_MINI_OBJECT_CLASS(h264_encode_buffer_parent_class)->finalize) {
281 GST_MINI_OBJECT_CLASS(h264_encode_buffer_parent_class)->finalize(GST_MINI_OBJECT(h264_buffer));
285 static GstH264EncodeBuffer *
286 gst_h264_encode_buffer_new(GstH264EncoderPrivate *h264_prv,
287 VABufferID *coded_id)
289 GstH264EncodeBuffer *buf = (GstH264EncodeBuffer*)gst_mini_object_new(GST_TYPE_H264_ENCODE_BUFFER);
290 buf->coded_id = coded_id;
291 buf->encoder = h264_prv;
296 static GstVaapiSurface *
297 h264_get_video_surface(GstH264EncoderPrivate *h264_prv, GstVaapiVideoBuffer *video_buffer)
300 GstVaapiSurface *ret = gst_vaapi_video_buffer_get_surface(video_buffer);
302 ENCODER_CHECK_STATUS(ret, NULL, "video buffer doesn't have a surface");
304 g_queue_push_tail(h264_prv->video_buffer_caches,video_buffer);
305 gst_buffer_ref(GST_BUFFER(video_buffer));
314 h264_release_video_surface(GstH264EncoderPrivate *h264_prv, VASurfaceID surface)
317 ENCODER_ASSERT(h264_prv->video_buffer_caches);
318 g_queue_find_custom(h264_prv->video_buffer_caches,xx, compare_func);
319 for (h264_prv->video_buffer_caches) {
325 h264_get_va_profile(guint32 profile)
328 case H264_PROFILE_BASELINE:
329 return VAProfileH264Baseline;
331 case H264_PROFILE_MAIN:
332 return VAProfileH264Main;
334 case H264_PROFILE_HIGH:
335 return VAProfileH264High;
344 gst_h264_encoder_init(GstH264Encoder *encoder)
346 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
347 ENCODER_ASSERT(h264_prv);
348 h264_prv->public = encoder;
350 /* init public attributes */
351 gst_h264_encoder_init_public_values(encoder);
352 gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
354 /* init private values*/
355 h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
356 h264_prv->es_flag = TRUE;
357 //h264_prv->es_flag = FALSE;
359 h264_prv->ref_surface1 = NULL;
360 h264_prv->ref_surface2 = NULL;
361 h264_prv->recon_surface = NULL;
363 h264_prv->seq_parameter = VA_INVALID_ID;
364 h264_prv->pic_parameter = VA_INVALID_ID;
365 h264_prv->slice_parameter = VA_INVALID_ID;
366 h264_prv->packed_sps_par_buf = VA_INVALID_ID;
367 h264_prv->packed_sps_data_buf = VA_INVALID_ID;
368 h264_prv->packed_pps_par_buf = VA_INVALID_ID;
369 h264_prv->packed_pps_data_buf = VA_INVALID_ID;
370 h264_prv->slice_param_buffers = NULL;
371 h264_prv->default_slice_height = 0;
372 h264_prv->slice_mod_mb_num = 0;
374 h264_prv->sps_data = NULL;
375 h264_prv->pps_data = NULL;
377 h264_prv->queued_buffers = g_queue_new();
378 h264_prv->gop_count = 0;
379 h264_prv->cur_display_num = 0;
380 h264_prv->cur_decode_num = 0;
381 h264_prv->cur_slice_type = SLICE_TYPE_I;
382 h264_prv->last_decode_time = 0LL;
383 h264_prv->default_cts_offset = 0;
387 gst_h264_encoder_finalize(GObject *object)
389 /*free private buffers*/
390 GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
391 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(object);
393 if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
394 gst_vaapi_encoder_uninitialize(encoder);
397 if (h264_prv->sps_data) {
398 gst_buffer_unref(h264_prv->sps_data);
399 h264_prv->sps_data = NULL;
401 if (h264_prv->pps_data) {
402 gst_buffer_unref(h264_prv->pps_data);
403 h264_prv->pps_data = NULL;
405 if (h264_prv->slice_param_buffers) {
406 g_free(h264_prv->slice_param_buffers);
407 h264_prv->slice_param_buffers = NULL;
410 if (h264_prv->queued_buffers) {
411 ENCODER_ASSERT(g_queue_is_empty(h264_prv->queued_buffers));
412 g_queue_free(h264_prv->queued_buffers);
413 h264_prv->queued_buffers = NULL;
416 G_OBJECT_CLASS(gst_h264_encoder_parent_class)->finalize(object);
421 gst_h264_encoder_new(void)
423 return GST_H264_ENCODER(g_object_new(GST_TYPE_H264_ENCODER, NULL));
427 gst_h264_encoder_init_public_values(GstH264Encoder* encoder)
429 encoder->profile = 0;
431 encoder->bitrate = 0;
432 encoder->intra_period = 0;
433 encoder->init_qp = -1;
434 encoder->min_qp = -1;
435 encoder->slice_num = 0;
436 encoder->b_frame_num = 0;
440 gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es)
442 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
443 h264_prv->es_flag = es;
448 gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
450 GstH264Encoder *encoder = GST_H264_ENCODER(base_encoder);
451 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
452 if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
455 if (!encoder->profile) {
456 encoder->profile = H264_DEFAULT_PROFILE;
458 gst_vaapi_base_encoder_set_va_profile(base_encoder, h264_get_va_profile(encoder->profile));
459 if (!encoder->level) {
460 if (encoder->profile <= H264_PROFILE_BASELINE)
461 encoder->level = H264_LEVEL_30;
463 encoder->level = H264_LEVEL_41;
465 if (!encoder->intra_period) {
466 encoder->intra_period = H264_DEFAULT_INTRA_PERIOD;
468 if (-1 == encoder->init_qp) {
469 encoder->init_qp = H264_DEFAULT_INIT_QP;
471 if (-1 == encoder->min_qp) {
472 encoder->min_qp = H264_DEFAULT_MIN_QP;
475 if (encoder->min_qp > encoder->init_qp) {
476 encoder->min_qp = encoder->init_qp;
479 /* default compress ratio 1: (4*8*1.5) */
480 if (!encoder->bitrate) {
481 encoder->bitrate = 0; //ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
484 if (!encoder->slice_num) {
485 encoder->slice_num = H264_DEFAULT_SLICE_NUM;
488 /* need calculate slice-num and each slice-height
489 suppose: ((encoder->height+15)/16) = 13, slice_num = 8
490 then: slice_1_height = 2
499 h264_prv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
500 if (0 == h264_prv->default_slice_height) { /* special value */
501 h264_prv->default_slice_height = 1;
502 h264_prv->slice_mod_mb_num = 0;
503 encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
505 h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
508 if (encoder->b_frame_num) {
509 h264_prv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
511 h264_prv->default_cts_offset = 0;
518 h264_encoder_release_parameters(GstH264Encoder *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
520 VAStatus va_status = VA_STATUS_SUCCESS;
521 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
523 gboolean is_locked = FALSE;
525 ENCODER_ASSERT(display);
526 ENCODER_ASSERT(context);
527 VAAPI_UNUSED_ARG(va_status);
528 VADisplay va_dpy = gst_vaapi_display_get_display(display);
530 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
531 if (VA_INVALID_ID != h264_prv->seq_parameter) {
532 va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
533 h264_prv->seq_parameter = VA_INVALID_ID;
535 if (VA_INVALID_ID != h264_prv->pic_parameter) {
536 va_status = vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
537 h264_prv->pic_parameter = VA_INVALID_ID;
539 if (VA_INVALID_ID != h264_prv->slice_parameter) {
540 va_status = vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
541 h264_prv->slice_parameter = VA_INVALID_ID;
544 if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
545 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_par_buf);
546 h264_prv->packed_sps_par_buf = VA_INVALID_ID;
548 if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
549 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_data_buf);
550 h264_prv->packed_sps_data_buf = VA_INVALID_ID;
552 if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
553 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_par_buf);
554 h264_prv->packed_pps_par_buf = VA_INVALID_ID;
556 if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
557 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_data_buf);
558 h264_prv->packed_pps_data_buf = VA_INVALID_ID;
561 ENCODER_RELEASE_DISPLAY_LOCK(display);
563 if (h264_prv->slice_param_buffers) {
564 g_free(h264_prv->slice_param_buffers);
565 h264_prv->slice_param_buffers = NULL;
568 if (h264_prv->sps_data) {
569 gst_buffer_unref(h264_prv->sps_data);
570 h264_prv->sps_data = NULL;
572 if (h264_prv->pps_data) {
573 gst_buffer_unref(h264_prv->pps_data);
574 h264_prv->pps_data = NULL;
581 h264_release_queued_buffers(GstH264EncoderPrivate *h264_prv)
583 while (!g_queue_is_empty(h264_prv->queued_buffers)) {
584 GstBuffer* tmp = g_queue_pop_head(h264_prv->queued_buffers);
586 gst_buffer_unref(tmp);
592 gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
594 GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
596 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
598 /* release buffers first */
599 h264_encoder_release_parameters(h264_encoder, display, context);
600 h264_release_queued_buffers(h264_prv);
601 h264_prv->cur_display_num = 0;
602 h264_prv->cur_decode_num = 0;
603 h264_prv->cur_slice_type = SLICE_TYPE_I;
604 h264_prv->gop_count = 0;
605 h264_prv->last_decode_time = 0LL;
606 h264_prv->default_cts_offset = 0;
608 /*remove ref_surface1*/
609 if (h264_prv->ref_surface1) {
611 gst_vaapi_context_put_surface(context, h264_prv->ref_surface1);
613 g_object_unref(h264_prv->ref_surface1);
615 h264_prv->ref_surface1 = NULL;
618 if (h264_prv->ref_surface2) {
620 gst_vaapi_context_put_surface(context, h264_prv->ref_surface2);
622 g_object_unref(h264_prv->ref_surface2);
624 h264_prv->ref_surface2 = NULL;
627 /*remove recon_surface*/
628 if (h264_prv->recon_surface) {
630 gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
632 g_object_unref(h264_prv->recon_surface);
634 h264_prv->recon_surface = NULL;
641 gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display, GstVaapiContext *context)
644 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
645 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
647 h264_prv->slice_param_buffers =
648 #ifdef _SIMPLE_LIB_VA_
649 (VAEncSliceParameterBuffer*)
651 (VAEncSliceParameterBufferH264*)
653 g_malloc0_n(h264_encoder->slice_num,
654 sizeof(h264_prv->slice_param_buffers[0]));
660 gst_h264_encoder_frame_failed(GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer)
662 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
663 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
665 h264_release_queued_buffers(h264_prv);
666 h264_prv->cur_display_num = 0;
667 h264_prv->cur_decode_num = 0;
668 h264_prv->cur_slice_type = SLICE_TYPE_I;
669 h264_prv->gop_count = 0;
670 h264_prv->last_decode_time = 0LL;
674 gst_h264_encoder_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
675 GstVaapiVideoBuffer *display_buf, gboolean need_flush,
676 GstVaapiVideoBuffer **out_buf)
678 EncoderStatus ret = ENCODER_NO_ERROR;
679 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
680 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
681 GstVaapiVideoBuffer *return_buf = NULL;
684 if (NULL == display_buf && g_queue_is_empty(h264_prv->queued_buffers)) {
685 ret = ENCODER_BUFFER_EMPTY;
686 if (h264_prv->gop_count >= h264_encoder->intra_period || need_flush)
687 h264_prv->gop_count = 0;
692 ++h264_prv->gop_count;
693 gst_buffer_ref(GST_BUFFER_CAST(display_buf));
694 h264_prv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
698 if (h264_prv->gop_count == 1) {
699 ENCODER_ASSERT(display_buf);
700 h264_prv->cur_display_num = 0;
701 h264_prv->cur_decode_num = 0;
702 h264_prv->cur_slice_type = SLICE_TYPE_I;
703 return_buf = display_buf;
708 if (h264_encoder->b_frame_num &&
709 h264_prv->gop_count < h264_encoder->intra_period &&
710 g_queue_get_length(h264_prv->queued_buffers) < h264_encoder->b_frame_num
713 g_queue_push_tail(h264_prv->queued_buffers, display_buf);
714 ret = ENCODER_BUFFER_WAITING;
717 h264_prv->cur_slice_type = SLICE_TYPE_P;
718 h264_prv->cur_display_num = h264_prv->gop_count-1;
719 ++h264_prv->cur_decode_num;
720 return_buf = display_buf;
723 return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(h264_prv->queued_buffers);
724 h264_prv->cur_slice_type = SLICE_TYPE_P;
725 h264_prv->cur_display_num = h264_prv->gop_count - 1;
726 ++h264_prv->cur_decode_num;
728 return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(h264_prv->queued_buffers);
729 h264_prv->cur_slice_type = SLICE_TYPE_B;
730 h264_prv->cur_display_num = h264_prv->gop_count - 2 - g_queue_get_length(h264_prv->queued_buffers);
735 *out_buf = return_buf;
736 /* calculate cts/pts/dts */
739 pts = GST_BUFFER_TIMESTAMP(return_buf);
740 tmp_next_buf = (GstVaapiVideoBuffer*)g_queue_peek_head(h264_prv->queued_buffers);
742 GST_BUFFER_TIMESTAMP(return_buf) = GST_BUFFER_TIMESTAMP(tmp_next_buf);
743 } else if (SLICE_TYPE_B == h264_prv->cur_slice_type) {
744 GST_BUFFER_TIMESTAMP(return_buf) = h264_prv->last_decode_time;
747 pts += h264_prv->default_cts_offset;
748 if ((gint64)(pts - GST_BUFFER_TIMESTAMP(return_buf)) < 0) {
749 pts = GST_BUFFER_TIMESTAMP(return_buf);
752 GST_BUFFER_OFFSET_END(return_buf) = pts;
753 GST_BUFFER_TIMESTAMP(return_buf) = pts;
761 #ifdef _SIMPLE_LIB_VA_
763 gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
764 GstVaapiContext *context, GstVaapiSurface *surface,
765 guint frame_index, VABufferID coded_buf, gboolean *is_key)
767 EncoderStatus ret = ENCODER_NO_ERROR;
768 VAStatus va_status = VA_STATUS_SUCCESS;
769 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
770 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
771 VAEncPictureParameterBufferH264 pic_h264;
772 VAEncSliceParameterBuffer *slice_h264 = NULL;
774 gboolean is_locked = FALSE;
776 ENCODER_ASSERT(display && context);
777 VADisplay va_dpy = gst_vaapi_display_get_display(display);
778 VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
780 *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
783 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
784 /*handle first surface_index*/
785 /*only need first frame*/
786 if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
787 VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
788 seq_h264.level_idc = h264_encoder->level; /* 3.0 */
789 seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
790 seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
791 seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
793 seq_h264.bits_per_second = h264_encoder->bitrate;
794 seq_h264.frame_rate = ENCODER_FPS(h264_encoder);
795 seq_h264.initial_qp = h264_encoder->init_qp; /*qp_value; 15, 24, 26?*/
796 seq_h264.min_qp = h264_encoder->min_qp; /*1, 6, 10*/
797 seq_h264.basic_unit_size = 0;
798 seq_h264.intra_period = h264_encoder->intra_period;
799 seq_h264.intra_idr_period = h264_encoder->intra_period;
801 va_status = vaCreateBuffer(va_dpy, context_id,
802 VAEncSequenceParameterBufferType,
803 sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
804 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
805 ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.");
806 va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
807 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
808 ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.");
811 /* set pic_parameters*/
812 if (!h264_prv->ref_surface1) {
813 h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
814 ENCODER_CHECK_STATUS(h264_prv->ref_surface1, ENCODER_SURFACE_ERR,
815 "reference surface, h264_pop_free_surface failed.");
817 if (!h264_prv->recon_surface) {
818 h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
819 ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR,
820 "reconstructed surface, h264_pop_free_surface failed.");
823 pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
824 pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
825 pic_h264.coded_buf = coded_buf;
826 pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
827 pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
828 pic_h264.last_picture = 0; // last pic or not
830 if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
831 vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
832 h264_prv->pic_parameter = VA_INVALID_ID;
834 va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
835 sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
837 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
838 ENCODER_PICTURE_ERR, "creating pic-param buffer failed.");
840 va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
841 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
842 ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.");
844 /* set slice parameters, support multiple slices */
846 guint32 last_row_num = 0;
847 guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
849 memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
850 for (i = 0; i < h264_encoder->slice_num; ++i) {
851 slice_h264 = &h264_prv->slice_param_buffers[i];
852 slice_h264->start_row_number = last_row_num; /* unit MB*/
853 slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
855 ++slice_h264->slice_height;
858 last_row_num += slice_h264->slice_height;
859 slice_h264->slice_flags.bits.is_intra = *is_key;
860 slice_h264->slice_flags.bits.disable_deblocking_filter_idc = 0;
863 ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
865 if (VA_INVALID_ID != h264_prv->slice_parameter) {
866 vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
867 h264_prv->slice_parameter = VA_INVALID_ID;
869 va_status = vaCreateBuffer(va_dpy,
871 VAEncSliceParameterBufferType,
872 sizeof(h264_prv->slice_param_buffers[0]),
873 h264_encoder->slice_num,
874 h264_prv->slice_param_buffers,
875 &h264_prv->slice_parameter);
876 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
877 ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.");
879 va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
880 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
881 ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.");
883 /*after finished, set ref_surface1_index, recon_surface_index */
884 GstVaapiSurface *swap = h264_prv->ref_surface1;
885 h264_prv->ref_surface1 = h264_prv->recon_surface;
886 h264_prv->recon_surface = swap;
889 ENCODER_RELEASE_DISPLAY_LOCK(display);
893 #else /* extended libva, new parameter structures*/
895 static void h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
897 GstVaapiSurface *tmp;
899 g_return_if_fail(s1 && s2);
906 h264_recreate_seq_param(GstH264Encoder *h264_encoder,
907 VADisplay va_dpy, VAContextID context_id)
909 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
910 VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
911 guint width_in_mbs, height_in_mbs;
913 VAStatus va_status = VA_STATUS_SUCCESS;
916 if (VA_INVALID_ID != h264_prv->seq_parameter)
919 width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
920 height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
922 seq_h264.seq_parameter_set_id = 0;
923 seq_h264.profile_idc = h264_encoder->profile;
924 seq_h264.level_idc = h264_encoder->level; /* 3.0 */
925 seq_h264.intra_period = h264_encoder->intra_period;
926 seq_h264.ip_period = 0; // ?
927 seq_h264.max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1); // ?, why 4
928 seq_h264.picture_width_in_mbs = width_in_mbs;
929 seq_h264.picture_height_in_mbs = height_in_mbs;
930 seq_h264.frame_mbs_only_flag = 1;
931 seq_h264.target_usage = 1; // ?
933 if (h264_encoder->init_qp == -1)
934 seq_h264.rate_control_method = BR_CBR;
935 else if (h264_encoder->init_qp == -2)
936 seq_h264.rate_control_method = BR_VBR;
938 ENCODER_ASSERT(h264_encoder->init_qp >= 0 && h264_encoder->init_qp <= 51);
939 seq_h264.rate_control_method = BR_CQP;
942 if (h264_encoder->bitrate> 0)
943 seq_h264.bits_per_second = h264_encoder->bitrate; /* use kbps as input */
945 seq_h264.bits_per_second = 0;
947 if (seq_h264.rate_control_method == BR_VBR) {
948 seq_h264.max_bits_per_second = seq_h264.bits_per_second*1.5;
949 seq_h264.min_bits_per_second = seq_h264.bits_per_second*0.3;
951 seq_h264.initial_hrd_buffer_fullness = 0; // ??
952 seq_h264.hrd_buffer_size = 0;
953 seq_h264.num_units_in_tick = 100;
954 seq_h264.time_scale = ENCODER_FPS(h264_encoder)*2*seq_h264.num_units_in_tick;
956 if (height_in_mbs*16 - ENCODER_HEIGHT(h264_encoder)) {
957 seq_h264.frame_cropping_flag = 1;
958 seq_h264.frame_crop_left_offset = 0;
959 seq_h264.frame_crop_right_offset = 0;
960 seq_h264.frame_crop_top_offset = 0;
961 seq_h264.frame_crop_bottom_offset =
962 (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_h264.frame_mbs_only_flag + 1));
964 seq_h264.pic_order_cnt_type = 0; // pic order cnt
965 seq_h264.direct_8x8_inference_flag = 0;
966 seq_h264.log2_max_frame_num_minus4 = 4; // log2(seq_h264.intra_period)-3 : 0
967 seq_h264.log2_max_pic_order_cnt_lsb_minus4 = seq_h264.log2_max_frame_num_minus4+2;
968 seq_h264.vui_flag = 0; // 0? or 1?
970 va_status = vaCreateBuffer(va_dpy, context_id,
971 VAEncSequenceParameterBufferType,
973 &seq_h264, &h264_prv->seq_parameter);
974 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
975 FALSE, "alloc seq-buffer failed.");
977 /*pack sps header buffer/data */
978 if (NULL == h264_prv->sps_data) {
979 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
980 guint32 length_in_bits, offset_in_bytes;
981 guint8 *packed_seq_buffer = NULL;
982 H264Bitstream bitstream;
983 h264_bitstream_init(&bitstream, 128*8);
984 h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
985 h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
986 h264_bitstream_write_sps(&bitstream, &seq_h264);
987 ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
988 length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
989 packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
990 //h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
991 //GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4;
992 //memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, (length_in_bits+7)/8-4);
995 packed_header_param_buffer.type = VAEncPackedHeaderSPS;
996 packed_header_param_buffer.insert_emulation_bytes = 1;
997 packed_header_param_buffer.skip_emulation_check_count = 5;
998 packed_header_param_buffer.num_headers = 1;
999 packed_header_param_buffer.length_in_bits = &length_in_bits;
1000 packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
1001 va_status = vaCreateBuffer(va_dpy,
1003 VAEncPackedHeaderParameterBufferType,
1004 sizeof(packed_header_param_buffer), 1,
1005 &packed_header_param_buffer,
1006 &h264_prv->packed_sps_par_buf);
1007 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1009 "EncPackedSeqHeaderParameterBuffer failed");
1010 va_status = vaCreateBuffer(va_dpy,
1012 VAEncPackedHeaderDataBufferType,
1013 (length_in_bits + 7) / 8, 1,
1015 &h264_prv->packed_sps_data_buf);
1016 h264_bitstream_destroy(&bitstream, TRUE);
1017 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1019 "EncPackedSeqHeaderDataBuffer failed");
1027 h264_recreate_pic_param(GstH264Encoder *h264_encoder,
1028 VADisplay va_dpy, VAContextID context_id,
1029 VABufferID coded_buf)
1031 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1032 VAEncPictureParameterBufferH264 pic_h264;
1033 gboolean ret = TRUE;
1034 VAStatus va_status = VA_STATUS_SUCCESS;
1036 VAAPI_UNUSED_ARG(va_status);
1037 memset(&pic_h264, 0, sizeof(pic_h264));
1038 pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
1039 pic_h264.CurrPic.TopFieldOrderCnt = h264_prv->cur_display_num * 2; // ??? /**/
1040 pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
1041 pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
1042 pic_h264.ReferenceFrames[2].picture_id = VA_INVALID_ID;
1043 pic_h264.CodedBuf = coded_buf;
1045 pic_h264.seq_parameter_set_id = 0;
1046 pic_h264.pic_parameter_set_id = 0;
1047 pic_h264.last_picture = 0;
1048 pic_h264.frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ?
1049 (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num);
1050 pic_h264.coding_type = 0;
1051 pic_h264.pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26);
1052 pic_h264.num_ref_idx_l0_active_minus1 = 0;
1053 pic_h264.num_ref_idx_l1_active_minus1 = 0;
1054 pic_h264.pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I);
1055 pic_h264.pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B);
1056 pic_h264.pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC;
1057 pic_h264.pic_fields.bits.weighted_pred_flag = 0;
1058 pic_h264.pic_fields.bits.weighted_bipred_idc = 0;
1059 pic_h264.pic_fields.bits.transform_8x8_mode_flag = 1;
1060 pic_h264.pic_fields.bits.deblocking_filter_control_present_flag = 1;
1062 char *frame_type = "I";
1063 if (h264_prv->cur_slice_type == SLICE_TYPE_P)
1065 if (h264_prv->cur_slice_type == SLICE_TYPE_B)
1067 ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
1068 frame_type, pic_h264.frame_num, pic_h264.CurrPic.TopFieldOrderCnt);
1070 if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
1071 vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
1072 h264_prv->pic_parameter = VA_INVALID_ID;
1074 va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
1075 sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
1077 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
1078 FALSE, "creating pic-param buffer failed.");
1080 //if (NULL == h264_prv->pps_data) {
1081 if (VA_INVALID_ID == h264_prv->packed_pps_data_buf) {
1082 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
1083 guint32 length_in_bits, offset_in_bytes;
1084 guint8 *packed_pic_buffer = NULL;
1085 H264Bitstream bitstream;
1086 h264_bitstream_init(&bitstream, 128*8);
1087 h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
1088 h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_PPS);
1089 h264_bitstream_write_pps(&bitstream, &pic_h264);
1090 ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
1091 length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
1092 packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
1093 //h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
1094 //GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4;
1095 //memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, (length_in_bits+7)/8-4);
1097 offset_in_bytes = 0;
1098 packed_header_param_buffer.type = VAEncPackedHeaderPPS;
1099 packed_header_param_buffer.insert_emulation_bytes = 1;
1100 packed_header_param_buffer.skip_emulation_check_count = 5;
1101 packed_header_param_buffer.num_headers = 1;
1102 packed_header_param_buffer.length_in_bits = &length_in_bits;
1103 packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
1105 va_status = vaCreateBuffer(va_dpy,
1107 VAEncPackedHeaderParameterBufferType,
1108 sizeof(packed_header_param_buffer), 1,
1109 &packed_header_param_buffer,
1110 &h264_prv->packed_pps_par_buf);
1111 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1113 "EncPackedPicHeaderParameterBuffer failed");
1115 va_status = vaCreateBuffer(va_dpy,
1117 VAEncPackedHeaderDataBufferType,
1118 (length_in_bits + 7) / 8, 1,
1120 &h264_prv->packed_pps_data_buf);
1121 h264_bitstream_destroy(&bitstream, TRUE);
1122 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1124 "EncPackedPicHeaderDataBuffer failed");
1133 h264_recreate_slice_param(GstH264Encoder *h264_encoder,
1134 VADisplay va_dpy, VAContextID context_id)
1136 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1137 VAEncSliceParameterBufferH264 *slice_h264 = NULL;
1139 gboolean ret = TRUE;
1140 VAStatus va_status = VA_STATUS_SUCCESS;
1142 width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
1145 guint32 last_row_num = 0;
1146 guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
1148 memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
1149 for (i = 0; i < h264_encoder->slice_num; ++i) {
1150 slice_h264 = &h264_prv->slice_param_buffers[i];
1152 slice_h264->starting_macroblock_address = last_row_num*width_in_mbs;
1153 slice_h264->number_of_mbs = width_in_mbs*h264_prv->default_slice_height;
1154 last_row_num += h264_prv->default_slice_height;
1155 if (slice_mod_num) {
1156 slice_h264->number_of_mbs += width_in_mbs;
1160 slice_h264->pic_parameter_set_id = 0;
1161 slice_h264->slice_type = h264_prv->cur_slice_type;
1162 slice_h264->direct_spatial_mv_pred_flag = 0;
1163 slice_h264->num_ref_idx_l0_active_minus1 = 0;
1164 slice_h264->num_ref_idx_l1_active_minus1 = 0;
1165 slice_h264->cabac_init_idc = 0;
1166 slice_h264->slice_qp_delta = 0;
1167 slice_h264->disable_deblocking_filter_idc = 0;
1168 slice_h264->slice_alpha_c0_offset_div2 = 2;
1169 slice_h264->slice_beta_offset_div2 = 2;
1170 slice_h264->idr_pic_id = 0;
1172 slice_h264->ref_pic_list_modification_flag_l0 = 0;
1173 slice_h264->ref_pic_list_modification_flag_l1 = 0;
1176 ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
1178 if (VA_INVALID_ID != h264_prv->slice_parameter) {
1179 vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
1180 h264_prv->slice_parameter = VA_INVALID_ID;
1182 va_status = vaCreateBuffer(va_dpy,
1184 VAEncSliceParameterBufferType,
1185 sizeof(h264_prv->slice_param_buffers[0]),
1186 h264_encoder->slice_num,
1187 h264_prv->slice_param_buffers,
1188 &h264_prv->slice_parameter);
1189 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
1190 FALSE, "creating slice-parameters buffer failed.");
1196 static EncoderStatus
1197 gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
1198 GstVaapiContext *context, GstVaapiSurface *surface,
1199 guint frame_index, VABufferID coded_buf, gboolean *is_key)
1201 EncoderStatus ret = ENCODER_NO_ERROR;
1202 VAStatus va_status = VA_STATUS_SUCCESS;
1203 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1204 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1205 VABufferID va_buffers[64];
1206 guint32 va_buffers_count = 0;
1207 gboolean is_params_ok = TRUE;
1209 gboolean is_locked = FALSE;
1211 ENCODER_ASSERT(display && context);
1212 VADisplay va_dpy = gst_vaapi_display_get_display(display);
1213 VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
1215 *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
1217 if (!h264_prv->ref_surface1) {
1218 h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
1219 ENCODER_CHECK_STATUS(h264_prv->ref_surface1,
1220 ENCODER_SURFACE_ERR,
1221 "reference surface, h264_pop_free_surface failed.");
1223 if (!h264_prv->ref_surface2) {
1224 h264_prv->ref_surface2 = gst_vaapi_context_get_surface(context);
1225 ENCODER_CHECK_STATUS(h264_prv->ref_surface2,
1226 ENCODER_SURFACE_ERR,
1227 "reference surface, h264_pop_free_surface failed.");
1229 if (!h264_prv->recon_surface) {
1230 h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
1231 ENCODER_CHECK_STATUS(h264_prv->recon_surface,
1232 ENCODER_SURFACE_ERR,
1233 "reconstructed surface, h264_pop_free_surface failed.");
1236 if (SLICE_TYPE_P == h264_prv->cur_slice_type) {
1237 h264_swap_surface(&h264_prv->ref_surface1, &h264_prv->ref_surface2);
1240 /* set sequence parameters, need set every time */
1241 is_params_ok = h264_recreate_seq_param(h264_encoder, va_dpy, context_id);
1242 ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1243 "h264_recreate_seq_param failed");
1244 /* set pic_parameters*/
1245 is_params_ok = h264_recreate_pic_param(h264_encoder, va_dpy, context_id, coded_buf);
1246 ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1247 "h264_recreate_pic_param failed");
1248 /* set slice parameters, support multiple slices */
1249 is_params_ok = h264_recreate_slice_param(h264_encoder, va_dpy, context_id);
1250 ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1251 "h264_recreate_slice_param failed");
1254 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
1256 /*render all buffers*/
1257 if (VA_INVALID_ID != h264_prv->seq_parameter) {
1258 va_buffers[va_buffers_count++] = h264_prv->seq_parameter;
1260 if (VA_INVALID_ID != h264_prv->pic_parameter) {
1261 va_buffers[va_buffers_count++] = h264_prv->pic_parameter;
1263 if (VA_INVALID_ID != h264_prv->slice_parameter) {
1264 va_buffers[va_buffers_count++] = h264_prv->slice_parameter;
1266 if (SLICE_TYPE_I == h264_prv->cur_slice_type) {
1267 if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
1268 va_buffers[va_buffers_count++] = h264_prv->packed_sps_par_buf;
1270 if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
1271 va_buffers[va_buffers_count++] = h264_prv->packed_sps_data_buf;
1273 if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
1274 va_buffers[va_buffers_count++] = h264_prv->packed_pps_par_buf;
1276 if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
1277 va_buffers[va_buffers_count++] = h264_prv->packed_pps_data_buf;
1281 va_status = vaRenderPicture(va_dpy, context_id, va_buffers, va_buffers_count);
1282 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR,
1283 "vaRenderH264Picture failed.");
1285 /*after finished, swap recon and surface2*/
1286 if (SLICE_TYPE_P == h264_prv->cur_slice_type ||
1287 SLICE_TYPE_I == h264_prv->cur_slice_type) {
1288 h264_swap_surface(&h264_prv->recon_surface, &h264_prv->ref_surface2);
1292 ENCODER_RELEASE_DISPLAY_LOCK(display);
1299 gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
1302 VABufferID *coded_buf)
1304 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
1305 GstBuffer *ret_buffer;
1307 const guint8 *nal_start;
1310 ret_buffer = gst_buffer_new();
1311 ENCODER_ASSERT(ret_buffer);
1312 H264Bitstream bitstream;
1313 h264_bitstream_init(&bitstream, (frame_size+32)*8);
1314 h264_bitstream_align(&bitstream, 0);
1315 ENCODER_ASSERT(bitstream.bit_size == 0);
1317 if (!h264_prv->es_flag) { /*nal format*/
1318 h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
1319 ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
1320 } else { /* elementary format */
1321 frame_end = frame + frame_size;
1324 while((nal_start = h264_next_nal(nal_start, frame_end-nal_start, &nal_size)) != NULL) {
1325 ENCODER_ASSERT(nal_size);
1327 nal_start += nal_size;
1330 h264_bitstream_write_uint(&bitstream, nal_size, 32);
1331 h264_bitstream_write_byte_array(&bitstream, nal_start, nal_size);
1332 nal_start += nal_size;
1335 h264_bitstream_align(&bitstream, 0);
1337 GST_BUFFER_MALLOCDATA(ret_buffer) =
1338 GST_BUFFER_DATA(ret_buffer) = BIT_STREAM_BUFFER(&bitstream);
1339 GST_BUFFER_SIZE(ret_buffer) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1340 h264_bitstream_destroy(&bitstream, FALSE);
1345 static EncoderStatus
1346 h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size)
1348 const guint8 *end = buf + size;
1349 const guint8 *nal_start = buf;
1350 guint32 nal_size = 0;
1352 GstBuffer *sps = NULL, *pps = NULL;
1354 while((!sps || !pps) && (nal_start = h264_next_nal(nal_start, end-nal_start, &nal_size)) != NULL) {
1356 nal_start += nal_size;
1360 nal_type = (*nal_start)&0x1F;
1363 sps = gst_buffer_new_and_alloc(nal_size);
1364 memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
1365 gst_buffer_replace(&h264_prv->sps_data, sps);
1366 gst_buffer_unref(sps); /*don't set to NULL*/
1371 pps = gst_buffer_new_and_alloc(nal_size);
1372 memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
1373 gst_buffer_replace(&h264_prv->pps_data, pps);
1374 gst_buffer_unref(pps);
1381 nal_start += nal_size;
1385 return ENCODER_DATA_NOT_READY;
1387 return ENCODER_NO_ERROR;
1391 gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
1393 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
1394 if (!h264_prv->sps_data || !h264_prv->pps_data) {
1395 h264_encoder_read_sps_pps(h264_prv, buf, size);
1397 if (h264_prv->sps_data && h264_prv->pps_data) {
1398 gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
1404 h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
1405 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc)
1407 ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
1408 ENCODER_ASSERT(sps_size >= 4);
1412 /*skip sps_data[0], nal_type*/
1413 *profile_idc = sps_data[1];
1414 *profile_comp = sps_data[2];
1415 *level_idc = sps_data[3];
1420 static EncoderStatus
1421 gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
1422 GstVaapiContext *context, GList **coded_pics)
1424 GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
1425 EncoderStatus ret = ENCODER_NO_ERROR;
1426 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1428 //h264_prv->frame_count = 0;
1429 h264_prv->cur_display_num = 0;
1430 h264_prv->cur_decode_num = 0;
1431 h264_prv->cur_slice_type = SLICE_TYPE_I;
1432 h264_prv->gop_count = g_queue_get_length(h264_prv->queued_buffers);
1433 //gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
1440 static int draw_picture(int width, int height,
1441 unsigned char *Y_start,
1442 unsigned char *U_start,
1443 unsigned char *V_start,
1444 int UV_interleave, int box_width, int row_shift);
1446 int main_test(int argc, char* argv[])
1448 EncoderStatus ret = ENCODER_NO_ERROR;
1449 GstVaapiEncoder *encoder = NULL;
1451 GList *coded_pics = NULL;
1452 GstBuffer **raw_buffer = NULL;
1453 const guint32 raw_buffer_num = 20;
1455 GstBuffer *tmp_buffer;
1457 guint32 i = 0, k = 0;
1459 gst_init (&argc, &argv);
1462 if (!g_thread_supported ())
1463 g_thread_init (NULL);
1465 GstH264Encoder *h264_encoder = gst_h264_encoder_new();
1466 encoder = GST_VAAPI_ENCODER(h264_encoder);
1467 ENCODER_ASSERT(encoder);
1469 h264_encoder->profile = 64;
1470 h264_encoder->level = 30;
1471 encoder->width = 1280;
1472 encoder->height = 720;
1473 encoder->frame_rate = 10;
1474 h264_encoder->bitrate = 512*1000;
1475 h264_encoder->intra_period = 30;
1476 ret = gst_vaapi_encoder_initialize(encoder);
1477 ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
1478 ret = gst_vaapi_encoder_open(encoder, NULL);
1479 ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
1481 guint32 buffer_size = encoder->width * encoder->width *3 /2;
1482 guint32 y_width = encoder->width, y_size = encoder->width * encoder->height;
1483 guint32 u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
1484 guint32 v_width = encoder->width/2;
1485 guint8 *y_src, *u_src, *v_src;
1491 VAAPI_UNUSED_ARG(v_width);
1492 VAAPI_UNUSED_ARG(u_width);
1493 VAAPI_UNUSED_ARG(y_width);
1494 raw_buffer = (GstBuffer**)g_malloc0(raw_buffer_num*sizeof(GstBuffer*));
1495 for (i = 0; i < raw_buffer_num; i++) {
1496 raw_buffer[i] = gst_buffer_new_and_alloc(buffer_size);
1497 y_src = GST_BUFFER_DATA(raw_buffer[i]);
1498 u_src = y_src + y_size;
1499 v_src = u_src + u_size;
1501 draw_picture(encoder->width, encoder->height, y_src, u_src, v_src, 0, box_width, row_shift);
1503 if (row_shift==(2*box_width)) row_shift= 0;
1506 FILE *fp = fopen("tmp.h264", "wb");
1511 for (i = 0; i < 50; i++) {
1513 ret = gst_vaapi_encoder_encode(encoder, raw_buffer[k], &coded_pics);
1514 ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
1516 if (k >= raw_buffer_num) k = 0;
1518 while (coded_pics) {
1519 tmp_buffer = coded_pics->data;
1520 coded_pics = g_list_remove(coded_pics, tmp_buffer);
1521 fwrite(GST_BUFFER_DATA(tmp_buffer), GST_BUFFER_SIZE(tmp_buffer), 1, fp);
1522 printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8));
1523 gst_buffer_unref(tmp_buffer);
1528 ret = gst_vaapi_encoder_close(encoder);
1529 ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
1531 for (i = 0; i < raw_buffer_num; i++) {
1532 gst_buffer_unref(raw_buffer[i]);
1535 gst_vaapi_encoder_unref(encoder);
1541 gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
1543 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1544 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1545 GstBuffer *avc_codec;
1546 const guint32 configuration_version = 0x01;
1547 const guint32 length_size_minus_one = 0x03;
1548 guint32 profile, profile_comp, level_idc;
1550 ENCODER_ASSERT(buffer);
1551 if (!h264_prv->sps_data || !h264_prv->pps_data) {
1552 return ENCODER_DATA_NOT_READY;
1555 if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(h264_prv->sps_data),
1556 GST_BUFFER_SIZE(h264_prv->sps_data),
1557 &profile, &profile_comp, &level_idc))
1560 return ENCODER_DATA_ERR;
1563 H264Bitstream bitstream;
1564 h264_bitstream_init(&bitstream,
1565 (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 32)*8);
1568 h264_bitstream_write_uint(&bitstream, configuration_version, 8);
1569 h264_bitstream_write_uint(&bitstream, profile, 8);
1570 h264_bitstream_write_uint(&bitstream, profile_comp, 8);
1571 h264_bitstream_write_uint(&bitstream, level_idc, 8);
1572 h264_bitstream_write_uint(&bitstream, h264_bit_mask[6], 6); /*111111*/
1573 h264_bitstream_write_uint(&bitstream, length_size_minus_one, 2);
1574 h264_bitstream_write_uint(&bitstream, h264_bit_mask[3], 3); /*111*/
1577 h264_bitstream_write_uint(&bitstream, 1, 5); /* sps count = 1*/
1578 ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
1579 h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->sps_data), 16);
1580 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
1581 GST_BUFFER_SIZE(h264_prv->sps_data));
1584 h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
1585 h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->pps_data), 16);
1586 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
1587 GST_BUFFER_SIZE(h264_prv->pps_data));
1589 avc_codec = gst_buffer_new();
1590 GST_BUFFER_MALLOCDATA(avc_codec) =
1591 GST_BUFFER_DATA(avc_codec) =
1592 BIT_STREAM_BUFFER(&bitstream);
1593 GST_BUFFER_SIZE(avc_codec) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1594 h264_bitstream_destroy(&bitstream, FALSE);
1595 *buffer = avc_codec;
1597 return ENCODER_NO_ERROR;
1601 gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
1603 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1604 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1605 GstBuffer *nal_sps_pps;
1607 ENCODER_ASSERT(buffer);
1608 if (!h264_prv->sps_data || !h264_prv->pps_data) {
1609 return ENCODER_DATA_NOT_READY;
1612 H264Bitstream bitstream;
1613 h264_bitstream_init(&bitstream,
1614 (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 8)*8);
1616 /*0x000001 start code*/
1617 h264_bitstream_write_uint(&bitstream, 0x000001, 24);
1618 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
1619 GST_BUFFER_SIZE(h264_prv->sps_data));
1620 h264_bitstream_write_uint(&bitstream, 0x000001, 24);
1621 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
1622 GST_BUFFER_SIZE(h264_prv->pps_data));
1624 nal_sps_pps = gst_buffer_new();
1625 GST_BUFFER_MALLOCDATA(nal_sps_pps) =
1626 GST_BUFFER_DATA(nal_sps_pps) =
1627 BIT_STREAM_BUFFER(&bitstream);
1628 GST_BUFFER_SIZE(nal_sps_pps) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1629 h264_bitstream_destroy(&bitstream, FALSE);
1630 *buffer = nal_sps_pps;
1631 return ENCODER_NO_ERROR;
1635 h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
1637 bitstream->bit_size = 0;
1638 bitstream->buffer = NULL;
1639 bitstream->max_bit_capability = 0;
1640 if (bit_capability) {
1641 h264_bitstream_auto_grow(bitstream, bit_capability);
1646 h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size)
1648 gboolean ret = TRUE;
1649 guint32 byte_pos, bit_offset;
1657 VAAPI_UNUSED_ARG(ret);
1658 ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, bit_size),
1660 "h264_bitstream_auto_grow failed.");
1661 byte_pos = (bitstream->bit_size>>3);
1662 bit_offset = (bitstream->bit_size&0x07);
1663 cur_byte = bitstream->buffer + byte_pos;
1664 ENCODER_ASSERT(bit_offset < 8 && bitstream->bit_size <= bitstream->max_bit_capability);
1667 fill_bits = ((8-bit_offset) < bit_size ? (8-bit_offset) : bit_size);
1668 bit_size -= fill_bits;
1669 bitstream->bit_size += fill_bits;
1671 *cur_byte |= ((value>>bit_size) & h264_bit_mask[fill_bits])<<(8-bit_offset-fill_bits);
1675 ENCODER_ASSERT(cur_byte <= bitstream->buffer + bitstream->max_bit_capability/8);
1681 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value)
1683 guint32 bit_offset, bit_left;
1685 bit_offset = (bitstream->bit_size&0x07);
1689 bit_left = 8 - bit_offset;
1690 if (value) value = h264_bit_mask[bit_left];
1691 return h264_bitstream_write_uint(bitstream, value, bit_left);
1696 h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size)
1698 gboolean ret = TRUE;
1703 VAAPI_UNUSED_ARG(ret);
1704 ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, byte_size<<3),
1706 "h264_bitstream_auto_grow failed.");
1707 if (0 == (bitstream->bit_size&0x07)) {
1708 memcpy(&bitstream->buffer[bitstream->bit_size>>3], buf, byte_size);
1709 bitstream->bit_size += (byte_size<<3);
1713 h264_bitstream_write_uint(bitstream, *buf, 8);
1724 h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value)
1726 gboolean ret = TRUE;
1727 guint32 size_in_bits = 0;
1728 guint32 tmp_value = ++value;
1733 ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1),
1735 "h264_bitstream_write_ue failed.");
1736 ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits),
1738 "h264_bitstream_write_ue failed.");
1745 h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value)
1747 gboolean ret = TRUE;
1751 new_val = -(value<<1);
1753 new_val = (value<<1) - 1;
1756 ENCODER_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val),
1758 "h264_bitstream_write_se failed.");
1765 h264_bitstream_write_trailing_bits(H264Bitstream *bitstream)
1767 h264_bitstream_write_uint(bitstream, 1, 1);
1768 h264_bitstream_align(bitstream, 0);
1773 h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag)
1775 if (bitstream->buffer && free_flag) {
1776 free (bitstream->buffer);
1778 bitstream->buffer = NULL;
1779 bitstream->bit_size = 0;
1780 bitstream->max_bit_capability = 0;
1784 h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size)
1786 guint32 new_bit_size = extra_bit_size + bitstream->bit_size;
1789 ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
1790 if (new_bit_size <= bitstream->max_bit_capability) {
1794 new_bit_size = ((new_bit_size + H264_BITSTREAM_ALLOC_ALIGN_MASK)
1795 &(~H264_BITSTREAM_ALLOC_ALIGN_MASK));
1796 ENCODER_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
1797 clear_pos = ((bitstream->bit_size+7)>>3);
1798 bitstream->buffer = realloc(bitstream->buffer, new_bit_size>>3);
1799 memset(bitstream->buffer+clear_pos, 0, (new_bit_size>>3)-clear_pos);
1800 bitstream->max_bit_capability = new_bit_size;
1805 h264_bitstream_write_nal_header(H264Bitstream *bitstream,
1806 guint nal_ref_idc, guint nal_unit_type)
1808 h264_bitstream_write_uint(bitstream, 0, 1);
1809 h264_bitstream_write_uint(bitstream, nal_ref_idc, 2);
1810 h264_bitstream_write_uint(bitstream, nal_unit_type, 5);
1815 h264_bitstream_write_sps(H264Bitstream *bitstream,
1816 VAEncSequenceParameterBufferH264 *seq)
1818 guint32 constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag;
1819 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
1821 guint32 b_qpprime_y_zero_transform_bypass = (seq->rate_control_method == BR_CQP);
1822 guint32 residual_color_transform_flag = 0;
1823 guint32 pic_height_in_map_units = (seq->frame_mbs_only_flag ?
1824 seq->picture_height_in_mbs :
1825 seq->picture_height_in_mbs/2);
1826 guint32 mb_adaptive_frame_field = !seq->frame_mbs_only_flag;
1829 constraint_set0_flag = seq->profile_idc == H264_PROFILE_BASELINE;
1830 constraint_set1_flag = seq->profile_idc <= H264_PROFILE_MAIN;
1831 constraint_set2_flag = 0;
1832 constraint_set3_flag = 0;
1834 h264_bitstream_write_uint(bitstream, seq->profile_idc, 8); /* profile_idc */
1835 h264_bitstream_write_uint(bitstream, constraint_set0_flag, 1); /* constraint_set0_flag */
1836 h264_bitstream_write_uint(bitstream, constraint_set1_flag, 1); /* constraint_set1_flag */
1837 h264_bitstream_write_uint(bitstream, constraint_set2_flag, 1); /* constraint_set2_flag */
1838 h264_bitstream_write_uint(bitstream, constraint_set3_flag, 1); /* constraint_set3_flag */
1839 h264_bitstream_write_uint(bitstream, 0, 4); /* reserved_zero_4bits */
1840 h264_bitstream_write_uint(bitstream, seq->level_idc, 8); /* level_idc */
1841 h264_bitstream_write_ue(bitstream, seq->seq_parameter_set_id); /* seq_parameter_set_id */
1843 if (seq->profile_idc >= H264_PROFILE_HIGH) {
1844 /* for high profile */
1846 h264_bitstream_write_ue(bitstream, seq->seq_fields.bits.chroma_format_idc); /* chroma_format_idc = 1, 4:2:0*/
1847 if (3 == seq->seq_fields.bits.chroma_format_idc) {
1848 h264_bitstream_write_uint(bitstream, residual_color_transform_flag, 1);
1850 h264_bitstream_write_ue(bitstream, seq->bit_depth_luma_minus8); /* bit_depth_luma_minus8 */
1851 h264_bitstream_write_ue(bitstream, seq->bit_depth_chroma_minus8); /* bit_depth_chroma_minus8 */
1852 h264_bitstream_write_uint(bitstream, b_qpprime_y_zero_transform_bypass, 1); /* b_qpprime_y_zero_transform_bypass */
1853 ENCODER_ASSERT(seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
1854 h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1); /*seq_scaling_matrix_present_flag */
1856 if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) {
1857 for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); i++) {
1858 h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_list_present_flag, 1);
1859 if (seq->seq_fields.bits.seq_scaling_list_present_flag) {
1861 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1*/
1867 h264_bitstream_write_ue(bitstream, seq->log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
1868 h264_bitstream_write_ue(bitstream, seq->pic_order_cnt_type); /* pic_order_cnt_type */
1870 if (seq->pic_order_cnt_type == 0)
1871 h264_bitstream_write_ue(bitstream, seq->log2_max_pic_order_cnt_lsb_minus4);/* log2_max_pic_order_cnt_lsb_minus4 */
1872 else if (seq->pic_order_cnt_type == 1) {
1874 h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
1875 h264_bitstream_write_se(bitstream, seq->offset_for_non_ref_pic);
1876 h264_bitstream_write_se(bitstream, seq->offset_for_top_to_bottom_field);
1877 h264_bitstream_write_ue(bitstream, seq->num_ref_frames_in_pic_order_cnt_cycle);
1878 for ( i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) {
1879 h264_bitstream_write_se(bitstream, seq->offset_for_ref_frame[i]);
1883 h264_bitstream_write_ue(bitstream, seq->max_num_ref_frames); /* num_ref_frames */
1884 h264_bitstream_write_uint(bitstream, gaps_in_frame_num_value_allowed_flag, 1); /* gaps_in_frame_num_value_allowed_flag */
1886 h264_bitstream_write_ue(bitstream, seq->picture_width_in_mbs - 1); /* pic_width_in_mbs_minus1 */
1887 h264_bitstream_write_ue(bitstream, pic_height_in_map_units - 1); /* pic_height_in_map_units_minus1 */
1888 h264_bitstream_write_uint(bitstream, seq->frame_mbs_only_flag, 1); /* frame_mbs_only_flag */
1890 if (!seq->frame_mbs_only_flag) { //ONLY mbs
1892 h264_bitstream_write_uint(bitstream, mb_adaptive_frame_field, 1);
1895 h264_bitstream_write_uint(bitstream, 0, 1); /* direct_8x8_inference_flag */
1896 h264_bitstream_write_uint(bitstream, seq->frame_cropping_flag, 1); /* frame_cropping_flag */
1898 if (seq->frame_cropping_flag) {
1899 h264_bitstream_write_ue(bitstream, seq->frame_crop_left_offset); /* frame_crop_left_offset */
1900 h264_bitstream_write_ue(bitstream, seq->frame_crop_right_offset); /* frame_crop_right_offset */
1901 h264_bitstream_write_ue(bitstream, seq->frame_crop_top_offset); /* frame_crop_top_offset */
1902 h264_bitstream_write_ue(bitstream, seq->frame_crop_bottom_offset); /* frame_crop_bottom_offset */
1904 ENCODER_ASSERT(seq->vui_flag == 0);
1905 h264_bitstream_write_uint(bitstream, seq->vui_flag, 1); /* vui_parameters_present_flag */
1906 if (seq->vui_flag) {
1907 /*FIXME, to write vui parameters*/
1909 h264_bitstream_write_trailing_bits(bitstream); /* rbsp_trailing_bits */
1915 h264_bitstream_write_pps(H264Bitstream *bitstream,
1916 VAEncPictureParameterBufferH264 *pic)
1918 guint32 num_slice_groups_minus1 = 0;
1919 guint32 pic_init_qs_minus26 = 0;
1920 guint32 redundant_pic_cnt_present_flag = 0;
1922 h264_bitstream_write_ue(bitstream, pic->pic_parameter_set_id); /* pic_parameter_set_id */
1923 h264_bitstream_write_ue(bitstream, pic->seq_parameter_set_id); /* seq_parameter_set_id */
1924 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.entropy_coding_mode_flag, 1); /* entropy_coding_mode_flag */
1925 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_order_present_flag, 1); /* pic_order_present_flag */
1926 h264_bitstream_write_ue(bitstream, num_slice_groups_minus1); /*slice_groups-1*/
1928 if (num_slice_groups_minus1 > 0) {
1932 h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l0_active_minus1);
1933 h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l1_active_minus1);
1934 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.weighted_pred_flag, 1);
1935 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.weighted_bipred_idc, 2);
1936 h264_bitstream_write_se(bitstream, pic->pic_init_qp-26); /* pic_init_qp_minus26 */
1937 h264_bitstream_write_se(bitstream, pic_init_qs_minus26); /* pic_init_qs_minus26 */
1938 h264_bitstream_write_se(bitstream, pic->chroma_qp_index_offset); /*chroma_qp_index_offset*/
1940 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.deblocking_filter_control_present_flag, 1);
1941 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.constrained_intra_pred_flag, 1);
1942 h264_bitstream_write_uint(bitstream, redundant_pic_cnt_present_flag, 1);
1945 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.transform_8x8_mode_flag, 1);
1946 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
1947 if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) {
1952 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag));
1954 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_list_present_flag, 1);
1959 h264_bitstream_write_se(bitstream, pic->second_chroma_qp_index_offset);
1960 h264_bitstream_write_trailing_bits(bitstream);
1965 static const guint8 *
1966 h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
1968 const guint8 *cur = buffer;
1969 const guint8 *end = buffer + len;
1970 const guint8 *nal_start = NULL;
1971 guint32 flag = 0xFFFFFFFF;
1972 guint32 nal_start_len = 0;
1974 ENCODER_ASSERT(len >= 0 && buffer && nal_size);
1977 nal_start = (len ? buffer : NULL);
1981 /*locate head postion*/
1982 if (!buffer[0] && !buffer[1]) {
1983 if (buffer[2] == 1) { // 0x000001
1985 } else if (!buffer[2] && len >=4 && buffer[3] == 1) { //0x00000001
1989 nal_start = buffer + nal_start_len;
1992 /*find next nal start position*/
1994 flag = ((flag<<8) | ((*cur++)&0xFF));
1995 if (flag == 0x00000001) {
1996 *nal_size = cur - 4 - nal_start;
1998 } else if ((flag&0x00FFFFFF) == 0x00000001) {
1999 *nal_size = cur - 3 - nal_start;
2004 *nal_size = end - nal_start;
2005 if (nal_start >= end) {
2012 static int draw_picture(int width, int height,
2013 unsigned char *Y_start,
2014 unsigned char *U_start,
2015 unsigned char *V_start,
2016 int UV_interleave, int box_width, int row_shift)
2020 int Y_pitch = width;
2021 int U_pitch = width/2;
2022 int V_pitch = width/2;
2025 for (row=0;row<height;row++) {
2026 unsigned char *Y_row = Y_start + row * Y_pitch;
2029 ypos = (row / box_width) & 0x1;
2031 /* fill garbage data into the other field */
2032 if (((field == 1) && (row &1))
2033 || ((field == 2) && ((row &1)==0))) {
2034 memset(Y_row, 0xff, width);
2038 for (jj=0; jj<width; jj++) {
2039 xpos = ((row_shift + jj) / box_width) & 0x1;
2041 if ((xpos == 0) && (ypos == 0))
2043 if ((xpos == 1) && (ypos == 1))
2046 if ((xpos == 1) && (ypos == 0))
2048 if ((xpos == 0) && (ypos == 1))
2054 for( row =0; row < height/2; row++) {
2055 unsigned short value = 0x80;
2057 /* fill garbage data into the other field */
2058 if (((field == 1) && (row &1))
2059 || ((field == 2) && ((row &1)==0))) {
2063 if (UV_interleave) {
2064 unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch);
2066 memset(UV_row, value, width);
2068 unsigned char *U_row = U_start + row * U_pitch;
2069 unsigned char *V_row = V_start + row * V_pitch;
2071 memset (U_row,value,width/2);
2072 memset (V_row,value,width/2);