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
f5c4d38c
Commit
f5c4d38c
authored
Jul 14, 2015
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
qsvdec: properly handle asynchronous decoding
Wait for async_depth frames before syncing.
parent
6b15874f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
38 additions
and
8 deletions
+38
-8
qsv_internal.h
libavcodec/qsv_internal.h
+2
-0
qsvdec.c
libavcodec/qsvdec.c
+33
-8
qsvdec.h
libavcodec/qsvdec.h
+3
-0
No files found.
libavcodec/qsv_internal.h
View file @
f5c4d38c
...
...
@@ -40,6 +40,8 @@ typedef struct QSVFrame {
mfxFrameSurface1
surface_internal
;
int
queued
;
struct
QSVFrame
*
next
;
}
QSVFrame
;
...
...
libavcodec/qsvdec.c
View file @
f5c4d38c
...
...
@@ -73,6 +73,11 @@ int ff_qsv_decode_init(AVCodecContext *avctx, QSVContext *q, mfxSession session)
mfxVideoParam
param
=
{
{
0
}
};
int
ret
;
q
->
async_fifo
=
av_fifo_alloc
((
1
+
q
->
async_depth
)
*
(
sizeof
(
mfxSyncPoint
)
+
sizeof
(
QSVFrame
*
)));
if
(
!
q
->
async_fifo
)
return
AVERROR
(
ENOMEM
);
ret
=
qsv_init_session
(
avctx
,
q
,
session
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error initializing an MFX session
\n
"
);
...
...
@@ -142,7 +147,7 @@ static void qsv_clear_unused_frames(QSVContext *q)
{
QSVFrame
*
cur
=
q
->
work_frames
;
while
(
cur
)
{
if
(
cur
->
surface
&&
!
cur
->
surface
->
Data
.
Locked
)
{
if
(
cur
->
surface
&&
!
cur
->
surface
->
Data
.
Locked
&&
!
cur
->
queued
)
{
cur
->
surface
=
NULL
;
av_frame_unref
(
cur
->
frame
);
}
...
...
@@ -191,12 +196,12 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **
return
0
;
}
static
A
VFrame
*
find_frame
(
QSVContext
*
q
,
mfxFrameSurface1
*
surf
)
static
QS
VFrame
*
find_frame
(
QSVContext
*
q
,
mfxFrameSurface1
*
surf
)
{
QSVFrame
*
cur
=
q
->
work_frames
;
while
(
cur
)
{
if
(
surf
==
cur
->
surface
)
return
cur
->
frame
;
return
cur
;
cur
=
cur
->
next
;
}
return
NULL
;
...
...
@@ -206,6 +211,7 @@ int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
AVFrame
*
frame
,
int
*
got_frame
,
AVPacket
*
avpkt
)
{
QSVFrame
*
out_frame
;
mfxFrameSurface1
*
insurf
;
mfxFrameSurface1
*
outsurf
;
mfxSyncPoint
sync
;
...
...
@@ -240,21 +246,37 @@ int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
}
if
(
sync
)
{
AVFrame
*
src_frame
;
MFXVideoCORE_SyncOperation
(
q
->
session
,
sync
,
60000
);
QSVFrame
*
out_frame
=
find_frame
(
q
,
outsurf
);
src_frame
=
find_frame
(
q
,
outsurf
);
if
(
!
src_frame
)
{
if
(
!
out_frame
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"The returned surface does not correspond to any frame
\n
"
);
return
AVERROR_BUG
;
}
out_frame
->
queued
=
1
;
av_fifo_generic_write
(
q
->
async_fifo
,
&
out_frame
,
sizeof
(
out_frame
),
NULL
);
av_fifo_generic_write
(
q
->
async_fifo
,
&
sync
,
sizeof
(
sync
),
NULL
);
}
if
(
!
av_fifo_space
(
q
->
async_fifo
)
||
(
!
avpkt
->
size
&&
av_fifo_size
(
q
->
async_fifo
)))
{
AVFrame
*
src_frame
;
av_fifo_generic_read
(
q
->
async_fifo
,
&
out_frame
,
sizeof
(
out_frame
),
NULL
);
av_fifo_generic_read
(
q
->
async_fifo
,
&
sync
,
sizeof
(
sync
),
NULL
);
out_frame
->
queued
=
0
;
MFXVideoCORE_SyncOperation
(
q
->
session
,
sync
,
60000
);
src_frame
=
out_frame
->
frame
;
ret
=
av_frame_ref
(
frame
,
src_frame
);
if
(
ret
<
0
)
return
ret
;
outsurf
=
out_frame
->
surface
;
frame
->
pkt_pts
=
frame
->
pts
=
outsurf
->
Data
.
TimeStamp
;
frame
->
repeat_pict
=
...
...
@@ -283,6 +305,9 @@ int ff_qsv_decode_close(QSVContext *q)
cur
=
q
->
work_frames
;
}
av_fifo_free
(
q
->
async_fifo
);
q
->
async_fifo
=
NULL
;
if
(
q
->
internal_session
)
MFXClose
(
q
->
internal_session
);
...
...
libavcodec/qsvdec.h
View file @
f5c4d38c
...
...
@@ -28,6 +28,7 @@
#include <mfx/mfxvideo.h>
#include "libavutil/fifo.h"
#include "libavutil/frame.h"
#include "libavutil/pixfmt.h"
...
...
@@ -47,6 +48,8 @@ typedef struct QSVContext {
*/
QSVFrame
*
work_frames
;
AVFifoBuffer
*
async_fifo
;
// options set by the caller
int
async_depth
;
int
iopattern
;
...
...
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