[Libva] [libva][PATCH 1/2] h264encode: Make it runnable with the latest libva-intel-driver (1.3.2)

Xiang, Haihao haihao.xiang at intel.com
Sun Aug 10 19:14:07 PDT 2014


Signed-off-by: Xiang, Haihao <haihao.xiang at intel.com>
---
 test/encode/h264encode.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 164 insertions(+), 1 deletion(-)

diff --git a/test/encode/h264encode.c b/test/encode/h264encode.c
index b2030bc..94ce13f 100644
--- a/test/encode/h264encode.c
+++ b/test/encode/h264encode.c
@@ -62,6 +62,10 @@
 #define SLICE_TYPE_P            0
 #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
@@ -78,7 +82,7 @@ static  VADisplay va_dpy;
 static  VAProfile h264_profile = ~0;
 static  VAConfigAttrib attrib[VAConfigAttribTypeMax];
 static  VAConfigAttrib config_attrib[VAConfigAttribTypeMax];
-static  int config_attrib_num = 0;
+static  int config_attrib_num = 0, enc_packed_header_idx;
 static  VASurfaceID src_surface[SURFACE_NUM];
 static  VABufferID  coded_buf[SURFACE_NUM];
 static  VASurfaceID ref_surface[SURFACE_NUM];
@@ -426,6 +430,100 @@ static void pps_rbsp(bitstream *bs)
     rbsp_trailing_bits(bs);
 }
 
+static void slice_header(bitstream *bs)
+{
+    int first_mb_in_slice = slice_param.macroblock_address;
+
+    bitstream_put_ue(bs, first_mb_in_slice);        /* first_mb_in_slice: 0 */
+    bitstream_put_ue(bs, slice_param.slice_type);   /* slice_type */
+    bitstream_put_ue(bs, slice_param.pic_parameter_set_id);        /* pic_parameter_set_id: 0 */
+    bitstream_put_ui(bs, pic_param.frame_num, seq_param.seq_fields.bits.log2_max_frame_num_minus4 + 4); /* frame_num */
+
+    /* frame_mbs_only_flag == 1 */
+    if (!seq_param.seq_fields.bits.frame_mbs_only_flag) {
+        /* FIXME: */
+        assert(0);
+    }
+
+    if (pic_param.pic_fields.bits.idr_pic_flag)
+        bitstream_put_ue(bs, slice_param.idr_pic_id);		/* idr_pic_id: 0 */
+
+    if (seq_param.seq_fields.bits.pic_order_cnt_type == 0) {
+        bitstream_put_ui(bs, pic_param.CurrPic.TopFieldOrderCnt, seq_param.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_param.slice_type)) {
+        bitstream_put_ui(bs, slice_param.num_ref_idx_active_override_flag, 1);            /* num_ref_idx_active_override_flag: */
+
+        if (slice_param.num_ref_idx_active_override_flag)
+            bitstream_put_ue(bs, slice_param.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_param.slice_type)) {
+        bitstream_put_ui(bs, slice_param.direct_spatial_mv_pred_flag, 1);            /* direct_spatial_mv_pred: 1 */
+
+        bitstream_put_ui(bs, slice_param.num_ref_idx_active_override_flag, 1);       /* num_ref_idx_active_override_flag: */
+
+        if (slice_param.num_ref_idx_active_override_flag) {
+            bitstream_put_ue(bs, slice_param.num_ref_idx_l0_active_minus1);
+            bitstream_put_ue(bs, slice_param.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_param.pic_fields.bits.weighted_pred_flag &&
+         IS_P_SLICE(slice_param.slice_type)) ||
+        ((pic_param.pic_fields.bits.weighted_bipred_idc == 1) &&
+         IS_B_SLICE(slice_param.slice_type))) {
+        /* FIXME: fill weight/offset table */
+        assert(0);
+    }
+
+    /* dec_ref_pic_marking */
+    if (pic_param.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_param.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_param.pic_fields.bits.entropy_coding_mode_flag &&
+        !IS_I_SLICE(slice_param.slice_type))
+        bitstream_put_ue(bs, slice_param.cabac_init_idc);               /* cabac_init_idc: 0 */
+
+    bitstream_put_se(bs, slice_param.slice_qp_delta);                   /* slice_qp_delta: 0 */
+
+    /* ignore for SP/SI */
+
+    if (pic_param.pic_fields.bits.deblocking_filter_control_present_flag) {
+        bitstream_put_ue(bs, slice_param.disable_deblocking_filter_idc);           /* disable_deblocking_filter_idc: 0 */
+
+        if (slice_param.disable_deblocking_filter_idc != 1) {
+            bitstream_put_se(bs, slice_param.slice_alpha_c0_offset_div2);          /* slice_alpha_c0_offset_div2: 2 */
+            bitstream_put_se(bs, slice_param.slice_beta_offset_div2);              /* slice_beta_offset_div2: 2 */
+        }
+    }
+
+    if (pic_param.pic_fields.bits.entropy_coding_mode_flag) {
+        bitstream_byte_aligning(bs, 1);
+    }
+}
 
 static int
 build_packed_pic_buffer(unsigned char **header_buffer)
@@ -523,6 +621,30 @@ build_packed_sei_buffer_timing(unsigned int init_cpb_removal_length,
     return nal_bs.bit_offset;
 }
 
+static int build_packed_slice_buffer(unsigned char **header_buffer)
+{
+    bitstream bs;
+    int is_idr = !!pic_param.pic_fields.bits.idr_pic_flag;
+    int is_ref = !!pic_param.pic_fields.bits.reference_pic_flag;
+
+    bitstream_start(&bs);
+    nal_start_code_prefix(&bs);
+
+    if (IS_I_SLICE(slice_param.slice_type)) {
+        nal_header(&bs, NAL_REF_IDC_HIGH, is_idr ? NAL_IDR : NAL_NON_IDR);
+    } else if (IS_P_SLICE(slice_param.slice_type)) {
+        nal_header(&bs, NAL_REF_IDC_MEDIUM, NAL_NON_IDR);
+    } else {
+        assert(IS_B_SLICE(slice_param.slice_type));
+        nal_header(&bs, is_ref ? NAL_REF_IDC_LOW : NAL_REF_IDC_NONE, NAL_NON_IDR);
+    }
+
+    slice_header(&bs);
+    bitstream_end(&bs);
+
+    *header_buffer = (unsigned char *)bs.buffer;
+    return bs.bit_offset;
+}
 
 
 /*
@@ -1060,6 +1182,7 @@ static int init_va(void)
             config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_MISC;
         }
         
+        enc_packed_header_idx = config_attrib_num;
         config_attrib_num++;
     }
 
@@ -1616,6 +1739,41 @@ static int render_hrd(void)
     return 0;
 }
 
+static void render_packedslice()
+{
+    VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
+    VABufferID packedslice_para_bufid, packedslice_data_bufid, render_id[2];
+    unsigned int length_in_bits;
+    unsigned char *packedslice_buffer = NULL;
+    VAStatus va_status;
+
+    length_in_bits = build_packed_slice_buffer(&packedslice_buffer);
+    packedheader_param_buffer.type = VAEncPackedHeaderSlice;
+    packedheader_param_buffer.bit_length = length_in_bits;
+    packedheader_param_buffer.has_emulation_bytes = 0;
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderParameterBufferType,
+                               sizeof(packedheader_param_buffer), 1, &packedheader_param_buffer,
+                               &packedslice_para_bufid);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    va_status = vaCreateBuffer(va_dpy,
+                               context_id,
+                               VAEncPackedHeaderDataBufferType,
+                               (length_in_bits + 7) / 8, 1, packedslice_buffer,
+                               &packedslice_data_bufid);
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+    render_id[0] = packedslice_para_bufid;
+    render_id[1] = packedslice_data_bufid;
+    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
+    CHECK_VASTATUS(va_status,"vaRenderPicture");
+
+    free(packedslice_buffer);
+}
+
 static int render_slice(void)
 {
     VABufferID slice_param_buf;
@@ -1661,6 +1819,11 @@ static int render_slice(void)
     slice_param.direct_spatial_mv_pred_flag = 1;
     slice_param.pic_order_cnt_lsb = (current_frame_display - current_IDR_display) % MaxPicOrderCntLsb;
     
+
+    if (h264_packedheader &&
+        config_attrib[enc_packed_header_idx].value & VA_ENC_PACKED_HEADER_SLICE)
+        render_packedslice();
+
     va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType,
                                sizeof(slice_param),1,&slice_param,&slice_param_buf);
     CHECK_VASTATUS(va_status,"vaCreateBuffer");;
-- 
1.9.1



More information about the Libva mailing list