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