| From 234430ba0c49ba7dec0fa35306479d009cd4f34d 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] 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 Wang, Yan<yan.wang@intel.com> for the review |
| and Li, Steven(steven.li@intel.com) for the suggestion |
| on keeping the scaling logic outside of the inter-frame code block. |
| |
| ChromeOS bug id: https://partnerissuetracker.corp.google.com/issues/152554969 |
| |
| (cherry picked from commit 1aa3e6995ccfac86b4ec68265591545302435038) |
| --- |
| .../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 e47cc03a..0d99e653 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 |
| @@ -2258,6 +2258,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; |
| @@ -2275,6 +2276,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) |
| @@ -2314,8 +2336,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; |
| @@ -2326,15 +2346,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 e9990b0b..bd8447a1 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 |
| @@ -3128,6 +3128,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; |
| @@ -3145,6 +3146,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) |
| @@ -3184,9 +3206,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; |
| @@ -3197,15 +3216,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 b3f4ef19..a2b42846 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 |
| @@ -3543,6 +3543,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; |
| @@ -3560,6 +3561,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) |
| @@ -3599,9 +3621,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; |
| @@ -3612,15 +3631,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 9fd31b5c..ca57f073 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 |
| @@ -1237,6 +1237,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; |
| @@ -1254,6 +1255,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) |
| @@ -1293,8 +1315,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; |
| @@ -1305,15 +1325,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; |
| @@ -1595,4 +1618,4 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpHevcPicBrcBuffer( |
| m_osInterface->pfnUnlockResource(m_osInterface, hcpImgStates); |
| |
| return eStatus; |
| -} |
| \ No newline at end of file |
| +} |
| -- |
| 2.26.2 |
| |