[vlc-devel] [PATCH] DxVA2: allow NV12 pixel format all the way to the D3D texture
Steve Lhomme
robux4 at videolabs.io
Wed Apr 1 13:19:41 CEST 2015
Do not force YV12 out of DxVA using the costly SplitPlanes as NV12 is the
preferred format and will always comes with DxVA and the renderers
https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750%28v=vs.85%29.aspx#nv12
"NV12 is the preferred 4:2:0 pixel format for DirectX VA. It is expected to be an intermediate-term requirement for DirectX VA accelerators supporting 4:2:0 video."
It is also the only 4:2:0 format we can write to in D3D11
---
modules/codec/avcodec/dxva2.c | 18 ++++++++++++------
modules/video_chroma/copy.c | 29 ++++++++++++++++++++---------
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 3e1ff3b..f7530a3 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -392,9 +392,6 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
return VLC_EGENERIC;
/* */
- assert(sys->output == MAKEFOURCC('Y','V','1','2'));
-
- /* */
D3DLOCKED_RECT lock;
if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) {
msg_Err(va, "Failed to lock surface");
@@ -406,6 +403,8 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
bool imc3 = sys->render == MAKEFOURCC('I','M','C','3');
size_t chroma_pitch = imc3 ? lock.Pitch : (lock.Pitch / 2);
+ assert(sys->output == MAKEFOURCC('Y','V','1','2'));
+
size_t pitch[3] = {
lock.Pitch,
chroma_pitch,
@@ -436,8 +435,16 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
lock.Pitch,
lock.Pitch,
};
- CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
- &sys->surface_cache);
+ if( sys->output == MAKEFOURCC('Y','V','1','2') )
+ {
+ CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
+ &sys->surface_cache);
+ }
+ else if( sys->output == MAKEFOURCC('N','V','1','2') )
+ {
+ CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
+ &sys->surface_cache);
+ }
}
/* */
@@ -1032,7 +1039,6 @@ static int DxResetVideoDecoder(vlc_va_t *va)
static void DxCreateVideoConversion(vlc_va_sys_t *va)
{
switch (va->render) {
- case MAKEFOURCC('N','V','1','2'):
case MAKEFOURCC('I','M','C','3'):
va->output = MAKEFOURCC('Y','V','1','2');
break;
diff --git a/modules/video_chroma/copy.c b/modules/video_chroma/copy.c
index cc98c92..0291a0a 100644
--- a/modules/video_chroma/copy.c
+++ b/modules/video_chroma/copy.c
@@ -326,11 +326,17 @@ static void SSE_CopyFromNv12(picture_t *dst,
src[0], src_pitch[0],
cache->buffer, cache->size,
width, height, cpu);
- SSE_SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
- dst->p[1].p_pixels, dst->p[1].i_pitch,
- src[1], src_pitch[1],
- cache->buffer, cache->size,
- (width+1)/2, (height+1)/2, cpu);
+ if( dst->format.i_chroma == VLC_CODEC_NV12 )
+ SSE_CopyPlane(dst->p[1].p_pixels, dst->p[1].i_pitch,
+ src[1], src_pitch[1],
+ cache->buffer, cache->size,
+ width, height/2, cpu);
+ else
+ SSE_SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
+ dst->p[1].p_pixels, dst->p[1].i_pitch,
+ src[1], src_pitch[1],
+ cache->buffer, cache->size,
+ (width+1)/2, (height+1)/2, cpu);
asm volatile ("emms");
}
@@ -394,10 +400,15 @@ void CopyFromNv12(picture_t *dst, uint8_t *src[2], size_t src_pitch[2],
CopyPlane(dst->p[0].p_pixels, dst->p[0].i_pitch,
src[0], src_pitch[0],
width, height);
- SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
- dst->p[1].p_pixels, dst->p[1].i_pitch,
- src[1], src_pitch[1],
- width/2, height/2);
+ if( dst->format.i_chroma == VLC_CODEC_NV12 )
+ CopyPlane(dst->p[1].p_pixels, dst->p[1].i_pitch,
+ src[1], src_pitch[1],
+ width, height/2);
+ else
+ SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
+ dst->p[1].p_pixels, dst->p[1].i_pitch,
+ src[1], src_pitch[1],
+ width/2, height/2);
}
void CopyFromYv12(picture_t *dst, uint8_t *src[3], size_t src_pitch[3],
--
2.3.0
More information about the vlc-devel
mailing list