Generate needed packed headers, fix h264 encoding on amd
This commit is contained in:
parent
3de05d047e
commit
560e43eea8
3 changed files with 323 additions and 58 deletions
|
@ -1,8 +1,8 @@
|
|||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
#define WIDTH 3200
|
||||
#define HEIGHT 2400
|
||||
#define WIDTH 1920
|
||||
#define HEIGHT 1080
|
||||
#define WORKGROUP_SIZE 32
|
||||
layout (local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1 ) in;
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@
|
|||
#define SLICE_TYPE_B 1
|
||||
#define SLICE_TYPE_I 2
|
||||
|
||||
#define IS_P_SLICE(type) (SLICE_TYPE_P == (type))
|
||||
#define IS_B_SLICE(type) (SLICE_TYPE_B == (type))
|
||||
#define IS_I_SLICE(type) (SLICE_TYPE_I == (type))
|
||||
|
||||
|
||||
#define ENTROPY_MODE_CAVLC 0
|
||||
#define ENTROPY_MODE_CABAC 1
|
||||
|
||||
|
@ -109,6 +114,88 @@ struct vaapi_recorder {
|
|||
} encoder;
|
||||
};
|
||||
|
||||
/*
|
||||
* {surface = 4, surface_region = 0x7fffe8003e38, surface_color_standard = VAProcColorStandardNone, output_region = 0x0,
|
||||
output_background_color = 4278190080, output_color_standard = VAProcColorStandardNone, pipeline_flags = 0, filter_flags = 512, filters = 0x0,
|
||||
num_filters = 0, forward_references = 0x0, num_forward_references = 0, backward_references = 0x0, num_backward_references = 0, rotation_state = 0,
|
||||
blend_state = 0x0, mirror_state = 0, additional_outputs = 0x0, num_additional_outputs = 0, input_surface_flag = 0, output_surface_flag = 0,
|
||||
input_color_properties = {chroma_sample_location = 0 '\000', color_range = 1 '\001', colour_primaries = 2 '\002',
|
||||
transfer_characteristics = 2 '\002', matrix_coefficients = 0 '\000', reserved = "\000\000"}, output_color_properties = {
|
||||
chroma_sample_location = 0 '\000', color_range = 1 '\001', colour_primaries = 2 '\002', transfer_characteristics = 2 '\002',
|
||||
matrix_coefficients = 2 '\002', reserved = "\000\000"}, processing_mode = VAProcDefaultMode, output_hdr_metadata = 0x0, va_reserved = {
|
||||
0 <repeats 16 times>}}
|
||||
{surface = 7, surface_region = 0x7fffe8003e38, surface_color_standard = VAProcColorStandardNone, output_region = 0x0,
|
||||
output_background_color = 4278190080, output_color_standard = VAProcColorStandardNone, pipeline_flags = 0, filter_flags = 512, filters = 0x0,
|
||||
num_filters = 0, forward_references = 0x0, num_forward_references = 0, backward_references = 0x0, num_backward_references = 0, rotation_state = 0,
|
||||
blend_state = 0x0, mirror_state = 0, additional_outputs = 0x0, num_additional_outputs = 0, input_surface_flag = 0, output_surface_flag = 0,
|
||||
input_color_properties = {chroma_sample_location = 0 '\000', color_range = 1 '\001', colour_primaries = 2 '\002',
|
||||
transfer_characteristics = 2 '\002', matrix_coefficients = 0 '\000', reserved = "\000\000"}, output_color_properties = {
|
||||
chroma_sample_location = 0 '\000', color_range = 1 '\001', colour_primaries = 2 '\002', transfer_characteristics = 2 '\002',
|
||||
matrix_coefficients = 2 '\002', reserved = "\000\000"}, processing_mode = VAProcDefaultMode, output_hdr_metadata = 0x0, va_reserved = {
|
||||
0 <repeats 16 times>}}
|
||||
|
||||
|
||||
* SPS
|
||||
* {seq_parameter_set_id = 0 '\000', level_idc = 60 '<', intra_period = 32767, intra_idr_period = 32767, ip_period = 1, bits_per_second = 0,
|
||||
max_num_ref_frames = 1, picture_width_in_mbs = 200, picture_height_in_mbs = 138, seq_fields = {bits = {chroma_format_idc = 1,
|
||||
frame_mbs_only_flag = 1, mb_adaptive_frame_field_flag = 0, seq_scaling_matrix_present_flag = 0, direct_8x8_inference_flag = 1,
|
||||
log2_max_frame_num_minus4 = 4, pic_order_cnt_type = 2, log2_max_pic_order_cnt_lsb_minus4 = 0, delta_pic_order_always_zero_flag = 0},
|
||||
value = 2341}, bit_depth_luma_minus8 = 0 '\000', bit_depth_chroma_minus8 = 0 '\000', num_ref_frames_in_pic_order_cnt_cycle = 0 '\000',
|
||||
offset_for_non_ref_pic = 0, offset_for_top_to_bottom_field = 0, offset_for_ref_frame = {0 <repeats 256 times>}, frame_cropping_flag = 1 '\001',
|
||||
frame_crop_left_offset = 0, frame_crop_right_offset = 0, frame_crop_top_offset = 0, frame_crop_bottom_offset = 4,
|
||||
vui_parameters_present_flag = 1 '\001', vui_fields = {bits = {aspect_ratio_info_present_flag = 0, timing_info_present_flag = 1,
|
||||
bitstream_restriction_flag = 1, log2_max_mv_length_horizontal = 15, log2_max_mv_length_vertical = 15, fixed_frame_rate_flag = 0,
|
||||
low_delay_hrd_flag = 0, motion_vectors_over_pic_boundaries_flag = 0, reserved = 0}, value = 3966}, aspect_ratio_idc = 0 '\000', sar_width = 0,
|
||||
sar_height = 0, num_units_in_tick = 1, time_scale = 180, va_reserved = {0, 0, 0, 0}}
|
||||
|
||||
* PPS
|
||||
* {CurrPic = {picture_id = 5, frame_idx = 0, flags = 0, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0, 0}},
|
||||
ReferenceFrames = {{picture_id = 4294967295, frame_idx = 0, flags = 1, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0,
|
||||
0}} <repeats 16 times>}, coded_buf = 9, pic_parameter_set_id = 0 '\000', seq_parameter_set_id = 0 '\000', last_picture = 0 '\000',
|
||||
frame_num = 0, pic_init_qp = 20 '\024', num_ref_idx_l0_active_minus1 = 0 '\000', num_ref_idx_l1_active_minus1 = 0 '\000',
|
||||
chroma_qp_index_offset = 0 '\000', second_chroma_qp_index_offset = 0 '\000', pic_fields = {bits = {idr_pic_flag = 1, reference_pic_flag = 1,
|
||||
entropy_coding_mode_flag = 1, weighted_pred_flag = 0, weighted_bipred_idc = 0, constrained_intra_pred_flag = 0, transform_8x8_mode_flag = 1,
|
||||
deblocking_filter_control_present_flag = 0, redundant_pic_cnt_present_flag = 0, pic_order_present_flag = 0,
|
||||
pic_scaling_matrix_present_flag = 0}, value = 267}, va_reserved = {0, 0, 0, 0}}
|
||||
|
||||
* I
|
||||
* {macroblock_address = 0, num_macroblocks = 27600, macroblock_info = 4294967295, slice_type = 2 '\002', pic_parameter_set_id = 0 '\000',
|
||||
idr_pic_id = 0, pic_order_cnt_lsb = 0, delta_pic_order_cnt_bottom = 0, delta_pic_order_cnt = {0, 0}, direct_spatial_mv_pred_flag = 1 '\001',
|
||||
num_ref_idx_active_override_flag = 0 '\000', num_ref_idx_l0_active_minus1 = 0 '\000', num_ref_idx_l1_active_minus1 = 0 '\000', RefPicList0 = {{
|
||||
picture_id = 4294967295, frame_idx = 0, flags = 1, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0,
|
||||
0}} <repeats 32 times>}, RefPicList1 = {{picture_id = 4294967295, frame_idx = 0, flags = 1, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0,
|
||||
va_reserved = {0, 0, 0, 0}} <repeats 32 times>}, luma_log2_weight_denom = 0 '\000', chroma_log2_weight_denom = 0 '\000',
|
||||
luma_weight_l0_flag = 0 '\000', luma_weight_l0 = {0 <repeats 32 times>}, luma_offset_l0 = {0 <repeats 32 times>}, chroma_weight_l0_flag = 0 '\000',
|
||||
chroma_weight_l0 = {{0, 0} <repeats 32 times>}, chroma_offset_l0 = {{0, 0} <repeats 32 times>}, luma_weight_l1_flag = 0 '\000', luma_weight_l1 = {
|
||||
0 <repeats 32 times>}, luma_offset_l1 = {0 <repeats 32 times>}, chroma_weight_l1_flag = 0 '\000', chroma_weight_l1 = {{0, 0} <repeats 32 times>},
|
||||
chroma_offset_l1 = {{0, 0} <repeats 32 times>}, cabac_init_idc = 0 '\000', slice_qp_delta = 0 '\000', disable_deblocking_filter_idc = 0 '\000',
|
||||
slice_alpha_c0_offset_div2 = 0 '\000', slice_beta_offset_div2 = 0 '\000', va_reserved = {0, 0, 0, 0}}
|
||||
|
||||
{CurrPic = {picture_id = 1, frame_idx = 1, flags = 0, TopFieldOrderCnt = 2, BottomFieldOrderCnt = 2, va_reserved = {0, 0, 0, 0}},
|
||||
ReferenceFrames = {{picture_id = 5, frame_idx = 0, flags = 8, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0, 0}}, {
|
||||
picture_id = 4294967295, frame_idx = 0, flags = 1, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0,
|
||||
0}} <repeats 15 times>}, coded_buf = 3, pic_parameter_set_id = 0 '\000', seq_parameter_set_id = 0 '\000', last_picture = 0 '\000',
|
||||
frame_num = 1, pic_init_qp = 20 '\024', num_ref_idx_l0_active_minus1 = 0 '\000', num_ref_idx_l1_active_minus1 = 0 '\000',
|
||||
chroma_qp_index_offset = 0 '\000', second_chroma_qp_index_offset = 0 '\000', pic_fields = {bits = {idr_pic_flag = 0, reference_pic_flag = 1,
|
||||
entropy_coding_mode_flag = 1, weighted_pred_flag = 0, weighted_bipred_idc = 0, constrained_intra_pred_flag = 0, transform_8x8_mode_flag = 1,
|
||||
deblocking_filter_control_present_flag = 0, redundant_pic_cnt_present_flag = 0, pic_order_present_flag = 0,
|
||||
pic_scaling_matrix_present_flag = 0}, value = 266}, va_reserved = {0, 0, 0, 0}}
|
||||
|
||||
*P
|
||||
{macroblock_address = 0, num_macroblocks = 27600, macroblock_info = 4294967295, slice_type = 0 '\000', pic_parameter_set_id = 0 '\000',
|
||||
idr_pic_id = 0, pic_order_cnt_lsb = 2, delta_pic_order_cnt_bottom = 0, delta_pic_order_cnt = {0, 0}, direct_spatial_mv_pred_flag = 1 '\001',
|
||||
num_ref_idx_active_override_flag = 0 '\000', num_ref_idx_l0_active_minus1 = 0 '\000', num_ref_idx_l1_active_minus1 = 0 '\000', RefPicList0 = {{
|
||||
picture_id = 5, frame_idx = 0, flags = 8, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0, 0}}, {picture_id = 4294967295,
|
||||
frame_idx = 0, flags = 1, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0, 0}} <repeats 31 times>}, RefPicList1 = {{
|
||||
picture_id = 4294967295, frame_idx = 0, flags = 1, TopFieldOrderCnt = 0, BottomFieldOrderCnt = 0, va_reserved = {0, 0, 0,
|
||||
0}} <repeats 32 times>}, luma_log2_weight_denom = 0 '\000', chroma_log2_weight_denom = 0 '\000', luma_weight_l0_flag = 0 '\000',
|
||||
luma_weight_l0 = {0 <repeats 32 times>}, luma_offset_l0 = {0 <repeats 32 times>}, chroma_weight_l0_flag = 0 '\000', chroma_weight_l0 = {{0,
|
||||
0} <repeats 32 times>}, chroma_offset_l0 = {{0, 0} <repeats 32 times>}, luma_weight_l1_flag = 0 '\000', luma_weight_l1 = {
|
||||
0 <repeats 32 times>}, luma_offset_l1 = {0 <repeats 32 times>}, chroma_weight_l1_flag = 0 '\000', chroma_weight_l1 = {{0, 0} <repeats 32 times>},
|
||||
chroma_offset_l1 = {{0, 0} <repeats 32 times>}, cabac_init_idc = 0 '\000', slice_qp_delta = 0 '\000', disable_deblocking_filter_idc = 0 '\000',
|
||||
slice_alpha_c0_offset_div2 = 0 '\000', slice_beta_offset_div2 = 0 '\000', va_reserved = {0, 0, 0, 0}}
|
||||
*/
|
||||
|
||||
static void *
|
||||
worker_thread_function(void *);
|
||||
|
||||
|
@ -167,22 +254,19 @@ bitstream_put_ui(struct bitstream *bs, unsigned int val, int size_in_bits)
|
|||
|
||||
if (bit_left > size_in_bits) {
|
||||
bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val);
|
||||
return;
|
||||
} else {
|
||||
size_in_bits -= bit_left;
|
||||
bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
|
||||
bs->buffer[pos] = va_swap32(bs->buffer[pos]);
|
||||
|
||||
if (pos + 1 == bs->max_size_in_dword) {
|
||||
bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
|
||||
bs->buffer = (unsigned int*)realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int));
|
||||
assert(bs->buffer);
|
||||
}
|
||||
|
||||
bs->buffer[pos + 1] = val;
|
||||
}
|
||||
|
||||
size_in_bits -= bit_left;
|
||||
bs->buffer[pos] =
|
||||
(bs->buffer[pos] << bit_left) | (val >> size_in_bits);
|
||||
bs->buffer[pos] = va_swap32(bs->buffer[pos]);
|
||||
|
||||
if (pos + 1 == bs->max_size_in_dword) {
|
||||
bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
|
||||
bs->buffer = (unsigned int *)
|
||||
realloc(bs->buffer,
|
||||
bs->max_size_in_dword * sizeof(unsigned int));
|
||||
}
|
||||
|
||||
bs->buffer[pos + 1] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -284,15 +368,16 @@ encoder_init_seq_parameters(struct vaapi_recorder *r)
|
|||
width_in_mbs = (r->width + 15) / 16;
|
||||
height_in_mbs = (r->height + 15) / 16;
|
||||
|
||||
r->encoder.param.seq.level_idc = 41;
|
||||
r->encoder.param.seq.intra_period = r->encoder.intra_period;
|
||||
r->encoder.param.seq.max_num_ref_frames = 4;
|
||||
r->encoder.param.seq.level_idc = 60;
|
||||
r->encoder.param.seq.intra_period = 32767; //r->encoder.intra_period;
|
||||
r->encoder.param.seq.max_num_ref_frames = 1;
|
||||
r->encoder.param.seq.picture_width_in_mbs = width_in_mbs;
|
||||
r->encoder.param.seq.picture_height_in_mbs = height_in_mbs;
|
||||
r->encoder.param.seq.seq_fields.bits.chroma_format_idc = 1;
|
||||
r->encoder.param.seq.seq_fields.bits.frame_mbs_only_flag = 1;
|
||||
|
||||
/* Tc = num_units_in_tick / time_scale */
|
||||
r->encoder.param.seq.time_scale = 1800;
|
||||
r->encoder.param.seq.time_scale = 180;
|
||||
r->encoder.param.seq.num_units_in_tick = 15;
|
||||
|
||||
if (height_in_mbs * 16 - r->height > 0) {
|
||||
|
@ -303,7 +388,9 @@ encoder_init_seq_parameters(struct vaapi_recorder *r)
|
|||
r->encoder.param.seq.frame_cropping_flag = frame_cropping_flag;
|
||||
r->encoder.param.seq.frame_crop_bottom_offset = frame_crop_bottom_offset;
|
||||
|
||||
r->encoder.param.seq.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = 2;
|
||||
r->encoder.param.seq.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = 0;
|
||||
r->encoder.param.seq.seq_fields.bits.log2_max_frame_num_minus4 = 4;
|
||||
r->encoder.param.seq.seq_fields.bits.pic_order_cnt_type = 2;
|
||||
}
|
||||
|
||||
static VABufferID
|
||||
|
@ -332,12 +419,13 @@ encoder_init_pic_parameters(struct vaapi_recorder *r)
|
|||
{
|
||||
VAEncPictureParameterBufferH264 *pic = &r->encoder.param.pic;
|
||||
|
||||
pic->pic_init_qp = 0;
|
||||
pic->pic_init_qp = 11;
|
||||
|
||||
/* ENTROPY_MODE_CABAC */
|
||||
pic->pic_fields.bits.entropy_coding_mode_flag = 1;
|
||||
|
||||
pic->pic_fields.bits.deblocking_filter_control_present_flag = 1;
|
||||
pic->pic_fields.bits.deblocking_filter_control_present_flag = 0;
|
||||
|
||||
}
|
||||
|
||||
static VABufferID
|
||||
|
@ -353,10 +441,21 @@ encoder_update_pic_parameters(struct vaapi_recorder *r,
|
|||
pic0 = r->encoder.reference_picture[(r->frame_count + 1) % 2];
|
||||
|
||||
pic->CurrPic.picture_id = curr_pic;
|
||||
pic->CurrPic.TopFieldOrderCnt = r->frame_count * 2;
|
||||
pic->ReferenceFrames[0].picture_id = r->frame_count?pic0:VA_INVALID_ID;
|
||||
pic->ReferenceFrames[1].picture_id = VA_INVALID_ID; // TODOr->frame_count > 1?r->encoder.reference_picture[2]:VA_INVALID_ID;
|
||||
pic->ReferenceFrames[2].picture_id = VA_INVALID_ID;
|
||||
pic->CurrPic.frame_idx = r->frame_count;
|
||||
pic->CurrPic.TopFieldOrderCnt = 0;//r->frame_count * 2;
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
pic->ReferenceFrames[i].picture_id = VA_INVALID_ID;
|
||||
pic->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
|
||||
}
|
||||
if(r->frame_count)
|
||||
{
|
||||
pic->ReferenceFrames[0].picture_id = pic0;
|
||||
pic->ReferenceFrames[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
||||
pic->ReferenceFrames[0].frame_idx = r->frame_count - 1;
|
||||
}
|
||||
//pic->ReferenceFrames[1].picture_id = VA_INVALID_ID; // TODOr->frame_count > 1?r->encoder.reference_picture[2]:VA_INVALID_ID;
|
||||
//pic->ReferenceFrames[2].picture_id = VA_INVALID_ID;
|
||||
|
||||
pic->coded_buf = output_buf;
|
||||
pic->frame_num = r->frame_count;
|
||||
|
@ -390,7 +489,26 @@ encoder_update_slice_parameter(struct vaapi_recorder *r, int slice_type)
|
|||
memset(&r->encoder.param.slice, 0, sizeof r->encoder.param.slice);
|
||||
|
||||
r->encoder.param.slice.num_macroblocks = width_in_mbs * height_in_mbs;
|
||||
r->encoder.param.slice.macroblock_info = VA_INVALID_ID;
|
||||
r->encoder.param.slice.slice_type = slice_type;
|
||||
r->encoder.param.slice.direct_spatial_mv_pred_flag = 1;
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
r->encoder.param.slice.RefPicList0[i].picture_id = VA_INVALID_ID;
|
||||
r->encoder.param.slice.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
|
||||
}
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
r->encoder.param.slice.RefPicList1[i].picture_id = VA_INVALID_ID;
|
||||
r->encoder.param.slice.RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
|
||||
}
|
||||
if(r->frame_count)
|
||||
{
|
||||
r->encoder.param.slice.RefPicList0[0].frame_idx = r->frame_count - 1;
|
||||
r->encoder.param.slice.RefPicList0[0].picture_id = r->encoder.reference_picture[(r->frame_count - 1)% 2];
|
||||
r->encoder.param.slice.RefPicList0[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
||||
}
|
||||
//r->encoder.param.slice.RefPicList0
|
||||
|
||||
r->encoder.param.slice.slice_alpha_c0_offset_div2 = 2;
|
||||
r->encoder.param.slice.slice_beta_offset_div2 = 2;
|
||||
|
@ -471,7 +589,7 @@ setup_encoder(struct vaapi_recorder *r)
|
|||
|
||||
r->encoder.output_size = r->width * r->height;
|
||||
|
||||
r->encoder.intra_period = 30;
|
||||
r->encoder.intra_period = 32767;
|
||||
|
||||
encoder_init_seq_parameters(r);
|
||||
encoder_init_pic_parameters(r);
|
||||
|
@ -516,7 +634,7 @@ static void sps_rbsp(struct bitstream *bs,
|
|||
{
|
||||
int i;
|
||||
|
||||
bitstream_put_ui(bs, PROFILE_IDC_MAIN, 8);
|
||||
bitstream_put_ui(bs, PROFILE_IDC_BASELINE, 8);
|
||||
|
||||
/* constraint_set[0-3] flag */
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
@ -531,7 +649,8 @@ static void sps_rbsp(struct bitstream *bs,
|
|||
|
||||
bitstream_put_ue(bs, seq->seq_fields.bits.log2_max_frame_num_minus4);
|
||||
bitstream_put_ue(bs, seq->seq_fields.bits.pic_order_cnt_type);
|
||||
bitstream_put_ue(bs,
|
||||
if(seq->seq_fields.bits.pic_order_cnt_type != 2)
|
||||
bitstream_put_ue(bs,
|
||||
seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
|
||||
|
||||
bitstream_put_ue(bs, seq->max_num_ref_frames);
|
||||
|
@ -633,6 +752,102 @@ static void pps_rbsp(struct bitstream *bs,
|
|||
rbsp_trailing_bits(bs);
|
||||
}
|
||||
|
||||
static void slice_header(bitstream *bs, VAEncSequenceParameterBufferH264 *seq,VAEncPictureParameterBufferH264 *pic, VAEncSliceParameterBufferH264 *slice )
|
||||
{
|
||||
int first_mb_in_slice = slice->macroblock_address;
|
||||
|
||||
bitstream_put_ue(bs, first_mb_in_slice); /* first_mb_in_slice: 0 */
|
||||
bitstream_put_ue(bs, slice->slice_type); /* slice_type */
|
||||
bitstream_put_ue(bs, slice->pic_parameter_set_id); /* pic_parameter_set_id: 0 */
|
||||
bitstream_put_ui(bs, pic->frame_num, seq->seq_fields.bits.log2_max_frame_num_minus4 + 4); /* frame_num */
|
||||
|
||||
/* frame_mbs_only_flag == 1 */
|
||||
if (!seq->seq_fields.bits.frame_mbs_only_flag) {
|
||||
/* FIXME: */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (pic->pic_fields.bits.idr_pic_flag)
|
||||
bitstream_put_ue(bs, slice->idr_pic_id); /* idr_pic_id: 0 */
|
||||
|
||||
if (seq->seq_fields.bits.pic_order_cnt_type == 0) {
|
||||
bitstream_put_ui(bs, pic->CurrPic.TopFieldOrderCnt, seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
|
||||
/* pic_order_present_flag == 0 */
|
||||
} else {
|
||||
/* FIXME: */
|
||||
// assert(0);
|
||||
}
|
||||
|
||||
/* redundant_pic_cnt_present_flag == 0 */
|
||||
/* slice type */
|
||||
if (IS_P_SLICE(slice->slice_type)) {
|
||||
bitstream_put_ui(bs, slice->num_ref_idx_active_override_flag, 1); /* num_ref_idx_active_override_flag: */
|
||||
|
||||
if (slice->num_ref_idx_active_override_flag)
|
||||
bitstream_put_ue(bs, slice->num_ref_idx_l0_active_minus1);
|
||||
|
||||
/* ref_pic_list_reordering */
|
||||
bitstream_put_ui(bs, 0, 1); /* ref_pic_list_reordering_flag_l0: 0 */
|
||||
} else if (IS_B_SLICE(slice->slice_type)) {
|
||||
bitstream_put_ui(bs, slice->direct_spatial_mv_pred_flag, 1); /* direct_spatial_mv_pred: 1 */
|
||||
|
||||
bitstream_put_ui(bs, slice->num_ref_idx_active_override_flag, 1); /* num_ref_idx_active_override_flag: */
|
||||
|
||||
if (slice->num_ref_idx_active_override_flag) {
|
||||
bitstream_put_ue(bs, slice->num_ref_idx_l0_active_minus1);
|
||||
bitstream_put_ue(bs, slice->num_ref_idx_l1_active_minus1);
|
||||
}
|
||||
|
||||
/* ref_pic_list_reordering */
|
||||
bitstream_put_ui(bs, 0, 1); /* ref_pic_list_reordering_flag_l0: 0 */
|
||||
bitstream_put_ui(bs, 0, 1); /* ref_pic_list_reordering_flag_l1: 0 */
|
||||
}
|
||||
|
||||
if ((pic->pic_fields.bits.weighted_pred_flag &&
|
||||
IS_P_SLICE(slice->slice_type)) ||
|
||||
((pic->pic_fields.bits.weighted_bipred_idc == 1) &&
|
||||
IS_B_SLICE(slice->slice_type))) {
|
||||
/* FIXME: fill weight/offset table */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* dec_ref_pic_marking */
|
||||
if (pic->pic_fields.bits.reference_pic_flag) { /* nal_ref_idc != 0 */
|
||||
unsigned char no_output_of_prior_pics_flag = 0;
|
||||
unsigned char long_term_reference_flag = 0;
|
||||
unsigned char adaptive_ref_pic_marking_mode_flag = 0;
|
||||
|
||||
if (pic->pic_fields.bits.idr_pic_flag) {
|
||||
bitstream_put_ui(bs, no_output_of_prior_pics_flag, 1); /* no_output_of_prior_pics_flag: 0 */
|
||||
bitstream_put_ui(bs, long_term_reference_flag, 1); /* long_term_reference_flag: 0 */
|
||||
} else {
|
||||
bitstream_put_ui(bs, adaptive_ref_pic_marking_mode_flag, 1); /* adaptive_ref_pic_marking_mode_flag: 0 */
|
||||
}
|
||||
}
|
||||
|
||||
if (pic->pic_fields.bits.entropy_coding_mode_flag &&
|
||||
!IS_I_SLICE(slice->slice_type))
|
||||
bitstream_put_ue(bs, slice->cabac_init_idc); /* cabac_init_idc: 0 */
|
||||
|
||||
bitstream_put_se(bs, slice->slice_qp_delta); /* slice_qp_delta: 0 */
|
||||
|
||||
/* ignore for SP/SI */
|
||||
|
||||
if (pic->pic_fields.bits.deblocking_filter_control_present_flag) {
|
||||
bitstream_put_ue(bs, slice->disable_deblocking_filter_idc); /* disable_deblocking_filter_idc: 0 */
|
||||
|
||||
if (slice->disable_deblocking_filter_idc != 1) {
|
||||
bitstream_put_se(bs, slice->slice_alpha_c0_offset_div2); /* slice_alpha_c0_offset_div2: 2 */
|
||||
bitstream_put_se(bs, slice->slice_beta_offset_div2); /* slice_beta_offset_div2: 2 */
|
||||
}
|
||||
}
|
||||
|
||||
if (pic->pic_fields.bits.entropy_coding_mode_flag) {
|
||||
bitstream_byte_aligning(bs, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
build_packed_pic_buffer(struct vaapi_recorder *r,
|
||||
void **header_buffer)
|
||||
|
@ -699,6 +914,32 @@ create_packed_header_buffers(struct vaapi_recorder *r, VABufferID *buffers,
|
|||
return 2;
|
||||
}
|
||||
|
||||
static int build_packed_slice_buffer(unsigned char **header_buffer, VAEncSequenceParameterBufferH264 *seq,VAEncPictureParameterBufferH264 *pic, VAEncSliceParameterBufferH264 *slice )
|
||||
{
|
||||
bitstream bs;
|
||||
int is_idr = !!pic->pic_fields.bits.idr_pic_flag;
|
||||
int is_ref = !!pic->pic_fields.bits.reference_pic_flag;
|
||||
|
||||
bitstream_start(&bs);
|
||||
nal_start_code_prefix(&bs);
|
||||
|
||||
if (IS_I_SLICE(slice->slice_type)) {
|
||||
nal_header(&bs, NAL_REF_IDC_HIGH, is_idr ? NAL_IDR : NAL_NON_IDR);
|
||||
} else if (IS_P_SLICE(slice->slice_type)) {
|
||||
nal_header(&bs, NAL_REF_IDC_MEDIUM, NAL_NON_IDR);
|
||||
} else {
|
||||
assert(IS_B_SLICE(slice->slice_type));
|
||||
nal_header(&bs, is_ref ? NAL_REF_IDC_LOW : NAL_REF_IDC_NONE, NAL_NON_IDR);
|
||||
}
|
||||
|
||||
slice_header(&bs, seq, pic, slice );
|
||||
bitstream_end(&bs);
|
||||
|
||||
*header_buffer = (unsigned char *)bs.buffer;
|
||||
return bs.bit_offset;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
encoder_prepare_headers(struct vaapi_recorder *r, VABufferID *buffers)
|
||||
{
|
||||
|
@ -726,21 +967,7 @@ static VAStatus
|
|||
encoder_render_picture(struct vaapi_recorder *r, VASurfaceID input,
|
||||
VABufferID *buffers, int count)
|
||||
{
|
||||
VAStatus status;
|
||||
|
||||
status = vaBeginPicture(r->va_dpy, r->encoder.ctx, input);
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = vaRenderPicture(r->va_dpy, r->encoder.ctx, buffers, count);
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = vaEndPicture(r->va_dpy, r->encoder.ctx);
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return vaSyncSurface(r->va_dpy, input);
|
||||
}
|
||||
|
||||
static VABufferID
|
||||
|
@ -769,7 +996,7 @@ encoder_write_output(struct vaapi_recorder *r, VABufferID output_buf)
|
|||
{
|
||||
VACodedBufferSegment *segment;
|
||||
VAStatus status;
|
||||
int count;
|
||||
int count = 0;
|
||||
|
||||
status = vaMapBuffer(r->va_dpy, output_buf, (void **) &segment);
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
|
@ -781,7 +1008,13 @@ encoder_write_output(struct vaapi_recorder *r, VABufferID output_buf)
|
|||
return OUTPUT_WRITE_OVERFLOW;
|
||||
}
|
||||
|
||||
count = write(r->output_fd, segment->buf, segment->size);
|
||||
do
|
||||
{
|
||||
count += write(r->output_fd, segment->buf, segment->size);
|
||||
segment = (VACodedBufferSegment *)segment->next;
|
||||
}
|
||||
while(segment);
|
||||
|
||||
|
||||
vaUnmapBuffer(r->va_dpy, output_buf);
|
||||
|
||||
|
@ -796,12 +1029,12 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
{
|
||||
VABufferID output_buf = VA_INVALID_ID;
|
||||
|
||||
VABufferID buffers[8];
|
||||
VABufferID buffers[12];
|
||||
int count = 0;
|
||||
int i, slice_type;
|
||||
enum output_write_status ret;
|
||||
|
||||
if (1)//(r->frame_count % r->encoder.intra_period) == 0)
|
||||
if ((r->frame_count % r->encoder.intra_period) == 0)
|
||||
slice_type = SLICE_TYPE_I;
|
||||
else
|
||||
slice_type = SLICE_TYPE_P;
|
||||
|
@ -813,10 +1046,20 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
for (i = 0; i < count; i++)
|
||||
if (buffers[i] == VA_INVALID_ID)
|
||||
goto bail;
|
||||
VAStatus status;
|
||||
|
||||
if (r->frame_count == 0)
|
||||
count += encoder_prepare_headers(r, buffers + count);
|
||||
status = vaBeginPicture(r->va_dpy, r->encoder.ctx, input);
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
goto bail;
|
||||
//status = vaRenderPicture(r->va_dpy, r->encoder.ctx, &buffers[0], 1);
|
||||
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
goto bail;
|
||||
|
||||
|
||||
|
||||
|
||||
//status = vaRenderPicture(r->va_dpy, r->encoder.ctx, &buffers[2], 1);
|
||||
do {
|
||||
output_buf = encoder_create_output_buffer(r);
|
||||
if (output_buf == VA_INVALID_ID)
|
||||
|
@ -826,21 +1069,41 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
encoder_update_pic_parameters(r, output_buf);
|
||||
if (buffers[count - 1] == VA_INVALID_ID)
|
||||
goto bail;
|
||||
|
||||
VAStatus er = encoder_render_picture(r, input, buffers, count);
|
||||
if (r->frame_count == 0)
|
||||
count += encoder_prepare_headers(r, buffers + count);
|
||||
// todo: this might be required in every frame
|
||||
if(r->frame_count == 0)
|
||||
{
|
||||
void *data;
|
||||
uint32_t bit_length = build_packed_slice_buffer((unsigned char **)&data, &r->encoder.param.seq, &r->encoder.param.pic, &r->encoder.param.slice );
|
||||
count += create_packed_header_buffers(r, buffers + count, VAEncPackedHeaderSlice,
|
||||
data, bit_length);
|
||||
free(data);
|
||||
}
|
||||
status = vaRenderPicture(r->va_dpy, r->encoder.ctx, buffers, count);
|
||||
/*VAStatus er = encoder_render_picture(r, input, buffers, count);
|
||||
if(er != VA_STATUS_SUCCESS)
|
||||
{
|
||||
printf("render error %d\n", er);
|
||||
goto bail;
|
||||
}
|
||||
}*/
|
||||
|
||||
status = vaEndPicture(r->va_dpy, r->encoder.ctx);
|
||||
if (status != VA_STATUS_SUCCESS)
|
||||
goto bail;
|
||||
|
||||
status = vaSyncSurface(r->va_dpy, input);
|
||||
ret = encoder_write_output(r, output_buf);
|
||||
|
||||
vaDestroyBuffer(r->va_dpy, output_buf);
|
||||
output_buf = VA_INVALID_ID;
|
||||
|
||||
vaDestroyBuffer(r->va_dpy, buffers[--count]);
|
||||
if(ret == OUTPUT_WRITE_OVERFLOW)
|
||||
exit(1);
|
||||
} while (ret == OUTPUT_WRITE_OVERFLOW);
|
||||
|
||||
|
||||
if (ret == OUTPUT_WRITE_FATAL)
|
||||
r->error = errno;
|
||||
|
||||
|
|
|
@ -120,8 +120,8 @@ struct DrmHelper
|
|||
|
||||
DrmHelper gDrm;
|
||||
|
||||
const int WIDTH = 3200; // Size of rendered mandelbrot set.
|
||||
const int HEIGHT = 2400; // Size of renderered mandelbrot set.
|
||||
const int WIDTH = 1920; // Size of rendered mandelbrot set.
|
||||
const int HEIGHT = 1080; // Size of renderered mandelbrot set.
|
||||
const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader.
|
||||
|
||||
/// TODO: why it even should depend on NDEBUG???
|
||||
|
@ -256,7 +256,7 @@ public:
|
|||
vkMapMemory(device, bufferMemory, 0, sizeof(UBO), 0, (void**)&pMappedBuffer);
|
||||
createImageExportableDmabuf();
|
||||
int drm_fd = drm_fd = open("/dev/dri/renderD128", O_RDWR);
|
||||
auto *r = vaapi_recorder_create2(drm_fd, WIDTH, 2300, "out.264", prime_fd, WIDTH * 4);
|
||||
auto *r = vaapi_recorder_create2(drm_fd, WIDTH, 1080, "out.264", prime_fd, WIDTH * 4);
|
||||
createDescriptorSetLayout();
|
||||
//createDescriptorSet();
|
||||
createComputePipeline();
|
||||
|
@ -275,8 +275,10 @@ public:
|
|||
{
|
||||
// Finally, run the recorded command buffer.
|
||||
runCommandBuffer();
|
||||
pMappedBuffer->frameNum = frameNum;
|
||||
//usleep(10000);
|
||||
recorder_frame2(r);
|
||||
pMappedBuffer->frameNum = frameNum;
|
||||
//usleep(10000);
|
||||
}
|
||||
|
||||
vkDestroyFence(device, fence, NULL);
|
||||
|
|
Loading…
Reference in a new issue