diff options
-rw-r--r-- | src/gen6_mfc_common.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c index 3e30335..95e4dc3 100644 --- a/src/gen6_mfc_common.c +++ b/src/gen6_mfc_common.c @@ -453,6 +453,58 @@ void intel_mfc_brc_prepare(struct encode_state *encode_state, } } +static int intel_avc_find_skipemulcnt(unsigned char *buf, int bits_length) +{ + int i, found; + int leading_zero_cnt, byte_length, zero_byte; + int nal_unit_type; + int skip_cnt = 0; + +#define NAL_UNIT_TYPE_MASK 0x1f +#define HW_MAX_SKIP_LENGTH 15 + + byte_length = ALIGN(bits_length, 32) >> 3; + + + leading_zero_cnt = 0; + found = 0; + for(i = 0; i < byte_length - 4; i++) { + if (((buf[i] == 0) && (buf[i + 1] == 0) && (buf[i + 2] == 1)) || + ((buf[i] == 0) && (buf[i + 1] == 0) && (buf[i + 2] == 0) && (buf[i + 3] == 1))) { + found = 1; + break; + } + leading_zero_cnt++; + } + if (!found) { + /* warning message is complained. But anyway it will be inserted. */ + WARN_ONCE("Invalid packed header data. " + "Can't find the 000001 start_prefix code\n"); + return 0; + } + i = leading_zero_cnt; + + zero_byte = 0; + if (!((buf[i] == 0) && (buf[i + 1] == 0) && (buf[i + 2] == 1))) + zero_byte = 1; + + skip_cnt = leading_zero_cnt + zero_byte + 3; + + /* the unit header byte is accounted */ + nal_unit_type = (buf[skip_cnt]) & NAL_UNIT_TYPE_MASK; + skip_cnt += 1; + + if (nal_unit_type == 14 || nal_unit_type == 20 || nal_unit_type == 21) { + /* more unit header bytes are accounted for MVC/SVC */ + skip_cnt += 3; + } + if (skip_cnt > HW_MAX_SKIP_LENGTH) { + WARN_ONCE("Too many leading zeros are padded for packed data. " + "It is beyond the HW range.!!!\n"); + } + return skip_cnt; +} + void intel_mfc_avc_pipeline_header_programing(VADriverContextP ctx, struct encode_state *encode_state, struct intel_encoder_context *encoder_context, @@ -461,6 +513,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; + unsigned int skip_emul_byte_cnt; if (encode_state->packed_header_data[idx]) { VAEncPackedHeaderParameterBuffer *param = NULL; @@ -471,12 +524,13 @@ void intel_mfc_avc_pipeline_header_programing(VADriverContextP ctx, param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer; length_in_bits = param->bit_length; + skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits); mfc_context->insert_object(ctx, encoder_context, header_data, ALIGN(length_in_bits, 32) >> 5, length_in_bits & 0x1f, - 5, /* FIXME: check it */ + skip_emul_byte_cnt, 0, 0, !param->has_emulation_bytes, @@ -494,12 +548,14 @@ void intel_mfc_avc_pipeline_header_programing(VADriverContextP ctx, param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer; length_in_bits = param->bit_length; + skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits); + mfc_context->insert_object(ctx, encoder_context, header_data, ALIGN(length_in_bits, 32) >> 5, length_in_bits & 0x1f, - 5, /* FIXME: check it */ + skip_emul_byte_cnt, 0, 0, !param->has_emulation_bytes, @@ -517,12 +573,13 @@ void intel_mfc_avc_pipeline_header_programing(VADriverContextP ctx, param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer; length_in_bits = param->bit_length; + skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits); mfc_context->insert_object(ctx, encoder_context, header_data, ALIGN(length_in_bits, 32) >> 5, length_in_bits & 0x1f, - 5, /* FIXME: check it */ + skip_emul_byte_cnt, 0, 0, !param->has_emulation_bytes, |