Fix h264 on intel vaapi
This commit is contained in:
parent
ffd6bb3d7d
commit
01293b5565
1 changed files with 24 additions and 13 deletions
|
@ -58,8 +58,9 @@
|
|||
#define SLICE_TYPE_P 0
|
||||
#define SLICE_TYPE_B 1
|
||||
#define SLICE_TYPE_I 2
|
||||
#define SLICE_TYPE_P_ONLY 5
|
||||
|
||||
#define IS_P_SLICE(type) (SLICE_TYPE_P == (type))
|
||||
#define IS_P_SLICE(type) (SLICE_TYPE_P == (type) || SLICE_TYPE_P_ONLY == (type))
|
||||
#define IS_B_SLICE(type) (SLICE_TYPE_B == (type))
|
||||
#define IS_I_SLICE(type) (SLICE_TYPE_I == (type))
|
||||
|
||||
|
@ -370,11 +371,14 @@ encoder_init_seq_parameters(struct vaapi_recorder *r)
|
|||
|
||||
r->encoder.param.seq.level_idc = 60;
|
||||
r->encoder.param.seq.intra_period = 32767; //r->encoder.intra_period;
|
||||
r->encoder.param.seq.intra_idr_period = 32767;
|
||||
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;
|
||||
r->encoder.param.seq.ip_period = 1;
|
||||
|
||||
|
||||
/* Tc = num_units_in_tick / time_scale */
|
||||
r->encoder.param.seq.time_scale = 180;
|
||||
|
@ -388,7 +392,7 @@ 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 = 0;
|
||||
r->encoder.param.seq.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = 0;//12;
|
||||
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;
|
||||
}
|
||||
|
@ -442,11 +446,12 @@ encoder_update_pic_parameters(struct vaapi_recorder *r,
|
|||
|
||||
pic->CurrPic.picture_id = curr_pic;
|
||||
pic->CurrPic.frame_idx = r->frame_count;
|
||||
pic->CurrPic.TopFieldOrderCnt = 0;//r->frame_count * 2;
|
||||
pic->CurrPic.TopFieldOrderCnt = r->encoder.param.seq.seq_fields.bits.pic_order_cnt_type == 0? r->frame_count:0;
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
pic->ReferenceFrames[i].picture_id = VA_INVALID_ID;
|
||||
pic->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
|
||||
pic->ReferenceFrames[i].frame_idx = 0;
|
||||
}
|
||||
if(r->frame_count)
|
||||
{
|
||||
|
@ -496,11 +501,13 @@ encoder_update_slice_parameter(struct vaapi_recorder *r, int slice_type)
|
|||
{
|
||||
r->encoder.param.slice.RefPicList0[i].picture_id = VA_INVALID_ID;
|
||||
r->encoder.param.slice.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
|
||||
r->encoder.param.slice.RefPicList0[i].frame_idx = 0;
|
||||
}
|
||||
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;
|
||||
r->encoder.param.slice.RefPicList0[i].frame_idx = 0;
|
||||
}
|
||||
if(r->frame_count)
|
||||
{
|
||||
|
@ -508,10 +515,11 @@ encoder_update_slice_parameter(struct vaapi_recorder *r, int slice_type)
|
|||
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.pic_order_cnt_lsb = r->encoder.param.seq.seq_fields.bits.pic_order_cnt_type == 0? r->frame_count: 0;
|
||||
//r->encoder.param.slice.RefPicList0
|
||||
|
||||
r->encoder.param.slice.slice_alpha_c0_offset_div2 = 2;
|
||||
r->encoder.param.slice.slice_beta_offset_div2 = 2;
|
||||
//r->encoder.param.slice.slice_alpha_c0_offset_div2 = 2;
|
||||
//r->encoder.param.slice.slice_beta_offset_div2 = 2;
|
||||
|
||||
status = vaCreateBuffer(r->va_dpy, r->encoder.ctx,
|
||||
VAEncSliceParameterBufferType,
|
||||
|
@ -675,8 +683,8 @@ static void sps_rbsp(struct bitstream *bs,
|
|||
}
|
||||
|
||||
/* vui_parameters_present_flag */
|
||||
bitstream_put_ui(bs, 1, 1);
|
||||
|
||||
bitstream_put_ui(bs, 0, 1);
|
||||
#if 0
|
||||
/* aspect_ratio_info_present_flag */
|
||||
bitstream_put_ui(bs, 0, 1);
|
||||
/* overscan_info_present_flag */
|
||||
|
@ -707,7 +715,7 @@ static void sps_rbsp(struct bitstream *bs,
|
|||
bitstream_put_ui(bs, 0, 1);
|
||||
/* bitstream_restriction_flag */
|
||||
bitstream_put_ui(bs, 0, 1);
|
||||
|
||||
#endif
|
||||
rbsp_trailing_bits(bs);
|
||||
}
|
||||
|
||||
|
@ -1039,9 +1047,10 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
else
|
||||
slice_type = SLICE_TYPE_P;
|
||||
|
||||
if (r->frame_count == 0)
|
||||
buffers[count++] = encoder_update_seq_parameters(r);
|
||||
buffers[count++] = encoder_update_misc_hdr_parameter(r);
|
||||
buffers[count++] = encoder_update_slice_parameter(r, slice_type);
|
||||
//buffers[count++] = encoder_update_misc_hdr_parameter(r);
|
||||
VABufferID slice_buf = encoder_update_slice_parameter(r, slice_type);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (buffers[i] == VA_INVALID_ID)
|
||||
|
@ -1057,8 +1066,6 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
goto bail;
|
||||
|
||||
|
||||
|
||||
|
||||
//status = vaRenderPicture(r->va_dpy, r->encoder.ctx, &buffers[2], 1);
|
||||
do {
|
||||
output_buf = encoder_create_output_buffer(r);
|
||||
|
@ -1072,7 +1079,7 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
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)
|
||||
//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 );
|
||||
|
@ -1080,6 +1087,10 @@ encoder_encode(struct vaapi_recorder *r, VASurfaceID input)
|
|||
data, bit_length);
|
||||
free(data);
|
||||
}
|
||||
// its important to push slice after packed slice
|
||||
// otherwise intel encoder will crash on packed slice encoding
|
||||
// or produce invalid slice header
|
||||
buffers[count++] = slice_buf;
|
||||
status = vaRenderPicture(r->va_dpy, r->encoder.ctx, buffers, count);
|
||||
/*VAStatus er = encoder_render_picture(r, input, buffers, count);
|
||||
if(er != VA_STATUS_SUCCESS)
|
||||
|
|
Loading…
Reference in a new issue