Mercurial > libavcodec.hg
annotate pthread.c @ 10874:bcfe2acbf190 libavcodec
AAC: Compress codebook tables and optimise sign bit handling
The codebooks each consist of small number of values repeated in
groups of 2 or 4. Storing the codebooks as a packed list of 2- or
4-bit indexes into a table reduces their size substantially (from 7.5k
to 1.5k), resulting in less cache pressure.
For the band types with sign bits in the bitstream, storing the number
and position of non-zero codebook values using a few bits avoids
multiple get_bits() calls and floating-point comparisons which gcc
handles miserably.
Some float/int type punning also avoids gcc brain damage.
Overall speedup 20-35% on Cortex-A8, 20% on Core i7.
| author | mru |
|---|---|
| date | Wed, 13 Jan 2010 16:46:28 +0000 |
| parents | 98501365c3aa |
| children | d7ef6611a49e |
| 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 | |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
148 c = av_mallocz(sizeof(ThreadContext)); |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
149 if (!c) |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
150 return -1; |
| 2967 | 151 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
152 c->workers = av_mallocz(sizeof(pthread_t)*thread_count); |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
153 if (!c->workers) { |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
154 av_free(c); |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
155 return -1; |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
156 } |
| 1799 | 157 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
158 avctx->thread_opaque = c; |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
159 avctx->thread_count = thread_count; |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
160 c->current_job = 0; |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
161 c->job_count = 0; |
|
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
162 c->job_size = 0; |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
163 c->done = 0; |
| 2967 | 164 pthread_cond_init(&c->current_job_cond, NULL); |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
165 pthread_cond_init(&c->last_job_cond, NULL); |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
166 pthread_mutex_init(&c->current_job_lock, NULL); |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
167 pthread_mutex_lock(&c->current_job_lock); |
| 2967 | 168 for (i=0; i<thread_count; i++) { |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
169 if(pthread_create(&c->workers[i], NULL, worker, avctx)) { |
| 2979 | 170 avctx->thread_count = i; |
| 171 pthread_mutex_unlock(&c->current_job_lock); | |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
172 avcodec_thread_free(avctx); |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
173 return -1; |
|
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
174 } |
| 1799 | 175 } |
| 2967 | 176 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
177 avcodec_thread_park_workers(c, thread_count); |
| 2967 | 178 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
179 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
|
180 avctx->execute2 = avcodec_thread_execute2; |
| 1799 | 181 return 0; |
| 182 } |
