| @@ -54,6 +54,7 @@ · 53 unmodified lines |
| 54 | #include "progressframe.h" | 54 | #include "progressframe.h" |
| 55 | #include "refstruct.h" | 55 | #include "refstruct.h" |
| 56 | #include "thread.h" | 56 | #include "thread.h" |
| | 57 | #include "threadprogress.h" |
| 57 | | 58 | |
| 58 | static const uint8_t hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2, [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] = 9 }; | 59 | static const uint8_t hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2, [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] = 9 }; |
| 59 | | 60 | |
| @@ -2751,6 +2752,8 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, · 2691 unmodified lines |
| 2751 | const uint8_t *data = s->data + s->sh.offset[ctb_row]; | 2752 | const uint8_t *data = s->data + s->sh.offset[ctb_row]; |
| 2752 | const size_t data_size = s->sh.size[ctb_row]; | 2753 | const size_t data_size = s->sh.size[ctb_row]; |
| 2753 | | 2754 | |
| | 2755 | int progress = 0; |
| | 2756 | |
| 2754 | int ret; | 2757 | int ret; |
| 2755 | | 2758 | |
| 2756 | if (ctb_row) | 2759 | if (ctb_row) |
| @@ -2762,13 +2765,15 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, · 5 unmodified lines |
| 2762 | | 2765 | |
| 2763 | hls_decode_neighbour(lc, l, pps, sps, x_ctb, y_ctb, ctb_addr_ts); | 2766 | hls_decode_neighbour(lc, l, pps, sps, x_ctb, y_ctb, ctb_addr_ts); |
| 2764 | | 2767 | |
| 2765 | ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP); | 2768 | if (ctb_row) |
| | 2769 | ff_thread_progress_await(&s->wpp_progress[ctb_row - 1], |
| | 2770 | progress + SHIFT_CTB_WPP + 1); |
| 2766 | | 2771 | |
| 2767 | /* atomic_load's prototype requires a pointer to non-const atomic variable | 2772 | /* atomic_load's prototype requires a pointer to non-const atomic variable |
| 2768 | * (due to implementations via mutexes, where reads involve writes). | 2773 | * (due to implementations via mutexes, where reads involve writes). |
| 2769 | * Of course, casting const away here is nevertheless safe. */ | 2774 | * Of course, casting const away here is nevertheless safe. */ |
| 2770 | if (atomic_load((atomic_int*)&s->wpp_err)) { | 2775 | if (atomic_load((atomic_int*)&s->wpp_err)) { |
| 2771 | ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); | 2776 | ff_thread_progress_report(&s->wpp_progress[ctb_row], INT_MAX); |
| 2772 | return 0; | 2777 | return 0; |
| 2773 | } | 2778 | } |
| 2774 | | 2779 | |
| @@ -2792,19 +2797,19 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, · 17 unmodified lines |
| 2792 | ctb_addr_ts++; | 2797 | ctb_addr_ts++; |
| 2793 | | 2798 | |
| 2794 | ff_hevc_save_states(lc, pps, ctb_addr_ts); | 2799 | ff_hevc_save_states(lc, pps, ctb_addr_ts); |
| 2795 | ff_thread_report_progress2(s->avctx, ctb_row, thread, 1); | 2800 | ff_thread_progress_report(&s->wpp_progress[ctb_row], ++progress); |
| 2796 | ff_hevc_hls_filters(lc, l, pps, x_ctb, y_ctb, ctb_size); | 2801 | ff_hevc_hls_filters(lc, l, pps, x_ctb, y_ctb, ctb_size); |
| 2797 | | 2802 | |
| 2798 | if (!more_data && (x_ctb+ctb_size) < sps->width && ctb_row != s->sh.num_entry_point_offsets) { | 2803 | if (!more_data && (x_ctb+ctb_size) < sps->width && ctb_row != s->sh.num_entry_point_offsets) { |
| 2799 | /* Casting const away here is safe, because it is an atomic operation. */ | 2804 | /* Casting const away here is safe, because it is an atomic operation. */ |
| 2800 | atomic_store((atomic_int*)&s->wpp_err, 1); | 2805 | atomic_store((atomic_int*)&s->wpp_err, 1); |
| 2801 | ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); | 2806 | ff_thread_progress_report(&s->wpp_progress[ctb_row], INT_MAX); |
| 2802 | return 0; | 2807 | return 0; |
| 2803 | } | 2808 | } |
| 2804 | | 2809 | |
| 2805 | if ((x_ctb+ctb_size) >= sps->width && (y_ctb+ctb_size) >= sps->height ) { | 2810 | if ((x_ctb+ctb_size) >= sps->width && (y_ctb+ctb_size) >= sps->height ) { |
| 2806 | ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb, ctb_size); | 2811 | ff_hevc_hls_filter(lc, l, pps, x_ctb, y_ctb, ctb_size); |
| 2807 | ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); | 2812 | ff_thread_progress_report(&s->wpp_progress[ctb_row], INT_MAX); |
| 2808 | return ctb_addr_ts; | 2813 | return ctb_addr_ts; |
| 2809 | } | 2814 | } |
| 2810 | ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; | 2815 | ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; |
| @@ -2814,17 +2819,43 @@ static int hls_decode_entry_wpp(AVCodecContext *avctx, void *hevc_lclist, · 3 unmodified lines |
| 2814 | break; | 2819 | break; |
| 2815 | } | 2820 | } |
| 2816 | } | 2821 | } |
| 2817 | ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); | 2822 | ff_thread_progress_report(&s->wpp_progress[ctb_row], INT_MAX); |
| 2818 | | 2823 | |
| 2819 | return 0; | 2824 | return 0; |
| 2820 | error: | 2825 | error: |
| 2821 | l->tab_slice_address[ctb_addr_rs] = -1; | 2826 | l->tab_slice_address[ctb_addr_rs] = -1; |
| 2822 | /* Casting const away here is safe, because it is an atomic operation. */ | 2827 | /* Casting const away here is safe, because it is an atomic operation. */ |
| 2823 | atomic_store((atomic_int*)&s->wpp_err, 1); | 2828 | atomic_store((atomic_int*)&s->wpp_err, 1); |
| 2824 | ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); | 2829 | ff_thread_progress_report(&s->wpp_progress[ctb_row], INT_MAX); |
| 2825 | return ret; | 2830 | return ret; |
| 2826 | } | 2831 | } |
| 2827 | | 2832 | |
| | 2833 | static int wpp_progress_init(HEVCContext *s, unsigned count) |
| | 2834 | { |
| | 2835 | if (s->nb_wpp_progress < count) { |
| | 2836 | void *tmp = av_realloc_array(s->wpp_progress, count, |
| | 2837 | sizeof(*s->wpp_progress)); |
| | 2838 | if (!tmp) |
| | 2839 | return AVERROR(ENOMEM); |
| | 2840 | |
| | 2841 | s->wpp_progress = tmp; |
| | 2842 | memset(s->wpp_progress + s->nb_wpp_progress, 0, |
| | 2843 | (count - s->nb_wpp_progress) * sizeof(*s->wpp_progress)); |
| | 2844 | |
| | 2845 | for (int i = s->nb_wpp_progress; i < count; i++) { |
| | 2846 | int ret = ff_thread_progress_init(&s->wpp_progress[i], 1); |
| | 2847 | if (ret < 0) |
| | 2848 | return ret; |
| | 2849 | s->nb_wpp_progress = i + 1; |
| | 2850 | } |
| | 2851 | } |
| | 2852 | |
| | 2853 | for (int i = 0; i < count; i++) |
| | 2854 | ff_thread_progress_reset(&s->wpp_progress[i]); |
| | 2855 | |
| | 2856 | return 0; |
| | 2857 | } |
| | 2858 | |
| 2828 | static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) | 2859 | static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) |
| 2829 | { | 2860 | { |
| 2830 | const HEVCPPS *const pps = s->pps; | 2861 | const HEVCPPS *const pps = s->pps; |
| @@ -2909,7 +2940,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) · 78 unmodified lines |
| 2909 | } | 2940 | } |
| 2910 | | 2941 | |
| 2911 | atomic_store(&s->wpp_err, 0); | 2942 | atomic_store(&s->wpp_err, 0); |
| 2912 | res = ff_slice_thread_allocz_entries(s->avctx, s->sh.num_entry_point_offsets + 1); | 2943 | res = wpp_progress_init(s, s->sh.num_entry_point_offsets + 1); |
| 2913 | if (res < 0) | 2944 | if (res < 0) |
| 2914 | return res; | 2945 | return res; |
| 2915 | | 2946 | |
| @@ -3826,6 +3857,10 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) · 910 unmodified lines |
| 3826 | | 3857 | |
| 3827 | ff_hevc_ps_uninit(&s->ps); | 3858 | ff_hevc_ps_uninit(&s->ps); |
| 3828 | | 3859 | |
| | 3860 | for (int i = 0; i < s->nb_wpp_progress; i++) |
| | 3861 | ff_thread_progress_destroy(&s->wpp_progress[i]); |
| | 3862 | av_freep(&s->wpp_progress); |
| | 3863 | |
| 3829 | av_freep(&s->sh.entry_point_offset); | 3864 | av_freep(&s->sh.entry_point_offset); |
| 3830 | av_freep(&s->sh.offset); | 3865 | av_freep(&s->sh.offset); |
| 3831 | av_freep(&s->sh.size); | 3866 | av_freep(&s->sh.size); |
| @@ -3981,12 +4016,6 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) · 149 unmodified lines |
| 3981 | HEVCContext *s = avctx->priv_data; | 4016 | HEVCContext *s = avctx->priv_data; |
| 3982 | int ret; | 4017 | int ret; |
| 3983 | | 4018 | |
| 3984 | if (avctx->active_thread_type & FF_THREAD_SLICE) { | | |
| 3985 | ret = ff_slice_thread_init_progress(avctx); | | |
| 3986 | if (ret < 0) | | |
| 3987 | return ret; | | |
| 3988 | } | | |
| 3989 | | | |
| 3990 | ret = hevc_init_context(avctx); | 4019 | ret = hevc_init_context(avctx); |
| 3991 | if (ret < 0) | 4020 | if (ret < 0) |
| 3992 | return ret; | 4021 | return ret; |