Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
35177ba7
Commit
35177ba7
authored
Apr 22, 2014
by
Hendrik Leppkes
Committed by
Anton Khirnov
Apr 28, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avconv: add support for DXVA2 decoding
Signed-off-by:
Anton Khirnov
<
anton@khirnov.net
>
parent
b2b4afe8
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
635 additions
and
0 deletions
+635
-0
Changelog
Changelog
+1
-0
Makefile
Makefile
+1
-0
avconv.h
avconv.h
+2
-0
avconv_dxva2.c
avconv_dxva2.c
+618
-0
avconv_opt.c
avconv_opt.c
+3
-0
configure
configure
+3
-0
avconv.texi
doc/avconv.texi
+7
-0
No files found.
Changelog
View file @
35177ba7
...
@@ -23,6 +23,7 @@ version <next>:
...
@@ -23,6 +23,7 @@ version <next>:
- Silicon Graphics Motion Video Compressor 1 & 2 decoder
- Silicon Graphics Motion Video Compressor 1 & 2 decoder
- Silicon Graphics Movie demuxer
- Silicon Graphics Movie demuxer
- On2 AVC (Audio for Video) decoder
- On2 AVC (Audio for Video) decoder
- support for decoding through DXVA2 in avconv
version 10:
version 10:
...
...
Makefile
View file @
35177ba7
...
@@ -75,6 +75,7 @@ $(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
...
@@ -75,6 +75,7 @@ $(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
OBJS-avconv
+=
avconv_opt.o avconv_filter.o
OBJS-avconv
+=
avconv_opt.o avconv_filter.o
OBJS-avconv-$(HAVE_VDPAU_X11)
+=
avconv_vdpau.o
OBJS-avconv-$(HAVE_VDPAU_X11)
+=
avconv_vdpau.o
OBJS-avconv-$(CONFIG_DXVA2)
+=
avconv_dxva2.o
TESTTOOLS
=
audiogen videogen rotozoom tiny_psnr
base64
TESTTOOLS
=
audiogen videogen rotozoom tiny_psnr
base64
HOSTPROGS
:=
$
(
TESTTOOLS:%
=
tests/%
)
doc/print_options
HOSTPROGS
:=
$
(
TESTTOOLS:%
=
tests/%
)
doc/print_options
...
...
avconv.h
View file @
35177ba7
...
@@ -52,6 +52,7 @@ enum HWAccelID {
...
@@ -52,6 +52,7 @@ enum HWAccelID {
HWACCEL_NONE
=
0
,
HWACCEL_NONE
=
0
,
HWACCEL_AUTO
,
HWACCEL_AUTO
,
HWACCEL_VDPAU
,
HWACCEL_VDPAU
,
HWACCEL_DXVA2
,
};
};
typedef
struct
HWAccel
{
typedef
struct
HWAccel
{
...
@@ -421,5 +422,6 @@ FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
...
@@ -421,5 +422,6 @@ FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
int
avconv_parse_options
(
int
argc
,
char
**
argv
);
int
avconv_parse_options
(
int
argc
,
char
**
argv
);
int
vdpau_init
(
AVCodecContext
*
s
);
int
vdpau_init
(
AVCodecContext
*
s
);
int
dxva2_init
(
AVCodecContext
*
s
);
#endif
/* AVCONV_H */
#endif
/* AVCONV_H */
avconv_dxva2.c
0 → 100644
View file @
35177ba7
/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <windows.h>
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#define DXVA2API_USE_BITFIELDS
#define COBJMACROS
#include <stdint.h>
/* initguid.h needs to be above d3d/dxva to ensure
the GUIDs are initialized properly */
#include <initguid.h>
#include <d3d9.h>
#include <dxva2api.h>
#include "avconv.h"
#include "libavcodec/dxva2.h"
#include "libavutil/avassert.h"
#include "libavutil/buffer.h"
#include "libavutil/frame.h"
#include "libavutil/imgutils.h"
#include "libavutil/pixfmt.h"
typedef
IDirect3D9
*
WINAPI
pDirect3DCreate9
(
UINT
);
typedef
HRESULT
WINAPI
pCreateDeviceManager9
(
UINT
*
,
IDirect3DDeviceManager9
**
);
/* GUIDs not defined in the common dxva2api.h in mingw-w64 */
#ifndef _MSC_VER
DEFINE_GUID
(
DXVA2_ModeMPEG2and1_VLD
,
0x86695f12
,
0x340e
,
0x4f04
,
0x9f
,
0xd3
,
0x92
,
0x53
,
0xdd
,
0x32
,
0x74
,
0x60
);
DEFINE_GUID
(
DXVA2_ModeVC1_D2010
,
0x1b81beA4
,
0xa0c7
,
0x11d3
,
0xb9
,
0x84
,
0x00
,
0xc0
,
0x4f
,
0x2e
,
0x73
,
0xc5
);
DEFINE_GUID
(
DXVA2_NoEncrypt
,
0x1b81beD0
,
0xa0c7
,
0x11d3
,
0xb9
,
0x84
,
0x00
,
0xc0
,
0x4f
,
0x2e
,
0x73
,
0xc5
);
#endif
DEFINE_GUID
(
DXVADDI_Intel_ModeH264_E
,
0x604F8E68
,
0x4951
,
0x4C54
,
0x88
,
0xFE
,
0xAB
,
0xD2
,
0x5C
,
0x15
,
0xB3
,
0xD6
);
DEFINE_GUID
(
GUID_NULL
,
0x00000000
,
0x0000
,
0x0000
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
);
typedef
struct
dxva2_mode
{
const
GUID
*
guid
;
enum
AVCodecID
codec
;
}
dxva2_mode
;
static
const
dxva2_mode
dxva2_modes
[]
=
{
/* MPEG-2 */
{
&
DXVA2_ModeMPEG2_VLD
,
AV_CODEC_ID_MPEG2VIDEO
},
{
&
DXVA2_ModeMPEG2and1_VLD
,
AV_CODEC_ID_MPEG2VIDEO
},
/* H.264 */
{
&
DXVA2_ModeH264_F
,
AV_CODEC_ID_H264
},
{
&
DXVA2_ModeH264_E
,
AV_CODEC_ID_H264
},
/* Intel specific H.264 mode */
{
&
DXVADDI_Intel_ModeH264_E
,
AV_CODEC_ID_H264
},
/* VC-1 / WMV3 */
{
&
DXVA2_ModeVC1_D2010
,
AV_CODEC_ID_VC1
},
{
&
DXVA2_ModeVC1_D2010
,
AV_CODEC_ID_WMV3
},
{
&
DXVA2_ModeVC1_D
,
AV_CODEC_ID_VC1
},
{
&
DXVA2_ModeVC1_D
,
AV_CODEC_ID_WMV3
},
{
NULL
,
0
},
};
typedef
struct
surface_info
{
int
used
;
uint64_t
age
;
}
surface_info
;
typedef
struct
DXVA2Context
{
HMODULE
d3dlib
;
HMODULE
dxva2lib
;
HANDLE
deviceHandle
;
IDirect3D9
*
d3d9
;
IDirect3DDevice9
*
d3d9device
;
IDirect3DDeviceManager9
*
d3d9devmgr
;
IDirectXVideoDecoderService
*
decoder_service
;
IDirectXVideoDecoder
*
decoder
;
GUID
decoder_guid
;
DXVA2_ConfigPictureDecode
decoder_config
;
LPDIRECT3DSURFACE9
*
surfaces
;
surface_info
*
surface_infos
;
uint32_t
num_surfaces
;
uint64_t
surface_age
;
AVFrame
*
tmp_frame
;
}
DXVA2Context
;
typedef
struct
DXVA2SurfaceWrapper
{
DXVA2Context
*
ctx
;
LPDIRECT3DSURFACE9
surface
;
IDirectXVideoDecoder
*
decoder
;
}
DXVA2SurfaceWrapper
;
static
void
dxva2_destroy_decoder
(
AVCodecContext
*
s
)
{
InputStream
*
ist
=
s
->
opaque
;
DXVA2Context
*
ctx
=
ist
->
hwaccel_ctx
;
if
(
ctx
->
surfaces
)
{
for
(
int
i
=
0
;
i
<
ctx
->
num_surfaces
;
i
++
)
{
if
(
ctx
->
surfaces
[
i
])
IDirect3DSurface9_Release
(
ctx
->
surfaces
[
i
]);
}
}
av_freep
(
&
ctx
->
surfaces
);
av_freep
(
&
ctx
->
surface_infos
);
ctx
->
num_surfaces
=
0
;
ctx
->
surface_age
=
0
;
if
(
ctx
->
decoder
)
{
IDirectXVideoDecoder_Release
(
ctx
->
decoder
);
ctx
->
decoder
=
NULL
;
}
}
static
void
dxva2_uninit
(
AVCodecContext
*
s
)
{
InputStream
*
ist
=
s
->
opaque
;
DXVA2Context
*
ctx
=
ist
->
hwaccel_ctx
;
ist
->
hwaccel_uninit
=
NULL
;
ist
->
hwaccel_get_buffer
=
NULL
;
ist
->
hwaccel_retrieve_data
=
NULL
;
if
(
ctx
->
decoder
)
dxva2_destroy_decoder
(
s
);
if
(
ctx
->
decoder_service
)
IDirectXVideoDecoderService_Release
(
ctx
->
decoder_service
);
if
(
ctx
->
d3d9devmgr
&&
ctx
->
deviceHandle
!=
INVALID_HANDLE_VALUE
)
IDirect3DDeviceManager9_CloseDeviceHandle
(
ctx
->
d3d9devmgr
,
ctx
->
deviceHandle
);
if
(
ctx
->
d3d9devmgr
)
IDirect3DDeviceManager9_Release
(
ctx
->
d3d9devmgr
);
if
(
ctx
->
d3d9device
)
IDirect3DDevice9_Release
(
ctx
->
d3d9device
);
if
(
ctx
->
d3d9
)
IDirect3D9_Release
(
ctx
->
d3d9
);
if
(
ctx
->
d3dlib
)
FreeLibrary
(
ctx
->
d3dlib
);
if
(
ctx
->
dxva2lib
)
FreeLibrary
(
ctx
->
dxva2lib
);
av_frame_free
(
&
ctx
->
tmp_frame
);
av_freep
(
&
ist
->
hwaccel_ctx
);
av_freep
(
&
s
->
hwaccel_context
);
}
static
void
dxva2_release_buffer
(
void
*
opaque
,
uint8_t
*
data
)
{
DXVA2SurfaceWrapper
*
w
=
opaque
;
DXVA2Context
*
ctx
=
w
->
ctx
;
int
i
;
for
(
i
=
0
;
i
<
ctx
->
num_surfaces
;
i
++
)
{
if
(
ctx
->
surfaces
[
i
]
==
w
->
surface
)
{
ctx
->
surface_infos
[
i
].
used
=
0
;
break
;
}
}
IDirect3DSurface9_Release
(
w
->
surface
);
IDirectXVideoDecoder_Release
(
w
->
decoder
);
av_free
(
w
);
}
static
int
dxva2_get_buffer
(
AVCodecContext
*
s
,
AVFrame
*
frame
,
int
flags
)
{
InputStream
*
ist
=
s
->
opaque
;
DXVA2Context
*
ctx
=
ist
->
hwaccel_ctx
;
int
i
,
old_unused
=
-
1
;
LPDIRECT3DSURFACE9
surface
;
DXVA2SurfaceWrapper
*
w
=
NULL
;
av_assert0
(
frame
->
format
==
AV_PIX_FMT_DXVA2_VLD
);
for
(
i
=
0
;
i
<
ctx
->
num_surfaces
;
i
++
)
{
surface_info
*
info
=
&
ctx
->
surface_infos
[
i
];
if
(
!
info
->
used
&&
(
old_unused
==
-
1
||
info
->
age
<
ctx
->
surface_infos
[
old_unused
].
age
))
old_unused
=
i
;
}
if
(
old_unused
==
-
1
)
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"No free DXVA2 surface!
\n
"
);
return
AVERROR
(
ENOMEM
);
}
i
=
old_unused
;
surface
=
ctx
->
surfaces
[
i
];
w
=
av_mallocz
(
sizeof
(
*
w
));
if
(
!
w
)
return
AVERROR
(
ENOMEM
);
frame
->
buf
[
0
]
=
av_buffer_create
((
uint8_t
*
)
surface
,
0
,
dxva2_release_buffer
,
w
,
AV_BUFFER_FLAG_READONLY
);
if
(
!
frame
->
buf
[
0
])
{
av_free
(
w
);
return
AVERROR
(
ENOMEM
);
}
w
->
ctx
=
ctx
;
w
->
surface
=
surface
;
IDirect3DSurface9_AddRef
(
w
->
surface
);
w
->
decoder
=
ctx
->
decoder
;
IDirectXVideoDecoder_AddRef
(
w
->
decoder
);
ctx
->
surface_infos
[
i
].
used
=
1
;
ctx
->
surface_infos
[
i
].
age
=
ctx
->
surface_age
++
;
frame
->
data
[
3
]
=
(
uint8_t
*
)
surface
;
return
0
;
}
static
int
dxva2_retrieve_data
(
AVCodecContext
*
s
,
AVFrame
*
frame
)
{
LPDIRECT3DSURFACE9
surface
=
(
LPDIRECT3DSURFACE9
)
frame
->
data
[
3
];
InputStream
*
ist
=
s
->
opaque
;
DXVA2Context
*
ctx
=
ist
->
hwaccel_ctx
;
D3DSURFACE_DESC
surfaceDesc
;
D3DLOCKED_RECT
LockedRect
;
HRESULT
hr
;
int
ret
;
IDirect3DSurface9_GetDesc
(
surface
,
&
surfaceDesc
);
ctx
->
tmp_frame
->
width
=
frame
->
width
;
ctx
->
tmp_frame
->
height
=
frame
->
height
;
ctx
->
tmp_frame
->
format
=
AV_PIX_FMT_NV12
;
ret
=
av_frame_get_buffer
(
ctx
->
tmp_frame
,
32
);
if
(
ret
<
0
)
return
ret
;
hr
=
IDirect3DSurface9_LockRect
(
surface
,
&
LockedRect
,
NULL
,
D3DLOCK_READONLY
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"Unable to lock DXVA2 surface
\n
"
);
return
AVERROR_UNKNOWN
;
}
av_image_copy_plane
(
ctx
->
tmp_frame
->
data
[
0
],
ctx
->
tmp_frame
->
linesize
[
0
],
(
uint8_t
*
)
LockedRect
.
pBits
,
LockedRect
.
Pitch
,
frame
->
width
,
frame
->
height
);
av_image_copy_plane
(
ctx
->
tmp_frame
->
data
[
1
],
ctx
->
tmp_frame
->
linesize
[
1
],
(
uint8_t
*
)
LockedRect
.
pBits
+
LockedRect
.
Pitch
*
surfaceDesc
.
Height
,
LockedRect
.
Pitch
,
frame
->
width
,
frame
->
height
/
2
);
IDirect3DSurface9_UnlockRect
(
surface
);
ret
=
av_frame_copy_props
(
ctx
->
tmp_frame
,
frame
);
if
(
ret
<
0
)
goto
fail
;
av_frame_unref
(
frame
);
av_frame_move_ref
(
frame
,
ctx
->
tmp_frame
);
return
0
;
fail:
av_frame_unref
(
ctx
->
tmp_frame
);
return
ret
;
}
static
int
dxva2_alloc
(
AVCodecContext
*
s
)
{
InputStream
*
ist
=
s
->
opaque
;
int
loglevel
=
(
ist
->
hwaccel_id
==
HWACCEL_AUTO
)
?
AV_LOG_VERBOSE
:
AV_LOG_ERROR
;
DXVA2Context
*
ctx
;
pDirect3DCreate9
*
createD3D
=
NULL
;
pCreateDeviceManager9
*
createDeviceManager
=
NULL
;
HRESULT
hr
;
D3DPRESENT_PARAMETERS
d3dpp
=
{
0
};
D3DDISPLAYMODE
d3ddm
;
unsigned
resetToken
=
0
;
UINT
adapter
=
D3DADAPTER_DEFAULT
;
ctx
=
av_mallocz
(
sizeof
(
*
ctx
));
if
(
!
ctx
)
return
AVERROR
(
ENOMEM
);
ctx
->
deviceHandle
=
INVALID_HANDLE_VALUE
;
ist
->
hwaccel_ctx
=
ctx
;
ist
->
hwaccel_uninit
=
dxva2_uninit
;
ist
->
hwaccel_get_buffer
=
dxva2_get_buffer
;
ist
->
hwaccel_retrieve_data
=
dxva2_retrieve_data
;
ctx
->
d3dlib
=
LoadLibrary
(
"d3d9.dll"
);
if
(
!
ctx
->
d3dlib
)
{
av_log
(
NULL
,
loglevel
,
"Failed to load D3D9 library
\n
"
);
goto
fail
;
}
ctx
->
dxva2lib
=
LoadLibrary
(
"dxva2.dll"
);
if
(
!
ctx
->
dxva2lib
)
{
av_log
(
NULL
,
loglevel
,
"Failed to load DXVA2 library
\n
"
);
goto
fail
;
}
createD3D
=
(
pDirect3DCreate9
*
)
GetProcAddress
(
ctx
->
d3dlib
,
"Direct3DCreate9"
);
if
(
!
createD3D
)
{
av_log
(
NULL
,
loglevel
,
"Failed to locate Direct3DCreate9
\n
"
);
goto
fail
;
}
createDeviceManager
=
(
pCreateDeviceManager9
*
)
GetProcAddress
(
ctx
->
dxva2lib
,
"DXVA2CreateDirect3DDeviceManager9"
);
if
(
!
createDeviceManager
)
{
av_log
(
NULL
,
loglevel
,
"Failed to locate DXVA2CreateDirect3DDeviceManager9
\n
"
);
goto
fail
;
}
ctx
->
d3d9
=
createD3D
(
D3D_SDK_VERSION
);
if
(
!
ctx
->
d3d9
)
{
av_log
(
NULL
,
loglevel
,
"Failed to create IDirect3D object
\n
"
);
goto
fail
;
}
if
(
ist
->
hwaccel_device
)
{
adapter
=
atoi
(
ist
->
hwaccel_device
);
av_log
(
NULL
,
AV_LOG_INFO
,
"Using HWAccel device %d
\n
"
,
adapter
);
}
IDirect3D9_GetAdapterDisplayMode
(
ctx
->
d3d9
,
adapter
,
&
d3ddm
);
d3dpp
.
Windowed
=
TRUE
;
d3dpp
.
BackBufferWidth
=
640
;
d3dpp
.
BackBufferHeight
=
480
;
d3dpp
.
BackBufferCount
=
0
;
d3dpp
.
BackBufferFormat
=
d3ddm
.
Format
;
d3dpp
.
SwapEffect
=
D3DSWAPEFFECT_DISCARD
;
d3dpp
.
Flags
=
D3DPRESENTFLAG_VIDEO
;
hr
=
IDirect3D9_CreateDevice
(
ctx
->
d3d9
,
adapter
,
D3DDEVTYPE_HAL
,
GetShellWindow
(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING
|
D3DCREATE_MULTITHREADED
|
D3DCREATE_FPU_PRESERVE
,
&
d3dpp
,
&
ctx
->
d3d9device
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to create Direct3D device
\n
"
);
goto
fail
;
}
hr
=
createDeviceManager
(
&
resetToken
,
&
ctx
->
d3d9devmgr
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to create Direct3D device manager
\n
"
);
goto
fail
;
}
hr
=
IDirect3DDeviceManager9_ResetDevice
(
ctx
->
d3d9devmgr
,
ctx
->
d3d9device
,
resetToken
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to bind Direct3D device to device manager
\n
"
);
goto
fail
;
}
hr
=
IDirect3DDeviceManager9_OpenDeviceHandle
(
ctx
->
d3d9devmgr
,
&
ctx
->
deviceHandle
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to open device handle
\n
"
);
goto
fail
;
}
hr
=
IDirect3DDeviceManager9_GetVideoService
(
ctx
->
d3d9devmgr
,
ctx
->
deviceHandle
,
&
IID_IDirectXVideoDecoderService
,
(
void
**
)
&
ctx
->
decoder_service
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to create IDirectXVideoDecoderService
\n
"
);
goto
fail
;
}
ctx
->
tmp_frame
=
av_frame_alloc
();
if
(
!
ctx
->
tmp_frame
)
goto
fail
;
s
->
hwaccel_context
=
av_mallocz
(
sizeof
(
struct
dxva_context
));
if
(
!
s
->
hwaccel_context
)
goto
fail
;
return
0
;
fail:
dxva2_uninit
(
s
);
return
AVERROR
(
EINVAL
);
}
static
int
dxva2_get_decoder_configuration
(
AVCodecContext
*
s
,
const
GUID
*
device_guid
,
const
DXVA2_VideoDesc
*
desc
,
DXVA2_ConfigPictureDecode
*
config
)
{
InputStream
*
ist
=
s
->
opaque
;
int
loglevel
=
(
ist
->
hwaccel_id
==
HWACCEL_AUTO
)
?
AV_LOG_VERBOSE
:
AV_LOG_ERROR
;
DXVA2Context
*
ctx
=
ist
->
hwaccel_ctx
;
unsigned
cfg_count
=
0
,
best_score
=
0
;
DXVA2_ConfigPictureDecode
*
cfg_list
=
NULL
;
DXVA2_ConfigPictureDecode
best_cfg
=
{{
0
}};
HRESULT
hr
;
int
i
;
hr
=
IDirectXVideoDecoderService_GetDecoderConfigurations
(
ctx
->
decoder_service
,
device_guid
,
desc
,
NULL
,
&
cfg_count
,
&
cfg_list
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Unable to retrieve decoder configurations
\n
"
);
return
AVERROR
(
EINVAL
);
}
for
(
i
=
0
;
i
<
cfg_count
;
i
++
)
{
DXVA2_ConfigPictureDecode
*
cfg
=
&
cfg_list
[
i
];
unsigned
score
;
if
(
cfg
->
ConfigBitstreamRaw
==
1
)
score
=
1
;
else
if
(
s
->
codec_id
==
AV_CODEC_ID_H264
&&
cfg
->
ConfigBitstreamRaw
==
2
)
score
=
2
;
else
continue
;
if
(
IsEqualGUID
(
&
cfg
->
guidConfigBitstreamEncryption
,
&
DXVA2_NoEncrypt
))
score
+=
16
;
if
(
score
>
best_score
)
{
best_score
=
score
;
best_cfg
=
*
cfg
;
}
}
CoTaskMemFree
(
cfg_list
);
if
(
!
best_score
)
{
av_log
(
NULL
,
loglevel
,
"No valid decoder configuration available
\n
"
);
return
AVERROR
(
EINVAL
);
}
*
config
=
best_cfg
;
return
0
;
}
static
int
dxva2_create_decoder
(
AVCodecContext
*
s
)
{
InputStream
*
ist
=
s
->
opaque
;
int
loglevel
=
(
ist
->
hwaccel_id
==
HWACCEL_AUTO
)
?
AV_LOG_VERBOSE
:
AV_LOG_ERROR
;
DXVA2Context
*
ctx
=
ist
->
hwaccel_ctx
;
struct
dxva_context
*
dxva_ctx
=
s
->
hwaccel_context
;
GUID
*
guid_list
=
NULL
;
unsigned
guid_count
=
0
,
i
,
j
;
GUID
device_guid
=
GUID_NULL
;
D3DFORMAT
target_format
=
0
;
DXVA2_VideoDesc
desc
=
{
0
};
DXVA2_ConfigPictureDecode
config
;
HRESULT
hr
;
int
surface_alignment
;
int
ret
;
hr
=
IDirectXVideoDecoderService_GetDecoderDeviceGuids
(
ctx
->
decoder_service
,
&
guid_count
,
&
guid_list
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to retrieve decoder device GUIDs
\n
"
);
goto
fail
;
}
for
(
i
=
0
;
dxva2_modes
[
i
].
guid
;
i
++
)
{
D3DFORMAT
*
target_list
=
NULL
;
unsigned
target_count
=
0
;
const
dxva2_mode
*
mode
=
&
dxva2_modes
[
i
];
if
(
mode
->
codec
!=
s
->
codec_id
)
continue
;
for
(
j
=
0
;
j
<
guid_count
;
j
++
)
{
if
(
IsEqualGUID
(
mode
->
guid
,
&
guid_list
[
j
]))
break
;
}
if
(
j
==
guid_count
)
continue
;
hr
=
IDirectXVideoDecoderService_GetDecoderRenderTargets
(
ctx
->
decoder_service
,
mode
->
guid
,
&
target_count
,
&
target_list
);
if
(
FAILED
(
hr
))
{
continue
;
}
for
(
j
=
0
;
j
<
target_count
;
j
++
)
{
const
D3DFORMAT
format
=
target_list
[
j
];
if
(
format
==
MKTAG
(
'N'
,
'V'
,
'1'
,
'2'
))
{
target_format
=
format
;
break
;
}
}
CoTaskMemFree
(
target_list
);
if
(
target_format
)
{
device_guid
=
*
mode
->
guid
;
break
;
}
}
CoTaskMemFree
(
guid_list
);
if
(
IsEqualGUID
(
&
device_guid
,
&
GUID_NULL
))
{
av_log
(
NULL
,
loglevel
,
"No decoder device for codec found
\n
"
);
goto
fail
;
}
desc
.
SampleWidth
=
s
->
coded_width
;
desc
.
SampleHeight
=
s
->
coded_height
;
desc
.
Format
=
target_format
;
ret
=
dxva2_get_decoder_configuration
(
s
,
&
device_guid
,
&
desc
,
&
config
);
if
(
ret
<
0
)
{
goto
fail
;
}
/* decoding MPEG-2 requires additional alignment on some Intel GPUs,
but it causes issues for H.264 on certain AMD GPUs..... */
if
(
s
->
codec_id
==
AV_CODEC_ID_MPEG2VIDEO
)
surface_alignment
=
32
;
else
surface_alignment
=
16
;
/* 4 base work surfaces */
ctx
->
num_surfaces
=
4
;
/* add surfaces based on number of possible refs */
if
(
s
->
codec_id
==
AV_CODEC_ID_H264
)
ctx
->
num_surfaces
+=
16
;
else
ctx
->
num_surfaces
+=
2
;
/* add extra surfaces for frame threading */
if
(
s
->
active_thread_type
&
FF_THREAD_FRAME
)
ctx
->
num_surfaces
+=
s
->
thread_count
;
ctx
->
surfaces
=
av_mallocz
(
ctx
->
num_surfaces
*
sizeof
(
*
ctx
->
surfaces
));
ctx
->
surface_infos
=
av_mallocz
(
ctx
->
num_surfaces
*
sizeof
(
*
ctx
->
surface_infos
));
if
(
!
ctx
->
surfaces
||
!
ctx
->
surface_infos
)
{
av_log
(
NULL
,
loglevel
,
"Unable to allocate surface arrays
\n
"
);
goto
fail
;
}
hr
=
IDirectXVideoDecoderService_CreateSurface
(
ctx
->
decoder_service
,
FFALIGN
(
s
->
coded_width
,
surface_alignment
),
FFALIGN
(
s
->
coded_height
,
surface_alignment
),
ctx
->
num_surfaces
-
1
,
target_format
,
D3DPOOL_DEFAULT
,
0
,
DXVA2_VideoDecoderRenderTarget
,
ctx
->
surfaces
,
NULL
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to create %d video surfaces
\n
"
,
ctx
->
num_surfaces
);
goto
fail
;
}
hr
=
IDirectXVideoDecoderService_CreateVideoDecoder
(
ctx
->
decoder_service
,
&
device_guid
,
&
desc
,
&
config
,
ctx
->
surfaces
,
ctx
->
num_surfaces
,
&
ctx
->
decoder
);
if
(
FAILED
(
hr
))
{
av_log
(
NULL
,
loglevel
,
"Failed to create DXVA2 video decoder
\n
"
);
goto
fail
;
}
ctx
->
decoder_guid
=
device_guid
;
ctx
->
decoder_config
=
config
;
dxva_ctx
->
cfg
=
&
ctx
->
decoder_config
;
dxva_ctx
->
decoder
=
ctx
->
decoder
;
dxva_ctx
->
surface
=
ctx
->
surfaces
;
dxva_ctx
->
surface_count
=
ctx
->
num_surfaces
;
if
(
IsEqualGUID
(
&
ctx
->
decoder_guid
,
&
DXVADDI_Intel_ModeH264_E
))
dxva_ctx
->
workaround
|=
FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
;
return
0
;
fail:
dxva2_destroy_decoder
(
s
);
return
AVERROR
(
EINVAL
);
}
int
dxva2_init
(
AVCodecContext
*
s
)
{
InputStream
*
ist
=
s
->
opaque
;
int
loglevel
=
(
ist
->
hwaccel_id
==
HWACCEL_AUTO
)
?
AV_LOG_VERBOSE
:
AV_LOG_ERROR
;
DXVA2Context
*
ctx
;
int
ret
;
if
(
!
ist
->
hwaccel_ctx
)
{
ret
=
dxva2_alloc
(
s
);
if
(
ret
<
0
)
return
ret
;
}
ctx
=
ist
->
hwaccel_ctx
;
if
(
s
->
codec_id
==
AV_CODEC_ID_H264
&&
(
s
->
profile
&
~
FF_PROFILE_H264_CONSTRAINED
)
>
FF_PROFILE_H264_HIGH
)
{
av_log
(
NULL
,
loglevel
,
"Unsupported H.264 profile for DXVA2 HWAccel: %d
\n
"
,
s
->
profile
);
return
AVERROR
(
EINVAL
);
}
if
(
ctx
->
decoder
)
dxva2_destroy_decoder
(
s
);
ret
=
dxva2_create_decoder
(
s
);
if
(
ret
<
0
)
{
av_log
(
NULL
,
loglevel
,
"Error creating the DXVA2 decoder
\n
"
);
return
ret
;
}
return
0
;
}
avconv_opt.c
View file @
35177ba7
...
@@ -56,6 +56,9 @@
...
@@ -56,6 +56,9 @@
const
HWAccel
hwaccels
[]
=
{
const
HWAccel
hwaccels
[]
=
{
#if HAVE_VDPAU_X11
#if HAVE_VDPAU_X11
{
"vdpau"
,
vdpau_init
,
HWACCEL_VDPAU
,
AV_PIX_FMT_VDPAU
},
{
"vdpau"
,
vdpau_init
,
HWACCEL_VDPAU
,
AV_PIX_FMT_VDPAU
},
#endif
#if CONFIG_DXVA2
{
"dxva2"
,
dxva2_init
,
HWACCEL_DXVA2
,
AV_PIX_FMT_DXVA2_VLD
},
#endif
#endif
{
0
},
{
0
},
};
};
...
...
configure
View file @
35177ba7
...
@@ -4146,6 +4146,9 @@ enabled vdpau && enabled xlib &&
...
@@ -4146,6 +4146,9 @@ enabled vdpau && enabled xlib &&
prepend avconv_libs
$(
$ldflags_filter
"-lvdpau"
)
&&
prepend avconv_libs
$(
$ldflags_filter
"-lvdpau"
)
&&
enable
vdpau_x11
enable
vdpau_x11
enabled dxva2
&&
prepend avconv_libs
$(
$ldflags_filter
"-lole32"
)
enabled debug
&&
add_cflags
-g
"
$debuglevel
"
&&
add_asflags
-g
"
$debuglevel
"
enabled debug
&&
add_cflags
-g
"
$debuglevel
"
&&
add_asflags
-g
"
$debuglevel
"
# add some useful compiler flags if supported
# add some useful compiler flags if supported
...
...
doc/avconv.texi
View file @
35177ba7
...
@@ -582,6 +582,9 @@ Automatically select the hardware acceleration method.
...
@@ -582,6 +582,9 @@ Automatically select the hardware acceleration method.
@item vdpau
@item vdpau
Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration.
Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration.
@item dxva2
Use DXVA2 (DirectX Video Acceleration) hardware acceleration.
@end table
@end table
This option has no effect if the selected hwaccel is not available or not
This option has no effect if the selected hwaccel is not available or not
...
@@ -604,6 +607,10 @@ method chosen.
...
@@ -604,6 +607,10 @@ method chosen.
@item vdpau
@item vdpau
For VDPAU, this option specifies the X11 display/screen to use. If this option
For VDPAU, this option specifies the X11 display/screen to use. If this option
is not specified, the value of the @var
{
DISPLAY
}
environment variable is used
is not specified, the value of the @var
{
DISPLAY
}
environment variable is used
@item dxva2
For DXVA2, this option should contain the number of the display adapter to use.
If this option is not specified, the default adapter is used.
@end table
@end table
@end table
@end table
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment