summaryrefslogtreecommitdiff
path: root/vaenc/h264encode.c
diff options
context:
space:
mode:
Diffstat (limited to 'vaenc/h264encode.c')
-rw-r--r--vaenc/h264encode.c158
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;
/*