LCOV - code coverage report
Current view: top level - home/magsoft/trunks/SVT-AV1/Source/Lib/Encoder/Codec - EbInitialRateControlProcess.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 516 602 85.7 %
Date: 2019-11-25 17:12:20 Functions: 20 26 76.9 %

          Line data    Source code
       1             : /*
       2             : * Copyright(c) 2019 Intel Corporation
       3             : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
       4             : */
       5             : 
       6             : #include <stdlib.h>
       7             : 
       8             : #include "EbDefinitions.h"
       9             : #include "EbSystemResourceManager.h"
      10             : #include "EbPictureControlSet.h"
      11             : #include "EbSequenceControlSet.h"
      12             : 
      13             : #include "EbMotionEstimationResults.h"
      14             : #include "EbInitialRateControlProcess.h"
      15             : #include "EbInitialRateControlResults.h"
      16             : #include "EbMotionEstimationContext.h"
      17             : #include "EbUtility.h"
      18             : #include "EbReferenceObject.h"
      19             : 
      20             : /**************************************
      21             : * Macros
      22             : **************************************/
      23             : #define PAN_LCU_PERCENTAGE                    75
      24             : #define LOW_AMPLITUDE_TH                      16
      25             : 
      26        3740 : void GetMv(
      27             :     PictureParentControlSet    *picture_control_set_ptr,
      28             :     uint32_t                         sb_index,
      29             :     int32_t                        *xCurrentMv,
      30             :     int32_t                        *yCurrentMv)
      31             : {
      32             :     uint32_t             meCandidateIndex;
      33             : 
      34        3740 :     const MeLcuResults *me_results = picture_control_set_ptr->me_results[sb_index];
      35        3740 :     uint8_t total_me_cnt = me_results->total_me_candidate_index[0];
      36        3740 :     const MeCandidate *me_block_results = me_results->me_candidate[0];
      37       20287 :     for (meCandidateIndex = 0; meCandidateIndex < total_me_cnt; meCandidateIndex++) {
      38       18176 :         if (me_block_results->direction == UNI_PRED_LIST_0) {
      39        1629 :             *xCurrentMv = me_results->me_mv_array[0][0].x_mv;
      40        1629 :             *yCurrentMv = me_results->me_mv_array[0][0].y_mv;
      41        1629 :             break;
      42             :         }
      43             :     }
      44        3740 : }
      45             : 
      46        2420 : void GetMeDist(
      47             :     PictureParentControlSet    *picture_control_set_ptr,
      48             :     uint32_t                         sb_index,
      49             :     uint32_t                      *distortion)
      50             : {
      51        2420 :     *distortion = (uint32_t)picture_control_set_ptr->me_results[sb_index]->me_candidate[0][0].distortion;
      52        2420 : }
      53             : 
      54           0 : EbBool CheckMvForPanHighAmp(
      55             :     uint32_t   hierarchical_levels,
      56             :     uint32_t     temporal_layer_index,
      57             :     int32_t    *xCurrentMv,
      58             :     int32_t    *xCandidateMv)
      59             : {
      60           0 :     if (*xCurrentMv * *xCandidateMv > 0                        // both negative or both positives and both different than 0 i.e. same direction and non Stationary)
      61           0 :         && ABS(*xCurrentMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
      62           0 :         && ABS(*xCandidateMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
      63           0 :         && ABS(*xCurrentMv - *xCandidateMv) < LOW_AMPLITUDE_TH) {    // close amplitude
      64             : 
      65           0 :         return(EB_TRUE);
      66             :     }
      67             : 
      68             :     else
      69           0 :         return(EB_FALSE);
      70             : }
      71             : 
      72           0 : EbBool CheckMvForTiltHighAmp(
      73             :     uint32_t   hierarchical_levels,
      74             :     uint32_t     temporal_layer_index,
      75             :     int32_t    *yCurrentMv,
      76             :     int32_t    *yCandidateMv)
      77             : {
      78           0 :     if (*yCurrentMv * *yCandidateMv > 0                        // both negative or both positives and both different than 0 i.e. same direction and non Stationary)
      79           0 :         && ABS(*yCurrentMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
      80           0 :         && ABS(*yCandidateMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
      81           0 :         && ABS(*yCurrentMv - *yCandidateMv) < LOW_AMPLITUDE_TH) {    // close amplitude
      82             : 
      83           0 :         return(EB_TRUE);
      84             :     }
      85             : 
      86             :     else
      87           0 :         return(EB_FALSE);
      88             : }
      89             : 
      90           0 : EbBool CheckMvForPan(
      91             :     uint32_t   hierarchical_levels,
      92             :     uint32_t     temporal_layer_index,
      93             :     int32_t    *xCurrentMv,
      94             :     int32_t    *yCurrentMv,
      95             :     int32_t    *xCandidateMv,
      96             :     int32_t    *yCandidateMv)
      97             : {
      98           0 :     if (*yCurrentMv < LOW_AMPLITUDE_TH
      99           0 :         && *yCandidateMv < LOW_AMPLITUDE_TH
     100           0 :         && *xCurrentMv * *xCandidateMv        > 0                        // both negative or both positives and both different than 0 i.e. same direction and non Stationary)
     101           0 :         && ABS(*xCurrentMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
     102           0 :         && ABS(*xCandidateMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
     103           0 :         && ABS(*xCurrentMv - *xCandidateMv) < LOW_AMPLITUDE_TH) {    // close amplitude
     104             : 
     105           0 :         return(EB_TRUE);
     106             :     }
     107             : 
     108             :     else
     109           0 :         return(EB_FALSE);
     110             : }
     111             : 
     112           0 : EbBool CheckMvForTilt(
     113             :     uint32_t   hierarchical_levels,
     114             :     uint32_t     temporal_layer_index,
     115             :     int32_t    *xCurrentMv,
     116             :     int32_t    *yCurrentMv,
     117             :     int32_t    *xCandidateMv,
     118             :     int32_t    *yCandidateMv)
     119             : {
     120           0 :     if (*xCurrentMv < LOW_AMPLITUDE_TH
     121           0 :         && *xCandidateMv < LOW_AMPLITUDE_TH
     122           0 :         && *yCurrentMv * *yCandidateMv        > 0                        // both negative or both positives and both different than 0 i.e. same direction and non Stationary)
     123           0 :         && ABS(*yCurrentMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
     124           0 :         && ABS(*yCandidateMv) >= global_motion_threshold[hierarchical_levels][temporal_layer_index]    // high amplitude
     125           0 :         && ABS(*yCurrentMv - *yCandidateMv) < LOW_AMPLITUDE_TH) {    // close amplitude
     126             : 
     127           0 :         return(EB_TRUE);
     128             :     }
     129             : 
     130             :     else
     131           0 :         return(EB_FALSE);
     132             : }
     133             : 
     134        1200 : EbBool CheckMvForNonUniformMotion(
     135             :     int32_t    *xCurrentMv,
     136             :     int32_t    *yCurrentMv,
     137             :     int32_t    *xCandidateMv,
     138             :     int32_t    *yCandidateMv)
     139             : {
     140        1200 :     int32_t mvThreshold = 40;//LOW_AMPLITUDE_TH + 18;
     141             :     // Either the x or the y direction is greater than threshold
     142        1200 :     if ((ABS(*xCurrentMv - *xCandidateMv) > mvThreshold) || (ABS(*yCurrentMv - *yCandidateMv) > mvThreshold))
     143         512 :         return(EB_TRUE);
     144             :     else
     145         688 :         return(EB_FALSE);
     146             : }
     147             : 
     148           6 : void CheckForNonUniformMotionVectorField(
     149             :     PictureParentControlSet    *picture_control_set_ptr)
     150             : {
     151             :     uint32_t    sb_count;
     152           6 :     uint32_t    picture_width_in_sb = (picture_control_set_ptr->enhanced_picture_ptr->width + BLOCK_SIZE_64 - 1) / BLOCK_SIZE_64;
     153             :     uint32_t    sb_origin_x;
     154             :     uint32_t    sb_origin_y;
     155             : 
     156           6 :     int32_t    xCurrentMv = 0;
     157           6 :     int32_t    yCurrentMv = 0;
     158           6 :     int32_t    xLeftMv = 0;
     159           6 :     int32_t    yLeftMv = 0;
     160           6 :     int32_t    xTopMv = 0;
     161           6 :     int32_t    yTopMv = 0;
     162           6 :     int32_t    xRightMv = 0;
     163           6 :     int32_t    yRightMv = 0;
     164           6 :     int32_t    xBottomMv = 0;
     165           6 :     int32_t    yBottomMv = 0;
     166           6 :     uint32_t countOfNonUniformNeighbors = 0;
     167             : 
     168         366 :     for (sb_count = 0; sb_count < picture_control_set_ptr->sb_total_count; ++sb_count) {
     169         360 :         countOfNonUniformNeighbors = 0;
     170             : 
     171         360 :         sb_origin_x = (sb_count % picture_width_in_sb) * BLOCK_SIZE_64;
     172         360 :         sb_origin_y = (sb_count / picture_width_in_sb) * BLOCK_SIZE_64;
     173             : 
     174         360 :         if (((sb_origin_x + BLOCK_SIZE_64) <= picture_control_set_ptr->enhanced_picture_ptr->width) &&
     175         360 :             ((sb_origin_y + BLOCK_SIZE_64) <= picture_control_set_ptr->enhanced_picture_ptr->height)) {
     176             :             // Current MV
     177         300 :             GetMv(picture_control_set_ptr, sb_count, &xCurrentMv, &yCurrentMv);
     178             : 
     179             :             // Left MV
     180         300 :             if (sb_origin_x == 0) {
     181          30 :                 xLeftMv = 0;
     182          30 :                 yLeftMv = 0;
     183             :             }
     184             :             else
     185         270 :                 GetMv(picture_control_set_ptr, sb_count - 1, &xLeftMv, &yLeftMv);
     186         300 :             countOfNonUniformNeighbors += CheckMvForNonUniformMotion(&xCurrentMv, &yCurrentMv, &xLeftMv, &yLeftMv);
     187             : 
     188             :             // Top MV
     189         300 :             if (sb_origin_y == 0) {
     190          60 :                 xTopMv = 0;
     191          60 :                 yTopMv = 0;
     192             :             }
     193             :             else
     194         240 :                 GetMv(picture_control_set_ptr, sb_count - picture_width_in_sb, &xTopMv, &yTopMv);
     195         300 :             countOfNonUniformNeighbors += CheckMvForNonUniformMotion(&xCurrentMv, &yCurrentMv, &xTopMv, &yTopMv);
     196             : 
     197             :             // Right MV
     198         300 :             if ((sb_origin_x + (BLOCK_SIZE_64 << 1)) > picture_control_set_ptr->enhanced_picture_ptr->width) {
     199          30 :                 xRightMv = 0;
     200          30 :                 yRightMv = 0;
     201             :             }
     202             :             else
     203         270 :                 GetMv(picture_control_set_ptr, sb_count + 1, &xRightMv, &yRightMv);
     204         300 :             countOfNonUniformNeighbors += CheckMvForNonUniformMotion(&xCurrentMv, &yCurrentMv, &xRightMv, &yRightMv);
     205             : 
     206             :             // Bottom MV
     207         300 :             if ((sb_origin_y + (BLOCK_SIZE_64 << 1)) > picture_control_set_ptr->enhanced_picture_ptr->height) {
     208          60 :                 xBottomMv = 0;
     209          60 :                 yBottomMv = 0;
     210             :             }
     211             :             else
     212         240 :                 GetMv(picture_control_set_ptr, sb_count + picture_width_in_sb, &xBottomMv, &yBottomMv);
     213         300 :             countOfNonUniformNeighbors += CheckMvForNonUniformMotion(&xCurrentMv, &yCurrentMv, &xBottomMv, &yBottomMv);
     214             :         }
     215             :     }
     216           6 : }
     217             : 
     218             : 
     219         118 : void DetectGlobalMotion(
     220             :     PictureParentControlSet    *picture_control_set_ptr)
     221             : {
     222             : #if GLOBAL_WARPED_MOTION
     223         118 :     uint32_t numOfListToSearch = (picture_control_set_ptr->slice_type == P_SLICE)
     224         118 :         ? (uint32_t)REF_LIST_0 : (uint32_t)REF_LIST_1;
     225             : 
     226         346 :     for (uint32_t listIndex = REF_LIST_0; listIndex <= numOfListToSearch; ++listIndex) {
     227             : 
     228             :         uint32_t num_of_ref_pic_to_search;
     229         228 :         if (picture_control_set_ptr->is_alt_ref == EB_TRUE)
     230           0 :             num_of_ref_pic_to_search = 1;
     231             :         else
     232         228 :             num_of_ref_pic_to_search = picture_control_set_ptr->slice_type == P_SLICE
     233           8 :                 ? picture_control_set_ptr->ref_list0_count
     234         448 :                 : listIndex == REF_LIST_0
     235         110 :                     ? picture_control_set_ptr->ref_list0_count
     236         110 :                     : picture_control_set_ptr->ref_list1_count;
     237             : 
     238             :         // Ref Picture Loop
     239         628 :         for (uint32_t ref_pic_index = 0; ref_pic_index < num_of_ref_pic_to_search;
     240         400 :              ++ref_pic_index)
     241             :         {
     242         400 :             picture_control_set_ptr->is_global_motion[listIndex][ref_pic_index] = EB_FALSE;
     243         400 :             if (picture_control_set_ptr->global_motion_estimation[listIndex][ref_pic_index].wmtype > TRANSLATION)
     244         114 :                 picture_control_set_ptr->is_global_motion[listIndex][ref_pic_index] = EB_TRUE;
     245             :         }
     246             :     }
     247             : #else
     248             :     uint32_t    sb_count;
     249             :     uint32_t    picture_width_in_sb = (picture_control_set_ptr->enhanced_picture_ptr->width + BLOCK_SIZE_64 - 1) / BLOCK_SIZE_64;
     250             :     uint32_t    sb_origin_x;
     251             :     uint32_t    sb_origin_y;
     252             : 
     253             :     uint32_t  totalCheckedLcus = 0;
     254             :     uint32_t  totalPanLcus = 0;
     255             : 
     256             :     int32_t    xCurrentMv = 0;
     257             :     int32_t    yCurrentMv = 0;
     258             :     int32_t    xLeftMv = 0;
     259             :     int32_t    yLeftMv = 0;
     260             :     int32_t    xTopMv = 0;
     261             :     int32_t    yTopMv = 0;
     262             :     int32_t    xRightMv = 0;
     263             :     int32_t    yRightMv = 0;
     264             :     int32_t    xBottomMv = 0;
     265             :     int32_t    yBottomMv = 0;
     266             :     int64_t  xTiltMvSum = 0;
     267             :     int64_t  yTiltMvSum = 0;
     268             :     int64_t xPanMvSum = 0;
     269             :     int64_t yPanMvSum = 0;
     270             :     uint32_t  totalTiltLcus = 0;
     271             : 
     272             :     uint32_t  totalTiltHighAmpLcus = 0;
     273             :     uint32_t  totalPanHighAmpLcus = 0;
     274             : 
     275             :     for (sb_count = 0; sb_count < picture_control_set_ptr->sb_total_count; ++sb_count) {
     276             :         sb_origin_x = (sb_count % picture_width_in_sb) * BLOCK_SIZE_64;
     277             :         sb_origin_y = (sb_count / picture_width_in_sb) * BLOCK_SIZE_64;
     278             :         if (((sb_origin_x + BLOCK_SIZE_64) <= picture_control_set_ptr->enhanced_picture_ptr->width) &&
     279             :             ((sb_origin_y + BLOCK_SIZE_64) <= picture_control_set_ptr->enhanced_picture_ptr->height)) {
     280             :             // Current MV
     281             :             GetMv(picture_control_set_ptr, sb_count, &xCurrentMv, &yCurrentMv);
     282             : 
     283             :             // Left MV
     284             :             if (sb_origin_x == 0) {
     285             :                 xLeftMv = 0;
     286             :                 yLeftMv = 0;
     287             :             }
     288             :             else
     289             :                 GetMv(picture_control_set_ptr, sb_count - 1, &xLeftMv, &yLeftMv);
     290             :             // Top MV
     291             :             if (sb_origin_y == 0) {
     292             :                 xTopMv = 0;
     293             :                 yTopMv = 0;
     294             :             }
     295             :             else
     296             :                 GetMv(picture_control_set_ptr, sb_count - picture_width_in_sb, &xTopMv, &yTopMv);
     297             :             // Right MV
     298             :             if ((sb_origin_x + (BLOCK_SIZE_64 << 1)) > picture_control_set_ptr->enhanced_picture_ptr->width) {
     299             :                 xRightMv = 0;
     300             :                 yRightMv = 0;
     301             :             }
     302             :             else
     303             :                 GetMv(picture_control_set_ptr, sb_count + 1, &xRightMv, &yRightMv);
     304             :             // Bottom MV
     305             :             if ((sb_origin_y + (BLOCK_SIZE_64 << 1)) > picture_control_set_ptr->enhanced_picture_ptr->height) {
     306             :                 xBottomMv = 0;
     307             :                 yBottomMv = 0;
     308             :             }
     309             :             else
     310             :                 GetMv(picture_control_set_ptr, sb_count + picture_width_in_sb, &xBottomMv, &yBottomMv);
     311             :             totalCheckedLcus++;
     312             : 
     313             :             if ((EbBool)(CheckMvForPan(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xLeftMv, &yLeftMv) ||
     314             :                 CheckMvForPan(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xTopMv, &yTopMv) ||
     315             :                 CheckMvForPan(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xRightMv, &yRightMv) ||
     316             :                 CheckMvForPan(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xBottomMv, &yBottomMv))) {
     317             :                 totalPanLcus++;
     318             : 
     319             :                 xPanMvSum += xCurrentMv;
     320             :                 yPanMvSum += yCurrentMv;
     321             :             }
     322             : 
     323             :             if ((EbBool)(CheckMvForTilt(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xLeftMv, &yLeftMv) ||
     324             :                 CheckMvForTilt(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xTopMv, &yTopMv) ||
     325             :                 CheckMvForTilt(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xRightMv, &yRightMv) ||
     326             :                 CheckMvForTilt(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &yCurrentMv, &xBottomMv, &yBottomMv))) {
     327             :                 totalTiltLcus++;
     328             : 
     329             :                 xTiltMvSum += xCurrentMv;
     330             :                 yTiltMvSum += yCurrentMv;
     331             :             }
     332             : 
     333             :             if ((EbBool)(CheckMvForPanHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &xLeftMv) ||
     334             :                 CheckMvForPanHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &xTopMv) ||
     335             :                 CheckMvForPanHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &xRightMv) ||
     336             :                 CheckMvForPanHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &xCurrentMv, &xBottomMv))) {
     337             :                 totalPanHighAmpLcus++;
     338             :             }
     339             : 
     340             :             if ((EbBool)(CheckMvForTiltHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &yCurrentMv, &yLeftMv) ||
     341             :                 CheckMvForTiltHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &yCurrentMv, &yTopMv) ||
     342             :                 CheckMvForTiltHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &yCurrentMv, &yRightMv) ||
     343             :                 CheckMvForTiltHighAmp(picture_control_set_ptr->hierarchical_levels, picture_control_set_ptr->temporal_layer_index, &yCurrentMv, &yBottomMv))) {
     344             :                 totalTiltHighAmpLcus++;
     345             :             }
     346             :         }
     347             :     }
     348             :     picture_control_set_ptr->is_pan = EB_FALSE;
     349             :     picture_control_set_ptr->is_tilt = EB_FALSE;
     350             : 
     351             :     picture_control_set_ptr->panMvx = 0;
     352             :     picture_control_set_ptr->panMvy = 0;
     353             :     picture_control_set_ptr->tiltMvx = 0;
     354             :     picture_control_set_ptr->tiltMvy = 0;
     355             : 
     356             :     // If more than PAN_LCU_PERCENTAGE % of LCUs are PAN
     357             :     if ((totalCheckedLcus > 0) && ((totalPanLcus * 100 / totalCheckedLcus) > PAN_LCU_PERCENTAGE)) {
     358             :         picture_control_set_ptr->is_pan = EB_TRUE;
     359             :         if (totalPanLcus > 0) {
     360             :             picture_control_set_ptr->panMvx = (int16_t)(xPanMvSum / totalPanLcus);
     361             :             picture_control_set_ptr->panMvy = (int16_t)(yPanMvSum / totalPanLcus);
     362             :         }
     363             :     }
     364             : 
     365             :     if ((totalCheckedLcus > 0) && ((totalTiltLcus * 100 / totalCheckedLcus) > PAN_LCU_PERCENTAGE)) {
     366             :         picture_control_set_ptr->is_tilt = EB_TRUE;
     367             :         if (totalTiltLcus > 0) {
     368             :             picture_control_set_ptr->tiltMvx = (int16_t)(xTiltMvSum / totalTiltLcus);
     369             :             picture_control_set_ptr->tiltMvy = (int16_t)(yTiltMvSum / totalTiltLcus);
     370             :         }
     371             :     }
     372             : #endif
     373         118 : }
     374             : 
     375             : /************************************************
     376             : * Initial Rate Control Context Constructor
     377             : ************************************************/
     378           2 : EbErrorType initial_rate_control_context_ctor(
     379             :     InitialRateControlContext  *context_ptr,
     380             :     EbFifo                     *motion_estimation_results_input_fifo_ptr,
     381             :     EbFifo                     *initialrate_control_results_output_fifo_ptr)
     382             : {
     383           2 :     context_ptr->motion_estimation_results_input_fifo_ptr = motion_estimation_results_input_fifo_ptr;
     384           2 :     context_ptr->initialrate_control_results_output_fifo_ptr = initialrate_control_results_output_fifo_ptr;
     385             : 
     386           2 :     return EB_ErrorNone;
     387             : }
     388             : 
     389             : /************************************************
     390             : * Release Pa Reference Objects
     391             : ** Check if reference pictures are needed
     392             : ** release them when appropriate
     393             : ************************************************/
     394         120 : void ReleasePaReferenceObjects(
     395             :     SequenceControlSet              *sequence_control_set_ptr,
     396             :     PictureParentControlSet         *picture_control_set_ptr)
     397             : {
     398             :     // PA Reference Pictures
     399             :     uint32_t                             numOfListToSearch;
     400             :     uint32_t                             listIndex;
     401             :     uint32_t                             ref_pic_index;
     402         120 :     if (picture_control_set_ptr->slice_type != I_SLICE) {
     403         116 :         numOfListToSearch = (picture_control_set_ptr->slice_type == P_SLICE) ? REF_LIST_0 : REF_LIST_1;
     404             : 
     405             :         // List Loop
     406         342 :         for (listIndex = REF_LIST_0; listIndex <= numOfListToSearch; ++listIndex) {
     407             :             // Release PA Reference Pictures
     408         446 :             uint8_t num_of_ref_pic_to_search = (picture_control_set_ptr->slice_type == P_SLICE) ?
     409           6 :                 MIN(picture_control_set_ptr->ref_list0_count, sequence_control_set_ptr->reference_count) :
     410             :                 (listIndex == REF_LIST_0) ?
     411         110 :                 MIN(picture_control_set_ptr->ref_list0_count, sequence_control_set_ptr->reference_count) :
     412         110 :                 MIN(picture_control_set_ptr->ref_list1_count, sequence_control_set_ptr->reference_count);
     413             : 
     414         621 :             for (ref_pic_index = 0; ref_pic_index < num_of_ref_pic_to_search; ++ref_pic_index) {
     415         395 :                 if (picture_control_set_ptr->ref_pa_pic_ptr_array[listIndex][ref_pic_index] != EB_NULL) {
     416         395 :                     eb_release_object(picture_control_set_ptr->ref_pa_pic_ptr_array[listIndex][ref_pic_index]);
     417             :                 }
     418             :             }
     419             :         }
     420             :     }
     421             : 
     422         120 :     if (picture_control_set_ptr->pa_reference_picture_wrapper_ptr != EB_NULL) {
     423         120 :         eb_release_object(picture_control_set_ptr->pa_reference_picture_wrapper_ptr);
     424             :     }
     425             : 
     426         120 :     return;
     427             : }
     428             : 
     429             : /************************************************
     430             : * Global Motion Detection Based on ME information
     431             : ** Mark pictures for pan
     432             : ** Mark pictures for tilt
     433             : ** No lookahead information used in this function
     434             : ************************************************/
     435         120 : void MeBasedGlobalMotionDetection(
     436             :     PictureParentControlSet         *picture_control_set_ptr)
     437             : {
     438             :     // PAN Generation
     439         120 :     picture_control_set_ptr->is_pan = EB_FALSE;
     440         120 :     picture_control_set_ptr->is_tilt = EB_FALSE;
     441             : 
     442         120 :     if (picture_control_set_ptr->slice_type != I_SLICE)
     443         116 :         DetectGlobalMotion(picture_control_set_ptr);
     444             :     // Check if the motion vector field for temporal layer 0 pictures
     445         120 :     if (picture_control_set_ptr->slice_type != I_SLICE && picture_control_set_ptr->temporal_layer_index == 0)
     446           6 :         CheckForNonUniformMotionVectorField(picture_control_set_ptr);
     447         120 :     return;
     448             : }
     449             : 
     450         688 : void StationaryEdgeCountLcu(
     451             :     SequenceControlSet        *sequence_control_set_ptr,
     452             :     PictureParentControlSet   *picture_control_set_ptr,
     453             :     PictureParentControlSet   *temporalPictureControlSetPtr,
     454             :     uint32_t                       totalLcuCount)
     455             : {
     456             :     uint32_t               sb_index;
     457       41968 :     for (sb_index = 0; sb_index < totalLcuCount; sb_index++) {
     458       41280 :         SbParams sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     459       41280 :         SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     460       41280 :         if (sb_params.potential_logo_sb &&sb_params.is_complete_sb && sb_stat_ptr->check1_for_logo_stationary_edge_over_time_flag && sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag) {
     461        8597 :             SbStat *tempLcuStatPtr = &temporalPictureControlSetPtr->sb_stat_array[sb_index];
     462             :             uint32_t rasterScanCuIndex;
     463             : 
     464        8597 :             if (tempLcuStatPtr->check1_for_logo_stationary_edge_over_time_flag)
     465             :             {
     466       77299 :                 for (rasterScanCuIndex = RASTER_SCAN_CU_INDEX_16x16_0; rasterScanCuIndex <= RASTER_SCAN_CU_INDEX_16x16_15; rasterScanCuIndex++)
     467       72752 :                     sb_stat_ptr->cu_stat_array[rasterScanCuIndex].similar_edge_count += tempLcuStatPtr->cu_stat_array[rasterScanCuIndex].edge_cu;
     468             :             }
     469             :         }
     470             : 
     471       41280 :         if (sb_params.potential_logo_sb &&sb_params.is_complete_sb && sb_stat_ptr->pm_check1_for_logo_stationary_edge_over_time_flag && sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag) {
     472       11882 :             SbStat *tempLcuStatPtr = &temporalPictureControlSetPtr->sb_stat_array[sb_index];
     473             :             uint32_t rasterScanCuIndex;
     474             : 
     475       11882 :             if (tempLcuStatPtr->pm_check1_for_logo_stationary_edge_over_time_flag)
     476             :             {
     477      190536 :                 for (rasterScanCuIndex = RASTER_SCAN_CU_INDEX_16x16_0; rasterScanCuIndex <= RASTER_SCAN_CU_INDEX_16x16_15; rasterScanCuIndex++)
     478      179328 :                     sb_stat_ptr->cu_stat_array[rasterScanCuIndex].pm_similar_edge_count += tempLcuStatPtr->cu_stat_array[rasterScanCuIndex].edge_cu;
     479             :             }
     480             :         }
     481             :     }
     482         688 : }
     483             : 
     484         120 : void StationaryEdgeOverUpdateOverTimeLcuPart1(
     485             :     SequenceControlSet        *sequence_control_set_ptr,
     486             :     PictureParentControlSet   *picture_control_set_ptr)
     487             : {
     488             :     uint32_t               sb_index;
     489         120 :     int32_t                 xCurrentMv = 0;
     490         120 :     int32_t                 yCurrentMv = 0;
     491             : 
     492        7320 :     for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; sb_index++) {
     493        7200 :         SbParams sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     494        7200 :         SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     495             : 
     496        9840 :         if (sb_params.potential_logo_sb &&sb_params.is_complete_sb) {
     497             :             // Current MV
     498        2640 :             if (picture_control_set_ptr->temporal_layer_index > 0)
     499        2420 :                 GetMv(picture_control_set_ptr, sb_index, &xCurrentMv, &yCurrentMv);
     500             : 
     501        2640 :             EbBool lowMotion = picture_control_set_ptr->temporal_layer_index == 0 ? EB_TRUE : (ABS(xCurrentMv) < 16) && (ABS(yCurrentMv) < 16) ? EB_TRUE : EB_FALSE;
     502        2640 :             uint16_t *yVariancePtr = picture_control_set_ptr->variance[sb_index];
     503        2640 :             uint64_t var0 = yVariancePtr[ME_TIER_ZERO_PU_32x32_0];
     504        2640 :             uint64_t var1 = yVariancePtr[ME_TIER_ZERO_PU_32x32_1];
     505        2640 :             uint64_t var2 = yVariancePtr[ME_TIER_ZERO_PU_32x32_2];
     506        2640 :             uint64_t var3 = yVariancePtr[ME_TIER_ZERO_PU_32x32_3];
     507             : 
     508        2640 :             uint64_t averageVar = (var0 + var1 + var2 + var3) >> 2;
     509        2640 :             uint64_t varOfVar = (((int32_t)(var0 - averageVar) * (int32_t)(var0 - averageVar)) +
     510        2640 :                 ((int32_t)(var1 - averageVar) * (int32_t)(var1 - averageVar)) +
     511        2640 :                 ((int32_t)(var2 - averageVar) * (int32_t)(var2 - averageVar)) +
     512        2640 :                 ((int32_t)(var3 - averageVar) * (int32_t)(var3 - averageVar))) >> 2;
     513             : 
     514        2640 :             if ((varOfVar <= 50000) || !lowMotion)
     515        1214 :                 sb_stat_ptr->check1_for_logo_stationary_edge_over_time_flag = 0;
     516             :             else
     517        1426 :                 sb_stat_ptr->check1_for_logo_stationary_edge_over_time_flag = 1;
     518        2640 :             if ((varOfVar <= 1000))
     519         594 :                 sb_stat_ptr->pm_check1_for_logo_stationary_edge_over_time_flag = 0;
     520             :             else
     521        2046 :                 sb_stat_ptr->pm_check1_for_logo_stationary_edge_over_time_flag = 1;
     522             :         }
     523             :         else {
     524        4560 :             sb_stat_ptr->check1_for_logo_stationary_edge_over_time_flag = 0;
     525             : 
     526        4560 :             sb_stat_ptr->pm_check1_for_logo_stationary_edge_over_time_flag = 0;
     527             :         }
     528             :     }
     529         120 : }
     530         118 : void StationaryEdgeOverUpdateOverTimeLcuPart2(
     531             :     SequenceControlSet        *sequence_control_set_ptr,
     532             :     PictureParentControlSet   *picture_control_set_ptr)
     533             : {
     534             :     uint32_t               sb_index;
     535             : 
     536         118 :     uint32_t               lowSadTh = (sequence_control_set_ptr->input_resolution < INPUT_SIZE_1080p_RANGE) ? 5 : 2;
     537             : 
     538        7198 :     for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; sb_index++) {
     539        7080 :         SbParams sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     540        7080 :         SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     541             : 
     542        9676 :         if (sb_params.potential_logo_sb &&sb_params.is_complete_sb) {
     543        2596 :             uint32_t meDist = 0;
     544             : 
     545        2596 :             EbBool lowSad = EB_FALSE;
     546             : 
     547        2596 :             if (picture_control_set_ptr->slice_type == B_SLICE)
     548        2420 :                 GetMeDist(picture_control_set_ptr, sb_index, &meDist);
     549        5192 :             lowSad = (picture_control_set_ptr->slice_type != B_SLICE) ?
     550             : 
     551        2596 :                 EB_FALSE : (meDist < 64 * 64 * lowSadTh) ? EB_TRUE : EB_FALSE;
     552             : 
     553        2596 :             if (lowSad) {
     554        2108 :                 sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag = 0;
     555        2108 :                 sb_stat_ptr->low_dist_logo = 1;
     556             :             }
     557             :             else {
     558         488 :                 sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag = 1;
     559             : 
     560         488 :                 sb_stat_ptr->low_dist_logo = 0;
     561             :             }
     562             :         }
     563             :         else {
     564        4484 :             sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag = 0;
     565             : 
     566        4484 :             sb_stat_ptr->low_dist_logo = 0;
     567             :         }
     568        7080 :         sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag = 1;
     569             :     }
     570         118 : }
     571             : 
     572         118 : void StationaryEdgeOverUpdateOverTimeLcu(
     573             :     SequenceControlSet        *sequence_control_set_ptr,
     574             :     uint32_t                        totalCheckedPictures,
     575             :     PictureParentControlSet   *picture_control_set_ptr,
     576             :     uint32_t                       totalLcuCount)
     577             : {
     578             :     uint32_t               sb_index;
     579         118 :     const uint32_t         slideWindowTh = ((totalCheckedPictures / 4) - 1);
     580             : 
     581        7198 :     for (sb_index = 0; sb_index < totalLcuCount; sb_index++) {
     582        7080 :         SbParams sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     583             : 
     584        7080 :         SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     585        7080 :         sb_stat_ptr->stationary_edge_over_time_flag = EB_FALSE;
     586        7080 :         if (sb_params.potential_logo_sb &&sb_params.is_complete_sb && sb_stat_ptr->check1_for_logo_stationary_edge_over_time_flag && sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag) {
     587             :             uint32_t rasterScanCuIndex;
     588        1400 :             uint32_t similarEdgeCountLcu = 0;
     589             :             // CU Loop
     590       23800 :             for (rasterScanCuIndex = RASTER_SCAN_CU_INDEX_16x16_0; rasterScanCuIndex <= RASTER_SCAN_CU_INDEX_16x16_15; rasterScanCuIndex++)
     591       22400 :                 similarEdgeCountLcu += (sb_stat_ptr->cu_stat_array[rasterScanCuIndex].similar_edge_count > slideWindowTh) ? 1 : 0;
     592        1400 :             sb_stat_ptr->stationary_edge_over_time_flag = (similarEdgeCountLcu >= 4) ? EB_TRUE : EB_FALSE;
     593             :         }
     594             : 
     595        7080 :         sb_stat_ptr->pm_stationary_edge_over_time_flag = EB_FALSE;
     596        7080 :         if (sb_params.potential_logo_sb &&sb_params.is_complete_sb && sb_stat_ptr->pm_check1_for_logo_stationary_edge_over_time_flag && sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag) {
     597             :             uint32_t rasterScanCuIndex;
     598        2012 :             uint32_t similarEdgeCountLcu = 0;
     599             :             // CU Loop
     600       34204 :             for (rasterScanCuIndex = RASTER_SCAN_CU_INDEX_16x16_0; rasterScanCuIndex <= RASTER_SCAN_CU_INDEX_16x16_15; rasterScanCuIndex++)
     601       32192 :                 similarEdgeCountLcu += (sb_stat_ptr->cu_stat_array[rasterScanCuIndex].pm_similar_edge_count > slideWindowTh) ? 1 : 0;
     602        2012 :             sb_stat_ptr->pm_stationary_edge_over_time_flag = (similarEdgeCountLcu >= 4) ? EB_TRUE : EB_FALSE;
     603             :         }
     604             :     }
     605             :     {
     606             :         uint32_t sb_index;
     607             :         uint32_t sb_x, sb_y;
     608         118 :         uint32_t countOfNeighbors = 0;
     609             : 
     610         118 :         uint32_t countOfNeighborsPm = 0;
     611             : 
     612             :         int32_t lcuHor, lcuVer, lcuVerOffset;
     613             :         int32_t lcuHorS, lcuVerS, lcuHorE, lcuVerE;
     614         118 :         uint32_t picture_width_in_sb = sequence_control_set_ptr->picture_width_in_sb;
     615         118 :         uint32_t picture_height_in_sb = sequence_control_set_ptr->picture_height_in_sb;
     616             : 
     617        7198 :         for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
     618        7080 :             SbParams                sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     619        7080 :             SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     620             : 
     621        7080 :             sb_x = sb_params.horizontal_index;
     622        7080 :             sb_y = sb_params.vertical_index;
     623        7080 :             if (sb_params.potential_logo_sb &&sb_params.is_complete_sb && sb_stat_ptr->check1_for_logo_stationary_edge_over_time_flag && sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag) {
     624             :                 {
     625        1400 :                     lcuHorS = (sb_x > 0) ? -1 : 0;
     626        1400 :                     lcuHorE = (sb_x < picture_width_in_sb - 1) ? 1 : 0;
     627        1400 :                     lcuVerS = (sb_y > 0) ? -1 : 0;
     628        1400 :                     lcuVerE = (sb_y < picture_height_in_sb - 1) ? 1 : 0;
     629        1400 :                     countOfNeighbors = 0;
     630        5057 :                     for (lcuVer = lcuVerS; lcuVer <= lcuVerE; lcuVer++) {
     631        3657 :                         lcuVerOffset = lcuVer * (int32_t)picture_width_in_sb;
     632       13610 :                         for (lcuHor = lcuHorS; lcuHor <= lcuHorE; lcuHor++)
     633        9953 :                             countOfNeighbors += (picture_control_set_ptr->sb_stat_array[sb_index + lcuVerOffset + lcuHor].stationary_edge_over_time_flag == 1);
     634             :                     }
     635        1400 :                     if (countOfNeighbors == 1)
     636         216 :                         sb_stat_ptr->stationary_edge_over_time_flag = 0;
     637             :                 }
     638             :             }
     639             : 
     640        7080 :             if (sb_params.potential_logo_sb &&sb_params.is_complete_sb && sb_stat_ptr->pm_check1_for_logo_stationary_edge_over_time_flag && sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag) {
     641             :                 {
     642        2012 :                     lcuHorS = (sb_x > 0) ? -1 : 0;
     643        2012 :                     lcuHorE = (sb_x < picture_width_in_sb - 1) ? 1 : 0;
     644        2012 :                     lcuVerS = (sb_y > 0) ? -1 : 0;
     645        2012 :                     lcuVerE = (sb_y < picture_height_in_sb - 1) ? 1 : 0;
     646        2012 :                     countOfNeighborsPm = 0;
     647        7402 :                     for (lcuVer = lcuVerS; lcuVer <= lcuVerE; lcuVer++) {
     648        5390 :                         lcuVerOffset = lcuVer * (int32_t)picture_width_in_sb;
     649       19672 :                         for (lcuHor = lcuHorS; lcuHor <= lcuHorE; lcuHor++)
     650       14282 :                             countOfNeighborsPm += (picture_control_set_ptr->sb_stat_array[sb_index + lcuVerOffset + lcuHor].pm_stationary_edge_over_time_flag == 1);
     651             :                     }
     652             : 
     653        2012 :                     if (countOfNeighborsPm == 1)
     654          80 :                         sb_stat_ptr->pm_stationary_edge_over_time_flag = 0;
     655             :                 }
     656             :             }
     657             :         }
     658             :     }
     659             : 
     660             :     {
     661             :         uint32_t sb_index;
     662             :         uint32_t sb_x, sb_y;
     663         118 :         uint32_t countOfNeighbors = 0;
     664             :         int32_t lcuHor, lcuVer, lcuVerOffset;
     665             :         int32_t lcuHorS, lcuVerS, lcuHorE, lcuVerE;
     666         118 :         uint32_t picture_width_in_sb = sequence_control_set_ptr->picture_width_in_sb;
     667         118 :         uint32_t picture_height_in_sb = sequence_control_set_ptr->picture_height_in_sb;
     668             : 
     669        7198 :         for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
     670        7080 :             SbParams                sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     671        7080 :             SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     672             : 
     673        7080 :             sb_x = sb_params.horizontal_index;
     674        7080 :             sb_y = sb_params.vertical_index;
     675             : 
     676             :             {
     677        7080 :                 if (sb_stat_ptr->stationary_edge_over_time_flag == 0 && sb_params.potential_logo_sb && (sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag || !sb_params.is_complete_sb)) {
     678        3601 :                     lcuHorS = (sb_x > 0) ? -1 : 0;
     679        3601 :                     lcuHorE = (sb_x < picture_width_in_sb - 1) ? 1 : 0;
     680        3601 :                     lcuVerS = (sb_y > 0) ? -1 : 0;
     681        3601 :                     lcuVerE = (sb_y < picture_height_in_sb - 1) ? 1 : 0;
     682        3601 :                     countOfNeighbors = 0;
     683       12618 :                     for (lcuVer = lcuVerS; lcuVer <= lcuVerE; lcuVer++) {
     684        9017 :                         lcuVerOffset = lcuVer * (int32_t)picture_width_in_sb;
     685       33757 :                         for (lcuHor = lcuHorS; lcuHor <= lcuHorE; lcuHor++)
     686       24740 :                             countOfNeighbors += (picture_control_set_ptr->sb_stat_array[sb_index + lcuVerOffset + lcuHor].stationary_edge_over_time_flag == 1);
     687             :                     }
     688        3601 :                     if (countOfNeighbors > 0)
     689         237 :                         sb_stat_ptr->stationary_edge_over_time_flag = 2;
     690             :                 }
     691             :             }
     692             :         }
     693             : 
     694        7198 :         for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
     695        7080 :             SbParams                sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     696        7080 :             SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     697             : 
     698        7080 :             sb_x = sb_params.horizontal_index;
     699        7080 :             sb_y = sb_params.vertical_index;
     700             : 
     701             :             {
     702        7080 :                 if (sb_stat_ptr->stationary_edge_over_time_flag == 0 && sb_params.potential_logo_sb && (sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag || !sb_params.is_complete_sb)) {
     703        3364 :                     lcuHorS = (sb_x > 0) ? -1 : 0;
     704        3364 :                     lcuHorE = (sb_x < picture_width_in_sb - 1) ? 1 : 0;
     705        3364 :                     lcuVerS = (sb_y > 0) ? -1 : 0;
     706        3364 :                     lcuVerE = (sb_y < picture_height_in_sb - 1) ? 1 : 0;
     707        3364 :                     countOfNeighbors = 0;
     708       11774 :                     for (lcuVer = lcuVerS; lcuVer <= lcuVerE; lcuVer++) {
     709        8410 :                         lcuVerOffset = lcuVer * (int32_t)picture_width_in_sb;
     710       31565 :                         for (lcuHor = lcuHorS; lcuHor <= lcuHorE; lcuHor++)
     711       23155 :                             countOfNeighbors += (picture_control_set_ptr->sb_stat_array[sb_index + lcuVerOffset + lcuHor].stationary_edge_over_time_flag == 2);
     712             :                     }
     713        3364 :                     if (countOfNeighbors > 3)
     714           0 :                         sb_stat_ptr->stationary_edge_over_time_flag = 3;
     715             :                 }
     716             :             }
     717             :         }
     718             :     }
     719             : 
     720             :     {
     721             :         uint32_t sb_index;
     722             :         uint32_t sb_x, sb_y;
     723         118 :         uint32_t countOfNeighbors = 0;
     724             :         int32_t lcuHor, lcuVer, lcuVerOffset;
     725             :         int32_t lcuHorS, lcuVerS, lcuHorE, lcuVerE;
     726         118 :         uint32_t picture_width_in_sb = sequence_control_set_ptr->picture_width_in_sb;
     727         118 :         uint32_t picture_height_in_sb = sequence_control_set_ptr->picture_height_in_sb;
     728             : 
     729        7198 :         for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
     730        7080 :             SbParams                sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     731        7080 :             SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     732             : 
     733        7080 :             sb_x = sb_params.horizontal_index;
     734        7080 :             sb_y = sb_params.vertical_index;
     735             : 
     736             :             {
     737        7080 :                 if (sb_stat_ptr->pm_stationary_edge_over_time_flag == 0 && sb_params.potential_logo_sb && (sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag || !sb_params.is_complete_sb)) {
     738        2152 :                     lcuHorS = (sb_x > 0) ? -1 : 0;
     739        2152 :                     lcuHorE = (sb_x < picture_width_in_sb - 1) ? 1 : 0;
     740        2152 :                     lcuVerS = (sb_y > 0) ? -1 : 0;
     741        2152 :                     lcuVerE = (sb_y < picture_height_in_sb - 1) ? 1 : 0;
     742        2152 :                     countOfNeighbors = 0;
     743        7228 :                     for (lcuVer = lcuVerS; lcuVer <= lcuVerE; lcuVer++) {
     744        5076 :                         lcuVerOffset = lcuVer * (int32_t)picture_width_in_sb;
     745       19420 :                         for (lcuHor = lcuHorS; lcuHor <= lcuHorE; lcuHor++)
     746       14344 :                             countOfNeighbors += (picture_control_set_ptr->sb_stat_array[sb_index + lcuVerOffset + lcuHor].pm_stationary_edge_over_time_flag == 1);
     747             :                     }
     748        2152 :                     if (countOfNeighbors > 0)
     749        1132 :                         sb_stat_ptr->pm_stationary_edge_over_time_flag = 2;
     750             :                 }
     751             :             }
     752             :         }
     753             : 
     754        7198 :         for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
     755        7080 :             SbParams                sb_params = sequence_control_set_ptr->sb_params_array[sb_index];
     756        7080 :             SbStat *sb_stat_ptr = &picture_control_set_ptr->sb_stat_array[sb_index];
     757             : 
     758        7080 :             sb_x = sb_params.horizontal_index;
     759        7080 :             sb_y = sb_params.vertical_index;
     760             : 
     761             :             {
     762        7080 :                 if (sb_stat_ptr->pm_stationary_edge_over_time_flag == 0 && sb_params.potential_logo_sb && (sb_stat_ptr->check2_for_logo_stationary_edge_over_time_flag || !sb_params.is_complete_sb)) {
     763        1020 :                     lcuHorS = (sb_x > 0) ? -1 : 0;
     764        1020 :                     lcuHorE = (sb_x < picture_width_in_sb - 1) ? 1 : 0;
     765        1020 :                     lcuVerS = (sb_y > 0) ? -1 : 0;
     766        1020 :                     lcuVerE = (sb_y < picture_height_in_sb - 1) ? 1 : 0;
     767        1020 :                     countOfNeighbors = 0;
     768        3570 :                     for (lcuVer = lcuVerS; lcuVer <= lcuVerE; lcuVer++) {
     769        2550 :                         lcuVerOffset = lcuVer * (int32_t)picture_width_in_sb;
     770        9550 :                         for (lcuHor = lcuHorS; lcuHor <= lcuHorE; lcuHor++)
     771        7000 :                             countOfNeighbors += (picture_control_set_ptr->sb_stat_array[sb_index + lcuVerOffset + lcuHor].pm_stationary_edge_over_time_flag == 2);
     772             :                     }
     773        1020 :                     if (countOfNeighbors > 3)
     774           0 :                         sb_stat_ptr->pm_stationary_edge_over_time_flag = 3;
     775             :                 }
     776             :             }
     777             :         }
     778             :     }
     779         118 : }
     780             : 
     781             : /************************************************
     782             : * Global Motion Detection Based on Lookahead
     783             : ** Mark pictures for pan
     784             : ** Mark pictures for tilt
     785             : ** LAD Window: min (8 or sliding window size)
     786             : ************************************************/
     787         118 : void UpdateGlobalMotionDetectionOverTime(
     788             :     EncodeContext                   *encode_context_ptr,
     789             :     SequenceControlSet              *sequence_control_set_ptr,
     790             :     PictureParentControlSet         *picture_control_set_ptr)
     791             : {
     792             :     InitialRateControlReorderEntry   *temporaryQueueEntryPtr;
     793             :     PictureParentControlSet          *temporaryPictureControlSetPtr;
     794             : 
     795         118 :     uint32_t                                totalPanPictures = 0;
     796         118 :     uint32_t                                totalCheckedPictures = 0;
     797         118 :     uint32_t                                totalTiltPictures = 0;
     798             :     uint32_t                                updateIsPanFramesToCheck;
     799             :     uint32_t                                inputQueueIndex;
     800             :     uint32_t                                framesToCheckIndex;
     801             : 
     802             :     (void)sequence_control_set_ptr;
     803             : 
     804             :     // Determine number of frames to check (8 frames)
     805         118 :     updateIsPanFramesToCheck = MIN(8, picture_control_set_ptr->frames_in_sw);
     806             : 
     807             :     // Walk the first N entries in the sliding window
     808         118 :     inputQueueIndex = encode_context_ptr->initial_rate_control_reorder_queue_head_index;
     809         118 :     uint32_t updateFramesToCheck = updateIsPanFramesToCheck;
     810        1020 :     for (framesToCheckIndex = 0; framesToCheckIndex < updateFramesToCheck; framesToCheckIndex++) {
     811         902 :         temporaryQueueEntryPtr = encode_context_ptr->initial_rate_control_reorder_queue[inputQueueIndex];
     812         902 :         temporaryPictureControlSetPtr = ((PictureParentControlSet*)(temporaryQueueEntryPtr->parent_pcs_wrapper_ptr)->object_ptr);
     813             : 
     814         902 :         if (temporaryPictureControlSetPtr->slice_type != I_SLICE) {
     815         884 :             totalPanPictures += (temporaryPictureControlSetPtr->is_pan == EB_TRUE);
     816             : 
     817         884 :             totalTiltPictures += (temporaryPictureControlSetPtr->is_tilt == EB_TRUE);
     818             : 
     819             :             // Keep track of checked pictures
     820         884 :             totalCheckedPictures++;
     821             :         }
     822             : 
     823             :         // Increment the inputQueueIndex Iterator
     824         902 :         inputQueueIndex = (inputQueueIndex == INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : inputQueueIndex + 1;
     825             :     }
     826             : 
     827         118 :     picture_control_set_ptr->is_pan = EB_FALSE;
     828         118 :     picture_control_set_ptr->is_tilt = EB_FALSE;
     829             : 
     830         118 :     if (totalCheckedPictures) {
     831         118 :         if (picture_control_set_ptr->slice_type != I_SLICE) {
     832         114 :             if ((totalPanPictures * 100 / totalCheckedPictures) > 75)
     833           0 :                 picture_control_set_ptr->is_pan = EB_TRUE;
     834             :         }
     835             :     }
     836         118 :     return;
     837             : }
     838             : 
     839             : /************************************************
     840             : * Update BEA Information Based on Lookahead
     841             : ** Average zzCost of Collocated SB throughout lookahead frames
     842             : ** Set isMostOfPictureNonMoving based on number of non moving LCUs
     843             : ** LAD Window: min (2xmgpos+1 or sliding window size)
     844             : ************************************************/
     845             : 
     846         118 : void UpdateBeaInfoOverTime(
     847             :     EncodeContext                   *encode_context_ptr,
     848             :     PictureParentControlSet         *picture_control_set_ptr)
     849             : {
     850             :     InitialRateControlReorderEntry   *temporaryQueueEntryPtr;
     851             :     PictureParentControlSet          *temporaryPictureControlSetPtr;
     852             :     uint32_t                                updateNonMovingIndexArrayFramesToCheck;
     853             :     uint16_t                              lcuIdx;
     854             :     uint16_t                                framesToCheckIndex;
     855         118 :     uint64_t                                nonMovingIndexSum = 0;
     856             :     uint32_t                                inputQueueIndex;
     857             : 
     858         118 :     SequenceControlSet *sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
     859             :     // Update motionIndexArray of the current picture by averaging the motionIndexArray of the N future pictures
     860             :     // Determine number of frames to check N
     861         118 :     updateNonMovingIndexArrayFramesToCheck = MIN(MIN(((picture_control_set_ptr->pred_struct_ptr->pred_struct_period << 1) + 1), picture_control_set_ptr->frames_in_sw), sequence_control_set_ptr->static_config.look_ahead_distance);
     862         118 :     uint64_t me_dist = 0;
     863         118 :     uint8_t me_dist_pic_count = 0;
     864             :     // SB Loop
     865        7198 :     for (lcuIdx = 0; lcuIdx < picture_control_set_ptr->sb_total_count; ++lcuIdx) {
     866        7080 :         uint16_t nonMovingIndexOverSlidingWindow = picture_control_set_ptr->non_moving_index_array[lcuIdx];
     867             : 
     868             :         // Walk the first N entries in the sliding window starting picture + 1
     869        7080 :         inputQueueIndex = (encode_context_ptr->initial_rate_control_reorder_queue_head_index == INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->initial_rate_control_reorder_queue_head_index + 1;
     870      108720 :         for (framesToCheckIndex = 0; framesToCheckIndex < updateNonMovingIndexArrayFramesToCheck - 1; framesToCheckIndex++) {
     871      108720 :             temporaryQueueEntryPtr = encode_context_ptr->initial_rate_control_reorder_queue[inputQueueIndex];
     872      108720 :             temporaryPictureControlSetPtr = ((PictureParentControlSet*)(temporaryQueueEntryPtr->parent_pcs_wrapper_ptr)->object_ptr);
     873             : 
     874      108720 :             if (temporaryPictureControlSetPtr->slice_type == I_SLICE || temporaryPictureControlSetPtr->end_of_sequence_flag)
     875             :                 break;
     876             :             // Limit the distortion to lower layers 0, 1 and 2 only. Higher layers have close temporal distance and lower distortion that might contaminate the data
     877      101640 :             if (temporaryPictureControlSetPtr->temporal_layer_index < MAX((int8_t)picture_control_set_ptr->hierarchical_levels - 1, 2) ) {
     878       29640 :                 if (lcuIdx == 0)
     879         494 :                     me_dist_pic_count++;
     880       29640 :                 me_dist += (temporaryPictureControlSetPtr->slice_type == I_SLICE) ? 0 : (uint64_t)temporaryPictureControlSetPtr->rc_me_distortion[lcuIdx];
     881             :             }
     882             :             // Store the filtered_sse of next ALT_REF picture in the I slice to be used in QP Scaling
     883      101640 :             if (picture_control_set_ptr->slice_type == I_SLICE && picture_control_set_ptr->filtered_sse == 0 && lcuIdx == 0 && temporaryPictureControlSetPtr->temporal_layer_index == 0) {
     884           2 :                 picture_control_set_ptr->filtered_sse = temporaryPictureControlSetPtr->filtered_sse;
     885           2 :                 picture_control_set_ptr->filtered_sse_uv = temporaryPictureControlSetPtr->filtered_sse_uv;
     886             :             }
     887      101640 :             nonMovingIndexOverSlidingWindow += temporaryPictureControlSetPtr->non_moving_index_array[lcuIdx];
     888             : 
     889             :             // Increment the inputQueueIndex Iterator
     890      101640 :             inputQueueIndex = (inputQueueIndex == INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : inputQueueIndex + 1;
     891             :         }
     892        7080 :         picture_control_set_ptr->non_moving_index_array[lcuIdx] = (uint8_t)(nonMovingIndexOverSlidingWindow / (framesToCheckIndex + 1));
     893             : 
     894        7080 :         nonMovingIndexSum += picture_control_set_ptr->non_moving_index_array[lcuIdx];
     895             :     }
     896             : 
     897         118 :     picture_control_set_ptr->non_moving_index_average = (uint16_t)nonMovingIndexSum / picture_control_set_ptr->sb_total_count;
     898         118 :     me_dist_pic_count = MAX(me_dist_pic_count, 1);
     899         118 :     picture_control_set_ptr->qp_scaling_average_complexity = (uint16_t)((uint64_t)me_dist / picture_control_set_ptr->sb_total_count / 256 / me_dist_pic_count);
     900         118 :     return;
     901             : }
     902             : 
     903             : /****************************************
     904             : * Init ZZ Cost array to default values
     905             : ** Used when no Lookahead is available
     906             : ****************************************/
     907           2 : void InitZzCostInfo(
     908             :     PictureParentControlSet         *picture_control_set_ptr)
     909             : {
     910             :     uint16_t lcuIdx;
     911           2 :     picture_control_set_ptr->non_moving_index_average = INVALID_ZZ_COST;
     912             : 
     913             :     // SB Loop
     914         122 :     for (lcuIdx = 0; lcuIdx < picture_control_set_ptr->sb_total_count; ++lcuIdx)
     915         120 :         picture_control_set_ptr->non_moving_index_array[lcuIdx] = INVALID_ZZ_COST;
     916           2 :     return;
     917             : }
     918             : 
     919             : /************************************************
     920             : * Update uniform motion field
     921             : ** Update Uniformly moving LCUs using
     922             : ** collocated LCUs infor in lookahead pictures
     923             : ** LAD Window: min (2xmgpos+1 or sliding window size)
     924             : ************************************************/
     925         118 : void UpdateMotionFieldUniformityOverTime(
     926             :     EncodeContext                   *encode_context_ptr,
     927             :     SequenceControlSet              *sequence_control_set_ptr,
     928             :     PictureParentControlSet         *picture_control_set_ptr)
     929             : {
     930             :     InitialRateControlReorderEntry   *temporaryQueueEntryPtr;
     931             :     PictureParentControlSet          *temporaryPictureControlSetPtr;
     932             :     uint32_t                                inputQueueIndex;
     933             :     uint32_t                              NoFramesToCheck;
     934             :     uint32_t                                framesToCheckIndex;
     935             :     //printf("To update POC %d\tframesInSw = %d\n", picture_control_set_ptr->picture_number, picture_control_set_ptr->frames_in_sw);
     936             : 
     937             :     //Check conditions for statinary edge over time
     938         118 :     StationaryEdgeOverUpdateOverTimeLcuPart2(
     939             :         sequence_control_set_ptr,
     940             :         picture_control_set_ptr);
     941             : 
     942             :     // Determine number of frames to check N
     943         118 :     NoFramesToCheck = MIN(MIN(((picture_control_set_ptr->pred_struct_ptr->pred_struct_period << 1) + 1), picture_control_set_ptr->frames_in_sw), sequence_control_set_ptr->static_config.look_ahead_distance);
     944             : 
     945             :     // Walk the first N entries in the sliding window starting picture + 1
     946         118 :     inputQueueIndex = (encode_context_ptr->initial_rate_control_reorder_queue_head_index == INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->initial_rate_control_reorder_queue_head_index;
     947        2902 :     for (framesToCheckIndex = 0; framesToCheckIndex < NoFramesToCheck - 1; framesToCheckIndex++) {
     948        2784 :         temporaryQueueEntryPtr = encode_context_ptr->initial_rate_control_reorder_queue[inputQueueIndex];
     949        2784 :         temporaryPictureControlSetPtr = ((PictureParentControlSet*)(temporaryQueueEntryPtr->parent_pcs_wrapper_ptr)->object_ptr);
     950             : 
     951        2784 :         if (temporaryPictureControlSetPtr->end_of_sequence_flag)
     952           0 :             break;
     953             :         // The values are calculated for every 4th frame
     954        2784 :         if ((temporaryPictureControlSetPtr->picture_number & 3) == 0) {
     955         688 :             StationaryEdgeCountLcu(
     956             :                 sequence_control_set_ptr,
     957             :                 picture_control_set_ptr,
     958             :                 temporaryPictureControlSetPtr,
     959         688 :                 picture_control_set_ptr->sb_total_count);
     960             :         }
     961             :         // Increment the inputQueueIndex Iterator
     962        2784 :         inputQueueIndex = (inputQueueIndex == INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : inputQueueIndex + 1;
     963             :     }
     964         118 :     StationaryEdgeOverUpdateOverTimeLcu(
     965             :         sequence_control_set_ptr,
     966             :         NoFramesToCheck,
     967             :         picture_control_set_ptr,
     968         118 :         picture_control_set_ptr->sb_total_count);
     969         118 :     return;
     970             : }
     971         120 : InitialRateControlReorderEntry  * DeterminePictureOffsetInQueue(
     972             :     EncodeContext                   *encode_context_ptr,
     973             :     PictureParentControlSet         *picture_control_set_ptr,
     974             :     MotionEstimationResults         *inputResultsPtr)
     975             : {
     976             :     InitialRateControlReorderEntry  *queueEntryPtr;
     977             :     int32_t                             queueEntryIndex;
     978             : 
     979         120 :     queueEntryIndex = (int32_t)(picture_control_set_ptr->picture_number - encode_context_ptr->initial_rate_control_reorder_queue[encode_context_ptr->initial_rate_control_reorder_queue_head_index]->picture_number);
     980         120 :     queueEntryIndex += encode_context_ptr->initial_rate_control_reorder_queue_head_index;
     981         120 :     queueEntryIndex = (queueEntryIndex > INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? queueEntryIndex - INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH : queueEntryIndex;
     982         120 :     queueEntryPtr = encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndex];
     983         120 :     queueEntryPtr->parent_pcs_wrapper_ptr = inputResultsPtr->picture_control_set_wrapper_ptr;
     984         120 :     queueEntryPtr->picture_number = picture_control_set_ptr->picture_number;
     985             : 
     986         120 :     return queueEntryPtr;
     987             : }
     988             : 
     989           0 : void GetHistogramQueueData(
     990             :     SequenceControlSet              *sequence_control_set_ptr,
     991             :     EncodeContext                   *encode_context_ptr,
     992             :     PictureParentControlSet         *picture_control_set_ptr)
     993             : {
     994             :     HlRateControlHistogramEntry     *histogramQueueEntryPtr;
     995             :     int32_t                             histogramQueueEntryIndex;
     996             : 
     997             :     // Determine offset from the Head Ptr for HLRC histogram queue
     998           0 :     eb_block_on_mutex(sequence_control_set_ptr->encode_context_ptr->hl_rate_control_historgram_queue_mutex);
     999           0 :     histogramQueueEntryIndex = (int32_t)(picture_control_set_ptr->picture_number - encode_context_ptr->hl_rate_control_historgram_queue[encode_context_ptr->hl_rate_control_historgram_queue_head_index]->picture_number);
    1000           0 :     histogramQueueEntryIndex += encode_context_ptr->hl_rate_control_historgram_queue_head_index;
    1001           0 :     histogramQueueEntryIndex = (histogramQueueEntryIndex > HIGH_LEVEL_RATE_CONTROL_HISTOGRAM_QUEUE_MAX_DEPTH - 1) ?
    1002           0 :         histogramQueueEntryIndex - HIGH_LEVEL_RATE_CONTROL_HISTOGRAM_QUEUE_MAX_DEPTH :
    1003             :         (histogramQueueEntryIndex < 0) ?
    1004           0 :         histogramQueueEntryIndex + HIGH_LEVEL_RATE_CONTROL_HISTOGRAM_QUEUE_MAX_DEPTH :
    1005             :         histogramQueueEntryIndex;
    1006           0 :     histogramQueueEntryPtr = encode_context_ptr->hl_rate_control_historgram_queue[histogramQueueEntryIndex];
    1007             : 
    1008             :     //histogramQueueEntryPtr->parent_pcs_wrapper_ptr  = inputResultsPtr->picture_control_set_wrapper_ptr;
    1009           0 :     histogramQueueEntryPtr->picture_number = picture_control_set_ptr->picture_number;
    1010           0 :     histogramQueueEntryPtr->end_of_sequence_flag = picture_control_set_ptr->end_of_sequence_flag;
    1011           0 :     histogramQueueEntryPtr->slice_type = picture_control_set_ptr->slice_type;
    1012           0 :     histogramQueueEntryPtr->temporal_layer_index = picture_control_set_ptr->temporal_layer_index;
    1013           0 :     histogramQueueEntryPtr->full_sb_count = picture_control_set_ptr->full_sb_count;
    1014           0 :     histogramQueueEntryPtr->life_count = 0;
    1015           0 :     histogramQueueEntryPtr->passed_to_hlrc = EB_FALSE;
    1016           0 :     histogramQueueEntryPtr->is_coded = EB_FALSE;
    1017           0 :     histogramQueueEntryPtr->total_num_bits_coded = 0;
    1018           0 :     histogramQueueEntryPtr->frames_in_sw = 0;
    1019           0 :     EB_MEMCPY(
    1020             :         histogramQueueEntryPtr->me_distortion_histogram,
    1021             :         picture_control_set_ptr->me_distortion_histogram,
    1022             :         sizeof(uint16_t) * NUMBER_OF_SAD_INTERVALS);
    1023             : 
    1024           0 :     EB_MEMCPY(
    1025             :         histogramQueueEntryPtr->ois_distortion_histogram,
    1026             :         picture_control_set_ptr->ois_distortion_histogram,
    1027             :         sizeof(uint16_t) * NUMBER_OF_INTRA_SAD_INTERVALS);
    1028             : 
    1029           0 :     eb_release_mutex(sequence_control_set_ptr->encode_context_ptr->hl_rate_control_historgram_queue_mutex);
    1030             :     //printf("Test1 POC: %d\t POC: %d\t LifeCount: %d\n", histogramQueueEntryPtr->picture_number, picture_control_set_ptr->picture_number,  histogramQueueEntryPtr->life_count);
    1031             : 
    1032           0 :     return;
    1033             : }
    1034             : 
    1035           0 : void UpdateHistogramQueueEntry(
    1036             :     SequenceControlSet              *sequence_control_set_ptr,
    1037             :     EncodeContext                   *encode_context_ptr,
    1038             :     PictureParentControlSet         *picture_control_set_ptr,
    1039             :     uint32_t                           frames_in_sw)
    1040             : {
    1041             :     HlRateControlHistogramEntry     *histogramQueueEntryPtr;
    1042             :     int32_t                             histogramQueueEntryIndex;
    1043             : 
    1044           0 :     eb_block_on_mutex(sequence_control_set_ptr->encode_context_ptr->hl_rate_control_historgram_queue_mutex);
    1045             : 
    1046           0 :     histogramQueueEntryIndex = (int32_t)(picture_control_set_ptr->picture_number - encode_context_ptr->hl_rate_control_historgram_queue[encode_context_ptr->hl_rate_control_historgram_queue_head_index]->picture_number);
    1047           0 :     histogramQueueEntryIndex += encode_context_ptr->hl_rate_control_historgram_queue_head_index;
    1048           0 :     histogramQueueEntryIndex = (histogramQueueEntryIndex > HIGH_LEVEL_RATE_CONTROL_HISTOGRAM_QUEUE_MAX_DEPTH - 1) ?
    1049           0 :         histogramQueueEntryIndex - HIGH_LEVEL_RATE_CONTROL_HISTOGRAM_QUEUE_MAX_DEPTH :
    1050             :         (histogramQueueEntryIndex < 0) ?
    1051           0 :         histogramQueueEntryIndex + HIGH_LEVEL_RATE_CONTROL_HISTOGRAM_QUEUE_MAX_DEPTH :
    1052             :         histogramQueueEntryIndex;
    1053           0 :     histogramQueueEntryPtr = encode_context_ptr->hl_rate_control_historgram_queue[histogramQueueEntryIndex];
    1054           0 :     histogramQueueEntryPtr->passed_to_hlrc = EB_TRUE;
    1055           0 :     if (sequence_control_set_ptr->static_config.rate_control_mode == 3)
    1056           0 :         histogramQueueEntryPtr->life_count += (int16_t)(sequence_control_set_ptr->static_config.intra_period_length + 1) - 3; // FramelevelRC does not decrease the life count for first picture in each temporal layer
    1057             :     else
    1058           0 :         histogramQueueEntryPtr->life_count += picture_control_set_ptr->historgram_life_count;
    1059           0 :     histogramQueueEntryPtr->frames_in_sw = frames_in_sw;
    1060           0 :     eb_release_mutex(sequence_control_set_ptr->encode_context_ptr->hl_rate_control_historgram_queue_mutex);
    1061             : 
    1062           0 :     return;
    1063             : }
    1064             : EbAuraStatus AuraDetection64x64Gold(
    1065             :     PictureControlSet           *picture_control_set_ptr,
    1066             :     uint8_t                          picture_qp,
    1067             :     uint32_t                         x_lcu_index,
    1068             :     uint32_t                         y_lcu_index
    1069             : );
    1070             : 
    1071             : /******************************************************
    1072             : Input   : variance
    1073             : Output  : true if current & neighbors are spatially complex
    1074             : ******************************************************/
    1075        7200 : EbBool IsSpatiallyComplexArea(
    1076             :     PictureParentControlSet    *parentPcs,
    1077             :     uint32_t                       pictureWidthInLcus,
    1078             :     uint32_t                       lcuAdrr,
    1079             :     uint32_t                       sb_origin_x,
    1080             :     uint32_t                       sb_origin_y)
    1081             : {
    1082        7200 :     uint32_t availableLcusCount = 0;
    1083        7200 :     uint32_t highVarianceLcusCount = 0;
    1084             : 
    1085             :     // Check the variance of the current LCU
    1086        7200 :     if ((parentPcs->variance[lcuAdrr][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH) {
    1087        4134 :         availableLcusCount++;
    1088        4134 :         highVarianceLcusCount++;
    1089             :     }
    1090             : 
    1091             :     // Check the variance of left SB if available
    1092        7200 :     if (sb_origin_x != 0) {
    1093        6480 :         availableLcusCount++;
    1094        6480 :         if ((parentPcs->variance[lcuAdrr - 1][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1095        3892 :             highVarianceLcusCount++;
    1096             :     }
    1097             : 
    1098             :     // Check the variance of right SB if available
    1099        7200 :     if ((sb_origin_x + BLOCK_SIZE_64) < parentPcs->enhanced_picture_ptr->width) {
    1100        6480 :         availableLcusCount++;
    1101        6480 :         if ((parentPcs->variance[lcuAdrr + 1][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1102        3420 :             highVarianceLcusCount++;
    1103             :     }
    1104             : 
    1105             :     // Check the variance of top SB if available
    1106        7200 :     if (sb_origin_y != 0) {
    1107        6000 :         availableLcusCount++;
    1108        6000 :         if ((parentPcs->variance[lcuAdrr - pictureWidthInLcus][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1109        3374 :             highVarianceLcusCount++;
    1110             :     }
    1111             : 
    1112             :     // Check the variance of bottom LCU
    1113        7200 :     if ((sb_origin_y + BLOCK_SIZE_64) < parentPcs->enhanced_picture_ptr->height) {
    1114        6000 :         availableLcusCount++;
    1115        6000 :         if ((parentPcs->variance[lcuAdrr + pictureWidthInLcus][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1116        3398 :             highVarianceLcusCount++;
    1117             :     }
    1118             : 
    1119             :     // Check the variance of top-left LCU
    1120        7200 :     if ((sb_origin_x >= BLOCK_SIZE_64) && (sb_origin_y >= BLOCK_SIZE_64)) {
    1121        5400 :         availableLcusCount++;
    1122        5400 :         if ((parentPcs->variance[lcuAdrr - pictureWidthInLcus - 1][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1123        3132 :             highVarianceLcusCount++;
    1124             :     }
    1125             : 
    1126             :     // Check the variance of top-right LCU
    1127        7200 :     if ((sb_origin_x < parentPcs->enhanced_picture_ptr->width - BLOCK_SIZE_64) && (sb_origin_y >= BLOCK_SIZE_64)) {
    1128        5400 :         availableLcusCount++;
    1129        5400 :         if ((parentPcs->variance[lcuAdrr - pictureWidthInLcus + 1][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1130        2776 :             highVarianceLcusCount++;
    1131             :     }
    1132             : 
    1133             :     // Check the variance of bottom-left LCU
    1134        7200 :     if ((sb_origin_x >= BLOCK_SIZE_64) && (sb_origin_y < parentPcs->enhanced_picture_ptr->height - BLOCK_SIZE_64)) {
    1135        5400 :         availableLcusCount++;
    1136        5400 :         if ((parentPcs->variance[lcuAdrr + pictureWidthInLcus - 1][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1137        3276 :             highVarianceLcusCount++;
    1138             :     }
    1139             : 
    1140             :     // Check the variance of bottom-right LCU
    1141        7200 :     if ((sb_origin_x < parentPcs->enhanced_picture_ptr->width - BLOCK_SIZE_64) && (sb_origin_y < parentPcs->enhanced_picture_ptr->height - BLOCK_SIZE_64)) {
    1142        5400 :         availableLcusCount++;
    1143        5400 :         if ((parentPcs->variance[lcuAdrr + pictureWidthInLcus + 1][ME_TIER_ZERO_PU_64x64]) > IS_COMPLEX_LCU_VARIANCE_TH)
    1144        2804 :             highVarianceLcusCount++;
    1145             :     }
    1146             : 
    1147        7200 :     if (highVarianceLcusCount == availableLcusCount)
    1148        2674 :         return EB_TRUE;
    1149        4526 :     return EB_FALSE;
    1150             : }
    1151             : 
    1152             : // Derives blockinessPresentFlag
    1153         120 : void DeriveBlockinessPresentFlag(
    1154             :     SequenceControlSet        *sequence_control_set_ptr,
    1155             :     PictureParentControlSet   *picture_control_set_ptr)
    1156             : {
    1157             :     uint32_t                      sb_index;
    1158             : 
    1159        7320 :     for (sb_index = 0; sb_index < picture_control_set_ptr->sb_total_count; ++sb_index) {
    1160        7200 :         SbParams         *lcuParamPtr = &sequence_control_set_ptr->sb_params_array[sb_index];
    1161        7200 :         picture_control_set_ptr->complex_sb_array[sb_index] = SB_COMPLEXITY_STATUS_INVALID;
    1162             : 
    1163             :         // Spatially complex SB within a spatially complex area
    1164        7200 :         if (IsSpatiallyComplexArea(
    1165             :             picture_control_set_ptr,
    1166        7200 :             (picture_control_set_ptr->enhanced_picture_ptr->width + BLOCK_SIZE_64 - 1) / BLOCK_SIZE_64,
    1167             :             sb_index,
    1168        7200 :             lcuParamPtr->origin_x,
    1169        7200 :             lcuParamPtr->origin_y)) {
    1170             :             // Active SB within an active scene (added a check on 4K & non-BASE to restrict the action - could be generated for all resolutions/layers)
    1171        2674 :             if (picture_control_set_ptr->non_moving_index_array[sb_index] == SB_COMPLEXITY_NON_MOVING_INDEX_TH_0 && picture_control_set_ptr->non_moving_index_average >= SB_COMPLEXITY_NON_MOVING_INDEX_TH_1 && picture_control_set_ptr->temporal_layer_index > 0 && sequence_control_set_ptr->input_resolution == INPUT_SIZE_4K_RANGE)
    1172           0 :                 picture_control_set_ptr->complex_sb_array[sb_index] = SB_COMPLEXITY_STATUS_2;
    1173             :             // Active SB within a scene with a moderate acitivity (eg. active foregroud & static background)
    1174        2674 :             else if (picture_control_set_ptr->non_moving_index_array[sb_index] == SB_COMPLEXITY_NON_MOVING_INDEX_TH_0 && picture_control_set_ptr->non_moving_index_average >= SB_COMPLEXITY_NON_MOVING_INDEX_TH_2 && picture_control_set_ptr->non_moving_index_average < SB_COMPLEXITY_NON_MOVING_INDEX_TH_1)
    1175           0 :                 picture_control_set_ptr->complex_sb_array[sb_index] = SB_COMPLEXITY_STATUS_1;
    1176             :             else
    1177        2674 :                 picture_control_set_ptr->complex_sb_array[sb_index] = SB_COMPLEXITY_STATUS_0;
    1178             :         }
    1179             :         else
    1180        4526 :             picture_control_set_ptr->complex_sb_array[sb_index] = SB_COMPLEXITY_STATUS_0;
    1181             :     }
    1182         120 : }
    1183             : 
    1184             : /************************************************
    1185             : * Initial Rate Control Kernel
    1186             : * The Initial Rate Control Process determines the initial bit budget for each
    1187             : * picture depending on the data gathered in the Picture Analysis and Motion
    1188             : * Analysis processes as well as the settings determined in the Picture Decision process.
    1189             : * The Initial Rate Control process also employs a sliding window buffer to analyze multiple
    1190             : * pictures if the delay is allowed.  Note that through this process, until the subsequent
    1191             : * Picture Manager process, no reference picture data has been used.
    1192             : * P.S. Temporal noise reduction is now performed in Initial Rate Control Process.
    1193             : * In future we might decide to move it to Motion Analysis Process.
    1194             : ************************************************/
    1195           2 : void* initial_rate_control_kernel(void *input_ptr)
    1196             : {
    1197           2 :     InitialRateControlContext       *context_ptr = (InitialRateControlContext*)input_ptr;
    1198             :     PictureParentControlSet         *picture_control_set_ptr;
    1199             :     PictureParentControlSet         *pictureControlSetPtrTemp;
    1200             :     EncodeContext                   *encode_context_ptr;
    1201             :     SequenceControlSet              *sequence_control_set_ptr;
    1202             : 
    1203             :     EbObjectWrapper                 *inputResultsWrapperPtr;
    1204             :     MotionEstimationResults         *inputResultsPtr;
    1205             : 
    1206             :     EbObjectWrapper                 *outputResultsWrapperPtr;
    1207             :     InitialRateControlResults       *outputResultsPtr;
    1208             : 
    1209             :     // Queue variables
    1210             :     uint32_t                             queueEntryIndexTemp;
    1211             :     uint32_t                             queueEntryIndexTemp2;
    1212             :     InitialRateControlReorderEntry  *queueEntryPtr;
    1213             : 
    1214           2 :     EbBool                            moveSlideWondowFlag = EB_TRUE;
    1215           2 :     EbBool                            end_of_sequence_flag = EB_TRUE;
    1216             :     uint8_t                               frames_in_sw;
    1217             :     uint8_t                               temporal_layer_index;
    1218             :     EbObjectWrapper                  *reference_picture_wrapper_ptr;
    1219             : 
    1220             :     // Segments
    1221             :     uint32_t                              segment_index;
    1222             : 
    1223             :     EbObjectWrapper                *output_stream_wrapper_ptr;
    1224             : 
    1225             :     for (;;) {
    1226             :         // Get Input Full Object
    1227        7202 :         eb_get_full_object(
    1228             :             context_ptr->motion_estimation_results_input_fifo_ptr,
    1229             :             &inputResultsWrapperPtr);
    1230             : 
    1231        7200 :         inputResultsPtr = (MotionEstimationResults*)inputResultsWrapperPtr->object_ptr;
    1232        7200 :         picture_control_set_ptr = (PictureParentControlSet*)inputResultsPtr->picture_control_set_wrapper_ptr->object_ptr;
    1233             : 
    1234        7200 :         segment_index = inputResultsPtr->segment_index;
    1235             : 
    1236             :         // Set the segment mask
    1237        7200 :         SEGMENT_COMPLETION_MASK_SET(picture_control_set_ptr->me_segments_completion_mask, segment_index);
    1238             : 
    1239             :         // If the picture is complete, proceed
    1240        7200 :         if (SEGMENT_COMPLETION_MASK_TEST(picture_control_set_ptr->me_segments_completion_mask, picture_control_set_ptr->me_segments_total_count)) {
    1241         120 :             sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    1242         120 :             encode_context_ptr = (EncodeContext*)sequence_control_set_ptr->encode_context_ptr;
    1243             :             // Mark picture when global motion is detected using ME results
    1244             :             //reset intraCodedEstimationLcu
    1245         120 :             MeBasedGlobalMotionDetection(
    1246             :                 picture_control_set_ptr);
    1247             :             // Release Pa Ref pictures when not needed
    1248         120 :             ReleasePaReferenceObjects(
    1249             :                 sequence_control_set_ptr,
    1250             :                 picture_control_set_ptr);
    1251             : 
    1252             :             //****************************************************
    1253             :             // Input Motion Analysis Results into Reordering Queue
    1254             :             //****************************************************
    1255             : 
    1256         120 :             if(!picture_control_set_ptr->is_overlay)
    1257             :             // Determine offset from the Head Ptr
    1258         120 :             queueEntryPtr = DeterminePictureOffsetInQueue(
    1259             :                 encode_context_ptr,
    1260             :                 picture_control_set_ptr,
    1261             :                 inputResultsPtr);
    1262             : 
    1263         120 :             if (sequence_control_set_ptr->static_config.rate_control_mode)
    1264             :             {
    1265           0 :                 if (sequence_control_set_ptr->static_config.look_ahead_distance != 0) {
    1266             :                     // Getting the Histogram Queue Data
    1267           0 :                     GetHistogramQueueData(
    1268             :                         sequence_control_set_ptr,
    1269             :                         encode_context_ptr,
    1270             :                         picture_control_set_ptr);
    1271             :                 }
    1272             :             }
    1273             : 
    1274         840 :             for (temporal_layer_index = 0; temporal_layer_index < EB_MAX_TEMPORAL_LAYERS; temporal_layer_index++)
    1275         720 :                 picture_control_set_ptr->frames_in_interval[temporal_layer_index] = 0;
    1276         120 :             picture_control_set_ptr->frames_in_sw = 0;
    1277         120 :             picture_control_set_ptr->historgram_life_count = 0;
    1278         120 :             picture_control_set_ptr->scene_change_in_gop = EB_FALSE;
    1279             : 
    1280             :             //Check conditions for statinary edge over time
    1281             : 
    1282         120 :             StationaryEdgeOverUpdateOverTimeLcuPart1(
    1283             :                 sequence_control_set_ptr,
    1284             :                 picture_control_set_ptr);
    1285             : 
    1286         120 :             moveSlideWondowFlag = EB_TRUE;
    1287         360 :             while (moveSlideWondowFlag) {
    1288             :                 // Check if the sliding window condition is valid
    1289         240 :                 queueEntryIndexTemp = encode_context_ptr->initial_rate_control_reorder_queue_head_index;
    1290         240 :                 if (encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndexTemp]->parent_pcs_wrapper_ptr != EB_NULL)
    1291         238 :                     end_of_sequence_flag = (((PictureParentControlSet*)(encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndexTemp]->parent_pcs_wrapper_ptr)->object_ptr))->end_of_sequence_flag;
    1292             :                 else
    1293           2 :                     end_of_sequence_flag = EB_FALSE;
    1294         240 :                 frames_in_sw = 0;
    1295        6152 :                 while (moveSlideWondowFlag && !end_of_sequence_flag &&
    1296        5964 :                     queueEntryIndexTemp <= encode_context_ptr->initial_rate_control_reorder_queue_head_index + sequence_control_set_ptr->static_config.look_ahead_distance) {
    1297             :                     // frames_in_sw <= sequence_control_set_ptr->static_config.look_ahead_distance){
    1298        5912 :                     frames_in_sw++;
    1299             : 
    1300        5912 :                     queueEntryIndexTemp2 = (queueEntryIndexTemp > INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? queueEntryIndexTemp - INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH : queueEntryIndexTemp;
    1301             : 
    1302        5912 :                     moveSlideWondowFlag = (EbBool)(moveSlideWondowFlag && (encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndexTemp2]->parent_pcs_wrapper_ptr != EB_NULL));
    1303        5912 :                     if (encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndexTemp2]->parent_pcs_wrapper_ptr != EB_NULL) {
    1304             :                         // check if it is the last frame. If we have reached the last frame, we would output the buffered frames in the Queue.
    1305        5792 :                         end_of_sequence_flag = ((PictureParentControlSet*)(encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndexTemp2]->parent_pcs_wrapper_ptr)->object_ptr)->end_of_sequence_flag;
    1306             :                     }
    1307             :                     else
    1308         120 :                         end_of_sequence_flag = EB_FALSE;
    1309        5912 :                     queueEntryIndexTemp++;
    1310             :                 }
    1311             : 
    1312         240 :                 if (moveSlideWondowFlag) {
    1313             :                     //get a new entry spot
    1314         120 :                     queueEntryPtr = encode_context_ptr->initial_rate_control_reorder_queue[encode_context_ptr->initial_rate_control_reorder_queue_head_index];
    1315         120 :                     picture_control_set_ptr = ((PictureParentControlSet*)(queueEntryPtr->parent_pcs_wrapper_ptr)->object_ptr);
    1316         120 :                     sequence_control_set_ptr = (SequenceControlSet*)picture_control_set_ptr->sequence_control_set_wrapper_ptr->object_ptr;
    1317             :                     // overlay picture was not added to the queue. For the alt_ref picture with an overlay picture, it loops on both alt ref and overlay pictures
    1318         120 :                     uint8_t has_overlay = picture_control_set_ptr->is_alt_ref ? 1 : 0;
    1319         240 :                     for (uint8_t loop_index = 0; loop_index <= has_overlay; loop_index++) {
    1320         120 :                         if (loop_index)
    1321           0 :                             picture_control_set_ptr = picture_control_set_ptr->overlay_ppcs_ptr;
    1322         120 :                         picture_control_set_ptr->frames_in_sw = frames_in_sw;
    1323         120 :                         queueEntryIndexTemp = encode_context_ptr->initial_rate_control_reorder_queue_head_index;
    1324         120 :                         end_of_sequence_flag = EB_FALSE;
    1325             :                         // find the frames_in_interval for the peroid I frames
    1326        3078 :                         while (!end_of_sequence_flag &&
    1327        3010 :                             queueEntryIndexTemp <= encode_context_ptr->initial_rate_control_reorder_queue_head_index + sequence_control_set_ptr->static_config.look_ahead_distance) {
    1328        2958 :                             queueEntryIndexTemp2 = (queueEntryIndexTemp > INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? queueEntryIndexTemp - INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH : queueEntryIndexTemp;
    1329        2958 :                             pictureControlSetPtrTemp = ((PictureParentControlSet*)(encode_context_ptr->initial_rate_control_reorder_queue[queueEntryIndexTemp2]->parent_pcs_wrapper_ptr)->object_ptr);
    1330        2958 :                             if (sequence_control_set_ptr->intra_period_length != -1) {
    1331        2958 :                                 if (picture_control_set_ptr->picture_number % ((sequence_control_set_ptr->intra_period_length + 1)) == 0) {
    1332         124 :                                     picture_control_set_ptr->frames_in_interval[pictureControlSetPtrTemp->temporal_layer_index] ++;
    1333         124 :                                     if (pictureControlSetPtrTemp->scene_change_flag)
    1334           0 :                                         picture_control_set_ptr->scene_change_in_gop = EB_TRUE;
    1335             :                                 }
    1336             :                             }
    1337             : 
    1338        2958 :                             pictureControlSetPtrTemp->historgram_life_count++;
    1339        2958 :                             end_of_sequence_flag = pictureControlSetPtrTemp->end_of_sequence_flag;
    1340        2958 :                             queueEntryIndexTemp++;
    1341             :                         }
    1342             : 
    1343         120 :                         if ((sequence_control_set_ptr->static_config.look_ahead_distance != 0) && (frames_in_sw < (sequence_control_set_ptr->static_config.look_ahead_distance + 1)))
    1344          66 :                             picture_control_set_ptr->end_of_sequence_region = EB_TRUE;
    1345             :                         else
    1346          54 :                             picture_control_set_ptr->end_of_sequence_region = EB_FALSE;
    1347             : 
    1348         120 :                         if (sequence_control_set_ptr->static_config.rate_control_mode)
    1349             :                         {
    1350             :                             // Determine offset from the Head Ptr for HLRC histogram queue and set the life count
    1351           0 :                             if (sequence_control_set_ptr->static_config.look_ahead_distance != 0) {
    1352             :                                 // Update Histogram Queue Entry Life count
    1353           0 :                                 UpdateHistogramQueueEntry(
    1354             :                                     sequence_control_set_ptr,
    1355             :                                     encode_context_ptr,
    1356             :                                     picture_control_set_ptr,
    1357             :                                     frames_in_sw);
    1358             :                             }
    1359             :                         }
    1360             : 
    1361             :                         // Mark each input picture as PAN or not
    1362             :                         // If a lookahead is present then check PAN for a period of time
    1363         120 :                         if (!picture_control_set_ptr->end_of_sequence_flag && sequence_control_set_ptr->static_config.look_ahead_distance != 0) {
    1364             :                             // Check for Pan,Tilt, Zoom and other global motion detectors over the future pictures in the lookahead
    1365         118 :                             UpdateGlobalMotionDetectionOverTime(
    1366             :                                 encode_context_ptr,
    1367             :                                 sequence_control_set_ptr,
    1368             :                                 picture_control_set_ptr);
    1369             :                         }
    1370             :                         else {
    1371           2 :                             if (picture_control_set_ptr->slice_type != I_SLICE)
    1372           2 :                                 DetectGlobalMotion(picture_control_set_ptr);
    1373             :                         }
    1374             : 
    1375             :                         // BACKGROUND ENHANCEMENT PART II
    1376         120 :                         if (!picture_control_set_ptr->end_of_sequence_flag && sequence_control_set_ptr->static_config.look_ahead_distance != 0) {
    1377             :                             // Update BEA information based on Lookahead information
    1378         118 :                             UpdateBeaInfoOverTime(
    1379             :                                 encode_context_ptr,
    1380             :                                 picture_control_set_ptr);
    1381             :                         }
    1382             :                         else {
    1383             :                             // Reset zzCost information to default When there's no lookahead available
    1384           2 :                             InitZzCostInfo(
    1385             :                                 picture_control_set_ptr);
    1386             :                         }
    1387             : 
    1388             :                         // Use the temporal layer 0 isLcuMotionFieldNonUniform array for all the other layer pictures in the mini GOP
    1389         120 :                         if (!picture_control_set_ptr->end_of_sequence_flag && sequence_control_set_ptr->static_config.look_ahead_distance != 0) {
    1390             :                             // Updat uniformly moving LCUs based on Collocated LCUs in LookAhead window
    1391         118 :                             UpdateMotionFieldUniformityOverTime(
    1392             :                                 encode_context_ptr,
    1393             :                                 sequence_control_set_ptr,
    1394             :                                 picture_control_set_ptr);
    1395             :                         }
    1396             :                         // Derive blockinessPresentFlag
    1397         120 :                         DeriveBlockinessPresentFlag(
    1398             :                             sequence_control_set_ptr,
    1399             :                             picture_control_set_ptr);
    1400             : 
    1401             :                         // Get Empty Reference Picture Object
    1402         120 :                         eb_get_empty_object(
    1403         120 :                             sequence_control_set_ptr->encode_context_ptr->reference_picture_pool_fifo_ptr,
    1404             :                             &reference_picture_wrapper_ptr);
    1405         120 :                         if (loop_index) {
    1406           0 :                             picture_control_set_ptr->reference_picture_wrapper_ptr = reference_picture_wrapper_ptr;
    1407             :                             // Give the new Reference a nominal live_count of 1
    1408           0 :                             eb_object_inc_live_count(
    1409             :                                 picture_control_set_ptr->reference_picture_wrapper_ptr,
    1410             :                                 1);
    1411             :                         }
    1412             :                         else {
    1413         120 :                             ((PictureParentControlSet*)(queueEntryPtr->parent_pcs_wrapper_ptr->object_ptr))->reference_picture_wrapper_ptr = reference_picture_wrapper_ptr;
    1414             :                             // Give the new Reference a nominal live_count of 1
    1415         120 :                             eb_object_inc_live_count(
    1416         120 :                                 ((PictureParentControlSet*)(queueEntryPtr->parent_pcs_wrapper_ptr->object_ptr))->reference_picture_wrapper_ptr,
    1417             :                                 1);
    1418             :                         }
    1419             : #if TWO_PASS
    1420         120 :                         picture_control_set_ptr->stat_struct_first_pass_ptr = picture_control_set_ptr->is_used_as_reference_flag ? &((EbReferenceObject*)picture_control_set_ptr->reference_picture_wrapper_ptr->object_ptr)->stat_struct : &picture_control_set_ptr->stat_struct;
    1421         120 :                         if (sequence_control_set_ptr->use_output_stat_file)
    1422           0 :                             memset(picture_control_set_ptr->stat_struct_first_pass_ptr, 0, sizeof(stat_struct_t));
    1423             : #endif
    1424             :                         //OPTION 1:  get the output stream buffer in ressource coordination
    1425         120 :                         eb_get_empty_object(
    1426         120 :                             sequence_control_set_ptr->encode_context_ptr->stream_output_fifo_ptr,
    1427             :                             &output_stream_wrapper_ptr);
    1428             : 
    1429         120 :                         picture_control_set_ptr->output_stream_wrapper_ptr = output_stream_wrapper_ptr;
    1430             : 
    1431             :                         // Get Empty Results Object
    1432         120 :                         eb_get_empty_object(
    1433             :                             context_ptr->initialrate_control_results_output_fifo_ptr,
    1434             :                             &outputResultsWrapperPtr);
    1435             : 
    1436         120 :                         outputResultsPtr = (InitialRateControlResults*)outputResultsWrapperPtr->object_ptr;
    1437             : 
    1438         120 :                         if (loop_index)
    1439           0 :                             outputResultsPtr->picture_control_set_wrapper_ptr = picture_control_set_ptr->p_pcs_wrapper_ptr;
    1440             :                         else
    1441         120 :                         outputResultsPtr->picture_control_set_wrapper_ptr = queueEntryPtr->parent_pcs_wrapper_ptr;
    1442             :                         // Post the Full Results Object
    1443         120 :                         eb_post_full_object(outputResultsWrapperPtr);
    1444             :                     }
    1445             :                     // Reset the Reorder Queue Entry
    1446         120 :                     queueEntryPtr->picture_number += INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH;
    1447         120 :                     queueEntryPtr->parent_pcs_wrapper_ptr = (EbObjectWrapper *)EB_NULL;
    1448             : 
    1449             :                     // Increment the Reorder Queue head Ptr
    1450         120 :                     encode_context_ptr->initial_rate_control_reorder_queue_head_index =
    1451         120 :                         (encode_context_ptr->initial_rate_control_reorder_queue_head_index == INITIAL_RATE_CONTROL_REORDER_QUEUE_MAX_DEPTH - 1) ? 0 : encode_context_ptr->initial_rate_control_reorder_queue_head_index + 1;
    1452             : 
    1453         120 :                     queueEntryPtr = encode_context_ptr->initial_rate_control_reorder_queue[encode_context_ptr->initial_rate_control_reorder_queue_head_index];
    1454             :                 }
    1455             :             }
    1456             :         }
    1457             : 
    1458             :         // Release the Input Results
    1459        7200 :         eb_release_object(inputResultsWrapperPtr);
    1460             :     }
    1461             :     return EB_NULL;
    1462             : }

Generated by: LCOV version 1.14