summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSureshGuttula <suresh.guttula@amd.corp-partner.google.com>2020-06-13 12:21:48 +0530
committerMarge Bot <eric+marge@anholt.net>2020-08-04 17:01:20 +0000
commit65d23e7fb1edea1f36d4f695b7e85f44c6b89232 (patch)
treed482c7e5d4827c2ca67c396b1b97af3002da2b08
parentb98dd704894713b5f0b8fa2c1b52c0b970e9f89b (diff)
radeon/vcn: Corrected vp9 ref associated data incase of target->codec is NULL
This patch fixes the case where less number of reference surfaces created and destoyed on need basis. The problem comes when we are refereing old assoiciated data for newly created target buffer with same address. Here old target buffer destroyed as that surface is no more used as reference for next frames and when we create a new surface for the next frame to process we will get the surfaceid and same target address of destroyed surface. When new surface/surface->buffer/target ,target->codec is null as we cleared when we destroy this surface, but per ref_mapping logic, it was taking null associated data i.e.0 as curr_ref_idx. Hence total reference mapping table goes wrong with wrong data. Beacuse of this, we have seen corrupted vp9 decoded frames. Signed-off-by: SureshGuttula <suresh.guttula@amd.corp-partner.google.com> Reviewed-by: Leo Liu <leo.liu@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5452>
-rw-r--r--src/gallium/drivers/radeon/radeon_vcn_dec.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c
index 8ef797e6809..849270a3df9 100644
--- a/src/gallium/drivers/radeon/radeon_vcn_dec.c
+++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c
@@ -371,7 +371,7 @@ static rvcn_dec_message_vp9_t get_vp9_msg(struct radeon_decoder *dec,
struct pipe_vp9_picture_desc *pic)
{
rvcn_dec_message_vp9_t result;
- unsigned i;
+ unsigned i ,j;
memset(&result, 0, sizeof(result));
@@ -486,14 +486,32 @@ static rvcn_dec_message_vp9_t get_vp9_msg(struct radeon_decoder *dec,
assert(dec->base.max_references + 1 <= ARRAY_SIZE(dec->render_pic_list));
+ //clear the dec->render list if it is not used as a reference
+ for (i = 0; i < ARRAY_SIZE(dec->render_pic_list); i++) {
+ if (dec->render_pic_list[i]) {
+ for (j=0;j<8;j++) {
+ if (dec->render_pic_list[i] == pic->ref[j])
+ break;
+ }
+ if(j == 8)
+ dec->render_pic_list[i] = NULL;
+ }
+ }
+
for (i = 0; i < ARRAY_SIZE(dec->render_pic_list); ++i) {
if (dec->render_pic_list[i] && dec->render_pic_list[i] == target) {
- result.curr_pic_idx = (uintptr_t)vl_video_buffer_get_associated_data(target, &dec->base);
- break;
+ if (target->codec != NULL){
+ result.curr_pic_idx =(uintptr_t)vl_video_buffer_get_associated_data(target, &dec->base);
+ } else {
+ result.curr_pic_idx = i;
+ vl_video_buffer_set_associated_data(target, &dec->base, (void *)(uintptr_t)i,
+ &radeon_dec_destroy_associated_data);
+ }
+ break;
} else if (!dec->render_pic_list[i]) {
dec->render_pic_list[i] = target;
- result.curr_pic_idx = dec->ref_idx;
- vl_video_buffer_set_associated_data(target, &dec->base, (void *)(uintptr_t)dec->ref_idx++,
+ result.curr_pic_idx = i;
+ vl_video_buffer_set_associated_data(target, &dec->base, (void *)(uintptr_t)i,
&radeon_dec_destroy_associated_data);
break;
}