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
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 @@
#include <string.h>
#include "libavutil/avstring.h"
#include "libavutil/common.h"
#include "libavutil/error.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_qsv.h"
#include "avcodec.h"
#include "qsv_internal.h"
...
...
@@ -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
,
const
char
*
load_plugins
)
{
...
...
@@ -101,45 +154,10 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
return
ff_qsv_error
(
ret
);
}
if
(
load_plugins
&&
*
load_plugins
)
{
while
(
*
load_plugins
)
{
mfxPluginUID
uid
;
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
(
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
;
}
ret
=
qsv_load_plugins
(
*
session
,
load_plugins
,
avctx
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error loading plugins
\n
"
);
return
ret
;
}
MFXQueryIMPL
(
*
session
,
&
impl
);
...
...
@@ -164,3 +182,147 @@ load_plugin_fail:
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 {
struct
QSVFrame
*
next
;
}
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.
*/
...
...
@@ -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
,
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 */
libavcodec/qsvdec.c
View file @
a0524d9b
...
...
@@ -27,6 +27,8 @@
#include <mfx/mfxvideo.h>
#include "libavutil/common.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_qsv.h"
#include "libavutil/mem.h"
#include "libavutil/log.h"
#include "libavutil/pixfmt.h"
...
...
@@ -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
)
{
int
ret
=
ff_qsv_init_internal_session
(
avctx
,
&
q
->
internal_session
,
q
->
load_plugins
);
ret
=
ff_qsv_init_internal_session
(
avctx
,
&
q
->
internal_session
,
q
->
load_plugins
);
if
(
ret
<
0
)
return
ret
;
}
q
->
session
=
q
->
internal_session
;
}
else
{
q
->
session
=
session
;
}
/* make sure the decoder is uninitialized */
...
...
@@ -73,6 +98,7 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses
static
int
qsv_decode_init
(
AVCodecContext
*
avctx
,
QSVContext
*
q
)
{
mfxSession
session
=
NULL
;
int
iopattern
=
0
;
mfxVideoParam
param
=
{
{
0
}
};
int
ret
;
...
...
@@ -86,12 +112,28 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
if
(
avctx
->
hwaccel_context
)
{
AVQSVContext
*
user_ctx
=
avctx
->
hwaccel_context
;
session
=
user_ctx
->
session
;
q
->
iopattern
=
user_ctx
->
iopattern
;
iopattern
=
user_ctx
->
iopattern
;
q
->
ext_buffers
=
user_ctx
->
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
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error initializing an MFX session
\n
"
);
return
ret
;
...
...
@@ -360,6 +402,10 @@ int ff_qsv_decode_close(QSVContext *q)
if
(
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
;
}
...
...
libavcodec/qsvdec.h
View file @
a0524d9b
...
...
@@ -43,6 +43,8 @@ typedef struct QSVContext {
// one
mfxSession
internal_session
;
QSVFramesContext
frames_ctx
;
/**
* 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)
goto
fail
;
}
s
->
qsv
.
iopattern
=
MFX_IOPATTERN_OUT_SYSTEM_MEMORY
;
return
0
;
fail:
qsv_decode_close
(
avctx
);
...
...
libavcodec/qsvdec_mpeg2.c
View file @
a0524d9b
...
...
@@ -80,8 +80,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
goto
fail
;
}
s
->
qsv
.
iopattern
=
MFX_IOPATTERN_OUT_SYSTEM_MEMORY
;
return
0
;
fail:
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