OSDN Git Service

i965_drv_video: support JPEG decoding on Ivybridge
authorXiang, Haihao <haihao.xiang@intel.com>
Wed, 7 Sep 2011 08:18:19 +0000 (16:18 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Thu, 8 Sep 2011 08:46:59 +0000 (16:46 +0800)
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
src/gen6_mfd.c
src/gen7_mfd.c
src/gen7_mfd.h
src/i965_avc_bsd.c
src/i965_defines.h
src/i965_drv_video.c
src/i965_drv_video.h
src/i965_render.c

index b27be13..db70e6b 100644 (file)
@@ -1040,8 +1040,8 @@ gen6_mfd_avc_decode_init(VADriverContextP ctx,
     assert(obj_surface);
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
-    gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface);
     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
     gen6_mfd_context->post_deblocking_output.bo = obj_surface->bo;
@@ -1513,8 +1513,8 @@ gen6_mfd_vc1_decode_init(VADriverContextP ctx,
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    gen6_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    gen6_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
     gen6_mfd_context->post_deblocking_output.bo = obj_surface->bo;
index 36d5594..252c63f 100644 (file)
@@ -235,7 +235,7 @@ gen7_mfd_pipe_mode_select(VADriverContextP ctx,
            standard_select == MFX_FORMAT_VC1 ||
            standard_select == MFX_FORMAT_JPEG);
 
-    BEGIN_BCS_BATCH(batch, 5); /* FIXME: 5 ??? */
+    BEGIN_BCS_BATCH(batch, 5);
     OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (5 - 2));
     OUT_BCS_BATCH(batch,
                   (MFX_LONG_MODE << 17) | /* Currently only support long format */
@@ -266,7 +266,21 @@ gen7_mfd_surface_state(VADriverContextP ctx,
     struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct object_surface *obj_surface = SURFACE(decode_state->current_render_target);
+    unsigned int y_cb_offset;
+    unsigned int y_cr_offset;
+
     assert(obj_surface);
+
+    if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
+        y_cb_offset = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
+        y_cr_offset = ALIGN(obj_surface->height, 32);
+    } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
+        y_cb_offset = ALIGN(obj_surface->height, 32);
+        y_cr_offset = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
+    } else {
+        y_cb_offset = ALIGN(obj_surface->height, 32);
+        y_cr_offset = 0;
+    }
     
     BEGIN_BCS_BATCH(batch, 6);
     OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
@@ -276,16 +290,18 @@ gen7_mfd_surface_state(VADriverContextP ctx,
                   ((obj_surface->orig_width - 1) << 4));
     OUT_BCS_BATCH(batch,
                   (MFX_SURFACE_PLANAR_420_8 << 28) | /* 420 planar YUV surface */
-                  (1 << 27) | /* FIXME: set to 0 for JPEG */
-                  (0 << 22) | /* surface object control state, FIXME??? */
+                  ((standard_select != MFX_FORMAT_JPEG) << 27) | /* interleave chroma, set to 0 for JPEG */
+                  (0 << 22) | /* surface object control state, ignored */
                   ((obj_surface->width - 1) << 3) | /* pitch */
-                  (0 << 2)  | /* must be 0 for interleave U/V */
+                  (0 << 2)  | /* must be 0 */
                   (1 << 1)  | /* must be tiled */
                   (I965_TILEWALK_YMAJOR << 0));  /* tile walk, must be 1 */
     OUT_BCS_BATCH(batch,
-                  (0 << 16) | /* FIXME: fix it for JPEG */
-                  (obj_surface->height)); /* FIXME: fix it for JPEG */
-    OUT_BCS_BATCH(batch, 0); /* FIXME: fix it for JPEG */
+                  (0 << 16) | /* X offset for U(Cb), must be 0 */
+                  (y_cb_offset << 0)); /* Y offset for U(Cb) */
+    OUT_BCS_BATCH(batch,
+                  (0 << 16) | /* X offset for V(Cr), must be 0 */
+                  (y_cr_offset << 0)); /* Y offset for V(Cr), must be 0 for video codec, non-zoro for JPEG */
     ADVANCE_BCS_BATCH(batch);
 }
 
@@ -987,8 +1003,8 @@ gen7_mfd_avc_decode_init(VADriverContextP ctx,
     assert(obj_surface);
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
-    gen7_mfd_init_avc_surface(ctx, pic_param, obj_surface);
     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    gen7_mfd_init_avc_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
     gen7_mfd_context->post_deblocking_output.bo = obj_surface->bo;
@@ -1468,8 +1484,8 @@ gen7_mfd_vc1_decode_init(VADriverContextP ctx,
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    gen7_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    gen7_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
     gen7_mfd_context->post_deblocking_output.bo = obj_surface->bo;
@@ -1983,6 +1999,293 @@ gen7_mfd_vc1_decode_picture(VADriverContextP ctx,
     intel_batchbuffer_flush(batch);
 }
 
+static void
+gen7_mfd_jpeg_decode_init(VADriverContextP ctx,
+                          struct decode_state *decode_state,
+                          struct gen7_mfd_context *gen7_mfd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    struct object_surface *obj_surface;
+
+    /* Current decoded picture */
+    obj_surface = SURFACE(decode_state->current_render_target);
+    assert(obj_surface);
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('I','M','C','1'));
+
+    dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo);
+    gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo;
+    dri_bo_reference(gen7_mfd_context->pre_deblocking_output.bo);
+    gen7_mfd_context->pre_deblocking_output.valid = 1;
+
+    gen7_mfd_context->post_deblocking_output.bo = NULL;
+    gen7_mfd_context->post_deblocking_output.valid = 0;
+
+    gen7_mfd_context->intra_row_store_scratch_buffer.bo = NULL;
+    gen7_mfd_context->intra_row_store_scratch_buffer.valid = 0;
+
+    gen7_mfd_context->deblocking_filter_row_store_scratch_buffer.bo = NULL;
+    gen7_mfd_context->deblocking_filter_row_store_scratch_buffer.valid = 0;
+
+    gen7_mfd_context->bsd_mpc_row_store_scratch_buffer.bo = NULL;
+    gen7_mfd_context->bsd_mpc_row_store_scratch_buffer.valid = 0;
+
+    gen7_mfd_context->mpr_row_store_scratch_buffer.bo = NULL;
+    gen7_mfd_context->mpr_row_store_scratch_buffer.valid = 0;
+
+    gen7_mfd_context->bitplane_read_buffer.bo = NULL;
+    gen7_mfd_context->bitplane_read_buffer.valid = 0;
+}
+
+static const int va_to_gen7_jpeg_rotation[4] = {
+    GEN7_JPEG_ROTATION_0,
+    GEN7_JPEG_ROTATION_90,
+    GEN7_JPEG_ROTATION_180,
+    GEN7_JPEG_ROTATION_270
+};
+
+static void
+gen7_mfd_jpeg_pic_state(VADriverContextP ctx,
+                        struct decode_state *decode_state,
+                        struct gen7_mfd_context *gen7_mfd_context)
+{
+    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+    VAPictureParameterBufferJPEG *pic_param;
+    int chroma_type = GEN7_YUV400;
+    int frame_width_in_blks;
+    int frame_height_in_blks;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VAPictureParameterBufferJPEG *)decode_state->pic_param->buffer;
+
+    assert(pic_param->type == VA_JPEG_SOF0); /* only support BASELINE on Ivybridge */
+
+    if (pic_param->num_components == 1)
+        chroma_type = GEN7_YUV400;
+    else if (pic_param->num_components == 3) {
+        int h1 = pic_param->components[0].h_sampling_factor;
+        int h2 = pic_param->components[1].h_sampling_factor;
+        int h3 = pic_param->components[2].h_sampling_factor;
+        int v1 = pic_param->components[0].v_sampling_factor;
+        int v2 = pic_param->components[1].v_sampling_factor;
+        int v3 = pic_param->components[2].v_sampling_factor;
+
+        if (h1 == 2 && h2 == 1 && h3 == 1 &&
+            v1 == 2 && v2 == 1 && v3 == 1)
+            chroma_type = GEN7_YUV420;
+        else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+                 v1 == 1 && v2 == 1 && v3 == 1)
+            chroma_type = GEN7_YUV422H_2Y;
+        else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+                 v1 == 1 && v2 == 1 && v3 == 1)
+            chroma_type = GEN7_YUV444;
+        else if (h1 == 4 && h2 == 1 && h3 == 1 &&
+                 v1 == 1 && v2 == 1 && v3 == 1)
+            chroma_type = GEN7_YUV411;
+        else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+                 v1 == 2 && v2 == 1 && v3 == 1)
+            chroma_type = GEN7_YUV422V_2Y;
+        else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+                 v1 == 2 && v2 == 2 && v3 == 2)
+            chroma_type = GEN7_YUV422H_4Y;
+        else if (h2 == 2 && h2 == 2 && h3 == 2 &&
+                 v1 == 2 && v2 == 1 && v3 == 1)
+            chroma_type = GEN7_YUV422V_4Y;
+        else
+            assert(0);
+    }
+
+    if (chroma_type == GEN7_YUV400 &&
+        chroma_type == GEN7_YUV444 &&
+        chroma_type == GEN7_YUV422V_2Y) {
+        frame_width_in_blks = ((pic_param->image_width + 7) / 8);
+        frame_height_in_blks = ((pic_param->image_height + 7) / 8);
+    } else if (chroma_type == GEN7_YUV411) {
+        frame_width_in_blks = ((pic_param->image_width + 31) / 32) * 4;
+        frame_height_in_blks = ((pic_param->image_height + 31) / 32) * 4;
+    } else {
+        frame_width_in_blks = ((pic_param->image_width + 15) / 16) * 2;
+        frame_height_in_blks = ((pic_param->image_height + 15) / 16) * 2;
+    }
+
+    BEGIN_BCS_BATCH(batch, 3);
+    OUT_BCS_BATCH(batch, MFX_JPEG_PIC_STATE | (3 - 2));
+    OUT_BCS_BATCH(batch,
+                  (va_to_gen7_jpeg_rotation[pic_param->rotation] << 4) |    /* rotation */
+                  (chroma_type << 0));
+    OUT_BCS_BATCH(batch,
+                  ((frame_height_in_blks - 1) << 16) |   /* FrameHeightInBlks */
+                  ((frame_width_in_blks - 1) << 0));    /* FrameWidthInBlks */
+    ADVANCE_BCS_BATCH(batch);
+}
+
+static const int va_to_gen7_jpeg_hufftable[2] = {
+    MFX_HUFFTABLE_ID_Y,
+    MFX_HUFFTABLE_ID_UV
+};
+
+static void
+gen7_mfd_jpeg_huff_table_state(VADriverContextP ctx,
+                               struct decode_state *decode_state,
+                               struct gen7_mfd_context *gen7_mfd_context)
+{
+    VAHuffmanTableBufferJPEG *huffman_table;
+    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+    int index;
+
+    if (!decode_state->huffman_table || !decode_state->huffman_table->buffer)
+        return;
+
+    huffman_table = (VAHuffmanTableBufferJPEG *)decode_state->huffman_table->buffer;
+
+    for (index = 0; index < 2; index++) {
+        if (huffman_table->huffman_table_mask & (1 << index)) {
+            int id = va_to_gen7_jpeg_hufftable[index];
+            BEGIN_BCS_BATCH(batch, 53);
+            OUT_BCS_BATCH(batch, MFX_JPEG_HUFF_TABLE_STATE | (53 - 2));
+            OUT_BCS_BATCH(batch, id);
+            intel_batchbuffer_data(batch, huffman_table->huffman_table[index].dc_bits, 12);
+            intel_batchbuffer_data(batch, huffman_table->huffman_table[index].dc_huffval, 12);
+            intel_batchbuffer_data(batch, huffman_table->huffman_table[index].ac_bits, 16);
+            intel_batchbuffer_data(batch, huffman_table->huffman_table[index].ac_huffval, 164);
+            ADVANCE_BCS_BATCH(batch);
+        }
+    }
+}
+
+static const int va_to_gen7_jpeg_qm[4] = {
+    MFX_QM_JPEG_LUMA_Y_QUANTIZER_MATRIX,
+    MFX_QM_JPEG_CHROMA_CB_QUANTIZER_MATRIX,
+    MFX_QM_JPEG_CHROMA_CR_QUANTIZER_MATRIX,
+    MFX_QM_JPEG_ALPHA_QUANTIZER_MATRIX
+};
+
+static void
+gen7_mfd_jpeg_qm_state(VADriverContextP ctx,
+                       struct decode_state *decode_state,
+                       struct gen7_mfd_context *gen7_mfd_context)
+{
+    VAIQMatrixBufferJPEG *iq_matrix;
+    int index;
+
+    if (!decode_state->iq_matrix || !decode_state->iq_matrix->buffer)
+        return;
+
+    iq_matrix = (VAIQMatrixBufferJPEG *)decode_state->iq_matrix->buffer;
+
+    for (index = 0; index < 3; index++) {
+        if (iq_matrix->quantizer_matrix_mask & (1 << index)) {
+            int qm_type = va_to_gen7_jpeg_qm[index];
+            unsigned char *qm = iq_matrix->quantizer_matrix[index];
+
+            gen7_mfd_qm_state(ctx, qm_type, qm, 64, gen7_mfd_context);
+        }
+    }
+}
+
+static void
+gen7_mfd_jpeg_bsd_object(VADriverContextP ctx,
+                         VAPictureParameterBufferJPEG *pic_param,
+                         VASliceParameterBufferJPEG *slice_param,
+                         VASliceParameterBufferJPEG *next_slice_param,
+                         dri_bo *slice_data_bo,
+                         struct gen7_mfd_context *gen7_mfd_context)
+{
+    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+    int scan_component_mask = 0;
+    int i;
+
+    assert(slice_param->num_components > 0);
+    assert(slice_param->num_components < 4);
+    assert(slice_param->num_components <= pic_param->num_components);
+
+    for (i = 0; i < slice_param->num_components; i++) {
+        switch (pic_param->components[slice_param->components[i].index].component_id) {
+        case VA_JPEG_COMPONENT_ID_Y:
+            scan_component_mask |= (1 << 0);
+            break;
+        case VA_JPEG_COMPONENT_ID_U:
+            scan_component_mask |= (1 << 1);
+            break;
+        case VA_JPEG_COMPONENT_ID_V:
+            scan_component_mask |= (1 << 2);
+            break;
+        default:
+            assert(0);
+            break;
+        }
+    }
+
+    BEGIN_BCS_BATCH(batch, 6);
+    OUT_BCS_BATCH(batch, MFD_JPEG_BSD_OBJECT | (6 - 2));
+    OUT_BCS_BATCH(batch, 
+                  slice_param->slice_data_size);
+    OUT_BCS_BATCH(batch, 
+                  slice_param->slice_data_offset);
+    OUT_BCS_BATCH(batch,
+                  slice_param->slice_horizontal_position << 16 |
+                  slice_param->slice_vertical_position << 0);
+    OUT_BCS_BATCH(batch,
+                  ((slice_param->num_components != 1) << 30) |  /* interleaved */
+                  (scan_component_mask << 27) |                 /* scan components */
+                  (0 << 26) |   /* disable interrupt allowed */
+                  (slice_param->count_in_mcus << 0));    /* MCU count */
+    OUT_BCS_BATCH(batch,
+                  (slice_param->restart_interval << 0));    /* RestartInterval */
+    ADVANCE_BCS_BATCH(batch);
+}
+
+static void
+gen7_mfd_jpeg_decode_picture(VADriverContextP ctx,
+                             struct decode_state *decode_state,
+                             struct gen7_mfd_context *gen7_mfd_context)
+{
+    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+    VAPictureParameterBufferJPEG *pic_param;
+    VASliceParameterBufferJPEG *slice_param, *next_slice_param, *next_slice_group_param;
+    dri_bo *slice_data_bo;
+    int i, j;
+
+    assert(decode_state->pic_param && decode_state->pic_param->buffer);
+    pic_param = (VAPictureParameterBufferJPEG *)decode_state->pic_param->buffer;
+
+    gen7_mfd_jpeg_decode_init(ctx, decode_state, gen7_mfd_context);
+    intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
+    intel_batchbuffer_emit_mi_flush(batch);
+    gen7_mfd_pipe_mode_select(ctx, decode_state, MFX_FORMAT_JPEG, gen7_mfd_context);
+    gen7_mfd_surface_state(ctx, decode_state, MFX_FORMAT_JPEG, gen7_mfd_context);
+    gen7_mfd_pipe_buf_addr_state(ctx, decode_state, MFX_FORMAT_JPEG, gen7_mfd_context);
+    gen7_mfd_jpeg_pic_state(ctx, decode_state, gen7_mfd_context);
+    gen7_mfd_jpeg_qm_state(ctx, decode_state, gen7_mfd_context);
+    gen7_mfd_jpeg_huff_table_state(ctx, decode_state, gen7_mfd_context);
+
+    for (j = 0; j < decode_state->num_slice_params; j++) {
+        assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
+        slice_param = (VASliceParameterBufferJPEG *)decode_state->slice_params[j]->buffer;
+        slice_data_bo = decode_state->slice_datas[j]->bo;
+        gen7_mfd_ind_obj_base_addr_state(ctx, slice_data_bo, MFX_FORMAT_JPEG, gen7_mfd_context);
+
+        if (j == decode_state->num_slice_params - 1)
+            next_slice_group_param = NULL;
+        else
+            next_slice_group_param = (VASliceParameterBufferJPEG *)decode_state->slice_params[j + 1]->buffer;
+
+        for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
+            assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
+
+            if (i < decode_state->slice_params[j]->num_elements - 1)
+                next_slice_param = slice_param + 1;
+            else
+                next_slice_param = next_slice_group_param;
+
+            gen7_mfd_jpeg_bsd_object(ctx, pic_param, slice_param, next_slice_param, slice_data_bo, gen7_mfd_context);
+            slice_param++;
+        }
+    }
+
+    intel_batchbuffer_end_atomic(batch);
+    intel_batchbuffer_flush(batch);
+}
+
 static void 
 gen7_mfd_decode_picture(VADriverContextP ctx, 
                         VAProfile profile, 
@@ -2013,6 +2316,10 @@ gen7_mfd_decode_picture(VADriverContextP ctx,
         gen7_mfd_vc1_decode_picture(ctx, decode_state, gen7_mfd_context);
         break;
 
+    case VAProfileJPEGBaseline:
+        gen7_mfd_jpeg_decode_picture(ctx, decode_state, gen7_mfd_context);
+        break;
+
     default:
         assert(0);
         break;
index af9cc54..b3eb149 100644 (file)
@@ -52,6 +52,20 @@ struct gen7_avc_surface
 #define GEN7_VC1_ADVANCED_PROFILE       2
 #define GEN7_VC1_RESERVED_PROFILE       3
 
+#define GEN7_JPEG_ROTATION_0            0
+#define GEN7_JPEG_ROTATION_90           1
+#define GEN7_JPEG_ROTATION_270          2
+#define GEN7_JPEG_ROTATION_180          3
+
+#define GEN7_YUV400                     0
+#define GEN7_YUV420                     1
+#define GEN7_YUV422H_2Y                 2
+#define GEN7_YUV444                     3
+#define GEN7_YUV411                     4
+#define GEN7_YUV422V_2Y                 5
+#define GEN7_YUV422H_4Y                 6
+#define GEN7_YUV422V_4Y                 7
+
 struct gen7_vc1_surface
 {
     dri_bo *dmv;
index 9fa9649..67d2bac 100644 (file)
@@ -512,9 +512,9 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     assert(obj_surface);
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
+    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
     i965_avc_bsd_init_avc_bsd_surface(ctx, obj_surface, pic_param, i965_h264_context);
     avc_bsd_surface = obj_surface->private_data;
-    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
 
     OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_top,
                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
index 509ae9e..13f6ed8 100644 (file)
 
 #define MFD_VC1_BSD_OBJECT                      MFX(2, 2, 1, 8)
 
+#define MFX_JPEG_PIC_STATE                      MFX(2, 7, 0, 0)
+#define MFX_JPEG_HUFF_TABLE_STATE               MFX(2, 7, 0, 2)
+
+#define MFD_JPEG_BSD_OBJECT                     MFX(2, 7, 1, 8)
+
 #define I965_DEPTHFORMAT_D32_FLOAT              1
 
 #define BASE_ADDRESS_MODIFY             (1 << 0)
 #define MFX_QM_JPEG_LUMA_Y_QUANTIZER_MATRIX     0
 #define MFX_QM_JPEG_CHROMA_CB_QUANTIZER_MATRIX  1
 #define MFX_QM_JPEG_CHROMA_CR_QUANTIZER_MATRIX  2
+#define MFX_QM_JPEG_ALPHA_QUANTIZER_MATRIX      3 /* for new device */
+
+#define MFX_HUFFTABLE_ID_Y                      0
+#define MFX_HUFFTABLE_ID_UV                     1 /* UV on Ivybridge */
 
 #define MFD_MODE_VLD            0
 #define MFD_MODE_IT             1
index 8b91d35..2443641 100644 (file)
                          IS_GEN6((ctx)->intel.device_id) ||         \
                          IS_GEN7((ctx)->intel.device_id))
 
+#define HAS_JPEG(ctx)   (IS_GEN7((ctx)->intel.device_id) &&     \
+                         (ctx)->intel.has_bsd)
+
+
 enum {
     I965_SURFACETYPE_RGBA = 1,
     I965_SURFACETYPE_YUV,
@@ -200,6 +204,10 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileNone;
     }
 
+    if (HAS_JPEG(i965)) {
+        profile_list[i++] = VAProfileJPEGBaseline;
+    }
+
     /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
     assert(i <= I965_MAX_PROFILES);
     *num_profiles = i;
@@ -246,6 +254,11 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
             entrypoint_list[n++] = VAEntrypointVideoProc;
         break;
 
+    case VAProfileJPEGBaseline:
+        if (HAS_JPEG(i965))
+            entrypoint_list[n++] = VAEntrypointVLD;
+        break;
+
     default:
         break;
     }
@@ -379,6 +392,13 @@ i965_CreateConfig(VADriverContextP ctx,
             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
 
+    case VAProfileJPEGBaseline:
+        if (HAS_JPEG(i965) && VAEntrypointVLD == entrypoint) {
+            vaStatus = VA_STATUS_SUCCESS;
+        } else {
+            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+        }
+
         break;
     default:
         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
@@ -518,7 +538,6 @@ i965_CreateSurfaces(VADriverContextP ctx,
             obj_surface->height = ALIGN(obj_surface->orig_height, 16);
         }
 
-        obj_surface->size = SIZE_YUV420(obj_surface->width, obj_surface->height);
         obj_surface->flags = SURFACE_REFERENCED;
         obj_surface->fourcc = 0;
         obj_surface->bo = NULL;
@@ -1074,7 +1093,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
     case VAProcFilterBaseParameterBufferType:
     case VAProcFilterDeinterlacingParameterBufferType:
     case VAProcFilterProcAmpParameterBufferType:
-
+    case VAHuffmanTableBufferType:
         /* Ok */
         break;
 
@@ -1451,6 +1470,7 @@ i965_BeginPicture(VADriverContextP ctx,
 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
+DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
 
 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
@@ -1492,6 +1512,10 @@ i965_decoder_render_picture(VADriverContextP ctx,
             vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
             break;
 
+        case VAHuffmanTableBufferType:
+            vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
+            break;
+
         default:
             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
             break;
@@ -2058,17 +2082,31 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
 
     if (obj_surface->bo) {
         assert(obj_surface->fourcc);
+        assert(obj_surface->fourcc == fourcc);
         return;
     }
 
+    if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
+        fourcc == VA_FOURCC('I', 'M', 'C', '3'))
+        obj_surface->size = ALIGN(obj_surface->width * obj_surface->height * 2, 0x1000);
+    else 
+        obj_surface->size = ALIGN(obj_surface->width * obj_surface->height * 3 / 2, 0x1000);
+
     if (tiled) {
         uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
         unsigned long pitch;
+        unsigned long height;
+
+        if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
+            fourcc == VA_FOURCC('I', 'M', 'C', '3'))
+            height = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32) * 2;
+        else
+            height = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
 
         obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr, 
                                                    "vaapi surface",
-                                                   obj_surface->width, 
-                                                   obj_surface->height + obj_surface->height / 2,
+                                                   obj_surface->width,
+                                                   height,
                                                    1,
                                                    &tiling_mode,
                                                    &pitch,
index 6285d7f..b4aef6a 100644 (file)
@@ -90,6 +90,7 @@ struct decode_state
     struct buffer_store **slice_params;
     struct buffer_store *iq_matrix;
     struct buffer_store *bit_plane;
+    struct buffer_store *huffman_table;
     struct buffer_store **slice_datas;
     VASurfaceID current_render_target;
     int max_slice_params;
index b45edfc..9be8bf7 100644 (file)
@@ -781,18 +781,30 @@ i965_render_src_surfaces_state(VADriverContextP ctx,
         i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
         i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);     /* V */
         i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
+    } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
+        int u3 = 5, u4 = 6, v5 = 3, v6 = 4;
+
+        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* U */
+        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+        i965_render_src_surface_state(ctx, v5, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);     /* V */
+        i965_render_src_surface_state(ctx, v6, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+    } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
+        int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
+
+        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* U */
+        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+        i965_render_src_surface_state(ctx, v5, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);     /* V */
+        i965_render_src_surface_state(ctx, v6, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
+    } else if (obj_surface->fourcc == VA_FOURCC('N','V','1','2')) {
+        i965_render_src_surface_state(ctx, 3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM); /* UV */
+        i965_render_src_surface_state(ctx, 4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM);
     } else {
-        if (obj_surface->fourcc == VA_FOURCC('N','V','1','2')) {
-            i965_render_src_surface_state(ctx, 3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM); /* UV */
-            i965_render_src_surface_state(ctx, 4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM);
-        } else {
-            int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
-            
-            i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* U */
-            i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
-            i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);     /* V */
-            i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
-        }
+        int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
+        
+        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* U */
+        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
+        i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);     /* V */
+        i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
     }
 }