summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhong Li <zhong.li@intel.com>2014-06-10 20:49:21 -0600
committerZhao, Yakui <yakui.zhao@intel.com>2014-09-09 09:12:56 +0800
commit22cdc92c99ef0805458e30b7b5ddb6b03c3731ff (patch)
tree3cc8439f61bd22f8f4116dcb2f031e4b908a1b94
parent812d8d039031bf20e66748a39edcdb8f9c798ec4 (diff)
downloadlibva-intel-driver-22cdc92c99ef0805458e30b7b5ddb6b03c3731ff.tar.gz
Add multi quality levels encoding support for GEN7
Two encoding quality levels are support on GEN7. Default quality level is set to be 1, which has better quality, but higher gpu usage. The second quality level is set to be 2, which has worse quality but it has lower gpu usage. Other platforms support for multi-quality-level will be added later. v1->v2: 1. follow haihao's comments to init and check quality_level. 2. remove CBR limitation for low quality level. (Zhao Yakui helps to merge several patches on staging so that it can be cherry-picked to master) Signed-off-by: Zhong Li <zhong.li@intel.com> Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
-rw-r--r--src/gen7_vme.c27
-rwxr-xr-xsrc/i965_drv_video.c9
-rw-r--r--src/i965_drv_video.h5
-rw-r--r--src/i965_encoder.c37
-rw-r--r--src/i965_encoder.h2
-rw-r--r--src/shaders/vme/inter_frame_ivb.asm22
-rw-r--r--src/shaders/vme/inter_frame_ivb.g7b16
-rw-r--r--src/shaders/vme/vme7.inc8
8 files changed, 109 insertions, 17 deletions
diff --git a/src/gen7_vme.c b/src/gen7_vme.c
index 042fe5d0..dc15445e 100644
--- a/src/gen7_vme.c
+++ b/src/gen7_vme.c
@@ -370,6 +370,7 @@ static VAStatus gen7_vme_avc_state_setup(VADriverContextP ctx,
unsigned int *mb_cost_table;
int i;
VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
+ unsigned int is_low_quality = (encoder_context->quality_level == ENCODER_LOW_QUALITY);
mb_cost_table = (unsigned int *)vme_context->vme_state_message;
//building VME state message
@@ -377,8 +378,9 @@ static VAStatus gen7_vme_avc_state_setup(VADriverContextP ctx,
assert(vme_context->vme_state.bo->virtual);
vme_state_message = (unsigned int *)vme_context->vme_state.bo->virtual;
- if ((slice_param->slice_type == SLICE_TYPE_P) ||
- (slice_param->slice_type == SLICE_TYPE_SP)) {
+ if (((slice_param->slice_type == SLICE_TYPE_P) ||
+ (slice_param->slice_type == SLICE_TYPE_SP) &&
+ !is_low_quality)) {
vme_state_message[0] = 0x01010101;
vme_state_message[1] = 0x10010101;
vme_state_message[2] = 0x0F0F0F0F;
@@ -544,7 +546,7 @@ gen7_vme_fill_vme_batchbuffer(VADriverContextP ctx,
/*inline data */
*command_ptr++ = (mb_width << 16 | mb_y << 8 | mb_x);
- *command_ptr++ = ( (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
+ *command_ptr++ = ((encoder_context->quality_level << 24) | (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
i += 1;
}
@@ -598,13 +600,18 @@ static void gen7_vme_pipeline_programing(VADriverContextP ctx,
int s;
bool allow_hwscore = true;
int kernel_shader;
-
- for (s = 0; s < encode_state->num_slice_params_ext; s++) {
- pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
- if ((pSliceParameter->macroblock_address % width_in_mbs)) {
- allow_hwscore = false;
- break;
- }
+ unsigned int is_low_quality = (encoder_context->quality_level == ENCODER_LOW_QUALITY);
+
+ if (is_low_quality)
+ allow_hwscore = false;
+ else {
+ for (s = 0; s < encode_state->num_slice_params_ext; s++) {
+ pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
+ if ((pSliceParameter->macroblock_address % width_in_mbs)) {
+ allow_hwscore = false;
+ break;
+ }
+ }
}
if ((pSliceParameter->slice_type == SLICE_TYPE_I) ||
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index b7a04853..7f35f01a 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -627,6 +627,7 @@ i965_GetConfigAttributes(VADriverContextP ctx,
int num_attribs)
{
VAStatus va_status;
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
int i;
va_status = i965_validate_config(ctx, profile, entrypoint);
@@ -672,6 +673,14 @@ i965_GetConfigAttributes(VADriverContextP ctx,
break;
}
+ case VAConfigAttribEncQualityRange:
+ if (entrypoint == VAEntrypointEncSlice) {
+ attrib_list[i].value = 1;
+ if(IS_GEN7(i965->intel.device_info))
+ attrib_list[i].value = ENCODER_QUALITY_RANGE;
+ break;
+ }
+
default:
/* Do nothing */
attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 10e87782..7b931d22 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -65,6 +65,11 @@
#define DEFAULT_HUE 0
#define DEFAULT_SATURATION 50
+#define ENCODER_QUALITY_RANGE 2
+#define ENCODER_DEFAULT_QUALITY 1
+#define ENCODER_HIGH_QUALITY ENCODER_DEFAULT_QUALITY
+#define ENCODER_LOW_QUALITY 2
+
struct i965_surface
{
struct object_base *base;
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index 14c37bb7..f1c1f3dc 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -123,6 +123,30 @@ intel_encoder_check_yuv_surface(VADriverContextP ctx,
}
static VAStatus
+intel_encoder_check_misc_parameter(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+
+ if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel] &&
+ encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer) {
+ VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer;
+ VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
+ encoder_context->quality_level = param_quality_level->quality_level;
+
+ if (encoder_context->quality_level == 0)
+ encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
+ else if (encoder_context->quality_level > encoder_context->quality_range)
+ goto error;
+ }
+
+ return VA_STATUS_SUCCESS;
+
+error:
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+}
+
+static VAStatus
intel_encoder_check_avc_parameter(VADriverContextP ctx,
struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
@@ -278,6 +302,9 @@ intel_encoder_sanity_check_input(VADriverContextP ctx,
vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
+ if (vaStatus == VA_STATUS_SUCCESS)
+ vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
+
out:
return vaStatus;
}
@@ -335,6 +362,8 @@ intel_enc_hw_context_init(VADriverContextP ctx,
encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
encoder_context->is_tmp_id = 0;
encoder_context->rate_control_mode = VA_RC_NONE;
+ encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
+ encoder_context->quality_range = 1;
switch (obj_config->profile) {
case VAProfileMPEG2Simple:
@@ -395,7 +424,13 @@ gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
struct hw_context *
gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
{
- return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
+ struct intel_encoder_context *encoder_context;
+
+ encoder_context = (struct intel_encoder_context *)intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
+
+ encoder_context->quality_range = ENCODER_QUALITY_RANGE;
+
+ return (struct hw_context *)encoder_context;
}
struct hw_context *
diff --git a/src/i965_encoder.h b/src/i965_encoder.h
index 71396d61..20d49fc2 100644
--- a/src/i965_encoder.h
+++ b/src/i965_encoder.h
@@ -43,6 +43,8 @@ struct intel_encoder_context
VASurfaceID input_yuv_surface;
int is_tmp_id;
unsigned int rate_control_mode;
+ unsigned int quality_level;
+ unsigned int quality_range;
void *vme_context;
void *mfc_context;
void (*vme_context_destroy)(void *vme_context);
diff --git a/src/shaders/vme/inter_frame_ivb.asm b/src/shaders/vme/inter_frame_ivb.asm
index 3c088511..46f2b4b0 100644
--- a/src/shaders/vme/inter_frame_ivb.asm
+++ b/src/shaders/vme/inter_frame_ivb.asm
@@ -391,12 +391,14 @@ mov (1) mb_intra_struct_ub<1>:UB input_mb_intra_ub<0,1,0>:UB {align1};
/* M0 */
/* IME search */
+cmp.z.f0.0 (1) null<1>:uw quality_level_ub<0,1,0>:ub LOW_QUALITY_LEVEL:uw {align1};
+(f0.0) jmpi (1) __low_quality_search;
+
+__high_quality_search:
mov (1) vme_m0.12<1>:UD SEARCH_CTRL_SINGLE + INTER_PART_MASK + INTER_SAD_HAAR + SUB_PEL_MODE_QUARTER:UD {align1};
/* 16x16 Source, 1/4 pixel, harr */
mov (1) vme_m0.22<1>:UW REF_REGION_SIZE {align1}; /* Reference Width&Height, 48x40 */
-mov (1) vme_m0.0<1>:UD vme_m0.8<0,1,0>:UD {align1};
-
mov (1) vme_m0.0<1>:W -16:W {align1};
mov (1) vme_m0.2<1>:W -12:W {align1};
@@ -405,6 +407,22 @@ and.z.f0.0 (1) null:uw input_mb_intra_ub<0,1,0>:ub INTRA_PRED_AVAIL_FLAG_AE:uw
and.z.f0.0 (1) null:uw input_mb_intra_ub<0,1,0>:ub INTRA_PRED_AVAIL_FLAG_B:uw {align1};
(f0.0) add (1) vme_m0.2<1>:w vme_m0.2<0,1,0>:w 8:w {align1};
+jmpi __vme_msg;
+
+__low_quality_search:
+mov (1) vme_m0.12<1>:UD SEARCH_CTRL_SINGLE + INTER_PART_MASK + INTER_SAD_HAAR + SUB_PEL_MODE_HALF:UD {align1};
+/* 16x16 Source, 1/2 pixel, harr */
+mov (1) vme_m0.22<1>:UW MIN_REF_REGION_SIZE {align1}; /* Reference Width&Height, 32x32 */
+
+mov (1) vme_m0.0<1>:W -8:W {align1};
+mov (1) vme_m0.2<1>:W -8:W {align1};
+
+and.z.f0.0 (1) null:uw input_mb_intra_ub<0,1,0>:ub INTRA_PRED_AVAIL_FLAG_AE:uw {align1};
+(f0.0) add (1) vme_m0.0<1>:w vme_m0.0<0,1,0>:w 4:w {align1};
+and.z.f0.0 (1) null:uw input_mb_intra_ub<0,1,0>:ub INTRA_PRED_AVAIL_FLAG_B:uw {align1};
+(f0.0) add (1) vme_m0.2<1>:w vme_m0.2<0,1,0>:w 4:w {align1};
+
+__vme_msg:
mov (1) vme_m0.4<1>:UD vme_m0.0<0,1,0>:UD {align1};
add (2) vme_m0.0<1>:w vme_m0.0<2,2,1>:w mb_ref_win.16<2,2,1>:w {align1};
add (2) vme_m0.4<1>:w vme_m0.4<2,2,1>:w mb_ref_win.16<2,2,1>:w {align1};
diff --git a/src/shaders/vme/inter_frame_ivb.g7b b/src/shaders/vme/inter_frame_ivb.g7b
index e4db6ea7..7ed38c5e 100644
--- a/src/shaders/vme/inter_frame_ivb.g7b
+++ b/src/shaders/vme/inter_frame_ivb.g7b
@@ -141,13 +141,13 @@
{ 0x00000001, 0x2fa401ad, 0x00000b04, 0x00000000 },
{ 0x00000001, 0x2fa801ad, 0x00000b24, 0x00000000 },
{ 0x00000040, 0x2fe00c01, 0x00001400, 0x00000020 },
- { 0x00000020, 0x34001c00, 0x00001400, 0x000000bc },
+ { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 },
{ 0x00000001, 0x2ac001ad, 0x00000fe4, 0x00000000 },
{ 0x00000001, 0x2fa001ad, 0x00000ae6, 0x00000000 },
{ 0x00000001, 0x2fa401ad, 0x00000b06, 0x00000000 },
{ 0x00000001, 0x2fa801ad, 0x00000b26, 0x00000000 },
{ 0x00000040, 0x2fe00c01, 0x00001400, 0x00000020 },
- { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 },
+ { 0x00000020, 0x34001c00, 0x00001400, 0x000000c4 },
{ 0x00000001, 0x2ac201ad, 0x00000fe4, 0x00000000 },
{ 0x0020000c, 0x2a803dad, 0x00450ac0, 0x00020002 },
{ 0x00200040, 0x2a883dad, 0x00450a80, 0x00030003 },
@@ -163,15 +163,25 @@
{ 0x01000005, 0x20002e28, 0x000000a4, 0x00010001 },
{ 0x00010001, 0x247c0171, 0x00000000, 0x00020002 },
{ 0x00000001, 0x247d0231, 0x000000a5, 0x00000000 },
+ { 0x01000010, 0x20002e28, 0x000000a7, 0x00020002 },
+ { 0x00010020, 0x34001c00, 0x00001400, 0x00000012 },
{ 0x00000001, 0x244c0061, 0x00000000, 0x00203000 },
{ 0x00000001, 0x24560169, 0x00000000, 0x28302830 },
- { 0x00000001, 0x24400021, 0x00000448, 0x00000000 },
{ 0x00000001, 0x244001ed, 0x00000000, 0xfff0fff0 },
{ 0x00000001, 0x244201ed, 0x00000000, 0xfff4fff4 },
{ 0x01000005, 0x20002e28, 0x000000a5, 0x00600060 },
{ 0x00010040, 0x24403dad, 0x00000440, 0x000c000c },
{ 0x01000005, 0x20002e28, 0x000000a5, 0x00100010 },
{ 0x00010040, 0x24423dad, 0x00000442, 0x00080008 },
+ { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 },
+ { 0x00000001, 0x244c0061, 0x00000000, 0x00201000 },
+ { 0x00000001, 0x24560169, 0x00000000, 0x20202020 },
+ { 0x00000001, 0x244001ed, 0x00000000, 0xfff8fff8 },
+ { 0x00000001, 0x244201ed, 0x00000000, 0xfff8fff8 },
+ { 0x01000005, 0x20002e28, 0x000000a5, 0x00600060 },
+ { 0x00010040, 0x24403dad, 0x00000440, 0x00040004 },
+ { 0x01000005, 0x20002e28, 0x000000a5, 0x00100010 },
+ { 0x00010040, 0x24423dad, 0x00000442, 0x00040004 },
{ 0x00000001, 0x24440021, 0x00000440, 0x00000000 },
{ 0x00200040, 0x244035ad, 0x00450440, 0x00450a90 },
{ 0x00200040, 0x244435ad, 0x00450444, 0x00450a90 },
diff --git a/src/shaders/vme/vme7.inc b/src/shaders/vme/vme7.inc
index 3fa99b75..e9d5864e 100644
--- a/src/shaders/vme/vme7.inc
+++ b/src/shaders/vme/vme7.inc
@@ -54,6 +54,8 @@ define(`SEARCH_CTRL_DUAL_RECORD', `0x00000300')
define(`SEARCH_CTRL_DUAL_REFERENCE', `0x00000700')
define(`REF_REGION_SIZE', `0x2830:UW')
+define(`MIN_REF_REGION_SIZE', `0x2020:UW')
+define(`DREF_REGION_SIZE', `0x2020:UW')
define(`BI_SUB_MB_PART_MASK', `0x0c000000')
define(`MAX_NUM_MV', `0x00000020')
@@ -132,6 +134,7 @@ define(`orig_y_ub', `inline_reg0.1')
define(`transform_8x8_ub', `inline_reg0.4')
define(`input_mb_intra_ub', `inline_reg0.5')
define(`num_macroblocks', `inline_reg0.6')
+define(`quality_level_ub', `inline_reg0.7')
/*
* GRF 6~11 -- reserved
@@ -291,7 +294,6 @@ define(`mb_mv3', `r96')
define(`mb_ref', `r97')
define(`mb_ref_win', `r84')
-define(`DREF_REGION_SIZE', `0x2020:UW')
define(`PRED_L0', `0x0':uw)
define(`PRED_L1', `0x1':uw)
define(`PRED_BI', `0x2':uw)
@@ -317,3 +319,7 @@ define(`INTER_8X16MODE', `0x02')
define(`OBR_MESSAGE_FENCE', `7')
define(`OBR_MF_NOCOMMIT', `0')
define(`OBR_MF_COMMIT', `0x20')
+
+define(`DEFAULT_QUALITY_LEVEL', `0x01')
+define(`HIGH_QUALITY_LEVEL', `DEFAULT_QUALITY_LEVEL')
+define(`LOW_QUALITY_LEVEL', `0x02')