summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gen6_mfc_common.c63
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,