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 #include "iep2_gmv.h"
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "mpp_common.h"
24 #include "mpp_buffer.h"
25
26 #include "iep2_api.h"
27
iep2_sort(uint32_t bin[],uint32_t map[],int size)28 void iep2_sort(uint32_t bin[], uint32_t 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)
44 if (dat[n] > dat[max])
45 max = n;
46 // Put found minimum element in its place
47 temp = dat[m];
48 p = map[m];
49
50 map[m] = map[max];
51 map[max] = p;
52 dat[m] = dat[max];
53 dat[max] = temp;
54 }
55
56 free(dat);
57 }
58
iep2_osd_check(int8_t * mv,int w,int sx,int ex,int sy,int ey,int * mvx)59 static int iep2_osd_check(int8_t *mv, int w, int sx, int ex, int sy, int ey,
60 int *mvx)
61 {
62 /* (28 + 27) * 4 + 1 */
63 uint32_t hist[221];
64 uint32_t map[221];
65 int total = (ey - sy + 1) * (ex - sx + 1);
66 int non_zero = 0;
67 int domin = 0;
68 int i, j;
69
70 memset(hist, 0, sizeof(hist));
71
72 for (i = sy; i <= ey; ++i) {
73 for (j = sx; j <= ex; ++j) {
74 int8_t v = mv[i * w + j];
75 uint32_t idx = v + 28 * 4;
76
77 if (idx >= MPP_ARRAY_ELEMS(hist)) {
78 mpp_log("invalid mv at (%d, %d)\n", j, i);
79 continue;
80 }
81 hist[idx]++;
82 }
83 }
84
85 non_zero = total - hist[28 * 4];
86
87 iep2_sort(hist, map, MPP_ARRAY_ELEMS(hist));
88
89 domin = hist[map[0]];
90 if (map[0] + 1 < MPP_ARRAY_ELEMS(hist))
91 domin += hist[map[0] + 1];
92 if (map[0] >= 1)
93 domin += hist[map[0] - 1];
94
95 iep_dbg_trace("total tiles in current osd: %d, non-zero %d\n",
96 total, non_zero);
97
98 if (domin * 4 < non_zero * 3) {
99 iep_dbg_trace("main mv %d count %d not dominant\n",
100 map[0] - 28 * 4, domin);
101 return 0;
102 }
103
104 *mvx = map[0] - 28 * 4;
105
106 return 1;
107 }
108
iep2_set_osd(struct iep2_api_ctx * ctx,struct mv_list * ls)109 void iep2_set_osd(struct iep2_api_ctx *ctx, struct mv_list *ls)
110 {
111 uint32_t i, j;
112 int idx = 0;
113
114 int sx[8];
115 int ex[8];
116 int sy[8];
117 int ey[8];
118
119 uint32_t osd_tile_cnt = 0;
120 int mvx;
121 int8_t *pmv = mpp_buffer_get_ptr(ctx->mv_buf);
122
123 memset(ls, 0, sizeof(*ls));
124
125 for (i = 0; i < ctx->output.dect_osd_cnt; ++i) {
126 sx[i] = ctx->output.x_sta[i];
127 ex[i] = ctx->output.x_end[i];
128 sy[i] = ctx->output.y_sta[i];
129 ey[i] = ctx->output.y_end[i];
130 }
131
132 /* Hardware isn't supporting subtitle regions overlap. */
133 for (i = 0; i < ctx->output.dect_osd_cnt; ++i) {
134 for (j = i + 1; j < ctx->output.dect_osd_cnt; ++j) {
135 if (sy[j] == ey[i]) {
136 if (ex[i] - sx[i] > ex[j] - sx[j]) {
137 sy[j]++;
138 } else {
139 ey[i]--;
140 }
141 } else {
142 break;
143 }
144 }
145 }
146
147 for (i = 0; i < ctx->output.dect_osd_cnt; ++i) {
148 if (!iep2_osd_check(pmv, ctx->params.tile_cols,
149 sx[i], ex[i], sy[i], ey[i], &mvx))
150 continue;
151
152 ctx->params.osd_x_sta[idx] = sx[i];
153 ctx->params.osd_x_end[idx] = ex[i];
154 ctx->params.osd_y_sta[idx] = sy[i];
155 ctx->params.osd_y_end[idx] = ey[i];
156
157 osd_tile_cnt += (ex[i] - sx[i] + 1) * (ey[i] - sy[i] + 1);
158
159 ls->mv[idx] = mvx;
160 ls->vld[idx] = 1;
161
162 iep_dbg_trace("[%d] from [%d,%d][%d,%d] to [%d,%d][%d,%d] mv %d\n", i,
163 sx[i], ex[i], sy[i], ey[i],
164 ctx->params.osd_x_sta[idx], ctx->params.osd_x_end[idx],
165 ctx->params.osd_y_sta[idx], ctx->params.osd_y_end[idx],
166 ls->mv[idx]);
167 idx++;
168 }
169
170 ctx->params.osd_area_num = idx;
171 ls->idx = idx;
172
173 iep_dbg_trace("osd tile count %d comb %d\n",
174 osd_tile_cnt, ctx->output.out_osd_comb_cnt);
175 if (osd_tile_cnt * 2 > ctx->output.out_osd_comb_cnt * 3) {
176 memset(ctx->params.comb_osd_vld, 0, sizeof(ctx->params.comb_osd_vld));
177 } else {
178 memset(ctx->params.comb_osd_vld, 1, sizeof(ctx->params.comb_osd_vld));
179 }
180 }
181
182