Skip to content
Snippets Groups Projects
Commit 0c1c5146 authored by Aaron Levinson's avatar Aaron Levinson Committed by Mark Thompson
Browse files

avutil/hwcontext_dxva2: Don't improperly free IDirect3DSurface9 objects


Add dxva2_pool_release_dummy() and use it in call to
av_buffer_create() in dxva2_pool_alloc().

Prior to this change, av_buffer_create() was called with NULL for the
third argument, which indicates that av_buffer_default_free() should
be used to free the buffer's data.  Eventually, it gets to
buffer_pool_free() and calls buf->free() on a surface object (which is
av_buffer_default_free()).

This can result in a crash when the debug version of the C-runtime is
used on Windows.  While it doesn't appear to result in a crash when
the release version of the C-runtime is used on Windows, it likely
results in memory corruption, since av_free() is being called on
memory that was allocated using
IDirectXVideoAccelerationService::CreateSurface().

Signed-off-by: default avatarAaron Levinson <alevinsn@aracnet.com>
Reviewed-by: default avatarwm4 <nfxjfg@googlemail.com>
Reviewed-by: default avatarSteven Liu <lingjiujianke@gmail.com>
Reviewed-by: default avatarMark Thompson <sw@jkqxz.net>
parent 605c5ca3
No related branches found
No related tags found
No related merge requests found
...@@ -121,6 +121,13 @@ static void dxva2_frames_uninit(AVHWFramesContext *ctx) ...@@ -121,6 +121,13 @@ static void dxva2_frames_uninit(AVHWFramesContext *ctx)
} }
} }
static void dxva2_pool_release_dummy(void *opaque, uint8_t *data)
{
// important not to free anything here--data is a surface object
// associated with the call to CreateSurface(), and these surfaces are
// released in dxva2_frames_uninit()
}
static AVBufferRef *dxva2_pool_alloc(void *opaque, int size) static AVBufferRef *dxva2_pool_alloc(void *opaque, int size)
{ {
AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; AVHWFramesContext *ctx = (AVHWFramesContext*)opaque;
...@@ -130,7 +137,7 @@ static AVBufferRef *dxva2_pool_alloc(void *opaque, int size) ...@@ -130,7 +137,7 @@ static AVBufferRef *dxva2_pool_alloc(void *opaque, int size)
if (s->nb_surfaces_used < hwctx->nb_surfaces) { if (s->nb_surfaces_used < hwctx->nb_surfaces) {
s->nb_surfaces_used++; s->nb_surfaces_used++;
return av_buffer_create((uint8_t*)s->surfaces_internal[s->nb_surfaces_used - 1], return av_buffer_create((uint8_t*)s->surfaces_internal[s->nb_surfaces_used - 1],
sizeof(*hwctx->surfaces), NULL, 0, 0); sizeof(*hwctx->surfaces), dxva2_pool_release_dummy, 0, 0);
} }
return NULL; return NULL;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment