[VP] Add DI support in APO path

[VP] Add DI support in APO path
1 Add DI related code in SwFilter/Policy/HwFilter/Packet.
2 By default disabled.

Change-Id: I9a8f07cdb7a8538b4a9d7f2ffde460caf5aa97c3
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.cpp
index 6173373..f87773b 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2018, Intel Corporation
+* Copyright (c) 2018-2020, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -35,6 +35,13 @@
 
 #define VP_SAME_SAMPLE_THRESHOLD 0
 
+inline bool IsInterleaveFirstField(VPHAL_SAMPLE_TYPE sampleType)
+{
+    return ((sampleType == SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD)   ||
+            (sampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD)     ||
+            (sampleType == SAMPLE_SINGLE_TOP_FIELD));
+}
+
 extern const VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION g_cInit_VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATIONS =
 {
     // DWORD 0
@@ -141,6 +148,7 @@
 VpResourceManager::VpResourceManager(MOS_INTERFACE &osInterface, VpAllocator &allocator, VphalFeatureReport &reporting)
     : m_osInterface(osInterface), m_allocator(allocator), m_reporting(reporting)
 {
+    InitSurfaceConfigMap();
 }
 
 VpResourceManager::~VpResourceManager()
@@ -201,8 +209,6 @@
     int32_t pastFrameId = pastSurface ? pastSurface->FrameID : 0;
     int32_t futureFrameId = futureSurface ? futureSurface->FrameID : 0;
 
-    m_pastFrameIds = m_currentFrameIds;
-
     m_currentFrameIds.valid                     = true;
     m_currentFrameIds.diEnabled                 = nullptr != diFilter;
     m_currentFrameIds.currentFrameId            = currentFrameId;
@@ -211,7 +217,6 @@
     m_currentFrameIds.pastFrameAvailable        = pastSurface ? true : false;
     m_currentFrameIds.futureFrameAvailable      = futureSurface ? true : false;
 
-
     // Only set sameSamples flag DI enabled frames.
     if (m_pastFrameIds.valid && m_currentFrameIds.pastFrameAvailable &&
         m_pastFrameIds.diEnabled && m_currentFrameIds.diEnabled)
@@ -226,11 +231,18 @@
                       -VP_SAME_SAMPLE_THRESHOLD,
                       VP_SAME_SAMPLE_THRESHOLD);
 
-        m_outOfBound    =
-               OUT_OF_BOUNDS(
-                      m_currentFrameIds.pastFrameId - m_pastFrameIds.currentFrameId,
-                      -VP_SAME_SAMPLE_THRESHOLD,
-                      VP_SAME_SAMPLE_THRESHOLD);
+        if (m_sameSamples)
+        {
+            m_outOfBound = false;
+        }
+        else
+        {
+            m_outOfBound =
+                OUT_OF_BOUNDS(
+                        m_currentFrameIds.pastFrameId - m_pastFrameIds.currentFrameId,
+                        -VP_SAME_SAMPLE_THRESHOLD,
+                        VP_SAME_SAMPLE_THRESHOLD);
+        }
     }
     // bSameSamples flag also needs to be set for no reference case
     else if (m_pastFrameIds.valid && !m_currentFrameIds.pastFrameAvailable &&
@@ -256,12 +268,39 @@
     }
 
     // Swap buffers for next iteration
-    m_currentDnOutput   = (m_currentDnOutput + 1) & 1;
-    m_currentStmmIndex  = (m_currentStmmIndex + 1) & 1;
+    if (!m_sameSamples)
+    {
+        m_currentDnOutput   = (m_currentDnOutput + 1) & 1;
+        m_currentStmmIndex  = (m_currentStmmIndex + 1) & 1;
+    }
+
+    m_pastFrameIds = m_currentFrameIds;
 
     return MOS_STATUS_SUCCESS;
 }
 
+void VpResourceManager::InitSurfaceConfigMap()
+{
+    ///*             _b64DI
+    //               |      _sfcEnable
+    //               |      |      _sameSample
+    //               |      |      |      _outOfBound
+    //               |      |      |      |      _pastRefAvailable
+    //               |      |      |      |      |      _futureRefAvailable
+    //               |      |      |      |      |      |      _firstDiField
+    //               |      |      |      |      |      |      |      _currentInputSurface
+    //               |      |      |      |      |      |      |      |                     _pastInputSurface
+    //               |      |      |      |      |      |      |      |                     |                      _currentOutputSurface
+    //               |      |      |      |      |      |      |      |                     |                      |                     _pastOutputSurface*/
+    //               |      |      |      |      |      |      |      |                     |                      |                     |                     */
+    AddSurfaceConfig(true,  true,  false, false, true,  false, true,  VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_PAST_REF, VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_FRAME0);
+    AddSurfaceConfig(true,  true,  true,  false, true,  false, false, VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL,    VEBOX_SURFACE_NULL,   VEBOX_SURFACE_NULL);
+    AddSurfaceConfig(true,  true,  false, false, false, false, true,  VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,    VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
+    AddSurfaceConfig(true,  true,  false, false, false, false, false, VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,    VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
+    AddSurfaceConfig(true,  true,  true,  false, false, false, true,  VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,    VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
+    AddSurfaceConfig(true,  true,  true,  false, false, false, false, VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,    VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
+}
+
 uint32_t VpResourceManager::GetHistogramSurfaceSize(VP_EXECUTE_CAPS& caps, uint32_t inputWidth, uint32_t inputHeight)
 {
     // Allocate Rgb Histogram surface----------------------------------------------
@@ -275,32 +314,76 @@
     return dwSize;
 }
 
-MOS_STATUS VpResourceManager::AssignExecuteResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE_GROUP &surfGroup)
+MOS_STATUS VpResourceManager::AssignExecuteResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface,
+    VP_SURFACE *pastSurface, VP_SURFACE *futureSurface, RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_GROUP &surfGroup)
 {
     surfGroup.clear();
 
     if (caps.bVebox)
     {
         // Create Vebox Resources
-        VP_PUBLIC_CHK_STATUS_RETURN(AssignVeboxResource(caps, inputSurface, outputSurface, surfGroup));
+        VP_PUBLIC_CHK_STATUS_RETURN(AssignVeboxResource(caps, inputSurface, outputSurface, pastSurface, futureSurface, resHint, surfGroup));
     }
     return MOS_STATUS_SUCCESS;
 }
 
-MOS_FORMAT GetVeboxOutputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, MOS_FORMAT outputFormat)
+MOS_STATUS GetVeboxOutputParams(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, MOS_TILE_TYPE inputTileType, MOS_FORMAT outputFormat,
+                                MOS_FORMAT &veboxOutputFormat, MOS_TILE_TYPE &veboxOutputTileType)
 {
+    // Vebox Chroma Co-Sited downsampleing is part of VEO. It only affects format of vebox output surface, but not
+    // affect sfc input format, that's why different logic between GetSfcInputFormat and GetVeboxOutputParams.
+    // Check DI first and downsampling to NV12 if possible to save bandwidth no matter IECP enabled or not.
+    if (executeCaps.bDI || executeCaps.bDiProcess2ndField)
+    {
+        // NV12 will be used if target output is not YUV2 to save bandwidth.
+        if (outputFormat == Format_YUY2)
+        {
+            veboxOutputFormat = Format_YUY2;
+        }
+        else
+        {
+            veboxOutputFormat = Format_NV12;
+        }
+        veboxOutputTileType = MOS_TILE_Y;
+    }
+    else if (executeCaps.bIECP)
+    {
+        // Upsampling to yuv444 for IECP input/output.
+        // To align with legacy path, need to check whether inputFormat can also be used for IECP case,
+        // in which case IECP down sampling will be applied.
+        veboxOutputFormat = Format_AYUV;
+        veboxOutputTileType = inputTileType;
+    }
+    else
+    {
+        veboxOutputFormat = inputFormat;
+        veboxOutputTileType = inputTileType;
+    }
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput)
+{
+    // Vebox Chroma Co-Sited downsampling is part of VEO. It only affects format of vebox output surface, but not
+    // affect sfc input format, that's why different logic between GetSfcInputFormat and GetVeboxOutputParams.
+    // Check IECP first here, since IECP is done after DI, and the vebox downsampling not affect the vebox input.
     if (executeCaps.bIECP)
     {
+        if (executeCaps.bHDR3DLUT)
+        {
+            return IS_COLOR_SPACE_BT2020(colorSpaceOutput) ? Format_R10G10B10A2 : Format_A8B8G8R8;
+        }
         // Upsampling to yuv444 for IECP input/output.
         // To align with legacy path, need to check whether inputFormat can also be used for IECP case,
         // in which case IECP down sampling will be applied.
         return Format_AYUV;
     }
-    else if (executeCaps.bDI && VpHal_GetSurfaceColorPack(inputFormat) == VPHAL_COLORPACK_420)
+    else if (executeCaps.bDI)
     {
         // If the input is 4:2:0, then chroma data is doubled vertically to 4:2:2
-        // In legacy path, NV12 will be used if target output is not YUV2 to save bandwidth.
-        // Need to check whether it can applied here.
+        // For executeCaps.bDiProcess2ndField, no DI enabled in vebox, so no need
+        // set to YUY2 here.
         return Format_YUY2;
     }
 
@@ -318,7 +401,11 @@
     VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
     VP_PUBLIC_CHK_NULL_RETURN(outputSurface->osSurface);
 
-    MOS_FORMAT format = GetVeboxOutputFormat(caps, inputSurface->osSurface->Format, outputSurface->osSurface->Format);
+    MOS_FORMAT      veboxOutputFormat                   = inputSurface->osSurface->Format;
+    MOS_TILE_TYPE   veboxOutputTileType                 = inputSurface->osSurface->TileType;
+
+    VP_PUBLIC_CHK_STATUS_RETURN(GetVeboxOutputParams(caps, inputSurface->osSurface->Format, inputSurface->osSurface->TileType,
+                                            outputSurface->osSurface->Format, veboxOutputFormat, veboxOutputTileType));
 
     allocated = false;
     if (IS_VP_VEBOX_DN_ONLY(caps))
@@ -343,9 +430,9 @@
         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
             m_veboxOutput[i],
             "VeboxSurfaceOutput",
-            format,
+            veboxOutputFormat,
             MOS_GFXRES_2D,
-            inputSurface->osSurface->TileType,
+            veboxOutputTileType,
             inputSurface->osSurface->dwWidth,
             inputSurface->osSurface->dwHeight,
             bSurfCompressible,
@@ -359,19 +446,14 @@
         m_veboxOutput[i]->rcSrc      = inputSurface->rcSrc;
         m_veboxOutput[i]->rcMaxSrc   = inputSurface->rcMaxSrc;
 
-        // When IECP is enabled and Bob or interlaced scaling is selected for interlaced input,
-        // output surface's SampleType should be same to input's. Bob is being
-        // done in Composition part
-        if ((caps.bIECP &&
-            (caps.bDI && caps.bBobDI)) ||
-            (caps.bIScaling))
-        {
-            m_veboxOutput[i]->SampleType = inputSurface->SampleType;
-        }
-        else
-        {
-            m_veboxOutput[i]->SampleType = SAMPLE_PROGRESSIVE;
-        }
+        m_veboxOutput[i]->SampleType = SAMPLE_PROGRESSIVE;
+    }
+
+    if (allocated)
+    {
+        // Report Compress Status
+        m_reporting.FFDICompressible = bSurfCompressible;
+        m_reporting.FFDICompressMode = (uint8_t)(surfCompressionMode);
     }
 
     return MOS_STATUS_SUCCESS;
@@ -449,6 +531,75 @@
     return MOS_STATUS_SUCCESS;
 }
 
+//!
+//! \brief    Vebox initialize STMM History
+//! \details  Initialize STMM History surface
+//! Description:
+//!   This function is used by VEBox for initializing
+//!   the STMM surface.  The STMM / Denoise history is a custom surface used 
+//!   for both input and output. Each cache line contains data for 4 4x4s. 
+//!   The STMM for each 4x4 is 8 bytes, while the denoise history is 1 byte 
+//!   and the chroma denoise history is 1 byte for each U and V.
+//!   Byte    Data\n
+//!   0       STMM for 2 luma values at luma Y=0, X=0 to 1\n
+//!   1       STMM for 2 luma values at luma Y=0, X=2 to 3\n
+//!   2       Luma Denoise History for 4x4 at 0,0\n
+//!   3       Not Used\n
+//!   4-5     STMM for luma from X=4 to 7\n
+//!   6       Luma Denoise History for 4x4 at 0,4\n
+//!   7       Not Used\n
+//!   8-15    Repeat for 4x4s at 0,8 and 0,12\n
+//!   16      STMM for 2 luma values at luma Y=1,X=0 to 1\n
+//!   17      STMM for 2 luma values at luma Y=1, X=2 to 3\n
+//!   18      U Chroma Denoise History\n
+//!   19      Not Used\n
+//!   20-31   Repeat for 3 4x4s at 1,4, 1,8 and 1,12\n
+//!   32      STMM for 2 luma values at luma Y=2,X=0 to 1\n
+//!   33      STMM for 2 luma values at luma Y=2, X=2 to 3\n
+//!   34      V Chroma Denoise History\n
+//!   35      Not Used\n
+//!   36-47   Repeat for 3 4x4s at 2,4, 2,8 and 2,12\n
+//!   48      STMM for 2 luma values at luma Y=3,X=0 to 1\n
+//!   49      STMM for 2 luma values at luma Y=3, X=2 to 3\n
+//!   50-51   Not Used\n
+//!   36-47   Repeat for 3 4x4s at 3,4, 3,8 and 3,12\n
+//! \param    [in] iSurfaceIndex
+//!           Index of STMM surface array
+//! \return   MOS_STATUS
+//!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
+//!
+MOS_STATUS VpResourceManager::VeboxInitSTMMHistory(MOS_SURFACE *stmmSurface)
+{
+    uint32_t            dwSize = 0;
+    int32_t             x = 0, y = 0;
+    uint8_t*            pByte = nullptr;
+
+    VP_PUBLIC_CHK_NULL_RETURN(stmmSurface);
+
+    // Lock the surface for writing
+    pByte = (uint8_t*)m_allocator.LockResouceForWrite(&stmmSurface->OsResource);
+    VP_PUBLIC_CHK_NULL_RETURN(pByte);
+
+    dwSize = stmmSurface->dwWidth >> 2;
+
+    // Fill STMM surface with DN history init values.
+    for (y = 0; y < (int32_t)stmmSurface->dwHeight; y++)
+    {
+        for (x = 0; x < (int32_t)dwSize; x++)
+        {
+            MOS_FillMemory(pByte, 2, DNDI_HISTORY_INITVALUE);
+            // skip denosie history init.
+            pByte += 4;
+        }
+
+        pByte += stmmSurface->dwPitch - stmmSurface->dwWidth;
+    }
+
+    // Unlock the surface
+    VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.UnLock(&stmmSurface->OsResource));
+    return MOS_STATUS_SUCCESS;
+}
+
 // Allocate STMM (Spatial-Temporal Motion Measure) Surfaces
 MOS_STATUS VpResourceManager::ReAllocateVeboxSTMMSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, bool &allocated)
 {
@@ -478,6 +629,8 @@
 
         if (allocated)
         {
+            VP_PUBLIC_CHK_NULL_RETURN(m_veboxSTMMSurface[i]);
+            VP_PUBLIC_CHK_STATUS_RETURN(VeboxInitSTMMHistory(m_veboxSTMMSurface[i]->osSurface));
             // Report Compress Status
             m_reporting.STMMCompressible = bSurfCompressible;
             m_reporting.STMMCompressMode = (uint8_t)surfCompressionMode;
@@ -568,7 +721,7 @@
         DestoryVeboxDenoiseOutputSurface();
     }
 
-    if (VeboxSTMMNeeded(caps))
+    if (VeboxSTMMNeeded(caps, false))
     {
         VP_PUBLIC_CHK_STATUS_RETURN(ReAllocateVeboxSTMMSurface(caps, inputSurface, bAllocated));
         if (bAllocated)
@@ -683,7 +836,42 @@
     return MOS_STATUS_SUCCESS;
 }
 
-MOS_STATUS VpResourceManager::AssignVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE_GROUP &surfGroup)
+MOS_STATUS VpResourceManager::AssignSurface(VEBOX_SURFACE_ID &surfaceId, SurfaceType surfaceType, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE *pastSurface, VP_SURFACE *futureSurface, VP_SURFACE_GROUP &surfGroup)
+{
+    switch (surfaceId)
+    {
+    case VEBOX_SURFACE_INPUT:
+        surfGroup.insert(std::make_pair(surfaceType, inputSurface));
+        break;
+    case VEBOX_SURFACE_OUTPUT:
+        surfGroup.insert(std::make_pair(surfaceType, outputSurface));
+        break;
+    case VEBOX_SURFACE_PAST_REF:
+        surfGroup.insert(std::make_pair(surfaceType, pastSurface));
+        break;
+    case VEBOX_SURFACE_FUTURE_REF:
+        surfGroup.insert(std::make_pair(surfaceType, futureSurface));
+        break;
+    case VEBOX_SURFACE_FRAME0:
+        surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 0) % m_veboxOutputCount]));
+        break;
+    case VEBOX_SURFACE_FRAME1:
+        surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 1) % m_veboxOutputCount]));
+        break;
+    case VEBOX_SURFACE_FRAME2:
+        surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 2) % m_veboxOutputCount]));
+        break;
+    case VEBOX_SURFACE_FRAME3:
+        surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 3) % m_veboxOutputCount]));
+        break;
+    default:
+        break;
+    }
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS VpResourceManager::AssignVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface,
+    VP_SURFACE *pastSurface, VP_SURFACE *futureSurface, RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_GROUP &surfGroup)
 {
     VP_FUNC_CALL();
     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
@@ -700,24 +888,54 @@
 
     VP_PUBLIC_CHK_STATUS_RETURN(AllocateVeboxResource(caps, inputSurface, outputSurface));
 
-    surfGroup.insert(std::make_pair(SurfaceTypeVeboxInput, inputSurface));
-    surfGroup.insert(std::make_pair(SurfaceTypeVeboxCurrentOutput, GetVeboxOutputSurface(caps, outputSurface)));
-
-    if (caps.bDN)
+    if (caps.bDI || caps.bDiProcess2ndField)
     {
-        // Insert DN output surface
-        surfGroup.insert(std::make_pair(SurfaceTypeDNOutput, m_veboxDenoiseOutput[m_currentDnOutput]));
-        // Insert DN Reference surface
-        if (caps.bRefValid)
+        bool b60fpsDi = resHint.b60fpsDi || caps.bDiProcess2ndField;
+        VEBOX_SURFACES_CONFIG cfg(b60fpsDi, caps.bSFC, m_sameSamples, m_outOfBound, m_currentFrameIds.pastFrameAvailable,
+            m_currentFrameIds.futureFrameAvailable, IsInterleaveFirstField(inputSurface->SampleType));
+        auto it = m_veboxSurfaceConfigMap.find(cfg.value);
+        if (m_veboxSurfaceConfigMap.end() == it)
         {
-            surfGroup.insert(std::make_pair(SurfaceTypeVeboxPreviousInput, m_veboxDenoiseOutput[(m_currentDnOutput + 1) & 1]));
+            VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
+        }
+        auto surfaces = it->second;
+        VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(surfaces.currentInputSurface, SurfaceTypeVeboxInput, inputSurface, outputSurface, pastSurface, futureSurface, surfGroup));
+        VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(surfaces.pastInputSurface, SurfaceTypeVeboxPreviousInput, inputSurface, outputSurface, pastSurface, futureSurface, surfGroup));
+        VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(surfaces.currentOutputSurface, SurfaceTypeVeboxCurrentOutput, inputSurface, outputSurface, pastSurface, futureSurface, surfGroup));
+        VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(surfaces.pastOutputSurface, SurfaceTypeVeboxPreviousOutput, inputSurface, outputSurface, pastSurface, futureSurface, surfGroup));
+
+        if (caps.bDN)
+        {
+            // Insert DN output surface
+            surfGroup.insert(std::make_pair(SurfaceTypeDNOutput, m_veboxDenoiseOutput[m_currentDnOutput]));
+        }
+
+        caps.bRefValid = surfGroup.find(SurfaceTypeVeboxPreviousInput) != surfGroup.end();
+    }
+    else
+    {
+        surfGroup.insert(std::make_pair(SurfaceTypeVeboxInput, inputSurface));
+        surfGroup.insert(std::make_pair(SurfaceTypeVeboxCurrentOutput, GetVeboxOutputSurface(caps, outputSurface)));
+
+        if (caps.bDN)
+        {
+            // Insert DN output surface
+            surfGroup.insert(std::make_pair(SurfaceTypeDNOutput, m_veboxDenoiseOutput[m_currentDnOutput]));
+            // Insert DN Reference surface
+            if (caps.bRefValid)
+            {
+                surfGroup.insert(std::make_pair(SurfaceTypeVeboxPreviousInput, m_veboxDenoiseOutput[(m_currentDnOutput + 1) & 1]));
+            }
         }
     }
 
-    // Insert STMM input surface
-    surfGroup.insert(std::make_pair(SurfaceTypeSTMMIn, m_veboxSTMMSurface[m_currentStmmIndex]));
-    // Insert STMM output surface
-    surfGroup.insert(std::make_pair(SurfaceTypeSTMMOut, m_veboxSTMMSurface[(m_currentStmmIndex + 1) & 1]));
+    if (VeboxSTMMNeeded(caps, true))
+    {
+        // Insert STMM input surface
+        surfGroup.insert(std::make_pair(SurfaceTypeSTMMIn, m_veboxSTMMSurface[m_currentStmmIndex]));
+        // Insert STMM output surface
+        surfGroup.insert(std::make_pair(SurfaceTypeSTMMOut, m_veboxSTMMSurface[(m_currentStmmIndex + 1) & 1]));
+    }
 
 #if VEBOX_AUTO_DENOISE_SUPPORTED
     // Insert Vebox auto DN noise level surface
@@ -788,9 +1006,10 @@
     // If DN and/or Hotpixel are the only functions enabled then the only output is the Denoised Output
     // and no need vebox output.
     // For any other vebox features being enabled, vebox output surface is needed.
-    if (caps.bDI            ||
-        caps.bQueryVariance ||
-        caps.bIECP          ||
+    if (caps.bDI                ||
+        caps.bQueryVariance     ||
+        caps.bDiProcess2ndField ||
+        caps.bIECP              ||
         (caps.bDN && caps.bSFC))  // DN + SFC needs IECP implicitly and outputs to DI surface
     {
         return true;
@@ -806,9 +1025,20 @@
     return caps.bDN;
 }
 
-bool VpResourceManager::VeboxSTMMNeeded(VP_EXECUTE_CAPS& caps)
+// In some case, STMM should not be destroyed even when not being used by current workload to maintain data,
+// e.g. DI second field case.
+// If queryAssignment == true, query whether STMM needed by current workload.
+// If queryAssignment == false, query whether STMM needed to be allocated.
+bool VpResourceManager::VeboxSTMMNeeded(VP_EXECUTE_CAPS& caps, bool queryAssignment)
 {
-    return caps.bDI || caps.bDN;
+    if (queryAssignment)
+    {
+        return caps.bDI || caps.bDN;
+    }
+    else
+    {
+        return caps.bDI || caps.bDiProcess2ndField || caps.bDN;
+    }
 }
 
 };
\ No newline at end of file
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.h b/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.h
index 21d05b3..6608392 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/bufferMgr/vp_resource_manager.h
@@ -259,6 +259,60 @@
         uint32_t dwPad[7];
     };
 
+enum VEBOX_SURFACE_ID
+{
+    VEBOX_SURFACE_NULL = 0,
+    VEBOX_SURFACE_INPUT,
+    VEBOX_SURFACE_OUTPUT,
+    VEBOX_SURFACE_PAST_REF,
+    VEBOX_SURFACE_FUTURE_REF,
+    VEBOX_SURFACE_FRAME0,
+    VEBOX_SURFACE_FRAME1,
+    VEBOX_SURFACE_FRAME2,
+    VEBOX_SURFACE_FRAME3,
+};
+
+struct VEBOX_SURFACES
+{
+    VEBOX_SURFACE_ID currentInputSurface;
+    VEBOX_SURFACE_ID pastInputSurface;
+    VEBOX_SURFACE_ID currentOutputSurface;
+    VEBOX_SURFACE_ID pastOutputSurface;
+
+    VEBOX_SURFACES(VEBOX_SURFACE_ID _currentInputSurface, VEBOX_SURFACE_ID _pastInputSurface, VEBOX_SURFACE_ID _currentOutputSurface, VEBOX_SURFACE_ID _pastOutputSurface)
+        : currentInputSurface(_currentInputSurface), pastInputSurface(_pastInputSurface), currentOutputSurface(_currentOutputSurface), pastOutputSurface(_pastOutputSurface)
+    {}
+};
+
+inline uint32_t BoolToInt(bool b)
+{
+    return ((b) ? 1 : 0);
+}
+
+union VEBOX_SURFACES_CONFIG
+{
+    struct
+    {
+        uint32_t b64DI              : 1;
+        uint32_t sfcEnable          : 1;
+        uint32_t sameSample         : 1;
+        uint32_t outOfBound         : 1;
+        uint32_t pastFrameAvailable    : 1;
+        uint32_t futureFrameAvailable    : 1;
+        uint32_t firstDiField       : 1;
+        uint32_t reserved           : 25;
+    };
+    uint32_t value;
+    VEBOX_SURFACES_CONFIG() : value(0)
+    {}
+    VEBOX_SURFACES_CONFIG(bool _b64DI, bool _sfcEnable, bool _sameSample, bool _outOfBound, bool _pastFrameAvailable, bool _futureFrameAvailable, bool _firstDiField) :
+        b64DI(BoolToInt(_b64DI)), sfcEnable(BoolToInt(_sfcEnable)), sameSample(BoolToInt(_sameSample)), outOfBound(BoolToInt(_outOfBound)),
+        pastFrameAvailable(BoolToInt(_pastFrameAvailable)), futureFrameAvailable(BoolToInt(_futureFrameAvailable)), firstDiField(BoolToInt(_firstDiField)), reserved(0)
+    {}
+};
+
+typedef std::map<uint32_t, VEBOX_SURFACES> VEBOX_SURFACE_CONFIG_MAP;
+
 struct VP_FRAME_IDS
 {
     bool        valid;
@@ -276,8 +330,10 @@
     VpResourceManager(MOS_INTERFACE &osInterface, VpAllocator &allocator, VphalFeatureReport &reporting);
     virtual ~VpResourceManager();
     MOS_STATUS StartProcessNewFrame(SwFilterPipe &pipe);
-    MOS_STATUS AssignExecuteResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE_GROUP &surfGroup);
-    virtual MOS_STATUS AssignVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE_GROUP &surfGroup);
+    MOS_STATUS AssignExecuteResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE *pastSurface, VP_SURFACE *futureSurface,
+        RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_GROUP &surfGroup);
+    virtual MOS_STATUS AssignVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE *pastSurface, VP_SURFACE *futureSurface,
+        RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_GROUP &surfGroup);
     bool IsSameSamples()
     {
         return m_sameSamples;
@@ -292,9 +348,14 @@
     VP_SURFACE* GetVeboxOutputSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *outputSurface);
     MOS_STATUS InitVeboxSpatialAttributesConfiguration();
     MOS_STATUS AllocateVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface);
+    MOS_STATUS AssignSurface(VEBOX_SURFACE_ID &surfaceId, SurfaceType surfaceType, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE *pastRefSurface, VP_SURFACE *futureRefSurface, VP_SURFACE_GROUP &surfGroup);
     bool VeboxOutputNeeded(VP_EXECUTE_CAPS& caps);
     bool VeboxDenoiseOutputNeeded(VP_EXECUTE_CAPS& caps);
-    bool VeboxSTMMNeeded(VP_EXECUTE_CAPS& caps);
+    // In some case, STMM should not be destroyed but not be used by current workload to maintain data,
+    // e.g. DI second field case.
+    // If queryAssignment == true, query whether STMM needed by current workload.
+    // If queryAssignment == false, query whether STMM needed to be allocated.
+    bool VeboxSTMMNeeded(VP_EXECUTE_CAPS& caps, bool queryAssignment);
     virtual uint32_t GetHistogramSurfaceSize(VP_EXECUTE_CAPS& caps, uint32_t inputWidth, uint32_t inputHeight);
     virtual uint32_t Get3DLutSize();
     MOS_STATUS ReAllocateVeboxOutputSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, bool &allocated);
@@ -304,6 +365,52 @@
     void DestoryVeboxDenoiseOutputSurface();
     void DestoryVeboxSTMMSurface();
 
+    //!
+    //! \brief    Vebox initialize STMM History
+    //! \details  Initialize STMM History surface
+    //! Description:
+    //!   This function is used by VEBox for initializing
+    //!   the STMM surface.  The STMM / Denoise history is a custom surface used 
+    //!   for both input and output. Each cache line contains data for 4 4x4s. 
+    //!   The STMM for each 4x4 is 8 bytes, while the denoise history is 1 byte 
+    //!   and the chroma denoise history is 1 byte for each U and V.
+    //!   Byte    Data\n
+    //!   0       STMM for 2 luma values at luma Y=0, X=0 to 1\n
+    //!   1       STMM for 2 luma values at luma Y=0, X=2 to 3\n
+    //!   2       Luma Denoise History for 4x4 at 0,0\n
+    //!   3       Not Used\n
+    //!   4-5     STMM for luma from X=4 to 7\n
+    //!   6       Luma Denoise History for 4x4 at 0,4\n
+    //!   7       Not Used\n
+    //!   8-15    Repeat for 4x4s at 0,8 and 0,12\n
+    //!   16      STMM for 2 luma values at luma Y=1,X=0 to 1\n
+    //!   17      STMM for 2 luma values at luma Y=1, X=2 to 3\n
+    //!   18      U Chroma Denoise History\n
+    //!   19      Not Used\n
+    //!   20-31   Repeat for 3 4x4s at 1,4, 1,8 and 1,12\n
+    //!   32      STMM for 2 luma values at luma Y=2,X=0 to 1\n
+    //!   33      STMM for 2 luma values at luma Y=2, X=2 to 3\n
+    //!   34      V Chroma Denoise History\n
+    //!   35      Not Used\n
+    //!   36-47   Repeat for 3 4x4s at 2,4, 2,8 and 2,12\n
+    //!   48      STMM for 2 luma values at luma Y=3,X=0 to 1\n
+    //!   49      STMM for 2 luma values at luma Y=3, X=2 to 3\n
+    //!   50-51   Not Used\n
+    //!   36-47   Repeat for 3 4x4s at 3,4, 3,8 and 3,12\n
+    //! \param    [in] stmmSurface
+    //!           STMM surface
+    //! \return   MOS_STATUS
+    //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
+    //!
+    MOS_STATUS VeboxInitSTMMHistory(MOS_SURFACE *stmmSurface);
+
+    void InitSurfaceConfigMap();
+    void AddSurfaceConfig(bool _b64DI, bool _sfcEnable, bool _sameSample, bool _outOfBound, bool _pastRefAvailable, bool _futureRefAvailable, bool _firstDiField,
+        VEBOX_SURFACE_ID _currentInputSurface, VEBOX_SURFACE_ID _pastInputSurface, VEBOX_SURFACE_ID _currentOutputSurface, VEBOX_SURFACE_ID _pastOutputSurface)
+    {
+        m_veboxSurfaceConfigMap.insert(std::make_pair(VEBOX_SURFACES_CONFIG(_b64DI, _sfcEnable, _sameSample, _outOfBound, _pastRefAvailable, _futureRefAvailable, _firstDiField).value, VEBOX_SURFACES(_currentInputSurface, _pastInputSurface, _currentOutputSurface, _pastOutputSurface)));
+    }
+
 protected:
     MOS_INTERFACE                &m_osInterface;
     VpAllocator                  &m_allocator;
@@ -321,13 +428,13 @@
     uint32_t    m_currentDnOutput                        = 0;
     uint32_t    m_currentStmmIndex                       = 0;
     uint32_t    m_veboxOutputCount                       = 2;             //!< PE on: 4 used. PE off: 2 used
-
     VP_FRAME_IDS m_currentFrameIds                       = {};
-    VP_FRAME_IDS m_pastFrameIds                      = {};
+    VP_FRAME_IDS m_pastFrameIds                          = {};
     bool         m_firstFrame                            = true;
     bool         m_sameSamples                           = false;
     bool         m_outOfBound                            = false;
     RECT         m_maxSrcRect                            = {};
+    VEBOX_SURFACE_CONFIG_MAP m_veboxSurfaceConfigMap;
 };
 }
 #endif // _VP_RESOURCE_MANAGER_H__
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/hw_filter.h b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/hw_filter.h
index ab9c3ef..1db5d96 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/hw_filter.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/hw_filter.h
@@ -46,6 +46,7 @@
 #include "vp_ste_filter.h"
 #include "vp_procamp_filter.h"
 #include "vp_hdr_filter.h"
+#include "vp_di_filter.h"
 
 namespace vp
 {
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.cpp
index c10f05f..d855d70 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.cpp
@@ -122,6 +122,10 @@
     VP_PUBLIC_CHK_NULL_RETURN(p);
     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDnOnVebox, p));
 
+    p = MOS_New(PolicyVeboxDiHandler);
+    VP_PUBLIC_CHK_NULL_RETURN(p);
+    m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeDiOnVebox, p));
+
     p = MOS_New(PolicyVeboxCscHandler);
     VP_PUBLIC_CHK_NULL_RETURN(p);
     m_VeboxSfcFeatureHandlers.insert(std::make_pair(FeatureTypeCscOnVebox, p));
@@ -152,6 +156,7 @@
     m_featurePool.push_back(FeatureTypeTcc);
     m_featurePool.push_back(FeatureTypeProcamp);
     m_featurePool.push_back(FeatureTypeHdr);
+    m_featurePool.push_back(FeatureTypeDi);
 
     return MOS_STATUS_SUCCESS;
 }
@@ -267,7 +272,15 @@
     switch (featureType)
     {
     case FeatureTypeCsc:
-        VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
+        diFilter = swFilterPipe.GetSwFilter(FeatureTypeDi);
+        if (diFilter)
+        {
+            VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCapsDi(feature));
+        }
+        else
+        {
+            VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
+        }
         break;
     case FeatureTypeScaling:
         VP_PUBLIC_CHK_STATUS_RETURN(GetScalingExecutionCaps(feature));
@@ -290,6 +303,9 @@
     case FeatureTypeHdr:
         VP_PUBLIC_CHK_STATUS_RETURN(GetHdrExecutionCaps(feature));
         break;
+    case FeatureTypeDi:
+        VP_PUBLIC_CHK_STATUS_RETURN(GetDeinterlaceExecutionCaps(feature));
+        break;
     default:
         VP_PUBLIC_CHK_STATUS_RETURN(GetExecutionCaps(feature));
         VP_PUBLIC_NORMALMESSAGE("Feature didn't have supported in driver, default to use Render");
@@ -365,6 +381,28 @@
     return MOS_STATUS_SUCCESS;
 }
 
+MOS_STATUS Policy::GetCSCExecutionCapsDi(SwFilter* feature)
+{
+    VP_PUBLIC_CHK_NULL_RETURN(feature);
+
+    SwFilterCsc* csc = dynamic_cast<SwFilterCsc*>(feature);
+    VP_PUBLIC_CHK_NULL_RETURN(csc);
+
+    VP_PUBLIC_CHK_STATUS_RETURN(GetCSCExecutionCaps(feature));
+
+    VP_EngineEntry *cscEngine = &csc->GetFilterEngineCaps();
+    VP_PUBLIC_CHK_NULL_RETURN(cscEngine);
+    if (cscEngine->bEnabled &&
+        (cscEngine->SfcNeeded && cscEngine->VeboxNeeded ||
+        0 == cscEngine->SfcNeeded && 0 == cscEngine->VeboxNeeded && 0 == cscEngine->RenderNeeded))
+    {
+        cscEngine->SfcNeeded    = 1;
+        cscEngine->VeboxNeeded  = 0;
+        cscEngine->RenderNeeded = 0;
+    }
+    return MOS_STATUS_SUCCESS;
+}
+
 MOS_STATUS Policy::GetCSCExecutionCaps(SwFilter* feature)
 {
     VP_FUNC_CALL();
@@ -690,6 +728,45 @@
     return MOS_STATUS_SUCCESS;
 }
 
+MOS_STATUS Policy::GetDeinterlaceExecutionCaps(SwFilter* feature)
+{
+    VP_FUNC_CALL();
+    VP_PUBLIC_CHK_NULL_RETURN(feature);
+
+    SwFilterDeinterlace* swFilterDi = dynamic_cast<SwFilterDeinterlace*>(feature); 
+    VP_PUBLIC_CHK_NULL_RETURN(swFilterDi);
+
+    FeatureParamDeinterlace &diParams = swFilterDi->GetSwFilterParams();
+
+    VP_EngineEntry &diEngine = swFilterDi->GetFilterEngineCaps();
+    MOS_FORMAT      inputformat = diParams.formatInput;
+
+    // MOS_FORMAT is [-14,103], cannot use -14~-1 as index for m_veboxHwEntry
+    if (inputformat < 0)
+    {
+        inputformat = Format_Any;
+    }
+
+    if (diEngine.value != 0)
+    {
+        VP_PUBLIC_NORMALMESSAGE("Scaling Feature Already been processed, Skip further process");
+        return MOS_STATUS_SUCCESS;
+    }
+
+    if (m_vpInterface.GetResourceManager()->IsRefValid()    &&
+        m_vpInterface.GetResourceManager()->IsSameSamples())
+    {
+        diEngine.bypassVeboxFeatures = 1;
+    }
+    else if (m_veboxHwEntry[inputformat].deinterlaceSupported)
+    {
+        diEngine.bEnabled    = 1;
+        diEngine.VeboxNeeded = 1;
+    }
+
+    return MOS_STATUS_SUCCESS;
+}
+
 MOS_STATUS Policy::GetSteExecutionCaps(SwFilter* feature)
 {
     VP_FUNC_CALL();
@@ -981,6 +1058,20 @@
                         feature->GetFilterEngineCaps().RenderNeeded = 0;
                     }
                 }
+
+                if (engineCaps.bypassVeboxFeatures)
+                {
+                    if (caps.bVebox && feature->GetFilterEngineCaps().VeboxNeeded)
+                    {
+                        // Disable vebox features.
+                        feature->GetFilterEngineCaps().bEnabled = false;
+                    }
+
+                    if (FeatureTypeDi == filterID)
+                    {
+                        caps.bDiProcess2ndField = 1;
+                    }
+                }
             }
         }
     }
@@ -1089,6 +1180,10 @@
         {
             // surface should be added before swFilters, since empty feature pipe will be allocated accordingly when surface being added.
             VP_PUBLIC_CHK_STATUS_RETURN(params.executedFilters->AddSurface(surfInput, true, index));
+            VP_SURFACE *pastRefSurface = featurePipe.RemovePastSurface(index);
+            VP_SURFACE *futureRefSurface = featurePipe.RemoveFutureSurface(index);
+            params.executedFilters->SetPastSurface(index, pastRefSurface);
+            params.executedFilters->SetFutureSurface(index, futureRefSurface);
         }
         else
         {
@@ -1118,12 +1213,6 @@
                     UpdateExeCaps(feature, caps, engineCaps->SfcNeeded ? EngineTypeVeboxSfc : EngineTypeVebox);
                     featurePipe.RemoveSwFilter(feature);
                     params.executedFilters->AddSwFilterUnordered(feature, true, 0);
-
-                    //Create and Add CSC filter for VEBOX IECP chromasiting config
-                    if (caps.bIECP && filterID == FeatureTypeCsc)
-                    {
-                        AddNewFilterOnVebox(featurePipe, caps, params, FeatureTypeCsc);
-                    }
                 }
                 // Vebox only cases
                 else if (caps.bVebox && engineCaps->bEnabled &&
@@ -1139,7 +1228,7 @@
                     UpdateExeCaps(feature, caps, EngineTypeRender);
                     if (caps.bIECP && filterID == FeatureTypeCsc)
                     {
-                        AddNewFilterOnVebox(featurePipe, caps, params, FeatureTypeCsc);
+                        AddNewFilterOnVebox(featurePipe, caps, *params.executedFilters, FeatureTypeCsc);
                     }
                 }
                 else
@@ -1158,6 +1247,8 @@
                 }
             }
         }
+
+        VP_PUBLIC_CHK_STATUS_RETURN(AddFiltersBasedOnCaps(featurePipe, caps, *params.executedFilters));
     }
     else
     {
@@ -1169,6 +1260,23 @@
     return MOS_STATUS_SUCCESS;
 }
 
+MOS_STATUS Policy::GetResourceHint(SwFilterPipe& featurePipe, RESOURCE_ASSIGNMENT_HINT &hint)
+{
+    uint32_t    index      = 0;
+    SwFilterSubPipe* inputPipe = featurePipe.GetSwFilterPrimaryPipe(index);
+    // only process Primary surface
+    VP_PUBLIC_CHK_NULL_RETURN(inputPipe);
+    for (auto filterID : m_featurePool)
+    {
+        SwFilter* feature = (SwFilter*)inputPipe->GetSwFilter(FeatureType(filterID));
+        if (feature)
+        {
+            VP_PUBLIC_CHK_STATUS_RETURN(feature->SetResourceAssignmentHint(hint));
+        }
+    }
+    return MOS_STATUS_SUCCESS;
+}
+
 MOS_STATUS Policy::SetupFilterResource(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params)
 {
     VP_FUNC_CALL();
@@ -1242,6 +1350,10 @@
             caps.bSTE = 1;
             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ste, Vebox)));
             break;
+        case FeatureTypeDi:
+            caps.bDI = 1;
+            feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Di, Vebox)));
+            break;
         case FeatureTypeAce:
             caps.bACE = 1;
             feature->SetFeatureType(FeatureType(FEATURE_TYPE_EXECUTE(Ace, Vebox)));
@@ -1296,7 +1408,12 @@
 
     VP_SURFACE                  *inputSurface   = params.executedFilters->GetSurface(true, 0);
     VP_SURFACE                  *outputSurface  = params.executedFilters->GetSurface(false, 0);
-    VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->AssignExecuteResource(caps, inputSurface, outputSurface, params.executedFilters->GetSurfacesGroup()));
+    VP_SURFACE                  *pastSurface    = params.executedFilters->GetPastSurface(0);
+    VP_SURFACE                  *futureSurface  = params.executedFilters->GetFutureSurface(0);
+    RESOURCE_ASSIGNMENT_HINT    resHint         = {};
+    VP_PUBLIC_CHK_STATUS_RETURN(GetResourceHint(*params.executedFilters, resHint));
+    VP_PUBLIC_CHK_STATUS_RETURN(m_vpInterface.GetResourceManager()->AssignExecuteResource(caps, inputSurface, outputSurface,
+        pastSurface, futureSurface, resHint, params.executedFilters->GetSurfacesGroup()));
     return MOS_STATUS_SUCCESS;
 }
 
@@ -1381,14 +1498,29 @@
     return MOS_STATUS_SUCCESS;
 }
 
+MOS_STATUS Policy::AddFiltersBasedOnCaps(
+    SwFilterPipe& featurePipe,
+    VP_EXECUTE_CAPS& caps,
+    SwFilterPipe& executedFilters)
+{
+    //Create and Add CSC filter for VEBOX IECP chromasiting config
+    if (caps.bSFC && !caps.bBeCSC && (caps.bIECP || caps.bDI))
+    {
+        VP_PUBLIC_CHK_STATUS_RETURN(AddNewFilterOnVebox(featurePipe, caps, executedFilters, FeatureTypeCsc));
+    }
+    return MOS_STATUS_SUCCESS;
+}
+
 MOS_STATUS Policy::AddNewFilterOnVebox(
     SwFilterPipe& featurePipe,
     VP_EXECUTE_CAPS& caps,
-    HW_FILTER_PARAMS& params,
+    SwFilterPipe& executedFilters,
     FeatureType featureType)
 {
     PVP_SURFACE pSurfInput = featurePipe.GetSurface(true, 0);
+    PVP_SURFACE pSurfOutput = featurePipe.GetSurface(false, 0);
     VP_PUBLIC_CHK_NULL_RETURN(pSurfInput);
+    VP_PUBLIC_CHK_NULL_RETURN(pSurfOutput);
 
     auto handler = m_vpInterface.GetSwFilterHandler(featureType);
 
@@ -1398,49 +1530,19 @@
         return MOS_STATUS_INVALID_HANDLE;
     }
 
-    SwFilter* pSwfilter = handler->CreateSwFilter();
-    VP_PUBLIC_CHK_NULL_RETURN(pSwfilter);
+    SwFilter* swfilter = handler->CreateSwFilter();
+    VP_PUBLIC_CHK_NULL_RETURN(swfilter);
 
-    MOS_STATUS status = pSwfilter->Configure(pSurfInput, caps);
+    MOS_STATUS status = swfilter->Configure(pSurfInput, pSurfOutput, caps);
     if (MOS_FAILED(status))
     {
-        handler->Destory(pSwfilter);
+        handler->Destory(swfilter);
         VP_PUBLIC_CHK_STATUS_RETURN(status);
     }
 
-    FeatureType featureOnVebox = FeatureTypeInvalid;
-    switch (featureType)
-    {
-    case FeatureTypeDn:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Dn, Vebox);
-        break;
-    case FeatureTypeSte:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Ste, Vebox);
-        break;
-    case FeatureTypeAce:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Ace, Vebox);
-        break;
-    case FeatureTypeTcc:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Tcc, Vebox);
-        break;
-    case FeatureTypeProcamp:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Procamp, Vebox);
-        break;
-    case FeatureTypeCsc:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Csc, Vebox);
-        break;
-    case FeatureTypeHdr:
-        featureOnVebox = FEATURE_TYPE_EXECUTE(Hdr, Vebox);
-        break;
-    default:
-        featureOnVebox = FeatureTypeInvalid;
-        break;
-    }
+    VP_PUBLIC_CHK_STATUS_RETURN(UpdateExeCaps(swfilter, caps, EngineTypeVebox));
 
-    status = pSwfilter->SetFeatureType(featureOnVebox);
-    VP_PUBLIC_CHK_STATUS_RETURN(status);
-
-    status = params.executedFilters->AddSwFilterUnordered(pSwfilter, true, 0);
+    status = executedFilters.AddSwFilterUnordered(swfilter, true, 0);
     VP_PUBLIC_CHK_STATUS_RETURN(status);
 
     return status;
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.h b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.h
index c8a5301..90296c6 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/policy.h
@@ -79,6 +79,7 @@
     MOS_STATUS ReleaseHwFilterParam(HW_FILTER_PARAMS &params);
     MOS_STATUS GetExecuteCaps(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params);
     MOS_STATUS GetCSCExecutionCapsHdr(SwFilter *hdr, SwFilter *csc);
+    MOS_STATUS GetCSCExecutionCapsDi(SwFilter* feature);
     MOS_STATUS GetCSCExecutionCaps(SwFilter* feature);
     MOS_STATUS GetScalingExecutionCaps(SwFilter* feature);
     MOS_STATUS GetRotationExecutionCaps(SwFilter* feature);
@@ -88,17 +89,23 @@
     MOS_STATUS GetProcampExecutionCaps(SwFilter* feature);
     MOS_STATUS GetHdrExecutionCaps(SwFilter *feature);
     MOS_STATUS GetExecutionCaps(SwFilter* feature);
+    MOS_STATUS GetDeinterlaceExecutionCaps(SwFilter* feature);
 
     MOS_STATUS BuildFilters(SwFilterPipe& subSwFilterPipe, HW_FILTER_PARAMS& params);
     MOS_STATUS UpdateFilterCaps(SwFilterPipe& subSwFilterPipe, VP_EngineEntry& engineCaps, VP_EXECUTE_CAPS &caps);
     MOS_STATUS BuildExecuteFilter(SwFilterPipe& subSwFilterPipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params);
     MOS_STATUS BuildExecuteHwFilter(SwFilterPipe& subSwFilterPipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params);
     MOS_STATUS SetupExecuteFilter(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params);
+    MOS_STATUS GetResourceHint(SwFilterPipe& featurePipe, RESOURCE_ASSIGNMENT_HINT &hint);
     MOS_STATUS SetupFilterResource(SwFilterPipe& featurePipe, VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params);
+    virtual MOS_STATUS AddFiltersBasedOnCaps(
+        SwFilterPipe& featurePipe,
+        VP_EXECUTE_CAPS& caps,
+        SwFilterPipe& executedFilters);
     MOS_STATUS AddNewFilterOnVebox(
         SwFilterPipe& featurePipe,
         VP_EXECUTE_CAPS& caps,
-        HW_FILTER_PARAMS& params,
+        SwFilterPipe& executedFilters,
         FeatureType featureType);
 
     MOS_STATUS AssignExecuteResource(VP_EXECUTE_CAPS& caps, HW_FILTER_PARAMS& params);
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.cpp
index bd9f424..8b4cbb6 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.cpp
@@ -129,30 +129,51 @@
     return MOS_STATUS_SUCCESS;
 }
 
-MOS_STATUS SwFilterCsc::Configure(PVP_SURFACE pSurfInput, VP_EXECUTE_CAPS caps)
+namespace vp
 {
-    VP_PUBLIC_CHK_NULL_RETURN(pSurfInput);
-    VP_PUBLIC_CHK_NULL_RETURN(pSurfInput->osSurface);
+MOS_STATUS GetVeboxOutputParams(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, MOS_TILE_TYPE inputTileType, MOS_FORMAT outputFormat,
+                                MOS_FORMAT &veboxOutputFormat, MOS_TILE_TYPE &veboxOutputTileType);
+}
+
+MOS_STATUS SwFilterCsc::Configure(PVP_SURFACE surfInput, PVP_SURFACE surfOutput, VP_EXECUTE_CAPS caps)
+{
+    VP_PUBLIC_CHK_NULL_RETURN(surfInput);
+    VP_PUBLIC_CHK_NULL_RETURN(surfInput->osSurface);
+    VP_PUBLIC_CHK_NULL_RETURN(surfOutput);
+    VP_PUBLIC_CHK_NULL_RETURN(surfOutput->osSurface);
 
     if (caps.bSFC)
     {
-        m_Params.colorSpaceInput = pSurfInput->ColorSpace;
-        m_Params.colorSpaceOutput = pSurfInput->ColorSpace;
+        MOS_FORMAT      veboxOutputFormat   = surfInput->osSurface->Format;
+        MOS_TILE_TYPE   veboxOutputTileType = surfInput->osSurface->TileType;
 
-        m_Params.formatInput = pSurfInput->osSurface->Format;
-        m_Params.formatOutput = Format_AYUV;   // To get colorPack as 4:4:4
-        m_Params.chromaSitingInput = pSurfInput->ChromaSiting;
-        m_Params.chromaSitingOutput = pSurfInput->ChromaSiting;
+        GetVeboxOutputParams(caps, surfInput->osSurface->Format, surfInput->osSurface->TileType,
+                            surfOutput->osSurface->Format, veboxOutputFormat, veboxOutputTileType);
+        m_Params.colorSpaceInput = surfInput->ColorSpace;
+        m_Params.colorSpaceOutput = surfInput->ColorSpace;
+
+        m_Params.formatInput = surfInput->osSurface->Format;
+        m_Params.formatOutput = veboxOutputFormat;
+        m_Params.chromaSitingInput = surfInput->ChromaSiting;
+        m_Params.chromaSitingOutput = surfOutput->ChromaSiting;
 
         m_Params.pAlphaParams = nullptr;
         m_Params.pIEFParams = nullptr;
+
+        m_noNeedUpdate = true;
+
+        return MOS_STATUS_SUCCESS;
     }
 
-    return MOS_STATUS_SUCCESS;
+    return MOS_STATUS_UNIMPLEMENTED;
 }
 
 MOS_STATUS SwFilterCsc::Configure(VEBOX_SFC_PARAMS &params)
 {
+    if (m_noNeedUpdate)
+    {
+        return MOS_STATUS_SUCCESS;
+    }
     m_Params.colorSpaceInput    = params.input.colorSpace;
     m_Params.colorSpaceOutput   = params.output.colorSpace;
     m_Params.pIEFParams         = nullptr;
@@ -192,6 +213,12 @@
 
 MOS_STATUS SwFilterCsc::Update(VP_SURFACE *inputSurf, VP_SURFACE *outputSurf)
 {
+    if (FeatureTypeCscOnVebox == m_type)
+    {
+        // BeCSC may be added for IECP/DI. No need update.
+        return MOS_STATUS_SUCCESS;
+    }
+
     VP_PUBLIC_CHK_NULL_RETURN(inputSurf);
     VP_PUBLIC_CHK_NULL_RETURN(outputSurf);
     VP_PUBLIC_CHK_NULL_RETURN(inputSurf->osSurface);
@@ -207,6 +234,13 @@
     return MOS_STATUS_SUCCESS;
 }
 
+MOS_STATUS SwFilterCsc::SetFeatureType(FeatureType type)
+{
+    VP_PUBLIC_CHK_STATUS_RETURN(SwFilter::SetFeatureType(type));
+    m_Params.type = m_type;
+    return MOS_STATUS_SUCCESS;
+}
+
 /****************************************************************************************************/
 /*                                      SwFilterScaling                                             */
 /****************************************************************************************************/
@@ -468,6 +502,7 @@
 {
     PVPHAL_SURFACE surfInput = isInputSurf ? params.pSrc[surfIndex] : params.pSrc[0];
 
+    m_Params.sampleTypeInput = surfInput->SampleType;
     m_Params.denoiseParams = *surfInput->pDenoiseParams;
     m_Params.formatInput   = surfInput->Format;
     m_Params.formatOutput  = surfInput->Format;// Denoise didn't change the original format;
@@ -517,7 +552,82 @@
 }
 
 /****************************************************************************************************/
-/*                                      SwFilterSte                                             */
+/*                                      SwFilterDeinterlace                                         */
+/****************************************************************************************************/
+
+SwFilterDeinterlace::SwFilterDeinterlace(VpInterface& vpInterface) : SwFilter(vpInterface, FeatureTypeDi)
+{
+    m_Params.type = m_type;
+}
+
+SwFilterDeinterlace::~SwFilterDeinterlace()
+{
+    Clean();
+}
+
+MOS_STATUS SwFilterDeinterlace::Clean()
+{
+    VP_PUBLIC_CHK_STATUS_RETURN(SwFilter::Clean());
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS SwFilterDeinterlace::Configure(VP_PIPELINE_PARAMS& params, bool isInputSurf, int surfIndex)
+{
+    PVPHAL_SURFACE surfInput = isInputSurf ? params.pSrc[surfIndex] : params.pSrc[0];
+    VP_PUBLIC_CHK_NULL_RETURN(surfInput);
+    VP_PUBLIC_CHK_NULL_RETURN(surfInput->pDeinterlaceParams);
+
+    m_Params.formatInput        = surfInput->Format;
+    m_Params.formatOutput       = surfInput->Format;
+    m_Params.sampleTypeInput    = surfInput->SampleType;
+    m_Params.DIMode             = surfInput->pDeinterlaceParams->DIMode;            //!< DeInterlacing mode
+    m_Params.bEnableFMD         = surfInput->pDeinterlaceParams->bEnableFMD;        //!< FMD
+    m_Params.b60fpsDi           = !surfInput->pDeinterlaceParams->bSingleField;      //!< Used in frame Recon - if 30fps (one call per sample pair)
+    m_Params.bSCDEnable         = surfInput->pDeinterlaceParams->bSCDEnable;        //!< Scene change detection
+    m_Params.bHDContent         = MEDIA_IS_HDCONTENT(surfInput->dwWidth, surfInput->dwHeight);
+
+    return MOS_STATUS_SUCCESS;
+}
+
+FeatureParamDeinterlace& SwFilterDeinterlace::GetSwFilterParams()
+{
+    return m_Params;
+}
+
+SwFilter *SwFilterDeinterlace::Clone()
+{
+    SwFilter* p = CreateSwFilter(m_type);
+
+    SwFilterDeinterlace *swFilter = dynamic_cast<SwFilterDeinterlace *>(p);
+    if (nullptr == swFilter)
+    {
+        DestroySwFilter(p);
+        return nullptr;
+    }
+
+    swFilter->m_Params = m_Params;
+    return p;
+}
+
+bool vp::SwFilterDeinterlace::operator==(SwFilter& swFilter)
+{
+    SwFilterDeinterlace* p = dynamic_cast<SwFilterDeinterlace*>(&swFilter);
+    return nullptr != p && 0 == memcmp(&this->m_Params, &p->m_Params, sizeof(FeatureParamDeinterlace));
+}
+
+MOS_STATUS vp::SwFilterDeinterlace::Update(VP_SURFACE* inputSurf, VP_SURFACE* outputSurf)
+{
+    VP_PUBLIC_CHK_NULL_RETURN(inputSurf);
+    VP_PUBLIC_CHK_NULL_RETURN(inputSurf->osSurface);
+    VP_PUBLIC_CHK_NULL_RETURN(outputSurf);
+    VP_PUBLIC_CHK_NULL_RETURN(outputSurf->osSurface);
+    m_Params.formatInput = inputSurf->osSurface->Format;
+    m_Params.formatOutput = outputSurf->osSurface->Format;
+    return MOS_STATUS_SUCCESS;
+}
+
+/****************************************************************************************************/
+/*                                      SwFilterSte                                                 */
 /****************************************************************************************************/
 
 SwFilterSte::SwFilterSte(VpInterface& vpInterface) : SwFilter(vpInterface, FeatureTypeSte)
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.h b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.h
index e19aa5c..251c186 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter.h
@@ -54,6 +54,7 @@
     FeatureTypeDn               = 0x400,
     FeatureTypeDnOnVebox,
     FeatureTypeDi               = 0x500,
+    FeatureTypeDiOnVebox,
     FeatureTypeSte              = 0x600,
     FeatureTypeSteOnVebox,
     FeatureTypeAce              = 0x700,
@@ -143,6 +144,7 @@
     virtual MOS_STATUS Clean()
     {
         MOS_ZeroMemory(&m_EngineCaps, sizeof(m_EngineCaps));
+        m_noNeedUpdate = false;
         return MOS_STATUS_SUCCESS;
     }
     virtual FeatureType GetFeatureType()
@@ -150,7 +152,7 @@
         return m_type;
     }
     virtual MOS_STATUS Configure(VP_PIPELINE_PARAMS &params, bool bInputSurf, int surfIndex) = 0;
-    virtual MOS_STATUS Configure(PVP_SURFACE surfInput, VP_EXECUTE_CAPS caps)
+    virtual MOS_STATUS Configure(PVP_SURFACE surfInput, PVP_SURFACE surfOutput, VP_EXECUTE_CAPS caps)
     {
         return MOS_STATUS_UNIMPLEMENTED;
     }
@@ -167,7 +169,7 @@
     virtual SwFilter *Clone() = 0;
     virtual bool operator == (class SwFilter&) = 0;
     virtual MOS_STATUS Update(VP_SURFACE *inputSurf, VP_SURFACE *outputSurf) = 0;
-    MOS_STATUS SetFeatureType(FeatureType type);
+    virtual MOS_STATUS SetFeatureType(FeatureType type);
     SwFilter* CreateSwFilter(FeatureType type);
     void DestroySwFilter(SwFilter* p);
 
@@ -191,12 +193,20 @@
         return m_EngineCaps;
     }
 
+    // The child class need to implement SetResourceAssignmentHint only when any feature
+    // parameters will affect the resource assignment.
+    virtual MOS_STATUS SetResourceAssignmentHint(RESOURCE_ASSIGNMENT_HINT &hint)
+    {
+        return MOS_STATUS_SUCCESS;
+    }
+
 protected:
     VpInterface &m_vpInterface;
     FeatureType m_type = FeatureTypeInvalid;
     // SwFilterSet current swFilter belongs to.
     SwFilterSet *m_location = nullptr;
     VP_EngineEntry  m_EngineCaps = {};
+    bool m_noNeedUpdate = false;
 };
 
 struct FeatureParamCsc : public FeatureParam
@@ -217,12 +227,13 @@
     virtual ~SwFilterCsc();
     virtual MOS_STATUS Clean();
     virtual MOS_STATUS Configure(VP_PIPELINE_PARAMS &params, bool isInputSurf, int surfIndex);
-    virtual MOS_STATUS Configure(PVP_SURFACE surfInput, VP_EXECUTE_CAPS caps);
+    virtual MOS_STATUS Configure(PVP_SURFACE surfInput, PVP_SURFACE surfOutput, VP_EXECUTE_CAPS caps);
     virtual MOS_STATUS Configure(VEBOX_SFC_PARAMS &params);
     virtual FeatureParamCsc &GetSwFilterParams();
     virtual SwFilter *Clone();
     virtual bool operator == (SwFilter& swFilter);
     virtual MOS_STATUS Update(VP_SURFACE *inputSurf, VP_SURFACE *outputSurf);
+    virtual MOS_STATUS SetFeatureType(FeatureType type);
 
 private:
     FeatureParamCsc m_Params = {};
@@ -318,6 +329,38 @@
     FeatureParamDenoise m_Params = {};
 };
 
+struct FeatureParamDeinterlace : public FeatureParam
+{
+    VPHAL_SAMPLE_TYPE       sampleTypeInput;
+    bool                    bHDContent;
+    VPHAL_DI_MODE           DIMode;             //!< DeInterlacing mode
+    bool                    bEnableFMD;         //!< FMD
+    bool                    b60fpsDi;           //!< Used in frame Recon - if 30fps (one call per sample pair)
+    bool                    bSCDEnable;         //!< Scene change detection
+};
+
+class SwFilterDeinterlace : public SwFilter
+{
+public:
+    SwFilterDeinterlace(VpInterface& vpInterface);
+    virtual ~SwFilterDeinterlace();
+    virtual MOS_STATUS Clean();
+    virtual MOS_STATUS Configure(VP_PIPELINE_PARAMS& params, bool isInputSurf, int surfIndex);
+    virtual FeatureParamDeinterlace& GetSwFilterParams();
+    virtual SwFilter* Clone();
+    virtual bool operator == (SwFilter& swFilter);
+    virtual MOS_STATUS Update(VP_SURFACE* inputSurf, VP_SURFACE* outputSurf);
+    virtual MOS_STATUS SetResourceAssignmentHint(RESOURCE_ASSIGNMENT_HINT &hint)
+    {
+        hint.bDi = 1;
+        hint.b60fpsDi = m_Params.b60fpsDi;
+        return MOS_STATUS_SUCCESS;
+    }
+
+private:
+    FeatureParamDeinterlace m_Params = {};
+};
+
 struct FeatureParamSte : public FeatureParam
 {
     bool                bEnableSTE;
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.cpp
index ff244fd..c3536ac 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.cpp
@@ -306,6 +306,54 @@
 }
 
 /****************************************************************************************************/
+/*                                      SwFilterDiHandler                                           */
+/****************************************************************************************************/
+
+SwFilterDiHandler::SwFilterDiHandler(VpInterface& vpInterface) :
+    SwFilterFeatureHandler(vpInterface, FeatureTypeDi),
+    m_swFilterFactory(vpInterface)
+{}
+SwFilterDiHandler::~SwFilterDiHandler()
+{}
+
+bool SwFilterDiHandler::IsFeatureEnabled(VP_PIPELINE_PARAMS& params, bool isInputSurf, int surfIndex, SwFilterPipeType pipeType)
+{
+    if (!SwFilterFeatureHandler::IsFeatureEnabled(params, isInputSurf, surfIndex, pipeType))
+    {
+        return false;
+    }
+
+    PVPHAL_SURFACE vphalSurf = isInputSurf ? params.pSrc[surfIndex] : params.pTarget[surfIndex];
+    if (vphalSurf && vphalSurf->pDeinterlaceParams && vphalSurf->SampleType != SAMPLE_PROGRESSIVE)
+    {
+        return true;
+    }
+
+    return false;
+}
+
+SwFilter* SwFilterDiHandler::CreateSwFilter()
+{
+    SwFilter* swFilter = nullptr;
+    swFilter = m_swFilterFactory.Create();
+
+    if (swFilter)
+    {
+        swFilter->SetFeatureType(FeatureTypeDi);
+    }
+
+    return swFilter;
+}
+
+void SwFilterDiHandler::Destory(SwFilter*& swFilter)
+{
+    SwFilterDeinterlace* filter = nullptr;
+    filter = dynamic_cast<SwFilterDeinterlace*>(swFilter);
+    m_swFilterFactory.Destory(filter);
+    return;
+}
+
+/****************************************************************************************************/
 /*                                      SwFilterSteHandler                                      */
 /****************************************************************************************************/
 
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.h b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.h
index e2d1b15..edbd91b 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_handle.h
@@ -109,6 +109,19 @@
     SwFilterFactory<SwFilterDenoise> m_swFilterFactory;
 };
 
+class SwFilterDiHandler : public SwFilterFeatureHandler
+{
+public:
+    SwFilterDiHandler(VpInterface& vpInterface);
+    virtual ~SwFilterDiHandler();
+    virtual bool IsFeatureEnabled(VP_PIPELINE_PARAMS& params, bool isInputPipe, int surfIndex, SwFilterPipeType pipeType);
+    virtual SwFilter* CreateSwFilter();
+protected:
+    virtual void Destory(SwFilter*& swFilter);
+protected:
+    SwFilterFactory<SwFilterDeinterlace> m_swFilterFactory;
+};
+
 class SwFilterSteHandler : public SwFilterFeatureHandler
 {
 public:
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.cpp
index bb03378..55abccd 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.cpp
@@ -175,9 +175,20 @@
             return MOS_STATUS_NULL_POINTER;
         }
         m_InputSurfaces.push_back(surf);
-        // Keep m_pastSurface same size as m_InputSurfaces.
-        m_pastSurface.push_back(nullptr);
-        m_futureSurface.push_back(nullptr);
+
+        // Keep m_pastSurface/m_futureSurface same size as m_InputSurfaces.
+        VP_SURFACE *pastSurface = nullptr;
+        if (params.pSrc[i]->pBwdRef)
+        {
+            pastSurface = m_vpInterface.GetAllocator().AllocateVpSurface(*params.pSrc[i]->pBwdRef);
+        }
+        VP_SURFACE *futureSurface = nullptr;
+        if (params.pSrc[i]->pFwdRef)
+        {
+            futureSurface = m_vpInterface.GetAllocator().AllocateVpSurface(*params.pSrc[i]->pFwdRef);
+        }
+        m_pastSurface.push_back(pastSurface);
+        m_futureSurface.push_back(futureSurface);
 
         // Initialize m_InputPipes.
         SwFilterSubPipe *pipe = MOS_New(SwFilterSubPipe);
@@ -666,6 +677,48 @@
     return index < m_futureSurface.size() ? m_futureSurface[index] : nullptr;
 }
 
+MOS_STATUS SwFilterPipe::SetPastSurface(uint32_t index, VP_SURFACE *surf)
+{
+    if (index >= m_pastSurface.size())
+    {
+        return MOS_STATUS_INVALID_PARAMETER;
+    }
+    m_pastSurface[index] = surf;
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS SwFilterPipe::SetFutureSurface(uint32_t index, VP_SURFACE *surf)
+{
+    if (index >= m_futureSurface.size())
+    {
+        return MOS_STATUS_INVALID_PARAMETER;
+    }
+    m_futureSurface[index] = surf;
+    return MOS_STATUS_SUCCESS;
+}
+
+VP_SURFACE *SwFilterPipe::RemovePastSurface(uint32_t index)
+{
+    if (index >= m_pastSurface.size())
+    {
+        return nullptr;
+    }
+    VP_SURFACE *surf = m_pastSurface[index];
+    m_pastSurface[index] = nullptr;
+    return surf;
+}
+
+VP_SURFACE *SwFilterPipe::RemoveFutureSurface(uint32_t index)
+{
+    if (index >= m_futureSurface.size())
+    {
+        return nullptr;
+    }
+    VP_SURFACE *surf = m_futureSurface[index];
+    m_futureSurface[index] = nullptr;
+    return surf;
+}
+
 VP_SURFACE *SwFilterPipe::RemoveSurface(bool isInputSurface, uint32_t index)
 {
     auto &surfaces = isInputSurface ? m_InputSurfaces : m_OutputSurfaces;
@@ -678,8 +731,14 @@
         if (isInputSurface)
         {
             // Keep m_pastSurface and m_futureSurface same status as m_InputSurfaces.
-            m_pastSurface[index] = nullptr;
-            m_futureSurface[index] = nullptr;
+            if (m_pastSurface[index])
+            {
+                m_vpInterface.GetAllocator().DestroyVpSurface(m_pastSurface[index]);
+            }
+            if (m_futureSurface[index])
+            {
+                m_vpInterface.GetAllocator().DestroyVpSurface(m_futureSurface[index]);
+            }
         }
 
         return surf;
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.h b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.h
index e84cb8a..9cc434a 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/sw_filter_pipe.h
@@ -135,7 +135,11 @@
     VP_SURFACE *GetSurface(bool isInputSurface, uint32_t index);
     VP_SURFACE *GetPastSurface(uint32_t index);
     VP_SURFACE *GetFutureSurface(uint32_t index);
+    MOS_STATUS SetPastSurface(uint32_t index, VP_SURFACE *surf);
+    MOS_STATUS SetFutureSurface(uint32_t index, VP_SURFACE *surf);
     VP_SURFACE *RemoveSurface(bool isInputSurface, uint32_t index);
+    VP_SURFACE *RemovePastSurface(uint32_t index);
+    VP_SURFACE *RemoveFutureSurface(uint32_t index);
     MOS_STATUS AddSurface(VP_SURFACE *&surf, bool isInputSurface, uint32_t index);
     MOS_STATUS Update();
     uint32_t GetSurfaceCount(bool isInputSurface);
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.cpp
index f7a6288..461c48e 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.cpp
@@ -154,6 +154,10 @@
     VP_PUBLIC_CHK_NULL_RETURN(p);
     m_featureHandler.insert(std::make_pair(FeatureTypeHdr, p));
 
+    p = MOS_New(SwFilterDiHandler, m_vpInterface);
+    VP_PUBLIC_CHK_NULL_RETURN(p);
+    m_featureHandler.insert(std::make_pair(FeatureTypeDi, p));
+
     m_isFeatureRegistered = true;
     return MOS_STATUS_SUCCESS;
 }
@@ -866,3 +870,23 @@
 
     return eStatus;
 }
+
+bool VPFeatureManager::IsDiFormatSupported(MOS_FORMAT format)
+{
+    if (format != Format_AYUV         &&
+        format != Format_Y416         &&
+        format != Format_Y410         &&
+        format != Format_A8B8G8R8     &&
+        format != Format_A8R8G8B8     &&
+        format != Format_B10G10R10A2  &&
+        format != Format_R10G10B10A2  &&
+        format != Format_A16B16G16R16 &&
+        format != Format_A16R16G16B16)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.h b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.h
index bc9ae73..869a62c 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/feature_manager/vp_feature_manager.h
@@ -151,6 +151,8 @@
         return false;
     }
 
+    virtual bool IsDiFormatSupported(MOS_FORMAT format);
+
 protected:
     PVP_MHWINTERFACE        m_hwInterface       = nullptr;
     PMOS_INTERFACE          m_pOsInterface      = nullptr;
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/features/media_srcs.cmake b/media_driver/media_driver_next/agnostic/common/vp/hal/features/media_srcs.cmake
index 12ba760..a5c314d 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/features/media_srcs.cmake
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/features/media_srcs.cmake
@@ -28,6 +28,7 @@
     ${CMAKE_CURRENT_LIST_DIR}/vp_tcc_filter.cpp
     ${CMAKE_CURRENT_LIST_DIR}/vp_procamp_filter.cpp
     ${CMAKE_CURRENT_LIST_DIR}/vp_hdr_filter.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/vp_di_filter.cpp
 )
 
 set(TMP_HEADERS_
@@ -40,6 +41,7 @@
     ${CMAKE_CURRENT_LIST_DIR}/vp_tcc_filter.h
     ${CMAKE_CURRENT_LIST_DIR}/vp_procamp_filter.h
     ${CMAKE_CURRENT_LIST_DIR}/vp_hdr_filter.h
+    ${CMAKE_CURRENT_LIST_DIR}/vp_di_filter.h
 )
 
 set(SOURCES_NEW
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.cpp
index bf4d397..d0eea82 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.cpp
@@ -80,6 +80,8 @@
 #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_VERT_OFFSET           0
 #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_VERT_OFFSET           0
 
+MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput);
+
 VpCscFilter::VpCscFilter(PVP_MHWINTERFACE vpMhwInterface) :
     VpFilter(vpMhwInterface)
 {
@@ -134,18 +136,19 @@
 {
     VP_FUNC_CALL();
 
-    if (m_executeCaps.bSfcCsc)
+    if (FeatureTypeCscOnSfc == m_cscParams.type)
     {
         VP_RENDER_CHK_STATUS_RETURN(CalculateSfcEngineParams());
     }
-    else if (m_executeCaps.bBeCSC)
+    else if (FeatureTypeCscOnVebox == m_cscParams.type)
     {
         VP_RENDER_CHK_STATUS_RETURN(CalculateVeboxEngineParams());
     }
-    else if (m_executeCaps.bRender)
+    else if (FeatureTypeCscOnRender == m_cscParams.type)
     {
         // place hold for Render solution
         VP_PUBLIC_ASSERTMESSAGE("No function support CSC in Render path now");
+        return MOS_STATUS_UNIMPLEMENTED;
     }
     else
     {
@@ -165,26 +168,6 @@
     return inputColorSpace;
 }
 
-MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput)
-{
-    if (executeCaps.bIECP)
-    {
-        if (executeCaps.bHDR3DLUT)
-        {
-            return IS_COLOR_SPACE_BT2020(colorSpaceOutput) ? Format_R10G10B10A2 : Format_A8B8G8R8;
-        }
-        // Upsampling to yuv444 for IECP input/output.
-        return Format_AYUV;
-    }
-    else if (executeCaps.bDI && VpHal_GetSurfaceColorPack(inputFormat) == VPHAL_COLORPACK_420)
-    {
-        // If the input is 4:2:0, then chroma data is doubled vertically to 4:2:2
-        return Format_YUY2;
-    }
-
-    return inputFormat;
-}
-
 MOS_STATUS VpCscFilter::CalculateSfcEngineParams()
 {
     VP_FUNC_CALL();
@@ -279,6 +262,8 @@
     m_veboxCSCParams->bCSCEnabled = (m_cscParams.colorSpaceInput != m_cscParams.colorSpaceOutput);
     m_veboxCSCParams->alphaParams = m_cscParams.pAlphaParams;
 
+    VP_RENDER_CHK_STATUS_RETURN(UpdateChromaSiting());
+
     VP_RENDER_CHK_STATUS_RETURN(SetVeboxCUSChromaParams(m_executeCaps));
     VP_RENDER_CHK_STATUS_RETURN(SetVeboxCDSChromaParams(m_executeCaps));
 
@@ -293,7 +278,9 @@
     VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams);
 
     // Update chroma sitting according to updated input format.
-    VP_RENDER_CHK_STATUS_RETURN(UpdateSfcChromaSiting());
+    VP_RENDER_CHK_STATUS_RETURN(UpdateChromaSiting());
+
+    m_sfcCSCParams->sfcSrcChromaSiting = m_cscParams.chromaSitingInput;
 
     // Setup General params
     // Set chroma subsampling type according to the Vebox output, but
@@ -473,10 +460,12 @@
 
     bool bNeedDownSampling = false;
 
+    VPHAL_COLORPACK dstColorPack = VpHal_GetSurfaceColorPack(m_cscParams.formatOutput);
+
     // Only VEBOX output, we use VEO to do downsampling.
     // Else, we use SFC/FC path to do downscaling.
     // if VEBOX intermediate buffer format is non_YUY2 on DI case, enable downsampling as center-left
-    if (vpExecuteCaps.bDI && (m_cscParams.formatOutput != Format_YUY2))
+    if (vpExecuteCaps.bDI && (m_cscParams.formatOutput != Format_YUY2 || vpExecuteCaps.bIECP))
     {
         bNeedDownSampling = true;
     }
@@ -485,10 +474,6 @@
         bNeedDownSampling = vpExecuteCaps.bVebox && !vpExecuteCaps.bSFC;
     }
 
-
-    VPHAL_COLORPACK dstColorPack;
-    dstColorPack = VpHal_GetSurfaceColorPack(m_cscParams.formatOutput);
-
     // Init as CDS disabled
     m_veboxCSCParams->bypassCDS = true;
 
@@ -576,12 +561,10 @@
     return MOS_STATUS_SUCCESS;
 }
 
-MOS_STATUS VpCscFilter::UpdateSfcChromaSiting()
+MOS_STATUS VpCscFilter::UpdateChromaSiting()
 {
     VP_FUNC_CALL();
 
-    VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams);
-
     if (MHW_CHROMA_SITING_NONE == m_cscParams.chromaSitingInput)
     {
         m_cscParams.chromaSitingInput = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
@@ -598,8 +581,6 @@
         break;
     }
 
-    m_sfcCSCParams->sfcSrcChromaSiting = m_cscParams.chromaSitingInput;
-
     if (MHW_CHROMA_SITING_NONE == m_cscParams.chromaSitingOutput)
     {
         m_cscParams.chromaSitingOutput = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.h b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.h
index bc22275..93913cc 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_csc_filter.h
@@ -106,7 +106,7 @@
     //! \details  Setup Chroma sitting parameters
     //! \return   MOS_STATUS
     //!
-    MOS_STATUS UpdateSfcChromaSiting();
+    MOS_STATUS UpdateChromaSiting();
 
     //!
     //! \brief    Check whether Chroma Up Sampling Needed
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_di_filter.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_di_filter.cpp
new file mode 100644
index 0000000..93499ee
--- /dev/null
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_di_filter.cpp
@@ -0,0 +1,269 @@
+/*
+* Copyright (c) 2020, Intel Corporation
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+//!
+//! \file     vp_di_filter.cpp
+//! \brief    Defines the common interface for Adaptive Contrast Enhancement
+//!           this file is for the base interface which is shared by all Ace in driver.
+//!
+#include "vp_di_filter.h"
+#include "vp_vebox_cmd_packet.h"
+#include "hw_filter.h"
+#include "sw_filter_pipe.h"
+
+using namespace vp;
+
+VpDiFilter::VpDiFilter(PVP_MHWINTERFACE vpMhwInterface) :
+    VpFilter(vpMhwInterface)
+{
+
+}
+
+MOS_STATUS VpDiFilter::Init()
+{
+    VP_FUNC_CALL();
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS VpDiFilter::Prepare()
+{
+    VP_FUNC_CALL();
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS VpDiFilter::Destroy()
+{
+    VP_FUNC_CALL();
+
+    if (m_pVeboxDiParams)
+    {
+        MOS_FreeMemAndSetNull(m_pVeboxDiParams);
+    }
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS VpDiFilter::SetExecuteEngineCaps(
+    FeatureParamDeinterlace &diParams,
+    VP_EXECUTE_CAPS         vpExecuteCaps)
+{
+    VP_FUNC_CALL();
+
+    m_diParams      = diParams;
+    m_executeCaps   = vpExecuteCaps;
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS VpDiFilter::CalculateEngineParams()
+{
+    VP_FUNC_CALL();
+    if (m_executeCaps.bVebox)
+    {
+        // create a filter Param buffer
+        if (!m_pVeboxDiParams)
+        {
+            m_pVeboxDiParams = (PVEBOX_DI_PARAMS)MOS_AllocAndZeroMemory(sizeof(VEBOX_DI_PARAMS));
+
+            if (m_pVeboxDiParams == nullptr)
+            {
+                VP_PUBLIC_ASSERTMESSAGE("Vebox DI Pamas buffer allocate failed, return nullpointer");
+                return MOS_STATUS_NO_SPACE;
+            }
+        }
+        else
+        {
+            MOS_ZeroMemory(m_pVeboxDiParams, sizeof(VEBOX_DI_PARAMS));
+        }
+
+        m_pVeboxDiParams->bDiEnabled        = true;
+        m_pVeboxDiParams->sampleTypeInput   = m_diParams.sampleTypeInput;
+        m_pVeboxDiParams->b60fpsDi          = m_diParams.b60fpsDi;
+        m_pVeboxDiParams->diMode            = m_diParams.DIMode;
+        m_pVeboxDiParams->enableFMD         = m_diParams.bEnableFMD;
+        m_pVeboxDiParams->bSCDEnabled       = m_diParams.bSCDEnable;
+        m_pVeboxDiParams->bHDContent        = m_diParams.bHDContent;
+    }
+    else
+    {
+        VP_PUBLIC_ASSERTMESSAGE("Wrong engine caps! Vebox should be used for DI");
+        return MOS_STATUS_INVALID_PARAMETER;
+    }
+
+    return MOS_STATUS_SUCCESS;
+}
+
+
+/****************************************************************************************************/
+/*                                   HwFilter DI Parameter                                         */
+/****************************************************************************************************/
+HwFilterParameter *HwFilterDiParameter::Create(HW_FILTER_DI_PARAM &param, FeatureType featureType)
+{
+    HwFilterDiParameter *p = MOS_New(HwFilterDiParameter, featureType);
+    if (p)
+    {
+        if (MOS_FAILED(p->Initialize(param)))
+        {
+            MOS_Delete(p);
+            return nullptr;
+        }
+    }
+    return p;
+}
+
+HwFilterDiParameter::HwFilterDiParameter(FeatureType featureType) : HwFilterParameter(featureType)
+{
+}
+
+HwFilterDiParameter::~HwFilterDiParameter()
+{
+}
+
+MOS_STATUS HwFilterDiParameter::ConfigParams(HwFilter &hwFilter)
+{
+    return hwFilter.ConfigParam(m_Params);
+}
+
+MOS_STATUS HwFilterDiParameter::Initialize(HW_FILTER_DI_PARAM &param)
+{
+    m_Params = param;
+    return MOS_STATUS_SUCCESS;
+}
+
+/****************************************************************************************************/
+/*                                   Packet Vebox DI Parameter                                       */
+/****************************************************************************************************/
+VpPacketParameter *VpVeboxDiParameter::Create(HW_FILTER_DI_PARAM &param)
+{
+    if (nullptr == param.pPacketParamFactory)
+    {
+        return nullptr;
+    }
+    VpVeboxDiParameter *p = dynamic_cast<VpVeboxDiParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface));
+    if (p)
+    {
+        if (MOS_FAILED(p->Initialize(param)))
+        {
+            VpPacketParameter *pParam = p;
+            param.pPacketParamFactory->ReturnPacketParameter(pParam);
+            return nullptr;
+        }
+    }
+    return p;
+}
+
+VpVeboxDiParameter::VpVeboxDiParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) :
+    VpPacketParameter(packetParamFactory), m_diFilter(pHwInterface)
+{
+}
+VpVeboxDiParameter::~VpVeboxDiParameter() {}
+
+bool VpVeboxDiParameter::SetPacketParam(VpCmdPacket *pPacket)
+{
+    VpVeboxCmdPacket *pVeboxPacket = dynamic_cast<VpVeboxCmdPacket *>(pPacket);
+    if (nullptr == pVeboxPacket)
+    {
+        return false;
+    }
+
+    VEBOX_DI_PARAMS *pParams = m_diFilter.GetVeboxParams();
+    if (nullptr == pParams)
+    {
+        return false;
+    }
+    return MOS_SUCCEEDED(pVeboxPacket->SetDiParams(pParams));
+}
+
+MOS_STATUS VpVeboxDiParameter::Initialize(HW_FILTER_DI_PARAM &params)
+{
+    VP_PUBLIC_CHK_STATUS_RETURN(m_diFilter.Init());
+    VP_PUBLIC_CHK_STATUS_RETURN(m_diFilter.SetExecuteEngineCaps(params.diParams, params.vpExecuteCaps));
+    VP_PUBLIC_CHK_STATUS_RETURN(m_diFilter.CalculateEngineParams());
+    return MOS_STATUS_SUCCESS;
+}
+
+/****************************************************************************************************/
+/*                                   Policy Vebox DI Handler                                         */
+/****************************************************************************************************/
+PolicyVeboxDiHandler::PolicyVeboxDiHandler()
+{
+    m_Type = FeatureTypeDiOnVebox;
+}
+PolicyVeboxDiHandler::~PolicyVeboxDiHandler()
+{
+}
+
+bool PolicyVeboxDiHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps)
+{
+    return vpExecuteCaps.bDI;
+}
+
+HwFilterParameter* PolicyVeboxDiHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe& swFilterPipe, PVP_MHWINTERFACE pHwInterface)
+{
+    if (IsFeatureEnabled(vpExecuteCaps))
+    {
+        if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType())
+        {
+            VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!");
+            return nullptr;
+        }
+
+        SwFilterDeinterlace *swFilter = dynamic_cast<SwFilterDeinterlace *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeDiOnVebox));
+
+        if (nullptr == swFilter)
+        {
+            VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!");
+            return nullptr;
+        }
+
+        FeatureParamDeinterlace &param = swFilter->GetSwFilterParams();
+
+        HW_FILTER_DI_PARAM diParam = {};
+        diParam.type = m_Type;
+        diParam.pHwInterface = pHwInterface;
+        diParam.vpExecuteCaps = vpExecuteCaps;
+        diParam.pPacketParamFactory = &m_PacketParamFactory;
+        diParam.diParams = param;
+        diParam.pfnCreatePacketParam = PolicyVeboxDiHandler::CreatePacketParam;
+
+        HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool();
+
+        if (pHwFilterParam)
+        {
+            if (MOS_FAILED(((HwFilterDiParameter*)pHwFilterParam)->Initialize(diParam)))
+            {
+                ReleaseHwFeatureParameter(pHwFilterParam);
+            }
+        }
+        else
+        {
+            pHwFilterParam = HwFilterDiParameter::Create(diParam, m_Type);
+        }
+
+        return pHwFilterParam;
+    }
+    else
+    {
+        return nullptr;
+    }
+}
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_di_filter.h b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_di_filter.h
new file mode 100644
index 0000000..0085f37
--- /dev/null
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_di_filter.h
@@ -0,0 +1,124 @@
+/*
+* Copyright (c) 2020, Intel Corporation
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+//!
+//! \file     vp_di_filter.h
+//! \brief    Defines the common interface for ace
+//!           this file is for the base interface which is shared by all ace in driver.
+//!
+#ifndef __VP_DI_FILTER_H__
+#define __VP_DI_FILTER_H__
+#include "vp_filter.h"
+#include "sw_filter.h"
+
+namespace vp {
+class VpDiFilter : public VpFilter
+{
+public:
+
+    VpDiFilter(
+        PVP_MHWINTERFACE vpMhwInterface);
+
+    ~VpDiFilter()
+    {
+        Destroy();
+    };
+
+    virtual MOS_STATUS Init() override;
+
+    virtual MOS_STATUS Prepare() override;
+
+    virtual MOS_STATUS Destroy() override;
+
+    virtual MOS_STATUS SetExecuteEngineCaps(
+        FeatureParamDeinterlace &diParams,
+        VP_EXECUTE_CAPS         vpExecuteCaps);
+
+    MOS_STATUS CalculateEngineParams();
+    PVEBOX_DI_PARAMS GetVeboxParams()
+    {
+        return m_pVeboxDiParams;
+    }
+
+protected:
+    FeatureParamDeinterlace     m_diParams = {};
+    PVEBOX_DI_PARAMS            m_pVeboxDiParams = nullptr;
+};
+
+struct HW_FILTER_DI_PARAM : public HW_FILTER_PARAM
+{
+    FeatureParamDeinterlace     diParams;
+};
+
+class HwFilterDiParameter : public HwFilterParameter
+{
+public:
+    static HwFilterParameter *Create(HW_FILTER_DI_PARAM &param, FeatureType featureType);
+    HwFilterDiParameter(FeatureType featureType);
+    virtual ~HwFilterDiParameter();
+    virtual MOS_STATUS ConfigParams(HwFilter &hwFilter);
+
+    MOS_STATUS Initialize(HW_FILTER_DI_PARAM&param);
+
+private:
+    HW_FILTER_DI_PARAM m_Params = {};
+};
+
+class VpVeboxDiParameter : public VpPacketParameter
+{
+public:
+    static VpPacketParameter *Create(HW_FILTER_DI_PARAM &param);
+    VpVeboxDiParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory);
+    virtual ~VpVeboxDiParameter();
+
+    virtual bool SetPacketParam(VpCmdPacket *pPacket);
+
+private:
+    MOS_STATUS Initialize(HW_FILTER_DI_PARAM&params);
+
+    VpDiFilter m_diFilter;
+};
+
+class PolicyVeboxDiHandler : public PolicyFeatureHandler
+{
+public:
+    PolicyVeboxDiHandler();
+    virtual ~PolicyVeboxDiHandler();
+    virtual bool IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps);
+    virtual HwFilterParameter *CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface);
+
+    static VpPacketParameter* CreatePacketParam(HW_FILTER_PARAM& param)
+    {
+        if (param.type != FeatureTypeDiOnVebox)
+        {
+            VP_PUBLIC_ASSERTMESSAGE("Invalid parameter for Vebox ACE!");
+            return nullptr;
+        }
+
+        HW_FILTER_DI_PARAM* aceParam = (HW_FILTER_DI_PARAM*)(&param);
+        return VpVeboxDiParameter::Create(*aceParam);
+    }
+
+private:
+    PacketParamFactory<VpVeboxDiParameter> m_PacketParamFactory;
+};
+}
+#endif
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_filter.h b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_filter.h
index ca7ea4b..a7c8fc0 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_filter.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/features/vp_filter.h
@@ -177,12 +177,24 @@
     uint32_t                        dwSTEFactor;
 };
 
+struct _VEBOX_DI_PARAMS
+{
+    bool                            bDiEnabled;                                 // DI Enabled
+    VPHAL_SAMPLE_TYPE               sampleTypeInput;
+    bool                            b60fpsDi;
+    VPHAL_DI_MODE                   diMode;                                     //!< DeInterlacing mode
+    bool                            enableFMD;                                  //!< FMD
+    bool                            bSCDEnabled;                                //!< Scene change detection
+    bool                            bHDContent;
+};
+
 struct _VEBOX_ACE_PARAMS
 {
     bool                            bEnableACE;                                 // ACE Enabled
     bool                            bAceLevelChanged;
     uint32_t                        dwAceLevel;
     uint32_t                        dwAceStrength;
+    bool                            bAceHistogramEnabled;
 };
 
 struct _VEBOX_TCC_PARAMS
@@ -261,6 +273,8 @@
 using PVEBOX_DN_PARAMS      = VEBOX_DN_PARAMS *;
 using VEBOX_STE_PARAMS      = _VEBOX_STE_PARAMS;
 using PVEBOX_STE_PARAMS     = VEBOX_STE_PARAMS *;
+using VEBOX_DI_PARAMS       = _VEBOX_DI_PARAMS;
+using PVEBOX_DI_PARAMS      = VEBOX_DI_PARAMS *;
 using VEBOX_ACE_PARAMS      = _VEBOX_ACE_PARAMS;
 using PVEBOX_ACE_PARAMS     = VEBOX_ACE_PARAMS *;
 using VEBOX_TCC_PARAMS      = _VEBOX_TCC_PARAMS;
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.cpp b/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.cpp
index d514f95..937d075 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.cpp
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.cpp
@@ -48,12 +48,10 @@
     0x000000ab, 0x00000080, 0x00000066, 0x00000055, 0x000000c2, 0x000000b9, 0x000000b0, 0x000000a9, 0x000000a2, 0x0000009c };
 
 void VpVeboxCmdPacket::SetupSurfaceStates(
-    bool                                    bDiVarianceEnable,
     PVPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS   pVeboxSurfaceStateCmdParams)
 {
     VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(pVeboxSurfaceStateCmdParams);
     MOS_ZeroMemory(pVeboxSurfaceStateCmdParams, sizeof(VPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS));
-    MOS_UNUSED(bDiVarianceEnable);
     pVeboxSurfaceStateCmdParams->pSurfInput    = m_veboxPacketSurface.pCurrInput;
     pVeboxSurfaceStateCmdParams->pSurfOutput   = m_veboxPacketSurface.pCurrOutput;
     pVeboxSurfaceStateCmdParams->pSurfSTMM     = m_veboxPacketSurface.pSTMMInput;
@@ -62,7 +60,6 @@
 }
 
 MOS_STATUS VpVeboxCmdPacket::SetupVeboxState(
-    bool                        bDiVarianceEnable,
     PMHW_VEBOX_STATE_CMD_PARAMS pVeboxStateCmdParams)
 {
     PMHW_VEBOX_MODE         pVeboxMode   = nullptr;
@@ -83,12 +80,12 @@
     // For next step, need to enable it only when necessary.
     pVeboxMode->GlobalIECPEnable = true;
 
-    pVeboxMode->DIEnable = bDiVarianceEnable;
+    pVeboxMode->DIEnable = m_PacketCaps.bDI;
 
     pVeboxMode->SFCParallelWriteEnable = m_IsSfcUsed &&
-                                            (m_PacketCaps.bDN || bDiVarianceEnable);
+                                            (m_PacketCaps.bDN || m_PacketCaps.bDI);
     pVeboxMode->DNEnable = m_PacketCaps.bDN;
-    pVeboxMode->DNDIFirstFrame = (!m_PacketCaps.bRefValid && (pVeboxMode->DNEnable || pVeboxMode->DIEnable));
+    pVeboxMode->DNDIFirstFrame = m_DNDIFirstFrame;
     pVeboxMode->DIOutputFrames = m_DIOutputFrames;
     pVeboxMode->DisableEncoderStatistics = true;
     pVeboxMode->DisableTemporalDenoiseFilter = false;
@@ -286,6 +283,27 @@
         // Vebox output case.
         surf = m_renderTarget;
     }
+    else if (SurfaceTypeVeboxInput == type && surf)
+    {
+        // The vp surface object for external surface will be destroyed by hw filter before packet submit.
+        // Store the vp surface object inside packet.
+        if (MOS_FAILED(m_allocator->CopyVpSurface(*m_currentSurface ,*surf)))
+        {
+            return nullptr;
+        }
+        m_currentSurface->rcMaxSrc = m_currentSurface->rcSrc;
+        surf = m_currentSurface;
+    }
+    else if (SurfaceTypeVeboxPreviousInput == type && surf)
+    {
+        // The vp surface object for external surface will be destroyed by hw filter before packet submit.
+        // Store the vp surface object inside packet.
+        if (MOS_FAILED(m_allocator->CopyVpSurface(*m_previousSurface ,*surf)))
+        {
+            return nullptr;
+        }
+        surf = m_previousSurface;
+    }
     return surf;
 }
 
@@ -692,6 +710,114 @@
     return MOS_STATUS_SUCCESS;
 }
 
+MOS_STATUS VpVeboxCmdPacket::SetDiParams(PVEBOX_DI_PARAMS diParams)
+{
+    MOS_STATUS                      eStatus         = MOS_STATUS_SUCCESS;
+    VpVeboxRenderData               *renderData     = GetLastExecRenderData();
+    VP_SAMPLER_STATE_DN_PARAM       lumaParams      = {};
+    VPHAL_DNUV_PARAMS               chromaParams    = {};
+
+    VP_PUBLIC_CHK_NULL_RETURN(diParams);
+    VP_PUBLIC_CHK_NULL_RETURN(renderData);
+
+    renderData->DI.value            = 0;
+    renderData->DI.bDeinterlace     = diParams->bDiEnabled;
+    renderData->DI.bQueryVariance   = false;
+
+    // for 30i->30fps + SFC
+    if (m_PacketCaps.bSFC && !diParams->b60fpsDi)
+    {
+        // Set BLT1's Current DI Output as BLT2's input, it is always under Mode0
+        // BLT1 output 1st field of current frame for the following cases:
+        if (m_DNDIFirstFrame                                                            ||
+            (diParams->sampleTypeInput == SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD) ||
+            (diParams->sampleTypeInput == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD)   ||
+            (diParams->sampleTypeInput == SAMPLE_SINGLE_TOP_FIELD)                   ||
+            (diParams->sampleTypeInput == SAMPLE_PROGRESSIVE))
+        {
+            m_DIOutputFrames = MEDIA_VEBOX_DI_OUTPUT_CURRENT;
+        }
+        else
+        {
+            // First sample output - 2nd field of the previous frame
+            m_DIOutputFrames = MEDIA_VEBOX_DI_OUTPUT_PREVIOUS;
+        }
+    }
+    // for 30i->60fps or other 30i->30fps cases
+    else
+    {
+            m_DIOutputFrames = m_DNDIFirstFrame ?
+                MEDIA_VEBOX_DI_OUTPUT_CURRENT :
+                MEDIA_VEBOX_DI_OUTPUT_BOTH;
+    }
+
+    VP_PUBLIC_CHK_STATUS_RETURN(SetDiParams(diParams->bDiEnabled, diParams->bSCDEnabled, diParams->bHDContent, diParams->sampleTypeInput, renderData->GetDNDIParams()));
+
+    return eStatus;
+}
+
+MOS_STATUS VpVeboxCmdPacket::SetDiParams(bool bDiEnabled, bool bSCDEnabled, bool bHDContent, VPHAL_SAMPLE_TYPE sampleTypeInput, MHW_VEBOX_DNDI_PARAMS &param)
+{
+    if (!bDiEnabled)
+    {
+        return MOS_STATUS_SUCCESS;
+    }
+
+    param.bDNDITopFirst = (sampleTypeInput == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD) ||
+                        (sampleTypeInput == SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD);
+    param.dwLumaTDMWeight            = VPHAL_VEBOX_DI_LUMA_TDM_WEIGHT_NATUAL;
+    param.dwChromaTDMWeight          = VPHAL_VEBOX_DI_CHROMA_TDM_WEIGHT_NATUAL;
+    param.dwSHCMDelta                = VPHAL_VEBOX_DI_SHCM_DELTA_NATUAL;
+    param.dwSHCMThreshold            = VPHAL_VEBOX_DI_SHCM_THRESHOLD_NATUAL;
+    param.dwSVCMDelta                = VPHAL_VEBOX_DI_SVCM_DELTA_NATUAL;
+    param.dwSVCMThreshold            = VPHAL_VEBOX_DI_SVCM_THRESHOLD_NATUAL;
+    param.bFasterConvergence         = false;
+    param.bTDMLumaSmallerWindow      = false;
+    param.bTDMChromaSmallerWindow    = false;
+    param.dwLumaTDMCoringThreshold   = VPHAL_VEBOX_DI_LUMA_TDM_CORING_THRESHOLD_NATUAL;
+    param.dwChromaTDMCoringThreshold = VPHAL_VEBOX_DI_CHROMA_TDM_CORING_THRESHOLD_NATUAL;
+    param.bBypassDeflickerFilter     = true;
+    param.bUseSyntheticContentMedian = false;
+    param.bLocalCheck                = true;
+    param.bSyntheticContentCheck     = false;
+    param.dwDirectionCheckThreshold  = VPHAL_VEBOX_DI_DIRECTION_CHECK_THRESHOLD_NATUAL;
+    param.dwTearingLowThreshold      = VPHAL_VEBOX_DI_TEARING_LOW_THRESHOLD_NATUAL;
+    param.dwTearingHighThreshold     = VPHAL_VEBOX_DI_TEARING_HIGH_THRESHOLD_NATUAL;
+    param.dwDiffCheckSlackThreshold  = VPHAL_VEBOX_DI_DIFF_CHECK_SLACK_THRESHOLD_NATUAL;
+    param.dwSADWT0                   = VPHAL_VEBOX_DI_SAD_WT0_NATUAL;
+    param.dwSADWT1                   = VPHAL_VEBOX_DI_SAD_WT1_NATUAL;
+    param.dwSADWT2                   = VPHAL_VEBOX_DI_SAD_WT2_NATUAL;
+    param.dwSADWT3                   = VPHAL_VEBOX_DI_SAD_WT3_NATUAL;
+    param.dwSADWT4                   = VPHAL_VEBOX_DI_SAD_WT4_NATUAL;
+    param.dwSADWT6                   = VPHAL_VEBOX_DI_SAD_WT6_NATUAL;
+    param.bSCDEnable                 = bSCDEnabled;
+
+    if (bHDContent)
+    {
+        param.dwLPFWtLUT0 = VPHAL_VEBOX_DI_LPFWTLUT0_HD_NATUAL;
+        param.dwLPFWtLUT1 = VPHAL_VEBOX_DI_LPFWTLUT1_HD_NATUAL;
+        param.dwLPFWtLUT2 = VPHAL_VEBOX_DI_LPFWTLUT2_HD_NATUAL;
+        param.dwLPFWtLUT3 = VPHAL_VEBOX_DI_LPFWTLUT3_HD_NATUAL;
+        param.dwLPFWtLUT4 = VPHAL_VEBOX_DI_LPFWTLUT4_HD_NATUAL;
+        param.dwLPFWtLUT5 = VPHAL_VEBOX_DI_LPFWTLUT5_HD_NATUAL;
+        param.dwLPFWtLUT6 = VPHAL_VEBOX_DI_LPFWTLUT6_HD_NATUAL;
+        param.dwLPFWtLUT7 = VPHAL_VEBOX_DI_LPFWTLUT7_HD_NATUAL;
+    }
+    else
+    {
+        param.dwLPFWtLUT0 = VPHAL_VEBOX_DI_LPFWTLUT0_SD_NATUAL;
+        param.dwLPFWtLUT1 = VPHAL_VEBOX_DI_LPFWTLUT1_SD_NATUAL;
+        param.dwLPFWtLUT2 = VPHAL_VEBOX_DI_LPFWTLUT2_SD_NATUAL;
+        param.dwLPFWtLUT3 = VPHAL_VEBOX_DI_LPFWTLUT3_SD_NATUAL;
+        param.dwLPFWtLUT4 = VPHAL_VEBOX_DI_LPFWTLUT4_SD_NATUAL;
+        param.dwLPFWtLUT5 = VPHAL_VEBOX_DI_LPFWTLUT5_SD_NATUAL;
+        param.dwLPFWtLUT6 = VPHAL_VEBOX_DI_LPFWTLUT6_SD_NATUAL;
+        param.dwLPFWtLUT7 = VPHAL_VEBOX_DI_LPFWTLUT7_SD_NATUAL;
+    }
+
+    return MOS_STATUS_SUCCESS;
+}
+
 MOS_STATUS VpVeboxCmdPacket::SetupDiIecpState(
     bool                        bDiScdEnable,
     PMHW_VEBOX_DI_IECP_CMD_PARAMS   pVeboxDiIecpCmdParams)
@@ -1099,7 +1225,6 @@
     bDiVarianceEnable = m_PacketCaps.bDI;
 
     SetupSurfaceStates(
-        bDiVarianceEnable,
         &VeboxSurfaceStateCmdParams);
 
     // Add compressible info of input/output surface to log
@@ -1111,7 +1236,6 @@
     }
 
     SetupVeboxState(
-        bDiVarianceEnable,
         &VeboxStateCmdParams);
 
     VP_RENDER_CHK_STATUS_RETURN(SetupDiIecpState(
@@ -1409,31 +1533,18 @@
 
     VP_RENDER_CHK_STATUS_RETURN(InitSurfMemCacheControl(packetCaps));
 
-    if (packetCaps.bSFC)
-    {
-        m_IsSfcUsed = true;
-    }
-    else
-    {
-        m_IsSfcUsed = false;
-    }
+    m_IsSfcUsed = packetCaps.bSFC;
 
     //update VEBOX resource GMM resource usage type
     m_allocator->UpdateResourceUsageType(&inputSurface->osSurface->OsResource, MOS_HW_RESOURCE_USAGE_VP_INPUT_PICTURE_FF);
     m_allocator->UpdateResourceUsageType(&outputSurface->osSurface->OsResource, MOS_HW_RESOURCE_USAGE_VP_OUTPUT_PICTURE_FF);
 
     // Set current src = current primary input
-    VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->CopyVpSurface(*m_currentSurface ,*inputSurface));
     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->CopyVpSurface(*m_renderTarget ,*outputSurface));
-    if (previousSurface)
-    {
-        VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->CopyVpSurface(*m_previousSurface ,*previousSurface));
-    }
-    m_currentSurface->rcMaxSrc = m_currentSurface->rcSrc;
 
     // Init packet surface params.
     m_surfacesGroup = internalSurfaces;
-    m_veboxPacketSurface.pCurrInput                 = m_currentSurface;
+    m_veboxPacketSurface.pCurrInput                 = GetSurface(SurfaceTypeVeboxInput);
     m_veboxPacketSurface.pStatisticsOutput          = GetSurface(SurfaceTypeStatistics);
     m_veboxPacketSurface.pCurrOutput                = GetSurface(SurfaceTypeVeboxCurrentOutput);
     m_veboxPacketSurface.pPrevInput                 = GetSurface(SurfaceTypeVeboxPreviousInput);
@@ -1448,6 +1559,9 @@
     VP_RENDER_CHK_NULL_RETURN(m_veboxPacketSurface.pStatisticsOutput);
     VP_RENDER_CHK_NULL_RETURN(m_veboxPacketSurface.pLaceOrAceOrRgbHistogram);
 
+    m_DNDIFirstFrame = (!m_PacketCaps.bRefValid && (m_PacketCaps.bDN || m_PacketCaps.bDI));
+    m_DIOutputFrames = MEDIA_VEBOX_DI_OUTPUT_CURRENT;
+
     return MOS_STATUS_SUCCESS;
 }
 
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.h b/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.h
index 2e86d68..bb7c792 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_cmd_packet.h
@@ -379,7 +379,6 @@
     //! \return   void
     //!
     virtual void SetupSurfaceStates(
-        bool                        bDiVarianceEnable,
         PVPHAL_VEBOX_SURFACE_STATE_CMD_PARAMS  pVeboxSurfaceStateCmdParams);
 
     //!
@@ -512,6 +511,16 @@
     virtual MOS_STATUS SetProcampParams(PVEBOX_PROCAMP_PARAMS procampParams);
 
     //!
+    //! \brief    Setup DI Params for Vebox
+    //! \details  Setup surface DN Params for Vebox
+    //! \param    [in] diParams
+    //!           DI Params
+    //! \return   MOS_STATUS
+    //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
+    //!
+    virtual MOS_STATUS SetDiParams(PVEBOX_DI_PARAMS diParams);
+
+    //!
     //! \brief    Get DN luma parameters
     //! \details  Get DN luma parameters
     //! \param    [in] bDnEnabled
@@ -683,15 +692,12 @@
 
     //!
     //! \brief    Setup Vebox_State Command parameter
-    //! \param    [in] bDiVarianceEnable
-    //!           Is DI/Variances report enabled
     //! \param    [in,out] pVeboxStateCmdParams
     //!           Pointer to VEBOX_STATE command parameters
     //! \return   MOS_STATUS
     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
     //!
     virtual MOS_STATUS SetupVeboxState(
-        bool                        bDiVarianceEnable,
         PMHW_VEBOX_STATE_CMD_PARAMS pVeboxStateCmdParams);
 
     //!
@@ -955,6 +961,13 @@
         PVPHAL_SURFACE pSrcSurface,
         PVPHAL_SURFACE pOutSurface);
 
+    virtual MOS_STATUS SetDiParams(
+        bool                    bDiEnabled,
+        bool                    bSCDEnabled,
+        bool                    bHDContent,
+        VPHAL_SAMPLE_TYPE       sampleTypeInput,
+        MHW_VEBOX_DNDI_PARAMS   &param);
+
     //!
     //! \brief    Get surface by type
     //! \details  Get surface by type
@@ -1012,6 +1025,7 @@
     uint32_t                    m_dwGlobalNoiseLevelV = 0;                        //!< Global Noise Level for V
     uint32_t                    m_dwGlobalNoiseLevel = 0;                         //!< Global Noise Level
     PVP_VEBOX_CACHE_CNTL        m_surfMemCacheCtl = nullptr;                      //!< Surface memory cache control
+    uint32_t                    m_DNDIFirstFrame = 0;
     uint32_t                    m_DIOutputFrames = MEDIA_VEBOX_DI_OUTPUT_CURRENT; //!< default value is 2 for non-DI case.
 
     // Statistics
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_common.h b/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_common.h
index a609aa5..04765cf 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_common.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/packet/vp_vebox_common.h
@@ -373,7 +373,7 @@
             struct
             {
                 uint32_t bAceEnabled            : 1;    // ACE enabled;
-                uint32_t bQueryAceHistogram     : 1;    // Chroma Dn Enabled
+                uint32_t bAceHistogramEnabled   : 1;    // ACE histogram enabled, should be set to 1 when bAceEnabled == 1;
             };
             uint32_t value = 0;
         } ACE;
diff --git a/media_driver/media_driver_next/agnostic/common/vp/hal/pipeline/vp_pipeline_common.h b/media_driver/media_driver_next/agnostic/common/vp/hal/pipeline/vp_pipeline_common.h
index 2ce8e71..567e92b 100644
--- a/media_driver/media_driver_next/agnostic/common/vp/hal/pipeline/vp_pipeline_common.h
+++ b/media_driver/media_driver_next/agnostic/common/vp/hal/pipeline/vp_pipeline_common.h
@@ -107,7 +107,8 @@
             uint32_t bRender        : 1;   // Render Only needed;
             // Vebox Features
             uint32_t bDN            : 1;   // Vebox DN needed;
-            uint32_t bDI            : 1;   // Vebox DNDI enabled
+            uint32_t bDI            : 1;   // Vebox DI enabled
+            uint32_t bDiProcess2ndField : 1;   // Vebox DI enabled
             uint32_t bIECP          : 1;   // Vebox IECP needed;
             uint32_t bSTE           : 1;   // Vebox STE needed;
             uint32_t bACE           : 1;   // Vebox ACE needed;
@@ -130,10 +131,8 @@
             uint32_t bSfcIef        : 1;   // Sfc Details Needed;
 
             // Render Features
-            uint32_t bComposite : 1;
-            uint32_t bBobDI     : 1;
-            uint32_t bIScaling  : 1;
-            uint32_t reserved   : 6;  // Reserved
+            uint32_t bComposite     : 1;
+            uint32_t reserved       : 7;   // Reserved
         };
     };
 };
@@ -154,7 +153,8 @@
             uint32_t DisableVeboxSFCMode : 1;
             uint32_t FurtherProcessNeeded : 1;
             uint32_t CompositionNeeded : 1;
-            uint32_t reserve : 19;
+            uint32_t bypassVeboxFeatures : 1;
+            uint32_t reserve : 18;
         };
         uint32_t value;
     };
@@ -173,6 +173,19 @@
     VP_COMP_BYPASS_ENABLED  = 0x1
 } VP_COMP_BYPASS_MODE, * PVP_COMP_BYPASS_MODE;
 
+// RESOURCE_ASSIGNMENT_HINT are feature parameters which will affect resource assignment.
+// For caps existing in VP_EXECUTE_CAPS, they should not be added to RESOURCE_ASSIGNMENT_HINT.
+union RESOURCE_ASSIGNMENT_HINT
+{
+    struct
+    {
+        // Hint for DI
+        uint32_t    bDi                 : 1;
+        uint32_t    b60fpsDi            : 1;
+    };
+    uint32_t value;
+};
+
 using VP_MHWINTERFACE  = _VP_MHWINTERFACE;
 using PVP_MHWINTERFACE = VP_MHWINTERFACE * ;
 using VP_EXECUTE_CAPS  = _VP_EXECUTE_CAPS;
diff --git a/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.cpp b/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.cpp
index 01440be..4f5822d 100644
--- a/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.cpp
+++ b/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2019, Intel Corporation
+* Copyright (c) 2019-2020, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -371,84 +371,6 @@
     return MOS_STATUS_SUCCESS;
 }
 
-MOS_STATUS VpVeboxCmdPacketG12::SetDIParams(
-    PVPHAL_SURFACE pSrcSurface)
-{
-    // Place Hold: Add it back when enabling DI.
-    //PVPHAL_VEBOX_RENDER_DATA pRenderData = GetLastExecRenderData();
-    //VP_RENDER_CHK_NULL_RETURN(pRenderData);
-
-    //if (!m_PacketCaps.bDI)
-    //{
-    //    VP_RENDER_NORMALMESSAGE("DI for Output is enabled in Vebox, pls recheck the features enabling in Vebox");
-    //    return MOS_STATUS_INVALID_PARAMETER;
-    //}
-
-    //// Set DI params
-    //if (pRenderData->bDeinterlace)
-    //{
-    //    pRenderData->VeboxDNDIParams.dwLumaTDMWeight            = VPHAL_VEBOX_DI_LUMA_TDM_WEIGHT_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwChromaTDMWeight          = VPHAL_VEBOX_DI_CHROMA_TDM_WEIGHT_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSHCMDelta                = VPHAL_VEBOX_DI_SHCM_DELTA_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSHCMThreshold            = VPHAL_VEBOX_DI_SHCM_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSVCMDelta                = VPHAL_VEBOX_DI_SVCM_DELTA_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSVCMThreshold            = VPHAL_VEBOX_DI_SVCM_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.bFasterConvergence         = false;
-    //    pRenderData->VeboxDNDIParams.bTDMLumaSmallerWindow      = false;
-    //    pRenderData->VeboxDNDIParams.bTDMChromaSmallerWindow    = false;
-    //    pRenderData->VeboxDNDIParams.dwLumaTDMCoringThreshold   = VPHAL_VEBOX_DI_LUMA_TDM_CORING_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwChromaTDMCoringThreshold = VPHAL_VEBOX_DI_CHROMA_TDM_CORING_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.bBypassDeflickerFilter     = true;
-    //    pRenderData->VeboxDNDIParams.bUseSyntheticContentMedian = false;
-    //    pRenderData->VeboxDNDIParams.bLocalCheck                = true;
-    //    pRenderData->VeboxDNDIParams.bSyntheticContentCheck     = false;
-    //    pRenderData->VeboxDNDIParams.dwDirectionCheckThreshold  = VPHAL_VEBOX_DI_DIRECTION_CHECK_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwTearingLowThreshold      = VPHAL_VEBOX_DI_TEARING_LOW_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwTearingHighThreshold     = VPHAL_VEBOX_DI_TEARING_HIGH_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwDiffCheckSlackThreshold  = VPHAL_VEBOX_DI_DIFF_CHECK_SLACK_THRESHOLD_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSADWT0                   = VPHAL_VEBOX_DI_SAD_WT0_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSADWT1                   = VPHAL_VEBOX_DI_SAD_WT1_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSADWT2                   = VPHAL_VEBOX_DI_SAD_WT2_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSADWT3                   = VPHAL_VEBOX_DI_SAD_WT3_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSADWT4                   = VPHAL_VEBOX_DI_SAD_WT4_NATUAL;
-    //    pRenderData->VeboxDNDIParams.dwSADWT6                   = VPHAL_VEBOX_DI_SAD_WT6_NATUAL;
-    //    if (pSrcSurface && pSrcSurface->pDeinterlaceParams)
-    //    {
-    //        pRenderData->VeboxDNDIParams.bSCDEnable             = pSrcSurface->pDeinterlaceParams->bSCDEnable;
-    //    }
-    //    else
-    //    {
-    //        pRenderData->VeboxDNDIParams.bSCDEnable             = false;
-    //    }
-
-    //    VP_RENDER_CHK_NULL_RETURN(pSrcSurface);
-    //    if (MEDIA_IS_HDCONTENT(pSrcSurface->dwWidth, pSrcSurface->dwHeight))
-    //    {
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT0 = VPHAL_VEBOX_DI_LPFWTLUT0_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT1 = VPHAL_VEBOX_DI_LPFWTLUT1_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT2 = VPHAL_VEBOX_DI_LPFWTLUT2_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT3 = VPHAL_VEBOX_DI_LPFWTLUT3_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT4 = VPHAL_VEBOX_DI_LPFWTLUT4_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT5 = VPHAL_VEBOX_DI_LPFWTLUT5_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT6 = VPHAL_VEBOX_DI_LPFWTLUT6_HD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT7 = VPHAL_VEBOX_DI_LPFWTLUT7_HD_NATUAL;
-    //    }
-    //    else
-    //    {
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT0 = VPHAL_VEBOX_DI_LPFWTLUT0_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT1 = VPHAL_VEBOX_DI_LPFWTLUT1_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT2 = VPHAL_VEBOX_DI_LPFWTLUT2_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT3 = VPHAL_VEBOX_DI_LPFWTLUT3_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT4 = VPHAL_VEBOX_DI_LPFWTLUT4_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT5 = VPHAL_VEBOX_DI_LPFWTLUT5_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT6 = VPHAL_VEBOX_DI_LPFWTLUT6_SD_NATUAL;
-    //        pRenderData->VeboxDNDIParams.dwLPFWtLUT7 = VPHAL_VEBOX_DI_LPFWTLUT7_SD_NATUAL;
-    //    }
-    //}
-
-    return MOS_STATUS_SUCCESS;
-}
-
 //!
 //! \brief    Setup Vebox_DI_IECP Command params
 //! \details  Setup Vebox_DI_IECP Command params
diff --git a/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.h b/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.h
index ba6780b..272cc9b 100644
--- a/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.h
+++ b/media_driver/media_driver_next/agnostic/gen12/vp/hal/vp_vebox_cmd_packet_g12.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2019, Intel Corporation
+* Copyright (c) 2019-2020, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -91,9 +91,6 @@
         bool                        bAutoDetect,
         float                       fDnFactor) override;
 
-    virtual MOS_STATUS SetDIParams(
-            PVPHAL_SURFACE          pSrcSurface);
-
     //!
     //! \brief    Setup Vebox_DI_IECP Command params
     //! \details  Setup Vebox_DI_IECP Command params