h264: Fix prediction weight table
The current code sets the prediction weight table by doing a memcpy of the libva structure to the v4l2's structure. However, for the offset and weight parameters, libva's structure uses 16-bits integer, while v4l2 uses 8-bits, which obviously doesn't work well with memcpy. Create a function to copy those arrays and matrices instead that follows the algorithm defined in the H264 spec, and use it so that it works properly. Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
This commit is contained in:
+37
-20
@@ -294,14 +294,34 @@ static void h264_va_matrix_to_v4l2(struct cedrus_data *driver_data,
|
|||||||
sizeof(v4l2_matrix->scaling_list_8x8[3]));
|
sizeof(v4l2_matrix->scaling_list_8x8[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void h264_copy_pred_table(struct v4l2_h264_weight_factors *factors,
|
||||||
|
unsigned int num_refs,
|
||||||
|
int16_t luma_weight[32],
|
||||||
|
int16_t luma_offset[32],
|
||||||
|
int16_t chroma_weight[32][2],
|
||||||
|
int16_t chroma_offset[32][2])
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_refs; i++) {
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
factors->luma_weight[i] = luma_weight[i];
|
||||||
|
factors->luma_offset[i] = luma_offset[i];
|
||||||
|
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
factors->chroma_weight[i][j] = chroma_weight[i][j];
|
||||||
|
factors->chroma_offset[i][j] = chroma_offset[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void h264_va_slice_to_v4l2(struct cedrus_data *driver_data,
|
static void h264_va_slice_to_v4l2(struct cedrus_data *driver_data,
|
||||||
struct object_context *context,
|
struct object_context *context,
|
||||||
VASliceParameterBufferH264 *VASlice,
|
VASliceParameterBufferH264 *VASlice,
|
||||||
VAPictureParameterBufferH264 *VAPicture,
|
VAPictureParameterBufferH264 *VAPicture,
|
||||||
struct v4l2_ctrl_h264_slice_param *slice)
|
struct v4l2_ctrl_h264_slice_param *slice)
|
||||||
{
|
{
|
||||||
struct v4l2_h264_weight_factors *factors;
|
|
||||||
|
|
||||||
slice->size = VASlice->slice_data_size;
|
slice->size = VASlice->slice_data_size;
|
||||||
slice->header_bit_size = VASlice->slice_data_bit_offset;
|
slice->header_bit_size = VASlice->slice_data_bit_offset;
|
||||||
slice->first_mb_in_slice = VASlice->first_mb_in_slice;
|
slice->first_mb_in_slice = VASlice->first_mb_in_slice;
|
||||||
@@ -360,25 +380,22 @@ static void h264_va_slice_to_v4l2(struct cedrus_data *driver_data,
|
|||||||
slice->pred_weight_table.luma_log2_weight_denom =
|
slice->pred_weight_table.luma_log2_weight_denom =
|
||||||
VASlice->luma_log2_weight_denom;
|
VASlice->luma_log2_weight_denom;
|
||||||
|
|
||||||
factors = &slice->pred_weight_table.weight_factors[0];
|
if (((VASlice->slice_type % 5) == H264_SLICE_P) ||
|
||||||
memcpy(&factors->chroma_weight, &VASlice->chroma_weight_l0,
|
((VASlice->slice_type % 5) == H264_SLICE_B))
|
||||||
sizeof(factors->chroma_weight));
|
h264_copy_pred_table(&slice->pred_weight_table.weight_factors[0],
|
||||||
memcpy(&factors->chroma_offset, &VASlice->chroma_offset_l0,
|
slice->num_ref_idx_l0_active_minus1 + 1,
|
||||||
sizeof(factors->chroma_offset));
|
VASlice->luma_weight_l0,
|
||||||
memcpy(&factors->luma_weight, &VASlice->luma_weight_l0,
|
VASlice->luma_offset_l0,
|
||||||
sizeof(factors->luma_weight));
|
VASlice->chroma_weight_l0,
|
||||||
memcpy(&factors->luma_offset, &VASlice->luma_offset_l0,
|
VASlice->chroma_offset_l0);
|
||||||
sizeof(factors->luma_offset));
|
|
||||||
|
|
||||||
factors = &slice->pred_weight_table.weight_factors[1];
|
if ((VASlice->slice_type % 5) == H264_SLICE_B)
|
||||||
memcpy(&factors->chroma_weight, &VASlice->chroma_weight_l1,
|
h264_copy_pred_table(&slice->pred_weight_table.weight_factors[1],
|
||||||
sizeof(factors->chroma_weight));
|
slice->num_ref_idx_l1_active_minus1 + 1,
|
||||||
memcpy(&factors->chroma_offset, &VASlice->chroma_offset_l1,
|
VASlice->luma_weight_l1,
|
||||||
sizeof(factors->chroma_offset));
|
VASlice->luma_offset_l1,
|
||||||
memcpy(&factors->luma_weight, &VASlice->luma_weight_l1,
|
VASlice->chroma_weight_l1,
|
||||||
sizeof(factors->luma_weight));
|
VASlice->chroma_offset_l1);
|
||||||
memcpy(&factors->luma_offset, &VASlice->luma_offset_l1,
|
|
||||||
sizeof(factors->luma_offset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int h264_set_controls(struct cedrus_data *driver_data,
|
int h264_set_controls(struct cedrus_data *driver_data,
|
||||||
|
|||||||
Reference in New Issue
Block a user