| 2207 | } |
| 2208 | |
| 2209 | static void mpeg12_execute_slice_threads(AVCodecContext *avctx, |
| 2210 | Mpeg1Context *const s) |
| 2211 | { |
| 2212 | if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && |
| 2213 | !avctx->hwaccel) { |
| 2214 | MPVContext *const s2 = &s->slice.c; |
| 2215 | int error_count = 0; |
| 2216 | |
| 2217 | avctx->execute(avctx, slice_decode_thread, |
| 2218 | s2->mpeg12_contexts, NULL, |
| 2219 | s->slice_count, sizeof(s2->mpeg12_contexts[0])); |
| 2220 | |
| 2221 | for (int i = 0; i < s->slice_count; i++) { |
| 2222 | MpegEncContext *const slice = s2->thread_context[i]; |
| 2223 | int slice_err = atomic_load_explicit(&slice->er.error_count, |
| 2224 | memory_order_relaxed); |
| 2225 | // error_count can get set to INT_MAX on serious errors. |
| 2226 | // So use saturated addition. |
| 2227 | if ((unsigned)slice_err > INT_MAX - error_count) { |
| 2228 | error_count = INT_MAX; |
| 2229 | break; |
| 2230 | } |
| 2231 | error_count += slice_err; |
| 2232 | } |
| 2233 | atomic_store_explicit(&s2->er.error_count, error_count, |
| 2234 | memory_order_relaxed); |
| 2235 | } |
| 2236 | } |
| 2237 | |
| 2238 | static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, |
| 2239 | int *got_output, const uint8_t *buf, int buf_size) |