summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2013-10-09 02:23:48 +0200
committerChristian König <christian.koenig@amd.com>2013-10-09 13:02:40 +0200
commit5403dd4b6869cabcb8e2a0ed4d4f278983d1a15c (patch)
tree055c95ad7f5d9fa3b3ced3523143ba3a97e42537
parent0bb05484bff3ff4ec791c463ed1340572da4333c (diff)
radeon/uvd: try to fix VC-1 decoding
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. Reviewed-by: Christian König <christian.koenig@amd.com>
-rw-r--r--src/gallium/drivers/radeon/radeon_uvd.c71
1 files changed, 38 insertions, 33 deletions
diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
index 34650d4d19..da92ace57b 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;
}