| 741 | } |
| 742 | |
| 743 | int ff_vvc_frame_thread_init(VVCFrameContext *fc) |
| 744 | { |
| 745 | const VVCSPS *sps = fc->ps.sps; |
| 746 | const VVCPPS *pps = fc->ps.pps; |
| 747 | VVCFrameThread *ft = fc->ft; |
| 748 | int ret; |
| 749 | |
| 750 | if (!ft || ft->ctu_width != pps->ctb_width || |
| 751 | ft->ctu_height != pps->ctb_height || |
| 752 | ft->ctu_size != sps->ctb_size_y) { |
| 753 | |
| 754 | ff_vvc_frame_thread_free(fc); |
| 755 | ft = av_calloc(1, sizeof(*fc->ft)); |
| 756 | if (!ft) |
| 757 | return AVERROR(ENOMEM); |
| 758 | |
| 759 | ft->ctu_width = fc->ps.pps->ctb_width; |
| 760 | ft->ctu_height = fc->ps.pps->ctb_height; |
| 761 | ft->ctu_count = fc->ps.pps->ctb_count; |
| 762 | ft->ctu_size = fc->ps.sps->ctb_size_y; |
| 763 | |
| 764 | ft->rows = av_calloc(ft->ctu_height, sizeof(*ft->rows)); |
| 765 | if (!ft->rows) |
| 766 | goto fail; |
| 767 | |
| 768 | ft->tasks = av_malloc(ft->ctu_count * sizeof(*ft->tasks)); |
| 769 | if (!ft->tasks) |
| 770 | goto fail; |
| 771 | |
| 772 | if ((ret = ff_cond_init(&ft->cond, NULL))) |
| 773 | goto fail; |
| 774 | |
| 775 | if ((ret = ff_mutex_init(&ft->lock, NULL))) { |
| 776 | ff_cond_destroy(&ft->cond); |
| 777 | goto fail; |
| 778 | } |
| 779 | } |
| 780 | fc->ft = ft; |
| 781 | ft->ret = 0; |
| 782 | for (int y = 0; y < ft->ctu_height; y++) { |
| 783 | VVCRowThread *row = ft->rows + y; |
| 784 | memset(row->col_progress, 0, sizeof(row->col_progress)); |
| 785 | } |
| 786 | |
| 787 | for (int rs = 0; rs < ft->ctu_count; rs++) { |
| 788 | VVCTask *t = ft->tasks + rs; |
| 789 | task_init(t, rs ? VVC_TASK_STAGE_PARSE : VVC_TASK_STAGE_INIT, fc, rs % ft->ctu_width, rs / ft->ctu_width); |
| 790 | } |
| 791 | |
| 792 | memset(&ft->row_progress[0], 0, sizeof(ft->row_progress)); |
| 793 | |
| 794 | frame_thread_init_score(fc); |
| 795 | |
| 796 | return 0; |
| 797 | |
| 798 | fail: |
| 799 | if (ft) { |
| 800 | av_freep(&ft->rows); |
no test coverage detected