From bd630edd844b88ea543a027654db296ff7da16cd Mon Sep 17 00:00:00 2001 From: Li Xiaowei Date: Thu, 19 Dec 2013 17:51:45 +0800 Subject: MVC: Pack prefix nal and ext slice header to compressed bitstream Signed-off-by: Li Xiaowei --- src/gen75_mfc.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++---------- src/gen75_vme.c | 5 +- src/gen8_mfc.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++---------- src/gen8_vme.c | 4 +- 4 files changed, 261 insertions(+), 58 deletions(-) diff --git a/src/gen75_mfc.c b/src/gen75_mfc.c index 28edd40..e27b803 100644 --- a/src/gen75_mfc.c +++ b/src/gen75_mfc.c @@ -427,7 +427,8 @@ static void gen75_mfc_init(VADriverContextP ctx, int height_in_mbs = 0; int slice_batchbuffer_size; - if (encoder_context->codec == CODEC_H264) { + if (encoder_context->codec == CODEC_H264 || + encoder_context->codec == CODEC_H264_MVC) { VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; width_in_mbs = pSequenceParameter->picture_width_in_mbs; height_in_mbs = pSequenceParameter->picture_height_in_mbs; @@ -1182,22 +1183,75 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52); assert(qp >= 0 && qp < 52); - gen75_mfc_avc_slice_state(ctx, - pPicParameter, - pSliceParameter, - encode_state, encoder_context, - (rate_control_mode == VA_RC_CBR), qp, slice_batch); - - if ( slice_index == 0) - intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + if (encoder_context->codec == CODEC_H264_MVC) { + VAEncSequenceParameterBufferH264_MVC *mvc_seq_param = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter; + VAEncPictureParameterBufferH264_MVC *mvc_pic_param = (VAEncPictureParameterBufferH264_MVC *)pPicParameter; + VAEncSliceParameterBufferH264 *mvc_slice_param = pSliceParameter; + + gen75_mfc_avc_slice_state(ctx, + pPicParameter, + pSliceParameter, + encode_state, encoder_context, + (rate_control_mode == VA_RC_CBR), qp, slice_batch); + + if (slice_index == 0) + intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + + if (mvc_pic_param->view_id != 0) { + /* generate one extension slice header with type of 20 */ + slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param, + mvc_pic_param, + mvc_slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + + } else { + /* generate one mvc prefix nal */ + slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param, + mvc_pic_param, + mvc_slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */ + 0, 0, 1, slice_batch); + free(slice_header); + + /* generate one common H264 slice header */ + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, + pPicParameter, + pSliceParameter, + &slice_header); + + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + } - slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); + } else { + gen75_mfc_avc_slice_state(ctx, + pPicParameter, + pSliceParameter, + encode_state, encoder_context, + (rate_control_mode == VA_RC_CBR), qp, slice_batch); + + if ( slice_index == 0) + intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); + + // slice hander + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + } - // slice hander - mfc_context->insert_object(ctx, encoder_context, - (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, - 5, /* first 5 bytes are start code + nal unit type */ - 1, 0, 1, slice_batch); + free(slice_header); dri_bo_map(vme_context->vme_output.bo , 1); msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual; @@ -1244,7 +1298,6 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, 1, 1, 1, 0, slice_batch); } - free(slice_header); } @@ -1543,19 +1596,63 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx, if (slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); - slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); - // slice hander - mfc_context->insert_object(ctx, - encoder_context, - (unsigned int *)slice_header, - ALIGN(slice_header_length_in_bits, 32) >> 5, - slice_header_length_in_bits & 0x1f, - 5, /* first 5 bytes are start code + nal unit type */ - 1, - 0, - 1, - slice_batch); + if (encoder_context->codec == CODEC_H264_MVC) { + VAEncSequenceParameterBufferH264_MVC *mvc_seq_param = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter; + VAEncPictureParameterBufferH264_MVC *mvc_pic_param = (VAEncPictureParameterBufferH264_MVC*)pPicParameter; + VAEncSliceParameterBufferH264 *slice_param = pSliceParameter; + + if (mvc_pic_param->view_id != 0) { + /* generate one extension slice header with type of 20 */ + slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param, + mvc_pic_param, + slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + + } else { + /* generate one mvc prefix nal */ + slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param, + mvc_pic_param, + slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */ + 0, 0, 1, slice_batch); + free(slice_header); + + /* generate common H264 slice header */ + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, + pPicParameter, + pSliceParameter, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + } + + } else { + + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); + + // slice hander + mfc_context->insert_object(ctx, + encoder_context, + (unsigned int *)slice_header, + ALIGN(slice_header_length_in_bits, 32) >> 5, + slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, + 0, + 1, + slice_batch); + } + free(slice_header); intel_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */ @@ -2534,6 +2631,8 @@ static VAStatus gen75_mfc_pipeline(VADriverContextP ctx, case VAProfileH264ConstrainedBaseline: case VAProfileH264Main: case VAProfileH264High: + case VAProfileH264MultiviewHigh: + case VAProfileH264StereoHigh: vaStatus = gen75_mfc_avc_encode_picture(ctx, encode_state, encoder_context); break; diff --git a/src/gen75_vme.c b/src/gen75_vme.c index 0467f38..e8527c3 100644 --- a/src/gen75_vme.c +++ b/src/gen75_vme.c @@ -336,7 +336,8 @@ static VAStatus gen75_vme_constant_setup(VADriverContextP ctx, vme_state_message = (unsigned int *)vme_context->vme_state_message; - if (encoder_context->codec == CODEC_H264) { + if (encoder_context->codec == CODEC_H264 || + encoder_context->codec == CODEC_H264_MVC) { if (vme_context->h264_level >= 30) { mv_num = 16; @@ -462,6 +463,7 @@ static VAStatus gen75_vme_vme_state_setup(VADriverContextP ctx, switch (encoder_context->codec) { case CODEC_H264: + case CODEC_H264_MVC: gen75_vme_state_setup_fixup(ctx, encode_state, encoder_context, vme_state_message); break; @@ -1010,6 +1012,7 @@ Bool gen75_vme_context_init(VADriverContextP ctx, struct intel_encoder_context * switch (encoder_context->codec) { case CODEC_H264: + case CODEC_H264_MVC: vme_kernel_list = gen75_vme_kernels; encoder_context->vme_pipeline = gen75_vme_pipeline; i965_kernel_num = sizeof(gen75_vme_kernels) / sizeof(struct i965_kernel); diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c index 90092a1..4f1ad5b 100644 --- a/src/gen8_mfc.c +++ b/src/gen8_mfc.c @@ -401,7 +401,8 @@ static void gen8_mfc_init(VADriverContextP ctx, int height_in_mbs = 0; int slice_batchbuffer_size; - if (encoder_context->codec == CODEC_H264) { + if (encoder_context->codec == CODEC_H264 || + encoder_context->codec == CODEC_H264_MVC) { VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer; width_in_mbs = pSequenceParameter->picture_width_in_mbs; height_in_mbs = pSequenceParameter->picture_height_in_mbs; @@ -1046,22 +1047,75 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52); assert(qp >= 0 && qp < 52); - gen8_mfc_avc_slice_state(ctx, - pPicParameter, - pSliceParameter, - encode_state, encoder_context, - (rate_control_mode == VA_RC_CBR), qp, slice_batch); - - if ( slice_index == 0) - intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + if (encoder_context->codec == CODEC_H264_MVC) { + VAEncSequenceParameterBufferH264_MVC *mvc_seq_param = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter; + VAEncPictureParameterBufferH264_MVC *mvc_pic_param = (VAEncPictureParameterBufferH264_MVC *)pPicParameter; + VAEncSliceParameterBufferH264 *mvc_slice_param = pSliceParameter; + + gen8_mfc_avc_slice_state(ctx, + pPicParameter, + pSliceParameter, + encode_state, encoder_context, + (rate_control_mode == VA_RC_CBR), qp, slice_batch); + + if (slice_index == 0) + intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + + if (mvc_pic_param->view_id != 0) { + /* generate one extension slice header with type of 20 */ + slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param, + mvc_pic_param, + mvc_slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + + } else { + /* generate one mvc prefix nal */ + slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param, + mvc_pic_param, + mvc_slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */ + 0, 0, 1, slice_batch); + free(slice_header); + + /* generate one common H264 slice header */ + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, + pPicParameter, + pSliceParameter, + &slice_header); + + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + } - slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); + } else { + gen8_mfc_avc_slice_state(ctx, + pPicParameter, + pSliceParameter, + encode_state, encoder_context, + (rate_control_mode == VA_RC_CBR), qp, slice_batch); + + if ( slice_index == 0) + intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); + + // slice hander + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + } - // slice hander - mfc_context->insert_object(ctx, encoder_context, - (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, - 5, /* first 5 bytes are start code + nal unit type */ - 1, 0, 1, slice_batch); + free(slice_header); dri_bo_map(vme_context->vme_output.bo , 1); msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual; @@ -1108,7 +1162,6 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, 1, 1, 1, 0, slice_batch); } - free(slice_header); } @@ -1439,19 +1492,63 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx, if (slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); - slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); - // slice hander - mfc_context->insert_object(ctx, - encoder_context, - (unsigned int *)slice_header, - ALIGN(slice_header_length_in_bits, 32) >> 5, - slice_header_length_in_bits & 0x1f, - 5, /* first 5 bytes are start code + nal unit type */ - 1, - 0, - 1, - slice_batch); + if (encoder_context->codec == CODEC_H264_MVC) { + VAEncSequenceParameterBufferH264_MVC *mvc_seq_param = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter; + VAEncPictureParameterBufferH264_MVC *mvc_pic_param = (VAEncPictureParameterBufferH264_MVC*)pPicParameter; + VAEncSliceParameterBufferH264 *slice_param = pSliceParameter; + + if (mvc_pic_param->view_id != 0) { + /* generate one extension slice header with type of 20 */ + slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param, + mvc_pic_param, + slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + + } else { + /* generate one mvc prefix nal */ + slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param, + mvc_pic_param, + slice_param, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */ + 0, 0, 1, slice_batch); + free(slice_header); + + /* generate common H264 slice header */ + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, + pPicParameter, + pSliceParameter, + &slice_header); + mfc_context->insert_object(ctx, encoder_context, + (unsigned int *)slice_header, ALIGN(slice_header_length_in_bits, 32) >> 5, slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, 0, 1, slice_batch); + } + + } else { + + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); + + // slice hander + mfc_context->insert_object(ctx, + encoder_context, + (unsigned int *)slice_header, + ALIGN(slice_header_length_in_bits, 32) >> 5, + slice_header_length_in_bits & 0x1f, + 5, /* first 5 bytes are start code + nal unit type */ + 1, + 0, + 1, + slice_batch); + } + free(slice_header); intel_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */ @@ -2435,6 +2532,8 @@ static VAStatus gen8_mfc_pipeline(VADriverContextP ctx, case VAProfileH264ConstrainedBaseline: case VAProfileH264Main: case VAProfileH264High: + case VAProfileH264MultiviewHigh: + case VAProfileH264StereoHigh: vaStatus = gen8_mfc_avc_encode_picture(ctx, encode_state, encoder_context); break; diff --git a/src/gen8_vme.c b/src/gen8_vme.c index 67571be..34a3b68 100644 --- a/src/gen8_vme.c +++ b/src/gen8_vme.c @@ -321,7 +321,8 @@ static VAStatus gen8_vme_constant_setup(VADriverContextP ctx, vme_state_message = (unsigned int *)vme_context->vme_state_message; - if (encoder_context->codec == CODEC_H264) { + if (encoder_context->codec == CODEC_H264 || + encoder_context->codec == CODEC_H264_MVC) { if (vme_context->h264_level >= 30) { mv_num = 16; @@ -1155,6 +1156,7 @@ Bool gen8_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *e switch (encoder_context->codec) { case CODEC_H264: + case CODEC_H264_MVC: vme_kernel_list = gen8_vme_kernels; encoder_context->vme_pipeline = gen8_vme_pipeline; i965_kernel_num = sizeof(gen8_vme_kernels) / sizeof(struct i965_kernel); -- cgit v1.2.3