2 * gstvaapih264encoder.c - H.264 encoder
4 * Copyright (C) 2011 Intel Corporation
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.
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.
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
22 #include "gstvaapih264encoder.h"
27 #include "va/va_x11.h"
31 #include "gst/gstclock.h"
32 #include "gst/gstvalue.h"
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"
41 /* enable old lib va*/
42 //#define _SIMPLE_LIB_VA_
44 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
45 #define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
47 #define SHARE_CODED_BUF 0
49 #define DEFAULT_SURFACE_NUMBER 3
50 #define DEFAULT_CODEDBUF_NUM 5
51 #define DEFAULT_SID_INPUT 0 // suface_ids[0]
53 #define REF_RECON_SURFACE_NUM 2
55 #define ENTROPY_MODE_CAVLC 0
56 #define ENTROPY_MODE_CABAC 1
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
71 NAL_IDR = 5, /* ref_idc != 0 */
72 NAL_SEI = 6, /* ref_idc == 0 */
86 struct _GstH264EncoderPrivate {
87 GstH264Encoder *public;
88 guint32 format; /*NV12, I420,*/
89 gboolean es_flag; /*elementary flag*/
92 GQueue *video_buffer_caches; /*not used for baseline*/
94 GstVaapiSurface *ref_surface1; /* reference buffer*/
95 GstVaapiSurface *ref_surface2; /* for B frames */
96 GstVaapiSurface *recon_surface; /* reconstruct buffer*/
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;
108 VAEncSliceParameterBufferH264 *slice_param_buffers;
110 guint32 default_slice_height;
111 guint32 slice_mod_mb_num;
112 guint32 default_cts_offset;
117 GQueue *queued_buffers; /* GstVaapiVideoBuffers with surface*/
120 guint32 cur_display_num;
121 guint32 cur_decode_num;
122 H264_SLICE_TYPE cur_slice_type;
123 guint64 last_decode_time;
126 G_DEFINE_TYPE(GstH264Encoder, gst_h264_encoder, GST_TYPE_VAAPI_BASE_ENCODER);
130 #define H264_BITSTREAM_ALLOC_ALIGN_MASK 0x0FFF
132 #define BIT_STREAM_BUFFER(stream) ((stream)->buffer)
133 #define BIT_STREAM_BIT_SIZE(stream) ((stream)->bit_size)
135 struct _H264Bitstream {
138 guint32 max_bit_capability;
141 typedef struct _H264Bitstream H264Bitstream;
143 static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
145 static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
146 GstVaapiContext *context, GList **coded_pics);
149 static EncoderStatus gst_h264_encoder_get_avcC_codec_data(
150 GstVaapiEncoder* encoder, GstBuffer **buffer);
151 static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
153 static gboolean gst_h264_validate_parameters(GstVaapiBaseEncoder *encoder);
154 static void gst_h264_encoder_finalize(GObject *object);
155 static void gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
157 static gboolean gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder,
158 GstVaapiDisplay *display, GstVaapiContext *context);
159 static gboolean gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder,
160 GstVaapiDisplay *display, GstVaapiContext *context);
161 static EncoderStatus gst_h264_encoder_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
162 GstVaapiVideoBuffer *display_buf, gboolean need_flush,
163 GstVaapiVideoBuffer **out_buf);
164 static void gst_h264_encoder_frame_failed(GstVaapiBaseEncoder *encoder,
165 GstVaapiVideoBuffer* buffer);
166 static EncoderStatus gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
167 GstVaapiContext *context, GstVaapiSurface *surface,
168 guint frame_index, VABufferID coded_buf, gboolean *is_key);
169 static void gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size);
170 //static EncoderStatus h264_encoder_read_sps_pps(
171 // GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size);
172 static GstBuffer *gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
173 guint8 *frame, guint32 frame_size, VABufferID *coded_buf);
175 /* h264 bitstream functions */
176 static void h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
177 static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
178 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value);
179 static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value);
180 static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value);
181 static gboolean h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
183 static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size);
184 static void h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
185 static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size);
186 static gboolean h264_bitstream_write_sps(H264Bitstream *bitstream, VAEncSequenceParameterBufferH264 *seq);
187 static gboolean h264_bitstream_write_pps(H264Bitstream *bitstream, VAEncPictureParameterBufferH264 *pic);
188 static gboolean h264_bitstream_write_nal_header(H264Bitstream *bitstream,
189 guint nal_ref_idc, guint nal_unit_type);
191 static const guint8 *h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size);
192 static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
193 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
196 gst_h264_encoder_class_init(GstH264EncoderClass *klass)
198 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
199 GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
200 GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
202 g_type_class_add_private(klass, sizeof(GstH264EncoderPrivate));
204 GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug, "gst_va_h264_encoder", 0,
205 "gst_va_h264_encoder element");
207 object_class->finalize = gst_h264_encoder_finalize;
209 base_class->validate_attributes = gst_h264_validate_parameters;
210 base_class->pre_alloc_resource = gst_h264_encoder_alloc_slices;
211 base_class->release_resource = gst_h264_encoder_release_resource;
212 base_class->prepare_next_input_buffer = gst_h264_encoder_prepare_next_buffer;
213 base_class->render_frame = gst_h264_encoder_rendering;
214 base_class->notify_frame = gst_h264_notify_frame;
215 base_class->copy_coded_frame = gst_h264_encoder_copy_coded_buffer;
216 base_class->encode_frame_failed = gst_h264_encoder_frame_failed;
218 encoder_class->flush = gst_h264_encoder_flush;
220 encoder_class->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
221 /* encoder_class->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
224 object_class->set_property = gst_h264_encoder_set_property;
225 object_class->get_property = gst_h264_encoder_get_property;
230 h264_get_va_profile(guint32 profile)
233 case H264_PROFILE_BASELINE:
234 return VAProfileH264Baseline;
236 case H264_PROFILE_MAIN:
237 return VAProfileH264Main;
239 case H264_PROFILE_HIGH:
240 return VAProfileH264High;
249 gst_h264_encoder_init(GstH264Encoder *encoder)
251 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
252 ENCODER_ASSERT(h264_prv);
253 h264_prv->public = encoder;
255 /* init public attributes */
256 gst_h264_encoder_init_public_values(encoder);
257 gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
259 /* init private values*/
260 h264_prv->format = GST_MAKE_FOURCC('N','V','1','2');
261 h264_prv->es_flag = TRUE;
262 //h264_prv->es_flag = FALSE;
264 h264_prv->ref_surface1 = NULL;
265 h264_prv->ref_surface2 = NULL;
266 h264_prv->recon_surface = NULL;
268 h264_prv->seq_parameter = VA_INVALID_ID;
269 h264_prv->pic_parameter = VA_INVALID_ID;
270 h264_prv->slice_parameter = VA_INVALID_ID;
271 h264_prv->packed_sps_par_buf = VA_INVALID_ID;
272 h264_prv->packed_sps_data_buf = VA_INVALID_ID;
273 h264_prv->packed_pps_par_buf = VA_INVALID_ID;
274 h264_prv->packed_pps_data_buf = VA_INVALID_ID;
275 h264_prv->slice_param_buffers = NULL;
276 h264_prv->default_slice_height = 0;
277 h264_prv->slice_mod_mb_num = 0;
279 h264_prv->sps_data = NULL;
280 h264_prv->pps_data = NULL;
282 h264_prv->queued_buffers = g_queue_new();
283 h264_prv->gop_count = 0;
284 h264_prv->cur_display_num = 0;
285 h264_prv->cur_decode_num = 0;
286 h264_prv->cur_slice_type = SLICE_TYPE_I;
287 h264_prv->last_decode_time = 0LL;
288 h264_prv->default_cts_offset = 0;
292 gst_h264_encoder_finalize(GObject *object)
294 /*free private buffers*/
295 GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
296 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(object);
298 if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
299 gst_vaapi_encoder_uninitialize(encoder);
302 if (h264_prv->sps_data) {
303 gst_buffer_unref(h264_prv->sps_data);
304 h264_prv->sps_data = NULL;
306 if (h264_prv->pps_data) {
307 gst_buffer_unref(h264_prv->pps_data);
308 h264_prv->pps_data = NULL;
310 if (h264_prv->slice_param_buffers) {
311 g_free(h264_prv->slice_param_buffers);
312 h264_prv->slice_param_buffers = NULL;
315 if (h264_prv->queued_buffers) {
316 ENCODER_ASSERT(g_queue_is_empty(h264_prv->queued_buffers));
317 g_queue_free(h264_prv->queued_buffers);
318 h264_prv->queued_buffers = NULL;
321 G_OBJECT_CLASS(gst_h264_encoder_parent_class)->finalize(object);
326 gst_h264_encoder_new(void)
328 return GST_H264_ENCODER(g_object_new(GST_TYPE_H264_ENCODER, NULL));
332 gst_h264_encoder_init_public_values(GstH264Encoder* encoder)
334 encoder->profile = 0;
336 encoder->bitrate = 0;
337 encoder->intra_period = 0;
338 encoder->init_qp = -1;
339 encoder->min_qp = -1;
340 encoder->slice_num = 0;
341 encoder->b_frame_num = 0;
345 gst_h264_encoder_set_es_flag(GstH264Encoder* encoder, gboolean es)
347 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
348 h264_prv->es_flag = es;
353 gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder)
355 GstH264Encoder *encoder = GST_H264_ENCODER(base_encoder);
356 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
357 if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) {
360 if (!encoder->profile) {
361 encoder->profile = H264_DEFAULT_PROFILE;
363 gst_vaapi_base_encoder_set_va_profile(base_encoder, h264_get_va_profile(encoder->profile));
364 if (!encoder->level) {
365 if (encoder->profile <= H264_PROFILE_BASELINE)
366 encoder->level = H264_LEVEL_30;
368 encoder->level = H264_LEVEL_41;
370 if (!encoder->intra_period) {
371 encoder->intra_period = H264_DEFAULT_INTRA_PERIOD;
373 if (-1 == encoder->init_qp) {
374 encoder->init_qp = H264_DEFAULT_INIT_QP;
376 if (-1 == encoder->min_qp) {
377 encoder->min_qp = H264_DEFAULT_MIN_QP;
380 if (encoder->min_qp > encoder->init_qp) {
381 encoder->min_qp = encoder->init_qp;
384 /* default compress ratio 1: (4*8*1.5) */
385 if (!encoder->bitrate) {
386 encoder->bitrate = 0; //ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
389 if (!encoder->slice_num) {
390 encoder->slice_num = H264_DEFAULT_SLICE_NUM;
393 /* need calculate slice-num and each slice-height
394 suppose: ((encoder->height+15)/16) = 13, slice_num = 8
395 then: slice_1_height = 2
404 h264_prv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
405 if (0 == h264_prv->default_slice_height) { /* special value */
406 h264_prv->default_slice_height = 1;
407 h264_prv->slice_mod_mb_num = 0;
408 encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
410 h264_prv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
413 if (encoder->b_frame_num) {
414 h264_prv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
416 h264_prv->default_cts_offset = 0;
423 h264_encoder_release_parameters(GstH264Encoder *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
425 VAStatus va_status = VA_STATUS_SUCCESS;
426 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
428 gboolean is_locked = FALSE;
430 ENCODER_ASSERT(display);
431 ENCODER_ASSERT(context);
432 VAAPI_UNUSED_ARG(va_status);
433 VADisplay va_dpy = gst_vaapi_display_get_display(display);
435 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
436 if (VA_INVALID_ID != h264_prv->seq_parameter) {
437 va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
438 h264_prv->seq_parameter = VA_INVALID_ID;
440 if (VA_INVALID_ID != h264_prv->pic_parameter) {
441 va_status = vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
442 h264_prv->pic_parameter = VA_INVALID_ID;
444 if (VA_INVALID_ID != h264_prv->slice_parameter) {
445 va_status = vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
446 h264_prv->slice_parameter = VA_INVALID_ID;
449 if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
450 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_par_buf);
451 h264_prv->packed_sps_par_buf = VA_INVALID_ID;
453 if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
454 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_sps_data_buf);
455 h264_prv->packed_sps_data_buf = VA_INVALID_ID;
457 if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
458 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_par_buf);
459 h264_prv->packed_pps_par_buf = VA_INVALID_ID;
461 if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
462 va_status = vaDestroyBuffer(va_dpy, h264_prv->packed_pps_data_buf);
463 h264_prv->packed_pps_data_buf = VA_INVALID_ID;
466 ENCODER_RELEASE_DISPLAY_LOCK(display);
468 if (h264_prv->slice_param_buffers) {
469 g_free(h264_prv->slice_param_buffers);
470 h264_prv->slice_param_buffers = NULL;
473 if (h264_prv->sps_data) {
474 gst_buffer_unref(h264_prv->sps_data);
475 h264_prv->sps_data = NULL;
477 if (h264_prv->pps_data) {
478 gst_buffer_unref(h264_prv->pps_data);
479 h264_prv->pps_data = NULL;
486 h264_release_queued_buffers(GstH264EncoderPrivate *h264_prv)
488 while (!g_queue_is_empty(h264_prv->queued_buffers)) {
489 GstBuffer* tmp = g_queue_pop_head(h264_prv->queued_buffers);
491 gst_buffer_unref(tmp);
497 gst_h264_encoder_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
499 GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
501 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
503 /* release buffers first */
504 h264_encoder_release_parameters(h264_encoder, display, context);
505 h264_release_queued_buffers(h264_prv);
506 h264_prv->cur_display_num = 0;
507 h264_prv->cur_decode_num = 0;
508 h264_prv->cur_slice_type = SLICE_TYPE_I;
509 h264_prv->gop_count = 0;
510 h264_prv->last_decode_time = 0LL;
511 h264_prv->default_cts_offset = 0;
513 /*remove ref_surface1*/
514 if (h264_prv->ref_surface1) {
516 gst_vaapi_context_put_surface(context, h264_prv->ref_surface1);
518 g_object_unref(h264_prv->ref_surface1);
520 h264_prv->ref_surface1 = NULL;
523 if (h264_prv->ref_surface2) {
525 gst_vaapi_context_put_surface(context, h264_prv->ref_surface2);
527 g_object_unref(h264_prv->ref_surface2);
529 h264_prv->ref_surface2 = NULL;
532 /*remove recon_surface*/
533 if (h264_prv->recon_surface) {
535 gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
537 g_object_unref(h264_prv->recon_surface);
539 h264_prv->recon_surface = NULL;
546 gst_h264_encoder_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display, GstVaapiContext *context)
549 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
550 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
552 h264_prv->slice_param_buffers =
553 #ifdef _SIMPLE_LIB_VA_
554 (VAEncSliceParameterBuffer*)
556 (VAEncSliceParameterBufferH264*)
558 g_malloc0_n(h264_encoder->slice_num,
559 sizeof(h264_prv->slice_param_buffers[0]));
565 gst_h264_encoder_frame_failed(GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer)
567 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
568 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
570 h264_release_queued_buffers(h264_prv);
571 h264_prv->cur_display_num = 0;
572 h264_prv->cur_decode_num = 0;
573 h264_prv->cur_slice_type = SLICE_TYPE_I;
574 h264_prv->gop_count = 0;
575 h264_prv->last_decode_time = 0LL;
579 gst_h264_encoder_prepare_next_buffer(GstVaapiBaseEncoder* encoder,
580 GstVaapiVideoBuffer *display_buf, gboolean need_flush,
581 GstVaapiVideoBuffer **out_buf)
583 EncoderStatus ret = ENCODER_NO_ERROR;
584 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
585 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
586 GstVaapiVideoBuffer *return_buf = NULL;
589 if (NULL == display_buf && g_queue_is_empty(h264_prv->queued_buffers)) {
590 ret = ENCODER_BUFFER_EMPTY;
591 if (h264_prv->gop_count >= h264_encoder->intra_period || need_flush)
592 h264_prv->gop_count = 0;
597 ++h264_prv->gop_count;
598 gst_buffer_ref(GST_BUFFER_CAST(display_buf));
599 h264_prv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
603 if (h264_prv->gop_count == 1) {
604 ENCODER_ASSERT(display_buf);
605 h264_prv->cur_display_num = 0;
606 h264_prv->cur_decode_num = 0;
607 h264_prv->cur_slice_type = SLICE_TYPE_I;
608 return_buf = display_buf;
613 if (h264_encoder->b_frame_num &&
614 h264_prv->gop_count < h264_encoder->intra_period &&
615 g_queue_get_length(h264_prv->queued_buffers) < h264_encoder->b_frame_num
618 g_queue_push_tail(h264_prv->queued_buffers, display_buf);
619 ret = ENCODER_BUFFER_WAITING;
622 h264_prv->cur_slice_type = SLICE_TYPE_P;
623 h264_prv->cur_display_num = h264_prv->gop_count-1;
624 ++h264_prv->cur_decode_num;
625 return_buf = display_buf;
628 return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(h264_prv->queued_buffers);
629 h264_prv->cur_slice_type = SLICE_TYPE_P;
630 h264_prv->cur_display_num = h264_prv->gop_count - 1;
631 ++h264_prv->cur_decode_num;
633 return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(h264_prv->queued_buffers);
634 h264_prv->cur_slice_type = SLICE_TYPE_B;
635 h264_prv->cur_display_num = h264_prv->gop_count - 2 - g_queue_get_length(h264_prv->queued_buffers);
640 *out_buf = return_buf;
641 /* calculate cts/pts/dts */
644 pts = GST_BUFFER_TIMESTAMP(return_buf);
645 tmp_next_buf = (GstVaapiVideoBuffer*)g_queue_peek_head(h264_prv->queued_buffers);
647 GST_BUFFER_TIMESTAMP(return_buf) = GST_BUFFER_TIMESTAMP(tmp_next_buf);
648 } else if (SLICE_TYPE_B == h264_prv->cur_slice_type) {
649 GST_BUFFER_TIMESTAMP(return_buf) = h264_prv->last_decode_time;
652 pts += h264_prv->default_cts_offset;
653 if ((gint64)(pts - GST_BUFFER_TIMESTAMP(return_buf)) < 0) {
654 pts = GST_BUFFER_TIMESTAMP(return_buf);
657 GST_BUFFER_OFFSET_END(return_buf) = pts;
658 GST_BUFFER_TIMESTAMP(return_buf) = pts;
666 #ifdef _SIMPLE_LIB_VA_
668 gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
669 GstVaapiContext *context, GstVaapiSurface *surface,
670 guint frame_index, VABufferID coded_buf, gboolean *is_key)
672 EncoderStatus ret = ENCODER_NO_ERROR;
673 VAStatus va_status = VA_STATUS_SUCCESS;
674 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
675 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
676 VAEncPictureParameterBufferH264 pic_h264;
677 VAEncSliceParameterBuffer *slice_h264 = NULL;
679 gboolean is_locked = FALSE;
681 ENCODER_ASSERT(display && context);
682 VADisplay va_dpy = gst_vaapi_display_get_display(display);
683 VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
685 *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
688 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
689 /*handle first surface_index*/
690 /*only need first frame*/
691 if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
692 VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
693 seq_h264.level_idc = h264_encoder->level; /* 3.0 */
694 seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
695 seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
696 seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
698 seq_h264.bits_per_second = h264_encoder->bitrate;
699 seq_h264.frame_rate = ENCODER_FPS(h264_encoder);
700 seq_h264.initial_qp = h264_encoder->init_qp; /*qp_value; 15, 24, 26?*/
701 seq_h264.min_qp = h264_encoder->min_qp; /*1, 6, 10*/
702 seq_h264.basic_unit_size = 0;
703 seq_h264.intra_period = h264_encoder->intra_period;
704 seq_h264.intra_idr_period = h264_encoder->intra_period;
706 va_status = vaCreateBuffer(va_dpy, context_id,
707 VAEncSequenceParameterBufferType,
708 sizeof(seq_h264), 1, &seq_h264, &h264_prv->seq_parameter);
709 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
710 ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.");
711 va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->seq_parameter, 1);
712 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
713 ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.");
716 /* set pic_parameters*/
717 if (!h264_prv->ref_surface1) {
718 h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
719 ENCODER_CHECK_STATUS(h264_prv->ref_surface1, ENCODER_SURFACE_ERR,
720 "reference surface, h264_pop_free_surface failed.");
722 if (!h264_prv->recon_surface) {
723 h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
724 ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR,
725 "reconstructed surface, h264_pop_free_surface failed.");
728 pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
729 pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
730 pic_h264.coded_buf = coded_buf;
731 pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
732 pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
733 pic_h264.last_picture = 0; // last pic or not
735 if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
736 vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
737 h264_prv->pic_parameter = VA_INVALID_ID;
739 va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
740 sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
742 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
743 ENCODER_PICTURE_ERR, "creating pic-param buffer failed.");
745 va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->pic_parameter, 1);
746 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
747 ENCODER_PICTURE_ERR, "rendering pic-param buffer failed.");
749 /* set slice parameters, support multiple slices */
751 guint32 last_row_num = 0;
752 guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
754 memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
755 for (i = 0; i < h264_encoder->slice_num; ++i) {
756 slice_h264 = &h264_prv->slice_param_buffers[i];
757 slice_h264->start_row_number = last_row_num; /* unit MB*/
758 slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
760 ++slice_h264->slice_height;
763 last_row_num += slice_h264->slice_height;
764 slice_h264->slice_flags.bits.is_intra = *is_key;
765 slice_h264->slice_flags.bits.disable_deblocking_filter_idc = 0;
768 ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
770 if (VA_INVALID_ID != h264_prv->slice_parameter) {
771 vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
772 h264_prv->slice_parameter = VA_INVALID_ID;
774 va_status = vaCreateBuffer(va_dpy,
776 VAEncSliceParameterBufferType,
777 sizeof(h264_prv->slice_param_buffers[0]),
778 h264_encoder->slice_num,
779 h264_prv->slice_param_buffers,
780 &h264_prv->slice_parameter);
781 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
782 ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.");
784 va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
785 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
786 ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.");
788 /*after finished, set ref_surface1_index, recon_surface_index */
789 GstVaapiSurface *swap = h264_prv->ref_surface1;
790 h264_prv->ref_surface1 = h264_prv->recon_surface;
791 h264_prv->recon_surface = swap;
794 ENCODER_RELEASE_DISPLAY_LOCK(display);
798 #else /* extended libva, new parameter structures*/
800 static void h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
802 GstVaapiSurface *tmp;
804 g_return_if_fail(s1 && s2);
811 h264_recreate_seq_param(GstH264Encoder *h264_encoder,
812 VADisplay va_dpy, VAContextID context_id)
814 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
815 VAEncSequenceParameterBufferH264 seq_h264 = { 0 };
816 guint width_in_mbs, height_in_mbs;
818 VAStatus va_status = VA_STATUS_SUCCESS;
821 if (VA_INVALID_ID != h264_prv->seq_parameter)
824 width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
825 height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
827 seq_h264.seq_parameter_set_id = 0;
828 seq_h264.profile_idc = h264_encoder->profile;
829 seq_h264.level_idc = h264_encoder->level; /* 3.0 */
830 seq_h264.intra_period = h264_encoder->intra_period;
831 seq_h264.ip_period = 0; // ?
832 seq_h264.max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1); // ?, why 4
833 seq_h264.picture_width_in_mbs = width_in_mbs;
834 seq_h264.picture_height_in_mbs = height_in_mbs;
835 seq_h264.frame_mbs_only_flag = 1;
836 seq_h264.target_usage = 1; // ?
838 if (h264_encoder->init_qp == -1)
839 seq_h264.rate_control_method = BR_CBR;
840 else if (h264_encoder->init_qp == -2)
841 seq_h264.rate_control_method = BR_VBR;
843 ENCODER_ASSERT(h264_encoder->init_qp >= 0 && h264_encoder->init_qp <= 51);
844 seq_h264.rate_control_method = BR_CQP;
847 if (h264_encoder->bitrate> 0)
848 seq_h264.bits_per_second = h264_encoder->bitrate; /* use kbps as input */
850 seq_h264.bits_per_second = 0;
852 if (seq_h264.rate_control_method == BR_VBR) {
853 seq_h264.max_bits_per_second = seq_h264.bits_per_second*1.5;
854 seq_h264.min_bits_per_second = seq_h264.bits_per_second*0.3;
856 seq_h264.initial_hrd_buffer_fullness = 0; // ??
857 seq_h264.hrd_buffer_size = 0;
858 seq_h264.num_units_in_tick = 100;
859 seq_h264.time_scale = ENCODER_FPS(h264_encoder)*2*seq_h264.num_units_in_tick;
861 if (height_in_mbs*16 - ENCODER_HEIGHT(h264_encoder)) {
862 seq_h264.frame_cropping_flag = 1;
863 seq_h264.frame_crop_left_offset = 0;
864 seq_h264.frame_crop_right_offset = 0;
865 seq_h264.frame_crop_top_offset = 0;
866 seq_h264.frame_crop_bottom_offset =
867 (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_h264.frame_mbs_only_flag + 1));
869 seq_h264.pic_order_cnt_type = 0; // pic order cnt
870 seq_h264.direct_8x8_inference_flag = 0;
871 seq_h264.log2_max_frame_num_minus4 = 4; // log2(seq_h264.intra_period)-3 : 0
872 seq_h264.log2_max_pic_order_cnt_lsb_minus4 = seq_h264.log2_max_frame_num_minus4+2;
873 seq_h264.vui_flag = 0; // 0? or 1?
875 va_status = vaCreateBuffer(va_dpy, context_id,
876 VAEncSequenceParameterBufferType,
878 &seq_h264, &h264_prv->seq_parameter);
879 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
880 FALSE, "alloc seq-buffer failed.");
882 /*pack sps header buffer/data */
883 if (NULL == h264_prv->sps_data) {
884 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
885 guint32 length_in_bits, offset_in_bytes;
886 guint8 *packed_seq_buffer = NULL;
887 H264Bitstream bitstream;
888 h264_bitstream_init(&bitstream, 128*8);
889 h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
890 h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
891 h264_bitstream_write_sps(&bitstream, &seq_h264);
892 ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
893 length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
894 packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
895 //h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
896 //GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4;
897 //memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, (length_in_bits+7)/8-4);
900 packed_header_param_buffer.type = VAEncPackedHeaderSPS;
901 packed_header_param_buffer.insert_emulation_bytes = 1;
902 packed_header_param_buffer.skip_emulation_check_count = 5;
903 packed_header_param_buffer.num_headers = 1;
904 packed_header_param_buffer.length_in_bits = &length_in_bits;
905 packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
906 va_status = vaCreateBuffer(va_dpy,
908 VAEncPackedHeaderParameterBufferType,
909 sizeof(packed_header_param_buffer), 1,
910 &packed_header_param_buffer,
911 &h264_prv->packed_sps_par_buf);
912 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
914 "EncPackedSeqHeaderParameterBuffer failed");
915 va_status = vaCreateBuffer(va_dpy,
917 VAEncPackedHeaderDataBufferType,
918 (length_in_bits + 7) / 8, 1,
920 &h264_prv->packed_sps_data_buf);
921 h264_bitstream_destroy(&bitstream, TRUE);
922 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
924 "EncPackedSeqHeaderDataBuffer failed");
932 h264_recreate_pic_param(GstH264Encoder *h264_encoder,
933 VADisplay va_dpy, VAContextID context_id,
934 VABufferID coded_buf)
936 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
937 VAEncPictureParameterBufferH264 pic_h264;
939 VAStatus va_status = VA_STATUS_SUCCESS;
941 VAAPI_UNUSED_ARG(va_status);
942 memset(&pic_h264, 0, sizeof(pic_h264));
943 pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
944 pic_h264.CurrPic.TopFieldOrderCnt = h264_prv->cur_display_num * 2; // ??? /**/
945 pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1);
946 pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2);
947 pic_h264.ReferenceFrames[2].picture_id = VA_INVALID_ID;
948 pic_h264.CodedBuf = coded_buf;
950 pic_h264.seq_parameter_set_id = 0;
951 pic_h264.pic_parameter_set_id = 0;
952 pic_h264.last_picture = 0;
953 pic_h264.frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ?
954 (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num);
955 pic_h264.coding_type = 0;
956 pic_h264.pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26);
957 pic_h264.num_ref_idx_l0_active_minus1 = 0;
958 pic_h264.num_ref_idx_l1_active_minus1 = 0;
959 pic_h264.pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I);
960 pic_h264.pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B);
961 pic_h264.pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC;
962 pic_h264.pic_fields.bits.weighted_pred_flag = 0;
963 pic_h264.pic_fields.bits.weighted_bipred_idc = 0;
964 pic_h264.pic_fields.bits.transform_8x8_mode_flag = 1;
965 pic_h264.pic_fields.bits.deblocking_filter_control_present_flag = 1;
967 char *frame_type = "I";
968 if (h264_prv->cur_slice_type == SLICE_TYPE_P)
970 if (h264_prv->cur_slice_type == SLICE_TYPE_B)
972 ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
973 frame_type, pic_h264.frame_num, pic_h264.CurrPic.TopFieldOrderCnt);
975 if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
976 vaDestroyBuffer(va_dpy, h264_prv->pic_parameter);
977 h264_prv->pic_parameter = VA_INVALID_ID;
979 va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
980 sizeof(pic_h264), 1, &pic_h264, &h264_prv->pic_parameter);
982 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
983 FALSE, "creating pic-param buffer failed.");
985 //if (NULL == h264_prv->pps_data) {
986 if (VA_INVALID_ID == h264_prv->packed_pps_data_buf) {
987 VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
988 guint32 length_in_bits, offset_in_bytes;
989 guint8 *packed_pic_buffer = NULL;
990 H264Bitstream bitstream;
991 h264_bitstream_init(&bitstream, 128*8);
992 h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
993 h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_PPS);
994 h264_bitstream_write_pps(&bitstream, &pic_h264);
995 ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
996 length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
997 packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
998 //h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
999 //GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4;
1000 //memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, (length_in_bits+7)/8-4);
1002 offset_in_bytes = 0;
1003 packed_header_param_buffer.type = VAEncPackedHeaderPPS;
1004 packed_header_param_buffer.insert_emulation_bytes = 1;
1005 packed_header_param_buffer.skip_emulation_check_count = 5;
1006 packed_header_param_buffer.num_headers = 1;
1007 packed_header_param_buffer.length_in_bits = &length_in_bits;
1008 packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
1010 va_status = vaCreateBuffer(va_dpy,
1012 VAEncPackedHeaderParameterBufferType,
1013 sizeof(packed_header_param_buffer), 1,
1014 &packed_header_param_buffer,
1015 &h264_prv->packed_pps_par_buf);
1016 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1018 "EncPackedPicHeaderParameterBuffer failed");
1020 va_status = vaCreateBuffer(va_dpy,
1022 VAEncPackedHeaderDataBufferType,
1023 (length_in_bits + 7) / 8, 1,
1025 &h264_prv->packed_pps_data_buf);
1026 h264_bitstream_destroy(&bitstream, TRUE);
1027 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
1029 "EncPackedPicHeaderDataBuffer failed");
1038 h264_recreate_slice_param(GstH264Encoder *h264_encoder,
1039 VADisplay va_dpy, VAContextID context_id)
1041 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1042 VAEncSliceParameterBufferH264 *slice_h264 = NULL;
1044 gboolean ret = TRUE;
1045 VAStatus va_status = VA_STATUS_SUCCESS;
1047 width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
1050 guint32 last_row_num = 0;
1051 guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
1053 memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
1054 for (i = 0; i < h264_encoder->slice_num; ++i) {
1055 slice_h264 = &h264_prv->slice_param_buffers[i];
1057 slice_h264->starting_macroblock_address = last_row_num*width_in_mbs;
1058 slice_h264->number_of_mbs = width_in_mbs*h264_prv->default_slice_height;
1059 last_row_num += h264_prv->default_slice_height;
1060 if (slice_mod_num) {
1061 slice_h264->number_of_mbs += width_in_mbs;
1065 slice_h264->pic_parameter_set_id = 0;
1066 slice_h264->slice_type = h264_prv->cur_slice_type;
1067 slice_h264->direct_spatial_mv_pred_flag = 0;
1068 slice_h264->num_ref_idx_l0_active_minus1 = 0;
1069 slice_h264->num_ref_idx_l1_active_minus1 = 0;
1070 slice_h264->cabac_init_idc = 0;
1071 slice_h264->slice_qp_delta = 0;
1072 slice_h264->disable_deblocking_filter_idc = 0;
1073 slice_h264->slice_alpha_c0_offset_div2 = 2;
1074 slice_h264->slice_beta_offset_div2 = 2;
1075 slice_h264->idr_pic_id = 0;
1077 slice_h264->ref_pic_list_modification_flag_l0 = 0;
1078 slice_h264->ref_pic_list_modification_flag_l1 = 0;
1081 ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
1083 if (VA_INVALID_ID != h264_prv->slice_parameter) {
1084 vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
1085 h264_prv->slice_parameter = VA_INVALID_ID;
1087 va_status = vaCreateBuffer(va_dpy,
1089 VAEncSliceParameterBufferType,
1090 sizeof(h264_prv->slice_param_buffers[0]),
1091 h264_encoder->slice_num,
1092 h264_prv->slice_param_buffers,
1093 &h264_prv->slice_parameter);
1094 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
1095 FALSE, "creating slice-parameters buffer failed.");
1101 static EncoderStatus
1102 gst_h264_encoder_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
1103 GstVaapiContext *context, GstVaapiSurface *surface,
1104 guint frame_index, VABufferID coded_buf, gboolean *is_key)
1106 EncoderStatus ret = ENCODER_NO_ERROR;
1107 VAStatus va_status = VA_STATUS_SUCCESS;
1108 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1109 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1110 VABufferID va_buffers[64];
1111 guint32 va_buffers_count = 0;
1112 gboolean is_params_ok = TRUE;
1114 gboolean is_locked = FALSE;
1116 ENCODER_ASSERT(display && context);
1117 VADisplay va_dpy = gst_vaapi_display_get_display(display);
1118 VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
1120 *is_key = (h264_prv->cur_slice_type == SLICE_TYPE_I);
1122 if (!h264_prv->ref_surface1) {
1123 h264_prv->ref_surface1 = gst_vaapi_context_get_surface(context);
1124 ENCODER_CHECK_STATUS(h264_prv->ref_surface1,
1125 ENCODER_SURFACE_ERR,
1126 "reference surface, h264_pop_free_surface failed.");
1128 if (!h264_prv->ref_surface2) {
1129 h264_prv->ref_surface2 = gst_vaapi_context_get_surface(context);
1130 ENCODER_CHECK_STATUS(h264_prv->ref_surface2,
1131 ENCODER_SURFACE_ERR,
1132 "reference surface, h264_pop_free_surface failed.");
1134 if (!h264_prv->recon_surface) {
1135 h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
1136 ENCODER_CHECK_STATUS(h264_prv->recon_surface,
1137 ENCODER_SURFACE_ERR,
1138 "reconstructed surface, h264_pop_free_surface failed.");
1141 if (SLICE_TYPE_P == h264_prv->cur_slice_type) {
1142 h264_swap_surface(&h264_prv->ref_surface1, &h264_prv->ref_surface2);
1145 /* set sequence parameters, need set every time */
1146 is_params_ok = h264_recreate_seq_param(h264_encoder, va_dpy, context_id);
1147 ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1148 "h264_recreate_seq_param failed");
1149 /* set pic_parameters*/
1150 is_params_ok = h264_recreate_pic_param(h264_encoder, va_dpy, context_id, coded_buf);
1151 ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1152 "h264_recreate_pic_param failed");
1153 /* set slice parameters, support multiple slices */
1154 is_params_ok = h264_recreate_slice_param(h264_encoder, va_dpy, context_id);
1155 ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR,
1156 "h264_recreate_slice_param failed");
1159 ENCODER_ACQUIRE_DISPLAY_LOCK(display);
1161 /*render all buffers*/
1162 if (VA_INVALID_ID != h264_prv->seq_parameter) {
1163 va_buffers[va_buffers_count++] = h264_prv->seq_parameter;
1165 if (VA_INVALID_ID != h264_prv->pic_parameter) {
1166 va_buffers[va_buffers_count++] = h264_prv->pic_parameter;
1168 if (VA_INVALID_ID != h264_prv->slice_parameter) {
1169 va_buffers[va_buffers_count++] = h264_prv->slice_parameter;
1171 if (SLICE_TYPE_I == h264_prv->cur_slice_type) {
1172 if (VA_INVALID_ID != h264_prv->packed_sps_par_buf) {
1173 va_buffers[va_buffers_count++] = h264_prv->packed_sps_par_buf;
1175 if (VA_INVALID_ID != h264_prv->packed_sps_data_buf) {
1176 va_buffers[va_buffers_count++] = h264_prv->packed_sps_data_buf;
1178 if (VA_INVALID_ID != h264_prv->packed_pps_par_buf) {
1179 va_buffers[va_buffers_count++] = h264_prv->packed_pps_par_buf;
1181 if (VA_INVALID_ID != h264_prv->packed_pps_data_buf) {
1182 va_buffers[va_buffers_count++] = h264_prv->packed_pps_data_buf;
1186 va_status = vaRenderPicture(va_dpy, context_id, va_buffers, va_buffers_count);
1187 ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR,
1188 "vaRenderH264Picture failed.");
1190 /*after finished, swap recon and surface2*/
1191 if (SLICE_TYPE_P == h264_prv->cur_slice_type ||
1192 SLICE_TYPE_I == h264_prv->cur_slice_type) {
1193 h264_swap_surface(&h264_prv->recon_surface, &h264_prv->ref_surface2);
1197 ENCODER_RELEASE_DISPLAY_LOCK(display);
1204 gst_h264_encoder_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
1207 VABufferID *coded_buf)
1209 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
1210 GstBuffer *ret_buffer;
1212 const guint8 *nal_start;
1215 ret_buffer = gst_buffer_new();
1216 ENCODER_ASSERT(ret_buffer);
1217 H264Bitstream bitstream;
1218 h264_bitstream_init(&bitstream, (frame_size+32)*8);
1219 h264_bitstream_align(&bitstream, 0);
1220 ENCODER_ASSERT(bitstream.bit_size == 0);
1222 if (!h264_prv->es_flag) { /*nal format*/
1223 h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
1224 ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
1225 } else { /* elementary format */
1226 frame_end = frame + frame_size;
1229 while((nal_start = h264_next_nal(nal_start, frame_end-nal_start, &nal_size)) != NULL) {
1230 ENCODER_ASSERT(nal_size);
1232 nal_start += nal_size;
1235 h264_bitstream_write_uint(&bitstream, nal_size, 32);
1236 h264_bitstream_write_byte_array(&bitstream, nal_start, nal_size);
1237 nal_start += nal_size;
1240 h264_bitstream_align(&bitstream, 0);
1242 GST_BUFFER_MALLOCDATA(ret_buffer) =
1243 GST_BUFFER_DATA(ret_buffer) = BIT_STREAM_BUFFER(&bitstream);
1244 GST_BUFFER_SIZE(ret_buffer) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1245 h264_bitstream_destroy(&bitstream, FALSE);
1250 static EncoderStatus
1251 h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size)
1253 const guint8 *end = buf + size;
1254 const guint8 *nal_start = buf;
1255 guint32 nal_size = 0;
1257 GstBuffer *sps = NULL, *pps = NULL;
1259 while((!sps || !pps) && (nal_start = h264_next_nal(nal_start, end-nal_start, &nal_size)) != NULL) {
1261 nal_start += nal_size;
1265 nal_type = (*nal_start)&0x1F;
1268 sps = gst_buffer_new_and_alloc(nal_size);
1269 memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
1270 gst_buffer_replace(&h264_prv->sps_data, sps);
1271 gst_buffer_unref(sps); /*don't set to NULL*/
1276 pps = gst_buffer_new_and_alloc(nal_size);
1277 memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
1278 gst_buffer_replace(&h264_prv->pps_data, pps);
1279 gst_buffer_unref(pps);
1286 nal_start += nal_size;
1290 return ENCODER_DATA_NOT_READY;
1292 return ENCODER_NO_ERROR;
1296 gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size)
1298 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(encoder);
1299 if (!h264_prv->sps_data || !h264_prv->pps_data) {
1300 h264_encoder_read_sps_pps(h264_prv, buf, size);
1302 if (h264_prv->sps_data && h264_prv->pps_data) {
1303 gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), FALSE);
1309 h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
1310 guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc)
1312 ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
1313 ENCODER_ASSERT(sps_size >= 4);
1317 /*skip sps_data[0], nal_type*/
1318 *profile_idc = sps_data[1];
1319 *profile_comp = sps_data[2];
1320 *level_idc = sps_data[3];
1325 static EncoderStatus
1326 gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
1327 GstVaapiContext *context, GList **coded_pics)
1329 GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
1330 EncoderStatus ret = ENCODER_NO_ERROR;
1331 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1333 //h264_prv->frame_count = 0;
1334 h264_prv->cur_display_num = 0;
1335 h264_prv->cur_decode_num = 0;
1336 h264_prv->cur_slice_type = SLICE_TYPE_I;
1337 h264_prv->gop_count = g_queue_get_length(h264_prv->queued_buffers);
1338 //gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
1345 static int draw_picture(int width, int height,
1346 unsigned char *Y_start,
1347 unsigned char *U_start,
1348 unsigned char *V_start,
1349 int UV_interleave, int box_width, int row_shift);
1351 int main_test(int argc, char* argv[])
1353 EncoderStatus ret = ENCODER_NO_ERROR;
1354 GstVaapiEncoder *encoder = NULL;
1356 GList *coded_pics = NULL;
1357 GstBuffer **raw_buffer = NULL;
1358 const guint32 raw_buffer_num = 20;
1360 GstBuffer *tmp_buffer;
1362 guint32 i = 0, k = 0;
1364 gst_init (&argc, &argv);
1367 if (!g_thread_supported ())
1368 g_thread_init (NULL);
1370 GstH264Encoder *h264_encoder = gst_h264_encoder_new();
1371 encoder = GST_VAAPI_ENCODER(h264_encoder);
1372 ENCODER_ASSERT(encoder);
1374 h264_encoder->profile = 64;
1375 h264_encoder->level = 30;
1376 encoder->width = 1280;
1377 encoder->height = 720;
1378 encoder->frame_rate = 10;
1379 h264_encoder->bitrate = 512*1000;
1380 h264_encoder->intra_period = 30;
1381 ret = gst_vaapi_encoder_initialize(encoder);
1382 ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
1383 ret = gst_vaapi_encoder_open(encoder, NULL);
1384 ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
1386 guint32 buffer_size = encoder->width * encoder->width *3 /2;
1387 guint32 y_width = encoder->width, y_size = encoder->width * encoder->height;
1388 guint32 u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
1389 guint32 v_width = encoder->width/2;
1390 guint8 *y_src, *u_src, *v_src;
1396 VAAPI_UNUSED_ARG(v_width);
1397 VAAPI_UNUSED_ARG(u_width);
1398 VAAPI_UNUSED_ARG(y_width);
1399 raw_buffer = (GstBuffer**)g_malloc0(raw_buffer_num*sizeof(GstBuffer*));
1400 for (i = 0; i < raw_buffer_num; i++) {
1401 raw_buffer[i] = gst_buffer_new_and_alloc(buffer_size);
1402 y_src = GST_BUFFER_DATA(raw_buffer[i]);
1403 u_src = y_src + y_size;
1404 v_src = u_src + u_size;
1406 draw_picture(encoder->width, encoder->height, y_src, u_src, v_src, 0, box_width, row_shift);
1408 if (row_shift==(2*box_width)) row_shift= 0;
1411 FILE *fp = fopen("tmp.h264", "wb");
1416 for (i = 0; i < 50; i++) {
1418 ret = gst_vaapi_encoder_encode(encoder, raw_buffer[k], &coded_pics);
1419 ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
1421 if (k >= raw_buffer_num) k = 0;
1423 while (coded_pics) {
1424 tmp_buffer = coded_pics->data;
1425 coded_pics = g_list_remove(coded_pics, tmp_buffer);
1426 fwrite(GST_BUFFER_DATA(tmp_buffer), GST_BUFFER_SIZE(tmp_buffer), 1, fp);
1427 printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8));
1428 gst_buffer_unref(tmp_buffer);
1433 ret = gst_vaapi_encoder_close(encoder);
1434 ENCODER_ASSERT(ENCODER_NO_ERROR == ret);
1436 for (i = 0; i < raw_buffer_num; i++) {
1437 gst_buffer_unref(raw_buffer[i]);
1440 gst_vaapi_encoder_unref(encoder);
1446 gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
1448 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1449 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1450 GstBuffer *avc_codec;
1451 const guint32 configuration_version = 0x01;
1452 const guint32 length_size_minus_one = 0x03;
1453 guint32 profile, profile_comp, level_idc;
1455 ENCODER_ASSERT(buffer);
1456 if (!h264_prv->sps_data || !h264_prv->pps_data) {
1457 return ENCODER_DATA_NOT_READY;
1460 if (FALSE == h264_read_sps_attributes(GST_BUFFER_DATA(h264_prv->sps_data),
1461 GST_BUFFER_SIZE(h264_prv->sps_data),
1462 &profile, &profile_comp, &level_idc))
1465 return ENCODER_DATA_ERR;
1468 H264Bitstream bitstream;
1469 h264_bitstream_init(&bitstream,
1470 (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 32)*8);
1473 h264_bitstream_write_uint(&bitstream, configuration_version, 8);
1474 h264_bitstream_write_uint(&bitstream, profile, 8);
1475 h264_bitstream_write_uint(&bitstream, profile_comp, 8);
1476 h264_bitstream_write_uint(&bitstream, level_idc, 8);
1477 h264_bitstream_write_uint(&bitstream, h264_bit_mask[6], 6); /*111111*/
1478 h264_bitstream_write_uint(&bitstream, length_size_minus_one, 2);
1479 h264_bitstream_write_uint(&bitstream, h264_bit_mask[3], 3); /*111*/
1482 h264_bitstream_write_uint(&bitstream, 1, 5); /* sps count = 1*/
1483 ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
1484 h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->sps_data), 16);
1485 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
1486 GST_BUFFER_SIZE(h264_prv->sps_data));
1489 h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
1490 h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(h264_prv->pps_data), 16);
1491 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
1492 GST_BUFFER_SIZE(h264_prv->pps_data));
1494 avc_codec = gst_buffer_new();
1495 GST_BUFFER_MALLOCDATA(avc_codec) =
1496 GST_BUFFER_DATA(avc_codec) =
1497 BIT_STREAM_BUFFER(&bitstream);
1498 GST_BUFFER_SIZE(avc_codec) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1499 h264_bitstream_destroy(&bitstream, FALSE);
1500 *buffer = avc_codec;
1502 return ENCODER_NO_ERROR;
1506 gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer)
1508 GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
1509 GstH264EncoderPrivate *h264_prv = GST_H264_ENCODER_GET_PRIVATE(h264_encoder);
1510 GstBuffer *nal_sps_pps;
1512 ENCODER_ASSERT(buffer);
1513 if (!h264_prv->sps_data || !h264_prv->pps_data) {
1514 return ENCODER_DATA_NOT_READY;
1517 H264Bitstream bitstream;
1518 h264_bitstream_init(&bitstream,
1519 (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 8)*8);
1521 /*0x000001 start code*/
1522 h264_bitstream_write_uint(&bitstream, 0x000001, 24);
1523 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data),
1524 GST_BUFFER_SIZE(h264_prv->sps_data));
1525 h264_bitstream_write_uint(&bitstream, 0x000001, 24);
1526 h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data),
1527 GST_BUFFER_SIZE(h264_prv->pps_data));
1529 nal_sps_pps = gst_buffer_new();
1530 GST_BUFFER_MALLOCDATA(nal_sps_pps) =
1531 GST_BUFFER_DATA(nal_sps_pps) =
1532 BIT_STREAM_BUFFER(&bitstream);
1533 GST_BUFFER_SIZE(nal_sps_pps) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
1534 h264_bitstream_destroy(&bitstream, FALSE);
1535 *buffer = nal_sps_pps;
1536 return ENCODER_NO_ERROR;
1540 h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
1542 bitstream->bit_size = 0;
1543 bitstream->buffer = NULL;
1544 bitstream->max_bit_capability = 0;
1545 if (bit_capability) {
1546 h264_bitstream_auto_grow(bitstream, bit_capability);
1551 h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size)
1553 gboolean ret = TRUE;
1554 guint32 byte_pos, bit_offset;
1562 VAAPI_UNUSED_ARG(ret);
1563 ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, bit_size),
1565 "h264_bitstream_auto_grow failed.");
1566 byte_pos = (bitstream->bit_size>>3);
1567 bit_offset = (bitstream->bit_size&0x07);
1568 cur_byte = bitstream->buffer + byte_pos;
1569 ENCODER_ASSERT(bit_offset < 8 && bitstream->bit_size <= bitstream->max_bit_capability);
1572 fill_bits = ((8-bit_offset) < bit_size ? (8-bit_offset) : bit_size);
1573 bit_size -= fill_bits;
1574 bitstream->bit_size += fill_bits;
1576 *cur_byte |= ((value>>bit_size) & h264_bit_mask[fill_bits])<<(8-bit_offset-fill_bits);
1580 ENCODER_ASSERT(cur_byte <= bitstream->buffer + bitstream->max_bit_capability/8);
1586 static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value)
1588 guint32 bit_offset, bit_left;
1590 bit_offset = (bitstream->bit_size&0x07);
1594 bit_left = 8 - bit_offset;
1595 if (value) value = h264_bit_mask[bit_left];
1596 return h264_bitstream_write_uint(bitstream, value, bit_left);
1601 h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size)
1603 gboolean ret = TRUE;
1608 VAAPI_UNUSED_ARG(ret);
1609 ENCODER_CHECK_STATUS(TRUE == h264_bitstream_auto_grow(bitstream, byte_size<<3),
1611 "h264_bitstream_auto_grow failed.");
1612 if (0 == (bitstream->bit_size&0x07)) {
1613 memcpy(&bitstream->buffer[bitstream->bit_size>>3], buf, byte_size);
1614 bitstream->bit_size += (byte_size<<3);
1618 h264_bitstream_write_uint(bitstream, *buf, 8);
1629 h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value)
1631 gboolean ret = TRUE;
1632 guint32 size_in_bits = 0;
1633 guint32 tmp_value = ++value;
1638 ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1),
1640 "h264_bitstream_write_ue failed.");
1641 ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits),
1643 "h264_bitstream_write_ue failed.");
1650 h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value)
1652 gboolean ret = TRUE;
1656 new_val = -(value<<1);
1658 new_val = (value<<1) - 1;
1661 ENCODER_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val),
1663 "h264_bitstream_write_se failed.");
1670 h264_bitstream_write_trailing_bits(H264Bitstream *bitstream)
1672 h264_bitstream_write_uint(bitstream, 1, 1);
1673 h264_bitstream_align(bitstream, 0);
1678 h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag)
1680 if (bitstream->buffer && free_flag) {
1681 free (bitstream->buffer);
1683 bitstream->buffer = NULL;
1684 bitstream->bit_size = 0;
1685 bitstream->max_bit_capability = 0;
1689 h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size)
1691 guint32 new_bit_size = extra_bit_size + bitstream->bit_size;
1694 ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
1695 if (new_bit_size <= bitstream->max_bit_capability) {
1699 new_bit_size = ((new_bit_size + H264_BITSTREAM_ALLOC_ALIGN_MASK)
1700 &(~H264_BITSTREAM_ALLOC_ALIGN_MASK));
1701 ENCODER_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
1702 clear_pos = ((bitstream->bit_size+7)>>3);
1703 bitstream->buffer = realloc(bitstream->buffer, new_bit_size>>3);
1704 memset(bitstream->buffer+clear_pos, 0, (new_bit_size>>3)-clear_pos);
1705 bitstream->max_bit_capability = new_bit_size;
1710 h264_bitstream_write_nal_header(H264Bitstream *bitstream,
1711 guint nal_ref_idc, guint nal_unit_type)
1713 h264_bitstream_write_uint(bitstream, 0, 1);
1714 h264_bitstream_write_uint(bitstream, nal_ref_idc, 2);
1715 h264_bitstream_write_uint(bitstream, nal_unit_type, 5);
1720 h264_bitstream_write_sps(H264Bitstream *bitstream,
1721 VAEncSequenceParameterBufferH264 *seq)
1723 guint32 constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag;
1724 guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
1726 guint32 b_qpprime_y_zero_transform_bypass = (seq->rate_control_method == BR_CQP);
1727 guint32 residual_color_transform_flag = 0;
1728 guint32 pic_height_in_map_units = (seq->frame_mbs_only_flag ?
1729 seq->picture_height_in_mbs :
1730 seq->picture_height_in_mbs/2);
1731 guint32 mb_adaptive_frame_field = !seq->frame_mbs_only_flag;
1734 constraint_set0_flag = seq->profile_idc == H264_PROFILE_BASELINE;
1735 constraint_set1_flag = seq->profile_idc <= H264_PROFILE_MAIN;
1736 constraint_set2_flag = 0;
1737 constraint_set3_flag = 0;
1739 h264_bitstream_write_uint(bitstream, seq->profile_idc, 8); /* profile_idc */
1740 h264_bitstream_write_uint(bitstream, constraint_set0_flag, 1); /* constraint_set0_flag */
1741 h264_bitstream_write_uint(bitstream, constraint_set1_flag, 1); /* constraint_set1_flag */
1742 h264_bitstream_write_uint(bitstream, constraint_set2_flag, 1); /* constraint_set2_flag */
1743 h264_bitstream_write_uint(bitstream, constraint_set3_flag, 1); /* constraint_set3_flag */
1744 h264_bitstream_write_uint(bitstream, 0, 4); /* reserved_zero_4bits */
1745 h264_bitstream_write_uint(bitstream, seq->level_idc, 8); /* level_idc */
1746 h264_bitstream_write_ue(bitstream, seq->seq_parameter_set_id); /* seq_parameter_set_id */
1748 if (seq->profile_idc >= H264_PROFILE_HIGH) {
1749 /* for high profile */
1751 h264_bitstream_write_ue(bitstream, seq->seq_fields.bits.chroma_format_idc); /* chroma_format_idc = 1, 4:2:0*/
1752 if (3 == seq->seq_fields.bits.chroma_format_idc) {
1753 h264_bitstream_write_uint(bitstream, residual_color_transform_flag, 1);
1755 h264_bitstream_write_ue(bitstream, seq->bit_depth_luma_minus8); /* bit_depth_luma_minus8 */
1756 h264_bitstream_write_ue(bitstream, seq->bit_depth_chroma_minus8); /* bit_depth_chroma_minus8 */
1757 h264_bitstream_write_uint(bitstream, b_qpprime_y_zero_transform_bypass, 1); /* b_qpprime_y_zero_transform_bypass */
1758 ENCODER_ASSERT(seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
1759 h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_matrix_present_flag, 1); /*seq_scaling_matrix_present_flag */
1761 if (seq->seq_fields.bits.seq_scaling_matrix_present_flag) {
1762 for (i = 0; i < (seq->seq_fields.bits.chroma_format_idc != 3 ? 8 : 12); i++) {
1763 h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_list_present_flag, 1);
1764 if (seq->seq_fields.bits.seq_scaling_list_present_flag) {
1766 /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1*/
1772 h264_bitstream_write_ue(bitstream, seq->log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
1773 h264_bitstream_write_ue(bitstream, seq->pic_order_cnt_type); /* pic_order_cnt_type */
1775 if (seq->pic_order_cnt_type == 0)
1776 h264_bitstream_write_ue(bitstream, seq->log2_max_pic_order_cnt_lsb_minus4);/* log2_max_pic_order_cnt_lsb_minus4 */
1777 else if (seq->pic_order_cnt_type == 1) {
1779 h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.delta_pic_order_always_zero_flag, 1);
1780 h264_bitstream_write_se(bitstream, seq->offset_for_non_ref_pic);
1781 h264_bitstream_write_se(bitstream, seq->offset_for_top_to_bottom_field);
1782 h264_bitstream_write_ue(bitstream, seq->num_ref_frames_in_pic_order_cnt_cycle);
1783 for ( i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) {
1784 h264_bitstream_write_se(bitstream, seq->offset_for_ref_frame[i]);
1788 h264_bitstream_write_ue(bitstream, seq->max_num_ref_frames); /* num_ref_frames */
1789 h264_bitstream_write_uint(bitstream, gaps_in_frame_num_value_allowed_flag, 1); /* gaps_in_frame_num_value_allowed_flag */
1791 h264_bitstream_write_ue(bitstream, seq->picture_width_in_mbs - 1); /* pic_width_in_mbs_minus1 */
1792 h264_bitstream_write_ue(bitstream, pic_height_in_map_units - 1); /* pic_height_in_map_units_minus1 */
1793 h264_bitstream_write_uint(bitstream, seq->frame_mbs_only_flag, 1); /* frame_mbs_only_flag */
1795 if (!seq->frame_mbs_only_flag) { //ONLY mbs
1797 h264_bitstream_write_uint(bitstream, mb_adaptive_frame_field, 1);
1800 h264_bitstream_write_uint(bitstream, 0, 1); /* direct_8x8_inference_flag */
1801 h264_bitstream_write_uint(bitstream, seq->frame_cropping_flag, 1); /* frame_cropping_flag */
1803 if (seq->frame_cropping_flag) {
1804 h264_bitstream_write_ue(bitstream, seq->frame_crop_left_offset); /* frame_crop_left_offset */
1805 h264_bitstream_write_ue(bitstream, seq->frame_crop_right_offset); /* frame_crop_right_offset */
1806 h264_bitstream_write_ue(bitstream, seq->frame_crop_top_offset); /* frame_crop_top_offset */
1807 h264_bitstream_write_ue(bitstream, seq->frame_crop_bottom_offset); /* frame_crop_bottom_offset */
1809 ENCODER_ASSERT(seq->vui_flag == 0);
1810 h264_bitstream_write_uint(bitstream, seq->vui_flag, 1); /* vui_parameters_present_flag */
1811 if (seq->vui_flag) {
1812 /*FIXME, to write vui parameters*/
1814 h264_bitstream_write_trailing_bits(bitstream); /* rbsp_trailing_bits */
1820 h264_bitstream_write_pps(H264Bitstream *bitstream,
1821 VAEncPictureParameterBufferH264 *pic)
1823 guint32 num_slice_groups_minus1 = 0;
1824 guint32 pic_init_qs_minus26 = 0;
1825 guint32 redundant_pic_cnt_present_flag = 0;
1827 h264_bitstream_write_ue(bitstream, pic->pic_parameter_set_id); /* pic_parameter_set_id */
1828 h264_bitstream_write_ue(bitstream, pic->seq_parameter_set_id); /* seq_parameter_set_id */
1829 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.entropy_coding_mode_flag, 1); /* entropy_coding_mode_flag */
1830 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_order_present_flag, 1); /* pic_order_present_flag */
1831 h264_bitstream_write_ue(bitstream, num_slice_groups_minus1); /*slice_groups-1*/
1833 if (num_slice_groups_minus1 > 0) {
1837 h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l0_active_minus1);
1838 h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l1_active_minus1);
1839 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.weighted_pred_flag, 1);
1840 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.weighted_bipred_idc, 2);
1841 h264_bitstream_write_se(bitstream, pic->pic_init_qp-26); /* pic_init_qp_minus26 */
1842 h264_bitstream_write_se(bitstream, pic_init_qs_minus26); /* pic_init_qs_minus26 */
1843 h264_bitstream_write_se(bitstream, pic->chroma_qp_index_offset); /*chroma_qp_index_offset*/
1845 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.deblocking_filter_control_present_flag, 1);
1846 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.constrained_intra_pred_flag, 1);
1847 h264_bitstream_write_uint(bitstream, redundant_pic_cnt_present_flag, 1);
1850 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.transform_8x8_mode_flag, 1);
1851 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_matrix_present_flag, 1);
1852 if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) {
1857 (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag));
1859 h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_list_present_flag, 1);
1864 h264_bitstream_write_se(bitstream, pic->second_chroma_qp_index_offset);
1865 h264_bitstream_write_trailing_bits(bitstream);
1870 static const guint8 *
1871 h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
1873 const guint8 *cur = buffer;
1874 const guint8 *end = buffer + len;
1875 const guint8 *nal_start = NULL;
1876 guint32 flag = 0xFFFFFFFF;
1877 guint32 nal_start_len = 0;
1879 ENCODER_ASSERT(len >= 0 && buffer && nal_size);
1882 nal_start = (len ? buffer : NULL);
1886 /*locate head postion*/
1887 if (!buffer[0] && !buffer[1]) {
1888 if (buffer[2] == 1) { // 0x000001
1890 } else if (!buffer[2] && len >=4 && buffer[3] == 1) { //0x00000001
1894 nal_start = buffer + nal_start_len;
1897 /*find next nal start position*/
1899 flag = ((flag<<8) | ((*cur++)&0xFF));
1900 if (flag == 0x00000001) {
1901 *nal_size = cur - 4 - nal_start;
1903 } else if ((flag&0x00FFFFFF) == 0x00000001) {
1904 *nal_size = cur - 3 - nal_start;
1909 *nal_size = end - nal_start;
1910 if (nal_start >= end) {
1917 static int draw_picture(int width, int height,
1918 unsigned char *Y_start,
1919 unsigned char *U_start,
1920 unsigned char *V_start,
1921 int UV_interleave, int box_width, int row_shift)
1925 int Y_pitch = width;
1926 int U_pitch = width/2;
1927 int V_pitch = width/2;
1930 for (row=0;row<height;row++) {
1931 unsigned char *Y_row = Y_start + row * Y_pitch;
1934 ypos = (row / box_width) & 0x1;
1936 /* fill garbage data into the other field */
1937 if (((field == 1) && (row &1))
1938 || ((field == 2) && ((row &1)==0))) {
1939 memset(Y_row, 0xff, width);
1943 for (jj=0; jj<width; jj++) {
1944 xpos = ((row_shift + jj) / box_width) & 0x1;
1946 if ((xpos == 0) && (ypos == 0))
1948 if ((xpos == 1) && (ypos == 1))
1951 if ((xpos == 1) && (ypos == 0))
1953 if ((xpos == 0) && (ypos == 1))
1959 for( row =0; row < height/2; row++) {
1960 unsigned short value = 0x80;
1962 /* fill garbage data into the other field */
1963 if (((field == 1) && (row &1))
1964 || ((field == 2) && ((row &1)==0))) {
1968 if (UV_interleave) {
1969 unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch);
1971 memset(UV_row, value, width);
1973 unsigned char *U_row = U_start + row * U_pitch;
1974 unsigned char *V_row = V_start + row * V_pitch;
1976 memset (U_row,value,width/2);
1977 memset (V_row,value,width/2);