Mercurial > libavcodec.hg
annotate pthread.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | d7ef6611a49e |
children | 8de15f200be8 |
rev | line source |
---|---|
1799 | 1 /* |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8333
diff
changeset
|
2 * Copyright (c) 2004 Roman Shaposhnik |
2967 | 3 * |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
4 * Many thanks to Steven M. Schultz for providing clever ideas and |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
5 * to Michael Niedermayer <michaelni@gmx.at> for writing initial |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
6 * implementation. |
1799 | 7 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
8 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
9 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * FFmpeg is free software; you can redistribute it and/or |
1799 | 11 * modify it under the terms of the GNU Lesser General Public |
12 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
13 * version 2.1 of the License, or (at your option) any later version. |
1799 | 14 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
15 * FFmpeg is distributed in the hope that it will be useful, |
1799 | 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 * Lesser General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
21 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1799 | 23 */ |
24 #include <pthread.h> | |
25 | |
26 #include "avcodec.h" | |
27 | |
8333 | 28 typedef int (action_func)(AVCodecContext *c, void *arg); |
10386
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
29 typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); |
1857 | 30 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
31 typedef struct ThreadContext { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
32 pthread_t *workers; |
8333 | 33 action_func *func; |
10386
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
34 action_func2 *func2; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
35 void *args; |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
36 int *rets; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
37 int rets_count; |
1857 | 38 int job_count; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
39 int job_size; |
2967 | 40 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
41 pthread_cond_t last_job_cond; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
42 pthread_cond_t current_job_cond; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
43 pthread_mutex_t current_job_lock; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
44 int current_job; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
45 int done; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
46 } ThreadContext; |
1799 | 47 |
5542
b0a566346fb1
Add attribute that forces alignment of stack to functions that need it.
ramiro
parents:
5232
diff
changeset
|
48 static void* attribute_align_arg worker(void *v) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
49 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
50 AVCodecContext *avctx = v; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
51 ThreadContext *c = avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
52 int our_job = c->job_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
53 int thread_count = avctx->thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
54 int self_id; |
1799 | 55 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
56 pthread_mutex_lock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
57 self_id = c->current_job++; |
2967 | 58 for (;;){ |
2979 | 59 while (our_job >= c->job_count) { |
60 if (c->current_job == thread_count + c->job_count) | |
61 pthread_cond_signal(&c->last_job_cond); | |
2967 | 62 |
2979 | 63 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
64 our_job = self_id; |
2967 | 65 |
2979 | 66 if (c->done) { |
67 pthread_mutex_unlock(&c->current_job_lock); | |
68 return NULL; | |
69 } | |
70 } | |
71 pthread_mutex_unlock(&c->current_job_lock); | |
2967 | 72 |
10386
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
73 c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size): |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
74 c->func2(avctx, c->args, our_job, self_id); |
2967 | 75 |
2979 | 76 pthread_mutex_lock(&c->current_job_lock); |
77 our_job = c->current_job++; | |
1799 | 78 } |
79 } | |
80 | |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
3947
diff
changeset
|
81 static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
82 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
83 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
84 pthread_mutex_unlock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
85 } |
1799 | 86 |
2967 | 87 void avcodec_thread_free(AVCodecContext *avctx) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
88 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
89 ThreadContext *c = avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
90 int i; |
2967 | 91 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
92 pthread_mutex_lock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
93 c->done = 1; |
2035
e1b69326ae36
10l fixes by ("Debabrata Banerjee" <davatar at comcast dot net>)
michael
parents:
2023
diff
changeset
|
94 pthread_cond_broadcast(&c->current_job_cond); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
95 pthread_mutex_unlock(&c->current_job_lock); |
1857 | 96 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
97 for (i=0; i<avctx->thread_count; i++) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
98 pthread_join(c->workers[i], NULL); |
1857 | 99 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
100 pthread_mutex_destroy(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
101 pthread_cond_destroy(&c->current_job_cond); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
102 pthread_cond_destroy(&c->last_job_cond); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
103 av_free(c->workers); |
5232 | 104 av_freep(&avctx->thread_opaque); |
1799 | 105 } |
106 | |
8333 | 107 int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
108 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
109 ThreadContext *c= avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
110 int dummy_ret; |
2967 | 111 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
112 if (job_count <= 0) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
113 return 0; |
2967 | 114 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
115 pthread_mutex_lock(&c->current_job_lock); |
1799 | 116 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
117 c->current_job = avctx->thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
118 c->job_count = job_count; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
119 c->job_size = job_size; |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
120 c->args = arg; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
121 c->func = func; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
122 if (ret) { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
123 c->rets = ret; |
2979 | 124 c->rets_count = job_count; |
2967 | 125 } else { |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
126 c->rets = &dummy_ret; |
2979 | 127 c->rets_count = 1; |
1799 | 128 } |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
129 pthread_cond_broadcast(&c->current_job_cond); |
1857 | 130 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
131 avcodec_thread_park_workers(c, avctx->thread_count); |
2967 | 132 |
1799 | 133 return 0; |
134 } | |
135 | |
10386
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
136 int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count) |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
137 { |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
138 ThreadContext *c= avctx->thread_opaque; |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
139 c->func2 = func2; |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
140 return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0); |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
141 } |
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
142 |
2967 | 143 int avcodec_thread_init(AVCodecContext *avctx, int thread_count) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
144 { |
1799 | 145 int i; |
146 ThreadContext *c; | |
147 | |
10954 | 148 avctx->thread_count = thread_count; |
149 | |
150 if (thread_count <= 1) | |
151 return 0; | |
152 | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
153 c = av_mallocz(sizeof(ThreadContext)); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
154 if (!c) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
155 return -1; |
2967 | 156 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
157 c->workers = av_mallocz(sizeof(pthread_t)*thread_count); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
158 if (!c->workers) { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
159 av_free(c); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
160 return -1; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
161 } |
1799 | 162 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
163 avctx->thread_opaque = c; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
164 c->current_job = 0; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
165 c->job_count = 0; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
166 c->job_size = 0; |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
167 c->done = 0; |
2967 | 168 pthread_cond_init(&c->current_job_cond, NULL); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
169 pthread_cond_init(&c->last_job_cond, NULL); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
170 pthread_mutex_init(&c->current_job_lock, NULL); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
171 pthread_mutex_lock(&c->current_job_lock); |
2967 | 172 for (i=0; i<thread_count; i++) { |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
173 if(pthread_create(&c->workers[i], NULL, worker, avctx)) { |
2979 | 174 avctx->thread_count = i; |
175 pthread_mutex_unlock(&c->current_job_lock); | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
176 avcodec_thread_free(avctx); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
177 return -1; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
178 } |
1799 | 179 } |
2967 | 180 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
181 avcodec_thread_park_workers(c, thread_count); |
2967 | 182 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
183 avctx->execute = avcodec_thread_execute; |
10386
98501365c3aa
Add an execute2 function that is more flexible and allows to use parallel
reimar
parents:
8629
diff
changeset
|
184 avctx->execute2 = avcodec_thread_execute2; |
1799 | 185 return 0; |
186 } |