vulkan/video: fix to write a h264 slice header for CAVLC mode
In CAVLC mode, slice header doesn't need to be aligned. Instead encoder needs exact bits written in the slice header in order to set the offset correctly. This fixes encoding with entropy_coding_mode_flag false. Signed-off-by: Hyunjun Ko <zzoon@igalia.com> Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36152>
This commit is contained in:
@@ -1151,15 +1151,14 @@ anv_h264_encode_video(struct anv_cmd_buffer *cmd, const VkVideoEncodeInfoKHR *en
|
||||
unsigned h_in_mb = align(src_img->vk.extent.height, ANV_MB_HEIGHT) / ANV_MB_HEIGHT;
|
||||
|
||||
uint8_t slice_header_data[256] = { 0, };
|
||||
size_t slice_header_data_len_in_bytes = 0;
|
||||
size_t slice_header_data_len_in_bits = 0;
|
||||
vk_video_encode_h264_slice_header(frame_info->pStdPictureInfo,
|
||||
sps,
|
||||
pps,
|
||||
slice_header,
|
||||
slice_qp - (pps->pic_init_qp_minus26 + 26),
|
||||
&slice_header_data_len_in_bytes,
|
||||
&slice_header_data_len_in_bits,
|
||||
&slice_header_data);
|
||||
uint32_t slice_header_data_len_in_bits = slice_header_data_len_in_bytes * 8;
|
||||
|
||||
anv_batch_emit(&cmd->batch, GENX(MFX_AVC_SLICE_STATE), avc_slice) {
|
||||
avc_slice.SliceType = slice_type;
|
||||
|
||||
@@ -2500,20 +2500,34 @@ vk_video_encode_h264_slice_header(const StdVideoEncodeH264PictureInfo *pic_info,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bits_written = 0;
|
||||
|
||||
if (pps->flags.entropy_coding_mode_flag) {
|
||||
/* CABAC */
|
||||
int left = vl_bitstream_get_num_bits_for_byte_align(&enc);
|
||||
int val = (1 << left) - 1;
|
||||
|
||||
if (left)
|
||||
vl_bitstream_put_bits(&enc, left, val);
|
||||
|
||||
ASSERTED bool is_aligned = vl_bitstream_is_byte_aligned(&enc);
|
||||
assert(is_aligned);
|
||||
bits_written = vl_bitstream_get_byte_count(&enc) * 8;
|
||||
} else {
|
||||
/* CAVLC */
|
||||
uint32_t bits_in_last_byte = enc.bits_to_go == 32 ? 0 : 32 - enc.bits_to_go;
|
||||
uint32_t bytes_written = enc.offset;
|
||||
bits_written = bytes_written * 8 + bits_in_last_byte;
|
||||
|
||||
/* Just padding to be aligned for flush, doesn't matter for the slice header.
|
||||
*/
|
||||
if (!vl_bitstream_is_byte_aligned(&enc)) {
|
||||
uint32_t left = vl_bitstream_get_num_bits_for_byte_align(&enc);
|
||||
|
||||
if (left)
|
||||
vl_bitstream_put_bits(&enc, left, 0);
|
||||
}
|
||||
}
|
||||
|
||||
vl_bitstream_rbsp_trailing(&enc);
|
||||
vl_bitstream_flush(&enc);
|
||||
*data_size_ptr += vl_bitstream_get_byte_count(&enc);
|
||||
*data_size_ptr += bits_written;
|
||||
vl_bitstream_encoder_free(&enc);
|
||||
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user