1 /*
2 * Copyright 2020 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "iep2"
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "mpp_common.h"
24
25 #include "iep2_api.h"
26 #include "iep2_gmv.h"
27
iep2_sort(uint32_t bin[],int map[],int size)28 static void iep2_sort(uint32_t bin[], int map[], int size)
29 {
30 int i, m, n;
31 uint32_t *dat = malloc(size * sizeof(uint32_t));
32
33 for (i = 0; i < size; ++i) {
34 map[i] = i;
35 dat[i] = bin[i];
36 }
37
38 for (m = 0; m < size; ++m) {
39 int max = m;
40 uint32_t temp;
41 int p;
42
43 for (n = m + 1; n < size; ++n) if (dat[n] > dat[max]) max = n;
44 // Put found minimum element in its place
45 temp = dat[m];
46 p = map[m];
47
48 map[m] = map[max];
49 map[max] = p;
50 dat[m] = dat[max];
51 dat[max] = temp;
52 }
53
54 free(dat);
55 }
56
iep2_is_subt_mv(int mv,struct mv_list * mv_ls)57 static int iep2_is_subt_mv(int mv, struct mv_list *mv_ls)
58 {
59 int i;
60
61 for (i = 0; i < mv_ls->idx; ++i) {
62 if (RKABS(mv_ls->mv[i] - (mv * 4)) < 3)
63 return 1;
64 }
65
66 return 0;
67 }
68
iep2_update_gmv(struct iep2_api_ctx * ctx,struct mv_list * mv_ls)69 void iep2_update_gmv(struct iep2_api_ctx *ctx, struct mv_list *mv_ls)
70 {
71 int rows = ctx->params.tile_rows;
72 int cols = ctx->params.tile_cols;
73 uint32_t *bin = ctx->output.mv_hist;
74 int lbin = MPP_ARRAY_ELEMS(ctx->output.mv_hist);
75 int i;
76
77 int map[MPP_ARRAY_ELEMS(ctx->output.mv_hist)];
78
79 uint32_t r = 6;
80
81 // print mvc histogram of current motion estimation.
82 for (i = 0; i < lbin; ++i) {
83 if (bin[i] == 0)
84 continue;
85 iep_dbg_trace("mv(%d) %d\n", i - MVL, bin[i]);
86 }
87
88 bin[MVL] = 0; // disable 0 mv
89
90 // update motion vector candidates
91 iep2_sort(bin, map, lbin);
92
93 iep_dbg_trace("sort map:\n");
94 if (0) {
95 for (i = 0; i < lbin; ++i) {
96 fprintf(stderr, "%d ", map[i]);
97 }
98 fprintf(stderr, "\n");
99 }
100
101 memset(ctx->params.mv_tru_list, 0, sizeof(ctx->params.mv_tru_list));
102 memset(ctx->params.mv_tru_vld, 0, sizeof(ctx->params.mv_tru_vld));
103
104 // Get top 8 candidates of current motion estimation.
105 for (i = 0; i < 8; ++i) {
106 int8_t x = map[i] - MVL;
107
108 if (bin[map[i]] > r * ((rows * cols) >> 7) ||
109 iep2_is_subt_mv(x, mv_ls)) {
110
111 // 1 bit at low endian for mv valid check
112 ctx->params.mv_tru_list[i] = x;
113 ctx->params.mv_tru_vld[i] = 1;
114 } else {
115 if (i == 0) {
116 ctx->params.mv_tru_list[0] = 0;
117 ctx->params.mv_tru_vld[0] = 1;
118 }
119 break;
120 }
121 }
122
123 for (i = 0; i < 8; ++i)
124 iep_dbg_trace("new mv candidates list[%d] (%d,%d) %d\n",
125 i, ctx->params.mv_tru_list[i], 0, ctx->params.mv_tru_vld[i]);
126 }
127
128