It is more efficient and easier to manage.
Unified · Split
| @@ -2598,7 +2598,7 @@ static int hls_slice_data(HEVCContext *s) · 2597 unmodified lines | |||
| 2598 | static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *hevc_lclist, | 2598 | static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *hevc_lclist, |
| 2599 | int job, int self_id) | 2599 | int job, int self_id) |
| 2600 | { | 2600 | { |
| 2601 | HEVCLocalContext *lc = ((HEVCLocalContext**)hevc_lclist)[self_id]; | 2601 | HEVCLocalContext *lc = &((HEVCLocalContext*)hevc_lclist)[self_id]; |
| 2602 | const HEVCContext *const s = lc->parent; | 2602 | const HEVCContext *const s = lc->parent; |
| 2603 | int ctb_size = 1 << s->ps.sps->log2_ctb_size; | 2603 | int ctb_size = 1 << s->ps.sps->log2_ctb_size; |
| 2604 | int more_data = 1; | 2604 | int more_data = 1; |
| @@ -2682,7 +2682,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) · 77 unmodified lines | |||
| 2682 | { | 2682 | { |
| 2683 | const uint8_t *data = nal->data; | 2683 | const uint8_t *data = nal->data; |
| 2684 | int length = nal->size; | 2684 | int length = nal->size; |
| 2685 | HEVCLocalContext *lc = s->HEVClc; | 2685 | HEVCLocalContext *lc; |
| 2686 | int *ret; | 2686 | int *ret; |
| 2687 | int64_t offset; | 2687 | int64_t offset; |
| 2688 | int64_t startheader, cmpt = 0; | 2688 | int64_t startheader, cmpt = 0; |
| @@ -2696,19 +2696,31 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) · 7 unmodified lines | |||
| 2696 | return AVERROR_INVALIDDATA; | 2696 | return AVERROR_INVALIDDATA; |
| 2697 | } | 2697 | } |
| 2698 | 2698 | ||
| 2699 | for (i = 1; i < s->threads_number; i++) { | 2699 | if (s->threads_number > s->nb_local_ctx) { |
| 2700 | if (i < s->nb_local_ctx) | 2700 | HEVCLocalContext *tmp = av_malloc_array(s->threads_number, sizeof(*s->local_ctx)); |
| 2701 | continue; | 2701 | |
| 2702 | s->local_ctx[i] = av_mallocz(sizeof(HEVCLocalContext)); | 2702 | if (!tmp) |
| 2703 | if (!s->local_ctx[i]) | ||
| 2704 | return AVERROR(ENOMEM); | 2703 | return AVERROR(ENOMEM); |
| 2705 | s->nb_local_ctx++; | ||
| 2706 | 2704 | ||
| 2707 | s->local_ctx[i]->logctx = s->avctx; | 2705 | memcpy(tmp, s->local_ctx, sizeof(*s->local_ctx) * s->nb_local_ctx); |
| 2708 | s->local_ctx[i]->parent = s; | 2706 | av_free(s->local_ctx); |
| 2709 | s->local_ctx[i]->common_cabac_state = &s->cabac; | 2707 | s->local_ctx = tmp; |
| 2708 | s->HEVClc = &s->local_ctx[0]; | ||
| 2709 | |||
| 2710 | for (unsigned i = s->nb_local_ctx; i < s->threads_number; i++) { | ||
| 2711 | tmp = &s->local_ctx[i]; | ||
| 2712 | |||
| 2713 | memset(tmp, 0, sizeof(*tmp)); | ||
| 2714 | |||
| 2715 | tmp->logctx = s->avctx; | ||
| 2716 | tmp->parent = s; | ||
| 2717 | tmp->common_cabac_state = &s->cabac; | ||
| 2718 | } | ||
| 2719 | |||
| 2720 | s->nb_local_ctx = s->threads_number; | ||
| 2710 | } | 2721 | } |
| 2711 | 2722 | ||
| 2723 | lc = &s->local_ctx[0]; | ||
| 2712 | offset = (lc->gb.index >> 3); | 2724 | offset = (lc->gb.index >> 3); |
| 2713 | 2725 | ||
| 2714 | for (j = 0, cmpt = 0, startheader = offset + s->sh.entry_point_offset[0]; j < nal->skipped_bytes; j++) { | 2726 | for (j = 0, cmpt = 0, startheader = offset + s->sh.entry_point_offset[0]; j < nal->skipped_bytes; j++) { |
| @@ -2744,8 +2756,8 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal) · 29 unmodified lines | |||
| 2744 | s->data = data; | 2756 | s->data = data; |
| 2745 | 2757 | ||
| 2746 | for (i = 1; i < s->threads_number; i++) { | 2758 | for (i = 1; i < s->threads_number; i++) { |
| 2747 | s->local_ctx[i]->first_qp_group = 1; | 2759 | s->local_ctx[i].first_qp_group = 1; |
| 2748 | s->local_ctx[i]->qp_y = s->HEVClc->qp_y; | 2760 | s->local_ctx[i].qp_y = s->HEVClc->qp_y; |
| 2749 | } | 2761 | } |
| 2750 | 2762 | ||
| 2751 | atomic_store(&s->wpp_err, 0); | 2763 | atomic_store(&s->wpp_err, 0); |
| @@ -3474,12 +3486,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) · 722 unmodified lines | |||
| 3474 | av_freep(&s->sh.offset); | 3486 | av_freep(&s->sh.offset); |
| 3475 | av_freep(&s->sh.size); | 3487 | av_freep(&s->sh.size); |
| 3476 | 3488 | ||
| 3477 | if (s->local_ctx) { | ||
| 3478 | for (i = 1; i < s->nb_local_ctx; i++) { | ||
| 3479 | av_freep(&s->local_ctx[i]); | ||
| 3480 | } | ||
| 3481 | } | ||
| 3482 | av_freep(&s->HEVClc); | ||
| 3483 | av_freep(&s->local_ctx); | 3489 | av_freep(&s->local_ctx); |
| 3484 | 3490 | ||
| 3485 | ff_h2645_packet_uninit(&s->pkt); | 3491 | ff_h2645_packet_uninit(&s->pkt); |
| @@ -3496,15 +3502,16 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) · 10 unmodified lines | |||
| 3496 | 3502 | ||
| 3497 | s->avctx = avctx; | 3503 | s->avctx = avctx; |
| 3498 | 3504 | ||
| 3499 | s->HEVClc = av_mallocz(sizeof(HEVCLocalContext)); | 3505 | s->local_ctx = av_mallocz(sizeof(*s->local_ctx)); |
| 3500 | s->local_ctx = av_mallocz(sizeof(HEVCLocalContext*) * s->threads_number); | 3506 | if (!s->local_ctx) |
| 3501 | if (!s->HEVClc || !s->local_ctx) | ||
| 3502 | return AVERROR(ENOMEM); | 3507 | return AVERROR(ENOMEM); |
| 3508 | s->nb_local_ctx = 1; | ||
| 3509 | |||
| 3510 | s->HEVClc = &s->local_ctx[0]; | ||
| 3511 | |||
| 3503 | s->HEVClc->parent = s; | 3512 | s->HEVClc->parent = s; |
| 3504 | s->HEVClc->logctx = avctx; | 3513 | s->HEVClc->logctx = avctx; |
| 3505 | s->HEVClc->common_cabac_state = &s->cabac; | 3514 | s->HEVClc->common_cabac_state = &s->cabac; |
| 3506 | s->local_ctx[0] = s->HEVClc; | ||
| 3507 | s->nb_local_ctx = 1; | ||
| 3508 | 3515 | ||
| 3509 | s->output_frame = av_frame_alloc(); | 3516 | s->output_frame = av_frame_alloc(); |
| 3510 | if (!s->output_frame) | 3517 | if (!s->output_frame) |
| @@ -439,13 +439,17 @@ typedef struct HEVCLocalContext { · 438 unmodified lines | |||
| 439 | /* properties of the boundary of the current CTB for the purposes | 439 | /* properties of the boundary of the current CTB for the purposes |
| 440 | * of the deblocking filter */ | 440 | * of the deblocking filter */ |
| 441 | int boundary_flags; | 441 | int boundary_flags; |
| 442 | |||
| 443 | // an array of these structs is used for per-thread state - pad its size | ||
| 444 | // to avoid false sharing | ||
| 445 | char padding[128]; | ||
| 442 | } HEVCLocalContext; | 446 | } HEVCLocalContext; |
| 443 | 447 | ||
| 444 | typedef struct HEVCContext { | 448 | typedef struct HEVCContext { |
| 445 | const AVClass *c; // needed by private avoptions | 449 | const AVClass *c; // needed by private avoptions |
| 446 | AVCodecContext *avctx; | 450 | AVCodecContext *avctx; |
| 447 | 451 | ||
| 448 | HEVCLocalContext **local_ctx; | 452 | HEVCLocalContext *local_ctx; |
| 449 | unsigned nb_local_ctx; | 453 | unsigned nb_local_ctx; |
| 450 | 454 | ||
| 451 | HEVCLocalContext *HEVClc; | 455 | HEVCLocalContext *HEVClc; |