| From 894247c63770f2e10e5999b7b03d5abdbda3bf7b Mon Sep 17 00:00:00 2001 |
| From: Sreerenj Balachandran <sreerenj.balachandran@intel.com> |
| Date: Mon, 1 Jun 2020 17:19:04 -0700 |
| Subject: [PATCH 1/2] Decoder:VP9:GEN{9,10,11,12} : Fix the GPU hang due to |
| wrong SegmentIDStreamIn & UsePrevInFindMvReferences |
| |
| We have been seeing random gpu hang on various devices while decoding 4k |
| VP9 streams. This patch is addressing a couple of issues which is expected |
| to fix the hangs: |
| |
| a) The current code tries to reset SegmentIDStreamIn if there is |
| a resolution change on inter-frames. But due to the mishandling, |
| the code was eventually setting SegmentIDStreamIn to true for all |
| non-scaling use cases. The patch ensures that the reset happens |
| only for res-change on P-frames irrespective of other conditions. |
| |
| b) The current implementation sets the SegmentIDStreamIn for any |
| decode where there is no Segmentation Enabled. We rather follow |
| strict constraints similar to the legacy i965 implementation. |
| |
| c) Ensure the correct SegmentIDStreamIn for key-frames, intra-only |
| frames and error-resilient mode. |
| |
| d) Reset UsePrevInFindMvReferences to zero if last picture has a different size, |
| Current picture is error-resilient mode, Last picture was intra_only or keyframe, |
| Last picture was not a displayed picture. |
| |
| Thanks to Li, Steven for review and suggestion on putting the scaling |
| logic outside of inter-frame code block. |
| |
| ChromeOS bug id: https://partnerissuetracker.corp.google.com/issues/152554969 |
| --- |
| .../gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp | 45 +++++++++++++----- |
| .../gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp | 46 +++++++++++++----- |
| .../gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp | 46 +++++++++++++----- |
| .../hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp | 47 ++++++++++++++----- |
| .../hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp | 47 ++++++++++++++----- |
| 5 files changed, 172 insertions(+), 59 deletions(-) |
| |
| diff --git a/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp b/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp |
| index f44ee324..c155c256 100644 |
| --- a/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp |
| +++ b/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp |
| @@ -2244,6 +2244,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd( |
| |
| uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1; |
| uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1; |
| + bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| |
| cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| @@ -2261,6 +2262,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd( |
| cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag; |
| cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap; |
| |
| + uint8_t segmentIDStreaminEnable = 0; |
| + if (vp9PicParams->PicFlags.fields.intra_only || |
| + (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) { |
| + segmentIDStreaminEnable = 1; |
| + } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| + if (!vp9PicParams->PicFlags.fields.segmentation_update_map) |
| + segmentIDStreaminEnable = 1; |
| + else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update) |
| + segmentIDStreaminEnable = 1; |
| + } |
| + if (vp9PicParams->PicFlags.fields.error_resilient_mode) { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + // Resolution change will reset the segment ID buffer |
| + if (isScaling) |
| + { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + |
| + cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable; |
| + |
| cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here. |
| cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here. |
| if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1) |
| @@ -2300,8 +2322,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd( |
| uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth; |
| uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight; |
| |
| - bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| - |
| cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv; |
| cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type; |
| cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update; |
| @@ -2312,15 +2332,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd( |
| |
| cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame; |
| |
| - cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - params->PrevFrameParams.fields.KeyFrame || |
| - params->PrevFrameParams.fields.IntraOnly || |
| - !params->PrevFrameParams.fields.Display || |
| - isScaling ? false : true; |
| - |
| - cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - !cmd.DW2.SegmentationEnabled || |
| - isScaling ? false : true; |
| + // Reset UsePrevInFindMvReferences to zero if last picture has a different size, |
| + // Current picture is error-resilient mode, Last picture was intra_only or keyframe, |
| + // Last picture was not a displayed picture. |
| + cmd.DW2.UsePrevInFindMvReferences = |
| + !(vp9PicParams->PicFlags.fields.error_resilient_mode || |
| + params->PrevFrameParams.fields.KeyFrame || |
| + params->PrevFrameParams.fields.IntraOnly || |
| + !params->PrevFrameParams.fields.Display); |
| + // Reset UsePrevInFindMvReferences in case of resolution change on inter frames |
| + if (isScaling) { |
| + cmd.DW2.UsePrevInFindMvReferences = 0; |
| + } |
| |
| cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth; |
| cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight; |
| diff --git a/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp b/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp |
| index 1a99523a..802bcfe8 100644 |
| --- a/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp |
| +++ b/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp |
| @@ -3106,6 +3106,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd( |
| |
| uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1; |
| uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1; |
| + bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| |
| cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| @@ -3123,6 +3124,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd( |
| cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag; |
| cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap; |
| |
| + uint8_t segmentIDStreaminEnable = 0; |
| + if (vp9PicParams->PicFlags.fields.intra_only || |
| + (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) { |
| + segmentIDStreaminEnable = 1; |
| + } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| + if (!vp9PicParams->PicFlags.fields.segmentation_update_map) |
| + segmentIDStreaminEnable = 1; |
| + else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update) |
| + segmentIDStreaminEnable = 1; |
| + } |
| + if (vp9PicParams->PicFlags.fields.error_resilient_mode) { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + // Resolution change will reset the segment ID buffer |
| + if (isScaling) |
| + { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + |
| + cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable; |
| + |
| cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here. |
| cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here. |
| if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1) |
| @@ -3162,9 +3184,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd( |
| uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth; |
| uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight; |
| |
| - bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? |
| - false : true; |
| - |
| cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv; |
| cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type; |
| cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update; |
| @@ -3175,15 +3194,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd( |
| |
| cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame; |
| |
| - cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - params->PrevFrameParams.fields.KeyFrame || |
| - params->PrevFrameParams.fields.IntraOnly || |
| - !params->PrevFrameParams.fields.Display || |
| - isScaling ? false : true; |
| - |
| - cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - !cmd.DW2.SegmentationEnabled || |
| - isScaling ? false : true; |
| + // Reset UsePrevInFindMvReferences to zero if last picture has a different size, |
| + // Current picture is error-resilient mode, Last picture was intra_only or keyframe, |
| + // Last picture was not a displayed picture. |
| + cmd.DW2.UsePrevInFindMvReferences = |
| + !(vp9PicParams->PicFlags.fields.error_resilient_mode || |
| + params->PrevFrameParams.fields.KeyFrame || |
| + params->PrevFrameParams.fields.IntraOnly || |
| + !params->PrevFrameParams.fields.Display); |
| + // Reset UsePrevInFindMvReferences in case of resolution change on inter frames |
| + if (isScaling) { |
| + cmd.DW2.UsePrevInFindMvReferences = 0; |
| + } |
| |
| cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth; |
| cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight; |
| diff --git a/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp b/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp |
| index f0a90a04..d92f1667 100644 |
| --- a/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp |
| +++ b/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp |
| @@ -3523,6 +3523,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd( |
| |
| uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1; |
| uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1; |
| + bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| |
| cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| @@ -3540,6 +3541,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd( |
| cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag; |
| cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap; |
| |
| + uint8_t segmentIDStreaminEnable = 0; |
| + if (vp9PicParams->PicFlags.fields.intra_only || |
| + (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) { |
| + segmentIDStreaminEnable = 1; |
| + } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| + if (!vp9PicParams->PicFlags.fields.segmentation_update_map) |
| + segmentIDStreaminEnable = 1; |
| + else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update) |
| + segmentIDStreaminEnable = 1; |
| + } |
| + if (vp9PicParams->PicFlags.fields.error_resilient_mode) { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + // Resolution change will reset the segment ID buffer |
| + if (isScaling) |
| + { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + |
| + cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable; |
| + |
| cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here. |
| cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here. |
| if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1) |
| @@ -3579,9 +3601,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd( |
| uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth; |
| uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight; |
| |
| - bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? |
| - false : true; |
| - |
| cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv; |
| cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type; |
| cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update; |
| @@ -3592,15 +3611,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd( |
| |
| cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame; |
| |
| - cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - params->PrevFrameParams.fields.KeyFrame || |
| - params->PrevFrameParams.fields.IntraOnly || |
| - !params->PrevFrameParams.fields.Display || |
| - isScaling ? false : true; |
| - |
| - cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - !cmd.DW2.SegmentationEnabled || |
| - isScaling ? false : true; |
| + // Reset UsePrevInFindMvReferences to zero if last picture has a different size, |
| + // Current picture is error-resilient mode, Last picture was intra_only or keyframe, |
| + // Last picture was not a displayed picture. |
| + cmd.DW2.UsePrevInFindMvReferences = |
| + !(vp9PicParams->PicFlags.fields.error_resilient_mode || |
| + params->PrevFrameParams.fields.KeyFrame || |
| + params->PrevFrameParams.fields.IntraOnly || |
| + !params->PrevFrameParams.fields.Display); |
| + // Reset UsePrevInFindMvReferences in case of resolution change on inter frames |
| + if (isScaling) { |
| + cmd.DW2.UsePrevInFindMvReferences = 0; |
| + } |
| |
| cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth; |
| cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight; |
| diff --git a/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp b/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp |
| index 2def6fd7..acd23e33 100644 |
| --- a/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp |
| +++ b/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp |
| @@ -399,6 +399,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd( |
| |
| uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1; |
| uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1; |
| + bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| |
| cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| @@ -416,6 +417,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd( |
| cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag; |
| cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap; |
| |
| + uint8_t segmentIDStreaminEnable = 0; |
| + if (vp9PicParams->PicFlags.fields.intra_only || |
| + (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) { |
| + segmentIDStreaminEnable = 1; |
| + } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| + if (!vp9PicParams->PicFlags.fields.segmentation_update_map) |
| + segmentIDStreaminEnable = 1; |
| + else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update) |
| + segmentIDStreaminEnable = 1; |
| + } |
| + if (vp9PicParams->PicFlags.fields.error_resilient_mode) { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + // Resolution change will reset the segment ID buffer |
| + if (isScaling) |
| + { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + |
| + cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable; |
| + |
| cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here. |
| cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here. |
| |
| @@ -438,8 +460,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd( |
| uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth; |
| uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight; |
| |
| - bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| - |
| cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv; |
| cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type; |
| cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update; |
| @@ -450,15 +470,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd( |
| |
| cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame; |
| |
| - cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - params->PrevFrameParams.fields.KeyFrame || |
| - params->PrevFrameParams.fields.IntraOnly || |
| - !params->PrevFrameParams.fields.Display || |
| - isScaling ? false : true; |
| - |
| - cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - !cmd.DW2.SegmentationEnabled || |
| - isScaling ? false : true; |
| + // Reset UsePrevInFindMvReferences to zero if last picture has a different size, |
| + // Current picture is error-resilient mode, Last picture was intra_only or keyframe, |
| + // Last picture was not a displayed picture. |
| + cmd.DW2.UsePrevInFindMvReferences = |
| + !(vp9PicParams->PicFlags.fields.error_resilient_mode || |
| + params->PrevFrameParams.fields.KeyFrame || |
| + params->PrevFrameParams.fields.IntraOnly || |
| + !params->PrevFrameParams.fields.Display); |
| + // Reset UsePrevInFindMvReferences in case of resolution change on inter frames |
| + if (isScaling) { |
| + cmd.DW2.UsePrevInFindMvReferences = 0; |
| + } |
| |
| cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth; |
| cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight; |
| @@ -548,4 +571,4 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9SegmentStateCmd( |
| MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(cmdBuffer, batchBuffer, segData, cmd.byteSize)); |
| |
| return eStatus; |
| -} |
| \ No newline at end of file |
| +} |
| diff --git a/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp b/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp |
| index 48879ca0..c61b26ac 100644 |
| --- a/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp |
| +++ b/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp |
| @@ -1223,6 +1223,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd( |
| |
| uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1; |
| uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1; |
| + bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| |
| cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1; |
| @@ -1240,6 +1241,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd( |
| cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag; |
| cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap; |
| |
| + uint8_t segmentIDStreaminEnable = 0; |
| + if (vp9PicParams->PicFlags.fields.intra_only || |
| + (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) { |
| + segmentIDStreaminEnable = 1; |
| + } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| + if (!vp9PicParams->PicFlags.fields.segmentation_update_map) |
| + segmentIDStreaminEnable = 1; |
| + else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update) |
| + segmentIDStreaminEnable = 1; |
| + } |
| + if (vp9PicParams->PicFlags.fields.error_resilient_mode) { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + // Resolution change will reset the segment ID buffer |
| + if (isScaling) |
| + { |
| + segmentIDStreaminEnable = 1; |
| + } |
| + |
| + cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable; |
| + |
| cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here. |
| cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here. |
| if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1) |
| @@ -1279,8 +1301,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd( |
| uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth; |
| uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight; |
| |
| - bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true; |
| - |
| cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv; |
| cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type; |
| cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update; |
| @@ -1291,15 +1311,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd( |
| |
| cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame; |
| |
| - cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - params->PrevFrameParams.fields.KeyFrame || |
| - params->PrevFrameParams.fields.IntraOnly || |
| - !params->PrevFrameParams.fields.Display || |
| - isScaling ? false : true; |
| - |
| - cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode || |
| - !cmd.DW2.SegmentationEnabled || |
| - isScaling ? false : true; |
| + // Reset UsePrevInFindMvReferences to zero if last picture has a different size, |
| + // Current picture is error-resilient mode, Last picture was intra_only or keyframe, |
| + // Last picture was not a displayed picture. |
| + cmd.DW2.UsePrevInFindMvReferences = |
| + !(vp9PicParams->PicFlags.fields.error_resilient_mode || |
| + params->PrevFrameParams.fields.KeyFrame || |
| + params->PrevFrameParams.fields.IntraOnly || |
| + !params->PrevFrameParams.fields.Display); |
| + // Reset UsePrevInFindMvReferences in case of resolution change on inter frames |
| + if (isScaling) { |
| + cmd.DW2.UsePrevInFindMvReferences = 0; |
| + } |
| |
| cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth; |
| cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight; |
| @@ -1581,4 +1604,4 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpHevcPicBrcBuffer( |
| m_osInterface->pfnUnlockResource(m_osInterface, hcpImgStates); |
| |
| return eStatus; |
| -} |
| \ No newline at end of file |
| +} |
| -- |
| 2.17.1 |
| |