2 * Copyright (c) 2004 Roman Shaposhnik
3 * Copyright (c) 2008 Alexander Strange (astrange@ithinksw.com)
5 * Many thanks to Steven M. Schultz for providing clever ideas and
6 * to Michael Niedermayer <michaelni@gmx.at> for writing initial
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 * Multithreading support functions
29 * @see doc/multithreading.txt
32 #include "libavutil/thread.h"
35 #include "codec_internal.h"
36 #include "pthread_internal.h"
40 * Set the threading algorithms used.
42 * Threading requires more than one thread.
43 * Frame threading requires entire frames to be passed to the codec,
44 * and introduces extra decoding delay, so is incompatible with low_delay.
46 * @param avctx The context.
48 static void validate_thread_parameters(AVCodecContext
*avctx
)
50 int frame_threading_supported
= (avctx
->codec
->capabilities
& AV_CODEC_CAP_FRAME_THREADS
)
51 #if FF_API_FLAG_TRUNCATED
52 && !(avctx
->flags
& AV_CODEC_FLAG_TRUNCATED
)
54 && !(avctx
->flags
& AV_CODEC_FLAG_LOW_DELAY
)
55 && !(avctx
->flags2
& AV_CODEC_FLAG2_CHUNKS
);
56 if (avctx
->thread_count
== 1) {
57 avctx
->active_thread_type
= 0;
58 } else if (frame_threading_supported
&& (avctx
->thread_type
& FF_THREAD_FRAME
)) {
59 avctx
->active_thread_type
= FF_THREAD_FRAME
;
60 } else if (avctx
->codec
->capabilities
& AV_CODEC_CAP_SLICE_THREADS
&&
61 avctx
->thread_type
& FF_THREAD_SLICE
) {
62 avctx
->active_thread_type
= FF_THREAD_SLICE
;
63 } else if (!(ffcodec(avctx
->codec
)->caps_internal
& FF_CODEC_CAP_AUTO_THREADS
)) {
64 avctx
->thread_count
= 1;
65 avctx
->active_thread_type
= 0;
68 if (avctx
->thread_count
> MAX_AUTO_THREADS
)
69 av_log(avctx
, AV_LOG_WARNING
,
70 "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
71 avctx
->thread_count
, MAX_AUTO_THREADS
);
74 int ff_thread_init(AVCodecContext
*avctx
)
76 validate_thread_parameters(avctx
);
78 if (avctx
->active_thread_type
&FF_THREAD_SLICE
)
79 return ff_slice_thread_init(avctx
);
80 else if (avctx
->active_thread_type
&FF_THREAD_FRAME
)
81 return ff_frame_thread_init(avctx
);
86 void ff_thread_free(AVCodecContext
*avctx
)
88 if (avctx
->active_thread_type
&FF_THREAD_FRAME
)
89 ff_frame_thread_free(avctx
, avctx
->thread_count
);
91 ff_slice_thread_free(avctx
);
94 av_cold
void ff_pthread_free(void *obj
, const unsigned offsets
[])
96 unsigned cnt
= *(unsigned*)((char*)obj
+ offsets
[0]);
97 const unsigned *cur_offset
= offsets
;
99 *(unsigned*)((char*)obj
+ offsets
[0]) = 0;
101 for (; *(++cur_offset
) != THREAD_SENTINEL
&& cnt
; cnt
--)
102 pthread_mutex_destroy((pthread_mutex_t
*)((char*)obj
+ *cur_offset
));
103 for (; *(++cur_offset
) != THREAD_SENTINEL
&& cnt
; cnt
--)
104 pthread_cond_destroy ((pthread_cond_t
*)((char*)obj
+ *cur_offset
));
107 av_cold
int ff_pthread_init(void *obj
, const unsigned offsets
[])
109 const unsigned *cur_offset
= offsets
;
113 #define PTHREAD_INIT_LOOP(type) \
114 for (; *(++cur_offset) != THREAD_SENTINEL; cnt++) { \
115 pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \
116 err = pthread_ ## type ## _init(dst, NULL); \
118 err = AVERROR(err); \
122 PTHREAD_INIT_LOOP(mutex
)
123 PTHREAD_INIT_LOOP(cond
)
126 *(unsigned*)((char*)obj
+ offsets
[0]) = cnt
;