[Mesa-dev] [PATCH 17/22] st/va: parse VP9 uncompressed frame header

Leo Liu leo.liu at amd.com
Mon Apr 9 16:36:13 UTC 2018


To get some of UVD required parameters.

Signed-off-by: Leo Liu <leo.liu at amd.com>
---
 src/gallium/state_trackers/va/picture.c     |   2 +-
 src/gallium/state_trackers/va/picture_vp9.c | 237 ++++++++++++++++++++++++++++
 src/gallium/state_trackers/va/va_private.h  |   1 +
 3 files changed, 239 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index e483ea3e21..e2cdb2b40c 100644
--- a/src/gallium/state_trackers/va/picture.c
+++ b/src/gallium/state_trackers/va/picture.c
@@ -303,7 +303,7 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
    case PIPE_VIDEO_FORMAT_JPEG:
       break;
    case PIPE_VIDEO_FORMAT_VP9:
-      /* TODO */
+      vlVaDecoderVP9BitstreamHeader(context, buf);
       break;
    default:
       break;
diff --git a/src/gallium/state_trackers/va/picture_vp9.c b/src/gallium/state_trackers/va/picture_vp9.c
index 38684ca21e..c1ca54cd00 100644
--- a/src/gallium/state_trackers/va/picture_vp9.c
+++ b/src/gallium/state_trackers/va/picture_vp9.c
@@ -25,6 +25,7 @@
  *
  **************************************************************************/
 
+#include "vl/vl_vlc.h"
 #include "va_private.h"
 
 void vlVaHandlePictureParameterBufferVP9(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
@@ -109,3 +110,239 @@ void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf)
       context->desc.vp9.slice_parameter.seg_param[i].chroma_dc_quant_scale = vp9->seg_param[i].chroma_dc_quant_scale;
    }
 }
+
+static unsigned vp9_u(struct vl_vlc *vlc, unsigned n)
+{
+   unsigned valid = vl_vlc_valid_bits(vlc);
+
+   if (n == 0)
+      return 0;
+
+   if (valid < 32)
+      vl_vlc_fillbits(vlc);
+
+   return vl_vlc_get_uimsbf(vlc, n);
+}
+
+static signed vp9_s(struct vl_vlc *vlc, unsigned n)
+{
+   unsigned v;
+   bool s;
+
+   v = vp9_u(vlc, n);
+   s = vp9_u(vlc, 1);
+
+   return s ? -v : v;
+}
+
+static void bitdepth_colorspace_sampling(struct vl_vlc *vlc, unsigned profile)
+{
+   unsigned cs;
+
+   if (profile == 2)
+      /* bit_depth */
+      vp9_u(vlc, 1);
+
+   cs = vp9_u(vlc, 3);
+   if (cs != 7)
+      /* yuv_range_flag */
+      vp9_u(vlc, 1);
+}
+
+static void frame_size(struct vl_vlc *vlc)
+{
+      /* width_minus_one */
+      vp9_u(vlc, 16);
+      /* height_minus_one */
+      vp9_u(vlc, 16);
+
+      /* has_scaling */
+      if (vp9_u(vlc, 1)) {
+         /* render_width_minus_one */
+         vp9_u(vlc, 16);
+         /* render_height_minus_one */
+         vp9_u(vlc, 16);
+      }
+}
+
+void vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf)
+{
+   struct vl_vlc vlc;
+   unsigned profile;
+   bool frame_type, show_frame, error_resilient_mode;
+   bool mode_ref_delta_enabled, mode_ref_delta_update = false;
+   int i;
+
+   vl_vlc_init(&vlc, 1, (const void * const*)&buf->data,
+      (const unsigned *)&context->desc.vp9.picture_parameter.frame_header_length_in_bytes);
+
+   /* frame_marker */
+   if (vp9_u(&vlc, 2) != 0x2)
+      return;
+
+   profile = vp9_u(&vlc, 1) | vp9_u(&vlc, 1) << 1;
+
+   if (profile == 3)
+      profile += vp9_u(&vlc, 1);
+
+   if (profile != 0 && profile != 2)
+      return;
+
+   /* show_existing_frame */
+   if (vp9_u(&vlc, 1))
+      return;
+
+   frame_type = vp9_u(&vlc, 1);
+   show_frame = vp9_u(&vlc, 1);
+   error_resilient_mode = vp9_u(&vlc, 1);
+
+   if (frame_type == 0) {
+      /* sync_code */
+      if (vp9_u(&vlc, 24) != 0x498342)
+         return;
+
+      bitdepth_colorspace_sampling(&vlc, profile);
+      frame_size(&vlc);
+   } else {
+      bool intra_only, size_in_refs = false;
+
+      intra_only = show_frame ? 0 : vp9_u(&vlc, 1);
+      if (!error_resilient_mode)
+         /* reset_frame_context */
+         vp9_u(&vlc, 2);
+
+      if (intra_only) {
+         /* sync_code */
+         if (vp9_u(&vlc, 24) != 0x498342)
+            return;
+
+         bitdepth_colorspace_sampling(&vlc, profile);
+         /* refresh_frame_flags */
+         vp9_u(&vlc, 8);
+         frame_size(&vlc);
+      } else {
+         /* refresh_frame_flags */
+         vp9_u(&vlc, 8);
+
+         for (i = 0; i < 3; ++i) {
+            /* frame refs */
+            vp9_u(&vlc, 3);
+            vp9_u(&vlc, 1);
+         }
+
+         for (i = 0; i < 3; ++i) {
+            size_in_refs = vp9_u(&vlc, 1);
+            if (size_in_refs)
+               break;
+         }
+
+         if (!size_in_refs) {
+            /* width/height_minus_one */
+            vp9_u(&vlc, 16);
+            vp9_u(&vlc, 16);
+         }
+
+         if (vp9_u(&vlc, 1)) {
+            /* render_width/height_minus_one */
+            vp9_u(&vlc, 16);
+            vp9_u(&vlc, 16);
+         }
+
+         /* high_precision_mv */
+         vp9_u(&vlc, 1);
+         /* filter_switchable */
+         if (!vp9_u(&vlc, 1))
+            /* filter_index */
+            vp9_u(&vlc, 2);
+      }
+   }
+   if (!error_resilient_mode) {
+      /* refresh_frame_context */
+      vp9_u(&vlc, 1);
+      /* frame_parallel_decoding_mode */
+      vp9_u(&vlc, 1);
+   }
+   /* frame_context_index */
+   vp9_u(&vlc, 2);
+
+   /* loop filter */
+
+   /* filter_level */
+   vp9_u(&vlc, 6);
+   /* sharpness_level */
+   vp9_u(&vlc, 3);
+
+   mode_ref_delta_enabled = vp9_u(&vlc, 1);
+   if (mode_ref_delta_enabled) {
+      mode_ref_delta_update = vp9_u(&vlc, 1);
+      if (mode_ref_delta_update) {
+         for (i = 0; i < 4; ++i) {
+            /* update_ref_delta */
+            if (vp9_u(&vlc, 1))
+               /* ref_deltas */
+               vp9_s(&vlc, 6);
+         }
+         for (i = 0; i < 2; ++i) {
+            /* update_mode_delta */
+            if (vp9_u(&vlc, 1))
+               /* mode_deltas */
+               vp9_s(&vlc, 6);
+         }
+      }
+   }
+   context->desc.vp9.picture_parameter.mode_ref_delta_enabled = mode_ref_delta_enabled;
+   context->desc.vp9.picture_parameter.mode_ref_delta_update = mode_ref_delta_update;
+
+   /* quantization */
+
+   context->desc.vp9.picture_parameter.base_qindex = vp9_u(&vlc, 8);
+   context->desc.vp9.picture_parameter.y_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0;
+   context->desc.vp9.picture_parameter.uv_ac_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0;
+   context->desc.vp9.picture_parameter.uv_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0;
+
+   /* segmentation */
+
+   /* enabled */
+   if (!vp9_u(&vlc, 1))
+      return;
+
+   /* update_map */
+   if (vp9_u(&vlc, 1)) {
+      for (i = 0; i < 7; ++i) {
+         /* tree_probs_set */
+         if (vp9_u(&vlc, 1)) {
+            /* tree_probs */
+            vp9_u(&vlc, 8);
+         }
+      }
+
+      /* temporal_update */
+      if (vp9_u(&vlc, 1)) {
+         for (i = 0; i < 3; ++i) {
+            /* pred_probs_set */
+            if (vp9_u(&vlc, 1))
+               /* pred_probs */
+               vp9_u(&vlc, 8);
+         }
+      }
+   }
+
+   /* update_data */
+   if (vp9_u(&vlc, 1)) {
+      /* abs_delta */
+      vp9_u(&vlc, 1);
+      for (i = 0; i < 8; ++i) {
+         /* Use alternate quantizer */
+         if ((context->desc.vp9.slice_parameter.seg_param[i].alt_quant_enabled = vp9_u(&vlc, 1)))
+            context->desc.vp9.slice_parameter.seg_param[i].alt_quant = vp9_s(&vlc, 8);
+         /* Use alternate loop filter value */
+         if ((context->desc.vp9.slice_parameter.seg_param[i].alt_lf_enabled = vp9_u(&vlc, 1)))
+            context->desc.vp9.slice_parameter.seg_param[i].alt_lf = vp9_s(&vlc, 6);
+         /* Optional Segment reference frame */
+         if (vp9_u(&vlc, 1))
+            vp9_u(&vlc, 2);
+         /* Optional Segment skip mode */
+         vp9_u(&vlc, 1);
+      }
+   }
+}
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
index ef9142876c..c82fec3d5f 100644
--- a/src/gallium/state_trackers/va/va_private.h
+++ b/src/gallium/state_trackers/va/va_private.h
@@ -431,6 +431,7 @@ void vlVaHandleHuffmanTableBufferType(vlVaContext *context, vlVaBuffer *buf);
 void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf);
 void vlVaHandlePictureParameterBufferVP9(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
 void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf);
+void vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf);
 void getEncParamPresetH264(vlVaContext *context);
 void getEncParamPresetH265(vlVaContext *context);
 VAStatus vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
-- 
2.14.1



More information about the mesa-dev mailing list