Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
a0524d9b
Commit
a0524d9b
authored
May 27, 2016
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
qsvdec: support getting the session from an AVHWFramesContext
parent
59e7361c
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
268 additions
and
51 deletions
+268
-51
qsv.c
libavcodec/qsv.c
+201
-39
qsv_internal.h
libavcodec/qsv_internal.h
+11
-0
qsvdec.c
libavcodec/qsvdec.c
+54
-8
qsvdec.h
libavcodec/qsvdec.h
+2
-0
qsvdec_h2645.c
libavcodec/qsvdec_h2645.c
+0
-2
qsvdec_mpeg2.c
libavcodec/qsvdec_mpeg2.c
+0
-2
No files found.
libavcodec/qsv.c
View file @
a0524d9b
...
@@ -25,7 +25,10 @@
...
@@ -25,7 +25,10 @@
#include <string.h>
#include <string.h>
#include "libavutil/avstring.h"
#include "libavutil/avstring.h"
#include "libavutil/common.h"
#include "libavutil/error.h"
#include "libavutil/error.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_qsv.h"
#include "avcodec.h"
#include "avcodec.h"
#include "qsv_internal.h"
#include "qsv_internal.h"
...
@@ -86,6 +89,56 @@ int ff_qsv_error(int mfx_err)
...
@@ -86,6 +89,56 @@ int ff_qsv_error(int mfx_err)
}
}
}
}
static
int
qsv_load_plugins
(
mfxSession
session
,
const
char
*
load_plugins
,
void
*
logctx
)
{
if
(
!
load_plugins
||
!*
load_plugins
)
return
0
;
while
(
*
load_plugins
)
{
mfxPluginUID
uid
;
mfxStatus
ret
;
int
i
,
err
=
0
;
char
*
plugin
=
av_get_token
(
&
load_plugins
,
":"
);
if
(
!
plugin
)
return
AVERROR
(
ENOMEM
);
if
(
strlen
(
plugin
)
!=
2
*
sizeof
(
uid
.
Data
))
{
av_log
(
logctx
,
AV_LOG_ERROR
,
"Invalid plugin UID length
\n
"
);
err
=
AVERROR
(
EINVAL
);
goto
load_plugin_fail
;
}
for
(
i
=
0
;
i
<
sizeof
(
uid
.
Data
);
i
++
)
{
err
=
sscanf
(
plugin
+
2
*
i
,
"%2hhx"
,
uid
.
Data
+
i
);
if
(
err
!=
1
)
{
av_log
(
logctx
,
AV_LOG_ERROR
,
"Invalid plugin UID
\n
"
);
err
=
AVERROR
(
EINVAL
);
goto
load_plugin_fail
;
}
}
ret
=
MFXVideoUSER_Load
(
session
,
&
uid
,
1
);
if
(
ret
<
0
)
{
av_log
(
logctx
,
AV_LOG_ERROR
,
"Could not load the requested plugin: %s
\n
"
,
plugin
);
err
=
ff_qsv_error
(
ret
);
goto
load_plugin_fail
;
}
if
(
*
load_plugins
)
load_plugins
++
;
load_plugin_fail:
av_freep
(
&
plugin
);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
int
ff_qsv_init_internal_session
(
AVCodecContext
*
avctx
,
mfxSession
*
session
,
int
ff_qsv_init_internal_session
(
AVCodecContext
*
avctx
,
mfxSession
*
session
,
const
char
*
load_plugins
)
const
char
*
load_plugins
)
{
{
...
@@ -101,45 +154,10 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
...
@@ -101,45 +154,10 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
return
ff_qsv_error
(
ret
);
return
ff_qsv_error
(
ret
);
}
}
if
(
load_plugins
&&
*
load_plugins
)
{
ret
=
qsv_load_plugins
(
*
session
,
load_plugins
,
avctx
);
while
(
*
load_plugins
)
{
if
(
ret
<
0
)
{
mfxPluginUID
uid
;
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error loading plugins
\n
"
);
int
i
,
err
=
0
;
return
ret
;
char
*
plugin
=
av_get_token
(
&
load_plugins
,
":"
);
if
(
!
plugin
)
return
AVERROR
(
ENOMEM
);
if
(
strlen
(
plugin
)
!=
2
*
sizeof
(
uid
.
Data
))
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Invalid plugin UID length
\n
"
);
err
=
AVERROR
(
EINVAL
);
goto
load_plugin_fail
;
}
for
(
i
=
0
;
i
<
sizeof
(
uid
.
Data
);
i
++
)
{
err
=
sscanf
(
plugin
+
2
*
i
,
"%2hhx"
,
uid
.
Data
+
i
);
if
(
err
!=
1
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Invalid plugin UID
\n
"
);
err
=
AVERROR
(
EINVAL
);
goto
load_plugin_fail
;
}
}
ret
=
MFXVideoUSER_Load
(
*
session
,
&
uid
,
1
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Could not load the requested plugin: %s
\n
"
,
plugin
);
err
=
ff_qsv_error
(
ret
);
goto
load_plugin_fail
;
}
if
(
*
load_plugins
)
load_plugins
++
;
load_plugin_fail:
av_freep
(
&
plugin
);
if
(
err
<
0
)
return
err
;
}
}
}
MFXQueryIMPL
(
*
session
,
&
impl
);
MFXQueryIMPL
(
*
session
,
&
impl
);
...
@@ -164,3 +182,147 @@ load_plugin_fail:
...
@@ -164,3 +182,147 @@ load_plugin_fail:
return
0
;
return
0
;
}
}
static
mfxStatus
qsv_frame_alloc
(
mfxHDL
pthis
,
mfxFrameAllocRequest
*
req
,
mfxFrameAllocResponse
*
resp
)
{
QSVFramesContext
*
ctx
=
pthis
;
mfxFrameInfo
*
i
=
&
req
->
Info
;
mfxFrameInfo
*
i1
=
&
ctx
->
info
;
if
(
!
(
req
->
Type
&
MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET
)
||
!
(
req
->
Type
&
(
MFX_MEMTYPE_FROM_DECODE
))
||
!
(
req
->
Type
&
MFX_MEMTYPE_EXTERNAL_FRAME
))
return
MFX_ERR_UNSUPPORTED
;
if
(
i
->
Width
!=
i1
->
Width
||
i
->
Height
!=
i1
->
Height
||
i
->
FourCC
!=
i1
->
FourCC
||
i
->
ChromaFormat
!=
i1
->
ChromaFormat
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Mismatching surface properties in an "
"allocation request: %dx%d %d %d vs %dx%d %d %d
\n
"
,
i
->
Width
,
i
->
Height
,
i
->
FourCC
,
i
->
ChromaFormat
,
i1
->
Width
,
i1
->
Height
,
i1
->
FourCC
,
i1
->
ChromaFormat
);
return
MFX_ERR_UNSUPPORTED
;
}
resp
->
mids
=
ctx
->
mids
;
resp
->
NumFrameActual
=
ctx
->
nb_mids
;
return
MFX_ERR_NONE
;
}
static
mfxStatus
qsv_frame_free
(
mfxHDL
pthis
,
mfxFrameAllocResponse
*
resp
)
{
return
MFX_ERR_NONE
;
}
static
mfxStatus
qsv_frame_lock
(
mfxHDL
pthis
,
mfxMemId
mid
,
mfxFrameData
*
ptr
)
{
return
MFX_ERR_UNSUPPORTED
;
}
static
mfxStatus
qsv_frame_unlock
(
mfxHDL
pthis
,
mfxMemId
mid
,
mfxFrameData
*
ptr
)
{
return
MFX_ERR_UNSUPPORTED
;
}
static
mfxStatus
qsv_frame_get_hdl
(
mfxHDL
pthis
,
mfxMemId
mid
,
mfxHDL
*
hdl
)
{
*
hdl
=
mid
;
return
MFX_ERR_NONE
;
}
int
ff_qsv_init_session_hwcontext
(
AVCodecContext
*
avctx
,
mfxSession
*
psession
,
QSVFramesContext
*
qsv_frames_ctx
,
const
char
*
load_plugins
,
int
opaque
)
{
static
const
mfxHandleType
handle_types
[]
=
{
MFX_HANDLE_VA_DISPLAY
,
MFX_HANDLE_D3D9_DEVICE_MANAGER
,
MFX_HANDLE_D3D11_DEVICE
,
};
mfxFrameAllocator
frame_allocator
=
{
.
pthis
=
qsv_frames_ctx
,
.
Alloc
=
qsv_frame_alloc
,
.
Lock
=
qsv_frame_lock
,
.
Unlock
=
qsv_frame_unlock
,
.
GetHDL
=
qsv_frame_get_hdl
,
.
Free
=
qsv_frame_free
,
};
AVHWFramesContext
*
frames_ctx
=
(
AVHWFramesContext
*
)
qsv_frames_ctx
->
hw_frames_ctx
->
data
;
AVQSVFramesContext
*
frames_hwctx
=
frames_ctx
->
hwctx
;
AVQSVDeviceContext
*
device_hwctx
=
frames_ctx
->
device_ctx
->
hwctx
;
mfxSession
parent_session
=
device_hwctx
->
session
;
mfxSession
session
;
mfxVersion
ver
;
mfxIMPL
impl
;
mfxHDL
handle
=
NULL
;
mfxHandleType
handle_type
;
mfxStatus
err
;
int
i
,
ret
;
err
=
MFXQueryIMPL
(
parent_session
,
&
impl
);
if
(
err
==
MFX_ERR_NONE
)
err
=
MFXQueryVersion
(
parent_session
,
&
ver
);
if
(
err
!=
MFX_ERR_NONE
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error querying the session attributes
\n
"
);
return
ff_qsv_error
(
err
);
}
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
handle_types
);
i
++
)
{
err
=
MFXVideoCORE_GetHandle
(
parent_session
,
handle_types
[
i
],
&
handle
);
if
(
err
==
MFX_ERR_NONE
)
{
handle_type
=
handle_types
[
i
];
break
;
}
handle
=
NULL
;
}
if
(
!
handle
)
{
av_log
(
avctx
,
AV_LOG_VERBOSE
,
"No supported hw handle could be retrieved "
"from the session
\n
"
);
}
err
=
MFXInit
(
impl
,
&
ver
,
&
session
);
if
(
err
!=
MFX_ERR_NONE
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error initializing a child MFX session: %d
\n
"
,
err
);
return
ff_qsv_error
(
err
);
}
if
(
handle
)
{
err
=
MFXVideoCORE_SetHandle
(
session
,
handle_type
,
handle
);
if
(
err
!=
MFX_ERR_NONE
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error setting a HW handle: %d
\n
"
,
err
);
return
ff_qsv_error
(
err
);
}
}
ret
=
qsv_load_plugins
(
session
,
load_plugins
,
avctx
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error loading plugins
\n
"
);
return
ret
;
}
if
(
!
opaque
)
{
av_freep
(
&
qsv_frames_ctx
->
mids
);
qsv_frames_ctx
->
mids
=
av_mallocz_array
(
frames_hwctx
->
nb_surfaces
,
sizeof
(
*
qsv_frames_ctx
->
mids
));
if
(
!
qsv_frames_ctx
->
mids
)
return
AVERROR
(
ENOMEM
);
qsv_frames_ctx
->
info
=
frames_hwctx
->
surfaces
[
0
].
Info
;
qsv_frames_ctx
->
nb_mids
=
frames_hwctx
->
nb_surfaces
;
for
(
i
=
0
;
i
<
frames_hwctx
->
nb_surfaces
;
i
++
)
qsv_frames_ctx
->
mids
[
i
]
=
frames_hwctx
->
surfaces
[
i
].
Data
.
MemId
;
err
=
MFXVideoCORE_SetFrameAllocator
(
session
,
&
frame_allocator
);
if
(
err
!=
MFX_ERR_NONE
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error setting a frame allocator: %d
\n
"
,
err
);
return
ff_qsv_error
(
err
);
}
}
*
psession
=
session
;
return
0
;
}
libavcodec/qsv_internal.h
View file @
a0524d9b
...
@@ -47,6 +47,13 @@ typedef struct QSVFrame {
...
@@ -47,6 +47,13 @@ typedef struct QSVFrame {
struct
QSVFrame
*
next
;
struct
QSVFrame
*
next
;
}
QSVFrame
;
}
QSVFrame
;
typedef
struct
QSVFramesContext
{
AVBufferRef
*
hw_frames_ctx
;
mfxFrameInfo
info
;
mfxMemId
*
mids
;
int
nb_mids
;
}
QSVFramesContext
;
/**
/**
* Convert a libmfx error code into a libav error code.
* Convert a libmfx error code into a libav error code.
*/
*/
...
@@ -57,4 +64,8 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id);
...
@@ -57,4 +64,8 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id);
int
ff_qsv_init_internal_session
(
AVCodecContext
*
avctx
,
mfxSession
*
session
,
int
ff_qsv_init_internal_session
(
AVCodecContext
*
avctx
,
mfxSession
*
session
,
const
char
*
load_plugins
);
const
char
*
load_plugins
);
int
ff_qsv_init_session_hwcontext
(
AVCodecContext
*
avctx
,
mfxSession
*
session
,
QSVFramesContext
*
qsv_frames_ctx
,
const
char
*
load_plugins
,
int
opaque
);
#endif
/* AVCODEC_QSV_INTERNAL_H */
#endif
/* AVCODEC_QSV_INTERNAL_H */
libavcodec/qsvdec.c
View file @
a0524d9b
...
@@ -27,6 +27,8 @@
...
@@ -27,6 +27,8 @@
#include <mfx/mfxvideo.h>
#include <mfx/mfxvideo.h>
#include "libavutil/common.h"
#include "libavutil/common.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_qsv.h"
#include "libavutil/mem.h"
#include "libavutil/mem.h"
#include "libavutil/log.h"
#include "libavutil/log.h"
#include "libavutil/pixfmt.h"
#include "libavutil/pixfmt.h"
...
@@ -49,19 +51,42 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format)
...
@@ -49,19 +51,42 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format)
}
}
}
}
static
int
qsv_init_session
(
AVCodecContext
*
avctx
,
QSVContext
*
q
,
mfxSession
session
)
static
int
qsv_init_session
(
AVCodecContext
*
avctx
,
QSVContext
*
q
,
mfxSession
session
,
AVBufferRef
*
hw_frames_ref
)
{
{
if
(
!
session
)
{
int
ret
;
if
(
session
)
{
q
->
session
=
session
;
}
else
if
(
hw_frames_ref
)
{
if
(
q
->
internal_session
)
{
MFXClose
(
q
->
internal_session
);
q
->
internal_session
=
NULL
;
}
av_buffer_unref
(
&
q
->
frames_ctx
.
hw_frames_ctx
);
q
->
frames_ctx
.
hw_frames_ctx
=
av_buffer_ref
(
hw_frames_ref
);
if
(
!
q
->
frames_ctx
.
hw_frames_ctx
)
return
AVERROR
(
ENOMEM
);
ret
=
ff_qsv_init_session_hwcontext
(
avctx
,
&
q
->
internal_session
,
&
q
->
frames_ctx
,
q
->
load_plugins
,
q
->
iopattern
==
MFX_IOPATTERN_OUT_OPAQUE_MEMORY
);
if
(
ret
<
0
)
{
av_buffer_unref
(
&
q
->
frames_ctx
.
hw_frames_ctx
);
return
ret
;
}
q
->
session
=
q
->
internal_session
;
}
else
{
if
(
!
q
->
internal_session
)
{
if
(
!
q
->
internal_session
)
{
int
ret
=
ff_qsv_init_internal_session
(
avctx
,
&
q
->
internal_session
,
ret
=
ff_qsv_init_internal_session
(
avctx
,
&
q
->
internal_session
,
q
->
load_plugins
);
q
->
load_plugins
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
}
}
q
->
session
=
q
->
internal_session
;
q
->
session
=
q
->
internal_session
;
}
else
{
q
->
session
=
session
;
}
}
/* make sure the decoder is uninitialized */
/* make sure the decoder is uninitialized */
...
@@ -73,6 +98,7 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses
...
@@ -73,6 +98,7 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses
static
int
qsv_decode_init
(
AVCodecContext
*
avctx
,
QSVContext
*
q
)
static
int
qsv_decode_init
(
AVCodecContext
*
avctx
,
QSVContext
*
q
)
{
{
mfxSession
session
=
NULL
;
mfxSession
session
=
NULL
;
int
iopattern
=
0
;
mfxVideoParam
param
=
{
{
0
}
};
mfxVideoParam
param
=
{
{
0
}
};
int
ret
;
int
ret
;
...
@@ -86,12 +112,28 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
...
@@ -86,12 +112,28 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
if
(
avctx
->
hwaccel_context
)
{
if
(
avctx
->
hwaccel_context
)
{
AVQSVContext
*
user_ctx
=
avctx
->
hwaccel_context
;
AVQSVContext
*
user_ctx
=
avctx
->
hwaccel_context
;
session
=
user_ctx
->
session
;
session
=
user_ctx
->
session
;
q
->
iopattern
=
user_ctx
->
iopattern
;
iopattern
=
user_ctx
->
iopattern
;
q
->
ext_buffers
=
user_ctx
->
ext_buffers
;
q
->
ext_buffers
=
user_ctx
->
ext_buffers
;
q
->
nb_ext_buffers
=
user_ctx
->
nb_ext_buffers
;
q
->
nb_ext_buffers
=
user_ctx
->
nb_ext_buffers
;
}
}
ret
=
qsv_init_session
(
avctx
,
q
,
session
);
if
(
avctx
->
hw_frames_ctx
)
{
AVHWFramesContext
*
frames_ctx
=
(
AVHWFramesContext
*
)
avctx
->
hw_frames_ctx
->
data
;
AVQSVFramesContext
*
frames_hwctx
=
frames_ctx
->
hwctx
;
if
(
!
iopattern
)
{
if
(
frames_hwctx
->
frame_type
&
MFX_MEMTYPE_OPAQUE_FRAME
)
iopattern
=
MFX_IOPATTERN_OUT_OPAQUE_MEMORY
;
else
if
(
frames_hwctx
->
frame_type
&
MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET
)
iopattern
=
MFX_IOPATTERN_OUT_VIDEO_MEMORY
;
}
}
if
(
!
iopattern
)
iopattern
=
MFX_IOPATTERN_OUT_SYSTEM_MEMORY
;
q
->
iopattern
=
iopattern
;
ret
=
qsv_init_session
(
avctx
,
q
,
session
,
avctx
->
hw_frames_ctx
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error initializing an MFX session
\n
"
);
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error initializing an MFX session
\n
"
);
return
ret
;
return
ret
;
...
@@ -360,6 +402,10 @@ int ff_qsv_decode_close(QSVContext *q)
...
@@ -360,6 +402,10 @@ int ff_qsv_decode_close(QSVContext *q)
if
(
q
->
internal_session
)
if
(
q
->
internal_session
)
MFXClose
(
q
->
internal_session
);
MFXClose
(
q
->
internal_session
);
av_buffer_unref
(
&
q
->
frames_ctx
.
hw_frames_ctx
);
av_freep
(
&
q
->
frames_ctx
.
mids
);
q
->
frames_ctx
.
nb_mids
=
0
;
return
0
;
return
0
;
}
}
...
...
libavcodec/qsvdec.h
View file @
a0524d9b
...
@@ -43,6 +43,8 @@ typedef struct QSVContext {
...
@@ -43,6 +43,8 @@ typedef struct QSVContext {
// one
// one
mfxSession
internal_session
;
mfxSession
internal_session
;
QSVFramesContext
frames_ctx
;
/**
/**
* a linked list of frames currently being used by QSV
* a linked list of frames currently being used by QSV
*/
*/
...
...
libavcodec/qsvdec_h2645.c
View file @
a0524d9b
...
@@ -108,8 +108,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
...
@@ -108,8 +108,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
goto
fail
;
goto
fail
;
}
}
s
->
qsv
.
iopattern
=
MFX_IOPATTERN_OUT_SYSTEM_MEMORY
;
return
0
;
return
0
;
fail:
fail:
qsv_decode_close
(
avctx
);
qsv_decode_close
(
avctx
);
...
...
libavcodec/qsvdec_mpeg2.c
View file @
a0524d9b
...
@@ -80,8 +80,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
...
@@ -80,8 +80,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
goto
fail
;
goto
fail
;
}
}
s
->
qsv
.
iopattern
=
MFX_IOPATTERN_OUT_SYSTEM_MEMORY
;
return
0
;
return
0
;
fail:
fail:
qsv_decode_close
(
avctx
);
qsv_decode_close
(
avctx
);
...
...
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