OSDN Git Service

Add the 10bit-scaling conversion for I010 format
[android-x86/hardware-intel-common-vaapi.git] / src / i965_drv_video.c
index 259bfc0..fbb6407 100644 (file)
 #include "i965_decoder.h"
 #include "i965_encoder.h"
 
+#include "i965_post_processing.h"
+
+#include "gen9_vp9_encapi.h"
+
 #define CONFIG_ID_OFFSET                0x01000000
 #define CONTEXT_ID_OFFSET               0x02000000
 #define SURFACE_ID_OFFSET               0x04000000
 #define IMAGE_ID_OFFSET                 0x0a000000
 #define SUBPIC_ID_OFFSET                0x10000000
 
-#define HAS_MPEG2_DECODING(ctx)  ((ctx)->codec_info->has_mpeg2_decoding && \
-                                  (ctx)->intel.has_bsd)
-
-#define HAS_MPEG2_ENCODING(ctx)  ((ctx)->codec_info->has_mpeg2_encoding && \
-                                  (ctx)->intel.has_bsd)
-
-#define HAS_H264_DECODING(ctx)  ((ctx)->codec_info->has_h264_decoding && \
-                                 (ctx)->intel.has_bsd)
-
-#define HAS_H264_ENCODING(ctx)  ((ctx)->codec_info->has_h264_encoding && \
-                                 (ctx)->intel.has_bsd)
-
-#define HAS_LP_H264_ENCODING(ctx)  ((ctx)->codec_info->has_lp_h264_encoding && \
-                                    (ctx)->intel.has_bsd)
-
-#define HAS_VC1_DECODING(ctx)   ((ctx)->codec_info->has_vc1_decoding && \
-                                 (ctx)->intel.has_bsd)
-
-#define HAS_JPEG_DECODING(ctx)  ((ctx)->codec_info->has_jpeg_decoding && \
-                                 (ctx)->intel.has_bsd)
-                                                                  
-#define HAS_JPEG_ENCODING(ctx)  ((ctx)->codec_info->has_jpeg_encoding && \
-                                 (ctx)->intel.has_bsd)      
-
-#define HAS_VPP(ctx)    ((ctx)->codec_info->has_vpp)
-
-#define HAS_ACCELERATED_GETIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_getimage)
-
-#define HAS_ACCELERATED_PUTIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_putimage)
-
-#define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
-
-#define HAS_VP8_DECODING(ctx)   ((ctx)->codec_info->has_vp8_decoding && \
-                                 (ctx)->intel.has_bsd)
-
-#define HAS_VP8_ENCODING(ctx)   ((ctx)->codec_info->has_vp8_encoding && \
-                                 (ctx)->intel.has_bsd)
-
-#define HAS_H264_MVC_DECODING(ctx) \
-    (HAS_H264_DECODING(ctx) && (ctx)->codec_info->h264_mvc_dec_profiles)
-
-#define HAS_H264_MVC_DECODING_PROFILE(ctx, profile)                     \
-    (HAS_H264_MVC_DECODING(ctx) &&                                      \
-     ((ctx)->codec_info->h264_mvc_dec_profiles & (1U << profile)))
-
-#define HAS_H264_MVC_ENCODING(ctx)  ((ctx)->codec_info->has_h264_mvc_encoding && \
-                                     (ctx)->intel.has_bsd)
-
-#define HAS_HEVC_DECODING(ctx)          ((ctx)->codec_info->has_hevc_decoding && \
-                                         (ctx)->intel.has_bsd)
-
-#define HAS_HEVC_ENCODING(ctx)          ((ctx)->codec_info->has_hevc_encoding && \
-                                         (ctx)->intel.has_bsd)
-
-#define HAS_VP9_DECODING(ctx)          ((ctx)->codec_info->has_vp9_decoding && \
-                                         (ctx)->intel.has_bsd)
-
-#define HAS_VP9_DECODING_PROFILE(ctx, profile)                     \
-    (HAS_VP9_DECODING(ctx) &&                                      \
-     ((ctx)->codec_info->vp9_dec_profiles & (1U << (profile - VAProfileVP9Profile0))))
-
-#define HAS_HEVC10_DECODING(ctx)        ((ctx)->codec_info->has_hevc10_decoding && \
-                                         (ctx)->intel.has_bsd)
-
-#define HAS_VPP_P010(ctx)        ((ctx)->codec_info->has_vpp_p010 && \
-                                         (ctx)->intel.has_bsd)
-
 static int get_sampling_from_fourcc(unsigned int fourcc);
 
 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
@@ -159,6 +96,8 @@ static int get_sampling_from_fourcc(unsigned int fourcc);
 
 #define I_P010  2, 2, 2, {I965_16BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_16} }
 
+#define I_I010  2, 2, 3, {I965_16BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
+
 #define I_422H  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
 #define I_422V  1, 2, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
 #define I_YV16  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
@@ -204,6 +143,7 @@ static const i965_fourcc_info i965_fourcc_infos[] = {
     DEF_YUV(IMC1, YUV420, I_S),
 
     DEF_YUV(P010, YUV420, I_SI),
+    DEF_YUV(I010, YUV420, I_S),
 
     DEF_YUV(422H, YUV422H, I_SI),
     DEF_YUV(422V, YUV422V, I_S),
@@ -600,11 +540,13 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileHEVCMain;
     }
 
-    if (HAS_HEVC10_DECODING(i965)) {
+    if (HAS_HEVC10_DECODING(i965)||
+        HAS_HEVC10_ENCODING(i965)) {
         profile_list[i++] = VAProfileHEVCMain10;
     }
 
-    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0)) {
+    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) ||
+        HAS_VP9_ENCODING(i965)) {
         profile_list[i++] = VAProfileVP9Profile0;
     }
 
@@ -722,6 +664,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
         if (HAS_HEVC10_DECODING(i965))
             entrypoint_list[n++] = VAEntrypointVLD;
 
+        if (HAS_HEVC10_ENCODING(i965))
+            entrypoint_list[n++] = VAEntrypointEncSlice;
+
         break;
 
     case VAProfileVP9Profile0:
@@ -729,6 +674,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
         if(HAS_VP9_DECODING_PROFILE(i965, profile))
             entrypoint_list[n++] = VAEntrypointVLD;
 
+        if (HAS_VP9_ENCODING(i965) && (profile == VAProfileVP9Profile0))
+            entrypoint_list[n++] = VAEntrypointEncSlice;
+
         if(profile == VAProfileVP9Profile0) {
           if (i965->wrapper_pdrvctx) {
               VAStatus va_status = VA_STATUS_SUCCESS;
@@ -768,6 +716,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
         if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
             (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
             va_status = VA_STATUS_SUCCESS;
+        } else if (!HAS_MPEG2_DECODING(i965) && !HAS_MPEG2_ENCODING(i965)){
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -780,6 +730,9 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
             (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice) ||
             (HAS_LP_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSliceLP)) {
             va_status = VA_STATUS_SUCCESS;
+        } else if (!HAS_H264_DECODING(i965) && !HAS_H264_ENCODING(i965) &&
+                   !HAS_LP_H264_ENCODING(i965)){
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -790,6 +743,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
     case VAProfileVC1Advanced:
         if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
             va_status = VA_STATUS_SUCCESS;
+        } else if (!HAS_VC1_DECODING(i965)) {
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -798,6 +753,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
     case VAProfileNone:
         if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
             va_status = VA_STATUS_SUCCESS;
+        } else if (!HAS_VPP(i965)){
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -807,6 +764,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
         if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
             (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
             va_status = VA_STATUS_SUCCESS;
+        } else if (!HAS_JPEG_DECODING(i965) && !HAS_JPEG_ENCODING(i965)){
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -816,6 +775,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
         if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
             (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
             va_status = VA_STATUS_SUCCESS;
+        } else if (!HAS_VP8_DECODING(i965) && !HAS_VP8_ENCODING(i965)){
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -825,8 +786,12 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
     case VAProfileH264StereoHigh:
         if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
              entrypoint == VAEntrypointVLD) ||
-            (HAS_H264_MVC_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
+            (HAS_H264_MVC_ENCODING(i965) &&
+             entrypoint == VAEntrypointEncSlice)) {
             va_status = VA_STATUS_SUCCESS;
+        } else if(!HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
+                  !HAS_H264_MVC_ENCODING(i965)) {
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
         }
@@ -835,29 +800,46 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
 
     case VAProfileHEVCMain:
         if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
-            (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice)))
+            (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice))) {
             va_status = VA_STATUS_SUCCESS;
-        else
+        } else if (!HAS_HEVC_DECODING(i965) && !HAS_HEVC_ENCODING(i965)) {
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+        } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+        }
 
         break;
 
     case VAProfileHEVCMain10:
-        if (HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))
+        if ((HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
+            (HAS_HEVC10_ENCODING(i965) &&
+             (entrypoint == VAEntrypointEncSlice))) {
             va_status = VA_STATUS_SUCCESS;
-        else
+        } else if (!HAS_HEVC10_DECODING(i965) && !HAS_HEVC10_ENCODING(i965)) {
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+        } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+        }
 
         break;
 
     case VAProfileVP9Profile0:
     case VAProfileVP9Profile2:
-        if ((HAS_VP9_DECODING_PROFILE(i965, profile)) && (entrypoint == VAEntrypointVLD))
+        if ((HAS_VP9_DECODING_PROFILE(i965, profile)) &&
+            (entrypoint == VAEntrypointVLD)) {
             va_status = VA_STATUS_SUCCESS;
-        else if ((profile == VAProfileVP9Profile0) && i965->wrapper_pdrvctx)
+        } else if ((HAS_VP9_ENCODING_PROFILE(i965, profile)) &&
+                   (entrypoint == VAEntrypointEncSlice)) {
             va_status = VA_STATUS_SUCCESS;
-        else
+        } else if (profile == VAProfileVP9Profile0 && i965->wrapper_pdrvctx) {
+            va_status = VA_STATUS_SUCCESS;
+        } else if(!HAS_VP9_DECODING_PROFILE(i965, profile) &&
+                  !HAS_VP9_ENCODING(i965) && !i965->wrapper_pdrvctx) {
+            va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+        } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
+        }
+
         break;
 
     default:
@@ -901,8 +883,11 @@ i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
         break;
 
     case VAProfileNone:
-       if(HAS_VPP_P010(i965))
+        if (HAS_VPP_P010(i965))
             chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
+
+        if (HAS_VPP(i965))
+            chroma_formats |= VA_RT_FORMAT_YUV422 | VA_RT_FORMAT_RGB32;
         break;
 
     case VAProfileVP9Profile0:
@@ -948,6 +933,10 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                 if (profile != VAProfileMPEG2Main &&
                     profile != VAProfileMPEG2Simple)
                     attrib_list[i].value |= VA_RC_CBR;
+
+                if (profile == VAProfileVP9Profile0)
+                    attrib_list[i].value |= VA_RC_VBR;
+
                 break;
             } else if (entrypoint == VAEntrypointEncSliceLP) {
                 struct i965_driver_data * const i965 = i965_driver_data(ctx);
@@ -973,10 +962,13 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                     profile == VAProfileH264High ||
                     profile == VAProfileH264StereoHigh ||
                     profile == VAProfileH264MultiviewHigh ||
-                    profile == VAProfileHEVCMain) {
+                    profile == VAProfileHEVCMain ||
+                    profile == VAProfileHEVCMain10) {
                     attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
                                              VA_ENC_PACKED_HEADER_SLICE);
                 }
+                else if (profile == VAProfileVP9Profile0)
+                    attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
                 break;
             }
             else if (entrypoint == VAEntrypointEncPicture) {
@@ -1031,13 +1023,45 @@ i965_GetConfigAttributes(VADriverContextP ctx,
             break;
 
         case VAConfigAttribEncROI:
-            if ((entrypoint == VAEntrypointEncSliceLP) &&
-                (profile == VAProfileH264ConstrainedBaseline ||
+            if (entrypoint == VAEntrypointEncSlice ||
+                entrypoint == VAEntrypointEncSliceLP) {
+
+                if (profile == VAProfileH264ConstrainedBaseline ||
+                    profile == VAProfileH264Main ||
+                    profile == VAProfileH264High) {
+
+                    VAConfigAttribValEncROI *roi_config =
+                        (VAConfigAttribValEncROI *)&(attrib_list[i].value);
+
+                    if(entrypoint == VAEntrypointEncSliceLP) {
+                        roi_config->bits.num_roi_regions = 3;
+                        roi_config->bits.roi_rc_priority_support = 0;
+                        roi_config->bits.roi_rc_qp_delat_support = 0;
+                    } else {
+                        roi_config->bits.num_roi_regions =
+                            I965_MAX_NUM_ROI_REGIONS;
+                        roi_config->bits.roi_rc_priority_support = 0;
+                        roi_config->bits.roi_rc_qp_delat_support = 1;
+                    }
+                }else {
+                    attrib_list[i].value = 0;
+                }
+            }
+
+            break;
+
+        case VAConfigAttribEncRateControlExt:
+            if ((profile == VAProfileH264ConstrainedBaseline ||
                  profile == VAProfileH264Main ||
-                 profile == VAProfileH264High))
-                attrib_list[i].value = 3;
-            else
-                attrib_list[i].value = 0;
+                 profile == VAProfileH264High) &&
+                entrypoint == VAEntrypointEncSlice) {
+                VAConfigAttribValEncRateControlExt *val_config = (VAConfigAttribValEncRateControlExt *)&(attrib_list[i].value);
+
+                val_config->bits.max_num_temporal_layers_minus1 = MAX_TEMPORAL_LAYERS - 1;
+                val_config->bits.temporal_layer_bitrate_control_flag = 1;
+            } else {
+                attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+            }
 
             break;
 
@@ -1267,6 +1291,7 @@ i965_surface_native_memory(VADriverContextP ctx,
     // todo, should we disable tiling for 422 format?
     if (expected_fourcc == VA_FOURCC_I420 ||
         expected_fourcc == VA_FOURCC_IYUV ||
+        expected_fourcc == VA_FOURCC_I010 ||
         expected_fourcc == VA_FOURCC_YV12 ||
         expected_fourcc == VA_FOURCC_YV16)
         tiling = 0;
@@ -1336,6 +1361,7 @@ i965_suface_external_memory(VADriverContextP ctx,
     case VA_FOURCC_I420:
     case VA_FOURCC_IYUV:
     case VA_FOURCC_IMC3:
+    case VA_FOURCC_I010:
         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
 
@@ -1559,6 +1585,7 @@ i965_CreateSurfaces2(
         obj_surface->user_disable_tiling = false;
         obj_surface->user_h_stride_set = false;
         obj_surface->user_v_stride_set = false;
+        obj_surface->border_cleared = false;
 
         obj_surface->subpic_render_idx = 0;
         for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
@@ -2028,7 +2055,7 @@ static void
 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
 {
     struct object_context *obj_context = (struct object_context *)obj;
-    int i;
+    int i, j;
 
     if (obj_context->hw_context) {
         obj_context->hw_context->destroy(obj_context->hw_context);
@@ -2039,18 +2066,9 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
         i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
 
     } else if (obj_context->codec_type == CODEC_ENC) {
-        assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
-        i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
-        i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
-
         i965_release_buffer_store(&obj_context->codec_state.encode.q_matrix);
         i965_release_buffer_store(&obj_context->codec_state.encode.huffman_table);
 
-        for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
-            i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
-
-        free(obj_context->codec_state.encode.slice_params);
-
         assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
         i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
@@ -2062,7 +2080,8 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
 
         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
-            i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
+            for (j = 0; j < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param[0]); j++)
+                i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i][j]);
 
         for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
@@ -2090,6 +2109,7 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
         free(obj_context->codec_state.encode.packed_header_data_ext);
 
+        i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
     } else {
         assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
         assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
@@ -2112,6 +2132,20 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
     object_heap_free(heap, obj);
 }
 
+static inline void
+max_resolution(struct i965_driver_data *i965,
+               struct object_config *obj_config,
+               int *w,                                  /* out */
+               int *h)                                  /* out */
+{
+    if (i965->codec_info->max_resolution) {
+        i965->codec_info->max_resolution(i965, obj_config, w, h);
+    } else {
+        *w = i965->codec_info->max_width;
+        *h = i965->codec_info->max_height;
+    }
+}
+
 VAStatus
 i965_CreateContext(VADriverContextP ctx,
                    VAConfigID config_id,
@@ -2129,14 +2163,18 @@ i965_CreateContext(VADriverContextP ctx,
     VAStatus vaStatus = VA_STATUS_SUCCESS;
     int contextID;
     int i;
+    int max_width;
+    int max_height;
 
     if (NULL == obj_config) {
         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
         return vaStatus;
     }
 
-    if (picture_width > i965->codec_info->max_width ||
-        picture_height > i965->codec_info->max_height) {
+    max_resolution(i965, obj_config, &max_width, &max_height);
+
+    if (picture_width > max_width ||
+        picture_height > max_height) {
         vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
         return vaStatus;
     }
@@ -2189,9 +2227,6 @@ i965_CreateContext(VADriverContextP ctx,
             obj_context->codec_type = CODEC_ENC;
             memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
             obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
-            obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
-            obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
-                                                               sizeof(*obj_context->codec_state.encode.slice_params));
             obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
             obj_context->codec_state.encode.packed_header_params_ext =
                 calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
@@ -2215,9 +2250,12 @@ i965_CreateContext(VADriverContextP ctx,
 
             obj_context->codec_state.encode.slice_index = 0;
             packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
-            if (packed_attrib)
+            if (packed_attrib) {
                 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
-            else {
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    obj_context->codec_state.encode.packed_header_flag =
+                            packed_attrib->value & VA_ENC_PACKED_HEADER_RAW_DATA;
+            } else {
                 /* use the default value. SPS/PPS/RAWDATA is passed from user
                  * while Slice_header data is generated by driver.
                  */
@@ -2225,6 +2263,10 @@ i965_CreateContext(VADriverContextP ctx,
                                VA_ENC_PACKED_HEADER_SEQUENCE |
                                VA_ENC_PACKED_HEADER_PICTURE |
                                VA_ENC_PACKED_HEADER_RAW_DATA;
+
+                /* it is not used for VP9 */
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    obj_context->codec_state.encode.packed_header_flag = 0;
             }
             assert(i965->codec_info->enc_hw_context_init);
             obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
@@ -2361,6 +2403,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
     case VAProcFilterParameterBufferType:
     case VAHuffmanTableBufferType:
     case VAProbabilityBufferType:
+    case VAEncMacroblockMapBufferType:
         /* Ok */
         break;
 
@@ -2421,6 +2464,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
     } else if (type == VASliceDataBufferType || 
                type == VAImageBufferType || 
                type == VAEncCodedBufferType ||
+               type == VAEncMacroblockMapBufferType ||
                type == VAProbabilityBufferType) {
 
         /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
@@ -2748,7 +2792,7 @@ i965_BeginPicture(VADriverContextP ctx,
     struct object_surface *obj_surface = SURFACE(render_target);
     struct object_config *obj_config;
     VAStatus vaStatus = VA_STATUS_SUCCESS;
-    int i;
+    int i, j;
 
     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
     ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
@@ -2761,14 +2805,6 @@ i965_BeginPicture(VADriverContextP ctx,
     if (obj_context->codec_type == CODEC_PROC) {
         obj_context->codec_state.proc.current_render_target = render_target;
     } else if (obj_context->codec_type == CODEC_ENC) {
-        i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
-
-        for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
-            i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
-        }
-
-        obj_context->codec_state.encode.num_slice_params = 0;
-
         /* ext */
         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
 
@@ -2799,6 +2835,25 @@ i965_BeginPicture(VADriverContextP ctx,
         obj_context->codec_state.encode.num_packed_header_data_ext = 0;
         obj_context->codec_state.encode.slice_index = 0;
         obj_context->codec_state.encode.vps_sps_seq_index = 0;
+        /*
+        * Based on ROI definition in va/va.h, the ROI set through this
+        * structure is applicable only to the current frame or field.
+        * That is to say: it is on-the-fly setting. If it is not set,
+        * the current frame doesn't use ROI.
+        * It is uncertain whether the other misc buffer should be released.
+        * So only release the previous ROI buffer.
+        */
+        i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[VAEncMiscParameterTypeROI][0]);
+
+        i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
+
+        if (obj_config->profile == VAProfileVP9Profile0) {
+            for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
+                for (j = 0; j < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param[0]); j++)
+                    i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i][j]);
+
+            i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
+        }
     } else {
         obj_context->codec_state.decode.current_render_target = render_target;
         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
@@ -3064,6 +3119,7 @@ DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
 /* extended buffer */
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
+DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(encmb_map, encmb_map)
 
 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
@@ -3104,6 +3160,29 @@ i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
     return VA_STATUS_SUCCESS;
 }
 
+static int
+i965_encoder_get_misc_paramerter_buffer_index(VADriverContextP ctx,
+                                              struct encode_state *encode,
+                                              VAEncMiscParameterBuffer *misc_param)
+{
+    int index = 0;
+
+    if (!encode->has_layers)
+        return 0;
+
+    if (misc_param->type == VAEncMiscParameterTypeRateControl) {
+        VAEncMiscParameterRateControl *misc_rate_control = (VAEncMiscParameterRateControl *)misc_param->data;
+
+        index = misc_rate_control->rc_flags.bits.temporal_id;
+    } else if (misc_param->type == VAEncMiscParameterTypeFrameRate) {
+        VAEncMiscParameterFrameRate *misc_frame_rate = (VAEncMiscParameterFrameRate *)misc_param->data;
+
+        index = misc_frame_rate->framerate_flags.bits.temporal_id;
+    }
+
+    return index;
+}
+
 static VAStatus
 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
                                           struct object_context *obj_context,
@@ -3111,6 +3190,7 @@ i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
 {
     struct encode_state *encode = &obj_context->codec_state.encode;
     VAEncMiscParameterBuffer *param = NULL;
+    int index;
 
     ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
     ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
@@ -3120,8 +3200,16 @@ i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
     if (param->type >= ARRAY_ELEMS(encode->misc_param))
         return VA_STATUS_ERROR_INVALID_PARAMETER;
 
-    i965_release_buffer_store(&encode->misc_param[param->type]);
-    i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
+    if (param->type == VAEncMiscParameterTypeTemporalLayerStructure)
+        encode->has_layers = 1;
+
+    index = i965_encoder_get_misc_paramerter_buffer_index(ctx, encode, param);
+
+    if (index >= ARRAY_ELEMS(encode->misc_param[0]))
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+    i965_release_buffer_store(&encode->misc_param[param->type][index]);
+    i965_reference_buffer_store(&encode->misc_param[param->type][index], obj_buffer->buffer_store);
 
     return VA_STATUS_SUCCESS;
 }
@@ -3215,7 +3303,8 @@ i965_encoder_render_picture(VADriverContextP ctx,
             if ((param->type == VAEncPackedHeaderRawData) ||
                 (param->type == VAEncPackedHeaderSlice)) {
                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
-            } else if((obj_config->profile == VAProfileHEVCMain) &&
+            } else if((obj_config->profile == VAProfileHEVCMain ||
+                obj_config->profile == VAProfileHEVCMain10) &&
                 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
                 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
                                                                           obj_context,
@@ -3237,10 +3326,14 @@ i965_encoder_render_picture(VADriverContextP ctx,
                 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                 return vaStatus;
             }
+
             if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
                 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
 
+                if (obj_config->profile == VAProfileVP9Profile0)
+                    break;
+
                 /* When the PACKED_SLICE_HEADER flag is passed, it will use
                  * the packed_slice_header as the delimeter to decide how
                  * the packed rawdata is inserted for the given slice.
@@ -3309,7 +3402,8 @@ i965_encoder_render_picture(VADriverContextP ctx,
                     ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
                     VA_STATUS_ERROR_ENCODING_ERROR);
 
-                if((obj_config->profile == VAProfileHEVCMain) &&
+                if((obj_config->profile == VAProfileHEVCMain ||
+                    obj_config->profile == VAProfileHEVCMain10) &&
                     (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
 
                         vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
@@ -3335,6 +3429,10 @@ i965_encoder_render_picture(VADriverContextP ctx,
                                                                  obj_buffer);
             break;
             
+        case VAEncMacroblockMapBufferType:
+            vaStatus = I965_RENDER_ENCODE_BUFFER(encmb_map);
+            break;
+
         default:
             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
             break;
@@ -3439,18 +3537,18 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
             WARN_ONCE("the packed header/data is not paired for encoding!\n");
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
-        if (!(obj_context->codec_state.encode.pic_param ||
-                obj_context->codec_state.encode.pic_param_ext)) {
+        if (!obj_context->codec_state.encode.pic_param_ext) {
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
-        if (!(obj_context->codec_state.encode.seq_param ||
-                obj_context->codec_state.encode.seq_param_ext) &&
+        if (!obj_context->codec_state.encode.seq_param_ext &&
                 (VAEntrypointEncPicture != obj_config->entrypoint)) {
-            return VA_STATUS_ERROR_INVALID_PARAMETER;
+            /* The seq_param is not mandatory for VP9 encoding */
+            if (obj_config->profile != VAProfileVP9Profile0)
+                return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
-        if ((obj_context->codec_state.encode.num_slice_params <=0) &&
-                (obj_context->codec_state.encode.num_slice_params_ext <=0) &&
-                (obj_config->profile != VAProfileVP8Version0_3)) {
+        if ((obj_context->codec_state.encode.num_slice_params_ext <=0) &&
+                ((obj_config->profile != VAProfileVP8Version0_3) &&
+                 (obj_config->profile != VAProfileVP9Profile0))) {
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
 
@@ -4041,7 +4139,7 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
             obj_surface->y_cb_offset = 0; 
             obj_surface->y_cr_offset = 0; 
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
-            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+            obj_surface->cb_cr_height = obj_surface->orig_height;
             region_width = obj_surface->width;
             region_height = obj_surface->height;
             
@@ -4085,15 +4183,18 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
 
         case VA_FOURCC_YV16:
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->width = ALIGN(obj_surface->cb_cr_width, i965->codec_info->min_linear_wpitch) * 2;
             obj_surface->cb_cr_height = obj_surface->orig_height;
             obj_surface->y_cr_offset = obj_surface->height;
             obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
             obj_surface->cb_cr_pitch = obj_surface->width / 2;
+            region_width = obj_surface->width;
             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
             break;
 
         case VA_FOURCC_YV12:
         case VA_FOURCC_I420:
+        case VA_FOURCC_IYUV:
             if (fourcc == VA_FOURCC_YV12) {
                 obj_surface->y_cr_offset = obj_surface->height;
                 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
@@ -4103,11 +4204,24 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
             }
 
             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->width = ALIGN(obj_surface->cb_cr_width, i965->codec_info->min_linear_wpitch) * 2;
             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
             obj_surface->cb_cr_pitch = obj_surface->width / 2;
+            region_width = obj_surface->width;
             region_height = obj_surface->height + obj_surface->height / 2;
             break;
 
+        case VA_FOURCC_I010:
+            obj_surface->y_cb_offset = obj_surface->height;
+            obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
+            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->width = ALIGN(obj_surface->cb_cr_width * 2, i965->codec_info->min_linear_wpitch) * 2;
+            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+            obj_surface->cb_cr_pitch = obj_surface->width / 2;
+            region_width = obj_surface->width;
+            region_height = obj_surface->height + obj_surface->height / 2;
+
+            break;
         case VA_FOURCC_YUY2:
         case VA_FOURCC_UYVY:
             obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
@@ -4258,6 +4372,7 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
         break;
 
     case VA_FOURCC_I420:
+    case VA_FOURCC_I010:
     case VA_FOURCC_422H:
     case VA_FOURCC_IMC3:
     case VA_FOURCC_444P:
@@ -4292,14 +4407,12 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
             image->format.red_mask = 0x000000ff;
             image->format.green_mask = 0x0000ff00;
             image->format.blue_mask = 0x00ff0000;
-            image->format.alpha_mask = 0x00000000;
             break;
         case VA_FOURCC_BGRA:
         case VA_FOURCC_BGRX:
             image->format.red_mask = 0x00ff0000;
             image->format.green_mask = 0x0000ff00;
             image->format.blue_mask = 0x000000ff;
-            image->format.alpha_mask = 0x00000000;
             break;
         default:
             goto error;
@@ -4308,10 +4421,12 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
         switch (image->format.fourcc) {
         case VA_FOURCC_RGBA:
         case VA_FOURCC_BGRA:
+            image->format.alpha_mask = 0xff000000;
             image->format.depth = 32;
             break;
         case VA_FOURCC_RGBX:
         case VA_FOURCC_BGRX:
+            image->format.alpha_mask = 0x00000000;
             image->format.depth = 24;
             break;
         default:
@@ -5426,7 +5541,9 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
     struct object_config *obj_config;
     int i = 0;
     VASurfaceAttrib *attribs = NULL;
-    
+    int max_width;
+    int max_height;
+
     if (config == VA_INVALID_ID)
         return VA_STATUS_ERROR_INVALID_CONFIG;
 
@@ -5715,6 +5832,15 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
                 attribs[i].value.value.i = VA_FOURCC_NV12;
                 i++;
+
+                if ((obj_config->profile == VAProfileHEVCMain10) ||
+                    (obj_config->profile == VAProfileVP9Profile2)) {
+                    attribs[i].type = VASurfaceAttribPixelFormat;
+                    attribs[i].value.type = VAGenericValueTypeInteger;
+                    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+                    attribs[i].value.value.i = VA_FOURCC_P010;
+                    i++;
+                }
             }
         } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
                    obj_config->entrypoint == VAEntrypointVideoProc ||
@@ -5795,6 +5921,12 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
                   attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
                   attribs[i].value.value.i = VA_FOURCC_P010;
                   i++;
+
+                  attribs[i].type = VASurfaceAttribPixelFormat;
+                  attribs[i].value.type = VAGenericValueTypeInteger;
+                  attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
+                  attribs[i].value.value.i = VA_FOURCC_I010;
+                  i++;
                 }
             }
         }
@@ -5814,16 +5946,18 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
     attribs[i].value.value.p = NULL; /* ignore */
     i++;
 
+    max_resolution(i965, obj_config, &max_width, &max_height);
+
     attribs[i].type = VASurfaceAttribMaxWidth;
     attribs[i].value.type = VAGenericValueTypeInteger;
     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
-    attribs[i].value.value.i = i965->codec_info->max_width;
+    attribs[i].value.value.i = max_width;
     i++;
 
     attribs[i].type = VASurfaceAttribMaxHeight;
     attribs[i].value.type = VAGenericValueTypeInteger;
     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
-    attribs[i].value.value.i = i965->codec_info->max_height;
+    attribs[i].value.value.i = max_height;
     i++;
 
     if (i > *num_attribs) {