LCOV - code coverage report
Current view: top level - Codec - EbEntropyCodingProcess.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 165 282 58.5 %
Date: 2019-11-25 17:12:20 Functions: 8 10 80.0 %

          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             : #if TWO_PASS
      19             : #include <stdio.h>
      20             : #endif
      21             : #include "EbEntropyCodingProcess.h"
      22             : #include "EbEncDecResults.h"
      23             : #include "EbEntropyCodingResults.h"
      24             : #include "EbRateControlTasks.h"
      25             : #include "EbCabacContextModel.h"
      26             : #define  AV1_MIN_TILE_SIZE_BYTES 1
      27             : void eb_av1_reset_loop_restoration(PictureControlSet     *piCSetPtr);
      28             : 
      29             : /******************************************************
      30             :  * Enc Dec Context Constructor
      31             :  ******************************************************/
      32           6 : EbErrorType entropy_coding_context_ctor(
      33             :     EntropyCodingContext  *context_ptr,
      34             :     EbFifo                *enc_dec_input_fifo_ptr,
      35             :     EbFifo                *packetization_output_fifo_ptr,
      36             :     EbFifo                *rate_control_output_fifo_ptr,
      37             :     EbBool                  is16bit)
      38             : {
      39           6 :     context_ptr->is16bit = is16bit;
      40             : 
      41             :     // Input/Output System Resource Manager FIFOs
      42           6 :     context_ptr->enc_dec_input_fifo_ptr = enc_dec_input_fifo_ptr;
      43           6 :     context_ptr->entropy_coding_output_fifo_ptr = packetization_output_fifo_ptr;
      44           6 :     context_ptr->rate_control_output_fifo_ptr = rate_control_output_fifo_ptr;
      45             : 
      46           6 :     return EB_ErrorNone;
      47             : }
      48             : 
      49             : /***********************************************
      50             :  * Entropy Coding Reset Neighbor Arrays
      51             :  ***********************************************/
      52         120 : static void EntropyCodingResetNeighborArrays(PictureControlSet *picture_control_set_ptr)
      53             : {
      54         120 :     neighbor_array_unit_reset(picture_control_set_ptr->mode_type_neighbor_array);
      55             : 
      56         120 :     neighbor_array_unit_reset(picture_control_set_ptr->partition_context_neighbor_array);
      57             : 
      58         120 :     neighbor_array_unit_reset(picture_control_set_ptr->skip_flag_neighbor_array);
      59             : 
      60         120 :     neighbor_array_unit_reset(picture_control_set_ptr->skip_coeff_neighbor_array);
      61         120 :     neighbor_array_unit_reset(picture_control_set_ptr->luma_dc_sign_level_coeff_neighbor_array);
      62         120 :     neighbor_array_unit_reset(picture_control_set_ptr->cb_dc_sign_level_coeff_neighbor_array);
      63         120 :     neighbor_array_unit_reset(picture_control_set_ptr->cr_dc_sign_level_coeff_neighbor_array);
      64         120 :     neighbor_array_unit_reset(picture_control_set_ptr->inter_pred_dir_neighbor_array);
      65         120 :     neighbor_array_unit_reset(picture_control_set_ptr->ref_frame_type_neighbor_array);
      66             : 
      67         120 :     neighbor_array_unit_reset(picture_control_set_ptr->intra_luma_mode_neighbor_array);
      68         120 :     neighbor_array_unit_reset32(picture_control_set_ptr->interpolation_type_neighbor_array);
      69         120 :     neighbor_array_unit_reset(picture_control_set_ptr->txfm_context_array);
      70         120 :     neighbor_array_unit_reset(picture_control_set_ptr->segmentation_id_pred_array);
      71         120 :     return;
      72             : }
      73             : 
      74             : void av1_get_syntax_rate_from_cdf(
      75             :     int32_t                      *costs,
      76             :     const AomCdfProb       *cdf,
      77             :     const int32_t                *inv_map);
      78             : 
      79        3956 : void eb_av1_cost_tokens_from_cdf(int32_t *costs, const AomCdfProb *cdf,
      80             :     const int32_t *inv_map) {
      81             :     // int32_t i;
      82             :     // AomCdfProb prev_cdf = 0;
      83             :     // for (i = 0;; ++i) {
      84             :     //     AomCdfProb p15 = AOM_ICDF(cdf[i]) - prev_cdf;
      85             :     //     p15 = (p15 < EC_MIN_PROB) ? EC_MIN_PROB : p15;
      86             :     //     prev_cdf = AOM_ICDF(cdf[i]);
      87             :     //
      88             :     //     if (inv_map)
      89             :     //         costs[inv_map[i]] = av1_cost_symbol(p15);
      90             :     //     else
      91             :     //         costs[i] = av1_cost_symbol(p15);
      92             :     //
      93             :     //     // Stop once we reach the end of the CDF
      94             :     //     if (cdf[i] == AOM_ICDF(CDF_PROB_TOP)) break;
      95             :     // }
      96             : 
      97        3956 :     av1_get_syntax_rate_from_cdf(costs, cdf, inv_map);
      98        3955 : }
      99             : 
     100         240 : static void build_nmv_component_cost_table(int32_t *mvcost,
     101             :     const NmvComponent *const mvcomp,
     102             :     MvSubpelPrecision precision) {
     103             :     int32_t i, v;
     104             :     int32_t sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE];
     105             :     int32_t bits_cost[MV_OFFSET_BITS][2];
     106             :     int32_t class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE];
     107             :     int32_t class0_hp_cost[2], hp_cost[2];
     108             : 
     109         240 :     eb_av1_cost_tokens_from_cdf(sign_cost, mvcomp->sign_cdf, NULL);
     110         240 :     eb_av1_cost_tokens_from_cdf(class_cost, mvcomp->classes_cdf, NULL);
     111         240 :     eb_av1_cost_tokens_from_cdf(class0_cost, mvcomp->class0_cdf, NULL);
     112        2638 :     for (i = 0; i < MV_OFFSET_BITS; ++i)
     113        2398 :         eb_av1_cost_tokens_from_cdf(bits_cost[i], mvcomp->bits_cdf[i], NULL);
     114         720 :     for (i = 0; i < CLASS0_SIZE; ++i)
     115         480 :         eb_av1_cost_tokens_from_cdf(class0_fp_cost[i], mvcomp->class0_fp_cdf[i], NULL);
     116         240 :     eb_av1_cost_tokens_from_cdf(fp_cost, mvcomp->fp_cdf, NULL);
     117             : 
     118         240 :     if (precision > MV_SUBPEL_LOW_PRECISION) {
     119           0 :         eb_av1_cost_tokens_from_cdf(class0_hp_cost, mvcomp->class0_hp_cdf, NULL);
     120           0 :         eb_av1_cost_tokens_from_cdf(hp_cost, mvcomp->hp_cdf, NULL);
     121             :     }
     122         240 :     mvcost[0] = 0;
     123     3823150 :     for (v = 1; v <= MV_MAX; ++v) {
     124     3827840 :         int32_t z, c, o, d, e, f, cost = 0;
     125     3827840 :         z = v - 1;
     126     3827840 :         c = av1_get_mv_class(z, &o);
     127     3822910 :         cost += class_cost[c];
     128     3822910 :         d = (o >> 3);     /* int32_t mv data */
     129     3822910 :         f = (o >> 1) & 3; /* fractional pel mv data */
     130     3822910 :         e = (o & 1);      /* high precision mv data */
     131     3822910 :         if (c == MV_CLASS_0)
     132        3840 :             cost += class0_cost[d];
     133             :         else {
     134     3819070 :             const int32_t b = c + CLASS0_BITS - 1; /* number of bits */
     135    38098600 :             for (i = 0; i < b; ++i) cost += bits_cost[i][((d >> i) & 1)];
     136             :         }
     137     3822910 :         if (precision > MV_SUBPEL_NONE) {
     138     3826480 :             if (c == MV_CLASS_0)
     139        3840 :                 cost += class0_fp_cost[d][f];
     140             :             else
     141     3822640 :                 cost += fp_cost[f];
     142     3826480 :             if (precision > MV_SUBPEL_LOW_PRECISION) {
     143           0 :                 if (c == MV_CLASS_0)
     144           0 :                     cost += class0_hp_cost[e];
     145             :                 else
     146           0 :                     cost += hp_cost[e];
     147             :             }
     148             :         }
     149     3822910 :         mvcost[v] = cost + sign_cost[0];
     150     3822910 :         mvcost[-v] = cost + sign_cost[1];
     151             :     }
     152           0 : }
     153         120 : void eb_av1_build_nmv_cost_table(int32_t *mvjoint, int32_t *mvcost[2],
     154             :     const NmvContext *ctx,
     155             :     MvSubpelPrecision precision) {
     156         120 :     eb_av1_cost_tokens_from_cdf(mvjoint, ctx->joints_cdf, NULL);
     157         120 :     build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], precision);
     158         120 :     build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], precision);
     159         120 : }
     160             : 
     161             : /**************************************************
     162             :  * Reset Entropy Coding Picture
     163             :  **************************************************/
     164         120 : static void ResetEntropyCodingPicture(
     165             :     EntropyCodingContext  *context_ptr,
     166             :     PictureControlSet     *picture_control_set_ptr,
     167             :     SequenceControlSet    *sequence_control_set_ptr)
     168             : {
     169         120 :     reset_bitstream(entropy_coder_get_bitstream_ptr(picture_control_set_ptr->entropy_coder_ptr));
     170             : 
     171             :     uint32_t                       entropyCodingQp;
     172             : 
     173         120 :     context_ptr->is16bit = (EbBool)(sequence_control_set_ptr->static_config.encoder_bit_depth > EB_8BIT);
     174         120 :     FrameHeader *frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
     175             :     // QP
     176             : #if ADD_DELTA_QP_SUPPORT
     177             : #else
     178             :     context_ptr->qp = picture_control_set_ptr->picture_qp;
     179             : #endif
     180             :     // Asuming cb and cr offset to be the same for chroma QP in both slice and pps for lambda computation
     181         120 :     entropyCodingQp = picture_control_set_ptr->parent_pcs_ptr->frm_hdr.quantization_params.base_q_idx;
     182             : 
     183             : #if ADD_DELTA_QP_SUPPORT
     184         120 :     picture_control_set_ptr->parent_pcs_ptr->prev_qindex = picture_control_set_ptr->parent_pcs_ptr->frm_hdr.quantization_params.base_q_idx;
     185         120 :     if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_intrabc)
     186           0 :         assert(picture_control_set_ptr->parent_pcs_ptr->frm_hdr.delta_lf_params.delta_lf_present == 0);
     187         120 :     if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.delta_lf_params.delta_lf_present) {
     188           0 :         picture_control_set_ptr->parent_pcs_ptr->prev_delta_lf_from_base = 0;
     189           0 :         const int32_t frame_lf_count =
     190           0 :             picture_control_set_ptr->parent_pcs_ptr->monochrome == 0 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
     191           0 :         for (int32_t lf_id = 0; lf_id < frame_lf_count; ++lf_id)
     192           0 :             picture_control_set_ptr->parent_pcs_ptr->prev_delta_lf[lf_id] = 0;
     193             :     }
     194             : #endif
     195             : 
     196             :     // pass the ent
     197         120 :     OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit*)(picture_control_set_ptr->entropy_coder_ptr->ec_output_bitstream_ptr);
     198             :     //****************************************************************//
     199             : 
     200         120 :     uint8_t *data = output_bitstream_ptr->buffer_av1;
     201         120 :     picture_control_set_ptr->entropy_coder_ptr->ec_writer.allow_update_cdf = !picture_control_set_ptr->parent_pcs_ptr->large_scale_tile;
     202         120 :     picture_control_set_ptr->entropy_coder_ptr->ec_writer.allow_update_cdf =
     203         120 :         picture_control_set_ptr->entropy_coder_ptr->ec_writer.allow_update_cdf && !frm_hdr->disable_cdf_update;
     204         120 :     aom_start_encode(&picture_control_set_ptr->entropy_coder_ptr->ec_writer, data);
     205             : 
     206             :     // ADD Reset here
     207         120 :     if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.primary_ref_frame != PRIMARY_REF_NONE)
     208          58 :         memcpy(picture_control_set_ptr->entropy_coder_ptr->fc, &picture_control_set_ptr->ref_frame_context[picture_control_set_ptr->parent_pcs_ptr->frm_hdr.primary_ref_frame], sizeof(FRAME_CONTEXT));
     209             :     else
     210          62 :         reset_entropy_coder(
     211             :             sequence_control_set_ptr->encode_context_ptr,
     212             :             picture_control_set_ptr->entropy_coder_ptr,
     213             :             entropyCodingQp,
     214          62 :             picture_control_set_ptr->slice_type);
     215         120 :     EntropyCodingResetNeighborArrays(picture_control_set_ptr);
     216             : 
     217         120 :     return;
     218             : }
     219             : 
     220           0 : static void reset_ec_tile(
     221             :     uint32_t  total_size,
     222             :     uint32_t  is_last_tile_in_tg,
     223             :     EntropyCodingContext  *context_ptr,
     224             :     PictureControlSet     *picture_control_set_ptr,
     225             :     SequenceControlSet    *sequence_control_set_ptr)
     226             : {
     227           0 :     reset_bitstream(entropy_coder_get_bitstream_ptr(picture_control_set_ptr->entropy_coder_ptr));
     228             : 
     229             :     uint32_t                       entropy_coding_qp;
     230             : 
     231           0 :     context_ptr->is16bit = (EbBool)(sequence_control_set_ptr->static_config.encoder_bit_depth > EB_8BIT);
     232           0 :     FrameHeader *frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
     233             :     // QP
     234             : #if ADD_DELTA_QP_SUPPORT
     235             : #else
     236             :     context_ptr->qp = picture_control_set_ptr->picture_qp;
     237             : #endif
     238           0 :     entropy_coding_qp = picture_control_set_ptr->parent_pcs_ptr->frm_hdr.quantization_params.base_q_idx;
     239             : #if ADD_DELTA_QP_SUPPORT
     240           0 :     picture_control_set_ptr->parent_pcs_ptr->prev_qindex = picture_control_set_ptr->parent_pcs_ptr->frm_hdr.quantization_params.base_q_idx;
     241           0 :     if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_intrabc)
     242           0 :         assert(picture_control_set_ptr->parent_pcs_ptr->frm_hdr.delta_lf_params.delta_lf_present == 0);
     243           0 :     if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.delta_lf_params.delta_lf_present) {
     244           0 :         picture_control_set_ptr->parent_pcs_ptr->prev_delta_lf_from_base = 0;
     245           0 :         const int32_t frame_lf_count =
     246           0 :             picture_control_set_ptr->parent_pcs_ptr->monochrome == 0 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
     247           0 :         for (int32_t lf_id = 0; lf_id < frame_lf_count; ++lf_id)
     248           0 :             picture_control_set_ptr->parent_pcs_ptr->prev_delta_lf[lf_id] = 0;
     249             :     }
     250             : #endif
     251             : 
     252             :     // pass the ent
     253           0 :     OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit*)(picture_control_set_ptr->entropy_coder_ptr->ec_output_bitstream_ptr);
     254             :     //****************************************************************//
     255             : 
     256           0 :     uint8_t *data = output_bitstream_ptr->buffer_av1 + total_size;
     257           0 :     picture_control_set_ptr->entropy_coder_ptr->ec_writer.allow_update_cdf = !picture_control_set_ptr->parent_pcs_ptr->large_scale_tile;
     258           0 :     picture_control_set_ptr->entropy_coder_ptr->ec_writer.allow_update_cdf =
     259           0 :         picture_control_set_ptr->entropy_coder_ptr->ec_writer.allow_update_cdf && !frm_hdr->disable_cdf_update;
     260             : 
     261             :     //if not last tile, advance buffer by 4B to leave space for tile Size
     262           0 :     if (is_last_tile_in_tg == 0)
     263           0 :         data += 4;
     264             : 
     265           0 :     aom_start_encode(&picture_control_set_ptr->entropy_coder_ptr->ec_writer, data);
     266           0 :     if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.primary_ref_frame != PRIMARY_REF_NONE)
     267           0 :         memcpy(picture_control_set_ptr->entropy_coder_ptr->fc, &picture_control_set_ptr->ref_frame_context[picture_control_set_ptr->parent_pcs_ptr->frm_hdr.primary_ref_frame], sizeof(FRAME_CONTEXT));
     268             :     else
     269             :         //reset probabilities
     270           0 :         reset_entropy_coder(
     271             :             sequence_control_set_ptr->encode_context_ptr,
     272             :             picture_control_set_ptr->entropy_coder_ptr,
     273             :             entropy_coding_qp,
     274           0 :             picture_control_set_ptr->slice_type);
     275           0 :     EntropyCodingResetNeighborArrays(picture_control_set_ptr);
     276             : 
     277           0 :     return;
     278             : }
     279             : 
     280             : /******************************************************
     281             :  * Update Entropy Coding Rows
     282             :  *
     283             :  * This function is responsible for synchronizing the
     284             :  *   processing of Entropy Coding LCU-rows and starts
     285             :  *   processing of LCU-rows as soon as their inputs are
     286             :  *   available and the previous LCU-row has completed.
     287             :  *   At any given time, only one segment row per picture
     288             :  *   is being processed.
     289             :  *
     290             :  * The function has two parts:
     291             :  *
     292             :  * (1) Update the available row index which tracks
     293             :  *   which SB Row-inputs are available.
     294             :  *
     295             :  * (2) Increment the lcu-row counter as the segment-rows
     296             :  *   are completed.
     297             :  *
     298             :  * Since there is the potentential for thread collusion,
     299             :  *   a MUTEX a used to protect the sensitive data and
     300             :  *   the execution flow is separated into two paths
     301             :  *
     302             :  * (A) Initial update.
     303             :  *  -Update the Completion Mask [see (1) above]
     304             :  *  -If the picture is not currently being processed,
     305             :  *     check to see if the next segment-row is available
     306             :  *     and start processing.
     307             :  * (B) Continued processing
     308             :  *  -Upon the completion of a segment-row, check
     309             :  *     to see if the next segment-row's inputs have
     310             :  *     become available and begin processing if so.
     311             :  *
     312             :  * On last important point is that the thread-safe
     313             :  *   code section is kept minimally short. The MUTEX
     314             :  *   should NOT be locked for the entire processing
     315             :  *   of the segment-row (B) as this would block other
     316             :  *   threads from performing an update (A).
     317             :  ******************************************************/
     318         840 : static EbBool UpdateEntropyCodingRows(
     319             :     PictureControlSet *picture_control_set_ptr,
     320             :     uint32_t              *row_index,
     321             :     uint32_t               row_count,
     322             :     EbBool             *initialProcessCall)
     323             : {
     324         840 :     EbBool processNextRow = EB_FALSE;
     325             : 
     326             :     // Note, any writes & reads to status variables (e.g. in_progress) in MD-CTRL must be thread-safe
     327         840 :     eb_block_on_mutex(picture_control_set_ptr->entropy_coding_mutex);
     328             : 
     329             :     // Update availability mask
     330         840 :     if (*initialProcessCall == EB_TRUE) {
     331             :         unsigned i;
     332             : 
     333         840 :         for (i = *row_index; i < *row_index + row_count; ++i)
     334         720 :             picture_control_set_ptr->entropy_coding_row_array[i] = EB_TRUE;
     335         840 :         while (picture_control_set_ptr->entropy_coding_row_array[picture_control_set_ptr->entropy_coding_current_available_row] == EB_TRUE &&
     336         720 :             picture_control_set_ptr->entropy_coding_current_available_row < picture_control_set_ptr->entropy_coding_row_count)
     337             :         {
     338         720 :             ++picture_control_set_ptr->entropy_coding_current_available_row;
     339             :         }
     340             :     }
     341             : 
     342             :     // Release in_progress token
     343         840 :     if (*initialProcessCall == EB_FALSE && picture_control_set_ptr->entropy_coding_in_progress == EB_TRUE)
     344         718 :         picture_control_set_ptr->entropy_coding_in_progress = EB_FALSE;
     345             :     // Test if the picture is not already complete AND not currently being worked on by another ENCDEC process
     346         840 :     if (picture_control_set_ptr->entropy_coding_current_row < picture_control_set_ptr->entropy_coding_row_count &&
     347         722 :         picture_control_set_ptr->entropy_coding_row_array[picture_control_set_ptr->entropy_coding_current_row] == EB_TRUE &&
     348         720 :         picture_control_set_ptr->entropy_coding_in_progress == EB_FALSE)
     349             :     {
     350             :         // Test if the next LCU-row is ready to go
     351         720 :         if (picture_control_set_ptr->entropy_coding_current_row <= picture_control_set_ptr->entropy_coding_current_available_row)
     352             :         {
     353         720 :             picture_control_set_ptr->entropy_coding_in_progress = EB_TRUE;
     354         720 :             *row_index = picture_control_set_ptr->entropy_coding_current_row++;
     355         720 :             processNextRow = EB_TRUE;
     356             :         }
     357             :     }
     358             : 
     359         840 :     *initialProcessCall = EB_FALSE;
     360             : 
     361         840 :     eb_release_mutex(picture_control_set_ptr->entropy_coding_mutex);
     362             : 
     363         840 :     return processNextRow;
     364             : }
     365             : #if TWO_PASS
     366             : /******************************************************
     367             :  * Write Stat to File
     368             :  * write stat_struct per frame in the first pass
     369             :  ******************************************************/
     370           0 : void write_stat_to_file(
     371             :     SequenceControlSet    *sequence_control_set_ptr,
     372             :     stat_struct_t          stat_struct,
     373             :     uint64_t               ref_poc)
     374             : {
     375           0 :     eb_block_on_mutex(sequence_control_set_ptr->encode_context_ptr->stat_file_mutex);
     376           0 :     int32_t fseek_return_value = fseek(sequence_control_set_ptr->static_config.output_stat_file, (long)ref_poc * sizeof(stat_struct_t), SEEK_SET);
     377           0 :     if (fseek_return_value != 0)
     378           0 :         printf("Error in fseek  returnVal %i\n", fseek_return_value);
     379           0 :     fwrite(&stat_struct,
     380             :         sizeof(stat_struct_t),
     381             :         (size_t)1,
     382             :         sequence_control_set_ptr->static_config.output_stat_file);
     383           0 :     eb_release_mutex(sequence_control_set_ptr->encode_context_ptr->stat_file_mutex);
     384           0 : }
     385             : #endif
     386             : /******************************************************
     387             :  * Entropy Coding Kernel
     388             :  ******************************************************/
     389           6 : void* entropy_coding_kernel(void *input_ptr)
     390             : {
     391             :     // Context & SCS & PCS
     392           6 :     EntropyCodingContext                  *context_ptr = (EntropyCodingContext*)input_ptr;
     393             :     PictureControlSet                     *picture_control_set_ptr;
     394             :     SequenceControlSet                    *sequence_control_set_ptr;
     395             : 
     396             :     // Input
     397             :     EbObjectWrapper                       *encDecResultsWrapperPtr;
     398             :     EncDecResults                         *encDecResultsPtr;
     399             : 
     400             :     // Output
     401             :     EbObjectWrapper                       *entropyCodingResultsWrapperPtr;
     402             :     EntropyCodingResults                  *entropyCodingResultsPtr;
     403             : 
     404             :     // SB Loop variables
     405             :     LargestCodingUnit                     *sb_ptr;
     406             :     uint16_t                                   sb_index;
     407             :     uint8_t                                    sb_sz;
     408             :     uint8_t                                    lcuSizeLog2;
     409             :     uint32_t                                   x_lcu_index;
     410             :     uint32_t                                   y_lcu_index;
     411             :     uint32_t                                   sb_origin_x;
     412             :     uint32_t                                   sb_origin_y;
     413             :     uint32_t                                   picture_width_in_sb;
     414             :     // Variables
     415             :     EbBool                                  initialProcessCall;
     416             :     for (;;) {
     417             :         // Get Mode Decision Results
     418         126 :         eb_get_full_object(
     419             :             context_ptr->enc_dec_input_fifo_ptr,
     420             :             &encDecResultsWrapperPtr);
     421         120 :         encDecResultsPtr = (EncDecResults*)encDecResultsWrapperPtr->object_ptr;
     422         120 :         picture_control_set_ptr = (PictureControlSet*)encDecResultsPtr->picture_control_set_wrapper_ptr->object_ptr;
     423         120 :         sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
     424             :         // SB Constants
     425             : 
     426         120 :         sb_sz = (uint8_t)sequence_control_set_ptr->sb_size_pix;
     427             : 
     428         120 :         lcuSizeLog2 = (uint8_t)Log2f(sb_sz);
     429         120 :         context_ptr->sb_sz = sb_sz;
     430         120 :         picture_width_in_sb = (sequence_control_set_ptr->seq_header.max_frame_width + sb_sz - 1) >> lcuSizeLog2;
     431         120 :         if(picture_control_set_ptr->parent_pcs_ptr->av1_cm->tiles_info.tile_cols * picture_control_set_ptr->parent_pcs_ptr->av1_cm->tiles_info.tile_rows == 1)
     432             : 
     433             :         {
     434         120 :             initialProcessCall = EB_TRUE;
     435         120 :             y_lcu_index = encDecResultsPtr->completed_lcu_row_index_start;
     436             : 
     437             :             // LCU-loops
     438         840 :             while (UpdateEntropyCodingRows(picture_control_set_ptr, &y_lcu_index, encDecResultsPtr->completed_lcu_row_count, &initialProcessCall) == EB_TRUE)
     439             :             {
     440         720 :                 uint32_t rowTotalBits = 0;
     441             : 
     442         720 :                 if (y_lcu_index == 0) {
     443         120 :                     ResetEntropyCodingPicture(
     444             :                         context_ptr,
     445             :                         picture_control_set_ptr,
     446             :                         sequence_control_set_ptr);
     447         120 :                     picture_control_set_ptr->entropy_coding_pic_done = EB_FALSE;
     448             :                 }
     449             : 
     450        7920 :                 for (x_lcu_index = 0; x_lcu_index < picture_width_in_sb; ++x_lcu_index)
     451             :                 {
     452        7200 :                     sb_index = (uint16_t)(x_lcu_index + y_lcu_index * picture_width_in_sb);
     453        7200 :                     sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
     454             : 
     455        7200 :                     sb_origin_x = x_lcu_index << lcuSizeLog2;
     456        7200 :                     sb_origin_y = y_lcu_index << lcuSizeLog2;
     457        7200 :                     context_ptr->sb_origin_x = sb_origin_x;
     458        7200 :                     context_ptr->sb_origin_y = sb_origin_y;
     459        7200 :                     if (sb_index == 0)
     460         120 :                         eb_av1_reset_loop_restoration(picture_control_set_ptr);
     461             : #if PAL_SUP
     462        7199 :                     if (sb_index == 0)
     463         120 :                         context_ptr->tok = picture_control_set_ptr->tile_tok[0][0];
     464             : #endif
     465        7199 :                     sb_ptr->total_bits = 0;
     466        7199 :                     uint32_t prev_pos = sb_index ? picture_control_set_ptr->entropy_coder_ptr->ec_writer.ec.offs : 0;//residual_bc.pos
     467        7199 :                     EbPictureBufferDesc *coeff_picture_ptr = sb_ptr->quantized_coeff;
     468        7199 :                     write_sb(
     469             :                         context_ptr,
     470             :                         sb_ptr,
     471             :                         picture_control_set_ptr,
     472             :                         picture_control_set_ptr->entropy_coder_ptr,
     473             :                         coeff_picture_ptr);
     474        7200 :                     sb_ptr->total_bits = (picture_control_set_ptr->entropy_coder_ptr->ec_writer.ec.offs - prev_pos) << 3;
     475        7200 :                     picture_control_set_ptr->parent_pcs_ptr->quantized_coeff_num_bits += sb_ptr->total_bits;
     476        7200 :                     rowTotalBits += sb_ptr->total_bits;
     477             :                 }
     478             : 
     479             :                 // At the end of each LCU-row, send the updated bit-count to Entropy Coding
     480             :                 {
     481             :                     EbObjectWrapper *rateControlTaskWrapperPtr;
     482             :                     RateControlTasks *rateControlTaskPtr;
     483             : 
     484             :                     // Get Empty EncDec Results
     485         720 :                     eb_get_empty_object(
     486             :                         context_ptr->rate_control_output_fifo_ptr,
     487             :                         &rateControlTaskWrapperPtr);
     488         720 :                     rateControlTaskPtr = (RateControlTasks*)rateControlTaskWrapperPtr->object_ptr;
     489         720 :                     rateControlTaskPtr->task_type = RC_ENTROPY_CODING_ROW_FEEDBACK_RESULT;
     490         720 :                     rateControlTaskPtr->picture_number = picture_control_set_ptr->picture_number;
     491         720 :                     rateControlTaskPtr->row_number = y_lcu_index;
     492         720 :                     rateControlTaskPtr->bit_count = rowTotalBits;
     493             : 
     494         720 :                     rateControlTaskPtr->picture_control_set_wrapper_ptr = 0;
     495         720 :                     rateControlTaskPtr->segment_index = ~0u;
     496             : 
     497             :                     // Post EncDec Results
     498         720 :                     eb_post_full_object(rateControlTaskWrapperPtr);
     499             :                 }
     500             : 
     501         720 :                 eb_block_on_mutex(picture_control_set_ptr->entropy_coding_mutex);
     502         720 :                 if (picture_control_set_ptr->entropy_coding_pic_done == EB_FALSE) {
     503             :                     // If the picture is complete, terminate the slice
     504         720 :                     if (picture_control_set_ptr->entropy_coding_current_row == picture_control_set_ptr->entropy_coding_row_count)
     505             :                     {
     506             :                         uint32_t ref_idx;
     507             : 
     508         120 :                         picture_control_set_ptr->entropy_coding_pic_done = EB_TRUE;
     509             : 
     510         120 :                         encode_slice_finish(picture_control_set_ptr->entropy_coder_ptr);
     511             : #if TWO_PASS
     512             :                         // for Non Reference frames
     513         120 :                         if (sequence_control_set_ptr->use_output_stat_file &&
     514           0 :                             !picture_control_set_ptr->parent_pcs_ptr->is_used_as_reference_flag)
     515           0 :                             write_stat_to_file(
     516             :                                 sequence_control_set_ptr,
     517           0 :                                 *picture_control_set_ptr->parent_pcs_ptr->stat_struct_first_pass_ptr,
     518           0 :                                 picture_control_set_ptr->parent_pcs_ptr->picture_number);
     519             : #endif
     520             :                         // Release the List 0 Reference Pictures
     521         352 :                         for (ref_idx = 0; ref_idx < picture_control_set_ptr->parent_pcs_ptr->ref_list0_count; ++ref_idx) {
     522             : #if TWO_PASS
     523         232 :                             if (sequence_control_set_ptr->use_output_stat_file &&
     524           0 :                                 picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx] != EB_NULL && picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx]->live_count == 1)
     525           0 :                                 write_stat_to_file(
     526             :                                     sequence_control_set_ptr,
     527           0 :                                     ((EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx]->object_ptr)->stat_struct,
     528           0 :                                     ((EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx]->object_ptr)->ref_poc);
     529             : #endif
     530         232 :                             if (picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx] != EB_NULL) {
     531             : 
     532         232 :                                 eb_release_object(picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx]);
     533             :                             }
     534             :                         }
     535             : 
     536             :                         // Release the List 1 Reference Pictures
     537         283 :                         for (ref_idx = 0; ref_idx < picture_control_set_ptr->parent_pcs_ptr->ref_list1_count; ++ref_idx) {
     538             : #if TWO_PASS
     539         163 :                             if (sequence_control_set_ptr->use_output_stat_file &&
     540           0 :                                 picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx] != EB_NULL && picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx]->live_count == 1)
     541           0 :                                 write_stat_to_file(
     542             :                                     sequence_control_set_ptr,
     543           0 :                                     ((EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx]->object_ptr)->stat_struct,
     544           0 :                                     ((EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx]->object_ptr)->ref_poc);
     545             : #endif
     546             : 
     547         163 :                             if (picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx] != EB_NULL)
     548         163 :                                 eb_release_object(picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx]);
     549             :                         }
     550             : 
     551             :                         // Get Empty Entropy Coding Results
     552         120 :                         eb_get_empty_object(
     553             :                             context_ptr->entropy_coding_output_fifo_ptr,
     554             :                             &entropyCodingResultsWrapperPtr);
     555         120 :                         entropyCodingResultsPtr = (EntropyCodingResults*)entropyCodingResultsWrapperPtr->object_ptr;
     556         120 :                         entropyCodingResultsPtr->picture_control_set_wrapper_ptr = encDecResultsPtr->picture_control_set_wrapper_ptr;
     557             : 
     558             :                         // Post EntropyCoding Results
     559         120 :                         eb_post_full_object(entropyCodingResultsWrapperPtr);
     560             :                     } // End if(PictureCompleteFlag)
     561             :                 }
     562         720 :                 eb_release_mutex(picture_control_set_ptr->entropy_coding_mutex);
     563             :             }
     564             :         }
     565             :         else
     566             :         {
     567           0 :              struct PictureParentControlSet     *ppcs_ptr = picture_control_set_ptr->parent_pcs_ptr;
     568           0 :              Av1Common *const cm = ppcs_ptr->av1_cm;
     569           0 :              uint32_t total_size = 0;
     570             :              int tile_row, tile_col;
     571           0 :              const int tile_cols = ppcs_ptr->av1_cm->tiles_info.tile_cols;
     572           0 :              const int tile_rows = ppcs_ptr->av1_cm->tiles_info.tile_rows;
     573             : 
     574             :              //Entropy Tile Loop
     575           0 :              for (tile_row = 0; tile_row < tile_rows; tile_row++)
     576             :              {
     577             :                  TileInfo tile_info;
     578           0 :                  eb_av1_tile_set_row(&tile_info, &cm->tiles_info, cm->mi_rows, tile_row);
     579             : 
     580           0 :                  for (tile_col = 0; tile_col < tile_cols; tile_col++)
     581             :                  {
     582           0 :                      const int tile_idx = tile_row * tile_cols + tile_col;
     583           0 :                      uint32_t is_last_tile_in_tg = 0;
     584             : 
     585           0 :                      if ( tile_idx == (tile_cols * tile_rows - 1))
     586           0 :                          is_last_tile_in_tg = 1;
     587             :                      else
     588           0 :                          is_last_tile_in_tg = 0;
     589           0 :                      reset_ec_tile(
     590             :                          total_size,
     591             :                          is_last_tile_in_tg,
     592             :                          context_ptr,
     593             :                          picture_control_set_ptr,
     594             :                          sequence_control_set_ptr);
     595             : #if PAL_SUP
     596           0 :                      context_ptr->tok = picture_control_set_ptr->tile_tok[0][0];
     597             : #endif
     598             : 
     599           0 :                      eb_av1_tile_set_col(&tile_info, &cm->tiles_info, cm->mi_cols, tile_col);
     600             : 
     601           0 :                      eb_av1_reset_loop_restoration(picture_control_set_ptr);
     602           0 :                      int sb_size_log2 = sequence_control_set_ptr->seq_header.sb_size_log2;
     603             : 
     604           0 :                      for ((y_lcu_index = cm->tiles_info.tile_row_start_mi[tile_row] >> sb_size_log2);
     605           0 :                           (y_lcu_index < (uint32_t)cm->tiles_info.tile_row_start_mi[tile_row + 1] >> sb_size_log2);
     606           0 :                           y_lcu_index++)
     607             :                      {
     608           0 :                          for (x_lcu_index = (cm->tiles_info.tile_col_start_mi[tile_col] >> sb_size_log2);
     609           0 :                               x_lcu_index < ((uint32_t)cm->tiles_info.tile_col_start_mi[tile_col + 1] >> sb_size_log2);
     610           0 :                               x_lcu_index++)
     611             :                          {
     612           0 :                              int sb_index = (uint16_t)(x_lcu_index + y_lcu_index * picture_width_in_sb);
     613           0 :                              sb_ptr = picture_control_set_ptr->sb_ptr_array[sb_index];
     614           0 :                              sb_origin_x = x_lcu_index << lcuSizeLog2;
     615           0 :                              sb_origin_y = y_lcu_index << lcuSizeLog2;
     616           0 :                              context_ptr->sb_origin_x = sb_origin_x;
     617           0 :                              context_ptr->sb_origin_y = sb_origin_y;
     618           0 :                              sb_ptr->total_bits = 0;
     619           0 :                              uint32_t prev_pos = sb_index ? picture_control_set_ptr->entropy_coder_ptr->ec_writer.ec.offs : 0;//residual_bc.pos
     620           0 :                              EbPictureBufferDesc *coeff_picture_ptr = sb_ptr->quantized_coeff;
     621           0 :                              write_sb(
     622             :                                  context_ptr,
     623             :                                  sb_ptr,
     624             :                                  picture_control_set_ptr,
     625             :                                  picture_control_set_ptr->entropy_coder_ptr,
     626             :                                  coeff_picture_ptr);
     627           0 :                              sb_ptr->total_bits = (picture_control_set_ptr->entropy_coder_ptr->ec_writer.ec.offs - prev_pos) << 3;
     628           0 :                              picture_control_set_ptr->parent_pcs_ptr->quantized_coeff_num_bits += sb_ptr->total_bits;
     629             :                          }
     630             :                      }
     631             : 
     632           0 :                      encode_slice_finish(picture_control_set_ptr->entropy_coder_ptr);
     633             : 
     634           0 :                      int tile_size = picture_control_set_ptr->entropy_coder_ptr->ec_writer.pos;
     635           0 :                      assert(tile_size >= AV1_MIN_TILE_SIZE_BYTES);
     636             : 
     637           0 :                      if (!is_last_tile_in_tg) {
     638           0 :                          OutputBitstreamUnit *output_bitstream_ptr = (OutputBitstreamUnit*)(picture_control_set_ptr->entropy_coder_ptr->ec_output_bitstream_ptr);
     639           0 :                          uint8_t *buf_data = output_bitstream_ptr->buffer_av1 + total_size;
     640           0 :                          mem_put_le32(buf_data, tile_size - AV1_MIN_TILE_SIZE_BYTES);
     641             :                      }
     642             : 
     643           0 :                      if (is_last_tile_in_tg==0)
     644           0 :                          total_size += 4;
     645             : 
     646           0 :                      total_size += tile_size;
     647             :                  }
     648             :              }
     649             : 
     650             :              //the picture is complete, terminate the slice
     651             :              {
     652             :                  uint32_t ref_idx;
     653           0 :                  picture_control_set_ptr->entropy_coder_ptr->ec_frame_size = total_size;
     654             : 
     655             :                  // Release the List 0 Reference Pictures
     656           0 :                  for (ref_idx = 0; ref_idx < picture_control_set_ptr->parent_pcs_ptr->ref_list0_count; ++ref_idx) {
     657           0 :                      if (picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx] != EB_NULL)
     658           0 :                          eb_release_object(picture_control_set_ptr->ref_pic_ptr_array[0][ref_idx]);
     659             :                  }
     660             : 
     661             :                  // Release the List 1 Reference Pictures
     662           0 :                  for (ref_idx = 0; ref_idx < picture_control_set_ptr->parent_pcs_ptr->ref_list1_count; ++ref_idx) {
     663           0 :                      if (picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx] != EB_NULL)
     664           0 :                          eb_release_object(picture_control_set_ptr->ref_pic_ptr_array[1][ref_idx]);
     665             :                  }
     666             : 
     667             :                  // Get Empty Entropy Coding Results
     668           0 :                  eb_get_empty_object(
     669             :                      context_ptr->entropy_coding_output_fifo_ptr,
     670             :                      &entropyCodingResultsWrapperPtr);
     671           0 :                  entropyCodingResultsPtr = (EntropyCodingResults*)entropyCodingResultsWrapperPtr->object_ptr;
     672           0 :                  entropyCodingResultsPtr->picture_control_set_wrapper_ptr = encDecResultsPtr->picture_control_set_wrapper_ptr;
     673             : 
     674             :                  // Post EntropyCoding Results
     675           0 :                  eb_post_full_object(entropyCodingResultsWrapperPtr);
     676             :              }
     677             :         }
     678             : 
     679             :         // Release Mode Decision Results
     680         120 :         eb_release_object(encDecResultsWrapperPtr);
     681             :     }
     682             : 
     683             :     return EB_NULL;
     684             : }

Generated by: LCOV version 1.14