summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2013-06-17 17:19:06 +0200
committerChristian König <christian.koenig@amd.com>2013-08-16 11:37:25 +0200
commit0021805751d04af42d9e0bd613f6aacf1bc1aa32 (patch)
tree73489a2f2b5473c6cd213dba5f61a44751d9f0aa
parent20580b7189c834d356c5176f41b2a00fefd1546d (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.c100
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: