[vlc-devel] [PATCH] DxVA2: use the same surface count as libav/FFMpeg (v3)
Steve Lhomme
robux4 at videolabs.io
Tue Apr 21 09:34:20 CEST 2015
--
replaces previous patch 8074
replaces previous patch 8391 which was missing proper init for H264
---
modules/codec/avcodec/dxva2.c | 45 ++++++++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 16 deletions(-)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 830c100..d11a83e 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -374,7 +374,7 @@ static void DxDestroyVideoService(vlc_va_sys_t *);
static int DxFindVideoServiceConversion(vlc_va_t *, GUID *input, const d3d_format_t **output);
static int DxCreateVideoDecoder(vlc_va_t *,
- int codec_id, const video_format_t *);
+ int codec_id, const video_format_t *, bool);
static void DxDestroyVideoDecoder(vlc_va_sys_t *);
static int DxResetVideoDecoder(vlc_va_t *);
@@ -524,7 +524,7 @@ static int Setup(vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *chroma, pict
fmt.i_width = avctx->coded_width;
fmt.i_height = avctx->coded_height;
- if (DxCreateVideoDecoder(va, sys->codec_id, &fmt))
+ if (DxCreateVideoDecoder(va, sys->codec_id, &fmt, avctx->active_thread_type & FF_THREAD_FRAME))
return VLC_EGENERIC;
/* */
sys->hw.decoder = sys->decoder;
@@ -1182,10 +1182,12 @@ static int DxFindVideoServiceConversion(vlc_va_t *va, GUID *input, const d3d_for
/**
* It creates a DXVA2 decoder using the given video format
*/
-static int DxCreateVideoDecoder(vlc_va_t *va,
- int codec_id, const video_format_t *fmt)
+static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id,
+ const video_format_t *fmt, bool b_threading)
{
vlc_va_sys_t *sys = va->sys;
+ int surface_alignment = 16;
+ int surface_count = 4;
/* */
msg_Dbg(va, "DxCreateVideoDecoder id %d %dx%d",
@@ -1194,23 +1196,34 @@ static int DxCreateVideoDecoder(vlc_va_t *va,
sys->width = fmt->i_width;
sys->height = fmt->i_height;
- /* Allocates all surfaces needed for the decoder */
- sys->surface_width = (fmt->i_width + 15) & ~15;
- sys->surface_height = (fmt->i_height + 15) & ~15;
- int surface_count;
- switch (codec_id) {
+ switch ( codec_id )
+ {
+ case AV_CODEC_ID_MPEG2VIDEO:
+ /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
+ but it causes issues for H.264 on certain AMD GPUs..... */
+ surface_alignment = 32;
+ surface_count += 2;
+ break;
case AV_CODEC_ID_HEVC:
- case AV_CODEC_ID_H264:
- surface_count = 16 + sys->thread_count + 2;
+ /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure
+ all coding features have enough room to work with */
+ surface_alignment = 128;
+ surface_count += 16;
break;
- case AV_CODEC_ID_MPEG1VIDEO:
- case AV_CODEC_ID_MPEG2VIDEO:
- surface_count = 2 + 2;
+ case AV_CODEC_ID_H264:
+ surface_count += 16;
break;
default:
- surface_count = 2 + 1;
- break;
+ surface_count += 2;
}
+
+#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
+ sys->surface_width = ALIGN(fmt->i_width, surface_alignment);
+ sys->surface_height = ALIGN(fmt->i_height, surface_alignment);
+
+ if ( b_threading )
+ surface_count += sys->thread_count;
+
if (surface_count > VA_DXVA2_MAX_SURFACE_COUNT)
return VLC_EGENERIC;
sys->surface_count = surface_count;
--
2.3.0
More information about the vlc-devel
mailing list