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
dc923bc2
Commit
dc923bc2
authored
Oct 11, 2015
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
qsvenc: add an API for allocating opaque surfaces
parent
2ec96b6b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
111 additions
and
5 deletions
+111
-5
APIchanges
doc/APIchanges
+3
-0
qsv.h
libavcodec/qsv.h
+47
-0
qsvenc.c
libavcodec/qsvenc.c
+53
-4
qsvenc.h
libavcodec/qsvenc.h
+8
-1
No files found.
doc/APIchanges
View file @
dc923bc2
...
...
@@ -13,6 +13,9 @@ libavutil: 2015-08-28
API changes, most recent first:
2015-xx-xx - xxxxxxx - lavc 57.0.0 - qsv.h
Add an API for allocating opaque surfaces.
2015-xx-xx - xxxxxxx - lavu 55.2.0 - dict.h
Change return type of av_dict_copy() from void to int, so that a proper
error code can be reported.
...
...
libavcodec/qsv.h
View file @
dc923bc2
...
...
@@ -23,6 +23,8 @@
#include <mfx/mfxvideo.h>
#include "libavutil/buffer.h"
/**
* This struct is used for communicating QSV parameters between libavcodec and
* the caller. It is managed by the caller and must be assigned to
...
...
@@ -48,6 +50,51 @@ typedef struct AVQSVContext {
*/
mfxExtBuffer
**
ext_buffers
;
int
nb_ext_buffers
;
/**
* Encoding only. If this field is set to non-zero by the caller, libavcodec
* will create an mfxExtOpaqueSurfaceAlloc extended buffer and pass it to
* the encoder initialization. This only makes sense if iopattern is also
* set to MFX_IOPATTERN_IN_OPAQUE_MEMORY.
*
* The number of allocated opaque surfaces will be the sum of the number
* required by the encoder and the user-provided value nb_opaque_surfaces.
* The array of the opaque surfaces will be exported to the caller through
* the opaque_surfaces field.
*/
int
opaque_alloc
;
/**
* Encoding only, and only if opaque_alloc is set to non-zero. Before
* calling avcodec_open2(), the caller should set this field to the number
* of extra opaque surfaces to allocate beyond what is required by the
* encoder.
*
* On return from avcodec_open2(), this field will be set by libavcodec to
* the total number of allocated opaque surfaces.
*/
int
nb_opaque_surfaces
;
/**
* Encoding only, and only if opaque_alloc is set to non-zero. On return
* from avcodec_open2(), this field will be used by libavcodec to export the
* array of the allocated opaque surfaces to the caller, so they can be
* passed to other parts of the pipeline.
*
* The buffer reference exported here is owned and managed by libavcodec,
* the callers should make their own reference with av_buffer_ref() and free
* it with av_buffer_unref() when it is no longer needed.
*
* The buffer data is an nb_opaque_surfaces-sized array of mfxFrameSurface1.
*/
AVBufferRef
*
opaque_surfaces
;
/**
* Encoding only, and only if opaque_alloc is set to non-zero. On return
* from avcodec_open2(), this field will be set to the surface type used in
* the opaque allocation request.
*/
int
opaque_alloc_type
;
}
AVQSVContext
;
/**
...
...
libavcodec/qsvenc.c
View file @
dc923bc2
...
...
@@ -134,7 +134,7 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
q
->
extco
.
CAVLC
=
avctx
->
coder_type
==
FF_CODER_TYPE_VLC
?
MFX_CODINGOPTION_ON
:
MFX_CODINGOPTION_UNKNOWN
;
q
->
extparam_internal
[
0
]
=
(
mfxExtBuffer
*
)
&
q
->
extco
;
q
->
extparam_internal
[
q
->
nb_extparam_internal
++
]
=
(
mfxExtBuffer
*
)
&
q
->
extco
;
}
return
0
;
...
...
@@ -187,8 +187,46 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
return
0
;
}
static
int
qsv_init_opaque_alloc
(
AVCodecContext
*
avctx
,
QSVEncContext
*
q
)
{
AVQSVContext
*
qsv
=
avctx
->
hwaccel_context
;
mfxFrameSurface1
*
surfaces
;
int
nb_surfaces
,
i
;
nb_surfaces
=
qsv
->
nb_opaque_surfaces
+
q
->
req
.
NumFrameSuggested
+
q
->
async_depth
;
q
->
opaque_alloc_buf
=
av_buffer_allocz
(
sizeof
(
*
surfaces
)
*
nb_surfaces
);
if
(
!
q
->
opaque_alloc_buf
)
return
AVERROR
(
ENOMEM
);
q
->
opaque_surfaces
=
av_malloc_array
(
nb_surfaces
,
sizeof
(
*
q
->
opaque_surfaces
));
if
(
!
q
->
opaque_surfaces
)
return
AVERROR
(
ENOMEM
);
surfaces
=
(
mfxFrameSurface1
*
)
q
->
opaque_alloc_buf
->
data
;
for
(
i
=
0
;
i
<
nb_surfaces
;
i
++
)
{
surfaces
[
i
].
Info
=
q
->
req
.
Info
;
q
->
opaque_surfaces
[
i
]
=
surfaces
+
i
;
}
q
->
opaque_alloc
.
Header
.
BufferId
=
MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
;
q
->
opaque_alloc
.
Header
.
BufferSz
=
sizeof
(
q
->
opaque_alloc
);
q
->
opaque_alloc
.
In
.
Surfaces
=
q
->
opaque_surfaces
;
q
->
opaque_alloc
.
In
.
NumSurface
=
nb_surfaces
;
q
->
opaque_alloc
.
In
.
Type
=
q
->
req
.
Type
;
q
->
extparam_internal
[
q
->
nb_extparam_internal
++
]
=
(
mfxExtBuffer
*
)
&
q
->
opaque_alloc
;
qsv
->
nb_opaque_surfaces
=
nb_surfaces
;
qsv
->
opaque_surfaces
=
q
->
opaque_alloc_buf
;
qsv
->
opaque_alloc_type
=
q
->
req
.
Type
;
return
0
;
}
int
ff_qsv_enc_init
(
AVCodecContext
*
avctx
,
QSVEncContext
*
q
)
{
int
opaque_alloc
=
0
;
int
ret
;
q
->
param
.
IOPattern
=
MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
...
...
@@ -204,6 +242,8 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
q
->
session
=
qsv
->
session
;
q
->
param
.
IOPattern
=
qsv
->
iopattern
;
opaque_alloc
=
qsv
->
opaque_alloc
;
}
if
(
!
q
->
session
)
{
...
...
@@ -225,11 +265,17 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
return
ff_qsv_error
(
ret
);
}
if
(
opaque_alloc
)
{
ret
=
qsv_init_opaque_alloc
(
avctx
,
q
);
if
(
ret
<
0
)
return
ret
;
}
if
(
avctx
->
hwaccel_context
)
{
AVQSVContext
*
qsv
=
avctx
->
hwaccel_context
;
int
i
,
j
;
q
->
extparam
=
av_mallocz_array
(
qsv
->
nb_ext_buffers
+
FF_ARRAY_ELEMS
(
q
->
extparam_internal
)
,
q
->
extparam
=
av_mallocz_array
(
qsv
->
nb_ext_buffers
+
q
->
nb_extparam_internal
,
sizeof
(
*
q
->
extparam
));
if
(
!
q
->
extparam
)
return
AVERROR
(
ENOMEM
);
...
...
@@ -239,7 +285,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
q
->
param
.
ExtParam
[
i
]
=
qsv
->
ext_buffers
[
i
];
q
->
param
.
NumExtParam
=
qsv
->
nb_ext_buffers
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
q
->
extparam_internal
)
;
i
++
)
{
for
(
i
=
0
;
i
<
q
->
nb_extparam_internal
;
i
++
)
{
for
(
j
=
0
;
j
<
qsv
->
nb_ext_buffers
;
j
++
)
{
if
(
qsv
->
ext_buffers
[
j
]
->
BufferId
==
q
->
extparam_internal
[
i
]
->
BufferId
)
break
;
...
...
@@ -251,7 +297,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
}
}
else
{
q
->
param
.
ExtParam
=
q
->
extparam_internal
;
q
->
param
.
NumExtParam
=
FF_ARRAY_ELEMS
(
q
->
extparam_internal
)
;
q
->
param
.
NumExtParam
=
q
->
nb_extparam_internal
;
}
ret
=
MFXVideoENCODE_Init
(
q
->
session
,
&
q
->
param
);
...
...
@@ -537,6 +583,9 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
av_fifo_free
(
q
->
async_fifo
);
q
->
async_fifo
=
NULL
;
av_freep
(
&
q
->
opaque_surfaces
);
av_buffer_unref
(
&
q
->
opaque_alloc_buf
);
av_freep
(
&
q
->
extparam
);
return
0
;
...
...
libavcodec/qsvenc.h
View file @
dc923bc2
...
...
@@ -49,7 +49,14 @@ typedef struct QSVEncContext {
mfxFrameAllocRequest
req
;
mfxExtCodingOption
extco
;
mfxExtBuffer
*
extparam_internal
[
1
];
mfxExtOpaqueSurfaceAlloc
opaque_alloc
;
mfxFrameSurface1
**
opaque_surfaces
;
AVBufferRef
*
opaque_alloc_buf
;
mfxExtBuffer
*
extparam_internal
[
2
];
int
nb_extparam_internal
;
mfxExtBuffer
**
extparam
;
AVFifoBuffer
*
async_fifo
;
...
...
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