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
8dfba25c
Commit
8dfba25c
authored
Dec 03, 2016
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pthread_frame: ensure the threads don't run simultaneously with hwaccel
parent
373fd76b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
37 additions
and
2 deletions
+37
-2
h263dec.c
libavcodec/h263dec.c
+1
-1
h264dec.c
libavcodec/h264dec.c
+1
-1
pthread_frame.c
libavcodec/pthread_frame.c
+35
-0
No files found.
libavcodec/h263dec.c
View file @
8dfba25c
...
@@ -558,7 +558,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -558,7 +558,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
if
((
ret
=
ff_mpv_frame_start
(
s
,
avctx
))
<
0
)
if
((
ret
=
ff_mpv_frame_start
(
s
,
avctx
))
<
0
)
return
ret
;
return
ret
;
if
(
!
s
->
divx_packed
&&
!
avctx
->
hwaccel
)
if
(
!
s
->
divx_packed
)
ff_thread_finish_setup
(
avctx
);
ff_thread_finish_setup
(
avctx
);
if
(
avctx
->
hwaccel
)
{
if
(
avctx
->
hwaccel
)
{
...
...
libavcodec/h264dec.c
View file @
8dfba25c
...
@@ -573,7 +573,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
...
@@ -573,7 +573,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
if
((
err
=
ff_h264_queue_decode_slice
(
h
,
nal
)))
if
((
err
=
ff_h264_queue_decode_slice
(
h
,
nal
)))
break
;
break
;
if
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
&&
!
h
->
avctx
->
hwaccel
&&
if
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
&&
i
>=
nals_needed
&&
!
h
->
setup_finished
&&
h
->
cur_pic_ptr
)
{
i
>=
nals_needed
&&
!
h
->
setup_finished
&&
h
->
cur_pic_ptr
)
{
ff_thread_finish_setup
(
avctx
);
ff_thread_finish_setup
(
avctx
);
h
->
setup_finished
=
1
;
h
->
setup_finished
=
1
;
...
...
libavcodec/pthread_frame.c
View file @
8dfba25c
...
@@ -99,6 +99,8 @@ typedef struct PerThreadContext {
...
@@ -99,6 +99,8 @@ typedef struct PerThreadContext {
int
requested_flags
;
///< flags passed to get_buffer() for requested_frame
int
requested_flags
;
///< flags passed to get_buffer() for requested_frame
int
die
;
///< Set when the thread should exit.
int
die
;
///< Set when the thread should exit.
int
hwaccel_serializing
;
}
PerThreadContext
;
}
PerThreadContext
;
/**
/**
...
@@ -109,6 +111,11 @@ typedef struct FrameThreadContext {
...
@@ -109,6 +111,11 @@ typedef struct FrameThreadContext {
PerThreadContext
*
prev_thread
;
///< The last thread submit_packet() was called on.
PerThreadContext
*
prev_thread
;
///< The last thread submit_packet() was called on.
pthread_mutex_t
buffer_mutex
;
///< Mutex used to protect get/release_buffer().
pthread_mutex_t
buffer_mutex
;
///< Mutex used to protect get/release_buffer().
/**
* This lock is used for ensuring threads run in serial when hwaccel
* is used.
*/
pthread_mutex_t
hwaccel_mutex
;
int
next_decoding
;
///< The next context to submit a packet to.
int
next_decoding
;
///< The next context to submit a packet to.
int
next_finished
;
///< The next context to return output from.
int
next_finished
;
///< The next context to return output from.
...
@@ -149,6 +156,22 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
...
@@ -149,6 +156,22 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
ff_thread_finish_setup
(
avctx
);
ff_thread_finish_setup
(
avctx
);
pthread_mutex_lock
(
&
p
->
mutex
);
pthread_mutex_lock
(
&
p
->
mutex
);
/* If a decoder supports hwaccel, then it must call ff_get_format().
* Since that call must happen before ff_thread_finish_setup(), the
* decoder is required to implement update_thread_context() and call
* ff_thread_finish_setup() manually. Therefore the above
* ff_thread_finish_setup() call did not happen and hwaccel_serializing
* cannot be true here. */
av_assert0
(
!
p
->
hwaccel_serializing
);
/* if the previous thread uses hwaccel then we take the lock to ensure
* the threads don't run concurrently */
if
(
avctx
->
hwaccel
)
{
pthread_mutex_lock
(
&
p
->
parent
->
hwaccel_mutex
);
p
->
hwaccel_serializing
=
1
;
}
av_frame_unref
(
p
->
frame
);
av_frame_unref
(
p
->
frame
);
p
->
got_frame
=
0
;
p
->
got_frame
=
0
;
p
->
result
=
codec
->
decode
(
avctx
,
p
->
frame
,
&
p
->
got_frame
,
&
p
->
avpkt
);
p
->
result
=
codec
->
decode
(
avctx
,
p
->
frame
,
&
p
->
got_frame
,
&
p
->
avpkt
);
...
@@ -163,6 +186,11 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
...
@@ -163,6 +186,11 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
if
(
atomic_load
(
&
p
->
state
)
==
STATE_SETTING_UP
)
if
(
atomic_load
(
&
p
->
state
)
==
STATE_SETTING_UP
)
ff_thread_finish_setup
(
avctx
);
ff_thread_finish_setup
(
avctx
);
if
(
p
->
hwaccel_serializing
)
{
p
->
hwaccel_serializing
=
0
;
pthread_mutex_unlock
(
&
p
->
parent
->
hwaccel_mutex
);
}
atomic_store
(
&
p
->
state
,
STATE_INPUT_READY
);
atomic_store
(
&
p
->
state
,
STATE_INPUT_READY
);
pthread_mutex_lock
(
&
p
->
progress_mutex
);
pthread_mutex_lock
(
&
p
->
progress_mutex
);
...
@@ -499,6 +527,11 @@ void ff_thread_finish_setup(AVCodecContext *avctx) {
...
@@ -499,6 +527,11 @@ void ff_thread_finish_setup(AVCodecContext *avctx) {
if
(
!
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
))
return
;
if
(
!
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
))
return
;
if
(
avctx
->
hwaccel
&&
!
p
->
hwaccel_serializing
)
{
pthread_mutex_lock
(
&
p
->
parent
->
hwaccel_mutex
);
p
->
hwaccel_serializing
=
1
;
}
pthread_mutex_lock
(
&
p
->
progress_mutex
);
pthread_mutex_lock
(
&
p
->
progress_mutex
);
atomic_store
(
&
p
->
state
,
STATE_SETUP_FINISHED
);
atomic_store
(
&
p
->
state
,
STATE_SETUP_FINISHED
);
...
@@ -579,6 +612,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
...
@@ -579,6 +612,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
av_freep
(
&
fctx
->
threads
);
av_freep
(
&
fctx
->
threads
);
pthread_mutex_destroy
(
&
fctx
->
buffer_mutex
);
pthread_mutex_destroy
(
&
fctx
->
buffer_mutex
);
pthread_mutex_destroy
(
&
fctx
->
hwaccel_mutex
);
av_freep
(
&
avctx
->
internal
->
thread_ctx
);
av_freep
(
&
avctx
->
internal
->
thread_ctx
);
}
}
...
@@ -620,6 +654,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
...
@@ -620,6 +654,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
}
}
pthread_mutex_init
(
&
fctx
->
buffer_mutex
,
NULL
);
pthread_mutex_init
(
&
fctx
->
buffer_mutex
,
NULL
);
pthread_mutex_init
(
&
fctx
->
hwaccel_mutex
,
NULL
);
fctx
->
delaying
=
1
;
fctx
->
delaying
=
1
;
for
(
i
=
0
;
i
<
thread_count
;
i
++
)
{
for
(
i
=
0
;
i
<
thread_count
;
i
++
)
{
...
...
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