diff options
Diffstat (limited to 'vaenc/h264encode.c')
| -rw-r--r-- | vaenc/h264encode.c | 158 |
1 files changed, 140 insertions, 18 deletions
diff --git a/vaenc/h264encode.c b/vaenc/h264encode.c index d69a2ba..bd4e93a 100644 --- a/vaenc/h264encode.c +++ b/vaenc/h264encode.c @@ -83,6 +83,15 @@ static VAProfile h264_profile = -1; unsigned int h264_entropy_mode = 1; /* cabac */ unsigned int h264_8x8_dct = 0; +unsigned int roi_enable = 0; +unsigned int roi_value = -2; +int roi_minqp = -4; +int roi_maxqp = 4; +unsigned int roi_rec_x = 0; +unsigned int roi_rec_y = 0; +unsigned int roi_rec_w = 0; +unsigned int roi_rec_h = 0; + struct __bitstream { unsigned int *buffer; int bit_offset; @@ -554,7 +563,8 @@ static int update_RefPicList(void) static int render_sequence(void) { - VABufferID seq_param_buf, rc_param_buf, misc_param_tmpbuf, render_id[2]; + VABufferID seq_param_buf = VA_INVALID_ID, rc_param_buf = VA_INVALID_ID; + VABufferID misc_param_tmpbuf = VA_INVALID_ID, render_id[2] = { VA_INVALID_ID, VA_INVALID_ID }; VAStatus va_status; VAEncMiscParameterBuffer *misc_param, *misc_param_tmp; VAEncMiscParameterRateControl *misc_rate_ctrl; @@ -608,13 +618,16 @@ static int render_sequence(void) va_status = vaRenderPicture(va_dpy,context_id, &misc_param_tmpbuf, 1); } + if (buf_destroy) + destroy_vabuffers(va_dpy, 5, seq_param_buf, rc_param_buf, + misc_param_tmpbuf, render_id[0], render_id[1]); return va_status; } static int render_framerate() { - VABufferID frame_rate_param_buf; + VABufferID frame_rate_param_buf = VA_INVALID_ID; VAStatus va_status; VAEncMiscParameterBuffer *misc_param, *misc_param_tmp; VAEncMiscParameterFrameRate *misc_frame_rate; @@ -643,12 +656,15 @@ static int render_framerate() va_status = vaRenderPicture(va_dpy,context_id, &frame_rate_param_buf, 1); CHECK_VASTATUS(va_status,"vaRenderPicture");; + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, frame_rate_param_buf); + return 0; } static int render_rcparam(unsigned int mask, struct rc_param_t *rc_param) { - VABufferID rc_param_buf; + VABufferID rc_param_buf = VA_INVALID_ID; VAStatus va_status; VAEncMiscParameterBuffer *misc_param, *misc_param_tmp; VAEncMiscParameterRateControl *misc_rate_ctrl; @@ -702,6 +718,9 @@ static int render_rcparam(unsigned int mask, struct rc_param_t *rc_param) va_status = vaRenderPicture(va_dpy,context_id, &rc_param_buf, 1); CHECK_VASTATUS(va_status,"vaRenderPicture");; + + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, rc_param_buf); return 0; } @@ -740,7 +759,7 @@ static int calc_poc(int pic_order_cnt_lsb) static int render_picture(void) { - VABufferID pic_param_buf; + VABufferID pic_param_buf = VA_INVALID_ID; VAStatus va_status; int i = 0; @@ -763,7 +782,8 @@ static int render_picture(void) } else { if (h264_autoref == 0) { memcpy(pic_param.ReferenceFrames, ReferenceFrames, numShortTerm*sizeof(VAPictureH264)); - for (i = numShortTerm; i < surface_num; i++) { + /* Reset the rest of non-used references */ + for (i = numShortTerm; i < 16; i++) { pic_param.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE; pic_param.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; } @@ -792,13 +812,17 @@ static int render_picture(void) va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1); CHECK_VASTATUS(va_status,"vaRenderPicture"); + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, pic_param_buf); + return 0; } static int render_packedsequence(void) { VAEncPackedHeaderParameterBuffer packedheader_param_buffer; - VABufferID packedseq_para_bufid, packedseq_data_bufid, render_id[2]; + VABufferID packedseq_para_bufid = VA_INVALID_ID, packedseq_data_bufid = VA_INVALID_ID; + VABufferID render_id[2] = { VA_INVALID_ID, VA_INVALID_ID }; unsigned int length_in_bits; unsigned char *packedseq_buffer = NULL; VAStatus va_status; @@ -829,6 +853,10 @@ static int render_packedsequence(void) CHECK_VASTATUS(va_status,"vaRenderPicture"); free(packedseq_buffer); + + if (buf_destroy) + destroy_vabuffers(va_dpy, 4, packedseq_para_bufid, packedseq_data_bufid, + render_id[0], render_id[1]); return 0; } @@ -836,7 +864,8 @@ static int render_packedsequence(void) static int render_packedpicture(void) { VAEncPackedHeaderParameterBuffer packedheader_param_buffer; - VABufferID packedpic_para_bufid, packedpic_data_bufid, render_id[2]; + VABufferID packedpic_para_bufid = VA_INVALID_ID, packedpic_data_bufid = VA_INVALID_ID; + VABufferID render_id[2] = { VA_INVALID_ID, VA_INVALID_ID }; unsigned int length_in_bits; unsigned char *packedpic_buffer = NULL; VAStatus va_status; @@ -866,14 +895,19 @@ static int render_packedpicture(void) CHECK_VASTATUS(va_status,"vaRenderPicture"); free(packedpic_buffer); + + if (buf_destroy) + destroy_vabuffers(va_dpy, 4, packedpic_para_bufid, packedpic_data_bufid, + render_id[0], render_id[1]); return 0; } static void render_packedsei(void) { + VABufferID packed_sei_header_param_buf_id = VA_INVALID_ID; + VABufferID packed_sei_buf_id = VA_INVALID_ID, render_id[2] = { VA_INVALID_ID, VA_INVALID_ID }; VAEncPackedHeaderParameterBuffer packed_header_param_buffer; - VABufferID packed_sei_header_param_buf_id, packed_sei_buf_id, render_id[2]; unsigned int length_in_bits /*offset_in_bytes*/; unsigned char *packed_sei_buffer = NULL; VAStatus va_status; @@ -925,14 +959,18 @@ static void render_packedsei(void) CHECK_VASTATUS(va_status,"vaRenderPicture"); free(packed_sei_buffer); - + + if (buf_destroy) + destroy_vabuffers(va_dpy, 4, packed_sei_header_param_buf_id, packed_sei_buf_id, + render_id[0], render_id[1]); + return; } static int render_air(void) { VAStatus va_status; - VABufferID misc_parameter_air_buf_id; + VABufferID misc_parameter_air_buf_id = VA_INVALID_ID; VAEncMiscParameterBuffer *misc_param; VAEncMiscParameterAIR *misc_air_param; @@ -959,13 +997,16 @@ static int render_air(void) va_status = vaRenderPicture(va_dpy,context_id, &misc_parameter_air_buf_id, 1); CHECK_VASTATUS(va_status,"vaRenderPicture");; + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, misc_parameter_air_buf_id); + return 0; } static int render_cir(void) { VAStatus va_status; - VABufferID misc_parameter_cir_buf_id; + VABufferID misc_parameter_cir_buf_id = VA_INVALID_ID; VAEncMiscParameterBuffer *misc_param; VAEncMiscParameterCIR *misc_cir_param; @@ -990,12 +1031,15 @@ static int render_cir(void) va_status = vaRenderPicture(va_dpy,context_id, &misc_parameter_cir_buf_id, 1); CHECK_VASTATUS(va_status,"vaRenderPicture"); + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, misc_parameter_cir_buf_id); + return 0; } static int render_hrd(void) { - VABufferID misc_parameter_hrd_buf_id; + VABufferID misc_parameter_hrd_buf_id = VA_INVALID_ID; VAStatus va_status; VAEncMiscParameterBuffer *misc_param; VAEncMiscParameterHRD *misc_hrd_param; @@ -1031,12 +1075,15 @@ static int render_hrd(void) va_status = vaRenderPicture(va_dpy,context_id, &misc_parameter_hrd_buf_id, 1); CHECK_VASTATUS(va_status,"vaRenderPicture");; + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, misc_parameter_hrd_buf_id); + return 0; } static int render_slice(void) { - VABufferID slice_param_buf; + VABufferID slice_param_buf = VA_INVALID_ID; VAStatus va_status; VAEncSliceParameterBufferH264 *slice_param, *current_slice; int i, j, frame_slice_cc = frame_slice_count; @@ -1055,7 +1102,7 @@ static int render_slice(void) for (j = 0; j < frame_slice_cc; j++) { current_slice = slice_param + j; - current_slice->disable_deblocking_filter_idc = 1; + current_slice->disable_deblocking_filter_idc = 0; current_slice->macroblock_address = mb_rendered; if (j == frame_slice_cc - 1) { current_slice->num_macroblocks = (frame_width_mbaligned * frame_height_mbaligned) / (16 * 16) - mb_rendered; @@ -1067,6 +1114,13 @@ static int render_slice(void) if (current_frame_type == FRAME_IDR) { if (current_frame_encoding != 0) ++current_slice->idr_pic_id; + /* Reset reference for IDR also */ + for (i = 0; i < 32; i++) { + current_slice->RefPicList0[i].picture_id = VA_INVALID_SURFACE; + current_slice->RefPicList0[i].flags = VA_PICTURE_H264_INVALID; + current_slice->RefPicList1[i].picture_id = VA_INVALID_SURFACE; + current_slice->RefPicList1[i].flags = VA_PICTURE_H264_INVALID; + } } else if (current_frame_type == FRAME_P) { int refpiclist0_max = h264_maxref & 0xffff; memcpy(current_slice->RefPicList0, RefPicList0_P, refpiclist0_max*sizeof(VAPictureH264)); @@ -1092,8 +1146,8 @@ static int render_slice(void) } } - current_slice->slice_alpha_c0_offset_div2 = 0; - current_slice->slice_beta_offset_div2 = 0; + current_slice->slice_alpha_c0_offset_div2 = 2; + current_slice->slice_beta_offset_div2 = 2; current_slice->direct_spatial_mv_pred_flag = 1; current_slice->pic_order_cnt_lsb = (current_frame_display - current_IDR_display) % MaxPicOrderCntLsb; } @@ -1103,13 +1157,17 @@ static int render_slice(void) va_status = vaRenderPicture(va_dpy, context_id, &slice_param_buf, 1); CHECK_VASTATUS(va_status,"vaRenderPicture"); + + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, slice_param_buf); + return 0; } static int render_max_slice_size(void) { VAStatus va_status; - VABufferID misc_parameter_max_slice_size_buf_id; + VABufferID misc_parameter_max_slice_size_buf_id = VA_INVALID_ID; VAEncMiscParameterBuffer *misc_param; VAEncMiscParameterMaxSliceSize *misc_max_slize_size_param; @@ -1139,6 +1197,62 @@ static int render_max_slice_size(void) va_status = vaRenderPicture(va_dpy, context_id, &misc_parameter_max_slice_size_buf_id, 1); CHECK_VASTATUS(va_status,"vaRenderPicture");; + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, misc_parameter_max_slice_size_buf_id); + + return 0; +} + +static int render_roi(void) +{ + VAStatus va_status; + VABufferID misc_roi_buf_id = VA_INVALID_ID; + VAEncMiscParameterBuffer *misc_param; + VAEncMiscParameterBufferROI *misc_roi_param; + VAEncROI encroi; + + + roi_rec_x = (!roi_rec_x)?frame_width / 3:roi_rec_x; + roi_rec_y = (!roi_rec_x)?frame_height / 3:roi_rec_y; + roi_rec_w = (!roi_rec_w)?frame_width / 3:roi_rec_w; + roi_rec_h = (!roi_rec_h)?frame_height / 3:roi_rec_h; + + va_status = vaCreateBuffer(va_dpy, context_id, + VAEncMiscParameterBufferType, + sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterBufferROI), + 1, + NULL, + &misc_roi_buf_id); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + vaMapBuffer(va_dpy, + misc_roi_buf_id, + (void **)&misc_param); + + misc_param->type = VAEncMiscParameterTypeROI; + misc_roi_param = (VAEncMiscParameterBufferROI *)misc_param->data; + + misc_roi_param->num_roi = 1; + misc_roi_param->max_delta_qp = roi_maxqp; + misc_roi_param->min_delta_qp = roi_minqp; + + encroi.roi_rectangle.x = roi_rec_x; + encroi.roi_rectangle.y = roi_rec_y; + encroi.roi_rectangle.width = roi_rec_w; + encroi.roi_rectangle.height = roi_rec_h; + + encroi.roi_value = roi_value; + + misc_roi_param->roi = &encroi; + + vaUnmapBuffer(va_dpy, misc_roi_buf_id); + + va_status = vaRenderPicture(va_dpy, context_id, &misc_roi_buf_id, 1); + CHECK_VASTATUS(va_status,"vaRenderPicture");; + + if (buf_destroy) + destroy_vabuffers(va_dpy, 1, misc_roi_buf_id); + return 0; } @@ -1170,9 +1284,13 @@ static VAStatus h264_render_frame(unsigned int mask, struct rc_param_t *rc_param if (max_slice_size) { render_max_slice_size(); } + if (roi_enable) + render_roi(); } else { //render_sequence(); render_picture(); + if (roi_enable) + render_roi(); //if (rc_mode == VA_RC_CBR) // render_packedsei(); //render_hrd(); @@ -1390,7 +1508,11 @@ static VAStatus h264_get_config(void) printf("Support VAConfigAttribEncAutoReference\n"); h264_autoref = 1; } - + + if (h264_attrib[VAConfigAttribEncROI].value != VA_ATTRIB_NOT_SUPPORTED) { + printf("Support VAConfigAttribEncROI\n"); + } + va_profile = h264_profile; /* |
