• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

hardware/intel/intel-driver


Commit MetaInfo

Revisión1cd9cf544d64e09ef3503374782cf5d682b4aa27 (tree)
Tiempo2015-05-25 09:25:42
AutorGwenole Beauchesne <gb.devel@gmai...>
CommiterXiang, Haihao

Log Message

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>

Cambiar Resumen

Diferencia incremental

--- a/src/gen8_post_processing.c
+++ b/src/gen8_post_processing.c
@@ -1392,9 +1392,6 @@ gen8_post_processing_context_finalize(VADriverContextP ctx,
13921392 dri_bo_unreference(pp_context->surface_state_binding_table.bo);
13931393 pp_context->surface_state_binding_table.bo = NULL;
13941394
1395- dri_bo_unreference(pp_context->pp_dndi_context.stmm_bo);
1396- pp_context->pp_dndi_context.stmm_bo = NULL;
1397-
13981395 dri_bo_unreference(pp_context->pp_dn_context.stmm_bo);
13991396 pp_context->pp_dn_context.stmm_bo = NULL;
14001397
@@ -1498,9 +1495,6 @@ gen8_post_processing_context_common_init(VADriverContextP ctx,
14981495 pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1);
14991496 pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1);
15001497
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;
15041498 pp_context->batch = batch;
15051499
15061500 pp_context->idrt_size = 5 * sizeof(struct gen8_interface_descriptor_data);
--- a/src/i965_post_processing.c
+++ b/src/i965_post_processing.c
@@ -1137,6 +1137,271 @@ static struct pp_module pp_modules_gen75[] = {
11371137
11381138 };
11391139
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+
11401405 static int
11411406 pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface)
11421407 {
@@ -3071,177 +3336,91 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex
30713336 const VARectangle *dst_rect,
30723337 void *filter_param)
30733338 {
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;
30763340 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
30773341 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;
30793351 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;
31743355
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;
31813360
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;
32063365
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;
32093370
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;
32153395
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);
32213400
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;
32273407
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);
32333412
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);
32393418
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));
32453424
32463425 /* sampler dndi */
32473426 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
32903469 sampler_dndi[index].dw6.di_partial = 0;
32913470 sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
32923471 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;
32943473 sampler_dndi[index].dw6.progressive_dn = 0;
32953474 sampler_dndi[index].dw6.fmd_tear_threshold = 2;
32963475 sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 100;
@@ -3306,7 +3485,7 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex
33063485 /* private function & data */
33073486 pp_context->pp_x_steps = pp_dndi_x_steps;
33083487 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;
33103489 pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
33113490
33123491 pp_static_parameter->grf1.statistics_surface_picth = w / 2;
@@ -3319,13 +3498,10 @@ pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_contex
33193498 pp_inline_parameter->grf5.block_vertical_mask = 0xff;
33203499 pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
33213500
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;
33243503
33253504 dst_surface->flags = I965_SURFACE_FLAG_FRAME;
3326-
3327- pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2;
3328-
33293505 return VA_STATUS_SUCCESS;
33303506 }
33313507
@@ -3571,176 +3747,90 @@ gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_c
35713747 const VARectangle *dst_rect,
35723748 void *filter_param)
35733749 {
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;
35763751 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;
35783761 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;
36733765
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;
37053770
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;
37083775
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;
37143780
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;
37203805
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);
37263810
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;
37323817
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);
37373822
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);
37433828
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));
37443834
37453835 /* sampler dndi */
37463836 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
37923882 sampler_dndi[index].dw6.di_partial = 0;
37933883 sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
37943884 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;
37963886 sampler_dndi[index].dw6.progressive_dn = 0;
37973887 sampler_dndi[index].dw6.mcdi_enable = 0;
37983888 sampler_dndi[index].dw6.fmd_tear_threshold = 2;
@@ -3814,7 +3904,7 @@ gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_c
38143904 /* private function & data */
38153905 pp_context->pp_x_steps = gen7_pp_dndi_x_steps;
38163906 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;
38183908 pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter;
38193909
38203910 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
38293919 pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
38303920 pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
38313921
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;
38343924
38353925 dst_surface->flags = I965_SURFACE_FLAG_FRAME;
3836-
3837- pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2;
3838-
38393926 return VA_STATUS_SUCCESS;
38403927 }
38413928
@@ -5299,15 +5386,9 @@ i965_post_processing_context_finalize(VADriverContextP ctx,
52995386 dri_bo_unreference(pp_context->vfe_state.bo);
53005387 pp_context->vfe_state.bo = NULL;
53015388
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);
53115392
53125393 dri_bo_unreference(pp_context->pp_dn_context.stmm_bo);
53135394 pp_context->pp_dn_context.stmm_bo = NULL;
@@ -5412,10 +5493,8 @@ i965_post_processing_context_init(VADriverContextP ctx,
54125493 pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1);
54135494 }
54145495
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;
54185496 pp_context->batch = batch;
5497+ pp_dndi_context_init(&pp_context->pp_dndi_context);
54195498
54205499 avs_config = IS_IRONLAKE(i965->intel.device_info) ? &gen5_avs_config :
54215500 &gen6_avs_config;
--- a/src/i965_post_processing.h
+++ b/src/i965_post_processing.h
@@ -88,14 +88,33 @@ struct pp_avs_context
8888 float horiz_range;
8989 };
9090
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+
91107 struct pp_dndi_context
92108 {
93109 int dest_w;
94110 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;
99118 };
100119
101120 struct pp_dn_context