[Mesa-dev] [PATCH 15/15] st/va: add support for H264

Christian König deathsimple at vodafone.de
Tue Jun 18 02:27:45 PDT 2013


From: Christian König <christian.koenig at amd.com>

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 src/gallium/state_trackers/va/picture.c |  100 ++++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 2 deletions(-)

diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index 7339366..1c7a1dc 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_CODEC_MPEG12:
@@ -105,6 +108,50 @@ handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *
 
       break;
 
+   case PIPE_VIDEO_CODEC_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_CODEC_MPEG12:
@@ -131,11 +179,60 @@ handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
          context->desc.mpeg12.non_intra_matrix = NULL;
       break;
 
+   case PIPE_VIDEO_CODEC_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_CODEC_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:
-- 
1.7.9.5



More information about the mesa-dev mailing list