summaryrefslogtreecommitdiff
path: root/libavcodec/frame_thread_encoder.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-08-25 18:59:58 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-09-03 15:41:19 +0200
commit65f68514486fade5c6ab973c90047a422198ce07 (patch)
tree3d1f4a0c33c3ac8a119be7fb42660ca60c7e1382 /libavcodec/frame_thread_encoder.c
parent25ea90b733883d0cbfdb76014b619a1b37489fca (diff)
downloadffmpeg-65f68514486fade5c6ab973c90047a422198ce07.tar.gz
avcodec/frame_thread_encoder: Stop serializing unreferencing AVFrames
Currently, the frame-threaded decoding API still supports thread-unsafe callbacks. If one uses a thread-unsafe get_buffer2() callback, calls to av_frame_unref() by the decoder are serialized, because it is presumed that the underlying deallocator is thread-unsafe. The frame-threaded encoder seems to have been written with this restriction in mind: It always serializes unreferencing its AVFrames, although no documentation forces it to do so. This commit schedules to change this behaviour as soon as thread-unsafe callbacks are removed. For this reason, the FF_API_THREAD_SAFE_CALLBACKS define is reused. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/frame_thread_encoder.c')
-rw-r--r--libavcodec/frame_thread_encoder.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index 1faaef522e..35775ae823 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -48,7 +48,9 @@ typedef struct{
typedef struct{
AVCodecContext *parent_avctx;
+#if FF_API_THREAD_SAFE_CALLBACKS
pthread_mutex_t buffer_mutex;
+#endif
pthread_mutex_t task_fifo_mutex; /* Used to guard (next_)task_index */
pthread_cond_t task_fifo_cond;
@@ -68,9 +70,15 @@ typedef struct{
} ThreadContext;
#define OFF(member) offsetof(ThreadContext, member)
+#if FF_API_THREAD_SAFE_CALLBACKS
DEFINE_OFFSET_ARRAY(ThreadContext, thread_ctx, pthread_init_cnt,
(OFF(buffer_mutex), OFF(task_fifo_mutex), OFF(finished_task_mutex)),
(OFF(task_fifo_cond), OFF(finished_task_cond)));
+#else
+DEFINE_OFFSET_ARRAY(ThreadContext, thread_ctx, pthread_init_cnt,
+ (OFF(task_fifo_mutex), OFF(finished_task_mutex)),
+ (OFF(task_fifo_cond), OFF(finished_task_cond)));
+#endif
#undef OFF
static void * attribute_align_arg worker(void *v){
@@ -104,9 +112,11 @@ static void * attribute_align_arg worker(void *v){
pkt = task->outdata;
ret = ff_encode_encode_cb(avctx, pkt, frame, &task->got_packet);
+#if FF_API_THREAD_SAFE_CALLBACKS
pthread_mutex_lock(&c->buffer_mutex);
av_frame_unref(frame);
pthread_mutex_unlock(&c->buffer_mutex);
+#endif
pthread_mutex_lock(&c->finished_task_mutex);
task->return_code = ret;
task->finished = 1;
@@ -114,9 +124,13 @@ static void * attribute_align_arg worker(void *v){
pthread_mutex_unlock(&c->finished_task_mutex);
}
end:
+#if FF_API_THREAD_SAFE_CALLBACKS
pthread_mutex_lock(&c->buffer_mutex);
+#endif
avcodec_close(avctx);
+#if FF_API_THREAD_SAFE_CALLBACKS
pthread_mutex_unlock(&c->buffer_mutex);
+#endif
av_freep(&avctx);
return NULL;
}