diff options
-rw-r--r-- | src/gen6_mfc_common.c | 26 | ||||
-rw-r--r-- | src/i965_encoder_utils.c | 65 | ||||
-rw-r--r-- | src/i965_encoder_utils.h | 9 |
3 files changed, 100 insertions, 0 deletions
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c index 83f2792..a576a53 100644 --- a/src/gen6_mfc_common.c +++ b/src/gen6_mfc_common.c @@ -393,6 +393,7 @@ void intel_mfc_avc_pipeline_header_programing(VADriverContextP ctx, { struct gen6_mfc_context *mfc_context = encoder_context->mfc_context; int idx = va_enc_packed_type_to_idx(VAEncPackedHeaderH264_SPS); + unsigned int rate_control_mode = encoder_context->rate_control_mode; if (encode_state->packed_header_data[idx]) { VAEncPackedHeaderParameterBuffer *param = NULL; @@ -459,6 +460,31 @@ void intel_mfc_avc_pipeline_header_programing(VADriverContextP ctx, 0, !param->has_emulation_bytes, slice_batch); + } else if (rate_control_mode == VA_RC_CBR) { + // this is frist AU + struct gen6_mfc_context *mfc_context = encoder_context->mfc_context; + + unsigned char *sei_data = NULL; + + int length_in_bits = build_avc_sei_buffer_timing( + mfc_context->vui_hrd.i_initial_cpb_removal_delay_length, + mfc_context->vui_hrd.i_initial_cpb_removal_delay, + 0, + mfc_context->vui_hrd.i_cpb_removal_delay_length, mfc_context->vui_hrd.i_cpb_removal_delay * mfc_context->vui_hrd.i_frame_number, + mfc_context->vui_hrd.i_dpb_output_delay_length, + 0, + &sei_data); + mfc_context->insert_object(ctx, + encoder_context, + (unsigned int *)sei_data, + ALIGN(length_in_bits, 32) >> 5, + length_in_bits & 0x1f, + 4, + 0, + 0, + 1, + slice_batch); + free(sei_data); } } diff --git a/src/i965_encoder_utils.c b/src/i965_encoder_utils.c index aeea6f6..61af3ae 100644 --- a/src/i965_encoder_utils.c +++ b/src/i965_encoder_utils.c @@ -400,3 +400,68 @@ build_avc_sei_pic_timing(unsigned int cpb_removal_length, unsigned int cpb_remov } +int +build_avc_sei_buffer_timing(unsigned int init_cpb_removal_length, + unsigned int init_cpb_removal_delay, + unsigned int init_cpb_removal_delay_offset, + unsigned int cpb_removal_length, + unsigned int cpb_removal_delay, + unsigned int dpb_output_length, + unsigned int dpb_output_delay, + unsigned char **sei_buffer) +{ + unsigned char *byte_buf; + int bp_byte_size, i, pic_byte_size; + + avc_bitstream nal_bs; + avc_bitstream sei_bp_bs, sei_pic_bs; + + avc_bitstream_start(&sei_bp_bs); + avc_bitstream_put_ue(&sei_bp_bs, 0); /*seq_parameter_set_id*/ + avc_bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay, cpb_removal_length); + avc_bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay_offset, cpb_removal_length); + if ( sei_bp_bs.bit_offset & 0x7) { + avc_bitstream_put_ui(&sei_bp_bs, 1, 1); + } + avc_bitstream_end(&sei_bp_bs); + bp_byte_size = (sei_bp_bs.bit_offset + 7) / 8; + + avc_bitstream_start(&sei_pic_bs); + avc_bitstream_put_ui(&sei_pic_bs, cpb_removal_delay, cpb_removal_length); + avc_bitstream_put_ui(&sei_pic_bs, dpb_output_delay, dpb_output_length); + if ( sei_pic_bs.bit_offset & 0x7) { + avc_bitstream_put_ui(&sei_pic_bs, 1, 1); + } + avc_bitstream_end(&sei_pic_bs); + pic_byte_size = (sei_pic_bs.bit_offset + 7) / 8; + + avc_bitstream_start(&nal_bs); + nal_start_code_prefix(&nal_bs); + nal_header(&nal_bs, NAL_REF_IDC_NONE, NAL_SEI); + + /* Write the SEI buffer period data */ + avc_bitstream_put_ui(&nal_bs, 0, 8); + avc_bitstream_put_ui(&nal_bs, bp_byte_size, 8); + + byte_buf = (unsigned char *)sei_bp_bs.buffer; + for(i = 0; i < bp_byte_size; i++) { + avc_bitstream_put_ui(&nal_bs, byte_buf[i], 8); + } + free(byte_buf); + /* write the SEI timing data */ + avc_bitstream_put_ui(&nal_bs, 0x01, 8); + avc_bitstream_put_ui(&nal_bs, pic_byte_size, 8); + + byte_buf = (unsigned char *)sei_pic_bs.buffer; + for(i = 0; i < pic_byte_size; i++) { + avc_bitstream_put_ui(&nal_bs, byte_buf[i], 8); + } + free(byte_buf); + + avc_rbsp_trailing_bits(&nal_bs); + avc_bitstream_end(&nal_bs); + + *sei_buffer = (unsigned char *)nal_bs.buffer; + + return nal_bs.bit_offset; +} diff --git a/src/i965_encoder_utils.h b/src/i965_encoder_utils.h index 62de4f6..cbed4e4 100644 --- a/src/i965_encoder_utils.h +++ b/src/i965_encoder_utils.h @@ -17,4 +17,13 @@ build_avc_sei_pic_timing(unsigned int cpb_removal_length, unsigned int cpb_remov unsigned int dpb_output_length, unsigned int dpb_output_delay, unsigned char **sei_buffer); +int +build_avc_sei_buffer_timing(unsigned int init_cpb_removal_length, + unsigned int init_cpb_removal_delay, + unsigned int init_cpb_removal_delay_offset, + unsigned int cpb_removal_length, + unsigned int cpb_removal_delay, + unsigned int dpb_output_length, + unsigned int dpb_output_delay, + unsigned char **sei_buffer); #endif /* __I965_ENCODER_UTILS_H__ */ |