LCOV - code coverage report
Current view: top level - Codec - EbGlobalMotionEstimation.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 68 84 81.0 %
Date: 2019-11-25 17:38:06 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*
       2             : * Copyright(c) 2019 Intel Corporation
       3             : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
       4             : */
       5             : 
       6             : /*
       7             : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
       8             : *
       9             : * This source code is subject to the terms of the BSD 2 Clause License and
      10             : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      11             : * was not distributed with this source code in the LICENSE file, you can
      12             : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      13             : * Media Patent License 1.0 was not distributed with this source code in the
      14             : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      15             : */
      16             : 
      17             : #include <stdlib.h>
      18             : 
      19             : #include "EbGlobalMotionEstimation.h"
      20             : #include "EbGlobalMotionEstimationCost.h"
      21             : #include "EbReferenceObject.h"
      22             : 
      23             : #include "global_motion.h"
      24             : #include "corner_detect.h"
      25             : 
      26             : 
      27             : 
      28          60 : void global_motion_estimation(PictureParentControlSet *picture_control_set_ptr,
      29             :                               MeContext *context_ptr,
      30             :                               EbPictureBufferDesc *input_picture_ptr)
      31             : {
      32          60 :     uint32_t numOfListToSearch = (picture_control_set_ptr->slice_type == P_SLICE)
      33          60 :         ? (uint32_t)REF_LIST_0 : (uint32_t)REF_LIST_1;
      34             : 
      35         177 :     for (uint32_t listIndex = REF_LIST_0; listIndex <= numOfListToSearch; ++listIndex) {
      36             : 
      37             :         uint32_t num_of_ref_pic_to_search;
      38         117 :         if (context_ptr->me_alt_ref == EB_TRUE)
      39           0 :             num_of_ref_pic_to_search = 1;
      40             :         else
      41         117 :             num_of_ref_pic_to_search = picture_control_set_ptr->slice_type == P_SLICE
      42           3 :                 ? picture_control_set_ptr->ref_list0_count
      43         231 :                 : listIndex == REF_LIST_0
      44          57 :                     ? picture_control_set_ptr->ref_list0_count
      45          57 :                     : picture_control_set_ptr->ref_list1_count;
      46             : 
      47             :         // Limit the global motion search to the first frame types of ref lists
      48         117 :         num_of_ref_pic_to_search = MIN(num_of_ref_pic_to_search, 1);
      49             : 
      50             :         // Ref Picture Loop
      51         230 :         for (uint32_t ref_pic_index = 0; ref_pic_index < num_of_ref_pic_to_search;
      52         113 :              ++ref_pic_index)
      53             :         {
      54             :             EbPaReferenceObject *referenceObject;
      55             : 
      56         113 :             if (context_ptr->me_alt_ref == EB_TRUE)
      57           0 :                 referenceObject = (EbPaReferenceObject *)context_ptr->alt_ref_reference_ptr;
      58             :             else
      59         113 :                 referenceObject = (EbPaReferenceObject *)picture_control_set_ptr
      60         113 :                         ->ref_pa_pic_ptr_array[listIndex][ref_pic_index]->object_ptr;
      61             : 
      62             : 
      63         113 :             EbPictureBufferDesc *ref_picture_ptr = (EbPictureBufferDesc*)referenceObject->input_padded_picture_ptr;
      64             : 
      65         113 :             compute_global_motion(input_picture_ptr, ref_picture_ptr,
      66             :                 &picture_control_set_ptr->global_motion_estimation[listIndex][ref_pic_index],
      67         113 :                 picture_control_set_ptr->frm_hdr.allow_high_precision_mv);
      68             :         }
      69             :     }
      70          60 : }
      71             : 
      72             : 
      73           0 : static INLINE int convert_to_trans_prec(int allow_hp, int coor) {
      74           0 :     if (allow_hp)
      75           0 :         return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 3);
      76             :     else
      77           0 :         return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 2) * 2;
      78             : }
      79             : 
      80             : 
      81         113 : void compute_global_motion(EbPictureBufferDesc *input_pic, EbPictureBufferDesc *ref_pic,
      82             :                            EbWarpedMotionParams *bestWarpedMotion, int allow_high_precision_mv)
      83             : {
      84             :     MotionModel params_by_motion[RANSAC_NUM_MOTIONS];
      85       11413 :     for (int m = 0; m < RANSAC_NUM_MOTIONS; m++) {
      86       11300 :         memset(&params_by_motion[m], 0, sizeof(params_by_motion[m]));
      87       11300 :         params_by_motion[m].inliers =
      88       11300 :                 malloc(sizeof(*(params_by_motion[m].inliers)) * 2 * MAX_CORNERS);
      89             :     }
      90             : 
      91             :     const double *params_this_motion;
      92             :     int inliers_by_motion[RANSAC_NUM_MOTIONS];
      93             :     EbWarpedMotionParams tmp_wm_params;
      94             :     // clang-format off
      95             :     static const double kIdentityParams[MAX_PARAMDIM - 1] = {
      96             :         0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
      97             :     };
      98             :     // clang-format on
      99             : 
     100             :     int frm_corners[2 * MAX_CORNERS];
     101         113 :     unsigned char *frm_buffer = input_pic->buffer_y + input_pic->origin_x + input_pic->origin_y * input_pic->stride_y;
     102         113 :     unsigned char *ref_buffer = ref_pic->buffer_y + ref_pic->origin_x + ref_pic->origin_y * ref_pic->stride_y;
     103             : 
     104         113 :     EbWarpedMotionParams global_motion = default_warp_params;
     105             : 
     106             :     // TODO: check ref_params
     107         113 :     const EbWarpedMotionParams *ref_params = &default_warp_params;
     108             : 
     109             :     {
     110             :         // compute interest points using FAST features
     111         113 :         int num_frm_corners = av1_fast_corner_detect(
     112         113 :             frm_buffer, input_pic->width, input_pic->height,
     113         113 :             input_pic->stride_y, frm_corners, MAX_CORNERS);
     114             : 
     115             :         TransformationType model;
     116             :         #define GLOBAL_TRANS_TYPES_ENC 3
     117             : 
     118         113 :         const GlobalMotionEstimationType gm_estimation_type = GLOBAL_MOTION_FEATURE_BASED;
     119         113 :         for (model = ROTZOOM; model <= GLOBAL_TRANS_TYPES_ENC; ++model) {
     120         113 :             int64_t best_warp_error = INT64_MAX;
     121             :             // Initially set all params to identity.
     122       11413 :             for (unsigned i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
     123       11300 :                 memcpy(params_by_motion[i].params, kIdentityParams,
     124             :                        (MAX_PARAMDIM - 1) * sizeof(*(params_by_motion[i].params)));
     125             :             }
     126             : 
     127         113 :             av1_compute_global_motion(
     128         113 :                         model, frm_buffer, input_pic->width, input_pic->height,
     129         113 :                         input_pic->stride_y, frm_corners, num_frm_corners,
     130         113 :                         ref_buffer, ref_pic->stride_y, EB_8BIT,
     131             :                         gm_estimation_type, inliers_by_motion, params_by_motion,
     132             :                         RANSAC_NUM_MOTIONS);
     133             : 
     134       11413 :             for (unsigned i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
     135       11300 :                 if (inliers_by_motion[i] == 0) continue;
     136             : 
     137        2173 :                 params_this_motion = params_by_motion[i].params;
     138        2173 :                 av1_convert_model_to_params(params_this_motion, &tmp_wm_params);
     139             : 
     140        2173 :                 if (tmp_wm_params.wmtype != IDENTITY) {
     141        2173 :                     const int64_t warp_error = av1_refine_integerized_param(
     142             :                                 &tmp_wm_params, tmp_wm_params.wmtype, EB_FALSE, EB_8BIT,
     143        2173 :                                 ref_buffer, ref_pic->width, ref_pic->height, ref_pic->stride_y,
     144        2173 :                                 frm_buffer, input_pic->width, input_pic->height, input_pic->stride_y, 5,
     145             :                                 best_warp_error);
     146        2173 :                     if (warp_error < best_warp_error) {
     147         255 :                         best_warp_error = warp_error;
     148             :                         // Save the wm_params modified by
     149             :                         // av1_refine_integerized_param() rather than motion index to
     150             :                         // avoid rerunning refine() below.
     151         255 :                         memcpy(&global_motion, &tmp_wm_params,
     152             :                                sizeof(EbWarpedMotionParams));
     153             :                     }
     154             :                 }
     155             :             }
     156         113 :             if (global_motion.wmtype <= AFFINE)
     157         113 :                 if (!eb_get_shear_params(&global_motion))
     158           0 :                     global_motion = default_warp_params;
     159             : 
     160         113 :             if (global_motion.wmtype == TRANSLATION) {
     161           0 :                 global_motion.wmmat[0] =
     162           0 :                         convert_to_trans_prec(allow_high_precision_mv,
     163           0 :                                               global_motion.wmmat[0]) *
     164             :                         GM_TRANS_ONLY_DECODE_FACTOR;
     165           0 :                 global_motion.wmmat[1] =
     166           0 :                         convert_to_trans_prec(allow_high_precision_mv,
     167           0 :                                               global_motion.wmmat[1]) *
     168             :                         GM_TRANS_ONLY_DECODE_FACTOR;
     169             :             }
     170             : 
     171         113 :             if (global_motion.wmtype == IDENTITY)
     172           0 :                 continue;
     173             : 
     174         113 :             const int64_t ref_frame_error = eb_av1_frame_error(
     175         113 :                         EB_FALSE, EB_8BIT, ref_buffer, ref_pic->stride_y, frm_buffer,
     176         113 :                         input_pic->width, input_pic->height, input_pic->stride_y);
     177             : 
     178         113 :             if (ref_frame_error == 0)
     179           0 :                 continue;
     180             : 
     181             :             // If the best error advantage found doesn't meet the threshold for
     182             :             // this motion type, revert to IDENTITY.
     183         226 :             if (!av1_is_enough_erroradvantage(
     184         113 :                         (double)best_warp_error / ref_frame_error,
     185             :                         gm_get_params_cost(&global_motion, ref_params,
     186             :                                            allow_high_precision_mv),
     187             :                         GM_ERRORADV_TR_0 /* TODO: check error advantage */)) {
     188           0 :                 global_motion = default_warp_params;
     189             :             }
     190         113 :             if (global_motion.wmtype != IDENTITY) {
     191         113 :                 break;
     192             :             }
     193             :         }
     194             :     }
     195             : 
     196         113 :     *bestWarpedMotion = global_motion;
     197             : 
     198       11413 :     for (int m = 0; m < RANSAC_NUM_MOTIONS; m++) {
     199       11300 :         free(params_by_motion[m].inliers);
     200             :     }
     201         113 : }

Generated by: LCOV version 1.14