1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 */
5 
6 #include <stdlib.h>
7 
8 #include "EbEntropyCodingProcess.h"
9 #include "EbEncDecResults.h"
10 #include "EbEntropyCodingResults.h"
11 #include "EbRateControlTasks.h"
12 
13 #include "vp9_blockd.h"
14 #include "vp9_encoder.h"
15 #include "stdint.h"//#include "bitwriter_buffer.h"
16 #include "vp9_bitstream.h"
17 #include "vp9_enums.h"
18 #include "bitwriter.h"
19 #if SEG_SUPPORT
20 #include "vp9_segmentation.h"
21 
22 #endif
23 /******************************************************
24  * Enc Dec Context Constructor
25  ******************************************************/
eb_vp9_entropy_coding_context_ctor(EntropyCodingContext ** context_dbl_ptr,EbFifo * enc_dec_input_fifo_ptr,EbFifo * packetization_output_fifo_ptr,EbFifo * rate_control_output_fifo_ptr,EB_BOOL is16bit)26 EbErrorType eb_vp9_entropy_coding_context_ctor(
27     EntropyCodingContext **context_dbl_ptr,
28     EbFifo                *enc_dec_input_fifo_ptr,
29     EbFifo                *packetization_output_fifo_ptr,
30     EbFifo                *rate_control_output_fifo_ptr,
31     EB_BOOL                is16bit)
32 {
33     EntropyCodingContext *context_ptr;
34     EB_MALLOC(EntropyCodingContext*, context_ptr, sizeof(EntropyCodingContext), EB_N_PTR);
35     *context_dbl_ptr = context_ptr;
36 
37     context_ptr->is16bit = is16bit;
38 
39     // Input/Output System Resource Manager FIFOs
40     context_ptr->enc_dec_input_fifo_ptr          = enc_dec_input_fifo_ptr;
41     context_ptr->entropy_coding_output_fifo_ptr  = packetization_output_fifo_ptr;
42     context_ptr->rate_control_output_fifo_ptr    = rate_control_output_fifo_ptr;
43 
44     EB_MALLOC(MACROBLOCKD*, context_ptr->e_mbd       , sizeof(MACROBLOCKD), EB_N_PTR);
45     EB_MALLOC(ModeInfo **, context_ptr->e_mbd->mi   , sizeof(ModeInfo *), EB_N_PTR);
46 
47     EB_MALLOC(ENTROPY_CONTEXT*, context_ptr->e_mbd->plane[0].above_context, sizeof(ENTROPY_CONTEXT) * 16, EB_N_PTR);
48     EB_MALLOC(ENTROPY_CONTEXT*, context_ptr->e_mbd->plane[0].left_context , sizeof(ENTROPY_CONTEXT) * 16, EB_N_PTR);
49 
50     EB_MALLOC(ENTROPY_CONTEXT*, context_ptr->e_mbd->plane[1].above_context, sizeof(ENTROPY_CONTEXT) * 16, EB_N_PTR);
51     EB_MALLOC(ENTROPY_CONTEXT*, context_ptr->e_mbd->plane[1].left_context , sizeof(ENTROPY_CONTEXT) * 16, EB_N_PTR);
52 
53     EB_MALLOC(ENTROPY_CONTEXT*, context_ptr->e_mbd->plane[2].above_context, sizeof(ENTROPY_CONTEXT) * 16, EB_N_PTR);
54     EB_MALLOC(ENTROPY_CONTEXT*, context_ptr->e_mbd->plane[2].left_context , sizeof(ENTROPY_CONTEXT) * 16, EB_N_PTR);
55     // Hsan - how many token do we really need ?
56     EB_MALLOC(TOKENEXTRA*, context_ptr->tok, sizeof(TOKENEXTRA) * MAX_CU_SIZE * MAX_CU_SIZE * MAX_MB_PLANE, EB_N_PTR);
57 
58     return EB_ErrorNone;
59 }
60 
61 /**********************************************
62 * Entropy Coding SB
63 **********************************************/
EntropyCodingSb(PictureControlSet * picture_control_set_ptr,EntropyCodingContext * context_ptr,SbUnit * sb_ptr,EntropyCoder * entropy_coder_ptr)64 EbErrorType EntropyCodingSb(
65     PictureControlSet    *picture_control_set_ptr,
66     EntropyCodingContext *context_ptr,
67     SbUnit               *sb_ptr,
68     EntropyCoder         *entropy_coder_ptr)
69 {
70     EbErrorType return_error = EB_ErrorNone;
71 
72     SequenceControlSet      *sequence_control_set_ptr = (SequenceControlSet *)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
73 
74     VpxWriter                *residual_bc = &(entropy_coder_ptr->residual_bc);
75     VP9_COMP                 *cpi = picture_control_set_ptr->parent_pcs_ptr->cpi;
76     VP9_COMMON               *const cm = &cpi->common;
77     MACROBLOCKD              *const xd = context_ptr->e_mbd;
78     OutputBitstreamUnit      *output_bitstream_ptr = (OutputBitstreamUnit  *)(picture_control_set_ptr->entropy_coder_ptr->ec_output_bitstream_ptr);
79 
80     uint32_t                  block_index = 0;
81     uint32_t                  rasterScanIndex;
82     uint16_t                  valid_block_index;
83 
84     // Set mi_grid_visible
85     cm->mi_grid_visible = picture_control_set_ptr->mode_info_array;
86 
87     // Get SB Params
88     SbParams * lcuParam = &sequence_control_set_ptr->sb_params_array[sb_ptr->sb_index];
89 
90     // Reset residual_bc each SB
91     uint8_t *data = output_bitstream_ptr->buffer;
92     size_t   total_size = 0;
93 
94     // Reset above context @ the 1st SB
95     if (sb_ptr->sb_index == 0) {
96 
97         eb_vp9_start_encode(residual_bc, data + total_size);
98 
99         // Note: this memset assumes above_context[0], [1] and [2]
100         // are allocated as part of the same buffer.
101         memset(cm->above_context, 0, sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * mi_cols_aligned_to_sb(cm->mi_cols));
102         memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) * mi_cols_aligned_to_sb(cm->mi_cols));
103     }
104 
105     // Reset left context @ each row of SB
106     if (sb_ptr->origin_x == 0) {
107         // Initialize the left context for the new SB row
108         memset(&xd->left_context, 0, sizeof(xd->left_context));
109         memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
110         set_partition_probs(cm, xd);
111     }
112 #if VP9_PERFORM_EP
113     sb_ptr->quantized_coeff_buffer_block_offset[0] = sb_ptr->quantized_coeff_buffer_block_offset[1] = sb_ptr->quantized_coeff_buffer_block_offset[2] = 0;
114 #endif
115     do {
116 
117         context_ptr->block_ptr = sb_ptr->coded_block_array_ptr[block_index];
118         context_ptr->ep_block_stats_ptr = ep_get_block_stats(block_index);
119         rasterScanIndex = ep_scan_to_raster_scan[block_index];
120         context_ptr->block_width = context_ptr->ep_block_stats_ptr->bwidth;
121         context_ptr->block_height = context_ptr->ep_block_stats_ptr->bheight;
122         context_ptr->block_origin_x = (uint16_t)sb_ptr->origin_x + context_ptr->ep_block_stats_ptr->origin_x;
123         context_ptr->block_origin_y = (uint16_t)sb_ptr->origin_y + context_ptr->ep_block_stats_ptr->origin_y;
124         context_ptr->mi_col = context_ptr->block_origin_x >> MI_SIZE_LOG2;
125         context_ptr->mi_row = context_ptr->block_origin_y >> MI_SIZE_LOG2;
126 
127         // Derive partition using block validity and split_flag
128         // ec_scan_block_valid_block holds the block index for the first valid block/subblock
129         // covered by the block (at any depth).  A block is valid if it is within the frame boundary.
130         valid_block_index = lcuParam->ec_scan_block_valid_block[block_index];
131 
132         PARTITION_TYPE partition;
133         if (valid_block_index == (uint16_t)~0) {
134             partition = PARTITION_INVALID;
135         }
136         else {
137             if (valid_block_index == block_index) {
138                 if(context_ptr->block_ptr->split_flag == EB_TRUE)
139                     partition = PARTITION_SPLIT;
140                 else
141                     partition = PARTITION_NONE;
142             }
143             else {
144                 partition = PARTITION_SPLIT;
145             }
146         }
147 
148         if (partition != PARTITION_INVALID) {
149             const int  bsl = eb_vp9_b_width_log2_lookup[context_ptr->ep_block_stats_ptr->bsize];
150             const int  bs = (1 << bsl) / 4;
151             BLOCK_SIZE subsize = get_subsize(context_ptr->ep_block_stats_ptr->bsize, partition);
152 
153             // From SVT to WebM (symbols)
154             xd->mi[0] = cm->mi_grid_visible[context_ptr->mi_col + context_ptr->mi_row * cm->mi_stride];
155 
156             vp9_init_macroblockd(cm, xd, NULL);
157 
158             // Write partition
159             write_partition(cm, xd, bs, context_ptr->mi_row, context_ptr->mi_col, partition, context_ptr->ep_block_stats_ptr->bsize, residual_bc);
160 
161             // Write mode info for final partitioning
162             if (partition == PARTITION_NONE || (partition == PARTITION_SPLIT && ep_get_block_stats(block_index)->bsize == BLOCK_8X8)) {
163 
164                 // Set above_mi and left_mi
165                 context_ptr->e_mbd->above_mi = (context_ptr->mi_row > 0) ? cm->mi_grid_visible[context_ptr->mi_col + context_ptr->mi_row * cm->mi_stride - cm->mi_stride] : NULL;
166                 context_ptr->e_mbd->left_mi = (context_ptr->mi_col > 0) ? cm->mi_grid_visible[context_ptr->mi_col + context_ptr->mi_row * cm->mi_stride - 1] : NULL;
167 
168                 // Set WebM relevant fields
169                 xd->mb_to_top_edge = -((context_ptr->mi_row * MI_SIZE) * 8);
170                 xd->mb_to_bottom_edge = ((picture_control_set_ptr->parent_pcs_ptr->cpi->common.mi_rows - eb_vp9_num_8x8_blocks_high_lookup[context_ptr->ep_block_stats_ptr->bsize] - context_ptr->mi_row) * MI_SIZE) * 8;
171                 xd->mb_to_left_edge = -((context_ptr->mi_col * MI_SIZE) * 8);
172                 xd->mb_to_right_edge = ((picture_control_set_ptr->parent_pcs_ptr->cpi->common.mi_cols - eb_vp9_num_8x8_blocks_wide_lookup[context_ptr->ep_block_stats_ptr->bsize] - context_ptr->mi_col) * MI_SIZE) * 8;
173 
174                 xd->plane[0].subsampling_x = xd->plane[0].subsampling_y = 0;
175                 xd->plane[1].subsampling_x = xd->plane[1].subsampling_y = 1;
176                 xd->plane[2].subsampling_x = xd->plane[2].subsampling_y = 1;
177 
178                 xd->lossless = 0;
179 
180                 // Get eobs
181                 if (xd->mi[0]->sb_type < BLOCK_8X8) {
182                     cpi->td.mb.plane[0].eobs[0] = sb_ptr->coded_block_array_ptr[block_index + ep_inter_depth_offset    ]->eob[0][0];
183                     cpi->td.mb.plane[0].eobs[1] = sb_ptr->coded_block_array_ptr[block_index + ep_inter_depth_offset + 1]->eob[0][0];
184                     cpi->td.mb.plane[0].eobs[2] = sb_ptr->coded_block_array_ptr[block_index + ep_inter_depth_offset + 2]->eob[0][0];
185                     cpi->td.mb.plane[0].eobs[3] = sb_ptr->coded_block_array_ptr[block_index + ep_inter_depth_offset + 3]->eob[0][0];
186 
187                     cpi->td.mb.plane[1].eobs[0] = sb_ptr->coded_block_array_ptr[block_index + ep_inter_depth_offset + 3]->eob[1][0];
188                     cpi->td.mb.plane[2].eobs[0] = sb_ptr->coded_block_array_ptr[block_index + ep_inter_depth_offset + 3]->eob[2][0];
189                 }
190                 else {
191                     for (uint8_t tu_index = 0; tu_index < ((context_ptr->ep_block_stats_ptr->sq_size == MAX_SB_SIZE) ? 4 : 1); tu_index++) {
192                         cpi->td.mb.plane[0].eobs[tu_index * 64] = context_ptr->block_ptr->eob[0][tu_index];
193                     }
194                     cpi->td.mb.plane[1].eobs[0] = context_ptr->block_ptr->eob[1][0];
195                     cpi->td.mb.plane[2].eobs[0] = context_ptr->block_ptr->eob[2][0];
196                 }
197 
198                 // From SVT to WebM (coeff)
199 #if VP9_PERFORM_EP
200                 cpi->td.mb.plane[0].qcoeff = &(((int16_t*)sb_ptr->quantized_coeff_buffer[0])[sb_ptr->quantized_coeff_buffer_block_offset[0]]);
201                 cpi->td.mb.plane[1].qcoeff = &(((int16_t*)sb_ptr->quantized_coeff_buffer[1])[sb_ptr->quantized_coeff_buffer_block_offset[1]]);
202                 cpi->td.mb.plane[2].qcoeff = &(((int16_t*)sb_ptr->quantized_coeff_buffer[2])[sb_ptr->quantized_coeff_buffer_block_offset[2]]);
203 
204                 sb_ptr->quantized_coeff_buffer_block_offset[0] += (context_ptr->ep_block_stats_ptr->sq_size * context_ptr->ep_block_stats_ptr->sq_size );
205                 sb_ptr->quantized_coeff_buffer_block_offset[1] += (context_ptr->ep_block_stats_ptr->sq_size * context_ptr->ep_block_stats_ptr->sq_size ) >> 2;
206                 sb_ptr->quantized_coeff_buffer_block_offset[2] += (context_ptr->ep_block_stats_ptr->sq_size * context_ptr->ep_block_stats_ptr->sq_size ) >> 2;
207 #else
208                 if (xd->mi[0]->skip == EB_FALSE)
209                 {
210 
211                     if (xd->mi[0]->sb_type < BLOCK_8X8) {
212 
213                         // Y: 1st mbi
214                         {
215                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_y)[context_ptr->ep_block_stats_ptr->origin_x + context_ptr->ep_block_stats_ptr->origin_y * sb_ptr->quantized_coeff->stride_y]);
216                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[0].qcoeff)[0]);
217 
218                             for (int j = 0; j < 4; j++) {
219                                 EB_MEMCPY(dst_ptr, src_ptr, 4 * sizeof(int16_t));
220                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_y;
221                                 dst_ptr = dst_ptr + 4;
222                             }
223                         }
224 
225                         // Y: 2nd mbi
226                         {
227                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_y)[context_ptr->ep_block_stats_ptr->origin_x + 4 + context_ptr->ep_block_stats_ptr->origin_y * sb_ptr->quantized_coeff->stride_y]);
228                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[0].qcoeff)[16]);
229 
230                             for (int j = 0; j < 4; j++) {
231                                 EB_MEMCPY(dst_ptr, src_ptr, 4 * sizeof(int16_t));
232                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_y;
233                                 dst_ptr = dst_ptr + 4;
234                             }
235                         }
236 
237                         // Y: 3rd mbi
238                         {
239                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_y)[context_ptr->ep_block_stats_ptr->origin_x + (context_ptr->ep_block_stats_ptr->origin_y + 4) * sb_ptr->quantized_coeff->stride_y]);
240                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[0].qcoeff)[32]);
241 
242                             for (int j = 0; j < 4; j++) {
243                                 EB_MEMCPY(dst_ptr, src_ptr, 4 * sizeof(int16_t));
244                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_y;
245                                 dst_ptr = dst_ptr + 4;
246                             }
247                         }
248 
249                         // Y: 4th mbi
250                         {
251                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_y)[context_ptr->ep_block_stats_ptr->origin_x + 4 + (context_ptr->ep_block_stats_ptr->origin_y + 4) * sb_ptr->quantized_coeff->stride_y]);
252                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[0].qcoeff)[48]);
253 
254                             for (int j = 0; j < 4; j++) {
255                                 EB_MEMCPY(dst_ptr, src_ptr, 4 * sizeof(int16_t));
256                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_y;
257                                 dst_ptr = dst_ptr + 4;
258                             }
259                         }
260 
261 #if 1
262                         //Cb
263                         {
264                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_cb)[(context_ptr->ep_block_stats_ptr->origin_x >> 1) + (context_ptr->ep_block_stats_ptr->origin_y >> 1) * sb_ptr->quantized_coeff->stride_cb]);
265                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[1].qcoeff)[0]);
266 
267                             for (int j = 0; j < context_ptr->ep_block_stats_ptr->sq_size_uv; j++) {
268                                 EB_MEMCPY(dst_ptr, src_ptr, context_ptr->ep_block_stats_ptr->sq_size_uv * sizeof(int16_t));
269                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_cb;
270                                 dst_ptr = dst_ptr + context_ptr->ep_block_stats_ptr->sq_size_uv;
271                             }
272                         }
273 
274                         //Cr
275                         {
276                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_cr)[(context_ptr->ep_block_stats_ptr->origin_x >> 1) + (context_ptr->ep_block_stats_ptr->origin_y >> 1) * sb_ptr->quantized_coeff->stride_cr]);
277                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[2].qcoeff)[0]);
278 
279                             for (int j = 0; j < context_ptr->ep_block_stats_ptr->sq_size_uv; j++) {
280                                 EB_MEMCPY(dst_ptr, src_ptr, context_ptr->ep_block_stats_ptr->sq_size_uv * sizeof(int16_t));
281                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_cr;
282                                 dst_ptr = dst_ptr + context_ptr->ep_block_stats_ptr->sq_size_uv;
283                             }
284                         }
285 #endif
286 
287                     }
288                     else {
289                         //Y
290                         {
291                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_y)[context_ptr->ep_block_stats_ptr->origin_x + context_ptr->ep_block_stats_ptr->origin_y * sb_ptr->quantized_coeff->stride_y]);
292                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[0].qcoeff)[0]);
293 
294                             for (int j = 0; j < context_ptr->ep_block_stats_ptr->sq_size; j++) {
295                                 EB_MEMCPY(dst_ptr, src_ptr, context_ptr->ep_block_stats_ptr->sq_size * sizeof(int16_t));
296                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_y;
297                                 dst_ptr = dst_ptr + context_ptr->ep_block_stats_ptr->sq_size;
298                             }
299                         }
300 
301                         //Cb
302                         {
303                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_cb)[(context_ptr->ep_block_stats_ptr->origin_x >> 1) + (context_ptr->ep_block_stats_ptr->origin_y >> 1) * sb_ptr->quantized_coeff->stride_cb]);
304                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[1].qcoeff)[0]);
305 
306                             for (int j = 0; j < context_ptr->ep_block_stats_ptr->sq_size_uv; j++) {
307                                 EB_MEMCPY(dst_ptr, src_ptr, context_ptr->ep_block_stats_ptr->sq_size_uv * sizeof(int16_t));
308                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_cb;
309                                 dst_ptr = dst_ptr + context_ptr->ep_block_stats_ptr->sq_size_uv;
310                             }
311                         }
312 
313                         //Cr
314                         {
315                             int16_t* src_ptr = &(((int16_t*)sb_ptr->quantized_coeff->buffer_cr)[(context_ptr->ep_block_stats_ptr->origin_x >> 1) + (context_ptr->ep_block_stats_ptr->origin_y >> 1) * sb_ptr->quantized_coeff->stride_cr]);
316                             tran_low_t* dst_ptr = &(((tran_low_t*)cpi->td.mb.plane[2].qcoeff)[0]);
317 
318                             for (int j = 0; j < context_ptr->ep_block_stats_ptr->sq_size_uv; j++) {
319                                 EB_MEMCPY(dst_ptr, src_ptr, context_ptr->ep_block_stats_ptr->sq_size_uv * sizeof(int16_t));
320                                 src_ptr = src_ptr + sb_ptr->quantized_coeff->stride_cr;
321                                 dst_ptr = dst_ptr + context_ptr->ep_block_stats_ptr->sq_size_uv;
322                             }
323                         }
324                     }
325                 }
326 #endif
327 
328                 // Set skip context
329                 set_skip_context(xd, context_ptr->mi_row, context_ptr->mi_col);
330 
331                 // Track the head of the tok buffer
332                 context_ptr->tok_start = context_ptr->tok;
333 
334                 // Tokonize the SB
335                 eb_vp9_tokenize_sb(cpi, xd, &cpi->td, &context_ptr->tok, 0, 0,  VPXMAX(context_ptr->ep_block_stats_ptr->bsize, BLOCK_8X8));
336 
337                 // Add EOSB_TOKEN
338                 context_ptr->tok->token  = EOSB_TOKEN;
339                 context_ptr->tok_end     = context_ptr->tok + 1;
340 
341                 // Reset the tok buffer
342                 context_ptr->tok         = context_ptr->tok_start;
343 
344                 // Write mode info
345                 eb_vp9_write_modes_b(context_ptr, cpi, xd, (TileInfo *)EB_NULL, residual_bc, &context_ptr->tok, context_ptr->tok_end, context_ptr->mi_row, context_ptr->mi_col, &cpi->max_mv_magnitude, cpi->interp_filter_selected);
346 
347                 // Reset the tok buffer
348                 context_ptr->tok = context_ptr->tok_start;
349 
350                 // Update partition context
351                 if (context_ptr->ep_block_stats_ptr->bsize >= BLOCK_8X8 && (context_ptr->ep_block_stats_ptr->bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
352                     update_partition_context(xd, context_ptr->mi_row, context_ptr->mi_col, subsize, context_ptr->ep_block_stats_ptr->bsize);
353 
354                 // Next CU in the current depth
355                 block_index += ep_intra_depth_offset[ep_raster_scan_block_depth[rasterScanIndex]];
356             }
357             else {
358                 // Next CU in the next depth
359                 block_index = block_index + ep_inter_depth_offset;
360             }
361         }
362         else {
363 
364             if (context_ptr->block_origin_x >= sequence_control_set_ptr->luma_width || context_ptr->block_origin_y >= sequence_control_set_ptr->luma_height) {
365                 // Next CU in the current depth
366                 block_index += ep_intra_depth_offset[ep_raster_scan_block_depth[rasterScanIndex]];
367             }
368             else {
369                 // Next CU in the next depth
370                 block_index = block_index + ep_inter_depth_offset;
371             }
372         }
373 
374     } while (block_index < EP_BLOCK_MAX_COUNT);
375 
376     // Stop writing
377     if (sb_ptr->sb_index == (unsigned) picture_control_set_ptr->sb_total_count - 1) {
378         eb_vp9_stop_encode(residual_bc);
379     }
380 
381     return return_error;
382 }
383 
384 /******************************************************
385  * Update Entropy Coding Rows
386  *
387  * This function is responsible for synchronizing the
388  *   processing of Entropy Coding LCU-rows and starts
389  *   processing of LCU-rows as soon as their inputs are
390  *   available and the previous LCU-row has completed.
391  *   At any given time, only one segment row per picture
392  *   is being processed.
393  *
394  * The function has two parts:
395  *
396  * (1) Update the available row index which tracks
397  *   which LCU Row-inputs are available.
398  *
399  * (2) Increment the lcu-row counter as the segment-rows
400  *   are completed.
401  *
402  * Since there is the potentential for thread collusion,
403  *   a MUTEX a used to protect the sensitive data and
404  *   the execution flow is separated into two paths
405  *
406  * (A) Initial update.
407  *  -Update the Completion Mask [see (1) above]
408  *  -If the picture is not currently being processed,
409  *     check to see if the next segment-row is available
410  *     and start processing.
411  * (B) Continued processing
412  *  -Upon the completion of a segment-row, check
413  *     to see if the next segment-row's inputs have
414  *     become available and begin processing if so.
415  *
416  * On last important point is that the thread-safe
417  *   code section is kept minimally short. The MUTEX
418  *   should NOT be locked for the entire processing
419  *   of the segment-row (B) as this would block other
420  *   threads from performing an update (A).
421  ******************************************************/
update_entropy_coding_rows(PictureControlSet * picture_control_set_ptr,uint32_t * row_index,uint32_t row_count,EB_BOOL * initial_process_call)422 static EB_BOOL update_entropy_coding_rows(
423     PictureControlSet *picture_control_set_ptr,
424     uint32_t          *row_index,
425     uint32_t           row_count,
426     EB_BOOL           *initial_process_call)
427 {
428     EB_BOOL process_next_row = EB_FALSE;
429 
430     // Note, any writes & reads to status variables (e.g. in_progress) in MD-CTRL must be thread-safe
431     eb_vp9_block_on_mutex(picture_control_set_ptr->entropy_coding_mutex);
432 
433     // Update availability mask
434     if (*initial_process_call == EB_TRUE) {
435         unsigned i;
436 
437         for(i=*row_index; i < *row_index + row_count; ++i) {
438             picture_control_set_ptr->entropy_coding_row_array[i] = EB_TRUE;
439         }
440 
441         while(picture_control_set_ptr->entropy_coding_row_array[picture_control_set_ptr->entropy_coding_current_available_row] == EB_TRUE &&
442               picture_control_set_ptr->entropy_coding_current_available_row < picture_control_set_ptr->entropy_coding_row_count)
443         {
444             ++picture_control_set_ptr->entropy_coding_current_available_row;
445         }
446     }
447 
448     // Release in_progress token
449     if(*initial_process_call == EB_FALSE && picture_control_set_ptr->entropy_coding_in_progress == EB_TRUE) {
450         picture_control_set_ptr->entropy_coding_in_progress = EB_FALSE;
451     }
452 
453     // Test if the picture is not already complete AND not currently being worked on by another ENCDEC process
454     if(picture_control_set_ptr->entropy_coding_current_row < picture_control_set_ptr->entropy_coding_row_count &&
455        picture_control_set_ptr->entropy_coding_row_array[picture_control_set_ptr->entropy_coding_current_row] == EB_TRUE &&
456        picture_control_set_ptr->entropy_coding_in_progress == EB_FALSE)
457     {
458         // Test if the next LCU-row is ready to go
459         if(picture_control_set_ptr->entropy_coding_current_row <= picture_control_set_ptr->entropy_coding_current_available_row)
460         {
461             picture_control_set_ptr->entropy_coding_in_progress = EB_TRUE;
462             *row_index = picture_control_set_ptr->entropy_coding_current_row++;
463             process_next_row = EB_TRUE;
464         }
465     }
466 
467     *initial_process_call = EB_FALSE;
468 
469     eb_vp9_release_mutex(picture_control_set_ptr->entropy_coding_mutex);
470 
471     return process_next_row;
472 }
473 
474 /******************************************************
475  * Entropy Coding Kernel
476  ******************************************************/
eb_vp9_entropy_coding_kernel(void * input_ptr)477 void* eb_vp9_entropy_coding_kernel(void *input_ptr)
478 {
479     // Context & SCS & PCS
480     EntropyCodingContext *context_ptr = (EntropyCodingContext*) input_ptr;
481     PictureControlSet    *picture_control_set_ptr;
482     SequenceControlSet   *sequence_control_set_ptr;
483 
484     // Input
485     EbObjectWrapper      *enc_dec_results_wrapper_ptr;
486     EncDecResults        *enc_dec_results_ptr;
487 
488     // Output
489     EbObjectWrapper      *entropy_coding_results_wrapper_ptr;
490     EntropyCodingResults *entropy_coding_results_ptr;
491 
492     // LCU Loop variables
493     SbUnit               *sb_ptr;
494     uint16_t              sb_index;
495     uint32_t              xsb_index;
496     uint32_t              ysb_index;
497     uint32_t              picture_width_in_sb;
498     // Variables
499     EB_BOOL               initial_process_call;
500 
501     for(;;) {
502 
503         // Get Mode Decision Results
504         eb_vp9_get_full_object(
505             context_ptr->enc_dec_input_fifo_ptr,
506             &enc_dec_results_wrapper_ptr);
507         enc_dec_results_ptr       = (EncDecResults*) enc_dec_results_wrapper_ptr->object_ptr;
508         picture_control_set_ptr   = (PictureControlSet  *) enc_dec_results_ptr->picture_control_set_wrapper_ptr->object_ptr;
509         sequence_control_set_ptr  = (SequenceControlSet *) picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
510 
511         // LCU Constants
512         picture_width_in_sb = (sequence_control_set_ptr->luma_width + MAX_SB_SIZE_MINUS_1) >> LOG2F_MAX_SB_SIZE;
513         {
514             initial_process_call = EB_TRUE;
515             ysb_index = enc_dec_results_ptr->completed_sb_row_index_start;
516 
517             // LCU-loops
518             while(update_entropy_coding_rows(picture_control_set_ptr, &ysb_index, enc_dec_results_ptr->completed_sb_row_count, &initial_process_call) == EB_TRUE)
519             {
520                 uint32_t rowsb_total_bits = 0;
521 
522                 if(ysb_index == 0) {
523                     picture_control_set_ptr->entropy_coding_pic_done = EB_FALSE;
524                 }
525 
526                 for(xsb_index = 0; xsb_index < picture_width_in_sb; ++xsb_index)
527                 {
528 
529                     sb_index = (uint16_t)(xsb_index + ysb_index * picture_width_in_sb);
530                     sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
531 
532                     sb_ptr->sb_total_bits = 0;
533 #if VP9_RC
534                     uint32_t prev_pos = sb_index ? picture_control_set_ptr->entropy_coder_ptr->residual_bc.pos : 0;
535 #endif
536 #if SEG_SUPPORT
537                     if (sb_index == 0) {
538                         MACROBLOCKD *xd = NULL;
539                         VP9_COMMON *const cm = &picture_control_set_ptr->parent_pcs_ptr->cpi->common;
540 
541                         struct segmentation *seg = &cm->seg;
542                         if (seg->update_map) {
543                             vpx_prob no_pred_tree[SEG_TREE_PROBS];
544                             memset(seg->tree_probs, 255, sizeof(seg->tree_probs));
545                             memset(seg->pred_probs, 255, sizeof(seg->pred_probs));
546                             // Work out probability tree for coding segments without prediction
547                             calc_segtree_probs(picture_control_set_ptr->segment_counts, no_pred_tree);
548                             seg->temporal_update = 0;
549                             EB_MEMCPY(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree));
550 
551                         }
552                     }
553 #endif
554                     // Entropy Coding
555                     EntropyCodingSb(
556                         picture_control_set_ptr,
557                         context_ptr,
558                         sb_ptr,
559                         picture_control_set_ptr->entropy_coder_ptr);
560 #if VP9_RC
561                     sb_ptr->sb_total_bits = (picture_control_set_ptr->entropy_coder_ptr->residual_bc.pos - prev_pos)<<3;
562                     picture_control_set_ptr->parent_pcs_ptr->quantized_coeff_num_bits += sb_ptr->sb_total_bits;
563 #endif
564 
565                     rowsb_total_bits += sb_ptr->sb_total_bits;
566                 }
567 
568                 // At the end of each LCU-row, send the updated bit-count to Entropy Coding
569                 {
570                     EbObjectWrapper  *rate_control_task_wrapper_ptr;
571                     RateControlTasks *rate_control_task_ptr;
572 
573                     // Get Empty EncDec Results
574                     eb_vp9_get_empty_object(
575                         context_ptr->rate_control_output_fifo_ptr,
576                         &rate_control_task_wrapper_ptr);
577                     rate_control_task_ptr = (RateControlTasks*) rate_control_task_wrapper_ptr->object_ptr;
578                     rate_control_task_ptr->task_type = RC_ENTROPY_CODING_ROW_FEEDBACK_RESULT;
579                     rate_control_task_ptr->picture_number = picture_control_set_ptr->picture_number;
580                     rate_control_task_ptr->row_number = ysb_index;
581                     rate_control_task_ptr->bit_count = rowsb_total_bits;
582 
583                     rate_control_task_ptr->picture_control_set_wrapper_ptr = 0;
584                     rate_control_task_ptr->segment_index = ~0u;
585 
586                     // Post EncDec Results
587                     eb_vp9_post_full_object(rate_control_task_wrapper_ptr);
588                 }
589 
590                 eb_vp9_block_on_mutex(picture_control_set_ptr->entropy_coding_mutex);
591                 if (picture_control_set_ptr->entropy_coding_pic_done == EB_FALSE) {
592 
593                     // If the picture is complete, terminate the slice
594                     if (picture_control_set_ptr->entropy_coding_current_row == picture_control_set_ptr->entropy_coding_row_count)
595                     {
596                         uint32_t ref_idx;
597 
598                         picture_control_set_ptr->entropy_coding_pic_done = EB_TRUE;
599 
600                         // Release the List 0 Reference Pictures
601                         for (ref_idx = 0; ref_idx < picture_control_set_ptr->parent_pcs_ptr->ref_list0_count; ++ref_idx) {
602                             if (picture_control_set_ptr->ref_pic_ptr_array[0] != EB_NULL) {
603 
604                                 eb_vp9_release_object(picture_control_set_ptr->ref_pic_ptr_array[0]);
605                             }
606                         }
607 
608                         // Release the List 1 Reference Pictures
609                         for (ref_idx = 0; ref_idx < picture_control_set_ptr->parent_pcs_ptr->ref_list1_count; ++ref_idx) {
610                             if (picture_control_set_ptr->ref_pic_ptr_array[1] != EB_NULL) {
611 
612                                 eb_vp9_release_object(picture_control_set_ptr->ref_pic_ptr_array[1]);
613                             }
614                         }
615 
616                         // Get Empty Entropy Coding Results
617                         eb_vp9_get_empty_object(
618                             context_ptr->entropy_coding_output_fifo_ptr,
619                             &entropy_coding_results_wrapper_ptr);
620                         entropy_coding_results_ptr = (EntropyCodingResults*)entropy_coding_results_wrapper_ptr->object_ptr;
621                         entropy_coding_results_ptr->picture_control_set_wrapper_ptr = enc_dec_results_ptr->picture_control_set_wrapper_ptr;
622 
623                         // Post EntropyCoding Results
624                         eb_vp9_post_full_object(entropy_coding_results_wrapper_ptr);
625 
626                     } // End if(PictureCompleteFlag)
627                 }
628                 eb_vp9_release_mutex(picture_control_set_ptr->entropy_coding_mutex);
629 
630             }
631         }
632         // Release Mode Decision Results
633         eb_vp9_release_object(enc_dec_results_wrapper_ptr);
634 
635     }
636 
637     return EB_NULL;
638 }
639