/work/svt-av1/Source/Lib/Codec/ec_process.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright(c) 2019 Intel Corporation |
3 | | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
4 | | * |
5 | | * This source code is subject to the terms of the BSD 2 Clause License and |
6 | | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
7 | | * was not distributed with this source code in the LICENSE file, you can |
8 | | * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open |
9 | | * Media Patent License 1.0 was not distributed with this source code in the |
10 | | * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license. |
11 | | */ |
12 | | |
13 | | #include <stdlib.h> |
14 | | #include <stdio.h> |
15 | | #include <string.h> |
16 | | #include "enc_handle.h" |
17 | | #include "entropy_coding.h" |
18 | | #include "ec_process.h" |
19 | | #include "enc_dec_results.h" |
20 | | #include "ec_results.h" |
21 | | #include "rc_tasks.h" |
22 | | #include "cabac_context_model.h" |
23 | | #include "svt_log.h" |
24 | | #include "common_dsp_rtcd.h" |
25 | | |
26 | 533 | static void rest_context_dctor(EbPtr p) { |
27 | 533 | EbThreadContext* thread_ctx = (EbThreadContext*)p; |
28 | 533 | EntropyCodingContext* obj = (EntropyCodingContext*)thread_ctx->priv; |
29 | 533 | EB_FREE_ARRAY(obj); |
30 | 533 | } |
31 | | |
32 | | /****************************************************** |
33 | | * Enc Dec Context Constructor |
34 | | ******************************************************/ |
35 | | EbErrorType svt_aom_entropy_coding_context_ctor(EbThreadContext* thread_ctx, const EbEncHandle* enc_handle_ptr, |
36 | 533 | int index) { |
37 | 533 | EntropyCodingContext* context_ptr; |
38 | 533 | EB_CALLOC_ARRAY(context_ptr, 1); |
39 | 533 | thread_ctx->priv = context_ptr; |
40 | 533 | thread_ctx->dctor = rest_context_dctor; |
41 | | |
42 | 533 | context_ptr->is_16bit = enc_handle_ptr->scs_instance->scs->static_config.encoder_bit_depth > EB_EIGHT_BIT; |
43 | | |
44 | | // Zero levels_buf once; the tail (offset >= LEVELS_TAIL_OFFSET) serves as |
45 | | // bottom padding for all block sizes via offset-based placement in set_levels. |
46 | 533 | memset(context_ptr->levels_buf + LEVELS_TAIL_OFFSET, 0, TX_PAD_2D - LEVELS_TAIL_OFFSET); |
47 | | |
48 | | // Input/Output System Resource Manager FIFOs |
49 | 533 | context_ptr->enc_dec_input_fifo_ptr = svt_system_resource_get_consumer_fifo( |
50 | 533 | enc_handle_ptr->rest_results_resource_ptr, index); |
51 | 533 | context_ptr->entropy_coding_output_fifo_ptr = svt_system_resource_get_producer_fifo( |
52 | 533 | enc_handle_ptr->entropy_coding_results_resource_ptr, index); |
53 | | |
54 | 533 | return EB_ErrorNone; |
55 | 533 | } |
56 | | |
57 | | /*********************************************** |
58 | | * Entropy Coding Reset Neighbor Arrays |
59 | | ***********************************************/ |
60 | 5.67k | static void entropy_coding_reset_neighbor_arrays(PictureControlSet* pcs, uint16_t tile_idx) { |
61 | 5.67k | svt_aom_neighbor_array_unit_reset(pcs->partition_context_na[tile_idx]); |
62 | | |
63 | 5.67k | svt_aom_neighbor_array_unit_reset(pcs->luma_dc_sign_level_coeff_na[tile_idx]); |
64 | 5.67k | svt_aom_neighbor_array_unit_reset(pcs->cb_dc_sign_level_coeff_na[tile_idx]); |
65 | 5.67k | svt_aom_neighbor_array_unit_reset(pcs->cr_dc_sign_level_coeff_na[tile_idx]); |
66 | 5.67k | svt_aom_neighbor_array_unit_reset(pcs->txfm_context_array[tile_idx]); |
67 | 5.67k | } |
68 | | |
69 | | /************************************************** |
70 | | * Reset Entropy Coding Picture |
71 | | **************************************************/ |
72 | 533 | static void reset_entropy_coding_picture(EntropyCodingContext* ctx, PictureControlSet* pcs, SequenceControlSet* scs) { |
73 | 533 | PictureParentControlSet* ppcs = pcs->ppcs; |
74 | 533 | const uint16_t tile_cnt = ppcs->av1_cm->tiles_info.tile_rows * ppcs->av1_cm->tiles_info.tile_cols; |
75 | 533 | ctx->is_16bit = scs->static_config.encoder_bit_depth > EB_EIGHT_BIT; |
76 | 533 | const FrameHeader* frm_hdr = &ppcs->frm_hdr; |
77 | | // Asuming cb and cr offset to be the same for chroma QP in both slice and pps for lambda computation |
78 | 533 | const uint32_t entropy_coding_qp = frm_hdr->quantization_params.base_q_idx; |
79 | | |
80 | 6.20k | for (uint16_t tile_idx = 0; tile_idx < tile_cnt; tile_idx++) { |
81 | 5.67k | ppcs->prev_qindex[tile_idx] = entropy_coding_qp; |
82 | 5.67k | } |
83 | 533 | if (frm_hdr->allow_intrabc) { |
84 | 0 | assert(frm_hdr->delta_lf_params.delta_lf_present == 0); |
85 | 0 | } |
86 | 533 | if (frm_hdr->delta_lf_params.delta_lf_present) { |
87 | 0 | ppcs->prev_delta_lf_from_base = 0; |
88 | |
|
89 | 0 | const int frame_lf_count = ppcs->monochrome == 0 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2; |
90 | 0 | for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) { |
91 | 0 | ppcs->prev_delta_lf[lf_id] = 0; |
92 | 0 | } |
93 | 0 | } |
94 | | |
95 | | // pass the ent |
96 | 6.20k | for (uint16_t tile_idx = 0; tile_idx < tile_cnt; tile_idx++) { |
97 | 5.67k | EntropyCoder* ec = pcs->ec_info[tile_idx]->ec; |
98 | 5.67k | OutputBitstreamUnit* output_bitstream_ptr = ec->ec_output_bitstream_ptr; |
99 | | //****************************************************************// |
100 | 5.67k | ec->ec_writer.allow_update_cdf = !ppcs->large_scale_tile && !frm_hdr->disable_cdf_update; |
101 | 5.67k | aom_start_encode(&ec->ec_writer, output_bitstream_ptr); |
102 | | // ADD Reset here |
103 | 5.67k | const uint8_t primary_ref_frame = frm_hdr->primary_ref_frame; |
104 | 5.67k | if (primary_ref_frame != PRIMARY_REF_NONE) { |
105 | | // primary ref stored as REF_FRAME_MINUS1, while get_list_idx/get_ref_frame_idx take arg of ref frame |
106 | | // Therefore, add 1 to the primary ref frame (e.g. LAST --> LAST_FRAME) |
107 | 0 | const uint8_t list_idx = get_list_idx(primary_ref_frame + 1); |
108 | 0 | const uint8_t ref_idx = get_ref_frame_idx(primary_ref_frame + 1); |
109 | 0 | EbReferenceObject* ref = (EbReferenceObject*)pcs->ref_pic_ptr_array[list_idx][ref_idx]->object_ptr; |
110 | 0 | svt_memcpy(ec->fc, &ref->frame_context, sizeof(FRAME_CONTEXT)); |
111 | 5.67k | } else { |
112 | 5.67k | svt_aom_reset_entropy_coder(scs->enc_ctx, ec, entropy_coding_qp, pcs->slice_type); |
113 | 5.67k | } |
114 | | |
115 | 5.67k | entropy_coding_reset_neighbor_arrays(pcs, tile_idx); |
116 | 5.67k | } |
117 | 533 | } |
118 | | |
119 | | /* Entropy Coding */ |
120 | | |
121 | | /********************************************************************************* |
122 | | * |
123 | | * @brief |
124 | | * The Entropy Coding process is responsible for producing an AV1 conformant bitstream for each |
125 | | *frame. |
126 | | * |
127 | | * @par Description: |
128 | | * The entropy coder is a frame-based process and is based on multi-symbol arithmetic range coding. |
129 | | * It takes as input the coding decisions and information for each block and produces as output the |
130 | | *bitstream for each frame. |
131 | | * |
132 | | * @param[in] Coding Decisions |
133 | | * Coding decisions and information for each block. |
134 | | * |
135 | | * @param[out] bitstream |
136 | | * Bitstream for each block |
137 | | * |
138 | | ********************************************************************************/ |
139 | 6.20k | EbErrorType svt_aom_entropy_coding_kernel_iter(void* context) { |
140 | 6.20k | EntropyCodingContext* context_ptr = (EntropyCodingContext*)context; |
141 | | |
142 | | // Input |
143 | 6.20k | EbObjectWrapper* rest_results_wrapper; |
144 | | |
145 | | // Output |
146 | 6.20k | EbObjectWrapper* entropy_coding_results_wrapper_ptr; |
147 | | |
148 | | // Get Mode Decision Results |
149 | 6.20k | EB_GET_FULL_OBJECT(context_ptr->enc_dec_input_fifo_ptr, &rest_results_wrapper); |
150 | | |
151 | 5.67k | RestResults* rest_results = (RestResults*)rest_results_wrapper->object_ptr; |
152 | 5.67k | PictureControlSet* pcs = (PictureControlSet*)rest_results->pcs_wrapper->object_ptr; |
153 | 5.67k | SequenceControlSet* scs = pcs->scs; |
154 | | // SB Constants |
155 | | |
156 | 5.67k | uint32_t sb_size = scs->sb_size; |
157 | | |
158 | 5.67k | uint8_t sb_size_log2 = (uint8_t)svt_log2f(sb_size); |
159 | 5.67k | uint32_t pic_width_in_sb = (pcs->ppcs->aligned_width + sb_size - 1) >> sb_size_log2; |
160 | 5.67k | uint16_t tile_idx = rest_results->tile_index; |
161 | 5.67k | Av1Common* const cm = pcs->ppcs->av1_cm; |
162 | 5.67k | const uint16_t tile_cnt = cm->tiles_info.tile_rows * cm->tiles_info.tile_cols; |
163 | 5.67k | const uint16_t tile_col = tile_idx % cm->tiles_info.tile_cols; |
164 | 5.67k | const uint16_t tile_row = tile_idx / cm->tiles_info.tile_cols; |
165 | 5.67k | const uint16_t tile_sb_start_x = cm->tiles_info.tile_col_start_mi[tile_col] >> scs->seq_header.sb_size_log2; |
166 | 5.67k | const uint16_t tile_sb_start_y = cm->tiles_info.tile_row_start_mi[tile_row] >> scs->seq_header.sb_size_log2; |
167 | | |
168 | 5.67k | uint16_t tile_width_in_sb = (cm->tiles_info.tile_col_start_mi[tile_col + 1] - |
169 | 5.67k | cm->tiles_info.tile_col_start_mi[tile_col]) >> |
170 | 5.67k | scs->seq_header.sb_size_log2; |
171 | 5.67k | uint16_t tile_height_in_sb = (cm->tiles_info.tile_row_start_mi[tile_row + 1] - |
172 | 5.67k | cm->tiles_info.tile_row_start_mi[tile_row]) >> |
173 | 5.67k | scs->seq_header.sb_size_log2; |
174 | | |
175 | 5.67k | bool frame_entropy_done = false; |
176 | | |
177 | 5.67k | svt_block_on_mutex(pcs->entropy_coding_pic_mutex); |
178 | 5.67k | if (pcs->entropy_coding_pic_reset_flag) { |
179 | 533 | pcs->entropy_coding_pic_reset_flag = false; |
180 | | |
181 | 533 | reset_entropy_coding_picture(context_ptr, pcs, scs); |
182 | 533 | } |
183 | 5.67k | svt_release_mutex(pcs->entropy_coding_pic_mutex); |
184 | | |
185 | 5.67k | if (!svt_aom_is_pic_skipped(pcs->ppcs)) { |
186 | 5.67k | #if OPT_STATS_MUTEX |
187 | 5.67k | context_ptr->tot_qindex = 0; |
188 | 5.67k | context_ptr->valid_area = 0; |
189 | 5.67k | #endif |
190 | 11.6k | for (uint32_t y_sb_index = 0; y_sb_index < tile_height_in_sb; ++y_sb_index) { |
191 | 12.9k | for (uint32_t x_sb_index = 0; x_sb_index < tile_width_in_sb; ++x_sb_index) { |
192 | 6.90k | uint16_t sb_index = (uint16_t)((x_sb_index + tile_sb_start_x) + |
193 | 6.90k | (y_sb_index + tile_sb_start_y) * pic_width_in_sb); |
194 | 6.90k | SuperBlock* sb_ptr = pcs->sb_ptr_array[sb_index]; |
195 | | |
196 | 6.90k | const uint32_t sb_origin_x = (x_sb_index + tile_sb_start_x) << sb_size_log2; |
197 | 6.90k | const uint32_t sb_origin_y = (y_sb_index + tile_sb_start_y) << sb_size_log2; |
198 | 6.90k | if (x_sb_index == 0 && y_sb_index == 0) { |
199 | 5.67k | svt_av1_reset_loop_restoration(context_ptr); |
200 | 5.67k | context_ptr->tok = pcs->tile_tok[tile_row][tile_col]; |
201 | 5.67k | } |
202 | | |
203 | 6.90k | EbPictureBufferDesc* coeff_picture_ptr = pcs->ppcs->enc_dec_ptr->quantized_coeff[sb_index]; |
204 | 6.90k | context_ptr->coded_area_sb = 0; |
205 | 6.90k | context_ptr->coded_area_sb_uv = 0; |
206 | | // Ensure EC buffer has room for worst-case SB output (4 bytes/pixel) |
207 | 6.90k | EbErrorType ret = svt_aom_ec_ensure_capacity(&pcs->ec_info[tile_idx]->ec->ec_writer, |
208 | 6.90k | sb_size * sb_size * 4); |
209 | 6.90k | if (ret != EB_ErrorNone) { |
210 | 0 | return ret; |
211 | 0 | } |
212 | 6.90k | svt_aom_write_modes_sb(context_ptr, |
213 | 6.90k | sb_ptr, |
214 | 6.90k | pcs, |
215 | 6.90k | tile_idx, |
216 | 6.90k | pcs->ec_info[tile_idx]->ec, |
217 | 6.90k | coeff_picture_ptr, |
218 | 6.90k | sb_ptr->ptree, |
219 | 6.90k | sb_origin_y >> MI_SIZE_LOG2, |
220 | 6.90k | sb_origin_x >> MI_SIZE_LOG2); |
221 | 6.90k | } |
222 | 6.02k | } |
223 | 5.67k | } |
224 | 5.67k | bool pic_ready = true; |
225 | | |
226 | | // Current tile ready |
227 | 5.67k | svt_aom_encode_slice_finish(pcs->ec_info[tile_idx]->ec); |
228 | | |
229 | 5.67k | svt_block_on_mutex(pcs->entropy_coding_pic_mutex); |
230 | 5.67k | #if OPT_STATS_MUTEX |
231 | | // Flush locally-accumulated qindex stats (avoids per-block mutex) |
232 | 5.67k | pcs->ppcs->tot_qindex += context_ptr->tot_qindex; |
233 | 5.67k | pcs->ppcs->valid_qindex_area += context_ptr->valid_area; |
234 | 5.67k | #endif |
235 | 5.67k | pcs->ec_info[tile_idx]->entropy_coding_tile_done = true; |
236 | 43.9k | for (uint16_t i = 0; i < tile_cnt; i++) { |
237 | 43.4k | if (pcs->ec_info[i]->entropy_coding_tile_done == false) { |
238 | 5.14k | pic_ready = false; |
239 | 5.14k | break; |
240 | 5.14k | } |
241 | 43.4k | } |
242 | 5.67k | svt_release_mutex(pcs->entropy_coding_pic_mutex); |
243 | 5.67k | if (pic_ready) { |
244 | 533 | if (pcs->ppcs->superres_total_recode_loop == 0) { |
245 | | // Release the reference Pictures from both lists |
246 | 4.26k | for (REF_FRAME_MINUS1 ref = LAST; ref < ALT + 1; ref++) { |
247 | 3.73k | const uint8_t list_idx = get_list_idx(ref + 1); |
248 | 3.73k | const uint8_t ref_idx = get_ref_frame_idx(ref + 1); |
249 | 3.73k | if (pcs->ref_pic_ptr_array[list_idx][ref_idx] != NULL) { |
250 | 0 | svt_release_object(pcs->ref_pic_ptr_array[list_idx][ref_idx]); |
251 | 0 | } |
252 | 3.73k | } |
253 | | |
254 | | //free palette data |
255 | 533 | if (pcs->tile_tok[0][0]) { |
256 | 0 | EB_FREE_ARRAY(pcs->tile_tok[0][0]); |
257 | 0 | } |
258 | 533 | } |
259 | 533 | frame_entropy_done = true; |
260 | 533 | } |
261 | | |
262 | 5.67k | if (frame_entropy_done) { |
263 | 533 | if (pcs->ppcs->valid_qindex_area) { |
264 | 533 | pcs->ppcs->avg_qp = ((pcs->ppcs->tot_qindex / pcs->ppcs->valid_qindex_area) + 2) >> 2; |
265 | 533 | } |
266 | | // Get Empty Entropy Coding Results |
267 | 533 | svt_get_empty_object(context_ptr->entropy_coding_output_fifo_ptr, &entropy_coding_results_wrapper_ptr); |
268 | 533 | EntropyCodingResults* entropy_coding_results_ptr = (EntropyCodingResults*) |
269 | 533 | entropy_coding_results_wrapper_ptr->object_ptr; |
270 | 533 | entropy_coding_results_ptr->pcs_wrapper = rest_results->pcs_wrapper; |
271 | | |
272 | | // Post EntropyCoding Results |
273 | 533 | svt_post_full_object(entropy_coding_results_wrapper_ptr); |
274 | 533 | } |
275 | | |
276 | | // Release Mode Decision Results |
277 | 5.67k | svt_release_object(rest_results_wrapper); |
278 | 5.67k | return EB_ErrorNone; |
279 | 5.67k | } |
280 | | |
281 | 533 | void* svt_aom_entropy_coding_kernel(void* input_ptr) { |
282 | 533 | EbThreadContext* thread_ctx = (EbThreadContext*)input_ptr; |
283 | 6.20k | for (;;) { |
284 | 6.20k | EbErrorType err = svt_aom_entropy_coding_kernel_iter(thread_ctx->priv); |
285 | 6.20k | if (err == EB_NoErrorFifoShutdown) { |
286 | 533 | return NULL; |
287 | 533 | } |
288 | 6.20k | } |
289 | 0 | return NULL; |
290 | 533 | } |