hardware/intel/intel-driver
Revisión | 1cd9cf544d64e09ef3503374782cf5d682b4aa27 (tree) |
---|---|
Tiempo | 2015-05-25 09:25:42 |
Autor | Gwenole Beauchesne <gb.devel@gmai...> |
Commiter | Xiang, Haihao |
vpp: fix advanced deinterlacing on Sandybridge and Ivybridge.
This fixes support for Motion Adaptive deinterlacing mode on both
Sandybridge and Ivybridge platforms. In particular, correct field
ordering is now supported, and STMM ping-pong buffering is added.
v2: changed STMM surface format to Y800 for a single plane.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
@@ -1392,9 +1392,6 @@ gen8_post_processing_context_finalize(VADriverContextP ctx, | ||
1392 | 1392 | dri_bo_unreference(pp_context->surface_state_binding_table.bo); |
1393 | 1393 | pp_context->surface_state_binding_table.bo = NULL; |
1394 | 1394 | |
1395 | - dri_bo_unreference(pp_context->pp_dndi_context.stmm_bo); | |
1396 | - pp_context->pp_dndi_context.stmm_bo = NULL; | |
1397 | - | |
1398 | 1395 | dri_bo_unreference(pp_context->pp_dn_context.stmm_bo); |
1399 | 1396 | pp_context->pp_dn_context.stmm_bo = NULL; |
1400 | 1397 |
@@ -1498,9 +1495,6 @@ gen8_post_processing_context_common_init(VADriverContextP ctx, | ||
1498 | 1495 | pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1); |
1499 | 1496 | pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1); |
1500 | 1497 | |
1501 | - pp_context->pp_dndi_context.current_out_surface = VA_INVALID_SURFACE; | |
1502 | - pp_context->pp_dndi_context.current_out_obj_surface = NULL; | |
1503 | - pp_context->pp_dndi_context.frame_order = -1; | |
1504 | 1498 | pp_context->batch = batch; |
1505 | 1499 | |
1506 | 1500 | pp_context->idrt_size = 5 * sizeof(struct gen8_interface_descriptor_data); |
@@ -1137,6 +1137,271 @@ static struct pp_module pp_modules_gen75[] = { | ||
1137 | 1137 | |
1138 | 1138 | }; |
1139 | 1139 | |
1140 | +static void | |
1141 | +pp_dndi_frame_store_reset(DNDIFrameStore *fs) | |
1142 | +{ | |
1143 | + fs->obj_surface = NULL; | |
1144 | + fs->surface_id = VA_INVALID_ID; | |
1145 | + fs->is_scratch_surface = 0; | |
1146 | +} | |
1147 | + | |
1148 | +static inline void | |
1149 | +pp_dndi_frame_store_swap(DNDIFrameStore *fs1, DNDIFrameStore *fs2) | |
1150 | +{ | |
1151 | + const DNDIFrameStore tmpfs = *fs1; | |
1152 | + *fs1 = *fs2; | |
1153 | + *fs2 = tmpfs; | |
1154 | +} | |
1155 | + | |
1156 | +static inline void | |
1157 | +pp_dndi_frame_store_clear(DNDIFrameStore *fs, VADriverContextP ctx) | |
1158 | +{ | |
1159 | + if (fs->obj_surface && fs->is_scratch_surface) { | |
1160 | + VASurfaceID va_surface = fs->obj_surface->base.id; | |
1161 | + i965_DestroySurfaces(ctx, &va_surface, 1); | |
1162 | + } | |
1163 | + pp_dndi_frame_store_reset(fs); | |
1164 | +} | |
1165 | + | |
1166 | +static void | |
1167 | +pp_dndi_context_init(struct pp_dndi_context *dndi_ctx) | |
1168 | +{ | |
1169 | + int i; | |
1170 | + | |
1171 | + memset(dndi_ctx, 0, sizeof(*dndi_ctx)); | |
1172 | + for (i = 0; i < ARRAY_ELEMS(dndi_ctx->frame_store); i++) | |
1173 | + pp_dndi_frame_store_reset(&dndi_ctx->frame_store[i]); | |
1174 | +} | |
1175 | + | |
1176 | +static VAStatus | |
1177 | +pp_dndi_context_init_surface_params(struct pp_dndi_context *dndi_ctx, | |
1178 | + struct object_surface *obj_surface, | |
1179 | + const VAProcPipelineParameterBuffer *pipe_params, | |
1180 | + const VAProcFilterParameterBufferDeinterlacing *deint_params) | |
1181 | +{ | |
1182 | + DNDIFrameStore *fs; | |
1183 | + | |
1184 | + dndi_ctx->is_di_enabled = 1; | |
1185 | + dndi_ctx->is_di_adv_enabled = 0; | |
1186 | + dndi_ctx->is_first_frame = 0; | |
1187 | + dndi_ctx->is_second_field = 0; | |
1188 | + | |
1189 | + /* Check whether we are deinterlacing the second field */ | |
1190 | + if (dndi_ctx->is_di_enabled) { | |
1191 | + const unsigned int tff = | |
1192 | + !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST); | |
1193 | + const unsigned int is_top_field = | |
1194 | + !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD); | |
1195 | + | |
1196 | + if ((tff ^ is_top_field) != 0) { | |
1197 | + fs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT]; | |
1198 | + if (fs->surface_id != obj_surface->base.id) { | |
1199 | + WARN_ONCE("invalid surface provided for second field\n"); | |
1200 | + return VA_STATUS_ERROR_INVALID_PARAMETER; | |
1201 | + } | |
1202 | + dndi_ctx->is_second_field = 1; | |
1203 | + } | |
1204 | + } | |
1205 | + | |
1206 | + /* Check whether we are deinterlacing the first frame */ | |
1207 | + if (dndi_ctx->is_di_enabled) { | |
1208 | + switch (deint_params->algorithm) { | |
1209 | + case VAProcDeinterlacingBob: | |
1210 | + dndi_ctx->is_first_frame = 1; | |
1211 | + break; | |
1212 | + case VAProcDeinterlacingMotionAdaptive: | |
1213 | + fs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT]; | |
1214 | + if (fs->surface_id == VA_INVALID_ID) | |
1215 | + dndi_ctx->is_first_frame = 1; | |
1216 | + else if (dndi_ctx->is_second_field) { | |
1217 | + /* At this stage, we have already deinterlaced the | |
1218 | + first field successfully. So, the first frame flag | |
1219 | + is trigerred if the previous field was deinterlaced | |
1220 | + without reference frame */ | |
1221 | + fs = &dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS]; | |
1222 | + if (fs->surface_id == VA_INVALID_ID) | |
1223 | + dndi_ctx->is_first_frame = 1; | |
1224 | + } | |
1225 | + else { | |
1226 | + if (pipe_params->num_forward_references < 1 || | |
1227 | + pipe_params->forward_references[0] == VA_INVALID_ID) { | |
1228 | + WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n"); | |
1229 | + return VA_STATUS_ERROR_INVALID_PARAMETER; | |
1230 | + } | |
1231 | + } | |
1232 | + dndi_ctx->is_di_adv_enabled = 1; | |
1233 | + break; | |
1234 | + default: | |
1235 | + WARN_ONCE("unsupported deinterlacing algorithm (%d)\n", | |
1236 | + deint_params->algorithm); | |
1237 | + return VA_STATUS_ERROR_UNSUPPORTED_FILTER; | |
1238 | + } | |
1239 | + } | |
1240 | + return VA_STATUS_SUCCESS; | |
1241 | +} | |
1242 | + | |
1243 | +static VAStatus | |
1244 | +pp_dndi_context_ensure_surfaces_storage(VADriverContextP ctx, | |
1245 | + struct i965_post_processing_context *pp_context, | |
1246 | + struct object_surface *src_surface, struct object_surface *dst_surface) | |
1247 | +{ | |
1248 | + struct i965_driver_data * const i965 = i965_driver_data(ctx); | |
1249 | + struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context; | |
1250 | + unsigned int src_fourcc, dst_fourcc; | |
1251 | + unsigned int src_sampling, dst_sampling; | |
1252 | + unsigned int src_tiling, dst_tiling; | |
1253 | + unsigned int i, swizzle; | |
1254 | + VAStatus status; | |
1255 | + | |
1256 | + /* Determine input surface info. Always use NV12 Y-tiled */ | |
1257 | + if (src_surface->bo) { | |
1258 | + src_fourcc = src_surface->fourcc; | |
1259 | + src_sampling = src_surface->subsampling; | |
1260 | + dri_bo_get_tiling(src_surface->bo, &src_tiling, &swizzle); | |
1261 | + src_tiling = !!src_tiling; | |
1262 | + } | |
1263 | + else { | |
1264 | + src_fourcc = VA_FOURCC_NV12; | |
1265 | + src_sampling = SUBSAMPLE_YUV420; | |
1266 | + src_tiling = 1; | |
1267 | + status = i965_check_alloc_surface_bo(ctx, src_surface, | |
1268 | + src_tiling, src_fourcc, src_sampling); | |
1269 | + if (status != VA_STATUS_SUCCESS) | |
1270 | + return status; | |
1271 | + } | |
1272 | + | |
1273 | + /* Determine output surface info. Always use NV12 Y-tiled */ | |
1274 | + if (dst_surface->bo) { | |
1275 | + dst_fourcc = dst_surface->fourcc; | |
1276 | + dst_sampling = dst_surface->subsampling; | |
1277 | + dri_bo_get_tiling(dst_surface->bo, &dst_tiling, &swizzle); | |
1278 | + dst_tiling = !!dst_tiling; | |
1279 | + } | |
1280 | + else { | |
1281 | + dst_fourcc = VA_FOURCC_NV12; | |
1282 | + dst_sampling = SUBSAMPLE_YUV420; | |
1283 | + dst_tiling = 1; | |
1284 | + status = i965_check_alloc_surface_bo(ctx, dst_surface, | |
1285 | + dst_tiling, dst_fourcc, dst_sampling); | |
1286 | + if (status != VA_STATUS_SUCCESS) | |
1287 | + return status; | |
1288 | + } | |
1289 | + | |
1290 | + /* Create pipeline surfaces */ | |
1291 | + for (i = 0; i < ARRAY_ELEMS(dndi_ctx->frame_store); i ++) { | |
1292 | + struct object_surface *obj_surface; | |
1293 | + VASurfaceID new_surface; | |
1294 | + unsigned int width, height; | |
1295 | + | |
1296 | + if (dndi_ctx->frame_store[i].obj_surface) | |
1297 | + continue; // user allocated surface, not VPP internal | |
1298 | + | |
1299 | + if (i <= DNDI_FRAME_IN_STMM) { | |
1300 | + width = src_surface->orig_width; | |
1301 | + height = src_surface->orig_height; | |
1302 | + } | |
1303 | + else { | |
1304 | + width = dst_surface->orig_width; | |
1305 | + height = dst_surface->orig_height; | |
1306 | + } | |
1307 | + | |
1308 | + status = i965_CreateSurfaces(ctx, width, height, VA_RT_FORMAT_YUV420, | |
1309 | + 1, &new_surface); | |
1310 | + if (status != VA_STATUS_SUCCESS) | |
1311 | + return status; | |
1312 | + | |
1313 | + obj_surface = SURFACE(new_surface); | |
1314 | + assert(obj_surface != NULL); | |
1315 | + | |
1316 | + if (i <= DNDI_FRAME_IN_PREVIOUS) { | |
1317 | + status = i965_check_alloc_surface_bo(ctx, obj_surface, | |
1318 | + src_tiling, src_fourcc, src_sampling); | |
1319 | + } | |
1320 | + else if (i == DNDI_FRAME_IN_STMM || i == DNDI_FRAME_OUT_STMM) { | |
1321 | + status = i965_check_alloc_surface_bo(ctx, obj_surface, | |
1322 | + 1, VA_FOURCC_Y800, SUBSAMPLE_YUV400); | |
1323 | + } | |
1324 | + else if (i >= DNDI_FRAME_OUT_CURRENT) { | |
1325 | + status = i965_check_alloc_surface_bo(ctx, obj_surface, | |
1326 | + dst_tiling, dst_fourcc, dst_sampling); | |
1327 | + } | |
1328 | + if (status != VA_STATUS_SUCCESS) | |
1329 | + return status; | |
1330 | + | |
1331 | + dndi_ctx->frame_store[i].obj_surface = obj_surface; | |
1332 | + dndi_ctx->frame_store[i].is_scratch_surface = 1; | |
1333 | + } | |
1334 | + return VA_STATUS_SUCCESS; | |
1335 | +} | |
1336 | + | |
1337 | +static VAStatus | |
1338 | +pp_dndi_context_ensure_surfaces(VADriverContextP ctx, | |
1339 | + struct i965_post_processing_context *pp_context, | |
1340 | + struct object_surface *src_surface, struct object_surface *dst_surface) | |
1341 | +{ | |
1342 | + struct i965_driver_data * const i965 = i965_driver_data(ctx); | |
1343 | + struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context; | |
1344 | + DNDIFrameStore *ifs, *ofs; | |
1345 | + bool is_new_frame = false; | |
1346 | + | |
1347 | + /* Update the previous input surface */ | |
1348 | + is_new_frame = dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT].surface_id != | |
1349 | + src_surface->base.id; | |
1350 | + if (is_new_frame) { | |
1351 | + ifs = &dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS]; | |
1352 | + ofs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT]; | |
1353 | + do { | |
1354 | + const VAProcPipelineParameterBuffer * const pipe_params = | |
1355 | + pp_context->pipeline_param; | |
1356 | + struct object_surface *obj_surface; | |
1357 | + | |
1358 | + if (pipe_params->num_forward_references < 1) | |
1359 | + break; | |
1360 | + if (pipe_params->forward_references[0] == VA_INVALID_ID) | |
1361 | + break; | |
1362 | + | |
1363 | + obj_surface = SURFACE(pipe_params->forward_references[0]); | |
1364 | + if (!obj_surface || obj_surface->base.id == ifs->surface_id) | |
1365 | + break; | |
1366 | + | |
1367 | + pp_dndi_frame_store_clear(ifs, ctx); | |
1368 | + if (obj_surface->base.id == ofs->surface_id) { | |
1369 | + *ifs = *ofs; | |
1370 | + pp_dndi_frame_store_reset(ofs); | |
1371 | + } | |
1372 | + else { | |
1373 | + ifs->obj_surface = obj_surface; | |
1374 | + ifs->surface_id = obj_surface->base.id; | |
1375 | + } | |
1376 | + } while (0); | |
1377 | + } | |
1378 | + | |
1379 | + /* Update the input surface */ | |
1380 | + ifs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT]; | |
1381 | + pp_dndi_frame_store_clear(ifs, ctx); | |
1382 | + ifs->obj_surface = src_surface; | |
1383 | + ifs->surface_id = src_surface->base.id; | |
1384 | + | |
1385 | + /* Update the Spatial Temporal Motion Measure (STMM) surfaces */ | |
1386 | + if (is_new_frame) | |
1387 | + pp_dndi_frame_store_swap(&dndi_ctx->frame_store[DNDI_FRAME_IN_STMM], | |
1388 | + &dndi_ctx->frame_store[DNDI_FRAME_OUT_STMM]); | |
1389 | + | |
1390 | + /* Update the output surfaces */ | |
1391 | + ofs = &dndi_ctx->frame_store[DNDI_FRAME_OUT_CURRENT]; | |
1392 | + if (dndi_ctx->is_di_adv_enabled && !dndi_ctx->is_first_frame) { | |
1393 | + pp_dndi_frame_store_swap(ofs, | |
1394 | + &dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS]); | |
1395 | + if (!dndi_ctx->is_second_field) | |
1396 | + ofs = &dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS]; | |
1397 | + } | |
1398 | + pp_dndi_frame_store_clear(ofs, ctx); | |
1399 | + ofs->obj_surface = dst_surface; | |
1400 | + ofs->surface_id = dst_surface->base.id; | |
1401 | + | |
1402 | + return VA_STATUS_SUCCESS; | |
1403 | +} | |
1404 | + | |
1140 | 1405 | static int |
1141 | 1406 | pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface) |
1142 | 1407 | { |
@@ -3071,177 +3336,91 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex | ||
3071 | 3336 | const VARectangle *dst_rect, |
3072 | 3337 | void *filter_param) |
3073 | 3338 | { |
3074 | - struct i965_driver_data *i965 = i965_driver_data(ctx); | |
3075 | - struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->pp_dndi_context; | |
3339 | + struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context; | |
3076 | 3340 | struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter; |
3077 | 3341 | struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter; |
3078 | - struct object_surface *previous_in_obj_surface, *current_in_obj_surface, *previous_out_obj_surface, *current_out_obj_surface; | |
3342 | + const VAProcPipelineParameterBuffer * const pipe_params = | |
3343 | + pp_context->pipeline_param; | |
3344 | + const VAProcFilterParameterBufferDeinterlacing * const deint_params = | |
3345 | + filter_param; | |
3346 | + struct object_surface * const src_obj_surface = (struct object_surface *) | |
3347 | + src_surface->base; | |
3348 | + struct object_surface * const dst_obj_surface = (struct object_surface *) | |
3349 | + dst_surface->base; | |
3350 | + struct object_surface *obj_surface; | |
3079 | 3351 | struct i965_sampler_dndi *sampler_dndi; |
3080 | - int index; | |
3081 | - int w, h; | |
3082 | - int orig_w, orig_h; | |
3083 | - int dndi_top_first = 1; | |
3084 | - VAProcFilterParameterBufferDeinterlacing *di_filter_param = (VAProcFilterParameterBufferDeinterlacing *)filter_param; | |
3085 | - int is_first_frame = (pp_dndi_context->frame_order == -1); | |
3086 | - | |
3087 | - if (di_filter_param->flags & VA_DEINTERLACING_BOTTOM_FIELD) | |
3088 | - dndi_top_first = 0; | |
3089 | - else | |
3090 | - dndi_top_first = 1; | |
3091 | - | |
3092 | - /* surface */ | |
3093 | - current_in_obj_surface = (struct object_surface *)src_surface->base; | |
3094 | - | |
3095 | - if (di_filter_param->algorithm == VAProcDeinterlacingBob) { | |
3096 | - previous_in_obj_surface = current_in_obj_surface; | |
3097 | - is_first_frame = 1; | |
3098 | - } else if (di_filter_param->algorithm == VAProcDeinterlacingMotionAdaptive) { | |
3099 | - if (pp_dndi_context->frame_order == 0) { | |
3100 | - VAProcPipelineParameterBuffer *pipeline_param = pp_context->pipeline_param; | |
3101 | - if (!pipeline_param || | |
3102 | - !pipeline_param->num_forward_references || | |
3103 | - pipeline_param->forward_references[0] == VA_INVALID_ID) { | |
3104 | - WARN_ONCE("A forward temporal reference is needed for Motion adaptive deinterlacing !!!\n"); | |
3105 | - | |
3106 | - return VA_STATUS_ERROR_INVALID_PARAMETER; | |
3107 | - } else { | |
3108 | - previous_in_obj_surface = SURFACE(pipeline_param->forward_references[0]); | |
3109 | - assert(previous_in_obj_surface && previous_in_obj_surface->bo); | |
3110 | - | |
3111 | - is_first_frame = 0; | |
3112 | - } | |
3113 | - } else if (pp_dndi_context->frame_order == 1) { | |
3114 | - vpp_surface_convert(ctx, | |
3115 | - pp_dndi_context->current_out_obj_surface, | |
3116 | - (struct object_surface *)dst_surface->base); | |
3117 | - pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2; | |
3118 | - is_first_frame = 0; | |
3119 | - | |
3120 | - return VA_STATUS_SUCCESS_1; | |
3121 | - } else { | |
3122 | - previous_in_obj_surface = current_in_obj_surface; | |
3123 | - is_first_frame = 1; | |
3124 | - } | |
3125 | - } else { | |
3126 | - return VA_STATUS_ERROR_UNIMPLEMENTED; | |
3127 | - } | |
3128 | - | |
3129 | - /* source (temporal reference) YUV surface index 5 */ | |
3130 | - orig_w = previous_in_obj_surface->orig_width; | |
3131 | - orig_h = previous_in_obj_surface->orig_height; | |
3132 | - w = previous_in_obj_surface->width; | |
3133 | - h = previous_in_obj_surface->height; | |
3134 | - i965_pp_set_surface2_state(ctx, pp_context, | |
3135 | - previous_in_obj_surface->bo, 0, | |
3136 | - orig_w, orig_h, w, | |
3137 | - 0, h, | |
3138 | - SURFACE_FORMAT_PLANAR_420_8, 1, | |
3139 | - 5); | |
3140 | - | |
3141 | - /* source surface */ | |
3142 | - orig_w = current_in_obj_surface->orig_width; | |
3143 | - orig_h = current_in_obj_surface->orig_height; | |
3144 | - w = current_in_obj_surface->width; | |
3145 | - h = current_in_obj_surface->height; | |
3146 | - | |
3147 | - /* source UV surface index 2 */ | |
3148 | - i965_pp_set_surface_state(ctx, pp_context, | |
3149 | - current_in_obj_surface->bo, w * h, | |
3150 | - orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, | |
3151 | - 2, 0); | |
3152 | - | |
3153 | - /* source YUV surface index 4 */ | |
3154 | - i965_pp_set_surface2_state(ctx, pp_context, | |
3155 | - current_in_obj_surface->bo, 0, | |
3156 | - orig_w, orig_h, w, | |
3157 | - 0, h, | |
3158 | - SURFACE_FORMAT_PLANAR_420_8, 1, | |
3159 | - 4); | |
3160 | - | |
3161 | - /* source STMM surface index 6 */ | |
3162 | - if (pp_dndi_context->stmm_bo == NULL) { | |
3163 | - pp_dndi_context->stmm_bo = dri_bo_alloc(i965->intel.bufmgr, | |
3164 | - "STMM surface", | |
3165 | - w * h, | |
3166 | - 4096); | |
3167 | - assert(pp_dndi_context->stmm_bo); | |
3168 | - } | |
3169 | - | |
3170 | - i965_pp_set_surface_state(ctx, pp_context, | |
3171 | - pp_dndi_context->stmm_bo, 0, | |
3172 | - orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3173 | - 6, 0); | |
3352 | + int index, dndi_top_first; | |
3353 | + int w, h, orig_w, orig_h; | |
3354 | + VAStatus status; | |
3174 | 3355 | |
3175 | - /* destination (Previous frame) */ | |
3176 | - previous_out_obj_surface = (struct object_surface *)dst_surface->base; | |
3177 | - orig_w = previous_out_obj_surface->orig_width; | |
3178 | - orig_h = previous_out_obj_surface->orig_height; | |
3179 | - w = previous_out_obj_surface->width; | |
3180 | - h = previous_out_obj_surface->height; | |
3356 | + status = pp_dndi_context_init_surface_params(dndi_ctx, src_obj_surface, | |
3357 | + pipe_params, deint_params); | |
3358 | + if (status != VA_STATUS_SUCCESS) | |
3359 | + return status; | |
3181 | 3360 | |
3182 | - if (is_first_frame) { | |
3183 | - current_out_obj_surface = previous_out_obj_surface; | |
3184 | - } else { | |
3185 | - VAStatus va_status; | |
3186 | - | |
3187 | - if (pp_dndi_context->current_out_surface == VA_INVALID_SURFACE) { | |
3188 | - unsigned int tiling = 0, swizzle = 0; | |
3189 | - dri_bo_get_tiling(previous_out_obj_surface->bo, &tiling, &swizzle); | |
3190 | - | |
3191 | - va_status = i965_CreateSurfaces(ctx, | |
3192 | - orig_w, | |
3193 | - orig_h, | |
3194 | - VA_RT_FORMAT_YUV420, | |
3195 | - 1, | |
3196 | - &pp_dndi_context->current_out_surface); | |
3197 | - assert(va_status == VA_STATUS_SUCCESS); | |
3198 | - pp_dndi_context->current_out_obj_surface = SURFACE(pp_dndi_context->current_out_surface); | |
3199 | - assert(pp_dndi_context->current_out_obj_surface); | |
3200 | - i965_check_alloc_surface_bo(ctx, | |
3201 | - pp_dndi_context->current_out_obj_surface, | |
3202 | - tiling != I915_TILING_NONE, | |
3203 | - VA_FOURCC_NV12, | |
3204 | - SUBSAMPLE_YUV420); | |
3205 | - } | |
3361 | + status = pp_dndi_context_ensure_surfaces(ctx, pp_context, | |
3362 | + src_obj_surface, dst_obj_surface); | |
3363 | + if (status != VA_STATUS_SUCCESS) | |
3364 | + return status; | |
3206 | 3365 | |
3207 | - current_out_obj_surface = pp_dndi_context->current_out_obj_surface; | |
3208 | - } | |
3366 | + status = pp_dndi_context_ensure_surfaces_storage(ctx, pp_context, | |
3367 | + src_obj_surface, dst_obj_surface); | |
3368 | + if (status != VA_STATUS_SUCCESS) | |
3369 | + return status; | |
3209 | 3370 | |
3210 | - /* destination (Previous frame) Y surface index 7 */ | |
3211 | - i965_pp_set_surface_state(ctx, pp_context, | |
3212 | - previous_out_obj_surface->bo, 0, | |
3213 | - orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3214 | - 7, 1); | |
3371 | + /* Current input surface (index = 4) */ | |
3372 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT].obj_surface; | |
3373 | + i965_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0, | |
3374 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3375 | + 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 4); | |
3376 | + | |
3377 | + /* Previous input surface (index = 5) */ | |
3378 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS].obj_surface; | |
3379 | + i965_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0, | |
3380 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3381 | + 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 5); | |
3382 | + | |
3383 | + /* STMM input surface (index = 6) */ | |
3384 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_STMM].obj_surface; | |
3385 | + i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3386 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3387 | + I965_SURFACEFORMAT_R8_UNORM, 6, 1); | |
3388 | + | |
3389 | + /* Previous output surfaces (index = { 7, 8 }) */ | |
3390 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS].obj_surface; | |
3391 | + w = obj_surface->width; | |
3392 | + h = obj_surface->height; | |
3393 | + orig_w = obj_surface->orig_width; | |
3394 | + orig_h = obj_surface->orig_height; | |
3215 | 3395 | |
3216 | - /* destination (Previous frame) UV surface index 8 */ | |
3217 | - i965_pp_set_surface_state(ctx, pp_context, | |
3218 | - previous_out_obj_surface->bo, w * h, | |
3219 | - orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, | |
3220 | - 8, 1); | |
3396 | + i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3397 | + orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 7, 1); | |
3398 | + i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h, | |
3399 | + orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 8, 1); | |
3221 | 3400 | |
3222 | - /* destination(Current frame) */ | |
3223 | - orig_w = current_out_obj_surface->orig_width; | |
3224 | - orig_h = current_out_obj_surface->orig_height; | |
3225 | - w = current_out_obj_surface->width; | |
3226 | - h = current_out_obj_surface->height; | |
3401 | + /* Current output surfaces (index = { 10, 11 }) */ | |
3402 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_CURRENT].obj_surface; | |
3403 | + w = obj_surface->width; | |
3404 | + h = obj_surface->height; | |
3405 | + orig_w = obj_surface->orig_width; | |
3406 | + orig_h = obj_surface->orig_height; | |
3227 | 3407 | |
3228 | - /* destination (Current frame) Y surface index xxx */ | |
3229 | - i965_pp_set_surface_state(ctx, pp_context, | |
3230 | - current_out_obj_surface->bo, 0, | |
3231 | - orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3232 | - 10, 1); | |
3408 | + i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3409 | + orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 10, 1); | |
3410 | + i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h, | |
3411 | + orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 11, 1); | |
3233 | 3412 | |
3234 | - /* destination (Current frame) UV surface index xxx */ | |
3235 | - i965_pp_set_surface_state(ctx, pp_context, | |
3236 | - current_out_obj_surface->bo, w * h, | |
3237 | - orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, | |
3238 | - 11, 1); | |
3413 | + /* STMM output surface (index = 20) */ | |
3414 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_STMM].obj_surface; | |
3415 | + i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3416 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3417 | + I965_SURFACEFORMAT_R8_UNORM, 20, 1); | |
3239 | 3418 | |
3240 | - /* STMM output surface, index 20 */ | |
3241 | - i965_pp_set_surface_state(ctx, pp_context, | |
3242 | - pp_dndi_context->stmm_bo, 0, | |
3243 | - orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3244 | - 20, 1); | |
3419 | + /* If we are in "First Frame" mode, i.e. past frames are not | |
3420 | + available for motion measure, then don't use the TFF flag */ | |
3421 | + dndi_top_first = !(deint_params->flags & (dndi_ctx->is_first_frame ? | |
3422 | + VA_DEINTERLACING_BOTTOM_FIELD : | |
3423 | + VA_DEINTERLACING_BOTTOM_FIELD_FIRST)); | |
3245 | 3424 | |
3246 | 3425 | /* sampler dndi */ |
3247 | 3426 | dri_bo_map(pp_context->sampler_state_table.bo, True); |
@@ -3290,7 +3469,7 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex | ||
3290 | 3469 | sampler_dndi[index].dw6.di_partial = 0; |
3291 | 3470 | sampler_dndi[index].dw6.dndi_top_first = dndi_top_first; |
3292 | 3471 | sampler_dndi[index].dw6.dndi_stream_id = 0; |
3293 | - sampler_dndi[index].dw6.dndi_first_frame = is_first_frame; | |
3472 | + sampler_dndi[index].dw6.dndi_first_frame = dndi_ctx->is_first_frame; | |
3294 | 3473 | sampler_dndi[index].dw6.progressive_dn = 0; |
3295 | 3474 | sampler_dndi[index].dw6.fmd_tear_threshold = 2; |
3296 | 3475 | sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 100; |
@@ -3306,7 +3485,7 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex | ||
3306 | 3485 | /* private function & data */ |
3307 | 3486 | pp_context->pp_x_steps = pp_dndi_x_steps; |
3308 | 3487 | pp_context->pp_y_steps = pp_dndi_y_steps; |
3309 | - pp_context->private_context = &pp_context->pp_dndi_context; | |
3488 | + pp_context->private_context = dndi_ctx; | |
3310 | 3489 | pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter; |
3311 | 3490 | |
3312 | 3491 | pp_static_parameter->grf1.statistics_surface_picth = w / 2; |
@@ -3319,13 +3498,10 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex | ||
3319 | 3498 | pp_inline_parameter->grf5.block_vertical_mask = 0xff; |
3320 | 3499 | pp_inline_parameter->grf5.block_horizontal_mask = 0xffff; |
3321 | 3500 | |
3322 | - pp_dndi_context->dest_w = w; | |
3323 | - pp_dndi_context->dest_h = h; | |
3501 | + dndi_ctx->dest_w = w; | |
3502 | + dndi_ctx->dest_h = h; | |
3324 | 3503 | |
3325 | 3504 | dst_surface->flags = I965_SURFACE_FLAG_FRAME; |
3326 | - | |
3327 | - pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2; | |
3328 | - | |
3329 | 3505 | return VA_STATUS_SUCCESS; |
3330 | 3506 | } |
3331 | 3507 |
@@ -3571,176 +3747,90 @@ gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_c | ||
3571 | 3747 | const VARectangle *dst_rect, |
3572 | 3748 | void *filter_param) |
3573 | 3749 | { |
3574 | - struct i965_driver_data *i965 = i965_driver_data(ctx); | |
3575 | - struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->pp_dndi_context; | |
3750 | + struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context; | |
3576 | 3751 | struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter; |
3577 | - struct object_surface *previous_in_obj_surface, *current_in_obj_surface, *previous_out_obj_surface, *current_out_obj_surface; | |
3752 | + const VAProcPipelineParameterBuffer * const pipe_params = | |
3753 | + pp_context->pipeline_param; | |
3754 | + const VAProcFilterParameterBufferDeinterlacing * const deint_params = | |
3755 | + filter_param; | |
3756 | + struct object_surface * const src_obj_surface = (struct object_surface *) | |
3757 | + src_surface->base; | |
3758 | + struct object_surface * const dst_obj_surface = (struct object_surface *) | |
3759 | + dst_surface->base; | |
3760 | + struct object_surface *obj_surface; | |
3578 | 3761 | struct gen7_sampler_dndi *sampler_dndi; |
3579 | - int index; | |
3580 | - int w, h; | |
3581 | - int orig_w, orig_h; | |
3582 | - int dndi_top_first = 1; | |
3583 | - VAProcFilterParameterBufferDeinterlacing *di_filter_param = (VAProcFilterParameterBufferDeinterlacing *)filter_param; | |
3584 | - int is_first_frame = (pp_dndi_context->frame_order == -1); | |
3585 | - | |
3586 | - if (di_filter_param->flags & VA_DEINTERLACING_BOTTOM_FIELD) | |
3587 | - dndi_top_first = 0; | |
3588 | - else | |
3589 | - dndi_top_first = 1; | |
3590 | - | |
3591 | - /* surface */ | |
3592 | - current_in_obj_surface = (struct object_surface *)src_surface->base; | |
3593 | - | |
3594 | - if (di_filter_param->algorithm == VAProcDeinterlacingBob) { | |
3595 | - previous_in_obj_surface = current_in_obj_surface; | |
3596 | - is_first_frame = 1; | |
3597 | - } else if (di_filter_param->algorithm == VAProcDeinterlacingMotionAdaptive) { | |
3598 | - if (pp_dndi_context->frame_order == 0) { | |
3599 | - VAProcPipelineParameterBuffer *pipeline_param = pp_context->pipeline_param; | |
3600 | - if (!pipeline_param || | |
3601 | - !pipeline_param->num_forward_references || | |
3602 | - pipeline_param->forward_references[0] == VA_INVALID_ID) { | |
3603 | - WARN_ONCE("A forward temporal reference is needed for Motion adaptive deinterlacing !!!\n"); | |
3604 | - | |
3605 | - return VA_STATUS_ERROR_INVALID_PARAMETER; | |
3606 | - } else { | |
3607 | - previous_in_obj_surface = SURFACE(pipeline_param->forward_references[0]); | |
3608 | - assert(previous_in_obj_surface && previous_in_obj_surface->bo); | |
3609 | - | |
3610 | - is_first_frame = 0; | |
3611 | - } | |
3612 | - } else if (pp_dndi_context->frame_order == 1) { | |
3613 | - vpp_surface_convert(ctx, | |
3614 | - pp_dndi_context->current_out_obj_surface, | |
3615 | - (struct object_surface *)dst_surface->base); | |
3616 | - pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2; | |
3617 | - is_first_frame = 0; | |
3618 | - | |
3619 | - return VA_STATUS_SUCCESS_1; | |
3620 | - } else { | |
3621 | - previous_in_obj_surface = current_in_obj_surface; | |
3622 | - is_first_frame = 1; | |
3623 | - } | |
3624 | - } else { | |
3625 | - return VA_STATUS_ERROR_UNIMPLEMENTED; | |
3626 | - } | |
3627 | - | |
3628 | - /* source (temporal reference) YUV surface index 4 */ | |
3629 | - orig_w = previous_in_obj_surface->orig_width; | |
3630 | - orig_h = previous_in_obj_surface->orig_height; | |
3631 | - w = previous_in_obj_surface->width; | |
3632 | - h = previous_in_obj_surface->height; | |
3633 | - gen7_pp_set_surface2_state(ctx, pp_context, | |
3634 | - previous_in_obj_surface->bo, 0, | |
3635 | - orig_w, orig_h, w, | |
3636 | - 0, h, | |
3637 | - SURFACE_FORMAT_PLANAR_420_8, 1, | |
3638 | - 4); | |
3639 | - | |
3640 | - /* source surface */ | |
3641 | - orig_w = current_in_obj_surface->orig_width; | |
3642 | - orig_h = current_in_obj_surface->orig_height; | |
3643 | - w = current_in_obj_surface->width; | |
3644 | - h = current_in_obj_surface->height; | |
3645 | - | |
3646 | - /* source UV surface index 1 */ | |
3647 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3648 | - current_in_obj_surface->bo, w * h, | |
3649 | - orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, | |
3650 | - 1, 0); | |
3651 | - | |
3652 | - /* source YUV surface index 3 */ | |
3653 | - gen7_pp_set_surface2_state(ctx, pp_context, | |
3654 | - current_in_obj_surface->bo, 0, | |
3655 | - orig_w, orig_h, w, | |
3656 | - 0, h, | |
3657 | - SURFACE_FORMAT_PLANAR_420_8, 1, | |
3658 | - 3); | |
3659 | - | |
3660 | - /* STMM / History Statistics input surface, index 5 */ | |
3661 | - if (pp_dndi_context->stmm_bo == NULL) { | |
3662 | - pp_dndi_context->stmm_bo = dri_bo_alloc(i965->intel.bufmgr, | |
3663 | - "STMM surface", | |
3664 | - w * h, | |
3665 | - 4096); | |
3666 | - assert(pp_dndi_context->stmm_bo); | |
3667 | - } | |
3668 | - | |
3669 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3670 | - pp_dndi_context->stmm_bo, 0, | |
3671 | - orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3672 | - 5, 1); | |
3762 | + int index, dndi_top_first; | |
3763 | + int w, h, orig_w, orig_h; | |
3764 | + VAStatus status; | |
3673 | 3765 | |
3674 | - /* destination surface */ | |
3675 | - previous_out_obj_surface = (struct object_surface *)dst_surface->base; | |
3676 | - orig_w = previous_out_obj_surface->orig_width; | |
3677 | - orig_h = previous_out_obj_surface->orig_height; | |
3678 | - w = previous_out_obj_surface->width; | |
3679 | - h = previous_out_obj_surface->height; | |
3680 | - | |
3681 | - if (is_first_frame) { | |
3682 | - current_out_obj_surface = previous_out_obj_surface; | |
3683 | - } else { | |
3684 | - VAStatus va_status; | |
3685 | - | |
3686 | - if (pp_dndi_context->current_out_surface == VA_INVALID_SURFACE) { | |
3687 | - unsigned int tiling = 0, swizzle = 0; | |
3688 | - dri_bo_get_tiling(previous_out_obj_surface->bo, &tiling, &swizzle); | |
3689 | - | |
3690 | - va_status = i965_CreateSurfaces(ctx, | |
3691 | - orig_w, | |
3692 | - orig_h, | |
3693 | - VA_RT_FORMAT_YUV420, | |
3694 | - 1, | |
3695 | - &pp_dndi_context->current_out_surface); | |
3696 | - assert(va_status == VA_STATUS_SUCCESS); | |
3697 | - pp_dndi_context->current_out_obj_surface = SURFACE(pp_dndi_context->current_out_surface); | |
3698 | - assert(pp_dndi_context->current_out_obj_surface); | |
3699 | - i965_check_alloc_surface_bo(ctx, | |
3700 | - pp_dndi_context->current_out_obj_surface, | |
3701 | - tiling != I915_TILING_NONE, | |
3702 | - VA_FOURCC_NV12, | |
3703 | - SUBSAMPLE_YUV420); | |
3704 | - } | |
3766 | + status = pp_dndi_context_init_surface_params(dndi_ctx, src_obj_surface, | |
3767 | + pipe_params, deint_params); | |
3768 | + if (status != VA_STATUS_SUCCESS) | |
3769 | + return status; | |
3705 | 3770 | |
3706 | - current_out_obj_surface = pp_dndi_context->current_out_obj_surface; | |
3707 | - } | |
3771 | + status = pp_dndi_context_ensure_surfaces(ctx, pp_context, | |
3772 | + src_obj_surface, dst_obj_surface); | |
3773 | + if (status != VA_STATUS_SUCCESS) | |
3774 | + return status; | |
3708 | 3775 | |
3709 | - /* destination(Previous frame) Y surface index 27 */ | |
3710 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3711 | - previous_out_obj_surface->bo, 0, | |
3712 | - orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3713 | - 27, 1); | |
3776 | + status = pp_dndi_context_ensure_surfaces_storage(ctx, pp_context, | |
3777 | + src_obj_surface, dst_obj_surface); | |
3778 | + if (status != VA_STATUS_SUCCESS) | |
3779 | + return status; | |
3714 | 3780 | |
3715 | - /* destination(Previous frame) UV surface index 28 */ | |
3716 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3717 | - previous_out_obj_surface->bo, w * h, | |
3718 | - orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, | |
3719 | - 28, 1); | |
3781 | + /* Current input surface (index = 3) */ | |
3782 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT].obj_surface; | |
3783 | + gen7_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0, | |
3784 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3785 | + 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 3); | |
3786 | + | |
3787 | + /* Previous input surface (index = 4) */ | |
3788 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS].obj_surface; | |
3789 | + gen7_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0, | |
3790 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3791 | + 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 4); | |
3792 | + | |
3793 | + /* STMM input surface (index = 5) */ | |
3794 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_STMM].obj_surface; | |
3795 | + gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3796 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3797 | + I965_SURFACEFORMAT_R8_UNORM, 5, 1); | |
3798 | + | |
3799 | + /* Previous output surfaces (index = { 27, 28 }) */ | |
3800 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS].obj_surface; | |
3801 | + w = obj_surface->width; | |
3802 | + h = obj_surface->height; | |
3803 | + orig_w = obj_surface->orig_width; | |
3804 | + orig_h = obj_surface->orig_height; | |
3720 | 3805 | |
3721 | - /* destination(Current frame) Y surface index 30 */ | |
3722 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3723 | - current_out_obj_surface->bo, 0, | |
3724 | - orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3725 | - 30, 1); | |
3806 | + gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3807 | + orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 27, 1); | |
3808 | + gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h, | |
3809 | + orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 28, 1); | |
3726 | 3810 | |
3727 | - /* destination(Current frame) UV surface index 31 */ | |
3728 | - orig_w = current_out_obj_surface->orig_width; | |
3729 | - orig_h = current_out_obj_surface->orig_height; | |
3730 | - w = current_out_obj_surface->width; | |
3731 | - h = current_out_obj_surface->height; | |
3811 | + /* Current output surfaces (index = { 30, 31 }) */ | |
3812 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_CURRENT].obj_surface; | |
3813 | + w = obj_surface->width; | |
3814 | + h = obj_surface->height; | |
3815 | + orig_w = obj_surface->orig_width; | |
3816 | + orig_h = obj_surface->orig_height; | |
3732 | 3817 | |
3733 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3734 | - current_out_obj_surface->bo, w * h, | |
3735 | - orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, | |
3736 | - 31, 1); | |
3818 | + gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3819 | + orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 30, 1); | |
3820 | + gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h, | |
3821 | + orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 31, 1); | |
3737 | 3822 | |
3738 | - /* STMM output surface, index 33 */ | |
3739 | - gen7_pp_set_surface_state(ctx, pp_context, | |
3740 | - pp_dndi_context->stmm_bo, 0, | |
3741 | - orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, | |
3742 | - 33, 1); | |
3823 | + /* STMM output surface (index = 33) */ | |
3824 | + obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_STMM].obj_surface; | |
3825 | + gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0, | |
3826 | + obj_surface->orig_width, obj_surface->orig_height, obj_surface->width, | |
3827 | + I965_SURFACEFORMAT_R8_UNORM, 33, 1); | |
3743 | 3828 | |
3829 | + /* If we are in "First Frame" mode, i.e. past frames are not | |
3830 | + available for motion measure, then don't use the TFF flag */ | |
3831 | + dndi_top_first = !(deint_params->flags & (dndi_ctx->is_first_frame ? | |
3832 | + VA_DEINTERLACING_BOTTOM_FIELD : | |
3833 | + VA_DEINTERLACING_BOTTOM_FIELD_FIRST)); | |
3744 | 3834 | |
3745 | 3835 | /* sampler dndi */ |
3746 | 3836 | dri_bo_map(pp_context->sampler_state_table.bo, True); |
@@ -3792,7 +3882,7 @@ gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_c | ||
3792 | 3882 | sampler_dndi[index].dw6.di_partial = 0; |
3793 | 3883 | sampler_dndi[index].dw6.dndi_top_first = dndi_top_first; |
3794 | 3884 | sampler_dndi[index].dw6.dndi_stream_id = 1; |
3795 | - sampler_dndi[index].dw6.dndi_first_frame = is_first_frame; | |
3885 | + sampler_dndi[index].dw6.dndi_first_frame = dndi_ctx->is_first_frame; | |
3796 | 3886 | sampler_dndi[index].dw6.progressive_dn = 0; |
3797 | 3887 | sampler_dndi[index].dw6.mcdi_enable = 0; |
3798 | 3888 | sampler_dndi[index].dw6.fmd_tear_threshold = 2; |
@@ -3814,7 +3904,7 @@ gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_c | ||
3814 | 3904 | /* private function & data */ |
3815 | 3905 | pp_context->pp_x_steps = gen7_pp_dndi_x_steps; |
3816 | 3906 | pp_context->pp_y_steps = gen7_pp_dndi_y_steps; |
3817 | - pp_context->private_context = &pp_context->pp_dndi_context; | |
3907 | + pp_context->private_context = dndi_ctx; | |
3818 | 3908 | pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter; |
3819 | 3909 | |
3820 | 3910 | pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2; |
@@ -3829,13 +3919,10 @@ gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_c | ||
3829 | 3919 | pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0; |
3830 | 3920 | pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0; |
3831 | 3921 | |
3832 | - pp_dndi_context->dest_w = w; | |
3833 | - pp_dndi_context->dest_h = h; | |
3922 | + dndi_ctx->dest_w = w; | |
3923 | + dndi_ctx->dest_h = h; | |
3834 | 3924 | |
3835 | 3925 | dst_surface->flags = I965_SURFACE_FLAG_FRAME; |
3836 | - | |
3837 | - pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2; | |
3838 | - | |
3839 | 3926 | return VA_STATUS_SUCCESS; |
3840 | 3927 | } |
3841 | 3928 |
@@ -5299,15 +5386,9 @@ i965_post_processing_context_finalize(VADriverContextP ctx, | ||
5299 | 5386 | dri_bo_unreference(pp_context->vfe_state.bo); |
5300 | 5387 | pp_context->vfe_state.bo = NULL; |
5301 | 5388 | |
5302 | - dri_bo_unreference(pp_context->pp_dndi_context.stmm_bo); | |
5303 | - pp_context->pp_dndi_context.stmm_bo = NULL; | |
5304 | - | |
5305 | - if (pp_context->pp_dndi_context.current_out_surface != VA_INVALID_ID) { | |
5306 | - i965_DestroySurfaces(ctx, | |
5307 | - &pp_context->pp_dndi_context.current_out_surface, 1); | |
5308 | - pp_context->pp_dndi_context.current_out_surface = VA_INVALID_ID; | |
5309 | - pp_context->pp_dndi_context.current_out_obj_surface = NULL; | |
5310 | - } | |
5389 | + for (i = 0; i < ARRAY_ELEMS(pp_context->pp_dndi_context.frame_store); i++) | |
5390 | + pp_dndi_frame_store_clear(&pp_context->pp_dndi_context.frame_store[i], | |
5391 | + ctx); | |
5311 | 5392 | |
5312 | 5393 | dri_bo_unreference(pp_context->pp_dn_context.stmm_bo); |
5313 | 5394 | pp_context->pp_dn_context.stmm_bo = NULL; |
@@ -5412,10 +5493,8 @@ i965_post_processing_context_init(VADriverContextP ctx, | ||
5412 | 5493 | pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1); |
5413 | 5494 | } |
5414 | 5495 | |
5415 | - pp_context->pp_dndi_context.current_out_surface = VA_INVALID_SURFACE; | |
5416 | - pp_context->pp_dndi_context.current_out_obj_surface = NULL; | |
5417 | - pp_context->pp_dndi_context.frame_order = -1; | |
5418 | 5496 | pp_context->batch = batch; |
5497 | + pp_dndi_context_init(&pp_context->pp_dndi_context); | |
5419 | 5498 | |
5420 | 5499 | avs_config = IS_IRONLAKE(i965->intel.device_info) ? &gen5_avs_config : |
5421 | 5500 | &gen6_avs_config; |
@@ -88,14 +88,33 @@ struct pp_avs_context | ||
88 | 88 | float horiz_range; |
89 | 89 | }; |
90 | 90 | |
91 | +enum { | |
92 | + DNDI_FRAME_IN_CURRENT = 0, | |
93 | + DNDI_FRAME_IN_PREVIOUS, | |
94 | + DNDI_FRAME_IN_STMM, | |
95 | + DNDI_FRAME_OUT_STMM, | |
96 | + DNDI_FRAME_OUT_CURRENT, | |
97 | + DNDI_FRAME_OUT_PREVIOUS, | |
98 | + DNDI_FRAME_STORE_COUNT | |
99 | +}; | |
100 | + | |
101 | +typedef struct dndi_frame_store { | |
102 | + struct object_surface *obj_surface; | |
103 | + VASurfaceID surface_id; /* always relative to the input surface */ | |
104 | + unsigned int is_scratch_surface : 1; | |
105 | +} DNDIFrameStore; | |
106 | + | |
91 | 107 | struct pp_dndi_context |
92 | 108 | { |
93 | 109 | int dest_w; |
94 | 110 | int dest_h; |
95 | - dri_bo *stmm_bo; | |
96 | - int frame_order; /* -1 for the first frame */ | |
97 | - VASurfaceID current_out_surface; | |
98 | - struct object_surface *current_out_obj_surface; | |
111 | + DNDIFrameStore frame_store[DNDI_FRAME_STORE_COUNT]; | |
112 | + | |
113 | + /* Temporary flags live until the current picture is processed */ | |
114 | + unsigned int is_di_enabled : 1; | |
115 | + unsigned int is_di_adv_enabled : 1; | |
116 | + unsigned int is_first_frame : 1; | |
117 | + unsigned int is_second_field : 1; | |
99 | 118 | }; |
100 | 119 | |
101 | 120 | struct pp_dn_context |