| 561 | } |
| 562 | |
| 563 | int ff_thread_receive_frame(AVCodecContext *avctx, AVFrame *frame, unsigned flags) |
| 564 | { |
| 565 | FrameThreadContext *fctx = avctx->internal->thread_ctx; |
| 566 | int ret = 0; |
| 567 | |
| 568 | /* release the async lock, permitting blocked hwaccel threads to |
| 569 | * go forward while we are in this function */ |
| 570 | async_unlock(fctx); |
| 571 | |
| 572 | /* submit packets to threads while there are no buffered results to return */ |
| 573 | while (!fctx->df.nb_f && !fctx->result) { |
| 574 | PerThreadContext *p; |
| 575 | |
| 576 | if (fctx->next_decoding != fctx->next_finished && |
| 577 | (flags & AV_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS)) |
| 578 | goto wait_for_result; |
| 579 | |
| 580 | /* get a packet to be submitted to the next thread */ |
| 581 | av_packet_unref(fctx->next_pkt); |
| 582 | ret = ff_decode_get_packet(avctx, fctx->next_pkt); |
| 583 | if (ret < 0 && ret != AVERROR_EOF) |
| 584 | goto finish; |
| 585 | |
| 586 | ret = submit_packet(&fctx->threads[fctx->next_decoding], avctx, |
| 587 | fctx->next_pkt); |
| 588 | if (ret < 0) |
| 589 | goto finish; |
| 590 | |
| 591 | /* do not return any frames until all threads have something to do */ |
| 592 | if (fctx->next_decoding != fctx->next_finished && |
| 593 | !avctx->internal->draining) |
| 594 | continue; |
| 595 | |
| 596 | wait_for_result: |
| 597 | p = &fctx->threads[fctx->next_finished]; |
| 598 | fctx->next_finished = (fctx->next_finished + 1) % avctx->thread_count; |
| 599 | |
| 600 | if (atomic_load(&p->state) != STATE_INPUT_READY) { |
| 601 | pthread_mutex_lock(&p->progress_mutex); |
| 602 | while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) |
| 603 | pthread_cond_wait(&p->output_cond, &p->progress_mutex); |
| 604 | pthread_mutex_unlock(&p->progress_mutex); |
| 605 | } |
| 606 | |
| 607 | update_context_from_thread(avctx, p->avctx, 1); |
| 608 | fctx->result = p->result; |
| 609 | p->result = 0; |
| 610 | if (p->df.nb_f) |
| 611 | FFSWAP(DecodedFrames, fctx->df, p->df); |
| 612 | } |
| 613 | |
| 614 | /* a thread may return multiple frames AND an error |
| 615 | * we first return all the frames, then the error */ |
| 616 | if (fctx->df.nb_f) { |
| 617 | decoded_frames_pop(&fctx->df, frame); |
| 618 | ret = 0; |
| 619 | } else { |
| 620 | ret = fctx->result; |
no test coverage detected