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
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 @@
#include <nvEncodeAPI.h>
#include "libavutil/fifo.h"
#include "libavutil/internal.h"
#include "libavutil/imgutils.h"
#include "libavutil/avassert.h"
...
...
@@ -89,15 +90,6 @@ typedef struct NvencData
}
u
;
}
NvencData
;
typedef
struct
NvencDataList
{
NvencData
*
data
;
uint32_t
pos
;
uint32_t
count
;
uint32_t
size
;
}
NvencDataList
;
typedef
struct
NvencDynLoadFunctions
{
PCUINIT
cu_init
;
...
...
@@ -141,9 +133,9 @@ typedef struct NvencContext
int
max_surface_count
;
NvencSurface
*
surfaces
;
NvencDataList
output_surface_queue
;
NvencDataList
output_surface_ready_queue
;
NvencDataList
timestamp_list
;
AVFifoBuffer
*
output_surface_queue
;
AVFifoBuffer
*
output_surface_ready_queue
;
AVFifoBuffer
*
timestamp_list
;
int64_t
last_dts
;
void
*
nvencoder
;
...
...
@@ -279,105 +271,18 @@ static int input_string_to_uint32(AVCodecContext *avctx, const NvencValuePair *p
return
AVERROR
(
EINVAL
);
}
static
NvencData
*
data_queue_dequeue
(
NvencDataList
*
queue
)
{
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
)
static
void
timestamp_queue_enqueue
(
AVFifoBuffer
*
queue
,
int64_t
timestamp
)
{
NvencData
*
res
=
data_queue_dequeue
(
queue
);
if
(
!
res
)
return
NULL
;
return
res
->
u
.
surface
;
av_fifo_generic_write
(
queue
,
&
timestamp
,
sizeof
(
timestamp
),
NULL
);
}
static
int
timestamp_queue_enqueue
(
NvencDataList
*
queue
,
int64_t
timestamp
)
static
int
64_t
timestamp_queue_dequeue
(
AVFifoBuffer
*
queue
)
{
NvencData
data
;
data
.
u
.
timestamp
=
timestamp
;
int64_t
timestamp
=
AV_NOPTS_VALUE
;
if
(
av_fifo_size
(
queue
)
>
0
)
av_fifo_generic_read
(
queue
,
&
timestamp
,
sizeof
(
timestamp
),
NULL
);
return
data_queue_enqueue
(
queue
,
&
data
);
}
static
int64_t
timestamp_queue_dequeue
(
NvencDataList
*
queue
)
{
NvencData
*
res
=
data_queue_dequeue
(
queue
);
if
(
!
res
)
return
AV_NOPTS_VALUE
;
return
res
->
u
.
timestamp
;
return
timestamp
;
}
#define CHECK_LOAD_FUNC(t, f, s) \
...
...
@@ -1218,6 +1123,16 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx, int* surfaceCount
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
)
{
res
=
nvenc_alloc_surface
(
avctx
,
*
surfaceCount
);
if
(
res
)
...
...
@@ -1298,11 +1213,15 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx)
return
0
;
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
)
{
p_nvenc
->
nvEncDestroyInputBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
input_surface
);
p_nvenc
->
nvEncDestroyBitstreamBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
output_surface
);
}
av_freep
(
&
ctx
->
surfaces
);
if
(
ctx
->
nvencoder
)
p_nvenc
->
nvEncDestroyEncoder
(
ctx
->
nvencoder
);
...
...
@@ -1325,14 +1244,15 @@ static av_cold int nvenc_encode_close(AVCodecContext *avctx)
NV_ENCODE_API_FUNCTION_LIST
*
p_nvenc
=
&
dl_fn
->
nvenc_funcs
;
int
i
;
av_f
reep
(
&
ctx
->
timestamp_list
.
data
);
av_f
reep
(
&
ctx
->
output_surface_ready_queue
.
data
);
av_f
reep
(
&
ctx
->
output_surface_queue
.
data
);
av_f
ifo_freep
(
&
ctx
->
timestamp_list
);
av_f
ifo_freep
(
&
ctx
->
output_surface_ready_queue
);
av_f
ifo_freep
(
&
ctx
->
output_surface_queue
);
for
(
i
=
0
;
i
<
ctx
->
max_surface_count
;
++
i
)
{
p_nvenc
->
nvEncDestroyInputBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
input_surface
);
p_nvenc
->
nvEncDestroyBitstreamBuffer
(
ctx
->
nvencoder
,
ctx
->
surfaces
[
i
].
output_surface
);
}
av_freep
(
&
ctx
->
surfaces
);
ctx
->
max_surface_count
=
0
;
p_nvenc
->
nvEncDestroyEncoder
(
ctx
->
nvencoder
);
...
...
@@ -1548,7 +1468,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
(
lock_params
.
frameAvgQP
-
1
)
*
FF_QP2LAMBDA
,
NULL
,
0
,
pict_type
);
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 */
if
(
ctx
->
encode_config
.
frameIntervalP
>=
2
)
...
...
@@ -1569,11 +1489,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
error:
av_free
(
slice_offsets
);
timestamp_queue_dequeue
(
&
ctx
->
timestamp_list
);
timestamp_queue_dequeue
(
ctx
->
timestamp_list
);
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
,
const
AVFrame
*
frame
,
int
*
got_packet
)
{
...
...
@@ -1621,48 +1550,32 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
nvenc_codec_specific_pic_params
(
avctx
,
&
pic_params
);
res
=
timestamp_queue_enqueue
(
&
ctx
->
timestamp_list
,
frame
->
pts
);
if
(
res
)
{
inSurf
->
lockCount
=
0
;
return
res
;
}
timestamp_queue_enqueue
(
ctx
->
timestamp_list
,
frame
->
pts
);
}
else
{
pic_params
.
encodePicFlags
=
NV_ENC_PIC_FLAG_EOS
;
}
nv_status
=
p_nvenc
->
nvEncEncodePicture
(
ctx
->
nvencoder
,
&
pic_params
);
if
(
frame
&&
nv_status
==
NV_ENC_ERR_NEED_MORE_INPUT
)
{
res
=
out_surf_queue_enqueue
(
&
ctx
->
output_surface_queue
,
inSurf
);
if
(
res
)
return
res
;
}
if
(
frame
&&
nv_status
==
NV_ENC_ERR_NEED_MORE_INPUT
)
av_fifo_generic_write
(
ctx
->
output_surface_queue
,
&
inSurf
,
sizeof
(
inSurf
),
NULL
);
if
(
nv_status
!=
NV_ENC_SUCCESS
&&
nv_status
!=
NV_ENC_ERR_NEED_MORE_INPUT
)
{
return
nvenc_print_error
(
avctx
,
nv_status
,
"EncodePicture failed!"
);
}
if
(
nv_status
!=
NV_ENC_ERR_NEED_MORE_INPUT
)
{
while
(
ctx
->
output_surface_queue
.
count
)
{
tmpoutsurf
=
out_surf_queue_dequeue
(
&
ctx
->
output_surface_queue
);
res
=
out_surf_queue_enqueue
(
&
ctx
->
output_surface_ready_queue
,
tmpoutsurf
);
if
(
res
)
return
res
;
while
(
av_fifo_size
(
ctx
->
output_surface_queue
)
>
0
)
{
av_fifo_generic_read
(
ctx
->
output_surface_queue
,
&
tmpoutsurf
,
sizeof
(
tmpoutsurf
),
NULL
);
av_fifo_generic_write
(
ctx
->
output_surface_ready_queue
,
&
tmpoutsurf
,
sizeof
(
tmpoutsurf
),
NULL
);
}
if
(
frame
)
{
res
=
out_surf_queue_enqueue
(
&
ctx
->
output_surface_ready_queue
,
inSurf
);
if
(
res
)
return
res
;
}
if
(
frame
)
av_fifo_generic_write
(
ctx
->
output_surface_ready_queue
,
&
inSurf
,
sizeof
(
inSurf
),
NULL
);
}
if
(
ctx
->
output_surface_ready_queue
.
count
&&
(
!
frame
||
ctx
->
output_surface_ready_queue
.
count
+
ctx
->
output_surface_queue
.
count
>=
ctx
->
buffer_delay
))
{
tmpoutsurf
=
out_surf_queue_dequeue
(
&
ctx
->
output_surface_ready_queue
);
if
(
output_ready
(
ctx
,
!
frame
))
{
av_fifo_generic_read
(
ctx
->
output_surface_ready_queue
,
&
tmpoutsurf
,
sizeof
(
tmpoutsurf
),
NULL
);
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