[Mesa-dev] [PATCH 2/6] radeon/uvd: try to fix VC-1 decoding

Grigori Goronzy greg at chown.ath.cx
Wed Oct 9 02:23:48 CEST 2013


The DPB size calculations seem to be off; there is various random
corruption happening, even with advanced profile. Always assuming
a minimum number of references appears to fix it, similarly to
H.264. This might overallocate the DPB.  Also clean up the SPS/PPS
field setup so that it matches VC-1 specifications better.

With these changes, all advanced profile VC-1 files I could get my
hand on work fine.
---
 src/gallium/drivers/radeon/radeon_uvd.c | 71 ++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 33 deletions(-)

diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
index 34650d4..da92ace 100644
--- a/src/gallium/drivers/radeon/radeon_uvd.c
+++ b/src/gallium/drivers/radeon/radeon_uvd.c
@@ -56,6 +56,7 @@
 
 #define NUM_MPEG2_REFS 6
 #define NUM_H264_REFS 17
+#define NUM_VC1_REFS 5
 
 /* UVD buffer representation */
 struct ruvd_buffer
@@ -304,6 +305,9 @@ static unsigned calc_dpb_size(const struct pipe_video_codec *templ)
 		break;
 
 	case PIPE_VIDEO_FORMAT_VC1:
+		// the firmware seems to allways assume a minimum of ref frames
+		max_references = MAX2(NUM_VC1_REFS, max_references);
+
 		// reference picture buffer
 		dpb_size = image_size * max_references;
 
@@ -431,60 +435,62 @@ static struct ruvd_vc1 get_vc1_msg(struct pipe_vc1_picture_desc *pic)
 	struct ruvd_vc1 result;
 
 	memset(&result, 0, sizeof(result));
+
 	switch(pic->base.profile) {
 	case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
 		result.profile = RUVD_VC1_PROFILE_SIMPLE;
+		result.level = 1;
 		break;
 
 	case PIPE_VIDEO_PROFILE_VC1_MAIN:
 		result.profile = RUVD_VC1_PROFILE_MAIN;
+		result.level = 2;
 		break;
-		
+
 	case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
 		result.profile = RUVD_VC1_PROFILE_ADVANCED;
+		result.level = 4;
 		break;
+
 	default:
 		assert(0);
 	}
 
-	if (pic->base.profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) {
-		result.level = 0;
-
-		result.sps_info_flags |= pic->postprocflag << 7;
-		result.sps_info_flags |= pic->pulldown << 6;
-		result.sps_info_flags |= pic->interlace << 5;
-		result.sps_info_flags |= pic->tfcntrflag << 4;
-		result.sps_info_flags |= pic->psf << 1;
-
-		result.pps_info_flags |= pic->panscan_flag << 7;
-		result.pps_info_flags |= pic->refdist_flag << 6;
-		result.pps_info_flags |= pic->extended_dmv << 8;
-		result.pps_info_flags |= pic->range_mapy_flag << 31;
-		result.pps_info_flags |= pic->range_mapy << 28;
-		result.pps_info_flags |= pic->range_mapuv_flag << 27;
-		result.pps_info_flags |= pic->range_mapuv << 24;
+	/* fields common for all profiles */
+	result.sps_info_flags |= pic->postprocflag << 7;
+	result.sps_info_flags |= pic->pulldown << 6;
+	result.sps_info_flags |= pic->interlace << 5;
+	result.sps_info_flags |= pic->tfcntrflag << 4;
+	result.sps_info_flags |= pic->finterpflag << 3;
+	result.sps_info_flags |= pic->psf << 1;
+
+	result.pps_info_flags |= pic->range_mapy_flag << 31;
+	result.pps_info_flags |= pic->range_mapy << 28;
+	result.pps_info_flags |= pic->range_mapuv_flag << 27;
+	result.pps_info_flags |= pic->range_mapuv << 24;
+	result.pps_info_flags |= pic->multires << 21;
+	result.pps_info_flags |= pic->maxbframes << 16;
+	result.pps_info_flags |= pic->overlap << 11;
+	result.pps_info_flags |= pic->quantizer << 9;
+	result.pps_info_flags |= pic->panscan_flag << 7;
+	result.pps_info_flags |= pic->refdist_flag << 6;
+	result.pps_info_flags |= pic->vstransform << 0;
 
-	} else {
-		result.level = 0;
-		result.pps_info_flags |= pic->multires << 21;
+	/* some fields only apply to main/advanced profile */
+	if (pic->base.profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE) {
 		result.pps_info_flags |= pic->syncmarker << 20;
 		result.pps_info_flags |= pic->rangered << 19;
-		result.pps_info_flags |= pic->maxbframes << 16;
+		result.pps_info_flags |= pic->loopfilter << 5;
+		result.pps_info_flags |= pic->fastuvmc << 4;
+		result.pps_info_flags |= pic->extended_mv << 3;
+		result.pps_info_flags |= pic->extended_dmv << 8;
+		result.pps_info_flags |= pic->dquant << 1;
 	}
 
-	result.sps_info_flags |= pic->finterpflag << 3;
-	//(((unsigned int)(pPicParams->advance.reserved1))        << SPS_INFO_VC1_RESERVED_SHIFT)
-
-	result.pps_info_flags |= pic->loopfilter << 5;
-	result.pps_info_flags |= pic->fastuvmc << 4;
-	result.pps_info_flags |= pic->extended_mv << 3;
-	result.pps_info_flags |= pic->dquant << 1;
-	result.pps_info_flags |= pic->vstransform << 0;
-	result.pps_info_flags |= pic->overlap << 11;
-	result.pps_info_flags |= pic->quantizer << 9;
-
+	result.chroma_format = 1;
 
 #if 0
+//(((unsigned int)(pPicParams->advance.reserved1))        << SPS_INFO_VC1_RESERVED_SHIFT)
 uint32_t 	slice_count
 uint8_t 	picture_type
 uint8_t 	frame_coding_mode
@@ -492,7 +498,6 @@ uint8_t 	deblockEnable
 uint8_t 	pquant
 #endif
 
-        result.chroma_format  = 1;
 	return result;
 }
 
-- 
1.8.1.2



More information about the mesa-dev mailing list