diff options
author | Christian König <christian.koenig@amd.com> | 2013-06-17 17:19:06 +0200 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2013-08-16 11:37:25 +0200 |
commit | 0021805751d04af42d9e0bd613f6aacf1bc1aa32 (patch) | |
tree | 73489a2f2b5473c6cd213dba5f61a44751d9f0aa | |
parent | 20580b7189c834d356c5176f41b2a00fefd1546d (diff) |
st/va: add support for H264vaapi
Signed-off-by: Christian König <christian.koenig@amd.com>
-rw-r--r-- | src/gallium/state_trackers/va/picture.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 4ece5103ad..baa88ab7e8 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -31,6 +31,8 @@ #include "util/u_handle_table.h" #include "util/u_video.h" +#include "vl/vl_vlc.h" + #include "va_private.h" VAStatus @@ -76,6 +78,7 @@ static void handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { VAPictureParameterBufferMPEG2 *mpeg2; + VAPictureParameterBufferH264 *h264; switch (u_reduce_video_profile(context->decoder->profile)) { case PIPE_VIDEO_FORMAT_MPEG12: @@ -105,6 +108,50 @@ handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer * break; + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + assert(buf->size >= sizeof(VAPictureParameterBufferH264) && buf->num_elements == 1); + h264 = buf->data; + + /*CurrPic*/ + context->desc.h264.field_order_cnt[0] = h264->CurrPic.TopFieldOrderCnt; + context->desc.h264.field_order_cnt[1] = h264->CurrPic.BottomFieldOrderCnt; + /*ReferenceFrames[16]*/ + /*picture_width_in_mbs_minus1*/ + /*picture_height_in_mbs_minus1*/ + /*bit_depth_luma_minus8*/ + /*bit_depth_chroma_minus8*/ + context->desc.h264.num_ref_frames = h264->num_ref_frames; + /*chroma_format_idc*/ + /*residual_colour_transform_flag*/ + /*gaps_in_frame_num_value_allowed_flag*/ + context->desc.h264.frame_mbs_only_flag = h264->seq_fields.bits.frame_mbs_only_flag; + context->desc.h264.mb_adaptive_frame_field_flag = h264->seq_fields.bits.mb_adaptive_frame_field_flag; + context->desc.h264.direct_8x8_inference_flag = h264->seq_fields.bits.direct_8x8_inference_flag; + /*MinLumaBiPredSize8x8*/ + context->desc.h264.log2_max_frame_num_minus4 = h264->seq_fields.bits.log2_max_frame_num_minus4; + context->desc.h264.pic_order_cnt_type = h264->seq_fields.bits.pic_order_cnt_type; + context->desc.h264.log2_max_pic_order_cnt_lsb_minus4 = h264->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4; + context->desc.h264.delta_pic_order_always_zero_flag = h264->seq_fields.bits.delta_pic_order_always_zero_flag; + /*num_slice_groups_minus1*/ + /*slice_group_map_type*/ + /*slice_group_change_rate_minus1*/ + context->desc.h264.pic_init_qp_minus26 = h264->pic_init_qp_minus26; + /*pic_init_qs_minus26*/ + context->desc.h264.chroma_qp_index_offset = h264->chroma_qp_index_offset; + context->desc.h264.second_chroma_qp_index_offset = h264->second_chroma_qp_index_offset; + context->desc.h264.entropy_coding_mode_flag = h264->pic_fields.bits.entropy_coding_mode_flag; + context->desc.h264.weighted_pred_flag = h264->pic_fields.bits.weighted_pred_flag; + context->desc.h264.weighted_bipred_idc = h264->pic_fields.bits.weighted_bipred_idc; + context->desc.h264.transform_8x8_mode_flag = h264->pic_fields.bits.transform_8x8_mode_flag; + context->desc.h264.field_pic_flag = h264->pic_fields.bits.field_pic_flag; + context->desc.h264.constrained_intra_pred_flag = h264->pic_fields.bits.constrained_intra_pred_flag; + context->desc.h264.pic_order_present_flag = h264->pic_fields.bits.pic_order_present_flag; + context->desc.h264.deblocking_filter_control_present_flag = h264->pic_fields.bits.deblocking_filter_control_present_flag; + context->desc.h264.redundant_pic_cnt_present_flag = h264->pic_fields.bits.redundant_pic_cnt_present_flag; + /*reference_pic_flag*/ + context->desc.h264.frame_num = h264->frame_num; + break; + default: break; } @@ -114,6 +161,7 @@ static void handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf) { VAIQMatrixBufferMPEG2 *mpeg2; + VAIQMatrixBufferH264 *h264; switch (u_reduce_video_profile(context->decoder->profile)) { case PIPE_VIDEO_FORMAT_MPEG12: @@ -131,11 +179,60 @@ handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf) context->desc.mpeg12.non_intra_matrix = NULL; break; + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + assert(buf->size >= sizeof(VAIQMatrixBufferH264) && buf->num_elements == 1); + h264 = buf->data; + + memcpy(&context->desc.h264.scaling_lists_4x4, h264->ScalingList4x4, 6 * 16); + memcpy(&context->desc.h264.scaling_lists_8x8, h264->ScalingList8x8, 2 * 64); + break; + default: break; } } +static void +handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + unsigned num_buffers = 0; + void * const *buffers[2]; + unsigned sizes[2]; + + if (u_reduce_video_profile(context->decoder->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + static const uint8_t start_code[] = { 0x00, 0x00, 0x01 }; + struct vl_vlc vlc; + bool found = false; + int i; + + /* search the first 64 bytes for a startcode */ + vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size); + for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= 24; ++i) { + uint32_t value = vl_vlc_peekbits(&vlc, 24); + if (value == 0x000001) { + found = true; + break; + } + vl_vlc_eatbits(&vlc, 8); + vl_vlc_fillbits(&vlc); + } + + /* none found, ok add one manually */ + if (!found) { + buffers[num_buffers] = (void *const)&start_code; + sizes[num_buffers] = sizeof(start_code); + ++num_buffers; + } + } + + buffers[num_buffers] = buf->data; + sizes[num_buffers] = buf->size; + ++num_buffers; + context->decoder->decode_bitstream(context->decoder, context->target, NULL, + num_buffers, (const void * const*)buffers, sizes); + +} + VAStatus vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers) { @@ -174,8 +271,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff break; case VASliceDataBufferType: - context->decoder->decode_bitstream(context->decoder, context->target, NULL, - 1, (const void * const*)&buf->data, &buf->size); + handleVASliceDataBufferType(context, buf); break; default: |