diff options
-rw-r--r-- | src/gen6_mfc.c | 4 | ||||
-rw-r--r-- | src/gen6_mfc.h | 7 | ||||
-rw-r--r-- | src/gen6_mfc_common.c | 47 | ||||
-rw-r--r-- | src/gen75_mfc.c | 6 | ||||
-rw-r--r-- | src/gen8_mfc.c | 6 | ||||
-rwxr-xr-x | src/i965_drv_video.c | 62 |
6 files changed, 121 insertions, 11 deletions
diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c index 21db0a7..c6702e8 100644 --- a/src/gen6_mfc.c +++ b/src/gen6_mfc.c @@ -814,6 +814,8 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, if ( slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch); + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); // slice hander @@ -1206,6 +1208,8 @@ gen6_mfc_avc_batchbuffer_slice(VADriverContextP ctx, if (slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch); + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); // slice hander diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h index 9437c31..67c62a4 100644 --- a/src/gen6_mfc.h +++ b/src/gen6_mfc.h @@ -271,4 +271,11 @@ intel_mfc_avc_ref_idx_state(VADriverContextP ctx, extern Bool gen8_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context); +extern void +intel_avc_slice_insert_packed_data(VADriverContextP ctx, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context, + int slice_index, + struct intel_batchbuffer *slice_batch); + #endif /* _GEN6_MFC_BCS_H_ */ diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c index 95e4dc3..44e6e95 100644 --- a/src/gen6_mfc_common.c +++ b/src/gen6_mfc_common.c @@ -1516,3 +1516,50 @@ intel_avc_vme_reference_state(VADriverContextP ctx, vme_context->ref_index_in_mb[list_index] = 0; } } + +void intel_avc_slice_insert_packed_data(VADriverContextP ctx, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context, + int slice_index, + struct intel_batchbuffer *slice_batch) +{ + int count, i, start_index; + unsigned int length_in_bits; + VAEncPackedHeaderParameterBuffer *param = NULL; + unsigned int *header_data = NULL; + struct gen6_mfc_context *mfc_context = encoder_context->mfc_context; + + /* If the number of packed data for current slice is zero, return */ + if (encode_state->slice_rawdata_count[slice_index] == 0) + return; + + count = encode_state->slice_rawdata_count[slice_index]; + start_index = (encode_state->slice_rawdata_index[slice_index] & SLICE_PACKED_DATA_INDEX_MASK); + + for (i = 0; i < count; i++) { + unsigned int skip_emul_byte_cnt; + + header_data = (unsigned int *)encode_state->packed_header_data_ext[start_index + i]->buffer; + + param = (VAEncPackedHeaderParameterBuffer *) + (encode_state->packed_header_params_ext[start_index + i]->buffer); + length_in_bits = param->bit_length; + + skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits); + + /* as the slice header is still required, the last header flag is set to + * zero. + */ + mfc_context->insert_object(ctx, + encoder_context, + header_data, + ALIGN(length_in_bits, 32) >> 5, + length_in_bits & 0x1f, + skip_emul_byte_cnt, + 0, + 0, + !param->has_emulation_bytes, + slice_batch); + } + return; +} diff --git a/src/gen75_mfc.c b/src/gen75_mfc.c index 48d84da..18a588f 100644 --- a/src/gen75_mfc.c +++ b/src/gen75_mfc.c @@ -1192,6 +1192,8 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, if ( slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch); + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); // slice hander @@ -1246,8 +1248,6 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, tail_data, 1, 8, 1, 1, 1, 0, slice_batch); } - - } static dri_bo * @@ -1545,6 +1545,8 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx, if (slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch); + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); // slice hander diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c index df99603..2fc1fac 100644 --- a/src/gen8_mfc.c +++ b/src/gen8_mfc.c @@ -1056,6 +1056,8 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, if ( slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch); + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); // slice hander @@ -1110,8 +1112,6 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx, tail_data, 1, 8, 1, 1, 1, 0, slice_batch); } - - } static dri_bo * @@ -1441,6 +1441,8 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx, if (slice_index == 0) intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch); + intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch); + slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header); // slice hander diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index db0440c..d8b50dc 100755 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -655,6 +655,12 @@ i965_GetConfigAttributes(VADriverContextP ctx, case VAConfigAttribEncPackedHeaders: if (entrypoint == VAEntrypointEncSlice) { attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC; + if (profile == VAProfileH264ConstrainedBaseline || + profile == VAProfileH264Main || + profile == VAProfileH264High || + profile == VAProfileH264MultiviewHigh) { + attrib_list[i].value |= VA_ENC_PACKED_HEADER_RAW_DATA; + } break; } @@ -2367,6 +2373,9 @@ DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext) // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params) DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext) +DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext) +DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext) + static VAStatus i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx, struct object_context *obj_context, @@ -2430,10 +2439,12 @@ i965_encoder_render_picture(VADriverContextP ctx, struct i965_driver_data *i965 = i965_driver_data(ctx); struct object_context *obj_context = CONTEXT(context); VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; + struct encode_state *encode; int i; ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT); + encode = &obj_context->codec_state.encode; for (i = 0; i < num_buffers; i++) { struct object_buffer *obj_buffer = BUFFER(buffers[i]); @@ -2459,35 +2470,67 @@ i965_encoder_render_picture(VADriverContextP ctx, case VAEncSliceParameterBufferType: vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext); + if (vaStatus == VA_STATUS_SUCCESS) { + /* When the max number of slices is updated, it also needs + * to reallocate the arrays that is used to store + * the packed data index/count for the slice + */ + if (encode->max_slice_params_ext > encode->slice_num) { + encode->slice_num = encode->max_slice_params_ext; + encode->slice_rawdata_index = realloc(encode->slice_rawdata_index, + encode->slice_num * sizeof(int)); + encode->slice_rawdata_count = realloc(encode->slice_rawdata_count, + encode->slice_num * sizeof(int)); + if ((encode->slice_rawdata_index == NULL) || + (encode->slice_rawdata_count == NULL)) { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + return vaStatus; + } + } + } break; case VAEncPackedHeaderParameterBufferType: { - struct encode_state *encode = &obj_context->codec_state.encode; VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer; encode->last_packed_header_type = param->type; - vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx, + if (param->type == VAEncPackedHeaderRawData) { + vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext); + } else { + vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx, obj_context, obj_buffer, va_enc_packed_type_to_idx(encode->last_packed_header_type)); + } break; } case VAEncPackedHeaderDataBufferType: { - struct encode_state *encode = &obj_context->codec_state.encode; - ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence || - encode->last_packed_header_type == VAEncPackedHeaderPicture || - encode->last_packed_header_type == VAEncPackedHeaderSlice || + if (encode->last_packed_header_type == VAEncPackedHeaderRawData) { + vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext); + if (vaStatus == VA_STATUS_SUCCESS) { + /* store the first index of the packed header data for current slice */ + if (encode->slice_rawdata_index[encode->num_slice_params_ext] == 0) { + encode->slice_rawdata_index[encode->num_slice_params_ext] = + SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1); + } + encode->slice_rawdata_count[encode->num_slice_params_ext]++; + } + } else { + ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence || + encode->last_packed_header_type == VAEncPackedHeaderPicture || + encode->last_packed_header_type == VAEncPackedHeaderSlice || (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) && ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)), VA_STATUS_ERROR_ENCODING_ERROR); - vaStatus = i965_encoder_render_packed_header_data_buffer(ctx, + vaStatus = i965_encoder_render_packed_header_data_buffer(ctx, obj_context, obj_buffer, va_enc_packed_type_to_idx(encode->last_packed_header_type)); + } break; } @@ -2591,6 +2634,11 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context) } else if (obj_context->codec_type == CODEC_ENC) { ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT); + if (obj_context->codec_state.encode.num_packed_header_params_ext != + obj_context->codec_state.encode.num_packed_header_data_ext) { + WARN_ONCE("the packed header/data is not paired for encoding!\n"); + return VA_STATUS_ERROR_INVALID_PARAMETER; + } if (!(obj_context->codec_state.encode.pic_param || obj_context->codec_state.encode.pic_param_ext)) { return VA_STATUS_ERROR_INVALID_PARAMETER; |