* Codec worker thread. * * Automatically calls ff_thread_finish_setup() if the codec does * not provide an update_thread_context method, or if the codec returns * before calling it. */
| 242 | * before calling it. |
| 243 | */ |
| 244 | static attribute_align_arg void *frame_worker_thread(void *arg) |
| 245 | { |
| 246 | PerThreadContext *p = arg; |
| 247 | AVCodecContext *avctx = p->avctx; |
| 248 | const FFCodec *codec = ffcodec(avctx->codec); |
| 249 | |
| 250 | thread_set_name(p); |
| 251 | |
| 252 | pthread_mutex_lock(&p->mutex); |
| 253 | while (1) { |
| 254 | int ret; |
| 255 | |
| 256 | while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die) |
| 257 | pthread_cond_wait(&p->input_cond, &p->mutex); |
| 258 | |
| 259 | if (p->die) break; |
| 260 | |
| 261 | if (!codec->update_thread_context) |
| 262 | ff_thread_finish_setup(avctx); |
| 263 | |
| 264 | /* If a decoder supports hwaccel, then it must call ff_get_format(). |
| 265 | * Since that call must happen before ff_thread_finish_setup(), the |
| 266 | * decoder is required to implement update_thread_context() and call |
| 267 | * ff_thread_finish_setup() manually. Therefore the above |
| 268 | * ff_thread_finish_setup() call did not happen and hwaccel_serializing |
| 269 | * cannot be true here. */ |
| 270 | av_assert0(!p->hwaccel_serializing); |
| 271 | |
| 272 | /* if the previous thread uses thread-unsafe hwaccel then we take the |
| 273 | * lock to ensure the threads don't run concurrently */ |
| 274 | if (hwaccel_serial(avctx)) { |
| 275 | pthread_mutex_lock(&p->parent->hwaccel_mutex); |
| 276 | p->hwaccel_serializing = 1; |
| 277 | } |
| 278 | |
| 279 | ret = 0; |
| 280 | while (ret >= 0) { |
| 281 | AVFrame *frame; |
| 282 | |
| 283 | /* get the frame which will store the output */ |
| 284 | frame = decoded_frames_get_free(&p->df); |
| 285 | if (!frame) { |
| 286 | p->result = AVERROR(ENOMEM); |
| 287 | goto alloc_fail; |
| 288 | } |
| 289 | |
| 290 | /* do the actual decoding */ |
| 291 | ret = ff_decode_receive_frame_internal(avctx, frame); |
| 292 | if (ret == 0) |
| 293 | p->df.nb_f++; |
| 294 | else if (ret < 0 && frame->buf[0]) |
| 295 | av_frame_unref(frame); |
| 296 | |
| 297 | p->result = (ret == AVERROR(EAGAIN)) ? 0 : ret; |
| 298 | } |
| 299 | |
| 300 | if (atomic_load(&p->state) == STATE_SETTING_UP) |
| 301 | ff_thread_finish_setup(avctx); |
nothing calls this directly
no test coverage detected