From 81c506e796eabc291d192d2fbc2839bc91611f68 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Mon, 30 Jul 2012 03:34:55 -0400 Subject: [PATCH] h264 encoder: worked in staging branch --- gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 495 +++++++++--------------------- gst-libs/gst/vaapi/gstvaapiencoder_h264.h | 2 + gst/vaapi/gstvaapiencode.c | 9 +- 3 files changed, 142 insertions(+), 364 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c index a635bd1..d3cc239 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -220,13 +220,7 @@ gst_vaapi_encoder_h264_class_init(GstVaapiEncoderH264Class *klass) base_class->encode_frame_failed = gst_vaapi_encoder_h264_frame_failed; encoder_class->flush = gst_vaapi_encoder_h264_flush; - encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data; - - /* - object_class->set_property = gst_vaapi_encoder_h264_set_property; - object_class->get_property = gst_vaapi_encoder_h264_get_property; - */ } static VAProfile @@ -254,6 +248,7 @@ gst_vaapi_encoder_h264_init(GstVaapiEncoderH264 *encoder) GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); ENCODER_ASSERT(h264_prv); h264_prv->public = encoder; + encoder->priv = h264_prv; /* init public attributes */ gst_vaapi_encoder_h264_init_public_values(encoder); @@ -350,14 +345,14 @@ gst_vaapi_encoder_h264_init_public_values(GstVaapiEncoderH264* encoder) void gst_vaapi_encoder_h264_set_avc_flag(GstVaapiEncoderH264* encoder, gboolean avc) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); + GstVaapiEncoderH264Private *h264_prv = encoder->priv; h264_prv->avc_flag = avc; } gboolean gst_vaapi_encoder_h264_get_avc_flag(GstVaapiEncoderH264* encoder) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); + GstVaapiEncoderH264Private *h264_prv = encoder->priv; return h264_prv->avc_flag; } @@ -365,7 +360,7 @@ gboolean gst_h264_validate_parameters(GstVaapiBaseEncoder *base_encoder) { GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264(base_encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); + GstVaapiEncoderH264Private *h264_prv = encoder->priv; if (!ENCODER_WIDTH(encoder) || !ENCODER_HEIGHT(encoder) || !ENCODER_FPS(encoder)) { return FALSE; } @@ -435,7 +430,7 @@ static gboolean h264_encoder_release_parameters(GstVaapiEncoderH264 *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context) { VAStatus va_status = VA_STATUS_SUCCESS; - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; gboolean is_locked = FALSE; @@ -510,7 +505,7 @@ gst_vaapi_encoder_h264_release_resource(GstVaapiBaseEncoder* encoder, GstVaapiDi { GstVaapiEncoderH264* h264_encoder = GST_VAAPI_ENCODER_H264(encoder); gboolean ret = TRUE; - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; /* release buffers first */ h264_encoder_release_parameters(h264_encoder, display, context); @@ -559,7 +554,7 @@ gst_vaapi_encoder_h264_alloc_slices(GstVaapiBaseEncoder *encoder, GstVaapiDispla { gboolean ret = TRUE; GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; h264_prv->slice_param_buffers = #ifdef _SIMPLE_LIB_VA_ @@ -577,7 +572,7 @@ static void gst_vaapi_encoder_h264_frame_failed(GstVaapiBaseEncoder *encoder, GstVaapiVideoBuffer* buffer) { GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; h264_release_queued_buffers(h264_prv); h264_prv->cur_display_num = 0; @@ -594,7 +589,7 @@ gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* encoder, { EncoderStatus ret = ENCODER_NO_ERROR; GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; GstVaapiVideoBuffer *return_buf = NULL; //guint64 pts = 0; @@ -651,26 +646,6 @@ gst_vaapi_encoder_h264_prepare_next_buffer(GstVaapiBaseEncoder* encoder, end: *out_buf = return_buf; - /* calculate cts/pts/dts */ -#if 0 - if (return_buf) { - pts = GST_BUFFER_TIMESTAMP(return_buf); - tmp_next_buf = (GstVaapiVideoBuffer*)g_queue_peek_head(h264_prv->queued_buffers); - if (tmp_next_buf) { - GST_BUFFER_TIMESTAMP(return_buf) = GST_BUFFER_TIMESTAMP(tmp_next_buf); - } else if (SLICE_TYPE_B == h264_prv->cur_slice_type) { - GST_BUFFER_TIMESTAMP(return_buf) = h264_prv->last_decode_time; - } - - pts += h264_prv->default_cts_offset; - if ((gint64)(pts - GST_BUFFER_TIMESTAMP(return_buf)) < 0) { - pts = GST_BUFFER_TIMESTAMP(return_buf); - } - - GST_BUFFER_OFFSET_END(return_buf) = pts; - GST_BUFFER_TIMESTAMP(return_buf) = pts; - } -#endif return ret; } @@ -685,7 +660,7 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay * EncoderStatus ret = ENCODER_NO_ERROR; VAStatus va_status = VA_STATUS_SUCCESS; GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; VAEncPictureParameterBufferH264 pic_h264; VAEncSliceParameterBuffer *slice_h264 = NULL; @@ -821,69 +796,62 @@ static void h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2) } static gboolean -h264_recreate_seq_param(GstVaapiEncoderH264 *h264_encoder, - VADisplay va_dpy, VAContextID context_id) +set_sequence_parameters(GstVaapiEncoderH264 *h264_encoder, + VAEncSequenceParameterBufferH264 *seq_param) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); - VAEncSequenceParameterBufferH264 seq_h264 = { 0 }; + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; guint width_in_mbs, height_in_mbs; - gboolean ret = TRUE; - VAStatus va_status = VA_STATUS_SUCCESS; - - /* only once */ - if (VA_INVALID_ID != h264_prv->seq_parameter) - return TRUE; width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16; height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16; - seq_h264.seq_parameter_set_id = 0; - seq_h264.level_idc = h264_encoder->level; /* 3.0 */ - seq_h264.intra_period = h264_encoder->intra_period; - seq_h264.ip_period = 0; // ? + seq_param->seq_parameter_set_id = 0; + seq_param->level_idc = h264_encoder->level; /* 3.0 */ + seq_param->intra_period = h264_encoder->intra_period; + seq_param->ip_period = 0; // ? if (h264_encoder->bitrate> 0) - seq_h264.bits_per_second = h264_encoder->bitrate; /* use kbps as input */ + seq_param->bits_per_second = h264_encoder->bitrate; /* use kbps as input */ else - seq_h264.bits_per_second = 0; + seq_param->bits_per_second = 0; - seq_h264.max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1); // ?, why 4 - seq_h264.picture_width_in_mbs = width_in_mbs; - seq_h264.picture_height_in_mbs = height_in_mbs; + seq_param->max_num_ref_frames = (h264_encoder->b_frame_num < 2 ? 3 : h264_encoder->b_frame_num+1); // ?, why 4 + seq_param->picture_width_in_mbs = width_in_mbs; + seq_param->picture_height_in_mbs = height_in_mbs; /*sequence field values*/ - seq_h264.seq_fields.value = 0; - seq_h264.seq_fields.bits.chroma_format_idc = 1; - seq_h264.seq_fields.bits.frame_mbs_only_flag = 1; - seq_h264.seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; - seq_h264.seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; + seq_param->seq_fields.value = 0; + seq_param->seq_fields.bits.chroma_format_idc = 1; + seq_param->seq_fields.bits.frame_mbs_only_flag = 1; + seq_param->seq_fields.bits.mb_adaptive_frame_field_flag = FALSE; + seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE; /* direct_8x8_inference_flag default false */ - seq_h264.seq_fields.bits.direct_8x8_inference_flag = FALSE; - seq_h264.seq_fields.bits.log2_max_frame_num_minus4 = 4; // log2(seq_h264.intra_period)-3 : 0 + seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE; + seq_param->seq_fields.bits.log2_max_frame_num_minus4 = 4; // log2(seq_h264.intra_period)-3 : 0 /* picture order count */ - seq_h264.seq_fields.bits.pic_order_cnt_type = 0; - seq_h264.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = - seq_h264.seq_fields.bits.log2_max_frame_num_minus4 + 2; - seq_h264.seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; + seq_param->seq_fields.bits.pic_order_cnt_type = 0; + seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = + seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 2; + seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE; - h264_prv->max_frame_num = 1<<(seq_h264.seq_fields.bits.log2_max_frame_num_minus4 + 4); - h264_prv->max_pic_order_cnt = 1 <<(seq_h264.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4); + h264_prv->max_frame_num = 1<<(seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4); + h264_prv->max_pic_order_cnt = 1 <<(seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4); - seq_h264.bit_depth_luma_minus8 = 0; - seq_h264.bit_depth_chroma_minus8 = 0; + seq_param->bit_depth_luma_minus8 = 0; + seq_param->bit_depth_chroma_minus8 = 0; /* not used if pic_order_cnt_type == 0 */ - seq_h264.num_ref_frames_in_pic_order_cnt_cycle = 0; - seq_h264.offset_for_non_ref_pic = 0; - seq_h264.offset_for_top_to_bottom_field = 0; - memset(seq_h264.offset_for_ref_frame, 0, sizeof(seq_h264.offset_for_ref_frame)); + seq_param->num_ref_frames_in_pic_order_cnt_cycle = 0; + seq_param->offset_for_non_ref_pic = 0; + seq_param->offset_for_top_to_bottom_field = 0; + memset(seq_param->offset_for_ref_frame, 0, sizeof(seq_param->offset_for_ref_frame)); if (height_in_mbs*16 - ENCODER_HEIGHT(h264_encoder)) { - seq_h264.frame_cropping_flag = 1; - seq_h264.frame_crop_left_offset = 0; - seq_h264.frame_crop_right_offset = 0; - seq_h264.frame_crop_top_offset = 0; - seq_h264.frame_crop_bottom_offset = - (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_h264.seq_fields.bits.frame_mbs_only_flag + 1)); + seq_param->frame_cropping_flag = 1; + seq_param->frame_crop_left_offset = 0; + seq_param->frame_crop_right_offset = 0; + seq_param->frame_crop_top_offset = 0; + seq_param->frame_crop_bottom_offset = + (height_in_mbs * 16 - ENCODER_HEIGHT(h264_encoder))/(2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)); } #if 0 if (h264_encoder->init_qp == -1) @@ -897,8 +865,24 @@ h264_recreate_seq_param(GstVaapiEncoderH264 *h264_encoder, #endif /*vui not set*/ - seq_h264.vui_parameters_present_flag = 0; + seq_param->vui_parameters_present_flag = FALSE; + return TRUE; +} + +static gboolean +h264_fill_sequence_buffer(GstVaapiEncoderH264 *h264_encoder, + VADisplay va_dpy, VAContextID context_id) +{ + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; + VAEncSequenceParameterBufferH264 seq_h264 = { 0 }; + gboolean ret = TRUE; + VAStatus va_status = VA_STATUS_SUCCESS; + /* only once */ + if (VA_INVALID_ID != h264_prv->seq_parameter) + return TRUE; + + set_sequence_parameters(h264_encoder, &seq_h264); va_status = vaCreateBuffer(va_dpy, context_id, VAEncSequenceParameterBufferType, sizeof(seq_h264), 1, @@ -906,31 +890,28 @@ h264_recreate_seq_param(GstVaapiEncoderH264 *h264_encoder, ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, FALSE, "alloc seq-buffer failed."); -#if 0 /*pack sps header buffer/data */ if (NULL == h264_prv->sps_data) { VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - guint32 length_in_bits, offset_in_bytes; + guint32 length_in_bits; guint8 *packed_seq_buffer = NULL; H264Bitstream bitstream; h264_bitstream_init(&bitstream, 128*8); h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/ h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS); - h264_bitstream_write_sps(&bitstream, &seq_h264); + h264_bitstream_write_sps(&bitstream, &seq_h264, h264_encoder->profile); ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0); length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream); packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream); - //h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8); - //GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4; - //memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, (length_in_bits+7)/8-4); - - offset_in_bytes = 0; - packed_header_param_buffer.type = VAEncPackedHeaderSPS; - packed_header_param_buffer.insert_emulation_bytes = 1; - packed_header_param_buffer.skip_emulation_check_count = 5; - packed_header_param_buffer.num_headers = 1; - packed_header_param_buffer.length_in_bits = &length_in_bits; - packed_header_param_buffer.offset_in_bytes = &offset_in_bytes; + + /* set codec data sps */ + h264_prv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8); + GST_BUFFER_SIZE(h264_prv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/ + memcpy(GST_BUFFER_DATA(h264_prv->sps_data), packed_seq_buffer+4, GST_BUFFER_SIZE(h264_prv->sps_data)); + + packed_header_param_buffer.type = VAEncPackedHeaderSequence; + packed_header_param_buffer.bit_length = length_in_bits; + packed_header_param_buffer.has_emulation_bytes = 0; va_status = vaCreateBuffer(va_dpy, context_id, VAEncPackedHeaderParameterBufferType, @@ -951,56 +932,66 @@ h264_recreate_seq_param(GstVaapiEncoderH264 *h264_encoder, FALSE, "EncPackedSeqHeaderDataBuffer failed"); } -#endif end: return ret; } static gboolean -h264_recreate_pic_param(GstVaapiEncoderH264 *h264_encoder, +set_picture_parameters(GstVaapiEncoderH264 *h264_encoder, + VAEncPictureParameterBufferH264 *pic_param) +{ + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; + + pic_param->pic_parameter_set_id = 0; + pic_param->seq_parameter_set_id = 0; + pic_param->last_picture = 0; /* means last encoding picture */ + pic_param->frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ? + (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num); + //pic_h264.coding_type = 0; + pic_param->pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26); + pic_param->num_ref_idx_l0_active_minus1 = 0; /* only 1 reference */ + pic_param->num_ref_idx_l1_active_minus1 = 0; /* B frames only have 1 backward and 1 forward reference*/ + pic_param->chroma_qp_index_offset = 0; + pic_param->second_chroma_qp_index_offset = 0; + + /* set picture fields */ + pic_param->pic_fields.value = 0; + pic_param->pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I); + pic_param->pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B); + pic_param->pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC; + pic_param->pic_fields.bits.weighted_pred_flag = FALSE; + pic_param->pic_fields.bits.weighted_bipred_idc = 0; + pic_param->pic_fields.bits.constrained_intra_pred_flag = 0; + pic_param->pic_fields.bits.transform_8x8_mode_flag = TRUE; /* enable 8x8 */ + pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; /* enable debloking */ + pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; + /* bottom_field_pic_order_in_frame_present_flag */ + pic_param->pic_fields.bits.pic_order_present_flag = FALSE; + pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; + + return TRUE; +} + +static gboolean +h264_fill_picture_buffer(GstVaapiEncoderH264 *h264_encoder, VADisplay va_dpy, VAContextID context_id, VABufferID coded_buf) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; VAEncPictureParameterBufferH264 pic_h264; gboolean ret = TRUE; VAStatus va_status = VA_STATUS_SUCCESS; VAAPI_UNUSED_ARG(va_status); memset(&pic_h264, 0, sizeof(pic_h264)); + set_picture_parameters(h264_encoder, &pic_h264); pic_h264.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface); pic_h264.CurrPic.TopFieldOrderCnt = h264_prv->cur_display_num * 2; // ??? /**/ pic_h264.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface1); pic_h264.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface2); pic_h264.ReferenceFrames[2].picture_id = VA_INVALID_ID; pic_h264.coded_buf = coded_buf; - pic_h264.pic_parameter_set_id = 0; - pic_h264.seq_parameter_set_id = 0; - pic_h264.last_picture = 0; /* means last encoding picture */ - pic_h264.frame_num = (h264_prv->cur_slice_type == SLICE_TYPE_B ? - (h264_prv->cur_decode_num + 1) : h264_prv->cur_decode_num); - //pic_h264.coding_type = 0; - pic_h264.pic_init_qp = (h264_encoder->init_qp >= 0 ? h264_encoder->init_qp : 26); - pic_h264.num_ref_idx_l0_active_minus1 = 0; /* only 1 reference */ - pic_h264.num_ref_idx_l1_active_minus1 = 0; /* B frames only have 1 backward and 1 forward reference*/ - pic_h264.chroma_qp_index_offset = 0; - pic_h264.second_chroma_qp_index_offset = 0; - - /* set picture fields */ - pic_h264.pic_fields.value = 0; - pic_h264.pic_fields.bits.idr_pic_flag = (h264_prv->cur_slice_type == SLICE_TYPE_I); - pic_h264.pic_fields.bits.reference_pic_flag = (h264_prv->cur_slice_type != SLICE_TYPE_B); - pic_h264.pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC; - pic_h264.pic_fields.bits.weighted_pred_flag = FALSE; - pic_h264.pic_fields.bits.weighted_bipred_idc = 0; - pic_h264.pic_fields.bits.constrained_intra_pred_flag = 0; - pic_h264.pic_fields.bits.transform_8x8_mode_flag = TRUE; /* enable 8x8 */ - pic_h264.pic_fields.bits.deblocking_filter_control_present_flag = TRUE; /* enable debloking */ - pic_h264.pic_fields.bits.redundant_pic_cnt_present_flag = FALSE; - /* bottom_field_pic_order_in_frame_present_flag */ - pic_h264.pic_fields.bits.pic_order_present_flag = FALSE; - pic_h264.pic_fields.bits.pic_scaling_matrix_present_flag = FALSE; char *frame_type = "I"; if (h264_prv->cur_slice_type == SLICE_TYPE_P) @@ -1019,11 +1010,10 @@ h264_recreate_pic_param(GstVaapiEncoderH264 *h264_encoder, ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, FALSE, "creating pic-param buffer failed."); -#if 0 - //if (NULL == h264_prv->pps_data) { + if (VA_INVALID_ID == h264_prv->packed_pps_data_buf) { VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; - guint32 length_in_bits, offset_in_bytes; + guint32 length_in_bits; guint8 *packed_pic_buffer = NULL; H264Bitstream bitstream; h264_bitstream_init(&bitstream, 128*8); @@ -1033,17 +1023,15 @@ h264_recreate_pic_param(GstVaapiEncoderH264 *h264_encoder, ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0); length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream); packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream); - //h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8); - //GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4; - //memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, (length_in_bits+7)/8-4); - - offset_in_bytes = 0; - packed_header_param_buffer.type = VAEncPackedHeaderPPS; - packed_header_param_buffer.insert_emulation_bytes = 1; - packed_header_param_buffer.skip_emulation_check_count = 5; - packed_header_param_buffer.num_headers = 1; - packed_header_param_buffer.length_in_bits = &length_in_bits; - packed_header_param_buffer.offset_in_bytes = &offset_in_bytes; + + /*set codec data pps*/ + h264_prv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8); + GST_BUFFER_SIZE(h264_prv->pps_data) = (length_in_bits+7)/8-4; + memcpy(GST_BUFFER_DATA(h264_prv->pps_data), packed_pic_buffer+4, GST_BUFFER_SIZE(h264_prv->pps_data)); + + packed_header_param_buffer.type = VAEncPackedHeaderPicture; + packed_header_param_buffer.bit_length = length_in_bits; + packed_header_param_buffer.has_emulation_bytes = 0; va_status = vaCreateBuffer(va_dpy, context_id, @@ -1066,17 +1054,16 @@ h264_recreate_pic_param(GstVaapiEncoderH264 *h264_encoder, FALSE, "EncPackedPicHeaderDataBuffer failed"); } -#endif end: return ret; } static gboolean -h264_recreate_slice_param(GstVaapiEncoderH264 *h264_encoder, +h264_fill_slice_buffers(GstVaapiEncoderH264 *h264_encoder, VADisplay va_dpy, VAContextID context_id) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; VAEncSliceParameterBufferH264 *slice_h264 = NULL; guint width_in_mbs; gboolean ret = TRUE; @@ -1184,7 +1171,7 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay * EncoderStatus ret = ENCODER_NO_ERROR; VAStatus va_status = VA_STATUS_SUCCESS; GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; VABufferID va_buffers[64]; guint32 va_buffers_count = 0; gboolean is_params_ok = TRUE; @@ -1220,16 +1207,16 @@ gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay * h264_swap_surface(&h264_prv->ref_surface1, &h264_prv->ref_surface2); } - /* set sequence parameters, need set every time */ - is_params_ok = h264_recreate_seq_param(h264_encoder, va_dpy, context_id); + /* fill sequence parameters, need set every time */ + is_params_ok = h264_fill_sequence_buffer(h264_encoder, va_dpy, context_id); ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR, "h264_recreate_seq_param failed"); /* set pic_parameters*/ - is_params_ok = h264_recreate_pic_param(h264_encoder, va_dpy, context_id, coded_buf); + is_params_ok = h264_fill_picture_buffer(h264_encoder, va_dpy, context_id, coded_buf); ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR, "h264_recreate_pic_param failed"); /* set slice parameters, support multiple slices */ - is_params_ok = h264_recreate_slice_param(h264_encoder, va_dpy, context_id); + is_params_ok = h264_fill_slice_buffers(h264_encoder, va_dpy, context_id); ENCODER_CHECK_STATUS(is_params_ok, ENCODER_PARAMETER_ERR, "h264_recreate_slice_param failed"); @@ -1284,7 +1271,8 @@ gst_vaapi_encoder_h264_copy_coded_buffer(GstVaapiBaseEncoder *encoder, guint32 frame_size, VABufferID *coded_buf) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); + GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; GstBuffer *ret_buffer; guint32 nal_size; const guint8 *nal_start; @@ -1373,7 +1361,8 @@ h264_encoder_read_sps_pps(GstVaapiEncoderH264Private *h264_prv, const guint8 *bu static void gst_h264_notify_frame(GstVaapiBaseEncoder *encoder, guint8 *buf, guint32 size) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder); + GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; if (!h264_prv->sps_data || !h264_prv->pps_data) { h264_encoder_read_sps_pps(h264_prv, buf, size); } @@ -1406,7 +1395,7 @@ gst_vaapi_encoder_h264_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display, { GstVaapiEncoderH264* h264_encoder = GST_VAAPI_ENCODER_H264(encoder); EncoderStatus ret = ENCODER_NO_ERROR; - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; //h264_prv->frame_count = 0; h264_prv->cur_display_num = 0; @@ -1419,111 +1408,10 @@ gst_vaapi_encoder_h264_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display, return ret; } -/*test*/ -static int draw_picture(int width, int height, - unsigned char *Y_start, - unsigned char *U_start, - unsigned char *V_start, - int UV_interleave, int box_width, int row_shift); - -int main_test(int argc, char* argv[]) -{ - EncoderStatus ret = ENCODER_NO_ERROR; - GstVaapiEncoder *encoder = NULL; - - GList *coded_pics = NULL; - GstBuffer **raw_buffer = NULL; - const guint32 raw_buffer_num = 20; - - GstBuffer *tmp_buffer; - - guint32 i = 0, k = 0; - - gst_init (&argc, &argv); - - g_type_init(); - if (!g_thread_supported ()) - g_thread_init (NULL); - - GstVaapiEncoderH264 *h264_encoder = gst_vaapi_encoder_h264_new(); - encoder = GST_VAAPI_ENCODER(h264_encoder); - ENCODER_ASSERT(encoder); - - h264_encoder->profile = 64; - h264_encoder->level = 30; - encoder->width = 1280; - encoder->height = 720; - encoder->frame_rate = 10; - h264_encoder->bitrate = 512*1000; - h264_encoder->intra_period = 30; - ret = gst_vaapi_encoder_initialize(encoder); - ENCODER_ASSERT(ret == ENCODER_NO_ERROR); - ret = gst_vaapi_encoder_open(encoder, NULL); - ENCODER_ASSERT(ret == ENCODER_NO_ERROR); - - guint32 buffer_size = encoder->width * encoder->width *3 /2; - guint32 y_width = encoder->width, y_size = encoder->width * encoder->height; - guint32 u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2); - guint32 v_width = encoder->width/2; - guint8 *y_src, *u_src, *v_src; - - /*set buffers*/ - int box_width=8; - int row_shift=0; - - VAAPI_UNUSED_ARG(v_width); - VAAPI_UNUSED_ARG(u_width); - VAAPI_UNUSED_ARG(y_width); - raw_buffer = (GstBuffer**)g_malloc0(raw_buffer_num*sizeof(GstBuffer*)); - for (i = 0; i < raw_buffer_num; i++) { - raw_buffer[i] = gst_buffer_new_and_alloc(buffer_size); - y_src = GST_BUFFER_DATA(raw_buffer[i]); - u_src = y_src + y_size; - v_src = u_src + u_size; - - draw_picture(encoder->width, encoder->height, y_src, u_src, v_src, 0, box_width, row_shift); - row_shift++; - if (row_shift==(2*box_width)) row_shift= 0; - } - - FILE *fp = fopen("tmp.h264", "wb"); - ENCODER_ASSERT(fp); - - k = 0; - - for (i = 0; i < 50; i++) { - coded_pics = NULL; - ret = gst_vaapi_encoder_encode(encoder, raw_buffer[k], &coded_pics); - ENCODER_ASSERT(ENCODER_NO_ERROR == ret); - ++k; - if (k >= raw_buffer_num) k = 0; - - while (coded_pics) { - tmp_buffer = coded_pics->data; - coded_pics = g_list_remove(coded_pics, tmp_buffer); - fwrite(GST_BUFFER_DATA(tmp_buffer), GST_BUFFER_SIZE(tmp_buffer), 1, fp); - printf("F:%d, S:%d, %s\n", i, GST_BUFFER_SIZE(tmp_buffer), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer)+4, 8)); - gst_buffer_unref(tmp_buffer); - } - } - fclose(fp); - - ret = gst_vaapi_encoder_close(encoder); - ENCODER_ASSERT(ENCODER_NO_ERROR == ret); - - for (i = 0; i < raw_buffer_num; i++) { - gst_buffer_unref(raw_buffer[i]); - } - g_free(raw_buffer); - gst_vaapi_encoder_unref(encoder); - - return 0; -} - EncoderStatus gst_vaapi_encoder_h264_get_avcC_codec_data(GstVaapiEncoderH264 *h264_encoder, GstBuffer **buffer) { - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; GstBuffer *avc_codec; const guint32 configuration_version = 0x01; const guint32 length_size_minus_one = 0x03; @@ -1583,49 +1471,13 @@ static EncoderStatus gst_vaapi_encoder_h264_get_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer) { GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); + GstVaapiEncoderH264Private *h264_prv = h264_encoder->priv; if (h264_prv->avc_flag) return gst_vaapi_encoder_h264_get_avcC_codec_data(h264_encoder, buffer); return ENCODER_NO_DATA; } -#if 0 -EncoderStatus -gst_vaapi_encoder_h264_get_nal_codec_data(GstVaapiEncoder *encoder, GstBuffer **buffer) -{ - GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264(encoder); - GstVaapiEncoderH264Private *h264_prv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(h264_encoder); - GstBuffer *nal_sps_pps; - - ENCODER_ASSERT(buffer); - if (!h264_prv->sps_data || !h264_prv->pps_data) { - return ENCODER_DATA_NOT_READY; - } - - H264Bitstream bitstream; - h264_bitstream_init(&bitstream, - (GST_BUFFER_SIZE(h264_prv->sps_data)+GST_BUFFER_SIZE(h264_prv->pps_data) + 8)*8); - - /*0x000001 start code*/ - h264_bitstream_write_uint(&bitstream, 0x000001, 24); - h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->sps_data), - GST_BUFFER_SIZE(h264_prv->sps_data)); - h264_bitstream_write_uint(&bitstream, 0x000001, 24); - h264_bitstream_write_byte_array(&bitstream, GST_BUFFER_DATA(h264_prv->pps_data), - GST_BUFFER_SIZE(h264_prv->pps_data)); - - nal_sps_pps = gst_buffer_new(); - GST_BUFFER_MALLOCDATA(nal_sps_pps) = - GST_BUFFER_DATA(nal_sps_pps) = - BIT_STREAM_BUFFER(&bitstream); - GST_BUFFER_SIZE(nal_sps_pps) = BIT_STREAM_BIT_SIZE(&bitstream)/8; - h264_bitstream_destroy(&bitstream, FALSE); - *buffer = nal_sps_pps; - return ENCODER_NO_ERROR; -} -#endif - static void h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability) { @@ -2005,72 +1857,3 @@ h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size) } return nal_start; } - -static int draw_picture(int width, int height, - unsigned char *Y_start, - unsigned char *U_start, - unsigned char *V_start, - int UV_interleave, int box_width, int row_shift) -{ - int row; - int field = 0; - int Y_pitch = width; - int U_pitch = width/2; - int V_pitch = width/2; - - /* copy Y plane */ - for (row=0;rowencoder); if (encode->first_sink_frame) { /* get first buffer caps and set encoder values */ @@ -401,8 +398,6 @@ gst_vaapi_encode_chain(GstPad *sink_pad, GstBuffer *buf) /*encoding frames*/ ENCODER_ASSERT(gst_vaapi_encoder_get_state(encode->encoder) >= VAAPI_ENC_OPENED); - ++input_count; - ENCODER_LOG_DEBUG("input %d", input_count); encoder_ret = gst_vaapi_encoder_encode(encode->encoder, buf, &out_buffers); ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == encoder_ret, GST_FLOW_ERROR, "gst_vaapi_encoder_encode failed."); @@ -422,9 +417,7 @@ gst_vaapi_encode_chain(GstPad *sink_pad, GstBuffer *buf) ENCODER_LOG_INFO("gst_vaapi_encode_chain 1st push-buffer caps,\n%s", _encode_dump_caps(encode->srcpad_caps)); encode->first_src_frame = FALSE; } - ++output_count; - ENCODER_LOG_DEBUG("output:%d, %" GST_TIME_FORMAT ", 0x%s", - output_count, + ENCODER_LOG_DEBUG("output:%" GST_TIME_FORMAT ", 0x%s", GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(tmp_buffer)), vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer), (GST_BUFFER_SIZE(tmp_buffer) > 16? 16: GST_BUFFER_SIZE(tmp_buffer)))); -- 2.7.4