Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : /*
7 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
8 : *
9 : * This source code is subject to the terms of the BSD 2 Clause License and
10 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
11 : * was not distributed with this source code in the LICENSE file, you can
12 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
13 : * Media Patent License 1.0 was not distributed with this source code in the
14 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
15 : */
16 :
17 : #include <stdlib.h>
18 : #include "EbDefinitions.h"
19 : #include "EbRestProcess.h"
20 : #include "EbEncDecResults.h"
21 :
22 : #include "EbThreads.h"
23 : #include "EbPictureDemuxResults.h"
24 : #include "EbReferenceObject.h"
25 :
26 : void ReconOutput(
27 : PictureControlSet *picture_control_set_ptr,
28 : SequenceControlSet *sequence_control_set_ptr);
29 : void eb_av1_loop_restoration_filter_frame(Yv12BufferConfig *frame,
30 : Av1Common *cm, int32_t optimized_lr);
31 : void CopyStatisticsToRefObject(
32 : PictureControlSet *picture_control_set_ptr,
33 : SequenceControlSet *sequence_control_set_ptr);
34 : void psnr_calculations(
35 : PictureControlSet *picture_control_set_ptr,
36 : SequenceControlSet *sequence_control_set_ptr);
37 : void PadRefAndSetFlags(
38 : PictureControlSet *picture_control_set_ptr,
39 : SequenceControlSet *sequence_control_set_ptr);
40 : void generate_padding(
41 : EbByte src_pic,
42 : uint32_t src_stride,
43 : uint32_t original_src_width,
44 : uint32_t original_src_height,
45 : uint32_t padding_width,
46 : uint32_t padding_height);
47 : void restoration_seg_search(
48 : RestContext *context_ptr,
49 : Yv12BufferConfig *org_fts,
50 : const Yv12BufferConfig *src,
51 : Yv12BufferConfig *trial_frame_rst,
52 : PictureControlSet *pcs_ptr,
53 : uint32_t segment_index);
54 : void rest_finish_search(Macroblock *x, Av1Common *const cm);
55 :
56 16 : static void rest_context_dctor(EbPtr p)
57 : {
58 16 : RestContext *obj = (RestContext*)p;
59 16 : EB_DELETE(obj->temp_lf_recon_picture_ptr);
60 16 : EB_DELETE(obj->temp_lf_recon_picture16bit_ptr);
61 16 : EB_DELETE(obj->trial_frame_rst);
62 16 : EB_DELETE(obj->org_rec_frame);
63 16 : EB_FREE_ALIGNED(obj->rst_tmpbuf);
64 16 : }
65 :
66 : /******************************************************
67 : * Rest Context Constructor
68 : ******************************************************/
69 16 : EbErrorType rest_context_ctor(
70 : RestContext *context_ptr,
71 : EbFifo *rest_input_fifo_ptr,
72 : EbFifo *rest_output_fifo_ptr ,
73 : EbFifo *picture_demux_fifo_ptr,
74 : EbBool is16bit,
75 : EbColorFormat color_format,
76 : uint32_t max_input_luma_width,
77 : uint32_t max_input_luma_height
78 : )
79 : {
80 :
81 16 : context_ptr->dctor = rest_context_dctor;
82 :
83 : // Input/Output System Resource Manager FIFOs
84 16 : context_ptr->rest_input_fifo_ptr = rest_input_fifo_ptr;
85 16 : context_ptr->rest_output_fifo_ptr = rest_output_fifo_ptr;
86 16 : context_ptr->picture_demux_fifo_ptr = picture_demux_fifo_ptr;
87 :
88 : {
89 : EbPictureBufferDescInitData initData;
90 :
91 16 : initData.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
92 16 : initData.max_width = (uint16_t)max_input_luma_width;
93 16 : initData.max_height = (uint16_t)max_input_luma_height;
94 16 : initData.bit_depth = is16bit ? EB_16BIT : EB_8BIT;
95 16 : initData.color_format = color_format;
96 16 : initData.left_padding = AOM_BORDER_IN_PIXELS;
97 16 : initData.right_padding = AOM_BORDER_IN_PIXELS;
98 16 : initData.top_padding = AOM_BORDER_IN_PIXELS;
99 16 : initData.bot_padding = AOM_BORDER_IN_PIXELS;
100 16 : initData.split_mode = EB_FALSE;
101 :
102 16 : EB_NEW(
103 : context_ptr->trial_frame_rst,
104 : eb_picture_buffer_desc_ctor,
105 : (EbPtr)&initData);
106 :
107 16 : EB_NEW(
108 : context_ptr->org_rec_frame,
109 : eb_picture_buffer_desc_ctor,
110 : (EbPtr)&initData);
111 :
112 16 : EB_MALLOC_ALIGNED(context_ptr->rst_tmpbuf, RESTORATION_TMPBUF_SIZE);
113 : }
114 :
115 : EbPictureBufferDescInitData tempLfReconDescInitData;
116 16 : tempLfReconDescInitData.max_width = (uint16_t)max_input_luma_width;
117 16 : tempLfReconDescInitData.max_height = (uint16_t)max_input_luma_height;
118 16 : tempLfReconDescInitData.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
119 :
120 16 : tempLfReconDescInitData.left_padding = PAD_VALUE;
121 16 : tempLfReconDescInitData.right_padding = PAD_VALUE;
122 16 : tempLfReconDescInitData.top_padding = PAD_VALUE;
123 16 : tempLfReconDescInitData.bot_padding = PAD_VALUE;
124 16 : tempLfReconDescInitData.split_mode = EB_FALSE;
125 16 : tempLfReconDescInitData.color_format = color_format;
126 :
127 16 : if (is16bit) {
128 0 : tempLfReconDescInitData.bit_depth = EB_16BIT;
129 0 : EB_NEW(
130 : context_ptr->temp_lf_recon_picture16bit_ptr,
131 : eb_recon_picture_buffer_desc_ctor,
132 : (EbPtr)&tempLfReconDescInitData);
133 : }
134 : else {
135 16 : tempLfReconDescInitData.bit_depth = EB_8BIT;
136 16 : EB_NEW(
137 : context_ptr->temp_lf_recon_picture_ptr,
138 : eb_recon_picture_buffer_desc_ctor,
139 : (EbPtr)&tempLfReconDescInitData);
140 : }
141 :
142 16 : return EB_ErrorNone;
143 : }
144 60 : void get_own_recon(
145 : SequenceControlSet *sequence_control_set_ptr,
146 : PictureControlSet *picture_control_set_ptr,
147 : RestContext *context_ptr,
148 : EbBool is16bit)
149 : {
150 : EbPictureBufferDesc * recon_picture_ptr;
151 60 : if (is16bit) {
152 0 : if (picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag == EB_TRUE)
153 0 : recon_picture_ptr = ((EbReferenceObject*)picture_control_set_ptr->parent_pcs_ptr->reference_picture_wrapper_ptr->object_ptr)->reference_picture16bit;
154 : else
155 0 : recon_picture_ptr = picture_control_set_ptr->recon_picture16bit_ptr;
156 :
157 0 : uint16_t* rec_ptr = (uint16_t*)recon_picture_ptr->buffer_y + recon_picture_ptr->origin_x + recon_picture_ptr->origin_y * recon_picture_ptr->stride_y;
158 0 : uint16_t* rec_ptr_cb = (uint16_t*)recon_picture_ptr->buffer_cb + recon_picture_ptr->origin_x / 2 + recon_picture_ptr->origin_y / 2 * recon_picture_ptr->stride_cb;
159 0 : uint16_t* rec_ptr_cr = (uint16_t*)recon_picture_ptr->buffer_cr + recon_picture_ptr->origin_x / 2 + recon_picture_ptr->origin_y / 2 * recon_picture_ptr->stride_cr;
160 :
161 0 : EbPictureBufferDesc *org_rec = context_ptr->org_rec_frame;
162 0 : uint16_t* org_ptr = (uint16_t*)org_rec->buffer_y + org_rec->origin_x + org_rec->origin_y * org_rec->stride_y;
163 0 : uint16_t* org_ptr_cb = (uint16_t*)org_rec->buffer_cb + org_rec->origin_x / 2 + org_rec->origin_y / 2 * org_rec->stride_cb;
164 0 : uint16_t* org_ptr_cr = (uint16_t*)org_rec->buffer_cr + org_rec->origin_x / 2 + org_rec->origin_y / 2 * org_rec->stride_cr;
165 :
166 0 : for (int r = 0; r < sequence_control_set_ptr->seq_header.max_frame_height; ++r)
167 0 : memcpy(org_ptr + r * org_rec->stride_y, rec_ptr + r * recon_picture_ptr->stride_y, sequence_control_set_ptr->seq_header.max_frame_width << 1);
168 :
169 0 : for (int r = 0; r < sequence_control_set_ptr->seq_header.max_frame_height / 2; ++r) {
170 0 : memcpy(org_ptr_cb + r * org_rec->stride_cb, rec_ptr_cb + r * recon_picture_ptr->stride_cb, (sequence_control_set_ptr->seq_header.max_frame_width / 2) << 1);
171 0 : memcpy(org_ptr_cr + r * org_rec->stride_cr, rec_ptr_cr + r * recon_picture_ptr->stride_cr, (sequence_control_set_ptr->seq_header.max_frame_width / 2) << 1);
172 : }
173 : }
174 : else {
175 60 : if (picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag == EB_TRUE)
176 38 : recon_picture_ptr = ((EbReferenceObject*)picture_control_set_ptr->parent_pcs_ptr->reference_picture_wrapper_ptr->object_ptr)->reference_picture;
177 : else
178 22 : recon_picture_ptr = picture_control_set_ptr->recon_picture_ptr;
179 :
180 60 : uint8_t * rec_ptr = &((recon_picture_ptr->buffer_y)[recon_picture_ptr->origin_x + recon_picture_ptr->origin_y * recon_picture_ptr->stride_y]);
181 60 : uint8_t * rec_ptr_cb = &((recon_picture_ptr->buffer_cb)[recon_picture_ptr->origin_x / 2 + recon_picture_ptr->origin_y / 2 * recon_picture_ptr->stride_cb]);
182 60 : uint8_t * rec_ptr_cr = &((recon_picture_ptr->buffer_cr)[recon_picture_ptr->origin_x / 2 + recon_picture_ptr->origin_y / 2 * recon_picture_ptr->stride_cr]);
183 :
184 60 : EbPictureBufferDesc *org_rec = context_ptr->org_rec_frame;
185 60 : uint8_t * org_ptr = &((org_rec->buffer_y)[org_rec->origin_x + org_rec->origin_y * org_rec->stride_y]);
186 60 : uint8_t * org_ptr_cb = &((org_rec->buffer_cb)[org_rec->origin_x / 2 + org_rec->origin_y / 2 * org_rec->stride_cb]);
187 60 : uint8_t * org_ptr_cr = &((org_rec->buffer_cr)[org_rec->origin_x / 2 + org_rec->origin_y / 2 * org_rec->stride_cr]);
188 :
189 21660 : for (int r = 0; r < sequence_control_set_ptr->seq_header.max_frame_height; ++r)
190 21600 : memcpy(org_ptr + r * org_rec->stride_y, rec_ptr + r * recon_picture_ptr->stride_y, sequence_control_set_ptr->seq_header.max_frame_width);
191 :
192 10860 : for (int r = 0; r < sequence_control_set_ptr->seq_header.max_frame_height / 2; ++r) {
193 10800 : memcpy(org_ptr_cb + r * org_rec->stride_cb, rec_ptr_cb + r * recon_picture_ptr->stride_cb, (sequence_control_set_ptr->seq_header.max_frame_width / 2));
194 10800 : memcpy(org_ptr_cr + r * org_rec->stride_cr, rec_ptr_cr + r * recon_picture_ptr->stride_cr, (sequence_control_set_ptr->seq_header.max_frame_width / 2));
195 : }
196 : }
197 60 : }
198 :
199 : /******************************************************
200 : * Rest Kernel
201 : ******************************************************/
202 16 : void* rest_kernel(void *input_ptr)
203 : {
204 : // Context & SCS & PCS
205 16 : RestContext *context_ptr = (RestContext*)input_ptr;
206 : PictureControlSet *picture_control_set_ptr;
207 : SequenceControlSet *sequence_control_set_ptr;
208 : FrameHeader *frm_hdr;
209 :
210 : //// Input
211 : EbObjectWrapper *cdef_results_wrapper_ptr;
212 : CdefResults *cdef_results_ptr;
213 :
214 : //// Output
215 : EbObjectWrapper *rest_results_wrapper_ptr;
216 : RestResults* rest_results_ptr;
217 : EbObjectWrapper *picture_demux_results_wrapper_ptr;
218 : PictureDemuxResults *picture_demux_results_rtr;
219 : // SB Loop variables
220 :
221 120 : for (;;) {
222 : // Get Cdef Results
223 136 : eb_get_full_object(
224 : context_ptr->rest_input_fifo_ptr,
225 : &cdef_results_wrapper_ptr);
226 :
227 120 : cdef_results_ptr = (CdefResults*)cdef_results_wrapper_ptr->object_ptr;
228 120 : picture_control_set_ptr = (PictureControlSet*)cdef_results_ptr->picture_control_set_wrapper_ptr->object_ptr;
229 120 : sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
230 120 : frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
231 120 : uint8_t lcuSizeLog2 = (uint8_t)Log2f(sequence_control_set_ptr->sb_size_pix);
232 120 : EbBool is16bit = (EbBool)(sequence_control_set_ptr->static_config.encoder_bit_depth > EB_8BIT);
233 120 : Av1Common* cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
234 :
235 120 : if (sequence_control_set_ptr->seq_header.enable_restoration && frm_hdr->allow_intrabc == 0)
236 : {
237 60 : get_own_recon(sequence_control_set_ptr, picture_control_set_ptr, context_ptr, is16bit);
238 :
239 : Yv12BufferConfig cpi_source;
240 120 : link_eb_to_aom_buffer_desc(
241 60 : is16bit ? picture_control_set_ptr->input_frame16bit : picture_control_set_ptr->parent_pcs_ptr->enhanced_picture_ptr,
242 : &cpi_source);
243 :
244 : Yv12BufferConfig trial_frame_rst;
245 60 : link_eb_to_aom_buffer_desc(
246 : context_ptr->trial_frame_rst,
247 : &trial_frame_rst);
248 :
249 : Yv12BufferConfig org_fts;
250 60 : link_eb_to_aom_buffer_desc(
251 : context_ptr->org_rec_frame,
252 : &org_fts);
253 :
254 60 : restoration_seg_search(
255 : context_ptr,
256 : &org_fts,
257 : &cpi_source,
258 : &trial_frame_rst,
259 : picture_control_set_ptr,
260 : cdef_results_ptr->segment_index);
261 : }
262 :
263 : //all seg based search is done. update total processed segments. if all done, finish the search and perfrom application.
264 120 : eb_block_on_mutex(picture_control_set_ptr->rest_search_mutex);
265 :
266 120 : picture_control_set_ptr->tot_seg_searched_rest++;
267 120 : if (picture_control_set_ptr->tot_seg_searched_rest == picture_control_set_ptr->rest_segments_total_count)
268 : {
269 120 : if (sequence_control_set_ptr->seq_header.enable_restoration && frm_hdr->allow_intrabc == 0) {
270 60 : rest_finish_search(
271 60 : picture_control_set_ptr->parent_pcs_ptr->av1x,
272 60 : picture_control_set_ptr->parent_pcs_ptr->av1_cm);
273 :
274 60 : if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
275 0 : cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
276 0 : cm->rst_info[2].frame_restoration_type != RESTORE_NONE)
277 : {
278 60 : eb_av1_loop_restoration_filter_frame(
279 : cm->frame_to_show,
280 : cm,
281 : 0);
282 : }
283 : }
284 : else {
285 60 : cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
286 60 : cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
287 60 : cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
288 : }
289 :
290 120 : uint8_t best_ep_cnt = 0;
291 120 : uint8_t best_ep = 0;
292 2040 : for (uint8_t i = 0; i < SGRPROJ_PARAMS; i++) {
293 1920 : if (cm->sg_frame_ep_cnt[i] > best_ep_cnt) {
294 91 : best_ep = i;
295 91 : best_ep_cnt = cm->sg_frame_ep_cnt[i];
296 : }
297 : }
298 120 : cm->sg_frame_ep = best_ep;
299 :
300 120 : if (picture_control_set_ptr->parent_pcs_ptr->reference_picture_wrapper_ptr != NULL) {
301 : // copy stat to ref object (intra_coded_area, Luminance, Scene change detection flags)
302 68 : CopyStatisticsToRefObject(
303 : picture_control_set_ptr,
304 : sequence_control_set_ptr);
305 : }
306 :
307 : // PSNR Calculation
308 120 : if (sequence_control_set_ptr->static_config.stat_report)
309 0 : psnr_calculations(
310 : picture_control_set_ptr,
311 : sequence_control_set_ptr);
312 :
313 : // Pad the reference picture and set ref POC
314 120 : if (picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag == EB_TRUE)
315 68 : PadRefAndSetFlags(
316 : picture_control_set_ptr,
317 : sequence_control_set_ptr);
318 120 : if (sequence_control_set_ptr->static_config.recon_enabled) {
319 0 : ReconOutput(
320 : picture_control_set_ptr,
321 : sequence_control_set_ptr);
322 : }
323 :
324 120 : if (picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag)
325 : {
326 : // Get Empty PicMgr Results
327 68 : eb_get_empty_object(
328 : context_ptr->picture_demux_fifo_ptr,
329 : &picture_demux_results_wrapper_ptr);
330 :
331 68 : picture_demux_results_rtr = (PictureDemuxResults*)picture_demux_results_wrapper_ptr->object_ptr;
332 68 : picture_demux_results_rtr->reference_picture_wrapper_ptr = picture_control_set_ptr->parent_pcs_ptr->reference_picture_wrapper_ptr;
333 68 : picture_demux_results_rtr->sequence_control_set_wrapper_ptr = picture_control_set_ptr->sequence_control_set_wrapper_ptr;
334 68 : picture_demux_results_rtr->picture_number = picture_control_set_ptr->picture_number;
335 68 : picture_demux_results_rtr->picture_type = EB_PIC_REFERENCE;
336 :
337 : // Post Reference Picture
338 68 : eb_post_full_object(picture_demux_results_wrapper_ptr);
339 : }
340 :
341 : // Get Empty rest Results to EC
342 120 : eb_get_empty_object(
343 : context_ptr->rest_output_fifo_ptr,
344 : &rest_results_wrapper_ptr);
345 120 : rest_results_ptr = (struct RestResults*)rest_results_wrapper_ptr->object_ptr;
346 120 : rest_results_ptr->picture_control_set_wrapper_ptr = cdef_results_ptr->picture_control_set_wrapper_ptr;
347 120 : rest_results_ptr->completed_lcu_row_index_start = 0;
348 120 : rest_results_ptr->completed_lcu_row_count = ((sequence_control_set_ptr->seq_header.max_frame_height + sequence_control_set_ptr->sb_size_pix - 1) >> lcuSizeLog2);
349 : // Post Rest Results
350 120 : eb_post_full_object(rest_results_wrapper_ptr);
351 : }
352 120 : eb_release_mutex(picture_control_set_ptr->rest_search_mutex);
353 :
354 : // Release input Results
355 120 : eb_release_object(cdef_results_wrapper_ptr);
356 : }
357 :
358 : return EB_NULL;
359 : }
|