Coverage Report

Created: 2026-07-16 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/encode_context.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
*
4
* This source code is subject to the terms of the BSD 2 Clause License and
5
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
* was not distributed with this source code in the LICENSE file, you can
7
* obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8
* Media Patent License 1.0 was not distributed with this source code in the
9
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10
*/
11
12
#include <stdlib.h>
13
14
#include "encode_context.h"
15
#include "EbSvtAv1ErrorCodes.h"
16
#include "svt_threads.h"
17
18
static EbErrorType create_stats_buffer(FIRSTPASS_STATS** frame_stats_buffer, STATS_BUFFER_CTX* stats_buf_context,
19
448
                                       int num_lap_buffers) {
20
448
    EbErrorType res = EB_ErrorNone;
21
22
448
    int size = get_stats_buf_size(num_lap_buffers, MAX_LAG_BUFFERS);
23
    // *frame_stats_buffer =
24
    //     (FIRSTPASS_STATS *)aom_calloc(size, sizeof(FIRSTPASS_STATS));
25
448
    EB_MALLOC_ARRAY((*frame_stats_buffer), size);
26
448
    if (*frame_stats_buffer == NULL) {
27
0
        return EB_ErrorInsufficientResources;
28
0
    }
29
30
448
    stats_buf_context->stats_in_start     = *frame_stats_buffer;
31
448
    stats_buf_context->stats_in_end_write = stats_buf_context->stats_in_start;
32
448
    stats_buf_context->stats_in_end       = stats_buf_context->stats_in_start;
33
448
    stats_buf_context->stats_in_buf_end   = stats_buf_context->stats_in_start + size;
34
35
448
    EB_MALLOC_ARRAY(stats_buf_context->total_left_stats, 1);
36
448
    if (stats_buf_context->total_left_stats == NULL) {
37
0
        return EB_ErrorInsufficientResources;
38
0
    }
39
448
    svt_av1_twopass_zero_stats(stats_buf_context->total_left_stats);
40
448
    EB_MALLOC_ARRAY(stats_buf_context->total_stats, 1);
41
448
    if (stats_buf_context->total_stats == NULL) {
42
0
        return EB_ErrorInsufficientResources;
43
0
    }
44
448
    svt_av1_twopass_zero_stats(stats_buf_context->total_stats);
45
448
    stats_buf_context->last_frame_accumulated = -1;
46
47
448
    EB_CREATE_MUTEX(stats_buf_context->stats_in_write_mutex);
48
448
    return res;
49
448
}
50
51
448
static void destroy_stats_buffer(STATS_BUFFER_CTX* stats_buf_context, FIRSTPASS_STATS* frame_stats_buffer) {
52
448
    EB_FREE_ARRAY(stats_buf_context->total_left_stats);
53
448
    EB_FREE_ARRAY(stats_buf_context->total_stats);
54
448
    EB_FREE_ARRAY(frame_stats_buffer);
55
448
    EB_DESTROY_MUTEX(stats_buf_context->stats_in_write_mutex);
56
448
}
57
58
448
static void encode_context_dctor(EbPtr p) {
59
448
    EncodeContext* obj = (EncodeContext*)p;
60
448
    EB_DESTROY_MUTEX(obj->total_number_of_recon_frame_mutex);
61
448
    EB_DESTROY_MUTEX(obj->total_number_of_shown_frames_mutex);
62
448
    EB_DESTROY_MUTEX(obj->sc_buffer_mutex);
63
448
    EB_DESTROY_MUTEX(obj->stat_file_mutex);
64
448
    EB_DESTROY_MUTEX(obj->frame_updated_mutex);
65
448
    EB_DELETE(obj->prediction_structure_group_ptr);
66
448
    EB_DELETE_PTR_ARRAY(obj->picture_decision_reorder_queue, obj->picture_decision_reorder_queue_size);
67
448
    obj->picture_decision_reorder_queue_size = 0;
68
448
    EB_FREE(obj->pre_assignment_buffer);
69
448
    EB_DELETE_PTR_ARRAY(obj->pic_mgr_input_pic_list, obj->pic_mgr_input_pic_list_size);
70
448
    obj->pic_mgr_input_pic_list_size = 0;
71
448
    EB_DELETE_PTR_ARRAY(obj->ref_pic_list, obj->ref_pic_list_length);
72
448
    EB_DESTROY_MUTEX(obj->ref_pic_list_mutex);
73
448
    EB_DELETE_PTR_ARRAY(obj->pd_dpb, REF_FRAMES);
74
448
    EB_DESTROY_MUTEX(obj->pd_dpb_mutex);
75
448
    EB_DELETE_PTR_ARRAY(obj->packetization_reorder_queue, obj->packetization_reorder_queue_size);
76
448
    obj->packetization_reorder_queue_size = 0;
77
448
    EB_FREE(obj->stats_out.stat);
78
448
    destroy_stats_buffer(&obj->stats_buf_context, obj->frame_stats_buffer);
79
    // coded_frames_stat_queue[] entries are borrowed from the pool; free the pool + the
80
    // (alias) pointer array once each.
81
448
    EB_FREE_ARRAY(obj->rc.coded_frames_stat_pool);
82
448
    EB_FREE_ARRAY(obj->rc.coded_frames_stat_queue);
83
84
448
    if (obj->rc_param_queue) {
85
448
        EB_FREE_2D(obj->rc_param_queue);
86
448
    }
87
448
    EB_DESTROY_MUTEX(obj->rc_param_queue_mutex);
88
448
    EB_DESTROY_MUTEX(obj->rc.rc_mutex);
89
448
}
90
91
448
EbErrorType svt_aom_encode_context_ctor(EncodeContext* enc_ctx, EbPtr object_init_data_ptr) {
92
448
    uint32_t picture_index;
93
94
448
    enc_ctx->dctor = encode_context_dctor;
95
96
448
    (void)object_init_data_ptr;
97
448
    CHECK_REPORT_ERROR(1, enc_ctx->app_callback_ptr, EB_ENC_EC_ERROR29);
98
99
448
    EB_CREATE_MUTEX(enc_ctx->total_number_of_recon_frame_mutex);
100
448
    EB_CREATE_MUTEX(enc_ctx->frame_updated_mutex);
101
448
    enc_ctx->picture_decision_reorder_queue_size = 0;
102
448
    EB_ALLOC_PTR_ARRAY(enc_ctx->pre_assignment_buffer, PRE_ASSIGNMENT_MAX_DEPTH);
103
104
    // input pic list allocated in svt_av1_enc_init based on number of ppcs
105
448
    enc_ctx->pic_mgr_input_pic_list_size = 0;
106
107
448
    EB_ALLOC_PTR_ARRAY(enc_ctx->pd_dpb, REF_FRAMES);
108
4.03k
    for (picture_index = 0; picture_index < REF_FRAMES; ++picture_index) {
109
3.58k
        EB_NEW(enc_ctx->pd_dpb[picture_index], svt_aom_pa_reference_queue_entry_ctor);
110
3.58k
    }
111
448
    EB_CREATE_MUTEX(enc_ctx->pd_dpb_mutex);
112
448
    EB_CREATE_MUTEX(enc_ctx->total_number_of_shown_frames_mutex);
113
448
    EB_CREATE_MUTEX(enc_ctx->ref_pic_list_mutex);
114
115
448
    enc_ctx->initial_picture = true;
116
117
    // Sequence Termination Flags
118
448
    enc_ctx->terminating_picture_number = ~0u;
119
448
    EB_CREATE_MUTEX(enc_ctx->sc_buffer_mutex);
120
448
    enc_ctx->enc_mode         = SPEED_CONTROL_INIT_MOD;
121
448
    enc_ctx->recode_tolerance = 25;
122
448
    enc_ctx->rc_cfg.min_cr    = 0;
123
448
    EB_CREATE_MUTEX(enc_ctx->stat_file_mutex);
124
448
    enc_ctx->num_lap_buffers = 0; // lap not supported for now
125
448
    int* num_lap_buffers     = &enc_ctx->num_lap_buffers;
126
448
    create_stats_buffer(&enc_ctx->frame_stats_buffer, &enc_ctx->stats_buf_context, *num_lap_buffers);
127
448
    EB_ALLOC_PTR_ARRAY(enc_ctx->rc.coded_frames_stat_queue, CODED_FRAMES_STAT_QUEUE_MAX_DEPTH);
128
129
448
    EB_CREATE_MUTEX(enc_ctx->rc.rc_mutex);
130
    // One backing allocation for the whole coded-frames stat ring (was one alloc per slot).
131
448
    EB_CALLOC_ARRAY(enc_ctx->rc.coded_frames_stat_pool, CODED_FRAMES_STAT_QUEUE_MAX_DEPTH);
132
896k
    for (picture_index = 0; picture_index < CODED_FRAMES_STAT_QUEUE_MAX_DEPTH; ++picture_index) {
133
896k
        coded_frames_stats_entry* entry                    = &enc_ctx->rc.coded_frames_stat_pool[picture_index];
134
896k
        entry->picture_number                              = picture_index;
135
896k
        entry->frame_total_bit_actual                      = -1;
136
896k
        enc_ctx->rc.coded_frames_stat_queue[picture_index] = entry;
137
896k
    }
138
#if DEBUG_RC_CAP_LOG
139
    enc_ctx->rc.min_bit_actual_per_gop = 0xfffffffffffff;
140
#endif
141
448
    EB_MALLOC_2D(enc_ctx->rc_param_queue, (int32_t)PARALLEL_GOP_MAX_NUMBER, 1);
142
143
115k
    for (int interval_index = 0; interval_index < PARALLEL_GOP_MAX_NUMBER; interval_index++) {
144
114k
        enc_ctx->rc_param_queue[interval_index]->first_poc                = 0;
145
114k
        enc_ctx->rc_param_queue[interval_index]->processed_frame_number   = 0;
146
114k
        enc_ctx->rc_param_queue[interval_index]->size                     = -1;
147
114k
        enc_ctx->rc_param_queue[interval_index]->end_of_seq_seen          = 0;
148
114k
        enc_ctx->rc_param_queue[interval_index]->vbr_bits_off_target      = 0;
149
114k
        enc_ctx->rc_param_queue[interval_index]->vbr_bits_off_target_fast = 0;
150
114k
        enc_ctx->rc_param_queue[interval_index]->rolling_target_bits      = enc_ctx->rc.avg_frame_bandwidth;
151
114k
        enc_ctx->rc_param_queue[interval_index]->rolling_actual_bits      = enc_ctx->rc.avg_frame_bandwidth;
152
114k
        enc_ctx->rc_param_queue[interval_index]->rate_error_estimate      = 0;
153
114k
        enc_ctx->rc_param_queue[interval_index]->total_actual_bits        = 0;
154
114k
        enc_ctx->rc_param_queue[interval_index]->total_target_bits        = 0;
155
114k
        enc_ctx->rc_param_queue[interval_index]->extend_minq              = 0;
156
114k
        enc_ctx->rc_param_queue[interval_index]->extend_maxq              = 0;
157
114k
        enc_ctx->rc_param_queue[interval_index]->extend_minq_fast         = 0;
158
114k
    }
159
448
    enc_ctx->rc_param_queue_head_index    = 0;
160
448
    enc_ctx->cr_sb_end                    = 0;
161
448
    enc_ctx->cr_sb_index                  = 0;
162
448
    enc_ctx->frames_since_last_cdf_update = 0;
163
164
448
    EB_CREATE_MUTEX(enc_ctx->rc_param_queue_mutex);
165
166
448
    enc_ctx->roi_map_evt = NULL;
167
448
    return EB_ErrorNone;
168
448
}