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
cfb49fc6
Commit
cfb49fc6
authored
May 20, 2016
by
Andrey Turkin
Committed by
Timo Rothenpieler
May 25, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avcodec/nvenc: replace custom FIFOs with AVFifos
Signed-off-by:
Timo Rothenpieler
<
timo@rothenpieler.org
>
parent
e1691c44
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
137 deletions
+50
-137
nvenc.c
libavcodec/nvenc.c
+50
-137
No files found.
libavcodec/nvenc.c
View file @
cfb49fc6
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <nvEncodeAPI.h>
#include <nvEncodeAPI.h>
#include "libavutil/fifo.h"
#include "libavutil/internal.h"
#include "libavutil/internal.h"
#include "libavutil/imgutils.h"
#include "libavutil/imgutils.h"
#include "libavutil/avassert.h"
#include "libavutil/avassert.h"
...
@@ -89,15 +90,6 @@ typedef struct NvencData
...
@@ -89,15 +90,6 @@ typedef struct NvencData
}
u
;
}
u
;
}
NvencData
;
}
NvencData
;
typedef
struct
NvencDataList
{
NvencData
*
data
;
uint32_t
pos
;
uint32_t
count
;
uint32_t
size
;
}
NvencDataList
;
typedef
struct
NvencDynLoadFunctions
typedef
struct
NvencDynLoadFunctions
{
{
PCUINIT
cu_init
;
PCUINIT
cu_init
;
...
@@ -141,9 +133,9 @@ typedef struct NvencContext
...
@@ -141,9 +133,9 @@ typedef struct NvencContext
int
max_surface_count
;
int
max_surface_count
;
NvencSurface
*
surfaces
;
NvencSurface
*
surfaces
;
NvencDataList
output_surface_queue
;
AVFifoBuffer
*
output_surface_queue
;
NvencDataList
output_surface_ready_queue
;
AVFifoBuffer
*
output_surface_ready_queue
;
NvencDataList
timestamp_list
;
AVFifoBuffer
*
timestamp_list
;
int64_t
last_dts
;
int64_t
last_dts
;
void
*
nvencoder
;
void
*
nvencoder
;
...
@@ -279,105 +271,18 @@ static int input_string_to_uint32(AVCodecContext *avctx, const NvencValuePair *p
...
@@ -279,105 +271,18 @@ static int input_string_to_uint32(AVCodecContext *avctx, const NvencValuePair *p
return
AVERROR
(
EINVAL
);
return
AVERROR
(
EINVAL
);
}
}
static
NvencData
*
data_queue_dequeue
(
NvencDataList
*
queue
)
static
void
timestamp_queue_enqueue
(
AVFifoBuffer
*
queue
,
int64_t
timestamp
)
{
uint32_t
mask
;
uint32_t
read_pos
;
av_assert0
(
queue
);
av_assert0
(
queue
->
size
);
av_assert0
(
queue
->
data
);
if
(
!
queue
->
count
)
return
NULL
;
/* Size always is a multiple of two */
mask
=
queue
->
size
-
1
;
read_pos
=
(
queue
->
pos
-
queue
->
count
)
&
mask
;
queue
->
count
--
;
return
&
queue
->
data
[
read_pos
];
}
static
int
data_queue_enqueue
(
NvencDataList
*
queue
,
NvencData
*
data
)
{
NvencDataList
new_queue
;
NvencData
*
tmp_data
;
uint32_t
mask
;
if
(
!
queue
->
size
)
{
/* size always has to be a multiple of two */
queue
->
size
=
4
;
queue
->
pos
=
0
;
queue
->
count
=
0
;
queue
->
data
=
av_malloc
(
queue
->
size
*
sizeof
(
*
(
queue
->
data
)));
if
(
!
queue
->
data
)
{
queue
->
size
=
0
;
return
AVERROR
(
ENOMEM
);
}
}
if
(
queue
->
count
==
queue
->
size
)
{
new_queue
.
size
=
queue
->
size
<<
1
;
new_queue
.
pos
=
0
;
new_queue
.
count
=
0
;
new_queue
.
data
=
av_malloc
(
new_queue
.
size
*
sizeof
(
*
(
queue
->
data
)));
if
(
!
new_queue
.
data
)
return
AVERROR
(
ENOMEM
);
while
(
tmp_data
=
data_queue_dequeue
(
queue
))
data_queue_enqueue
(
&
new_queue
,
tmp_data
);
av_free
(
queue
->
data
);
*
queue
=
new_queue
;
}
mask
=
queue
->
size
-
1
;
queue
->
data
[
queue
->
pos
]
=
*
data
;
queue
->
pos
=
(
queue
->
pos
+
1
)
&
mask
;
queue
->
count
++
;
return
0
;
}
static
int
out_surf_queue_enqueue
(
NvencDataList
*
queue
,
NvencSurface
*
surface
)
{
NvencData
data
;
data
.
u
.
surface
=
surface
;
return
data_queue_enqueue
(
queue
,
&
data
);
}
static
NvencSurface
*
out_surf_queue_dequeue
(
NvencDataList
*
queue
)
{
{
NvencData
*
res
=
data_queue_dequeue
(
queue
);
av_fifo_generic_write
(
queue
,
&
timestamp
,
sizeof
(
timestamp
),
NULL
);
if
(
!
res
)
return
NULL
;
return
res
->
u
.
surface
;
}
}
static
int
timestamp_queue_enqueue
(
NvencDataList
*
queue
,
int64_t
timestamp
)
static
int
64_t
timestamp_queue_dequeue
(
AVFifoBuffer
*
queue
)
{
{
NvencData
data
;
int64_t
timestamp
=
AV_NOPTS_VALUE
;
data
.
u
.
timestamp
=
timestamp
;
if
(
av_fifo_size
(
queue
)
>
0
)
av_fifo_generic_read
(
queue
,
&
timestamp
,
sizeof
(
timestamp
),
NULL
);
return
data_queue_enqueue
(
queue
,
&
data
);
return
timestamp
;
}
static
int64_t
timestamp_queue_dequeue
(
NvencDataList
*
queue
)
{
NvencData
*
res
=
data_queue_dequeue
(
queue
);
if
(
!
res
)
return
AV_NOPTS_VALUE
;
return
res
->
u
.
timestamp
;
}
}
#define CHECK_LOAD_FUNC(t, f, s) \
#define CHECK_LOAD_FUNC(t, f, s) \
...
@@ -1218,6 +1123,16 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx, int* surfaceCount
...
@@ -1218,6 +1123,16 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx, int* surfaceCount
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
}
}
ctx
->
timestamp_list
=
av_fifo_alloc
(
ctx
->
max_surface_count
*
sizeof
(
int64_t
));
if
(
!
ctx
->
timestamp_list
)
return
AVERROR
(
ENOMEM
);
ctx
->
output_surface_queue
=
av_fifo_alloc
(
ctx
->
max_surface_count
*
sizeof
(
NvencSurface
*
));
if
(
!
ctx
->
output_surface_queue
)
return
AVERROR
(
ENOMEM
);
ctx
->
output_surface_ready_queue
=
av_fifo_alloc
(
ctx
->
max_surface_count
*
sizeof
(
NvencSurface
*
));
if
(
!
ctx
->
output_surface_ready_queue
)
return
AVERROR
(
ENOMEM
);
for
(
*
surfaceCount
=
0
;
*
surfaceCount
<
ctx
->
max_surface_count
;
++*
surfaceCount
)
{
for
(
*
surfaceCount
=
0
;
*
surfaceCount
<
ctx
->
max_surface_count
;
++*
surfaceCount
)
{
res
=
nvenc_alloc_surface
(
avctx
,
*
surfaceCount
);
res
=
nvenc_alloc_surface
(
avctx
,
*
surfaceCount
);
if
(
res
)
if
(
res
)
...
@@ -1298,11 +1213,15 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx)
...
@@ -1298,11 +1213,15 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx)
return
0
;
return
0
;
error:
error:
av_fifo_freep
(
&
ctx
->
timestamp_list
);
av_fifo_freep
(
&
ctx
->
output_surface_ready_queue
);
av_fifo_freep
(
&
ctx
->
output_surface_queue
);
for
(
i
=
0
;
i
<
surfaceCount
;
++
i
)
{
for
(
i
=
0
;
i
<
surfaceCount
;
++
i
)
{
p_nvenc
->
nvEncDestroyInputBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
input_surface
);
p_nvenc
->
nvEncDestroyInputBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
input_surface
);
p_nvenc
->
nvEncDestroyBitstreamBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
output_surface
);
p_nvenc
->
nvEncDestroyBitstreamBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
output_surface
);
}
}
av_freep
(
&
ctx
->
surfaces
);
if
(
ctx
->
nvencoder
)
if
(
ctx
->
nvencoder
)
p_nvenc
->
nvEncDestroyEncoder
(
ctx
->
nvencoder
);
p_nvenc
->
nvEncDestroyEncoder
(
ctx
->
nvencoder
);
...
@@ -1325,14 +1244,15 @@ static av_cold int nvenc_encode_close(AVCodecContext *avctx)
...
@@ -1325,14 +1244,15 @@ static av_cold int nvenc_encode_close(AVCodecContext *avctx)
NV_ENCODE_API_FUNCTION_LIST
*
p_nvenc
=
&
dl_fn
->
nvenc_funcs
;
NV_ENCODE_API_FUNCTION_LIST
*
p_nvenc
=
&
dl_fn
->
nvenc_funcs
;
int
i
;
int
i
;
av_f
reep
(
&
ctx
->
timestamp_list
.
data
);
av_f
ifo_freep
(
&
ctx
->
timestamp_list
);
av_f
reep
(
&
ctx
->
output_surface_ready_queue
.
data
);
av_f
ifo_freep
(
&
ctx
->
output_surface_ready_queue
);
av_f
reep
(
&
ctx
->
output_surface_queue
.
data
);
av_f
ifo_freep
(
&
ctx
->
output_surface_queue
);
for
(
i
=
0
;
i
<
ctx
->
max_surface_count
;
++
i
)
{
for
(
i
=
0
;
i
<
ctx
->
max_surface_count
;
++
i
)
{
p_nvenc
->
nvEncDestroyInputBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
input_surface
);
p_nvenc
->
nvEncDestroyInputBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
input_surface
);
p_nvenc
->
nvEncDestroyBitstreamBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
output_surface
);
p_nvenc
->
nvEncDestroyBitstreamBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
output_surface
);
}
}
av_freep
(
&
ctx
->
surfaces
);
ctx
->
max_surface_count
=
0
;
ctx
->
max_surface_count
=
0
;
p_nvenc
->
nvEncDestroyEncoder
(
ctx
->
nvencoder
);
p_nvenc
->
nvEncDestroyEncoder
(
ctx
->
nvencoder
);
...
@@ -1548,7 +1468,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
...
@@ -1548,7 +1468,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
(
lock_params
.
frameAvgQP
-
1
)
*
FF_QP2LAMBDA
,
NULL
,
0
,
pict_type
);
(
lock_params
.
frameAvgQP
-
1
)
*
FF_QP2LAMBDA
,
NULL
,
0
,
pict_type
);
pkt
->
pts
=
lock_params
.
outputTimeStamp
;
pkt
->
pts
=
lock_params
.
outputTimeStamp
;
pkt
->
dts
=
timestamp_queue_dequeue
(
&
ctx
->
timestamp_list
);
pkt
->
dts
=
timestamp_queue_dequeue
(
ctx
->
timestamp_list
);
/* when there're b frame(s), set dts offset */
/* when there're b frame(s), set dts offset */
if
(
ctx
->
encode_config
.
frameIntervalP
>=
2
)
if
(
ctx
->
encode_config
.
frameIntervalP
>=
2
)
...
@@ -1569,11 +1489,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
...
@@ -1569,11 +1489,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
error:
error:
av_free
(
slice_offsets
);
av_free
(
slice_offsets
);
timestamp_queue_dequeue
(
&
ctx
->
timestamp_list
);
timestamp_queue_dequeue
(
ctx
->
timestamp_list
);
return
res
;
return
res
;
}
}
static
int
output_ready
(
NvencContext
*
ctx
,
int
flush
)
{
int
nb_ready
,
nb_pending
;
nb_ready
=
av_fifo_size
(
ctx
->
output_surface_ready_queue
)
/
sizeof
(
NvencSurface
*
);
nb_pending
=
av_fifo_size
(
ctx
->
output_surface_queue
)
/
sizeof
(
NvencSurface
*
);
return
nb_ready
>
0
&&
(
flush
||
nb_ready
+
nb_pending
>=
ctx
->
buffer_delay
);
}
static
int
nvenc_encode_frame
(
AVCodecContext
*
avctx
,
AVPacket
*
pkt
,
static
int
nvenc_encode_frame
(
AVCodecContext
*
avctx
,
AVPacket
*
pkt
,
const
AVFrame
*
frame
,
int
*
got_packet
)
const
AVFrame
*
frame
,
int
*
got_packet
)
{
{
...
@@ -1621,48 +1550,32 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
...
@@ -1621,48 +1550,32 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
nvenc_codec_specific_pic_params
(
avctx
,
&
pic_params
);
nvenc_codec_specific_pic_params
(
avctx
,
&
pic_params
);
res
=
timestamp_queue_enqueue
(
&
ctx
->
timestamp_list
,
frame
->
pts
);
timestamp_queue_enqueue
(
ctx
->
timestamp_list
,
frame
->
pts
);
if
(
res
)
{
inSurf
->
lockCount
=
0
;
return
res
;
}
}
else
{
}
else
{
pic_params
.
encodePicFlags
=
NV_ENC_PIC_FLAG_EOS
;
pic_params
.
encodePicFlags
=
NV_ENC_PIC_FLAG_EOS
;
}
}
nv_status
=
p_nvenc
->
nvEncEncodePicture
(
ctx
->
nvencoder
,
&
pic_params
);
nv_status
=
p_nvenc
->
nvEncEncodePicture
(
ctx
->
nvencoder
,
&
pic_params
);
if
(
frame
&&
nv_status
==
NV_ENC_ERR_NEED_MORE_INPUT
)
{
if
(
frame
&&
nv_status
==
NV_ENC_ERR_NEED_MORE_INPUT
)
res
=
out_surf_queue_enqueue
(
&
ctx
->
output_surface_queue
,
inSurf
);
av_fifo_generic_write
(
ctx
->
output_surface_queue
,
&
inSurf
,
sizeof
(
inSurf
),
NULL
);
if
(
res
)
return
res
;
}
if
(
nv_status
!=
NV_ENC_SUCCESS
&&
nv_status
!=
NV_ENC_ERR_NEED_MORE_INPUT
)
{
if
(
nv_status
!=
NV_ENC_SUCCESS
&&
nv_status
!=
NV_ENC_ERR_NEED_MORE_INPUT
)
{
return
nvenc_print_error
(
avctx
,
nv_status
,
"EncodePicture failed!"
);
return
nvenc_print_error
(
avctx
,
nv_status
,
"EncodePicture failed!"
);
}
}
if
(
nv_status
!=
NV_ENC_ERR_NEED_MORE_INPUT
)
{
if
(
nv_status
!=
NV_ENC_ERR_NEED_MORE_INPUT
)
{
while
(
ctx
->
output_surface_queue
.
count
)
{
while
(
av_fifo_size
(
ctx
->
output_surface_queue
)
>
0
)
{
tmpoutsurf
=
out_surf_queue_dequeue
(
&
ctx
->
output_surface_queue
);
av_fifo_generic_read
(
ctx
->
output_surface_queue
,
&
tmpoutsurf
,
sizeof
(
tmpoutsurf
),
NULL
);
res
=
out_surf_queue_enqueue
(
&
ctx
->
output_surface_ready_queue
,
tmpoutsurf
);
av_fifo_generic_write
(
ctx
->
output_surface_ready_queue
,
&
tmpoutsurf
,
sizeof
(
tmpoutsurf
),
NULL
);
if
(
res
)
return
res
;
}
}
if
(
frame
)
{
if
(
frame
)
res
=
out_surf_queue_enqueue
(
&
ctx
->
output_surface_ready_queue
,
inSurf
);
av_fifo_generic_write
(
ctx
->
output_surface_ready_queue
,
&
inSurf
,
sizeof
(
inSurf
),
NULL
);
if
(
res
)
return
res
;
}
}
}
if
(
ctx
->
output_surface_ready_queue
.
count
&&
(
!
frame
||
ctx
->
output_surface_ready_queue
.
count
+
ctx
->
output_surface_queue
.
count
>=
ctx
->
buffer_delay
))
{
if
(
output_ready
(
ctx
,
!
frame
))
{
tmpoutsurf
=
out_surf_queue_dequeue
(
&
ctx
->
output_surface_ready_queue
);
av_fifo_generic_read
(
ctx
->
output_surface_ready_queue
,
&
tmpoutsurf
,
sizeof
(
tmpoutsurf
),
NULL
);
res
=
process_output_surface
(
avctx
,
pkt
,
tmpoutsurf
);
res
=
process_output_surface
(
avctx
,
pkt
,
tmpoutsurf
);
...
...
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