OSDN Git Service

Add the 10bit-scaling conversion for I010 format
[android-x86/hardware-intel-common-vaapi.git] / src / i965_drv_video.c
index 66cdb9e..fbb6407 100644 (file)
@@ -48,6 +48,8 @@
 #include "i965_decoder.h"
 #include "i965_encoder.h"
 
+#include "i965_post_processing.h"
+
 #include "gen9_vp9_encapi.h"
 
 #define CONFIG_ID_OFFSET                0x01000000
 #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)
-
-#define HAS_VP9_ENCODING(ctx)          ((ctx)->codec_info->has_vp9_encoding && \
-                                         (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) */
@@ -164,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} }
@@ -209,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),
@@ -605,7 +540,8 @@ 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;
     }
 
@@ -728,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:
@@ -777,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;
         }
@@ -789,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;
         }
@@ -799,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;
         }
@@ -807,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;
         }
@@ -816,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;
         }
@@ -825,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;
         }
@@ -834,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;
         }
@@ -844,31 +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 ((HAS_VP9_ENCODING(i965)) && (entrypoint == VAEntrypointEncSlice))
+        } else if ((HAS_VP9_ENCODING_PROFILE(i965, profile)) &&
+                   (entrypoint == VAEntrypointEncSlice)) {
             va_status = VA_STATUS_SUCCESS;
-        else if ((profile == VAProfileVP9Profile0) && i965->wrapper_pdrvctx)
+        } else if (profile == VAProfileVP9Profile0 && i965->wrapper_pdrvctx) {
             va_status = VA_STATUS_SUCCESS;
-        else
+        } 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:
@@ -912,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:
@@ -988,7 +962,8 @@ 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);
                 }
@@ -1048,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;
 
@@ -1284,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;
@@ -1353,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);
 
@@ -1576,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++){
@@ -2045,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);
@@ -2056,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);
@@ -2079,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]);
@@ -2225,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,
@@ -2643,16 +2642,7 @@ i965_MapBuffer(VADriverContextP ctx,
                     coded_buffer_segment->status_support) {
                     vaStatus = obj_context->hw_context->get_status(ctx, obj_context->hw_context, coded_buffer_segment);
                 } else {
-
-                    if (coded_buffer_segment->codec == CODEC_VP9) {
-
-                        if (obj_context == NULL)
-                            return VA_STATUS_ERROR_ENCODING_ERROR;
-
-                        gen9_vp9_get_coded_status(ctx, (char *)coded_buffer_segment,
-                                                  obj_context->hw_context);
-                    }
-                    else if (coded_buffer_segment->codec == CODEC_H264 ||
+                    if (coded_buffer_segment->codec == CODEC_H264 ||
                         coded_buffer_segment->codec == CODEC_H264_MVC) {
                         delimiter0 = H264_DELIMITER0;
                         delimiter1 = H264_DELIMITER1;
@@ -2679,9 +2669,6 @@ i965_MapBuffer(VADriverContextP ctx,
                         ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
                     }
 
-                    if(coded_buffer_segment->codec == CODEC_VP9) {
-                        /* it is already handled */
-                    } else
                     if(coded_buffer_segment->codec == CODEC_JPEG) {
                         for(i = 0; i <  obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
                             if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
@@ -2805,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);
@@ -2818,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);
 
@@ -2856,11 +2835,22 @@ 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++)
-                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]);
 
             i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
         }
@@ -3170,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,
@@ -3177,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);
@@ -3186,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;
 }
@@ -3281,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,
@@ -3379,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,
@@ -3513,19 +3537,16 @@ 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)) {
             /* 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) &&
+        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;
@@ -4118,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;
             
@@ -4162,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;
@@ -4180,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);
@@ -4335,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:
@@ -5794,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 ||
@@ -5874,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++;
                 }
             }
         }