blob: d7b07fce3f5c2c07e1f13b7a98de513d6cabb0db [file] [log] [blame]
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