| @@ -41,6 +41,11 @@ typedef int (action_func)(AVCodecContext *c, void *arg); · 40 unmodified lines |
| 41 | typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); | 41 | typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); |
| 42 | typedef int (main_func)(AVCodecContext *c); | 42 | typedef int (main_func)(AVCodecContext *c); |
| 43 | | 43 | |
| | 44 | typedef struct Progress { |
| | 45 | pthread_cond_t cond; |
| | 46 | pthread_mutex_t mutex; |
| | 47 | } Progress; |
| | 48 | |
| 44 | typedef struct SliceThreadContext { | 49 | typedef struct SliceThreadContext { |
| 45 | AVSliceThread *thread; | 50 | AVSliceThread *thread; |
| 46 | action_func *func; | 51 | action_func *func; |
| @@ -53,8 +58,7 @@ typedef struct SliceThreadContext { · 6 unmodified lines |
| 53 | int *entries; | 58 | int *entries; |
| 54 | int entries_count; | 59 | int entries_count; |
| 55 | int thread_count; | 60 | int thread_count; |
| 56 | pthread_cond_t *progress_cond; | 61 | Progress *progress; |
| 57 | pthread_mutex_t *progress_mutex; | | |
| 58 | } SliceThreadContext; | 62 | } SliceThreadContext; |
| 59 | | 63 | |
| 60 | static void main_function(void *priv) { | 64 | static void main_function(void *priv) { |
| @@ -83,13 +87,13 @@ void ff_slice_thread_free(AVCodecContext *avctx) · 22 unmodified lines |
| 83 | avpriv_slicethread_free(&c->thread); | 87 | avpriv_slicethread_free(&c->thread); |
| 84 | | 88 | |
| 85 | for (i = 0; i < c->thread_count; i++) { | 89 | for (i = 0; i < c->thread_count; i++) { |
| 86 | pthread_mutex_destroy(&c->progress_mutex[i]); | 90 | Progress *const progress = &c->progress[i]; |
| 87 | pthread_cond_destroy(&c->progress_cond[i]); | 91 | pthread_mutex_destroy(&progress->mutex); |
| | 92 | pthread_cond_destroy(&progress->cond); |
| 88 | } | 93 | } |
| 89 | | 94 | |
| 90 | av_freep(&c->entries); | 95 | av_freep(&c->entries); |
| 91 | av_freep(&c->progress_mutex); | 96 | av_freep(&c->progress); |
| 92 | av_freep(&c->progress_cond); | | |
| 93 | av_freep(&avctx->internal->thread_ctx); | 97 | av_freep(&avctx->internal->thread_ctx); |
| 94 | } | 98 | } |
| 95 | | 99 | |
| @@ -172,65 +176,82 @@ int ff_slice_thread_init(AVCodecContext *avctx) · 76 unmodified lines |
| 172 | return 0; | 176 | return 0; |
| 173 | } | 177 | } |
| 174 | | 178 | |
| | 179 | int av_cold ff_slice_thread_init_progress(AVCodecContext *avctx) |
| | 180 | { |
| | 181 | SliceThreadContext *const p = avctx->internal->thread_ctx; |
| | 182 | int err, i = 0, thread_count = avctx->thread_count; |
| | 183 | |
| | 184 | p->progress = av_calloc(thread_count, sizeof(*p->progress)); |
| | 185 | if (!p->progress) { |
| | 186 | err = AVERROR(ENOMEM); |
| | 187 | goto fail; |
| | 188 | } |
| | 189 | |
| | 190 | for (; i < thread_count; i++) { |
| | 191 | Progress *const progress = &p->progress[i]; |
| | 192 | err = pthread_mutex_init(&progress->mutex, NULL); |
| | 193 | if (err) { |
| | 194 | err = AVERROR(err); |
| | 195 | goto fail; |
| | 196 | } |
| | 197 | err = pthread_cond_init (&progress->cond, NULL); |
| | 198 | if (err) { |
| | 199 | err = AVERROR(err); |
| | 200 | pthread_mutex_destroy(&progress->mutex); |
| | 201 | goto fail; |
| | 202 | } |
| | 203 | } |
| | 204 | err = 0; |
| | 205 | fail: |
| | 206 | p->thread_count = i; |
| | 207 | return err; |
| | 208 | } |
| | 209 | |
| 175 | void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) | 210 | void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) |
| 176 | { | 211 | { |
| 177 | SliceThreadContext *p = avctx->internal->thread_ctx; | 212 | SliceThreadContext *p = avctx->internal->thread_ctx; |
| | 213 | Progress *const progress = &p->progress[thread]; |
| 178 | int *entries = p->entries; | 214 | int *entries = p->entries; |
| 179 | | 215 | |
| 180 | pthread_mutex_lock(&p->progress_mutex[thread]); | 216 | pthread_mutex_lock(&progress->mutex); |
| 181 | entries[field] +=n; | 217 | entries[field] +=n; |
| 182 | pthread_cond_signal(&p->progress_cond[thread]); | 218 | pthread_cond_signal(&progress->cond); |
| 183 | pthread_mutex_unlock(&p->progress_mutex[thread]); | 219 | pthread_mutex_unlock(&progress->mutex); |
| 184 | } | 220 | } |
| 185 | | 221 | |
| 186 | void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) | 222 | void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) |
| 187 | { | 223 | { |
| 188 | SliceThreadContext *p = avctx->internal->thread_ctx; | 224 | SliceThreadContext *p = avctx->internal->thread_ctx; |
| | 225 | Progress *progress; |
| 189 | int *entries = p->entries; | 226 | int *entries = p->entries; |
| 190 | | 227 | |
| 191 | if (!entries || !field) return; | 228 | if (!entries || !field) return; |
| 192 | | 229 | |
| 193 | thread = thread ? thread - 1 : p->thread_count - 1; | 230 | thread = thread ? thread - 1 : p->thread_count - 1; |
| | 231 | progress = &p->progress[thread]; |
| 194 | | 232 | |
| 195 | pthread_mutex_lock(&p->progress_mutex[thread]); | 233 | pthread_mutex_lock(&progress->mutex); |
| 196 | while ((entries[field - 1] - entries[field]) < shift){ | 234 | while ((entries[field - 1] - entries[field]) < shift){ |
| 197 | pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]); | 235 | pthread_cond_wait(&progress->cond, &progress->mutex); |
| 198 | } | 236 | } |
| 199 | pthread_mutex_unlock(&p->progress_mutex[thread]); | 237 | pthread_mutex_unlock(&progress->mutex); |
| 200 | } | 238 | } |
| 201 | | 239 | |
| 202 | int ff_alloc_entries(AVCodecContext *avctx, int count) | 240 | int ff_alloc_entries(AVCodecContext *avctx, int count) |
| 203 | { | 241 | { |
| 204 | int i; | | |
| 205 | | | |
| 206 | if (avctx->active_thread_type & FF_THREAD_SLICE) { | 242 | if (avctx->active_thread_type & FF_THREAD_SLICE) { |
| 207 | SliceThreadContext *p = avctx->internal->thread_ctx; | 243 | SliceThreadContext *p = avctx->internal->thread_ctx; |
| 208 | | 244 | |
| 209 | if (p->entries) { | 245 | if (p->entries) { |
| 210 | av_assert0(p->thread_count == avctx->thread_count); | | |
| 211 | av_freep(&p->entries); | 246 | av_freep(&p->entries); |
| 212 | } | 247 | } |
| 213 | | 248 | |
| 214 | p->thread_count = avctx->thread_count; | | |
| 215 | p->entries = av_calloc(count, sizeof(*p->entries)); | 249 | p->entries = av_calloc(count, sizeof(*p->entries)); |
| 216 | | 250 | if (!p->entries) { |
| 217 | if (!p->progress_mutex) { | 251 | p->entries_count = 0; |
| 218 | p->progress_mutex = av_malloc_array(p->thread_count, sizeof(pthread_mutex_t)); | | |
| 219 | p->progress_cond = av_malloc_array(p->thread_count, sizeof(pthread_cond_t)); | | |
| 220 | } | | |
| 221 | | | |
| 222 | if (!p->entries || !p->progress_mutex || !p->progress_cond) { | | |
| 223 | av_freep(&p->entries); | | |
| 224 | av_freep(&p->progress_mutex); | | |
| 225 | av_freep(&p->progress_cond); | | |
| 226 | return AVERROR(ENOMEM); | 252 | return AVERROR(ENOMEM); |
| 227 | } | 253 | } |
| 228 | p->entries_count = count; | 254 | p->entries_count = count; |
| 229 | | | |
| 230 | for (i = 0; i < p->thread_count; i++) { | | |
| 231 | pthread_mutex_init(&p->progress_mutex[i], NULL); | | |
| 232 | pthread_cond_init(&p->progress_cond[i], NULL); | | |
| 233 | } | | |
| 234 | } | 255 | } |
| 235 | | 256 | |
| 236 | return 0; | 257 | return 0; |